Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
ricequant avatar

Rq Sector Overview

  • 1 installs
  • 43 repo stars
  • Updated June 23, 2026
  • ricequant/ricequant-skills

Generate a structured Chinese industry overview report from RiceQuant JSON datasets using the sector-overview generator script and template sections.

About

rq-sector-overview is a RiceQuant-aligned agent skill for developers and quant-adjacent founders who need an industry overview memo without hand-writing every section from scratch. It expects curated JSON under a data directory—definitions, stock pools, financials, ROE, market cap, and industry maps—and drives sector-overview/scripts/generate_report.py to fill a Chinese markdown template with executive summary, sector state, financial structure, competition, valuation, relative performance, investment cues, and risk blocks. The skill is opinionated about data shape so agents do not improvise metrics or mix industry cohorts. Use it in early research when you are deciding whether a vertical is investable, crowding, or margin-compressed, and you already have or can export RiceQuant-style datasets rather than live brokerage APIs inside the agent session.

  • Fixed report skeleton: executive summary through risks and appendix placeholders
  • generate_report.py reads a --data-dir of contract JSON files
  • Documented inputs: sector_definition, stock_pool, financials, ROE, market_cap, and industry_map
  • Sections cover competition, valuation, performance, and investment tracking framework
  • Explicit data contract notes for pool formats and industry-level validation

Rq Sector Overview 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: MEDIUM risk (skills.sh audit)
  • Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/ricequant/ricequant-skills --skill rq-sector-overview

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1
repo stars43
Security audit2 / 3 scanners passed
Last updatedJune 23, 2026
Repositoryricequant/ricequant-skills

What it does

Generate a structured Chinese industry overview report from RiceQuant JSON datasets using the sector-overview generator script and template sections.

Files

SKILL.mdMarkdownGitHub ↗

RQ 股票研究 - 行业概览

核心原则

  • 所有内容必须遵循三阶段流程:数据采集 -> 报告生成 -> HTML 渲染
  • assets/template.md 是唯一报告模板来源;Python 只做数据归一化、指标计算、占位符填充和结构校验
  • skill 必须自包含,不能依赖仓库级 utils
  • 生成器只消费显式的 stock_pool.json,不能在代码里硬写“白酒股池”“新能源股池”
  • 缺失数据时必须明确写“无数据/未提供”,不能留空
  • 若估值因子文件只有空字符串,必须回溯到最近非空因子日,不能接受“文件有记录但关键章节无数据”的报告
  • 最终 Markdown 必须按客户阅读口径呈现,重点输出行业状态判断、龙头梯队、投资线索和跟踪指标,不能把生成过程写进正文
  • 每个主要章节都必须保留 数据来源:RQData,置信度5

数据源分工

RQData CLI 负责

  • 行业股票池、财务、估值、价格与基准表现
  • 行业内公司对比、集中度和横向排序

web_search 负责

  • 市场规模、行业趋势、监管政策
  • 竞争格局、并购整合与主题链背景

web_search 禁止替代的内容

  • 财务、估值、行情和公告等结构化主数据
  • 股票池定义和量化排序结果

web_search 使用规则

详细字段与约束见 references/web_search.md

  • 所有网络搜索信息必须先写入 web_search_findings.json
  • 若未提供该文件,报告仍可交付,但只能保持结构化行业概览边界
  • 若提供了网络搜索信息,正文必须真正吸收,而不是只多一个 sidecar 文件

硬性规则

  • [MUST-1] 先完整收集所有数据,再开始分析和撰写报告
  • [MUST-2] 财务、估值和行情数据必须来自 RQData CLI
  • [MUST-3] 市场规模、行业趋势和政策背景必须通过 web_search 实时获取,不能依赖训练记忆
  • [MUST-4] 市值和金额类数据必须统一换算为“亿元”等客户可读口径
  • [MUST-5] 每个关键数据点或关键结论都要标 数据来源:XXX,置信度X
  • [MUST-6] 客户稿不得暴露文件名、字段名或内部 workflow 术语
  • [MUST-7] 低置信度网络搜索信息不能单独支撑行业结论或投资线索

