ricequant/ricequant-skills/initiating-coverage

Claude Code and agent skill by ricequant/ricequant-skills

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

创建模板驱动的首次覆盖研究报告,基于真实财务、股权结构、交易、分红、市场预期、卖方摘要与可比公司数据输出长篇结构化报告。 `RQData CLI` 负责财务、交易、分红、预期、可比公司与公司基础资料主数据;若需要补充管理层履历、行业规模、竞争格局或政策背景,可额外使用 `web_search` 获取实时定性信息,并先落为结构化 JSON,再由当前报告脚本将其以客户可读方式纳入对应章节。 务必使用此技能当用户: - 明确请求首次覆盖、initiating coverage、深度公司研究、完整公司分析框架 - 需要为新纳入跟踪的公司建立完整的公司研究报告、对比框架和估值定位 - 需要公司概况、财务轨迹、股权结构、卖方预期、可比估值等一揽子分析输入 不适用场景: - 财报后单次复盘 -> earnings-analysis - 财报前瞻 -> earnings-preview - 行业整体研究 -> sector-overview

Install

npx vskill@latest install ricequant/ricequant-skills/initiating-coverage

SKILL.md

RQ 股票研究 - 首次覆盖

核心原则

  • 所有内容必须遵循三阶段流程:数据采集 -> 报告生成 -> HTML 渲染
  • assets/template.md 是唯一报告模板来源;Python 只做数据归一化、指标计算、占位符填充和结构校验
  • Python 可以基于真实数据生成客户可读摘要,但不能硬写脱离数据的主观结论、固定公司故事或静态投资判断
  • 当前实现不是 skills-reference 中 5 任务 DOCX 工程的逐任务复刻,而是将其压缩为单次自动化长篇报告;但研究深度、来源规范、图表替代表达和证据覆盖不得明显降级
  • 最新财报季度必须从真实 historical_financials.json 中按 info_date <= report-date 自动识别
  • financial-indicator 必须使用 factor + start_date/end_date
  • peers 选择必须显式落盘为 peer_pool.json,不能在脚本里偷藏固定可比公司列表
  • research_reports.json 若提供 data_source 字段,应将 0 视为公司研报主样本;其他来源默认不进入最终正文
  • research_reports.json 若要进入最终报告,必须先在同一文件内回写 summaries.core_view 等客户可读摘要;最终报告不直接截断原始 summary
  • 缺失数据时必须明确写“无数据 / 未提供 / 未验证”,不能留空

数据源分工

RQData CLI 负责
  • 公司基础资料、行业口径、股本与十大股东
  • 历史财务、ROE、估值、价格、换手率、分红
  • 一致预期、目标价、卖方研报结构化字段
  • 可比公司池、可比公司财务与估值
web_search 负责
  • 管理层公开履历补充
  • 行业规模、竞争格局、政策环境与监管变化
  • 公司重大新闻、产能 / 产品 / 组织调整等实时定性背景
  • RQData 无法直接提供的竞争对手定性描述
web_search 禁止替代的内容
  • 财务数据、估值指标、价格、换手率、分红与一致预期
  • 可比公司筛选、peer 排名和量化定位
  • 任何本应由 RQData 提供的结构化主数据

web_search 使用规则

详细字段、来源等级、落盘示例和 fallback 规则见 references/web_search.md。

允许补充的内容:

  • 管理层履历、重要任职背景、治理事件
  • 行业规模、竞争格局、政策动态和监管要求
  • 公司近期产品、产能、组织或合作进展

落盘要求:

  • 所有 web_search 结果必须先写入 web_search_findings.json
  • 只写结构化记录,不把搜索草稿或碎片化笔记直接塞进报告
  • 若未提供该文件,报告仍可交付,但相关定性背景必须保持“未验证”边界
  • 即便提供了 web_search_findings.json,它也只能补充定性语境,不能改写量化结论

硬性规则

以下任一条违反,视为输出失败:

  • [MUST-1] 财务数据、估值数据、价格数据、分红数据和一致预期必须来自 RQData CLI
  • [MUST-2] web_search 只补充定性信息,不能替代结构化金融主数据
  • [MUST-3] 金额类字段在客户稿中必须换算为“亿元”等可读口径
  • [MUST-4] peers 必须来自显式落盘并可复核的可比公司池,不能在代码里写死
  • [MUST-5] 若使用卖方研报,最终报告必须优先消费 summaries.core_view 等客户可读摘要,不直接截断原始 summary
  • [MUST-6] 每个关键数据点或关键结论都要标 数据来源:XXX,置信度X
  • [MUST-7] 客户稿不得暴露 LLM、skill、文件名、JSON 字段名、workflow 术语或内部状态
  • [MUST-8] 低置信度网络搜索结果不得单独支撑核心投资结论
  • [MUST-9] 图表若未生成,必须由等价表格、趋势表或对比表完成降级,不得让关键分析断层

