SuperAPI AI Directory

quant-buddy-skill

Data & analytics

View repository

Updated 10-15 22:32

About this skill

Guanzhao Quantitative Investment Research

Above-the-fold first: first read the "Platform Tool Parameter Quick Reference," "Hard Rules," and "Scenario Routing" at the front of this document. For high-frequency tasks such as simple market quotes, window series, latest reporting period, fixed-interval returns, and candlestick charts, when a Fast Path is hit, there is no need to continue reading the entire document.

Platform Tool Parameter Quick Reference (high-frequency pitfalls, read this section first)

The table below shows the three schemas that LLMs most easily get wrong. Before any call, verify them first; do not guess parameter names based on what "looks reasonable."

Tool ✅ Correct parameters ❌ Common model errors (already automatically normalized or intercepted by call.py, but should still be avoided)
confirmDataMulti {"data_desc": "市盈率 TTM,股息率"} — comma-separated string {"queries": [...]} / {"query": "..."} / {"names": [...]}
runMultiFormulaBatchStream Reference session intermediate variables in formulas must usedouble quotesto wrap:排序値 = "A股股息率〔估値数据〕" * "条件合并" bare variable names multiplied together:"A股股息率…" * 条件合并 ← the platform directly reports an error
readData {"ids": ["69fe…<24位hex>"], "mode": "last_column_full"} — must be the runMultiFormulaBatchStream returned by data_id field (hex) passing a Chinese variable name {"ids": ["Top10股息"]} / using the wrong parameter name {"index_title": "..."} / {"variable_names": [...]} / pass expression_id instead of data_id(the two are adjacent and easily confused; passing the wrong one returns "error": "IndexInfo {id}")

caliber conversion (confirmDataMulti query term): when the user writes PE(TTM) / 归母净利润 or other English terms or abbreviations, the query term should usestandard Chinese names(such as 市盈率 TTM / 归母净利润), rather than copying the user's original text into data_desc. For detailed rules, see workflows/global-rules.md#指标口径精确匹配。


