
Rq Initiating Coverage
- 1 installs
- 43 repo stars
- Updated June 23, 2026
- ricequant/ricequant-skills
Generate a structured first-coverage equity research report for a Chinese listed company from RiceQuant-style JSON feeds.
About
rq-initiating-coverage is an agent skill for developers and analysts who need institutional-style first-coverage equity write-ups without rebuilding section order from scratch. It pairs a fixed Chinese report outline (执行摘要 through 风险提示 and appendix) with a explicit data contract that generate_report.py consumes from a local data directory. You supply normalized JSON for listing metadata, industry classification, share structure, shareholder concentration, and multi-quarter financials; the skill drives consistent narrative blocks for ownership, sell-side expectations, trading/dividend context, and comparable valuation. It suits diligence when you are scoping whether to cover, model, or build tooling around a ticker—not live execution or portfolio ops. Complexity is intermediate because you must source or export compliant RiceQuant-shaped datasets and interpret financial quality sections yourself.
- Chinese-language report skeleton with placeholders for exec summary, peers, valuation, and risks
- Documented JSON data contract for company_info, industry, shares, top-10 shareholders, and historical_financials
- generate_report.py reads --data-dir and assembles sections from structured inputs
- Anchors industry taxonomy and peer selection via first/second/third industry fields
- Builds 5-year same-basis financial trajectory from quarterly historical_financials
Rq Initiating Coverage by the numbers
- 1 all-time installs (skills.sh)
- Ranked #909 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/ricequant/ricequant-skills --skill rq-initiating-coverageAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 43 |
| Security audit | 3 / 3 scanners passed |
| Last updated | June 23, 2026 |
| Repository | ricequant/ricequant-skills ↗ |
What it does
Generate a structured first-coverage equity research report for a Chinese listed company from RiceQuant-style JSON feeds.
Files
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指定,不能写死固定路径
目录结构
initiating-coverage/
├── SKILL.md
├── scripts/
│ └── generate_report.py
├── assets/
│ └── template.md
└── references/
├── data_contract.md
└── web_search.md输入文件契约
原始数据目录由 --data-dir 指定,脚本会按下列文件名查找输入:
company_info.jsonindustry.jsonshares.jsonshareholder_top10.jsonhistorical_financials.jsonroe_history.jsonmarket_cap.jsonpe_ratio.jsonpb_ratio.jsondividend_yield.jsonprice_history.jsonturnover_history.jsonbenchmark_price.jsondividend_history.jsonconsensus.jsonresearch_reports.jsonpeer_pool.jsonpeer_company_info.jsonpeer_industry.jsonpeer_latest_financials.jsonpeer_roe.jsonpeer_market_cap.jsonpeer_pe_ratio.jsonpeer_pb_ratio.jsonpeer_dividend_yield.jsonweb_search_findings.json(可选)
完整字段说明见 references/data_contract.md。
工作流
步骤 1:准备参数
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:采集目标公司基础数据
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:采集目标公司估值、交易、分红与卖方数据
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"先根据财务数据识别最新季度与预测年份:
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 数据
先生成全市场股票列表和行业映射:
rqdata stock cn list --payload "{
\"date\": \"$FACTOR_DATE\",
\"type\": \"CS\"
}" --format json > "$DATA_DIR/stock_list.json"
python3 - "$DATA_DIR" "$ORDER_BOOK_ID" "$REPORT_DATE" "$FACTOR_DATE" <<'PY'
import json
import subprocess
import sys
from pathlib import Path
data_dir = Path(sys.argv[1])
target = sys.argv[2]
report_date = sys.argv[3]
factor_date = sys.argv[4]
target_industry = json.loads(data_dir.joinpath("industry.json").read_text(encoding="utf-8"))
target_rows = target_industry if isinstance(target_industry, list) else target_industry.get("data", [])
target_row = next(item for item in target_rows if isinstance(item, dict) and item.get("order_book_id") == target)
target_third = target_row.get("third_industry_name")
target_second = target_row.get("second_industry_name")
stock_list = json.loads(data_dir.joinpath("stock_list.json").read_text(encoding="utf-8"))
stock_rows = stock_list if isinstance(stock_list, list) else stock_list.get("data", [])
ids = [row["order_book_id"] for row in stock_rows if isinstance(row, dict) and row.get("order_book_id")]
industry_rows = []
for start in range(0, len(ids), 800):
chunk = ids[start:start + 800]
payload = json.dumps({
"order_book_ids": chunk,
"date": report_date,
"level": 0,
"source": "citics_2019",
}, ensure_ascii=False)
output = subprocess.check_output(
["rqdata", "stock", "cn", "industry", "--payload", payload, "--format", "json"],
text=True,
)
batch = json.loads(output)
industry_rows.extend(batch if isinstance(batch, list) else batch.get("data", []))
data_dir.joinpath("industry_universe.json").write_text(
json.dumps(industry_rows, ensure_ascii=False, indent=2),
encoding="utf-8",
)
third_matches = [row for row in industry_rows if isinstance(row, dict) and row.get("third_industry_name") == target_third]
second_matches = [row for row in industry_rows if isinstance(row, dict) and row.get("second_industry_name") == target_second]
selected = third_matches if len(third_matches) >= 6 else second_matches
candidate_ids = []
seen = set()
for row in selected:
stock = row.get("order_book_id")
if not stock or stock in seen:
continue
seen.add(stock)
candidate_ids.append(stock)
payload = json.dumps({
"order_book_ids": candidate_ids,
"factor": "market_cap",
"start_date": factor_date,
"end_date": factor_date,
}, ensure_ascii=False)
output = subprocess.check_output(
["rqdata", "stock", "cn", "financial-indicator", "--payload", payload, "--format", "json"],
text=True,
)
factor_rows = json.loads(output)
market_cap = {}
for row in factor_rows:
if isinstance(row, dict) and row.get("order_book_id") and row.get("market_cap") not in (None, "", "null"):
market_cap[row["order_book_id"]] = float(row["market_cap"])
peer_rows = []
for stock in candidate_ids:
if stock not in market_cap:
continue
peer_rows.append({
"order_book_id": stock,
"selection_level": "third" if stock in {item.get("order_book_id") for item in third_matches} else "second",
"market_cap": market_cap[stock],
})
peer_rows.sort(key=lambda item: item["market_cap"], reverse=True)
peer_rows = peer_rows[:6]
if target not in {item["order_book_id"] for item in peer_rows} and target in market_cap:
peer_rows = [{"order_book_id": target, "selection_level": "target", "market_cap": market_cap[target]}] + peer_rows[:5]
data_dir.joinpath("peer_pool.json").write_text(
json.dumps(peer_rows, ensure_ascii=False, indent=2),
encoding="utf-8",
)
PY再采集 peers 元数据与最新快照:
PEER_IDS="$(python3 - "$DATA_DIR/peer_pool.json" <<'PY'
import json
import sys
rows = json.load(open(sys.argv[1], "r", encoding="utf-8"))
print(json.dumps([row["order_book_id"] for row in rows], ensure_ascii=False))
PY
)"
rqdata stock cn instruments --payload "{
\"order_book_ids\": $PEER_IDS
}" --format json > "$DATA_DIR/peer_company_info.json"
rqdata stock cn industry --payload "{
\"order_book_ids\": $PEER_IDS,
\"date\": \"$REPORT_DATE\",
\"level\": 0,
\"source\": \"citics_2019\"
}" --format json > "$DATA_DIR/peer_industry.json"
rqdata stock cn financial --payload "{
\"order_book_ids\": $PEER_IDS,
\"fields\": [
\"revenue\",
\"net_profit\",
\"gross_profit\",
\"total_assets\",
\"total_liabilities\",
\"cash_from_operating_activities\"
],
\"start_quarter\": \"$HISTORY_START_QUARTER\",
\"end_quarter\": \"$HISTORY_END_QUARTER\",
\"statements\": \"all\"
}" --format json > "$DATA_DIR/peer_latest_financials.json"
rqdata stock cn financial-indicator --payload "{
\"order_book_ids\": $PEER_IDS,
\"factor\": \"return_on_equity_weighted_average\",
\"start_date\": \"$PRICE_START_DATE\",
\"end_date\": \"$FACTOR_DATE\"
}" --format json > "$DATA_DIR/peer_roe.json"
for factor in market_cap pe_ratio pb_ratio dividend_yield; do
rqdata stock cn financial-indicator --payload "{
\"order_book_ids\": $PEER_IDS,
\"factor\": \"$factor\",
\"start_date\": \"$FACTOR_DATE\",
\"end_date\": \"$FACTOR_DATE\"
}" --format json > "$DATA_DIR/peer_${factor}.json"
done步骤 5:生成 Markdown / HTML
python3 initiating-coverage/scripts/generate_report.py \
--stock "$ORDER_BOOK_ID" \
--data-dir "$DATA_DIR" \
--report-date "$REPORT_DATE" \
--output "$OUTPUT_MD"阶段门控
Gate 1:公司与财务主数据齐备
- 已识别最新财报季度
- 价格历史、一致预期、peer 主数据齐全
- 公司、股东、财务、估值、分红、交易文件存在
Gate 2:卖方与可比样本整理完成
research_reports.json已抓取且公司直接相关样本可识别- 若需要进入最终报告,
summaries.core_view已补齐 peer_pool.json已生成,且可比公司数量足以支撑对比
Gate 3:可选网络搜索结果完成
- 若启用定性补充,
web_search_findings.json已落盘 - 字段完整、来源等级可解释
- 网络搜索结果仅用于管理层 / 行业 / 政策 / 竞争背景,不替代量化主数据
Gate 4:成稿完成
- Markdown 已生成
- 若本地渲染器存在,HTML 已生成
- 客户稿不暴露内部术语
- 长度、章节、来源标注和结构化对比均达标
模板规则
- 报告必须严格基于 template.md 生成
- 占位符采用
[[TOKEN]]语法,不使用 Jinja - 当前模板仅允许以下占位符:
[[REPORT_DATE]][[COMPANY_NAME]][[STOCK_CODE]][[EXEC_SUMMARY]][[COMPANY_PROFILE]][[OWNERSHIP_SECTION]][[FINANCIAL_TRAJECTORY]][[QUALITY_AND_CASHFLOW]][[EXPECTATION_AND_SELLSIDE]][[PEER_AND_VALUATION]][[TRADING_AND_DIVIDEND]][[RISK_SECTION]][[APPENDIX]]
报告质量要求
- 报告必须包含模板中的所有一级章节
- 必须同时覆盖:
- 公司基本信息与股权结构
- 历史财务轨迹
- 现金流与资产负债表
- 市场预期与卖方摘录
- 可比公司与估值定位
- 交易表现与股东回报
- 风险提示与口径说明
- 报告必须达到首次覆盖的最低研究深度,不能退化成“财务 + peer 简表”
- 最低研究深度至少应回答 4 类问题:
- 公司是什么、处于什么行业位置、覆盖边界在哪里
- 近 5 年财务轨迹和最近单季度经营节奏如何变化
- 当前市场预期、卖方口径与可比估值把公司放在什么位置
- 后续持续跟踪时最需要盯住哪些风险与验证点
- 若启用了网络搜索结果补充,正文至少要出现“管理层 / 行业 / 政策 / 公司动态 / 竞争格局”中的一类实质信息,而不是只多一个 sidecar 文件
- 不允许残留
[[PLACEHOLDER]] - 不允许在正文中暴露内部流程描述、文件名、字段名或脚本术语
- Markdown 输出必须与模板章节和数据契约保持一致
阶段验收清单
- [ ] Markdown 文件存在
- [ ] 若本地渲染器存在则 HTML 文件存在
- [ ] 模板占位符无残留
- [ ] 主章节完整
- [ ] 报告长度达到 10-16 页的最低可交付标准
- [ ] 关键数据点与关键结论带
数据来源:XXX,置信度X - [ ] peers 来自显式生成且可复核的可比公司池
- [ ] 若使用卖方摘要,正文消费的是客户可读摘要层
- [ ] 若使用
web_search,其内容已真正进入最终报告且未越权替代 RQData 主数据
常见错误
- 把
financial-indicator返回字段错误地当成统一value - 在脚本里硬写固定 peers 或固定公司结论
- 把原始卖方
summary直接截断贴进客户稿 - 把
web_search结果写成主结论,反而压过 RQData 主数据 - 在正文里出现文件名、JSON 字段名或内部执行语言
- 使用固定日期、固定季度、固定输出路径
首次覆盖研究报告
- 报告日期:[[REPORT_DATE]]
- 公司:[[COMPANY_NAME]]([[STOCK_CODE]])
执行摘要
[[EXEC_SUMMARY]]
公司概况与覆盖边界
[[COMPANY_PROFILE]]
股权结构与治理画像
[[OWNERSHIP_SECTION]]
历史财务轨迹
[[FINANCIAL_TRAJECTORY]]
盈利质量与现金流
[[QUALITY_AND_CASHFLOW]]
市场预期与卖方口径
[[EXPECTATION_AND_SELLSIDE]]
可比公司与估值定位
[[PEER_AND_VALUATION]]
交易表现与股东回报
[[TRADING_AND_DIVIDEND]]
风险提示
[[RISK_SECTION]]
附录:口径说明
[[APPENDIX]]
initiating-coverage 数据契约
initiating-coverage/scripts/generate_report.py 默认从 --data-dir 读取以下 JSON 文件。
1. company_info.json
典型字段:
order_book_idsymbolabbrev_symbolindustry_namelisted_dateoffice_addressprovincesector_code_name
用途:
- 公司名称、上市时间、办公地、基础资料
2. industry.json
典型字段:
first_industry_namesecond_industry_namethird_industry_name
用途:
- 行业口径与 peers 选择锚点
3. shares.json
典型字段:
datetotaltotal_acirculation_afree_circulation
用途:
- 总股本、流通股本、自由流通股本和自由流通比例
4. shareholder_top10.json
典型字段:
end_dateinfo_daterankshareholder_namehold_percent_totalhold_percent_floatshareholder_kind
用途:
- 十大股东结构、集中度、国资 / 基金 / 外资等持有人画像
5. historical_financials.json
典型字段:
quarterinfo_daterevenuenet_profitgross_profittotal_assetstotal_liabilitiestotal_equitycash_from_operating_activitiescash_flow_from_investing_activitiescash_flow_from_financing_activities
用途:
- 自动识别最新财报季度
- 生成 5 年同口径财务轨迹
- 计算同比、单季度、毛利率、资产负债率、现金转化率
6. roe_history.json
典型字段:
datereturn_on_equity_weighted_average
用途:
- ROE 时间序列与当前盈利质量
7. market_cap.json / pe_ratio.json / pb_ratio.json / dividend_yield.json
典型字段:
date- 对应 factor 字段
说明:
dividend_yield原始值为 bps,生成报告时需要除以100后按百分比展示
用途:
- 当前估值、股东回报与 peer percentile
8. price_history.json
典型字段:
datetimeclosevolumetotal_turnover
用途:
- 1M / 3M / 6M / 1Y / 3Y 绝对收益
- 相对基准收益
9. turnover_history.json
典型字段:
tradedatetodayweekmonthyear
用途:
- 最新换手率与历史中位数对比
10. benchmark_price.json
典型字段:
datetimeclose
用途:
- 计算相对沪深300等基准的超额收益
11. dividend_history.json
典型字段:
quarterdividend_cash_before_taxround_lotdeclaration_announcement_dateex_dividend_date
用途:
- 分红历史、年度派现节奏与每手税前现金分配
12. consensus.json
典型字段:
datecreate_tmreport_year_tcomp_con_operating_revenue_t / t1 / t2 / t3comp_con_net_profit_t / t1 / t2 / t3comp_con_eps_t / t1 / t2 / t3con_targ_price
用途:
- 最新一致预期与 60 天前预期对比
- 目标价变化
13. research_reports.json
典型字段:
create_tmdatereport_titlesummarysummaries.core_viewinstituteauthorfiscal_yearnet_profit_t / t1 / t2eps_t / t1 / t2targ_pricereport_main_iddata_source
用途:
- 卖方口径摘要
- 目标价、盈利预测与机构分布补充
补充说明:
- 若存在
data_source字段,应将0视为公司研报主样本;其他来源默认不进入最终正文 - 最终报告优先读取
summaries.core_view等客户可读摘要,不直接截断原始summary
14. peer_pool.json
允许格式:
[
{
"order_book_id": "600519.XSHG",
"selection_level": "third",
"market_cap": 2000000000000
}
]用途:
- 显式记录可比公司池来源和选择结果
15. peer_company_info.json / peer_industry.json / peer_latest_financials.json
用途:
- 提供 peers 名称、行业归属、最新财务快照
16. peer_roe.json / peer_market_cap.json / peer_pe_ratio.json / peer_pb_ratio.json / peer_dividend_yield.json
用途:
- 生成可比公司估值与盈利质量对比表
17. web_search_findings.json
该文件可选,仅用于补充管理层、行业、政策、竞争或公司近期动态的定性背景。
每条记录至少包含:
querysource_namesource_typetitleurlpublished_atretrieved_atsummarywhy_relevantconfidencefinding_type
推荐附加字段:
subjectrelated_entitiesstance
说明:
published_at是源内容发布时间,不是报告日期retrieved_at是实际检索时间source_type/confidence需遵守 references/web_search.md 的来源等级约束web_search_findings.json不能替代财务、估值、价格、分红、一致预期和 peer 量化主数据- 若该文件存在,报告会将其压缩为客户可读的补充背景,不会直接回显原始字段
解析约定
- 所有文件都允许
{"data": [...]}、{"data": {...}}、[...]、{...}四种包装方式 - 同一股票同一季度若存在多条财务记录,脚本会按
info_date <= report-date选择最新披露版本 consensus年份映射按report_year_t + offset- 研报必须做相关性过滤,标题或
report_main_id优先,不能把纯行业周报直接塞进正文 web_search_findings.json若存在,记录必须包含完整来源元数据,且置信度不能超过来源类别上限- 最终报告面向客户阅读,附录仅保留必要口径说明,不回显内部执行流程或文件名
Initiating Coverage Web Search Reference
Purpose
Use web_search only to supplement qualitative information that RQData CLI does not directly provide for an initiating-coverage report.
Allowed Coverage
- Management biographies, public career history, and governance events
- Industry size, competitive structure, policy environment, and regulatory changes
- Recent company product, capacity, organization, or partnership updates
- Competitor qualitative positioning that helps explain the peer set
Prohibited Usage
- Do not replace financial statements, valuation multiples, prices, dividends, consensus, or peer ranking
- Do not use
web_searchto fabricate official disclosures or hard financial facts - Do not let low-confidence external context dominate the core valuation or rating logic
Required Output File
All external findings must be written to web_search_findings.json.
Each record must contain:
querysource_namesource_typetitleurlpublished_atretrieved_atsummarywhy_relevantconfidencefinding_type
Recommended fields:
subjectrelated_entitiesstance
Allowed finding_type
management_updateindustry_contextpolicy_contextcompany_newscompetition_context
Source Types And Confidence Ceiling
official: max confidence5government: max confidence4association: max confidence4authoritative_media: max confidence4general_news: max confidence3inference: max confidence1
Search Workflow
1. Confirm the needed information is not directly available from RQData CLI. 2. Prefer official and primary sources first. 3. Save the finding into web_search_findings.json with structured metadata. 4. Keep the summary factual and keep the relevance note concrete. 5. Use the findings only as qualitative context for company research, industry framing, or governance interpretation.
Fallback
1. Use the native web_search tool when available. 2. Otherwise use the configured network search tool in the current environment. 3. If neither is available:
- do not fabricate real-time information
- explicitly mark that the qualitative context is unavailable or unverified
- keep the report at the structured-data level instead of pretending the research is complete
Example
{
"data": [
{
"query": "公司名 董事长 简历 2026",
"source_name": "公司官网",
"source_type": "official",
"title": "董事长简历",
"url": "https://www.example.com/management",
"published_at": "2026-03-01",
"retrieved_at": "2026-04-07",
"summary": "公司官网披露董事长曾在行业龙头和监管机构任职,拥有较长产业和管理经验。",
"why_relevant": "可用于补充管理层与治理画像章节的定性背景。",
"confidence": 5,
"finding_type": "management_update",
"subject": "董事长履历",
"related_entities": ["示例公司"],
"stance": "neutral"
}
]
}Related skills
FAQ
Is Rq Initiating Coverage safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.