目标产出

  • 报告长度:10-15 页,正文至少达到约 3000 中文字符
  • 输出文件:
  • Markdown 报告
  • HTML 报告(若本地已安装渲染器)
  • 输出目录必须由 --data-dir / --output 指定,不能写死固定路径

目录结构

sector-overview/
├── SKILL.md
├── scripts/
│   └── generate_report.py
├── assets/
│   └── template.md
└── references/
    └── data_contract.md

输入文件契约

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

  • sector_definition.json:可选
  • stock_pool.json
  • instrument_meta.json
  • industry_map.json
  • historical_financials.json
  • latest_financials.json
  • roe.json
  • market_cap.json
  • pe_ratio.json
  • pb_ratio.json
  • dividend_yield.json
  • price_period.json
  • benchmark_price.json

这些文件都允许以下结构:

  • { "data": [...] }
  • { "data": { ... } }
  • [...]
  • { ... }

其中:

  • stock_pool.json 定义行业股票池
  • sector_definition.json 推荐用于记录行业名、分类级别、分类来源和基准指数
  • industry_map.json 用于补充一级/二级/三级行业名
  • historical_financials.json / latest_financials.json 用于行业财务结构与同比分析
  • roe.jsonmarket_cap.jsonpe_ratio.jsonpb_ratio.jsondividend_yield.json 用于竞争格局和估值分析
  • price_period.json / benchmark_price.json 用于区间表现与相对收益

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

工作流

步骤 1:准备参数

REPORT_DATE="${REPORT_DATE:-$(date +%F)}"
INDUSTRY_NAME="${INDUSTRY_NAME:-白酒}"
INDUSTRY_LEVEL="${INDUSTRY_LEVEL:-third}"
INDUSTRY_VALUE="${INDUSTRY_VALUE:-白酒}"
INDUSTRY_SOURCE="${INDUSTRY_SOURCE:-citics_2019}"
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=180)).isoformat())
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": ["600519.XSHG", "000858.XSHE"],
        "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(10):
    if has_non_empty_factor(cursor.isoformat()):
        print(cursor.isoformat())
        break
    cursor -= timedelta(days=1)
else:
    raise SystemExit("最近 10 个自然日都未找到非空 market_cap 因子日期")
PY
)"
HISTORY_START_QUARTER="$(python3 - <<PY
from datetime import date
report_date = date.fromisoformat("${REPORT_DATE}")
print(f"{report_date.year - 2}q1")
PY
)"
HISTORY_END_QUARTER="$(python3 - <<PY
from datetime import date
report_date = date.fromisoformat("${REPORT_DATE}")
print(f"{report_date.year}q4")
PY
)"

DATA_DIR="${DATA_DIR:-$HOME/rq_equities_reports/sector_overview}"
OUTPUT_MD="${OUTPUT_MD:-$DATA_DIR/sector_overview_${INDUSTRY_NAME}_${REPORT_DATE}.md}"

步骤 2:生成行业股票池

推荐先产出行业定义文件:

{
  "industry_name": "白酒",
  "industry_level": "third",
  "industry_value": "白酒",
  "industry_source": "citics_2019",
  "benchmark_order_book_id": "000300.XSHG"
}

保存为 $DATA_DIR/sector_definition.json 后执行:

mkdir -p "$DATA_DIR"

rqdata stock cn list --payload "{
  \"date\": \"$FACTOR_DATE\",
  \"type\": \"CS\"
}" --format json > "$DATA_DIR/stock_list.json"

python3 - "$DATA_DIR/stock_list.json" "$DATA_DIR/industry_map.json" "$DATA_DIR/stock_pool.json" <<'PY'
import json
import subprocess
import sys
from pathlib import Path

stock_list_path = Path(sys.argv[1])
industry_map_path = Path(sys.argv[2])
stock_pool_path = Path(sys.argv[3])
definition_path = stock_list_path.parent / "sector_definition.json"
definition = json.loads(definition_path.read_text()) if definition_path.exists() else {}