确信度评级

  • 5:RQData CLI、交易所公告、上市公司官网、官方监管披露
  • 4:政府 / 监管 / 行业协会 / 官方机构、权威财经媒体
  • 3:一般媒体或二手整理,但来源清晰且与其他来源一致
  • 2:单一来源、细节不完整、时点未充分验证
  • 1:推断、估算窗口、未验证信息

使用规则:

  • 混合结论的置信度取关键来源中的最低值
  • 推断类文字不得标成高置信度
  • 低置信度信息只能作为补充背景,不得单独推导出评级或估值判断

图表 / 图片需求

当前实现以表格和趋势事实完成最小可交付版本,但首次覆盖报告仍必须定义图表需求;若图表缺失,必须用等价结构化表达降级。

  • 图表名称:收入与净利润五年轨迹
  • 图表目的:展示 5 年历史财务变化和最新同口径趋势
  • 使用的数据文件:historical_financials.json
  • 关键字段:quarter、revenue、net_profit
  • 建议图表类型:柱线组合图
  • 回答问题:公司收入和利润的扩张节奏是否稳定
  • 放置位置:## 历史财务轨迹
  • 若图表缺失:保留同口径财务表和近 8 季趋势表
  • 图表名称:盈利质量与现金流结构图
  • 图表目的:展示毛利率、ROE、资产负债率和现金转化率变化
  • 使用的数据文件:historical_financials.json、roe_history.json
  • 关键字段:gross_profit、revenue、return_on_equity_weighted_average、cash_from_operating_activities、total_assets、total_liabilities
  • 建议图表类型:折线图或分组柱图
  • 回答问题:盈利质量是改善还是弱化,现金流是否跟得上利润
  • 放置位置:## 盈利质量与现金流
  • 若图表缺失:保留质量指标表和现金流对比表
  • 图表名称:可比公司估值定位图
  • 图表目的:比较目标公司与 peers 的市值、ROE、PE、PB、股息率定位
  • 使用的数据文件:peer_pool.json、peer_*
  • 关键字段:market_cap、return_on_equity_weighted_average、pe_ratio、pb_ratio、dividend_yield
  • 建议图表类型:散点图、条形图或对比表
  • 回答问题:公司当前估值在可比样本中偏高还是偏低
  • 放置位置:## 可比公司与估值定位
  • 若图表缺失:保留 peer 对比表与中位数偏离表
  • 图表名称:股价与股东回报图
  • 图表目的:展示目标公司相对基准的股价表现与历史分红
  • 使用的数据文件:price_history.json、benchmark_price.json、dividend_history.json
  • 关键字段:close、dividend_cash_before_tax、declaration_announcement_date
  • 建议图表类型:收益曲线图 + 分红时间轴
  • 回答问题:市场历史定价与股东回报特征如何
  • 放置位置:## 交易表现与股东回报
  • 若图表缺失:保留收益表、换手表和分红表

目标产出

  • 报告长度:10-16 页
  • 推荐中文字符数:3500-6000
  • 输出文件:
  • Markdown 报告
  • HTML 报告(若本地已安装渲染器)
  • 输出目录必须由 --data-dir / --output 指定,不能写死固定路径

目录结构

text
initiating-coverage/
├── SKILL.md
├── scripts/
│ └── generate_report.py
├── assets/
│ └── template.md
└── references/
├── data_contract.md
└── web_search.md

输入文件契约

原始数据目录由 --data-dir 指定,脚本会按下列文件名查找输入:

  • company_info.json
  • industry.json
  • shares.json
  • shareholder_top10.json
  • historical_financials.json
  • roe_history.json
  • market_cap.json
  • pe_ratio.json
  • pb_ratio.json
  • dividend_yield.json
  • price_history.json
  • turnover_history.json
  • benchmark_price.json
  • dividend_history.json
  • consensus.json
  • research_reports.json
  • peer_pool.json
  • peer_company_info.json
  • peer_industry.json
  • peer_latest_financials.json
  • peer_roe.json
  • peer_market_cap.json
  • peer_pe_ratio.json
  • peer_pb_ratio.json
  • peer_dividend_yield.json
  • web_search_findings.json(可选)

完整字段说明见 references/data_contract.md。

工作流

