skills/financial-report-writing/SKILL.md
wangyitong a65adcc2e5 Initial commit: merged, deduplicated, and vetted skill collection
Sources: extracted from two upstream archives (skill-repo, skills-main),
merged with the following policy:

- 15 broken symlinks (pointing to /Users/jameslee/.cc-switch/skills or
  ../../.agents/skills on a foreign machine) discarded
- 3 real name collisions with identical content (ai-pair, ifind-http-api,
  zhipu-websearch) kept as one copy
- Functional overlaps deduped keeping the strongest variant:
  - docx family: kept docx (official, full toolchain) + docx-cn
    (GB/T 9704 Chinese official-document constants),
    dropped docx_writer (no scripts, name collided with docx)
  - humanizer family: kept humanizer-zh (6 zh reference docs),
    dropped humanizer (en, redundant for CN workflow)
- Skills that only ran in a foreign environment removed:
  ablemind-ops, app-publish, hlb-design-system, openclaw-adj-skill,
  claude-driver
- alphapai excluded from this public repo because its SKILL.md hard-coded
  live credentials

Result: 25 skills, 572 files, ~7.5 MB.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 14:47:12 +08:00

686 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 金融研究报告撰写技能
## 概述
本技能用于协助用户撰写专业的A股上市公司投资研究报告涵盖数据获取、分析和文档格式化等全流程。
## 适用场景
- 撰写上市公司周报、月报或专项研究报告
- 需要使用Wind金融终端获取实时或历史数据
- 生成符合中国国家标准的Word格式文档
- 技术分析与基本面分析相结合的投资报告
## 核心能力
### 1. 数据获取WindPy SDK
#### 连接Wind终端
```python
from WindPy import w
w.start()
data = w.wsd("300866.SZ", "close", "2025-11-01", "2026-02-06")
w.stop()
```
#### 常用数据函数
- `w.wsd()` - 日线序列数据
- `w.wsi()` - 分钟线数据
- `w.wss()` - 截面数据(最新值)
- `wsd` 常用字段:
- `close` - 收盘价
- `open`/`high`/`low` - 开盘/最高/最低价
- `volume`/`amt` - 成交量/成交额
- `pct_chg` - 涨跌幅
- `ma5`, `ma10`, `ma20`, `ma60` - 均线
- `roe` - 净资产收益率
- `pe_ttm`, `pb_lf` - 市盈率/市净率
#### 技术指标计算
- 移动平均线MA5, MA10, MA20, MA60
- 波动率:使用标准差计算年化波动率
- 支撑位/阻力位:基于高低点分析
### 2. Word文档格式化python-docx
#### 国家标准 GB/T 9704-2012
**页面设置**
```python
from docx.shared import Mm
section.top_margin = Mm(37)
section.bottom_margin = Mm(35)
section.left_margin = Mm(28)
section.right_margin = Mm(26)
```
**字体规范**
```python
def set_font(run, font_name, size=None, bold=None):
run.font.name = font_name
run.font.size = Pt(size) if size else None
if bold is not None:
run.font.bold = bold
# 设置中文字体
run._element.rPr.rFonts.set(qn('w:eastAsia'), font_name)
# 三号标题16pt
# 四号正文14pt
# 小四表格12pt
```
**字号对照表**
- 三号16pt
- 四号14pt
- 小四12pt
- 五号10.5pt
**行距设置**
```python
paragraph.paragraph_format.line_spacing = Pt(28) # 正文
paragraph.paragraph_format.line_spacing = Pt(25) # 小标题
paragraph.paragraph_format.line_spacing_rule = 2 # 固定值
```
**段落格式**
```python
# 首行缩进2字符28pt
paragraph.paragraph_format.first_line_indent = Pt(28)
# 两端对齐
paragraph.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
# 段前段后距
paragraph.paragraph_format.space_before = Pt(0)
paragraph.paragraph_format.space_after = Pt(0)
```
#### 三线表格式
```python
def set_table_borders(table):
tblPr = table._tbl.tblPr
tblBorders = OxmlElement('w:tblBorders')
# 顶底边框 1.5pt (sz=18)
for pos in ['top', 'bottom']:
border = OxmlElement(f'w:{pos}')
border.set(qn('w:val'), 'single')
border.set(qn('w:sz'), '18')
border.set(qn('w:color'), 'auto')
tblBorders.append(border)
# 内部横线 0.75pt (sz=9)
for pos in ['insideH']:
border = OxmlElement(f'w:{pos}')
border.set(qn('w:val'), 'single')
border.set(qn('w:sz'), '9')
border.set(qn('w:color'), 'auto')
tblBorders.append(border)
# 无左右和竖线
for pos in ['left', 'right', 'insideV']:
border = OxmlElement(f'w:{pos}')
border.set(qn('w:val'), 'none')
tblBorders.append(border)
tblPr.append(tblBorders)
```
#### 页脚页码
```python
from docx.enum.text import WD_ALIGN_PARAGRAPH
footer = section.footer
p = footer.paragraphs[0] if footer.paragraphs else footer.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r1 = p.add_run('—')
set_font(r1, '仿宋', 12)
r2 = p.add_run() # 页码占位
set_font(r2, '仿宋', 12)
r3 = p.add_run(' ')
set_font(r3, '仿宋', 12)
r4 = p.add_run() # 页码占位
set_font(r4, '仿宋', 12)
r5 = p.add_run('—')
set_font(r5, '仿宋', 12)
```
### 3. 报告结构标准
#### 完整报告结构(可选封面版)
1. **封面页**
- 标题黑体三号16pt居中
- 报告机构和日期黑体三号16pt居中
2. **免责声明**(可选)
- 标题黑体三号16pt居中
- 内容仿宋四号14pt两端对齐
3. **核心提要**
- 标题黑体三号16pt居中
- 内容3-4个要点仿宋四号14pt首行缩进2字符
4. **一、投资评级**
- 标题黑体三号16pt
- 评级表格小四12pt三线表
- 内容:投资建议、目标价格、有效期、风险等级
5. **二、核心观点**
- 标题黑体三号16pt
- 内容:基本面+技术面分析+投资建议
6. **三、市场表现回顾**
- 标题黑体三号16pt
- 价格走势分析黑体三号16pt
- K线数据表标题黑体小四12pt
#### 简化报告结构(无封面)
- 核心提要 → 一、投资评级 → 二、核心观点 → 三、市场表现回顾
- 不使用分页符,保持内容连贯
### 4. 内容撰写要点
#### 核心提要
- 突出关键数据ROE、涨跌幅等
- 简明扼要3-4个要点
- 包含明确的投资建议
#### 核心观点
- 基本面盈利能力ROE、估值水平PE/PB
- 技术面:价格趋势、均线、支撑阻力位
- 投资建议:具体操作策略
#### 市场表现回顾
- 时间周期近13周周线数据
- 价格区间:最高价、最低价、累计涨跌幅
- 数据表格:日期、开盘、最高、最低、收盘、涨跌幅、成交量
### 5. 数据处理技巧
#### 时间序列对齐
```python
import pandas as pd
df = pd.DataFrame(data, columns=['date', 'open', 'high', 'low', 'close'])
df['date'] = pd.to_datetime(df['date'])
df.sort_values('date', ascending=True)
```
#### 周线数据汇总
```python
df_weekly = df.resample('W').agg({
'open': 'first',
'high': 'max',
'low': 'min',
'close': 'last',
'volume': 'sum'
})
```
#### 波动率计算
```python
import numpy as np
returns = df['close'].pct_change().dropna()
volatility = returns.std() * np.sqrt(52) * 100 # 年化百分比
```
### 6. 常见问题解决
#### 字体显示问题
- 必须同时设置中文字体:`run._element.rPr.rFonts.set(qn('w:eastAsia'), font_name)`
- 不要只设置 `run.font.name`
#### 表格单元格格式
- Cell对象没有 `paragraph_format` 属性
- 需要通过 `cell.paragraphs[0].paragraph_format` 访问
#### Run对象访问
- Run对象没有 `runs` 属性
- 段落的runs通过 `paragraph.runs` 访问
#### 行距单位
- 使用 `Pt()` 设置固定行距(点)
- `line_spacing_rule = 2` 表示固定值
## 使用示例
### 基本流程
1. 使用WindPy SDK获取股票数据
2. 计算技术指标MA、波动率等
3. 分析基本面指标ROE、PE等
4. 整理分析结论
5. 使用python-docx生成Word文档
6. 应用GB/T 9704-2012格式规范
7. 保存文档
### 快速检查清单Word文档
- [ ] 页面边距37/35/28/26mm
- [ ] 字体:标题黑体三号、正文仿宋四号、表格小四
- [ ] 行距正文28pt、小标题25pt
- [ ] 首行缩进正文2字符28pt
- [ ] 三线表顶底1.5pt、内部0.75pt、无边框
- [ ] 数据来源注脚右对齐小四12pt
### Excel图表检查清单
详见「图表设置检查清单」表格第7节末尾
## 注意事项
1. **字体重要性**:中文文本必须设置 `w:eastAsia` 属性,否则可能显示为默认字体
2. **表格边框**:使用三线表格式,无左右和竖线
3. **段落缩进**:正文段落需要首行缩进,标题不需要
4. **分页控制**:根据需要决定是否分页,简化版通常不分页
5. **数据时效**:注意数据更新日期,避免使用过期数据
6. **投资建议**:提供明确的操作策略,但需提醒风险
### 7. Excel 图表绘制openpyxl
本技能支持生成包含原生 Excel 图表的 .xlsx 文件,图表可在 Excel 中编辑和交互。
#### 基础图表创建
```python
from openpyxl import Workbook
from openpyxl.chart import LineChart, BarChart, Reference
from openpyxl.chart.axis import DateAxis
# 创建工作簿
wb = Workbook()
ws = wb.active
ws.title = "股价走势"
# 写入数据
ws.append(["日期", "收盘价", "成交量"])
for date, close, vol in data:
ws.append([date, close, vol])
# 创建折线图(股价走势)
chart = LineChart()
chart.title = "股价走势"
chart.y_axis.title = "价格(元)"
chart.x_axis.title = "日期"
# 设置数据区域
data_ref = Reference(ws, min_col=2, min_row=1, max_row=len(data)+1)
cats_ref = Reference(ws, min_col=1, min_row=2, max_row=len(data)+1)
chart.add_data(data_ref, titles_from_data=True)
chart.set_categories(cats_ref)
# 设置样式
chart.style = 10
chart.height = 10 # 高度(厘米)
chart.width = 20 # 宽度(厘米)
# 添加到工作表
ws.add_chart(chart, "D2")
wb.save("股价走势.xlsx")
```
#### 常用图表类型
**折线图LineChart**
- 适用:股价走势、均线趋势
- 特点:展示时间序列变化
```python
from openpyxl.chart import LineChart
chart = LineChart()
chart.add_data(data_ref)
chart.set_categories(cats_ref)
```
**柱状图BarChart**
- 适用:成交量对比、财务数据对比
- 特点:横向展示数据大小
```python
from openpyxl.chart import BarChart
chart = BarChart()
chart.type = "col" # 垂直柱状图
chart.add_data(data_ref)
```
**组合图表(股价+成交量)**
- 适用K线+成交量组合展示
- 特点双Y轴价格+量能
```python
from openpyxl.chart import LineChart, BarChart
from openpyxl.chart.series import DataPoint
# 主图:股价线
price_chart = LineChart()
price_chart.add_data(price_ref, titles_from_data=True)
price_chart.y_axis.title = "价格(元)"
# 副图:成交量柱状
vol_chart = BarChart()
vol_chart.add_data(vol_ref, titles_from_data=True)
vol_chart.y_axis.axId = 200 # 设置次要Y轴
vol_chart.y_axis.title = "成交量(手)"
# 组合图表
price_chart += vol_chart
price_chart.y_axis.crosses = "max" # 成交量轴在右侧
```
#### 图表样式设置
**线条与颜色规范**
```python
# 线条样式
from openpyxl.chart.series import DataPoint
from openpyxl.drawing.fill import SolidColorFillProperties
from openpyxl.drawing.line import LineProperties
series = chart.series[0]
series.graphicalProperties.line.solidFill = "4472C4" # 线条颜色
series.graphicalProperties.line.width = 25000 # 线条粗细EMUs
# 标记点样式
series.marker.symbol = "circle"
series.marker.size = 5
```
**A股颜色规范涨跌自动着色**
```python
# 柱状图根据涨跌自动设置颜色(红涨绿跌)
from openpyxl.drawing.fill import PatternFillProperties, ColorChoice
from openpyxl.chart.series import DataPoint
# 为每个数据点设置颜色
for i, val in enumerate(values):
pt = DataPoint(idx=i)
# A股规范上涨红色下跌绿色
fill_color = "FF0000" if val >= 0 else "00B050"
pt.graphicalProperties = GraphicalProperties(
solidFill=fill_color
)
series.data_points.append(pt)
```
**网格线与图例**
```python
# 网格线设置(研报风格:仅水平主网格线)
chart.x_axis.majorGridlines = None # 隐藏X轴网格
chart.y_axis.majorGridlines = None # 或设置为浅灰色虚线
# 图例位置
chart.legend.position = "b" # 底部b, 右侧r, 顶部t, 左侧l
```
#### 双轴图表(价格+涨跌幅)
```python
from openpyxl.chart import LineChart
from openpyxl.chart.axis import DateAxis
# 主图:股价
price_chart = LineChart()
price_chart.add_data(price_ref, titles_from_data=True)
price_chart.y_axis.title = "价格(元)"
# 副图:涨跌幅(柱状)
pct_chart = LineChart()
pct_chart.add_data(pct_ref, titles_from_data=True)
pct_chart.y_axis.axId = 200
pct_chart.y_axis.title = "涨跌幅(%"
# 组合
price_chart += pct_chart
price_chart.y_axis.crosses = "max"
```
#### 坐标轴精修(研报级设置)
**数值轴Y轴刻度设置**
```python
# 设置Y轴最大最小值避免自动刻度导致的空白过多
chart.y_axis.scaling.min = 10 # 根据实际数据调整
chart.y_axis.scaling.max = 50
# 设置主要刻度单位
chart.y_axis.majorUnit = 5
# 对于大数值(如成交量),建议数据预处理转换为"亿"或"万"
# 并在轴标题中注明单位
chart.y_axis.title = "成交量(亿元)"
```
**日期轴X轴标签优化**
```python
from openpyxl.chart.axis import DateAxis
from openpyxl.drawing.text import Paragraph, ParagraphProperties, CharacterProperties
# 设置X轴为日期轴
chart.x_axis = DateAxis()
chart.x_axis.title = "日期"
# 标签间隔(避免数据点过多导致重叠)
chart.x_axis.tickLblSkip = 5 # 每5个数据点显示一个标签
# 标签旋转(防止重叠)
from copy import deepcopy
from openpyxl.drawing.text import RichText
rt = RichText(p=[Paragraph(
pPr=ParagraphProperties(defRPr=CharacterProperties(sz=900)),
endParaRPr=CharacterProperties(sz=900)
)])
chart.x_axis.txPr = rt
```
**坐标轴数字格式**
```python
# Y轴数字格式保留2位小数
chart.y_axis.numFmt = '0.00'
# 百分比格式
chart.y_axis.numFmt = '0.00%'
```
#### 数据标签与参考线(视觉增强)
**数据标签设置**
```python
from openpyxl.chart.label import DataLabelList
# 显示所有数据点的值
chart.dataLabels = DataLabelList()
chart.dataLabels.showVal = True
# 仅显示最后一个点(标注最新价)- 需要手动设置
from openpyxl.chart.series import DataPoint
last_pt = DataPoint(idx=len(values)-1)
last_pt.graphicalProperties = GraphicalProperties(solidFill="FF0000")
series.data_points = [last_pt]
```
**参考线(均值/目标价)**
```python
from openpyxl.chart.series import SeriesLabel
# 添加均值参考线(作为单独的数据系列)
mean_value = sum(values) / len(values)
ws.append([""] * (len(headers)-1) + ["均值"])
for i in range(len(values)):
ws.append([""] * (len(headers)-1) + [mean_value])
mean_ref = Reference(ws, min_col=len(headers), min_row=len(values)+2, max_row=len(values)*2+1)
mean_series = Series(mean_ref, title="均值线")
chart.series.append(mean_series)
```
#### 财务数据可视化
**营收利润趋势图**
```python
# 数据准备
ws.append(["报告期", "营业收入", "净利润"])
for period, revenue, profit in financial_data:
ws.append([period, revenue/1e8, profit/1e8]) # 转换为亿元
# 组合图表
chart = BarChart()
chart.type = "col"
chart.grouping = "clustered"
chart.title = "营业收入与净利润"
chart.y_axis.title = "金额(亿元)"
data = Reference(ws, min_col=2, max_col=3, min_row=1, max_row=len(financial_data)+1)
cats = Reference(ws, min_col=1, min_row=2, max_row=len(financial_data)+1)
chart.add_data(data, titles_from_data=True)
chart.set_categories(cats)
# 添加数据标签
chart.dataLabels = DataLabelList()
chart.dataLabels.showVal = True
```
**ROE 柱状图**
```python
chart = BarChart()
chart.type = "col"
data = Reference(ws, min_col=2, min_row=1, max_row=5)
cats = Reference(ws, min_col=1, min_row=2, max_row=5)
chart.add_data(data, titles_from_data=True)
chart.set_categories(cats)
chart.title = "年度 ROE 对比"
```
#### Excel 文件与 Word 报告配合
**方案AExcel 作为附件**
```python
# 生成带图表的 Excel 文件
wb.save(f"{stock_name}_数据分析.xlsx")
# 在 Word 中引用
paragraph = doc.add_paragraph()
run = paragraph.add_run(f"详细数据及图表请参见附件《{stock_name}_数据分析.xlsx》")
set_font(run, "仿宋", 12)
```
**方案B图表图片直接插入 Word推荐**
```python
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from docx.shared import Inches
# 使用 Matplotlib 生成符合 GB/T 9704 字体要求的图表
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
fig, ax = plt.subplots(figsize=(8, 4.5))
ax.plot(dates, prices, color='#4472C4', linewidth=1.5)
ax.set_title('股价走势', fontsize=12, fontweight='bold')
ax.set_xlabel('日期', fontsize=10)
ax.set_ylabel('价格(元)', fontsize=10)
ax.grid(True, alpha=0.3)
# 保存为图片
fig.savefig('chart.png', dpi=150, bbox_inches='tight')
plt.close()
# 插入 Word
doc.add_picture('chart.png', width=Inches(6))
```
**方案CWord 原生图表(功能有限)**
```python
from docx.chart import Chart
from docx.enum.chart import XL_CHART_TYPE
# 注意docx.chart 功能较弱,仅支持基础图表类型
# 如需复杂图表建议使用方案A或B
```
#### 图表最佳实践
1. **数据准备**:使用 pandas 预处理数据,确保格式正确
2. **图表选择**
- 时间序列 → 折线图
- 对比分析 → 柱状图
- 价格+成交量 → 组合图
3. **颜色规范**A股标准
- 上涨红色FF0000
- 下跌绿色00B050推荐00AA00
- 中性蓝色4472C4
4. **数据单位**:图表标题或轴标题中注明单位(元、%、亿元等)
5. **数据来源**:图表下方注明数据来源,如"数据来源Wind"
#### 图表设置检查清单
| 检查项 | 专业要求 | 常见错误 |
|--------|----------|----------|
| **坐标轴标题** | 必须包含单位,如"价格(元)"、"比例(%" | 漏写单位或单位不统一 |
| **色彩方案** | 涨红跌绿A股规范多序列使用高对比度商务色 | 使用 Excel 默认全家桶配色 |
| **网格线** | 仅保留水平主网格线,且设为浅灰色/虚线,或直接隐藏 | 粗黑实线网格,遮盖趋势线 |
| **字体统一** | 图表内字体需与 Word 正文匹配建议微软雅黑或等线9pt | 默认小号宋体,缩放后模糊 |
| **数据源标注** | 图表下方须注明数据来源WindXX证券研究所 | 来源不明 |
| **标签间隔** | X轴数据点密集时需设置 `tickLblSkip` 防止重叠 | 标签重叠难以辨认 |
| **数值精度** | Y轴根据数据类型设置合适的小数位价格2位百分比1-2位 | 小数位过多或过少 |
#### 高度封装工具函数
工具函数已封装在 `scripts/chart_utils.py` 中,使用时直接导入:
```python
import sys
sys.path.insert(0, ".claude/skills/financial-report-writing/scripts")
from chart_utils import create_research_chart, create_price_volume_chart
import pandas as pd
# 准备数据
df = pd.DataFrame({
"date": ["2024-01", "2024-02", "2024-03"],
"close": [10.5, 11.2, 10.8]
})
# 生成股价走势图
wb = create_research_chart(
df,
chart_type="line",
title="股价走势",
x_col="date",
y_cols="close",
y_axis_title="价格(元)",
show_last_label_only=True,
add_mean_line=True,
output_path="股价走势.xlsx"
)
```
**可用函数**
| 函数 | 用途 |
|------|------|
| `create_research_chart()` | 通用图表(折线/柱状/多序列) |
| `create_price_volume_chart()` | 股价+成交量双Y轴组合图 |
**`create_research_chart()` 主要参数**
| 参数 | 说明 | 默认值 |
|------|------|--------|
| `df` | DataFrame数据源 | 必填 |
| `chart_type` | 图表类型:"line"/"bar" | "line" |
| `x_col` | X轴列名 | 必填 |
| `y_cols` | Y轴列名支持列表 | 必填 |
| `y_axis_title` | Y轴标题建议带单位 | "" |
| `y_format` | 数字格式 | "0.00" |
| `show_last_label_only` | 仅显示最后一个标签 | False |
| `add_mean_line` | 添加均值参考线 | False |
| `color_up/color_down` | 涨跌颜色 | FF0000/00B050 |
| `tick_skip` | X轴标签间隔 | 5 |
完整函数定义和源码见:`scripts/chart_utils.py`
## 相关工具
- **WindPy**Wind金融终端Python API
- **python-docx**Word文档操作库
- **openpyxl**Excel文件操作支持原生图表
- **pandas**:数据处理和分析
- **numpy**:数值计算
- **GB/T 9704-2012**:党政机关公文格式标准
## 参考资源
- WindPy SDK官方文档
- python-docx API文档
- GB/T 9704-2012国家公文格式标准
- 券商研究报告格式规范