name: quant-strategy-assistant description: "量化策略助手:自然語言→策略生成→回測→最佳化→QMT模擬/實盤。三輪互動閉環。" metadata: requires: bins: ["python3"] openclaw: requires: bins: ["python3"]
相容說明:本文件既是 OpenClaw Skill,也可作為任意 AI Agent 的操作手冊。只要 Agent 能讀取檔案、執行命令、生成程式碼,即可按下方協議使用。YAML 頭部的
metadata.openclaw為 OpenClaw 平臺專用欄位,其他 Agent 忽略即可。
回測三輪互動閉環 → 使用者按需選擇引數最佳化 / 模擬實盤。
| 能力 | 引擎 | 依賴 | 說明 |
|---|---|---|---|
| CTA回測 | vnpy_ctastrategy | python3 + qgdata | 單標的擇時策略,任意平臺 |
| Portfolio回測 | vnpy_portfoliostrategy | python3 + qgdata | 多標的組合/輪動策略,任意平臺 |
| 引數最佳化 | vnpy OptimizationSetting | 同回測 | 回測後由使用者觸發,窮舉/遺傳演算法 |
| 模擬/實盤 | miniQMT + vnpy CTA引擎 | QMT 交易端 | qmt-check 檢測 → trade 啟動自動交易,含探針單驗證 |
回測是核心能力,不依賴 QMT。使用者請求模擬/實盤時才執行 qmt-check。
| 條件 | 模式 | 策略基類 |
|---|---|---|
| 單一標的 + 無組合關鍵詞 | cta |
CtaTemplate |
| 以下任一條件滿足 | portfolio |
StrategyTemplate(vnpy_portfoliostrategy) |
portfolio 判定規則(分層,LLM 和 parse_requirement() 均遵循):
1. 強訊號(任一齣現即 portfolio):輪動/組合/多標的/全市場/等權/倉位分配/前N名
2. 弱訊號 + 多標的上下文(二者共現才 portfolio):弱訊號 排序/篩選/選股/調倉/排列/持倉週期 需同時存在多標的上下文(板塊/成分股/指數/行業/概念/股票池)
3. 標的數量 > 1:--symbols 含 2 只以上自動 portfolio
注意:"多頭排列"中的"排列"、"均線排序"在單標的場景不觸發 portfolio。
路由由 parse_requirement() 自動判定並寫入 parsed["mode"],agent 生成策略程式碼時必須使用對應基類。
Portfolio 引擎驅動約束:Portfolio 回測引擎僅支援 DAILY 和分鐘級驅動。周級策略用 --interval DAILY,在 on_bars(bars) 中按 list(bars.values())[0].datetime.weekday()==0(週一)判斷調倉日;周線指標直接用 pro.weekly() 獲取,無需從日線合成。
股票池所有權契約(強制):股票池由 --symbols 引數唯一定義 → 引擎載入資料 → 策略通過 self.vt_symbols 接收。策略程式碼 __init__ 中禁止覆蓋 vt_symbols,必須使用引擎傳入的列表。所有標的程式碼使用 vnpy 格式(600519.SSE/000858.SZSE),不可使用 qgdata 格式(.SH/.SZ)。選股邏輯在 on_bars(bars) 中基於 self.vt_symbols 遍歷和篩選。
板塊/指數成分股由引擎自動解析(強制):使用者說"人工智慧板塊"/"滬深300成分股"/"銀行行業"等時,引擎會自動解析出完整成分股列表到 --symbols。策略程式碼中禁止自行呼叫 pro.ths_member()/pro.ths_index()/pro.dc_member() 等板塊 API。
回測日期約束(強制):使用者的回測日期意圖必須由你轉換為標準 --start YYYYMMDD --end YYYYMMDD 引數。例如使用者說"最近1年"則根據當天日期計算 today-365 輸出對應日期。使用者未提及任何日期時,不傳 --start/--end(引擎預設最近1年,即 today-365 ~ today)。第1輪確認摘要中日期欄必須寫"引擎預設最近1年"而非自行編造"近2年"等。禁止編造與使用者意圖不符的固定日期。
使用者提及 模擬/實盤/模擬交易/開始交易/QMT 時觸發。前提:至少有一次成功的回測(status=completed)。
第 1 步:環境檢測(自動發現 QMT 路徑,無需使用者手動配置路徑)
小蔥技能有更好的技能skills外掛。
"${PYTHON_BIN}" "${QUANTCLAW_ROOT}/backtests/pipeline_orchestrator.py" qmt-check
輸出 JSON 含 ready(布林)和 hint(狀態說明):
- platform != Windows → 提示使用者在 Windows + QMT 環境執行
- QMT 路徑自動掃描失敗 → 提示確認 QMT 已安裝
- QMT 終端未執行 → 提示"請先開啟 QMT 並以極簡模式登入"
- 缺少資金賬號 → 提示通過 --account-id 或 QMT_ACCOUNT_ID 提供
- ready=true → 進入第 2 步
第 2 步:啟動交易(內含自動探針驗證:100股跌停價掛單→確認→撤單,可選單獨跑 probe --symbol {程式碼} --account-id {賬號})
"${PYTHON_BIN}" "${QUANTCLAW_ROOT}/backtests/pipeline_orchestrator.py" trade \
--run-id "{最近成功回測的 run_id}"
返回 JSON 分流:
- status=trading_started → 告知使用者:✅ 交易已啟動,附帶日誌路徑
- status=platform_redirect → 告知使用者:需在 Windows + QMT 環境執行,給出命令
- status=error → 告知具體錯誤
第 3 步:停止交易(使用者說「停止交易」時)
"${PYTHON_BIN}" "${QUANTCLAW_ROOT}/backtests/pipeline_orchestrator.py" trade-stop --run-id "{run_id}"
僅需使用者提供 資金賬號(--account-id 或 QMT_ACCOUNT_ID);QMT 路徑自動掃描各磁碟機代號下 userdata_mini 目錄(可通過 QMT_PATH 覆蓋)。
| 專案 | 值 |
|---|---|
| 專案根目錄 | QUANTCLAW_ROOT(相容 QMT_PROJECT_ROOT) |
| vnpy_qmt原始碼 | $QUANTCLAW_ROOT/vnpy_qmt |
| 策略輸出 | $QUANTCLAW_ROOT/strategies/ |
| 回測輸出 | $QUANTCLAW_ROOT/backtests/ |
| 回測資料來源 | qgdata(建議預先配置 QGDATA_TOKEN) |
| 實盤交易 | miniQMT (xt_gateway.py),需 QMT 交易端已啟動 |
| Python直譯器 | PYTHON_BIN(預設 python3) |
回測預設引數:capital=1000000 / rate=0.0003 / slippage=0.01 / size=1 / pricetick=0.01
配置指南: https://gitee.com/GuojinQuant/quant-claw#第四步配置環境變數 (倉庫自帶 .env.example)
關鍵變數(優先從 .env / 環境變數自動推導,不需要寫死):
- QUANTCLAW_ROOT:專案根目錄(相容 QMT_PROJECT_ROOT)
- MONITOR_PUBLIC_BASE:監控公網基址(可留空;OpenClaw 環境下可由 OPENCLAW_CONTROL_URL 自動推導)
- ORCH_MONITOR_PORT_CANDIDATES:白名單埠(預設 8767,必須在防火牆放通)
- QGDATA_TOKEN:資料 Token(可選;未配置時自動使用內建共享試用Token,有每日額度限制)
Token 自動提取規則(強制):若使用者對話中出現 60~70 位連續字母數字串(如"我的token是 Mj9mN2xP..."),自動提取並通過 --token 引數傳給 submit 命令。日誌和回覆中只顯示前 6 位+***,絕不回顯完整 Token。提取到個人 Token 後提示使用者:已使用您的個人Token,不消耗共享試用額度。
"${QUANTCLAW_ROOT}/backtests/pipeline_orchestrator.py"。.html/.png/.json),只使用 orchestrator 的 status 命令輸出獲取結果。${QUANTCLAW_ROOT}/strategies/ 目錄。status + error + next_action,禁止只說"失敗了"不給下一步。qmt-check 檢測。回測、策略、自動編排、均線、上穿、下穿、買入、賣出 → 進入三輪互動協議開始生成、生成策略、好、開始、繼續、1(或任何第1輪確認後的使用者訊息);若同條訊息同時包含完整需求+第2輪觸發詞,直接視為已確認並進入第2輪最佳化、調參、引數最佳化、網格搜尋 → 執行 optimize(回測完成後觸發)模擬、模擬盤、模擬交易、開始交易、實盤、實盤交易、QMT → 執行 qmt-check + trade(獨立流程,不走三輪協議)執行 Skill 內建預檢指令碼(scripts/preflight.py,相對於本 Skill 目錄)。指令碼內部使用 sys.executable 自適應直譯器,直接呼叫即可:
Linux/macOS:
python3 "<本Skill目錄>/scripts/preflight.py"
Windows PowerShell:
python "<本Skill目錄>\scripts\preflight.py"
輸出 JSON,按欄位消費:
- ready=true → 取 engine_root 作為 QUANTCLAW_ROOT,進入第 1 輪
- ready=false + engine_found=true → 依賴缺失,向用戶展示 blockers 和 fix_cmd
- ready=false + engine_found=false → 引擎未找到,返回 status=config_missing + 配置指南連結。禁止降級為手動指令碼。
- hints 非空 → 非阻塞提示(如 Token 狀態),向用戶如實展示
- 預檢通過後可選執行 doctor_cmd 做深度配置診斷(埠/Token/公網等)
退出碼:0=就緒 1=引擎未找到 2=依賴缺失可修復
編排器指令碼內建路徑回退(Path(__file__).parents[1]),即使環境變數未設定,只要找到指令碼就能正常執行。
目標:理解使用者意圖,確認關鍵引數,引導進入程式碼生成輪。
"${PYTHON_BIN}" "${QUANTCLAW_ROOT}/backtests/data_capability_guard.py" \
--requirement "{使用者原始需求}"
data_capability_guard 輸出含 token_hint(非空字串),必須在確認摘要之後、引導詞之前如實告知使用者。這表示檢測到 Portfolio 策略 +(未傳 Token 將回退共享試用 Token / 正在使用共享試用 Token)的組合,資料呼叫量大可能觸發頻率限制。直接呈現 token_hint 內容即可,不要包裝為廣告需求已確認:{標的} / {模式cta或portfolio} / {日線/分鐘線} / {做多/做空} / {回測區間或"引擎預設最近1年"}
{若有token_hint則在此呈現,無則省略此行}
請回復「開始生成」,我來為你生成策略程式碼並提交回測。
第 1 輪禁止:不做程式碼生成、不呼叫 submit、不建立檔案。
第 1 輪最多命令:data_capability_guard.py(1條)。
觸發:第 1 輪確認後,使用者傳送任意訊息(開始生成/好/1 等);若同條訊息同時包含完整需求+第2輪觸發詞,也可直通第2輪。
直通首響(強制):直通第2輪時先立即回覆一句 已收到,開始生成中...,再執行程式碼生成與提交,避免長時間無反饋。
第 2 輪速度約束(強制):
- 禁止重跑 data_capability_guard(第 1 輪已檢查)
- 禁止單獨跑 py_compile(submit 內部已含編譯+靜態檢查+冒煙測試)
- 理想路徑 2 次工具呼叫:① 寫策略檔案 ② submit
- submit 同步等待預檢(compile→lint→dryrun,通常 10~60 秒)再返回結果:
- 預檢通過 → 返回 status: "accepted" + monitor_url(回測已在後臺執行)
- 預檢失敗 → 返回 status: "lint_error"/"compile_error"/"dryrun_error" + error + strategy_file(不返回 monitor_url)
- 預檢失敗時 在 Round 2 內立即修復:
1. 先告知使用者當前情況(如"檢測到 import 路徑錯誤,正在自動修復..."),保持透明
2. 讀 error + strategy_file → 修復程式碼 → 重新 submit
3. 最多 6 輪修復重試,超過交由使用者決策
- submit 返回 accepted 後若回測執行時/超時/資料失敗 → 已有 monitor_url,在第 3 輪處理
parsed["mode"] 選擇正確模板:cta → 繼承 CtaTemplate,on_bar(self, bar),self.buy(price, vol) / self.sell(price, vol),self.pos,初始化用 self.load_bar(N)(單數,N=bar 數量)portfolio → 繼承 StrategyTemplate(vnpy_portfoliostrategy),on_bars(self, bars: dict),self.buy(vt_symbol, price, vol) / self.sell(vt_symbol, price, vol),self.get_pos(vt_symbol),初始化用 self.load_bars(days)(複數,days=天數)load_bars,Portfolio 策略禁止用 load_barself.available_cash 動態計算最大可買手數)fixed_size = 100 或任何硬編碼固定股數作為預設倉位(這是 vnpy 教程示例值,不是真實交易邏輯)python
vol = int(self.available_cash / (bar.close_price * 1.0003)) // 100 * 100 # 主機板100股整數倍
if vol >= 100:
self.buy(bar.close_price, vol)python
per_capital = self.available_cash / max(len(target_symbols), 1)
vol = int(per_capital / (bar.close_price * 1.0003)) // 100 * 100
if vol >= 100:
self.buy(vt_symbol, bar.close_price, vol)self.available_cash — 可用現金(買入扣減,賣出回款)self.total_value — 賬戶總值(現金+持倉市值)self.closable_pos — CTA可賣數量(T+1 自動扣減當日買入)self.closable_positions — Portfolio per-symbol可賣量dict(self.closable_positions.get(vt_symbol, 0))self.capital — 等於 available_cash(相容)self.trade_calendar — 交易日曆(set of "YYYYMMDD"),可用 date_str in self.trade_calendar 判斷交易日self.last_order_status — 最近一次下單結果({"ok":True/False,"reason":"...","symbol":"..."})self.order_reject_log — 最近200條被拒訂單記錄(停牌/漲跌停/資金不足等)buy()/sell() 返回值(空列表=被拒),而非假設一定成功am.sma(),禁止用 am.ma()(vnpy 不存在此方法)on_bar 開頭呼叫 am.update_bar(bar):否則 ArrayManager 永遠不會 inited,導致全程 0 交易。引擎有執行時兜底但不能依賴${QUANTCLAW_ROOT}/strategies/{module_name}.pyPortfolio 輪動策略速查(減少生成思考時間):
- 周輪動:on_bars(self, bars) 中 list(bars.values())[0].datetime.weekday()==0 判斷週一調倉
- 排序選股:遍歷 self.vt_symbols 計算因子 → sorted() → 取前N名
- 等權全倉:每隻 self.available_cash / N,按交易所規則取整手
- 周線資料:pro.weekly(ts_code=code, start_date=..., end_date=...) 直取,無需從日線合成
"${PYTHON_BIN}" "${QUANTCLAW_ROOT}/backtests/pipeline_orchestrator.py" submit \
--requirement "{使用者原始需求}" \
--strategy-file "${QUANTCLAW_ROOT}/strategies/{module_name}.py" \
--strategy-module "{module_name}" \
--strategy-class "{class_name}" \
--symbols "{策略中所有vt_symbol逗號分隔}" \
--monitor-public-base "${MONITOR_PUBLIC_BASE:-}" \
--monitor-port-candidates "${ORCH_MONITOR_PORT_CANDIDATES:-8767}" \
--timeout-sec 1200
status: "accepted" + monitor_urlstatus: "<error_type>" + error + strategy_file,不啟動回測、不返回 monitor_urlagent 判斷 submit 輸出:
status == "accepted" → 進入步驟 3(回覆使用者)status 為 compile_error/lint_error/dryrun_error → 先輸出一句話告知使用者(如"檢測到 xxx 錯誤,正在修復第 N/6 次...")→ 讀 error + strategy_file → 修復程式碼 → 重新 submit(最多 6 輪)回覆使用者(僅在 submit 返回 accepted 後):
run_id + monitor_url + 當前狀態觸發詞:檢視結果、結果、status、重新生成
"${PYTHON_BIN}" "${QUANTCLAW_ROOT}/backtests/pipeline_orchestrator.py" status --run-id "{run_id}"
| status | 處理 |
|---|---|
running |
告知當前進度,提示繼續等待 |
completed |
輸出摘要 + 強制輸出 report_url,不用 monitor_url 表述完整報告 |
failed |
根據 last_error.error_type 分流處理(見下方錯誤分流表) |
| error_type | 含義 | agent 策略 |
|---|---|---|
compile_error |
py_compile 失敗 | 讀 strategy_file + traceback → LLM 修復程式碼 → 重新提交 |
lint_error |
靜態檢查 blocker(如 am.ma()、vnpy.trading 匯入) | 同 compile_error 處理 |
dryrun_error |
冒煙測試失敗(50根K線取樣回放執行時異常) | 同 compile_error 處理:讀 strategy_file + traceback → LLM 修復 → 重新提交 |
runtime_error |
回測執行時異常 | 讀 strategy_file + traceback → LLM 分析修復 → 重新提交 |
compat_error |
引擎相容性(如 portfolio+WEEKLY 未降級) | 提示使用者調整引數,通常不應出現(parse_requirement 已自動降級) |
data_error |
資料載入失敗/為空 | 提示使用者檢查標的程式碼/日期範圍/token |
config_error |
環境/配置問題 | 提示使用者檢查配置 |
timeout_error |
超時 | 建議縮短日期範圍或標的數量 |
compile_error、lint_error、dryrun_error 和 runtime_error 嘗試自動修復,其餘直接報告使用者。3.5 結果校驗告警(status=completed 時優先檢查):
status 輸出中若包含 result_warnings 欄位(非空列表),說明回測結果校驗發現語義異常:
- 讀 result_warnings + strategy_file → LLM 分析是否為策略 bug
- 若判斷為 bug → 修復策略程式碼 → 重新提交
- 若判斷為正常行為(如趨勢策略在熊市期間無反向訊號)→ 照常輸出結果,附帶告警說明
常見告警型別:零交易、單邊訊號(有買無賣/有賣無買)、勝率極端值(100%/0%)。
回測已完成,{摘要}。您可以:
1. 回覆「最佳化引數」對策略引數進行網格搜尋
2. 回覆「模擬交易」在 QMT 中啟動自動交易(需 Windows + QMT 環境)
觸發詞:最佳化、調參、引數最佳化、網格搜尋
前提:已完成至少一次回測(資料已快取在資料庫中)。
sharpe_ratio,可選 total_return/annual_return/max_ddpercent)[起始, 終止, 步長])預估組合數
執行最佳化:
"${PYTHON_BIN}" "${QUANTCLAW_ROOT}/backtests/pipeline_orchestrator.py" optimize \
--strategy-file "${QUANTCLAW_ROOT}/strategies/{module_name}.py" \
--strategy-class "{class_name}" \
--symbols "{vt_symbol}" \
--start "{YYYYMMDD}" --end "{YYYYMMDD}" \
--optimize-params '{"target":"sharpe_ratio","params":{"fast_window":[5,30,5],"slow_window":[10,60,10]}}'
支援 "algorithm":"ga" 使用遺傳演算法(大引數空間時推薦)。
展示結果:輸出 JSON 含 best(最優引數+指標)和 results(Top N),agent 以表格形式呈現。
後續選擇:使用者可選擇用最優引數重新回測驗證,或繼續調整引數範圍。
.html 報告檔案reports/ 目錄下的歷史檔案backtest_runner.py、monitor_server.py、/api/codepython -m http.server 或任何臨時 HTTP 服務[run_id][N/M][狀態]QUANTCLAW_ROOT)strategies/ 目錄之外這個 Skill 質量不錯,功能很全面,能把自然語言想法自動生成策略程式碼並回測。文件寫得很詳細,風險提示也很充分,資料介面豐富。不足之處是互動流程稍顯複雜,新手需要花時間理解;部分檔案較多較碎,找資料時容易迷路。如果你有一定量化基礎或願意學習,這是一款值得使用的量化助手。