步骤 1:准备参数
bash
REPORT_DATE="${REPORT_DATE:-$(date +%F)}"
ORDER_BOOK_ID="${ORDER_BOOK_ID:-600519.XSHG}"
BENCHMARK_ORDER_BOOK_ID="${BENCHMARK_ORDER_BOOK_ID:-000300.XSHG}"
PRICE_START_DATE="$(python3 - <<PY
from datetime import date, timedelta
report_date = date.fromisoformat("${REPORT_DATE}")
print((report_date - timedelta(days=365 * 3 + 30)).isoformat())
PY
)"
CONSENSUS_START_DATE="$(python3 - <<PY
from datetime import date, timedelta
report_date = date.fromisoformat("${REPORT_DATE}")
print((report_date - timedelta(days=210)).isoformat())
PY
)"
HISTORY_START_QUARTER="$(python3 - <<PY
from datetime import date
report_date = date.fromisoformat("${REPORT_DATE}")
print(f"{report_date.year - 5}q1")
PY
)"
HISTORY_END_QUARTER="$(python3 - <<PY
from datetime import date
report_date = date.fromisoformat("${REPORT_DATE}")
print(f"{report_date.year}q4")
PY
)"
FACTOR_DATE="$(python3 - <<PY
import json
import subprocess
from datetime import date, timedelta
def has_non_empty_factor(day: str) -> bool:
payload = json.dumps({
"order_book_ids": ["${ORDER_BOOK_ID}"],
"factor": "market_cap",
"start_date": day,
"end_date": day,
}, ensure_ascii=False)
rows = json.loads(subprocess.check_output(
["rqdata", "stock", "cn", "financial-indicator", "--payload", payload, "--format", "json"],
text=True,
))
return any(isinstance(row, dict) and row.get("market_cap") not in (None, "", "null") for row in rows)
cursor = date.fromisoformat("${REPORT_DATE}")
for _ in range(15):
if has_non_empty_factor(cursor.isoformat()):
print(cursor.isoformat())
break
cursor -= timedelta(days=1)
else:
raise SystemExit("最近 15 个自然日都未找到非空 market_cap 因子日期")
PY
)"
DATA_DIR="${DATA_DIR:-$HOME/rq_equities_reports/initiating_coverage}"
OUTPUT_MD="${OUTPUT_MD:-$DATA_DIR/initiating_coverage_${ORDER_BOOK_ID}_${REPORT_DATE}.md}"
mkdir -p "$DATA_DIR"
步骤 2:采集目标公司基础数据
bash
rqdata stock cn instruments --payload "{
\"order_book_ids\": [\"$ORDER_BOOK_ID\"]
}" --format json > "$DATA_DIR/company_info.json"
rqdata stock cn industry --payload "{
\"order_book_ids\": [\"$ORDER_BOOK_ID\"],
\"date\": \"$REPORT_DATE\",
\"level\": 0,
\"source\": \"citics_2019\"
}" --format json > "$DATA_DIR/industry.json"
rqdata stock cn shares --payload "{
\"order_book_ids\": [\"$ORDER_BOOK_ID\"],
\"start_date\": \"$CONSENSUS_START_DATE\",
\"end_date\": \"$REPORT_DATE\"
}" --format json > "$DATA_DIR/shares.json"
rqdata stock cn shareholder-top10 --payload "{
\"order_book_ids\": [\"$ORDER_BOOK_ID\"],
\"start_date\": \"$CONSENSUS_START_DATE\",
\"end_date\": \"$REPORT_DATE\",
\"start_rank\": 1,
\"end_rank\": 10
}" --format json > "$DATA_DIR/shareholder_top10.json"
rqdata stock cn financial --payload "{
\"order_book_ids\": [\"$ORDER_BOOK_ID\"],
\"fields\": [
\"revenue\",
\"net_profit\",
\"gross_profit\",
\"total_assets\",
\"total_liabilities\",
\"total_equity\",
\"cash_from_operating_activities\",
\"cash_flow_from_investing_activities\",
\"cash_flow_from_financing_activities\"
],
\"start_quarter\": \"$HISTORY_START_QUARTER\",
\"end_quarter\": \"$HISTORY_END_QUARTER\",
\"statements\": \"all\"
}" --format json > "$DATA_DIR/historical_financials.json"
步骤 3:采集目标公司估值、交易、分红与卖方数据
bash
rqdata stock cn financial-indicator --payload "{
\"order_book_ids\": [\"$ORDER_BOOK_ID\"],
\"factor\": \"return_on_equity_weighted_average\",
\"start_date\": \"$PRICE_START_DATE\",
\"end_date\": \"$FACTOR_DATE\"
}" --format json > "$DATA_DIR/roe_history.json"
for factor in market_cap pe_ratio pb_ratio dividend_yield; do
rqdata stock cn financial-indicator --payload "{
\"order_book_ids\": [\"$ORDER_BOOK_ID\"],
\"factor\": \"$factor\",
\"start_date\": \"$FACTOR_DATE\",
\"end_date\": \"$FACTOR_DATE\"
}" --format json > "$DATA_DIR/${factor}.json"
done
rqdata stock cn price --payload "{
\"order_book_ids\": [\"$ORDER_BOOK_ID\"],
\"start_date\": \"$PRICE_START_DATE\",
\"end_date\": \"$REPORT_DATE\",
\"fields\": [\"close\", \"volume\", \"total_turnover\", \"high\", \"low\"],
\"adjust_type\": \"post\"
}" --format json > "$DATA_DIR/price_history.json"
rqdata stock cn turnover-rate --payload "{
\"order_book_ids\": [\"$ORDER_BOOK_ID\"],
\"start_date\": \"$PRICE_START_DATE\",
\"end_date\": \"$REPORT_DATE\"
}" --format json > "$DATA_DIR/turnover_history.json"
rqdata index price --payload "{
\"order_book_ids\": [\"$BENCHMARK_ORDER_BOOK_ID\"],
\"start_date\": \"$PRICE_START_DATE\",
\"end_date\": \"$REPORT_DATE\",
\"fields\": [\"close\"]
}" --format json > "$DATA_DIR/benchmark_price.json"
rqdata stock cn dividend --payload "{
\"order_book_ids\": [\"$ORDER_BOOK_ID\"],
\"start_date\": \"$(python3 - <<PY
from datetime import date
report_date = date.fromisoformat("${REPORT_DATE}")
print(f\"{report_date.year - 5}-01-01\")
PY
)\",
\"end_date\": \"$REPORT_DATE\"
}" --format json > "$DATA_DIR/dividend_history.json"
rqdata stock cn consensus --payload "{
\"order_book_ids\": [\"$ORDER_BOOK_ID\"],
\"start_date\": \"$CONSENSUS_START_DATE\",
\"end_date\": \"$REPORT_DATE\",
\"report_range\": 3
}" --format json > "$DATA_DIR/consensus.json"