industry_level = definition.get("industry_level", "third")
industry_value = definition.get("industry_value")
industry_source = definition.get("industry_source", "citics_2019")
if not industry_value:
    raise SystemExit("sector_definition.json 缺少 industry_value")

payload = json.loads(stock_list_path.read_text())
items = payload if isinstance(payload, list) else payload.get("data", [])
order_book_ids = [item["order_book_id"] for item in items if isinstance(item, dict) and item.get("order_book_id")]

industry_rows = []
for start in range(0, len(order_book_ids), 800):
    chunk = order_book_ids[start:start + 800]
    cmd = [
        "rqdata", "stock", "cn", "industry",
        "--payload", json.dumps({
            "order_book_ids": chunk,
            "date": definition.get("factor_date"),
            "level": 0,
            "source": industry_source,
        }, ensure_ascii=False),
        "--format", "json",
    ]
    industry_rows.extend(json.loads(subprocess.check_output(cmd, text=True)))

industry_map_path.write_text(json.dumps(industry_rows, ensure_ascii=False, indent=2), encoding="utf-8")

field_map = {
    "first": "first_industry_name",
    "second": "second_industry_name",
    "third": "third_industry_name",
}
field_name = field_map[industry_level]
selected = [row for row in industry_rows if isinstance(row, dict) and row.get(field_name) == industry_value]
stock_pool_path.write_text(json.dumps(selected, ensure_ascii=False, indent=2), encoding="utf-8")
PY

说明:

  • 脚本会把全 A 股按批查询行业分类,再过滤出目标赛道
  • sector_definition.json 建议额外写入 factor_date,与下游估值/价格查询保持一致
  • factor_date 必须是最近非空因子日,不是“最近交易日”四个字就算完成
  • 如果上游已经有明确成分股,也可以直接提供 stock_pool.json

步骤 3:采集行业财务、估值与价格数据

STOCK_POOL_JSON="$(python3 - "$DATA_DIR/stock_pool.json" <<'PY'
import json
import sys
from pathlib import Path
payload = json.loads(Path(sys.argv[1]).read_text())
items = payload if isinstance(payload, list) else payload.get("data", [])
order_book_ids = []
for item in items:
    if isinstance(item, dict) and item.get("order_book_id"):
        order_book_ids.append(item["order_book_id"])
print(json.dumps(order_book_ids, ensure_ascii=False))
PY
)"

rqdata stock cn instruments --payload "{
  \"order_book_ids\": $STOCK_POOL_JSON
}" --format json > "$DATA_DIR/instrument_meta.json"

rqdata stock cn financial --payload "{
  \"order_book_ids\": $STOCK_POOL_JSON,
  \"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/historical_financials.json"

cp "$DATA_DIR/historical_financials.json" "$DATA_DIR/latest_financials.json"

rqdata stock cn financial-indicator --payload "{
  \"order_book_ids\": $STOCK_POOL_JSON,
  \"factor\": \"return_on_equity_weighted_average\",
  \"start_date\": \"$FACTOR_DATE\",
  \"end_date\": \"$FACTOR_DATE\"
}" --format json > "$DATA_DIR/roe.json"

rqdata stock cn financial-indicator --payload "{
  \"order_book_ids\": $STOCK_POOL_JSON,
  \"factor\": \"market_cap\",
  \"start_date\": \"$FACTOR_DATE\",
  \"end_date\": \"$FACTOR_DATE\"
}" --format json > "$DATA_DIR/market_cap.json"

rqdata stock cn financial-indicator --payload "{
  \"order_book_ids\": $STOCK_POOL_JSON,
  \"factor\": \"pe_ratio\",
  \"start_date\": \"$FACTOR_DATE\",
  \"end_date\": \"$FACTOR_DATE\"
}" --format json > "$DATA_DIR/pe_ratio.json"

