rq-initiating-coverage
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 字段名或内部执行语言
- 使用固定日期、固定季度、固定输出路径
More from ricequant/ricequant-skills
rqdata-python
RQData数据API使用指南。当需要查询RQData数据接口、获取金融数据时使用。支持A股、港股、期货、期权、指数、基金、可转债等市场数据查询,包含HTTP API和Python API文档。
9ricequant
Ricequant量化平台文档阅读和API查询工具。当Claude需要访问Ricequant量化工具时使用,特别是提到某类金融相关数据或者RQ等字眼时:包括RQAlphaPlus回测框架、RQData数据API、RQFactor因子计算、RQOptimizer优化器、RQPAttr归因分析等文档的查询和阅读。
1rq-morning-note
|
1rq-idea-generation
|
1rq-earnings-preview
|
1rq-sector-overview
|
1