先根据财务数据识别最新季度与预测年份:

bash
read LATEST_QUARTER LATEST_YEAR NEXT_YEAR <<EOF
$(python3 - "$DATA_DIR/historical_financials.json" "$REPORT_DATE" <<'PY'
import json
import sys
from datetime import date
payload = json.load(open(sys.argv[1], "r", encoding="utf-8"))
report_date = date.fromisoformat(sys.argv[2])
records = payload if isinstance(payload, list) else payload.get("data", [])
best = None
for item in records:
if not isinstance(item, dict):
continue
quarter = str(item.get("quarter") or "").lower()
info_date = str(item.get("info_date") or "")[:10]
if not quarter or not info_date:
continue
if info_date > report_date.isoformat():
continue
if best is None or quarter > best:
best = quarter
if not best:
raise SystemExit("未识别到最新财报季度")
year = int(best[:4])
print(best, year, year + 1)
PY
)
EOF
python3 - "$DATA_DIR" "$ORDER_BOOK_ID" "$LATEST_YEAR" "$NEXT_YEAR" "$CONSENSUS_START_DATE" "$REPORT_DATE" <<'PY'
import json
import subprocess
import sys
from pathlib import Path
data_dir = Path(sys.argv[1])
stock = sys.argv[2]
years = [sys.argv[3], sys.argv[4]]
start_date = sys.argv[5]
end_date = sys.argv[6]
rows = []
for year in years:
payload = json.dumps({
"order_book_ids": [stock],
"fiscal_year": year,
"start_date": start_date,
"end_date": end_date,
"date_rule": "create_tm",
}, ensure_ascii=False)
output = subprocess.check_output(
["rqdata", "stock", "cn", "research-reports", "--payload", payload, "--format", "json"],
text=True,
)
data = json.loads(output)
rows.extend(data if isinstance(data, list) else data.get("data", []))
data_dir.joinpath("research_reports.json").write_text(
json.dumps(rows, ensure_ascii=False, indent=2),
encoding="utf-8",
)
PY

若 research_reports.json 需要进入最终正文,应先在原记录内补齐客户可读摘要:

  • 摘要输入位置:research_reports.json -> records[].summary
  • 摘要回写位置:research_reports.json -> records[].summaries.core_view
  • 仅 data_source=0 且公司直接相关的记录可以进入最终报告
步骤 3.5:可选的管理层 / 行业 / 竞争语境补充

当用户需要更完整的首次覆盖定性背景时,可执行该步骤。

  • 使用 web_search 补充管理层、行业规模、政策环境、竞争格局或公司最新重大动态
  • 结果必须写入 web_search_findings.json
  • 这类结果只补充定性语境,不参与 Python 量化计算或 peer 排序
步骤 4:生成可比公司池并采集 peers 数据

先生成全市场股票列表和行业映射:

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
50
Repository forks
7
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/ricequant/ricequant-skills/initiating-coverage/badge)](https://verified-skill.com/skills/ricequant/ricequant-skills/initiating-coverage)

Something wrong with this skill or its page? Tell us.