rqdata stock cn financial-indicator --payload "{
  \"order_book_ids\": $STOCK_POOL_JSON,
  \"factor\": \"pb_ratio\",
  \"start_date\": \"$FACTOR_DATE\",
  \"end_date\": \"$FACTOR_DATE\"
}" --format json > "$DATA_DIR/pb_ratio.json"

rqdata stock cn financial-indicator --payload "{
  \"order_book_ids\": $STOCK_POOL_JSON,
  \"factor\": \"dividend_yield\",
  \"start_date\": \"$FACTOR_DATE\",
  \"end_date\": \"$FACTOR_DATE\"
}" --format json > "$DATA_DIR/dividend_yield.json"

rqdata stock cn price --payload "{
  \"order_book_ids\": $STOCK_POOL_JSON,
  \"start_date\": \"$PRICE_START_DATE\",
  \"end_date\": \"$FACTOR_DATE\",
  \"fields\": [\"close\"],
  \"adjust_type\": \"post\"
}" --format json > "$DATA_DIR/price_period.json"

rqdata index price --payload "{
  \"order_book_ids\": [\"$BENCHMARK_ORDER_BOOK_ID\"],
  \"start_date\": \"$PRICE_START_DATE\",
  \"end_date\": \"$FACTOR_DATE\",
  \"fields\": [\"close\"]
}" --format json > "$DATA_DIR/benchmark_price.json"

步骤 4:生成 Markdown 报告

python3 sector-overview/scripts/generate_report.py \
  --industry "$INDUSTRY_NAME" \
  --data-dir "$DATA_DIR" \
  --report-date "$REPORT_DATE" \
  --output "$OUTPUT_MD"

兼容旧入口:

python3 sector-overview/generate_report.py \
  --industry "$INDUSTRY_NAME" \
  --data-dir "$DATA_DIR" \
  --report-date "$REPORT_DATE" \
  --output "$OUTPUT_MD"

常用参数:

  • --industry:行业名称,例如 白酒
  • --data-dir:原始 JSON 数据目录
  • --report-date:报告日期,默认当天
  • --output:输出 Markdown 路径
  • --template:自定义模板路径,默认 sector-overview/assets/template.md
  • --no-render:不生成 HTML

步骤 5:渲染 HTML

脚本会优先尝试调用本地安装的 rq-report-renderer,若不存在则回退到仓库内的 report-renderer/scripts/render_report.py;两者都不可用时保留 Markdown 并打印警告。

模板规则

  • 报告必须严格基于 template.md 生成
  • 占位符采用 [[TOKEN]] 语法,不使用 Jinja
  • 当前模板仅允许以下占位符:
  • [[REPORT_DATE]]
  • [[INDUSTRY_NAME]]
  • [[EXEC_SUMMARY]]
  • [[SECTOR_SCOPE]]
  • [[FINANCIAL_STRUCTURE]]
  • [[COMPETITION]]
  • [[VALUATION]]
  • [[PERFORMANCE]]
  • [[OPPORTUNITIES]]
  • [[RISK_SECTION]]
  • [[APPENDIX]]

报告质量要求

  • 完整包含模板中的主章节
  • 行业结论必须基于显式股票池和真实财务/估值/价格数据
  • 不得残留 [XX][公司A][行业机会] 这类占位文本
  • 必须显式说明股票池覆盖数、主导财报季度和集中度
  • 机会筛选不能只列公司名,必须说明估值/盈利/回报依据
  • dividend_yield 原始值单位为 bps,报告中必须换算为百分比后再展示
  • 若市值、ROE、PE/PB 因子整体为空,生成器应直接失败,而不是输出残缺章节

常见错误

  • 在代码里硬写“白酒/新能源/银行”股票池
  • 使用固定 2024q3、固定 2024-12-31
  • 把“最近交易日”误当成“最近非空因子日”,导致估值文件虽有记录却全是空值
  • 继续依赖旧版 utils 或公共 sector_analysis 模块

Related skills

FAQ

Is Rq Sector Overview safe to install?

skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.