Hard Rules (violation will definitely fail)

  1. Tool names and the unknown-tool red line (highest priority):

    • The only callable tool name for formula execution:runMultiFormulaBatchStream。
    • Calling or retrying old/wrong names is prohibited:runMultiFormulaBatch / runMultiFormula / run_multi_formula。
    • after any tool returns 未知工具 / Unknown tool / tool not found , for the same-name tool 0 retries, and do not attempt name variants.
    • If the workflow has declared the only correct native tool, only switching to that tool once is allowed; if it still fails, immediately output a controlled failure response.
    • If the result of the previous step is already sufficient to answer the user's question, you must directly converge on the answer; continuing to escalate the tool chain is prohibited.
  2. Post-authentication verification and session initialization:

    • Do not read config.jsonin the first step of an ordinary data query, and do not check .session.json、output/.session*.json or any local session file.
    • As long as this round is preparing to call a platform native tool, directly call the native newSessionfirst; do not use Bash / Glob / Read / ls to probe for session existence.
    • Only when the tool actually returns api_key 为空 / code: 1 / 401/402 should you enter authentication guidance and stop the current data query task.
    • Follow-up questions in the same conversation may reuse the current session; new questions must create a new session.
  3. Native tools take priority; script wrapping is prohibited:

    • When the platform already has native tools, the native tools must be called directly:fast_query、confirmDataMulti、selectByComposition、runMultiFormulaBatchStream、resumeJob、readData、renderKLine、renderChart etc.
    • It is forbidden to use Bash / shell / Python / scripts/call.py / run_skill_script to wrap existing native platform tools.
    • Local scripts may be used only when the platform clearly has no equivalent native tool and the workflow explicitly permits scripts as a fallback.
    • Licensed exception (csv parsing): when fast_query returns mode:"csv" + csv_url(normal delivery for data points > 500), calling python scripts/fetch_fastquery_csv.py "<csv_url>" to download and parse that csv is alicensed path—this is an OSS artifact returned by a consumption tool (the platform has no equivalent native parsing tool), and does not count as "wrapping a native tool". However, it is still forbidden to use bare curl / a self-written temporary script to replace that script.
    • When assets are involved, you still need to first use grep presets/assets_db/{类型}.yaml to search the local asset library; reading the entire file is forbidden; if multiple matches are hit, clarify first; if none are hit, hand it over to the server-side fallback parsing.
    • When an English code has no market suffix, you must first grep the corresponding asset library to confirm the ticker format.
  4. Tool failure circuit breaker: the same type of error must not be repeated

    • After the same tool, same parameter structure, and same error type occur for the 1st time, you may only switch according to the fallback path declared by the workflow; if there is no fallback path, fail in a controlled manner.
    • It is forbidden to repeatedly call a failed tool without new information; it is forbidden to try name variants; it is forbidden to read more documentation instead of executing; it is forbidden to use shell/Python wrappers to bypass a failed tool.
  5. When any workflow exits with failure, a controlled failure reply must be output: it is forbidden to end the conversation with blank content or pure process logs. The failure reply must include:

    • ① the user's original question (restated in one sentence)
    • ② which step the failure is stuck at (tool name + error summary)
    • ③ a one-sentence explanation to the user ("currently unable to obtain..., reason: ...")
    • Optional ④: the next step the user can take (such as "retry later" or "switch to the full pipeline")
  6. Read the workflow before operating: load the corresponding workflow according to the "Scenario Routing" table below, and do not guess the parameter format on your own.

  7. Configuration/authentication errors must stop immediately, and must not be converted into authentication collection in an ordinary data query process:

    • The tool returns an API Key missing error(including api_key 为空 message / code: 1): stop the data query immediately, output thenew user guidance message(for the format, see the template in the "Prerequisites" section), and it is forbidden to continue executing the data query; wait for the user to paste the Key before executing the configuration wizard.
    • Other tool errors(network, server errors, etc.): directly report "internal tool exception", and do not provide authentication-related guidance.
  8. The first sentence of the final answer must be the data conclusion: when answering the user, the first sentence must directly give the data conclusion (such as asset name + value, table, or "there are N matching in total"), and it is absolutely forbidden to start with procedural statements such as "successfully obtained", "data has been obtained", "according to the returned results", or "let me". Violating this rule = the procedural wording must be deleted and the output regenerated.

    • It is forbidden to paste tool JSON as-is: after the tool returns code:0 / success:true , the final reply must convert the data.results and other business fields into human-readable conclusions (one sentence, short table, or list). Unless the user explicitly asks for "give me the raw JSON / debug output", the complete tool response must not be sent to the user as-is.
    • Hide runtime-state fields: the final answer ignores by default code、success、task_id、_quota、skill_latest_version、skill_update_available、skill_update_enforced、skill_self_update、auto_upgrade*、version_check and other runtime/upgrade fields; these fields are only for the Agent to determine the process flow, not answer content for ordinary users to see.
    • Version heartbeats do not interrupt business answers: if the business data has returned successfully, even if the response body carries a version heartbeat, the user's question must still be answered first; only when the tool explicitly returns a business failure or SKILL_VERSION_MISMATCH does it enter the self-healing/troubleshooting process.
  9. User conditions are frozen and must not be rewritten: Before execution, the user's original conditions must be checked word by word; the following rewriting behaviors are all violations (once discovered, must roll back and reconfirm):

    • Converting percentages ↔ decimals(e.g., "dividend yield >3%" is prohibited from being rewritten as >0.03)
    • Converting relative time into a year range(e.g., "the past 10 years" is prohibited from being rewritten as "2015-2025")
    • Replacing the asset universe(e.g., "ordinary stocks" is prohibited from being rewritten as "Wind All A constituent stocks" or "non-ST stocks")
    • Expanding the event scope(e.g., "annual report/semi-annual report" is prohibited from being expanded to all performance disclosure types)
    • Inheriting additional conditions from cards: After a knowledge card is matched, if the card contains additional conditions that the user did not explicitly raise, such as "first-time/non-ST/limit-up/liquidity threshold", they must be deleted first before execution; silently inheriting them into the final answer is prohibited
  10. When the task is ambiguous, ask first; guessing and starting is prohibited: If the user's instruction has 2 or more reasonable interpretations(e.g., "batch confirm X" does not make clear whether it means confirming the index itself or all constituent stocks, and "analyze Y" does not make clear which dimension is wanted),the first step must be to ask the user for clarification, and one interpretation must not be chosen and executed based on speculation. The clarifying question should concisely list the possibilities (e.g., "Do you mean ① … or ② …?"), and continue only after the user confirms.The only exception: The user's semantics are clear and unambiguous (e.g., "give me Guizhou Moutai's closing price today"), so no clarifying question is needed.

    ⚠️ Ambiguous-word handling rules (first determine whether there is true ambiguity, then decide whether to ask or use the default interpretation and proceed):

    The following words have multiple definitions in quantitative semantics and must be handled correctly:

    • Technical analysis type: support level / resistance level / pressure level / neckline level / key level / key point level / breakout level
    • Trend judgment type: trend / trend forecast / outlook judgment / can it still rise / will it fall / short-term view / medium-term view
    • Market characterization type: unusual movement / main force / main-force flow / market maker movement / strong / weak / resistant to decline / decline resistance
    • Health type: whether fundamentals are good / whether valuation is expensive / financial health / how are the results / fundamentals

    Determination process (match in order, stop once hit):

    1. Comprehensive analysis request → use the default interpretation and proceed, clarifying questions that block are prohibited. Determination: The user lists ≥2 analysis dimensions in one sentence (e.g., "fundamentals + technical indicators + trend", "valuation + financials + price action"), or explicitly says "comprehensive analysis / take a holistic look / give me a report". Action: Directly proceed with stockProfile(comprehensive profile) + conventional technical indicators + default trend basis,report first sentenceinform the user of the basis used (e.g., "This output uses the following default basis: fundamentals = comprehensive profile (valuation + financials + capital flow + volatility), technicals = MACD/KDJ/RSI/Bollinger Bands, trend = MA20/MA60 alignment direction. If you need to adjust the basis, please let me know.").

    2. Isolated single-point definitional request → must ask back. Determination: The trigger word appears alone, and its definition directly determines the conclusion value (e.g., "What is Kweichow Moutai's support level", "How is CATL's trend", with no other dimensional context). Action: Ask back ① the definition of the basis (e.g., "support level" = lowest over the past N days / lower Bollinger band / moving average cluster zone); ② the time window; ③ the output format.

    3. Trigger word is merely a modifier → proceed directly. Determination: The user's main request is clear, and the trigger word is only incidental description (e.g., "find stocks with recent fundamental improvement" — the main request is screening, and "fundamental improvement" already implies executable criteria such as "year-over-year increase in revenue/net profit"). Action: Execute using the most common executable basis, and annotate the basis in the results.

    Empirical lesson (T-036): The user asked "Kweichow Moutai support level", and the model arbitrarily used "near the 60-day low" as the definition and executed directly — this is an isolated single-point request and should follow process 2 to ask back. Counterexample (do not repeat): The user asked "analyze East Money's fundamentals, technical indicators, and trend forecast", and the model asked back 4 questions and blocked — this is a comprehensive analysis request and should follow process 1 to proceed directly with the default basis.

  11. When a tool returns SKILL_VERSION_MISMATCH , you must self-heal and must not continue executing the original task: When "error": "SKILL_VERSION_MISMATCH" appears in the output of any tool call, it indicates that the tool signature/parameter format in the current conversation context is outdated. At this point you must execute the following self-healing process (no step may be omitted):

  12. Immediately stopthe current task, and do not call any platform tool again;

  13. Call newSession(create a new session, obtain a new task_id);

  14. Force re-read SKILL.md(this file) + the workflow document corresponding to the current scenario + the involved tools/*.md;

  15. Using thenewly readtool signature and parameter format, re-execute the user's original task;

  16. Prohibitedto ask the user "whether to continue" or explain the version upgrade process — directly and silently complete the self-healing and return the result.

  17. CHANGELOG / skill-changelog serves only as an audit, not as a rule source:CHANGELOG.md、skill-changelog/** is a change record accumulated over time, containing old bases that have been reversed or deprecated by later versions. For any judgment related to "execution order, field names, protocol block semantics, tool signatures, parameter formats",mustuse SKILL.md + workflows/** + tools/** + references/troubleshooting.md as the sole authority; when the CHANGELOG description conflicts with the above files, the above files shall prevail. The CHANGELOG may only be used for: ① reviewing "which version changed what" when troubleshooting; ② producing a version context summary of no more than 5 items after a successful upgrade.Prohibited: Treating a historical narrative in the CHANGELOG as a current execution rule, inferring the current parameter format from the CHANGELOG, or favoring the CHANGELOG when it conflicts with SKILL.md.

  18. Judge tool success or failure by the returned body's code/success, not by the HTTP status code: HTTP 200 does not mean business success—if the body contains "code": -1 / "success": false it is abusiness error, and it must be handled as a failure (read error/message before deciding to retry/adjust parameters/go through the troubleshooting table); it is forbidden to continue onward by treating "HTTP went through as success." Also:call.py returns "error": "INVALID_TOOL_NAME" indicates the tool name is written incorrectly or is missing (the tool name must come first in the command and must be a registered tool name); this is a local error that can be corrected immediately. See references/troubleshooting.md at the top of "General Rules for Success/Failure Determination."

Hard gate at the top of Fast Path / Leaf workflow (takes effect every time a leaf is entered)

Fix the issue in T-001 / T-011 / T-024 and other leaves where newSession is not treated as the first mandatory step, skipping it and directly calling platform tools.

Regardless of routing into fast-snapshot / fast-window / fast-report-period / render-kline / any leaf workflow:

  1. before preparing to call any platform-native tool (fast_query / renderKLine / stockProfile / selectByComposition / runMultiFormulaBatchStream / readData / downloadData / getCardFormulas / searchFunctions / searchSimilarCases / confirmDataMulti / scanDimensions / uploadData / renderChart / refreshSnapshotTime / resumeJob),you must first call newSession。
  2. It is not allowedto exempt this article by saying "since SKILL.md has been read, skip newSession" or "since the leaf workflow has been read, skip newSession"; this rule does not depend on whether the leaf restates it again.
  3. Follow-up questions in the same conversation may reuse the current session; but a new user question (including an obvious topic switch) must be re- newSession, and in the parameters set user_query to the original text of the new question.
    • It is recommended to also pass agent_model: fill in the model identifier you (the current Agent) are using as the parameter for newSession (for example, gpt-4o / claude-sonnet-4 / gemini-2.5-pro etc., using your actual runtime model name), so the backend can tally on this session the model currently used by the user.If unsure, leave it blank; do not fill it in randomly(a wrong model name is worse than none).
  4. Skipping newSession and directly calling platform tools = MISSING_NEW_SESSION contract failure (HIGH level); points will definitely be deducted in scoring.

Minimal Sufficiency Principle (self-check before any action)

By default take the narrowest path; only after receiving evidence of "clearly insufficient" should you expand the scope.

Before each time you prepare to read a file, call a tool, or expand the reading scope, answer three questions:

  1. What is the specific problem this step is meant to solve? — It must be expressible in one sentence as "in order to do X, do Y," where X is aalready occurredneed; it cannot be "X might be needed," "just in case," or "prepare it first."
  2. Is there a narrower option that can accomplish the same X? — A more downstream output / a more concise file / fewer fields / not calling this tool and directly constructing it.
  3. If the current choice fails, what is the next step? — If you cannot answer, it means you have not thought it through and are already taking action.

If any answer is vague → do not take this step.

The only legitimate trigger for expanding the scope: The previous tool explicitly returned "missing data / field does not exist / failed", and the reason for the failure can be traced. It is not allowed to use "for more comprehensiveness", "for more accuracy", or "to avoid omissions" as reasons.

This principle covers: whether to read one more document; which variable readData reads; whether to call confirmDataMulti for a certain field; whether to write a formula yourself or look up an existing dataset; and all similar decisions that arise in the future.

Implementation at the tool level: Before calling confirmDataMulti / readData / runMultiFormulaBatchStream or loading extra documents, you must mentally complete the tool checklist self-check;Do not search, load, or read recipes/tool-call-checklist.mdin order to execute the checklist. Regardless of whether the file is already in context, just mentally complete the following three minimal self-checks (these three are already a condensed version of the checklist, and there is no need to consult the original text again):

  1. Does this call directly serve the user's current question?
  2. Is there a narrower output or fewer fields that can be read?
  3. If the call fails, is the next step clear and does it change only one dimension?

The top-level principles govern "whether to do it", and the checklist governs "specifically how to do it".

Skill package root directory

The directory where this SKILL.md is located is the skill root directory (SKILL_ROOT), and all relative paths below are based on this. All terminal commands must first cd to this directory before execution.

SKILL_ROOT/
├── config.json              ← API Key 配置(按需读取;非每题必读)
├── SKILL.md                 ← 本文件(入口 + 路由)
│
├── workflows/               ← 业务流程编排(路由目标)
│   ├── fast-snapshot.md         Fast Path:最新时点行情/估值(≤1000资产,标量/CSV)
│   ├── fast-window.md           Fast Path:最近N日序列/窗口统计(≤2500日)
│   ├── fast-report-period.md    Fast Path:最近报告期财务(≤1000资产)
│   ├── quick-lookup.md          快速查数路由器 + 共享基础规则
│   ├── quick-snapshot.md        最新时点行情/估值快照(字段齐即停)
│   ├── quick-window.md          最近N日短窗序列/窗口统计
│   ├── quick-report-period.md   最近报告期财务指标
│   ├── period-return-compare.md 固定区间累计涨跌幅对比
│   ├── stock-profile.md         单股预计算指标画像
│   ├── composition-select.md    已物化维度组合选股(selectByComposition 快路径)
│   ├── global-rules-lite.md     精简全局规则(quick-window/period-return-compare 专用)
│   ├── quant-standard.md        选股/回测/因子/图表标准流程
│   ├── event-study.md           事件研究(给定或可识别事件后的窗口表现)
│   ├── regime-segmentation.md   阈值区间/连续阶段识别与区间统计
│   └── render-kline.md          K线图渲染与交付
│
├── recipes/                 ← 公式模板 & 工具用法(被 workflow 引用)
│   ├── ma-crossover-backtest.md     均线金叉策略
│   ├── value-pe-strategy.md         PE估值选股
│   ├── upload-custom-data.md        上传自有数据
│   ├── render-chart.md              渲染图表
│   ├── download-data.md             下载数据
│   └── industry-aggregation.md      行业聚合排名
│
├── references/              ← 参考文档
│   ├── environment.md           环境依赖
│   ├── troubleshooting.md       故障排查
│   └── ru-billing.md            RU 计费
│
├── tools/                   ← API 工具完整参数文档(默认不读;workflow 标注「必读」或报错时再查)
│   │                           ⚠️ 下表列出所有可用工具的**实际调用名**,调用时必须使用此名,不得变体
│   ├── fast_query.md            → 工具名 `fast_query`          快速合并查询(行情/估值/财务,≤1000资产,支持CSV)
│   ├── confirm_data_multi.md    → 工具名 `confirmDataMulti`    批量确认数据项存在性与维度(写公式前必查)
│   ├── run_multi_formula.md     → 工具名 `runMultiFormulaBatchStream`  执行公式批次(选股/回测/因子计算)
│   ├── read_data.md             → 工具名 `readData`            读取公式计算结果(需传 data_id,非 expression_id)
│   ├── render_kline.md          → 工具名 `renderKLine`         渲染 K 线图(直接传 ticker,无需提前跑公式)
│   ├── stock_profile.md         → 工具名 `stockProfile`        单股预计算指标画像(估值/财务/资金/波动/走势)
│   ├── select_by_composition.md → 工具名 `selectByComposition` 已物化维度组合选股/筛选(不走公式引擎)
│   ├── render_chart.md          → 工具名 `renderChart`         渲染折线/柱状/面积图(需先有 data_id)
│   ├── get_card_formulas.md     → 工具名 `getCardFormulas`     按卡片名拉取完整公式组(量化场景使用)
│   ├── scan_dimensions.md       → 工具名 `scanDimensions`      九维度 IC 扫描(单股多维度预测力分析)
│   ├── search_similar_cases.md  → 工具名 `searchSimilarCases`  向量检索相似案例(设计策略前的 fallback 查找)
│   ├── search_functions.md      → 工具名 `searchFunctions`     检索平台函数名称与调用格式
│   ├── download_data.md         → 工具名 `downloadData`        按 data_id 下载一维时序到 CSV/JSON
│   ├── upload_data.md           → 工具名 `uploadData`          上传自有因子 CSV,上传后可在公式中引用
│   ├── refresh_snapshot_time.md → 工具名 `refreshSnapshotTime` 强制刷新分钟数据截止时间(盘中实时场景)
│   ├── resume_job.md            → 工具名 `resumeJob`           续传 deferred 后台任务(配合 research_24h 使用)
│   └── formula_package.md       → 脚本 `scripts/formula_package.py` 注册公式组为「任务包」→ 凭 package_id+signature 无 key 取数(对外只读/前端页面接入)
│
├── presets/                 ← 已验证的常用数据(按需加载)
│   ├── cases_index.yaml         106 张案例卡片目录(量化标准场景必读,快速查数无需)
│   ├── assets.yaml              常用资产(99 行精选,可一次读完)
│   ├── assets_db/               全量资产字典(按类型分文件,⚠️ 仅 grep 检索,禁止 read_file 整文件;不含指数成分股映射)
│   │   ├── stock_a.yaml             A 股 5540 条(SH/SZ,含场内 ETF)
│   │   ├── stock_hk.yaml            港股 2862 条(HK 前缀;行情优先,财务以 fast_query 返回为准)
│   │   ├── stock_us.yaml            美股及境外ETF 1068 条(.N/.O/.A;行情优先,财务以 fast_query 返回为准)
│   │   ├── index.yaml               指数 503 条
│   │   └── future.yaml              期货 257 条
│   ├── functions.yaml           常用函数
│   ├── data_catalog.yaml        常用数据集
│   ├── dimensions.yaml          已物化维度目录(score/screen 指标,用于 selectByComposition)
│   ├── sectors.yaml             行业板块
│   └── themes.yaml              题材板块
│
├── scripts/                 ← 执行脚本
│   ├── call.py                  工具统一入口(所有命令通过它调用)
│   ├── executor.py              call.py 的底层(禁止直接调用)
│   ├── formula_package.py       公式任务包客户端(register/query/list/revoke/refresh,取数走 SSE)
│   ├── quant_api.py             Python SDK(供其他脚本 import)
│   ├── auth/                    认证脚本
│   └── eval/                    评测脚本
│
└── output/                  ← 输出目录(自动创建)
    ├── .session.<key>.json      当前 session task_id(按 QBS_SESSION_KEY 派生,多会话隔离)
    ├── ic_data/                 IC 扫描结果
    └── *.png / *.csv            图表和数据文件

Global 429 handling (applicable to all paths):

error.code Handle
RATE_LIMIT_EXCEEDED / CONCURRENT_LIMIT Read retryAfter seconds latersilently retry, without exposing it to the user
WINDOW_QUOTA_EXCEEDED stop immediately, read references/troubleshooting.md quota throttling section, output a prompt
DAILY_QUOTA_EXCEEDED / DAILY_SCAN_EXCEEDED stop immediately, output:⚠️ 今日额度已满,次日 00:00 重置。
SERVICE_OVERLOADED(503) retryAfter silently retry once after N seconds; if it still fails, tell them "the system is busy, please try again later"

⛔ Execution order (must-read before routing, all scenarios must comply)

No matter which leaf workflow is matched, the execution order is fixed as:

① read_skill_file(global-rules 版本,见下表)  →  ② read_skill_file(leaf workflow)  →  ③ 执行

Step ① Global rule file selection (determined by the target leaf workflow):

Target leaf workflow File read in step ①
fast-snapshot.md None (Fast Path, skip step ① and execute directly)
fast-window.md None (Fast Path, skip step ① and execute directly)
fast-report-period.md None (Fast Path, skip step ① and execute directly)
quick-window.md workflows/global-rules-lite.md
period-return-compare.md workflows/global-rules-lite.md
All other workflows workflows/global-rules.md
  • Step ① is a hard prerequisite. After determining the target leaf, first select and read the corresponding global-rules version according to the table above, then read the leaf workflow, and finally execute.
  • Fast Path (fast-*.md) starts directly from step ② and does not need step ①.

Scenario routing

First identify the user's intent and determine the target leaf workflow; then load according to the execution order above:

Scenario Trigger words Target leaf workflow
Latest point-in-time quotes / valuation (snapshot) Latest price, today's close, latest change percentage, current turnover rate, latest PE/PB/market cap… Fast Path conditions are met → read only fast-snapshot.md; if not met / unable to query → global-rules.md → quick-snapshot.md
Recent N-day series / window statistics Last 5 days, last 20 days, last N trading days, window high/low/amplitude... (single asset only, last N days) Fast Path conditions met → read-only fast-window.md; not met/unable to query → global-rules-lite.md → quick-window.md
Latest reporting period financials Revenue, net profit, net profit attributable to parent, ROE, total assets, total liabilities, debt-to-asset ratio... Fast Path conditions met → read-only fast-report-period.md; not met/unable to query → global-rules.md → quick-report-period.md
Single-stock indicator profile / individual stock comprehensive analysis Analyze stock XX, take a look at stock XX, stock profile, indicator overview, comprehensive look at valuation, financials, capital flows and trends, how are the fundamentals and valuation... global-rules.md → stock-profile.md
K-line chart (visualization) K-line chart, draw a chart, image, with volume chart... (user explicitly requests a visual artifact) global-rules.md → render-kline.md
Fixed-interval cumulative return From A to B, from a certain year/month to a certain year/month, interval return, cumulative return, interval performance, multi-asset interval comparison global-rules-lite.md → period-return-compare.md
Data download / export local CSV Download as CSV, export to local, save to local, download historical data global-rules.md → recipes/download-data.md; single-asset single-field time series takes priority runMultiFormulaBatchStream → downloadData → write_skill_file, Bash fallback prohibited
Materialized dimension stock selection / dimension score TopN / recommended stocks Highest score, highest composite score, dimension score, recommend/select/filter TopN, and semantics can match presets/dimensions.yaml score/screen indicators in global-rules.md → composition-select.md(newSession → read presets/dimensions.yaml → selectByComposition)
Quantitative stock selection / backtesting / factors / charts / upload & download Stock selection, backtesting, moving averages, PE stock selection, factors, net value, upload CSV, download data, draw charts...; or the directory has no matching dimension and temporary indicators/historical curves/custom formulas need to be constructed global-rules.md → quant-standard.md
Directly run the user-specified formula chain file "Run/run through/execute all formulas in this file", "formula chain file", "formula chain", "run according to this md/json" global-rules.md → run-formula-chain.md
Event study Review, past occurrences, price increases, rate cuts, rate hikes, event window, subsequent performance, above expectations, below expectations, post-policy performance... (given event or event date needs to be identified first) global-rules.md → event-study.md
Threshold interval statistics / continuous phases Past occurrences, each time, average, drawdown exceeding, decline from high exceeding, bear market interval, continuous phases, regime global-rules.md → regime-segmentation.md
Publish formula groups externally / build data retrieval pages / register task packages Register formula package, package_id, signed data retrieval, make a page/dashboard that can be opened directly, frontend real-time data retrieval, external read-only API, third-party integration tools/formula_package.md + recipes/formula-package.md(using scripts/formula_package.py, not a platform-native tool)

Upload, download, and drawing charts are not independent scenarios—they are sub-steps within a workflow; the workflow document will guide you to read the corresponding recipes/。

Routing hard exclusions (take priority over trigger word matching)

The following rules are checkedbeforetrigger word matching; a match forces rerouting and must not be overridden by trigger words:

User intent characteristics Prohibited entry Forced redirect Basis for judgment
Intraday/real-time/current/now/today/today/on that day + query intraday quotes (gain rankings, limit up, intraday declines, etc.) quick-snapshot quick-window quant-standard.md(Prefer matching the minute-frequency card) requires the dedicated formula for the minute-frequency card;use_minute_data: true Already the global default
Intraday/realtime/current/today/today's/on the day + whole market/sector + TopN/ranking/threshold list/stock selection/screening/signal quick-snapshot quick-window quant-standard.md → preferentially hits the "realtime cross-sectional TopN ranking" or "intraday threshold screening_list query" micro-workflow this type of high-frequency short question has a dedicated closed micro-workflow
gives explicit start and end dates, and only asks about cumulative return/performance over the interval event-study quick-window quant-standard period-return-compare.md essentially a fixed-interval return comparison, not causal window analysis, nor a complex quantitative workflow
industry/sector aggregate ranking (e.g. "Top 5 Shenwan industry gainers") quick-window quick-snapshot quant-standard.md requires cross-sectional aggregation, not a single-asset series
threshold-triggered discrete event identification (e.g. "the number of times the decline exceeded X%", asking about performance after each occurrence) — event-study.md(threshold trigger mode) requires first identifying threshold event days, then performing window analysis
defines continuous intervals by threshold conditions (e.g. "past bear markets", "stages with drawdown exceeding 30%") event-study regime-segmentation.md studies continuous stages rather than windows after discrete events
"hits a new N-day high/low" (excluding the modifier "for the first time") must not add the "not satisfied yesterday" condition bycurrent statejudgment (state check); the formula only compares the current value with yesterday's N-day extremum only when the user explicitly says "first breakout/first breakdown", "newly entered", or "first time today" is it allowed to add a first-trigger condition; see quant-standard.md

judgment mnemonic:

  • has explicit start and end dates + only asks about interval values → period-return-compare(fixed-interval return comparison)
  • has an event + asks about "performance in the following N days/months" → event-study(causal window)
  • has threshold conditions + asks about "performance after each occurrence" → event-study(threshold trigger mode)
  • has threshold conditions + asks about "performance within a continuous stage/interval" → regime-segmentation(continuous stage statistics)

if the user's request satisfies any of the following patterns, it should preferentially be judged as a [quick data lookup task] and routed directly according to the following routing, without first entering any other workflow:

Fast Path conditions (Fast Path can be taken only if both of the following are satisfied at the same time; otherwise take the full pipeline):

  • all target fields belong to the fast_query whitelist (price/valuation/financial/derived/fund flow · northbound-southbound holdings/commodity spot · inventory fields, see tools/fast_query.md), and do not involve custom formulas/stock selection/ranking
  • not a whole-market cross-sectional query (not scenarios such as "whole-market ranking/top N/industry screening")

the number of assets no longer limits Fast Path routing (the server supports ≤1000 assets). When there are more than 500 data points, the server automatically returns CSV format (OSS download link), see tools/fast_query.md rate limiting and CSV mode section.

quick data lookup routing (judged in order of priority, stopping at the first match):

  1. the user is asking for an open-ended single-stock comprehensive indicator overview (e.g. "analyze XX stock", "take a look at this stock XX", "stock profile", "indicator overview", "take a comprehensive look at valuation, financials, funds, and trends"), and is not only asking about a single field/an explicit window/IC predictive power → workflows/global-rules.md → workflows/stock-profile.md
  2. The time anchor is a "recent N-day window/sequence", or the user explicitly gives start and end dates and requests a range sequence (e.g. "the daily ... trend/sequence/data from day X to day X"), or the user only says "recent trend/view trend" but does not explicitly ask for a chart/candlestick chart → when the Fast Path conditions are met, read workflows/fast-window.md, otherwise workflows/global-rules-lite.md → workflows/quick-window.md; if N is not given, default to the most recent 20 trading days
  3. The time anchor is the "most recent reporting period" and the fields are financial → when the Fast Path conditions are met, read workflows/fast-report-period.md, otherwise workflows/global-rules.md → workflows/quick-report-period.md
  4. The user explicitly asks to "draw a chart / candlestick chart / image / chart with volume" → directly load workflows/render-kline.md
  5. All others (clearly the most recently completed trading day's or the current day's quotes/valuation/multi-asset comparison, anddoes not include ranking/screening/whole-market semantics) → when the Fast Path conditions are met, read workflows/fast-snapshot.md, otherwise workflows/global-rules.md → workflows/quick-snapshot.md

    Note: contains "today/this day/current/now/realtime/intraday" but only queries single-asset quote fields, which belongs to the intraday refresh scenario,fast_query snapshot has automatically enabled intraday refresh (equivalent to use_minute_data: true), and should go directly through the Fast Path; the "hard routing exclusion" above has already blocked "today + whole market/sector + ranking/screening", so there is no need to repeat the exclusion here.

The above routing does not require first reading workflows/quick-lookup.md。

Key red lines quick reference (must be followed even if global-rules.md has not been read)

The following 4 rules are excerpted from global-rules.md,have the highest priority, and apply to all scenarios:

  1. Event definition freezing: the event type/scope mustmatch the user's original wording verbatim. If the user says "annual report/semi-annual report", then only query annual reports and semi-annual reports, and do not expand to earnings forecasts/flash reports/quarterly reports; if the user says "State Council or Ministry of Housing and Urban-Rural Development", then only include that level, and do not expand to the central bank/CBIRC/local governments. If you believe the user's definition may have omissions, at the end of the answersuggestexpanding it, but do not expand it without authorization.
  2. evidence-only answers: the final answer outputs only the numerical values, dates, rankings, and definition notes directly supported by this round's tool results. Without tool verification, it is forbidden to output macro attribution, policy attribution, or directional judgments by default ("usually", "often", "slightly positive").
  3. De-processed delivery: it is forbidden to use process-oriented phrases such as "successfully obtained", "let me", "according to the process", "Step 1/2/3", "according to the workflow"; it is forbidden to leak _working/ paths, checkpoint names, or workflow file names. Answer as soon as the result is found, and do not show the internal process.
  4. Condition definition freezing: user conditions must be executed as-is, and any rewriting is forbidden (percentages ↔ decimals, relative time → year ranges, asset universe substitution, card additional condition inheritance). See hard rule No. 8 for details.

Trigger word reference:

  • Analyze XX stock / take a look at this stock XX / stock profile / indicator overview / take a comprehensive look at valuation, financials, capital, and trend → stock-profile
  • Most recent trading day's close / latest disclosed PE / latest market cap (not intraday, not screening) → quick-snapshot
  • Most recent 5 days / most recent 20 trading days / recent N-day sequence / window high and low → quick-window
  • Revenue / net profit / ROE / total assets / total liabilities / debt-to-asset ratio → quick-report-period

Forbidden:

  • Prioritize calling scanDimensions、renderKLine(unless the user explicitly wants to see a chart)
  • First perform analytical expansion, then supplement structured numerical values
  • Before reading the corresponding leaf workflowDirectly call runMultiFormulaBatchStream / renderKLine / scanDimensions / stockProfile / Output "Unable to connect to the internet" or "Unable to obtain real-time data"
  • Asset has uniquely matched presets/assets_db/future.yaml , statically output "The platform does not support futures/options" or "Futures cannot be queried"; you should first try according to the market/window series toolchain, and after failure only state according to the tool's return that the current instrument or field is temporarily unavailable
  • Silently inherit the card's additional conditions (first-time/non-ST/limit-up/liquidity threshold, etc.) into the final answer
  • Using description、samples, preview rows, and truncated large tables aslist-type question's complete result and directly concluding (the complete list must be extracted or incompleteness explicitly stated)

The leaf workflow's final answer contract takes priority: the "final answer contract" in the leaf workflow is responsible first for tightening the output format of that scenario; if the leaf workflow has already met the stopping conditions, it must output directly according to that contract and must not further explain the internal process.

Execution authority authorization rules

Rule hierarchy (from high to low):

  1. SKILL.md: routing + global gatekeeping (10 hard rules, routing hard exclusions)
  2. global-rules.md: global contracts that all leaves must comply with (execution contract, evidence grading, concise answer mode, no precision supplementation, method limitation explanation, parameter specification, numerical precision, final answer consistency check)
  3. leaf workflow: the specific execution flow for the current task (checkpoint, template, stopping conditions, formatting)

Conflict resolution:

  • Specific rules in the leaf workflow (such as readData mode selection) take priority over general rules in global-rules
  • But the leaf workflow must notrelax the red lines of global-rules (such as the evidence grading threshold and the principle of no precision supplementation)
  • Must not borrow templates, fallbacks, or answer formats from other leaf workflows

The positioning of quick-lookup.md:

  • Serves only as the routing entry point and general rule reference table for the quick-lookup subflow
  • Each leaf workflow is already self-contained with all execution rules, and there is no need to return to quick-lookup.md during execution
  • quick-lookup.md does not define any leaf-specific rules

Global execution rules

See the global contract for details at workflows/global-rules.md, which automatically takes effect when entering any leaf workflow. A leaf workflow may add stricter constraints internally, but must not exempt or relax the rules in global-rules.

Platform data coverage scope

✅ Supported ⚠️ Conditionally supported ❌ Not supported (will not be supported in the short term)
A-share individual stocks (Shanghai and Shenzhen Main Board/ChiNext/STAR Market/Beijing Stock Exchange) ETF / LOF / off-exchange funds (first grep the local asset library; if uniquely matched, execute normally; only if not matched, inform that it is not supported); futures quotes/window series (first grep presets/assets_db/future.yaml, and after a unique match try the quote fields according to the tool's return; valuation/financials/K-line charts are not promised) Options
Hong Kong individual stocks (HK + code, such as HK0001) Taiwan stocks / Korean stocks / Japanese stocks / German stocks and other overseas markets
U.S. individual stocks (NASDAQ: code.N; NYSE: code.O; AMEX: code.A)
Major broad-based indices (CSI 300, CSI 500, Wind All A, etc.)

Hong Kong / US stock data scope limitations:

  • Market price types(closing price, opening price, highest price, lowest price, change percentage, trading volume, trading value): A / HK / US are all supported.
  • Valuation types:
    • A/US/HK:PE/PE_TTM/PB/PS_TTM/股息率/PCF/总市值(Hong Kong and US stocks use TTM [valuation data], daily frequency, automatically mapped on the server side)
    • A-shares only:流通市值/换手率
    • PE (static): A-shares use static PE, Hong Kong and US stocks are automatically mapped to the TTM version
    • Single-quarter basis:PE_单季/PB_单季/PS_单季/股息率_单季 can still be used for explicit queries of quarterly-frequency data
  • Financial types(operating revenue/net profit/net profit attributable to parent, etc.): A / HK / US are all supported (via the fast_query interface);ROE is A-shares only。
  • Capital flow / northbound-southbound holdings types(fast_query snapshot/window,Non- report):
    • A-shares only:主力资金净额/主力资金净占比、超大单/大单/中单/小单 净额·净占比(main force = extra-large orders + large orders)
    • A-shares only:北向持股比例(陆股通持股比例)/北向持股市值(quarterly/sparse after 2024-08)
    • Hong Kong stocks only:南向持股比例/南向持股市值(daily frequency)
    • Use dynamic parsing (not whitelist, full name required): northbound/southbound "top 10 active stocks by trading value"
    • Not supported: northbound/southbound "capital trading value · trading volume · net buying" (market-level one-dimensional series, no individual stock dimension) — should use confirmDataMulti + readData, rather than fast_query。
  • Commodity futures types(fast_query snapshot/window, A-share futures varieties only, units vary by variety):
    • Futures quotes 收盘价/开盘价/最高价/最低价: units vary by variety (silver yuan/kg, rebar yuan/ton, gold yuan/gram…)
    • 现货价格(basis, mostly yuan/ton),商品库存/库存按发布日(units vary by varietyinferred, with STOCK_UNIT_INFERRED warning)
    • Query using futures ticker (e.g. RB.SHF);when units diverge by variety fields_meta[字段].unit_per_asset=true, units are pushed down to each asset value ({v, unit}), when reading values prioritize the asset inline unit
  • When querying Hong Kong/US stocks, if a field is not within the above supported scope, you should proactively inform the user rather than silently skipping it.

Stock code format quick reference

Market Format Example
A-shares - Shanghai Stock Exchange SH + code SH600000
A-shares - Shenzhen Stock Exchange SZ + code SZ000001
Hong Kong stocks HK + code HK0001
US stocks - NASDAQ code.N AAPL.N
US stocks - NYSE code.O AAL.O
US stocks - AMEX code.A SBE.A

Asset confirmation failure (circuit breaker rules) see workflows/quick-lookup.md § Step 1。

Environment dependencies (Python version, Playwright, API Key) → references/environment.md Troubleshooting → references/troubleshooting.md RU billing → references/ru-billing.md


Prerequisites (execute as needed, not the default first step for simple data queries)

Credential storage note: this skill's quant-buddy API Key is only stored in the skill directory's config.json 's api_key field, environment variables are not used (QUANT_BUDDY_API_KEY environment variables will not be read). Only the optional BOCHA_API_KEY(event news search) goes through environment variables.

Only in the following situations is it necessary to explicitly read config.json check api_key:

  • The current round actually needs to call a local script or platform tool, and a usable session has not yet been established in the current environment
  • A previous round of tool calls already produced a 401 / 402 / explicit authentication error
  • The workflow explicitly requires executing a script chain (such as local Python script rendering)

For simple data-query questions that already hit a leaf workflow (quick-snapshot / quick-window / quick-report-period / render-kline):

  • Do not read extra items just for formal completeness config.json
  • Prefer to execute directly according to the leaf workflow
  • Only when an explicit authentication problem occurs in a tool call, return to the authentication wizard

Principle: authentication checks serve execution and should not become a fixed extra step for simple questions.

  • If api_key is non-empty → continue normally

  • If api_key is empty → stop immediately, prohibit continuing to query data, and output the followingnew user guidance message(output verbatim, no omissions allowed):


    ⚠️ API Key has not been configured yet, data cannot be queried currently.

    Go to https://www.quantbuddy.cn/login to log in/register and obtain an API Key, then send it directly to me:

    Help me configure APIkey: sk-xxxxxxxx



Configuration wizard (user pastes Key)

When the user message contains sk- a string starting with:

  1. Extract from the user message sk- the complete Key string starting with
  2. Write the Key into config.json the api_key field (use replace_string_in_file to write directly)
  3. must output: "✅ API Key configured successfully!"
  4. Automatic retry: If in this conversation there is a query interrupted by an api_key missing error (such as when the user previously asked about market quotes),first call newSession(using the original user question as user_query) to create a new session, then immediately re-execute that query and give the data conclusion; the user does not need to initiate it again.

Runtime 401/402 → stop immediately, and prompt the user that the API Key is invalid/expired/quota exhausted; please go to the official website again to obtain a new Key and reconfigure it.


Tool invocation method

All tools are invoked through scripts/call.py .call.py will simultaneously print the result to stdout and write it to a temporary file.

Standard invocation (completed in one step)

python scripts/call.py <工具名> '{"key":"value"}'

The result is obtained directly from stdout. If stdout is truncated, you can read back /tmp/gzq_out.txt。

Parameters can also be passed via environment variables (suitable for scenarios where parameters contain special characters):

GZQ_PARAMS='<JSON>' python scripts/call.py <工具名>

Prohibited items

Prohibited Reason
Creating a custom .py to write a parameter file The environment variable solution has already resolved the encoding problem
Directly calling scripts/executor.py call.py encapsulates logic such as renderChart automatic saving
echo pipeline parameter passing (Windows) GBK encoding truncates Chinese
Passing JSON via command-line arguments (Windows) PS eats the double quotes

Division of labor among the three directories presets/, recipes/, and tools/

Directory What it is When to read
presets/ Local snapshot of the platform's actual return values (YAML). Asset names, function formats, dataset index_title, industry/concept names, etc.Directly usable in formulas, eliminating confirmation-type API calls. Check the preset before writing a formula; if not found, call the corresponding API and add the new result back to the preset.cases_index.yaml cases_index.yaml is read only whenquantitative standard scenarios such as stock selection/backtesting/factors/charts(quant-standard.md(quant-standard.md) begin; quick data-query scenarios (quick-snapshot/window/report-period) do not need to read it.
recipes/ End-to-end usage examples (Markdown). Show complete scenarios—from parameter preparation to final output. Loaded under the guidance of the workflow at specific steps (not triggered independently).
tools/ API parameter manual (Markdown). Fields, types, and constraints for each tool. Not read by default. Check again only when the workflow tool table marks it as "required reading" or an error occurs.

In short: presets are data snapshots, recipes are complete tutorials, and tools are the parameter dictionary. Detailed usage and loading timing of the 6 preset files → the "Preset Resources" table in the current workflow document.


Skill update and deployment specification (required reading for LLM)

When the user requests an update to this skill (sending a zip archive), the following rules must be strictly followed:

Backup location

⚠️ The backup directory must not be placed under the skills/ directory. Otherwise openclaw will also recognize the backup as an independent skill, causing subsequent requests to possibly mistakenly use the old code.

Correct approach:

# 备份到 skills/ 之外的位置
cp -r ~/.openclaw/workspace/skills/quant-buddy-skill ~/.openclaw/workspace/quant-buddy-skill-backup-$(date +%Y%m%d%H%M)

# ❌ 错误:备份仍在 skills/ 下
# cp -r ~/.openclaw/workspace/skills/quant-buddy-skill ~/.openclaw/workspace/skills/quant-buddy-skill-backup-xxx

Extract and overwrite

# 解压到临时目录再拷贝(避免嵌套)
TMPDIR=$(mktemp -d)
unzip -o <压缩包路径> -d "$TMPDIR"
# 如果解压出嵌套目录 quant-buddy-skill/,取内层
if [ -d "$TMPDIR/quant-buddy-skill" ]; then
  cp -rf "$TMPDIR/quant-buddy-skill/"* ~/.openclaw/workspace/skills/quant-buddy-skill/
else
  cp -rf "$TMPDIR/"* ~/.openclaw/workspace/skills/quant-buddy-skill/
fi
rm -rf "$TMPDIR"

Check after deployment

  1. Confirm that under ~/.openclaw/workspace/skills/ there is only quant-buddy-skill/ one directory related to this skill
  2. Read SKILL.md to confirm the version number
  3. Keep the existing config.json in api_key(if the user has authenticated before)