quant-buddy-view · 量化看板發布
把「在 quant-buddy-skill 裡探索得到的指標」沈澱成一個公開可分享的網頁看板。本技能不做行情查詢/回測探索(那是 quant-buddy-skill 的職責),只負責三件事:
- 註冊公式任務包(
formula_package)—— 把一組公式 + 各產出的讀取模式註冊到服務端,拿到package_id+signature。底層數據更新後服務端自動重算,取數永遠是最新結果。 - 生成看板 HTML(
build_dashboard)—— 用一份 spec 描述「哪些產出、用什麼圖表/表格展示」,編譯成一份 live 即時取數 HTML(骨架自包含、數據打開時即時取)。 - 發布託管(
static_page)—— 把 HTML 上傳到對象存儲,得到https://pages.quantbuddy.cn/...公開鏈接。
何時用本技能 vs quant-buddy-skill
- 探索/一次性查詢("茅臺今天漲跌幅"、"跑個均線金叉回測看看")→ 用 quant-buddy-skill。
- 要一個能反覆看、能發給別人、數據會自動更新的頁面 → 探索清楚後切到 quant-buddy-view。
前置依賴:需要先裝 quant-buddy-skill
本技能運行時自包含(註冊/生成/發布只憑 config.json 的 api_key,不依賴 quant-buddy-skill 的代碼)。
但正常使用流程裡有一道硬門檻:註冊公式包前,每組公式必須先在 quant-buddy-skill 裡用 runMultiFormulaBatchStream 跑通確認出數(見下方「註冊前硬規則」)。因此沒有裝 quant-buddy-skill 就無法正確完成公式驗證這一步。
如果尚未安裝 quant-buddy-skill,按以下優先級安裝:
-
優先:GitHub 安裝(
npx skills) —— quant-buddy-skill 與本技能同屬 GitHub 倉庫pseudo-longinus/quant-buddy-skills:# 全新安裝(從未裝過) npx skills add pseudo-longinus/quant-buddy-skills -g --all # 已裝過、只是要更新 npx skills update pseudo-longinus/quant-buddy-skills -y # 裝在哪 / 是否裝上,自檢: npx skills list -g --jsonWindows 上若 symlink /
EPERM報錯,命令末尾追加--copy重試。安裝路徑通常是~/.agents/skills/quant-buddy-skill。 -
兜底:下載 zip 壓縮包手動解壓(無 node/npx、或網路受限時)——下載官方
quant-buddy-skillzip,解壓覆蓋到 skills 目錄下的quant-buddy-skill/(先解壓到臨時目錄,若內含嵌套quant-buddy-skill/取內層;保留已有config.json的 api_key)。quant-buddy-skill 自帶scripts/self_update.py,支援--url/--zip-path+--sha512+--version做校驗解壓,優先用它。
放置佈局:讓 quant-buddy-skill 與 quant-buddy-view 同級並列:
<skills 目錄>/
quant-buddy-skill/ ← 探索 / 公式驗證(runMultiFormulaBatchStream、confirmDataMulti)
quant-buddy-view/ ← 本技能:註冊公式包 / 生成看板 / 發布
這個同級佈局是推薦佈局:
formula_package import(遷移舊憑證)找不到顯式路徑時,正是按「同級../quant-buddy-skill」兜底定位的。
- 配置:在 quant-buddy-skill 裡配好它自己的 api_key(與本技能各自獨立)。裝好後即可在那邊驗證公式,再回到本技能
register。
老用戶遷移:已在舊版 quant-buddy-skill 裡註冊過的公式包無需重註冊——用 python scripts/formula_package.py import ... 一次性把憑證導入本技能即可繼續用舊 package_id 取數(詳見 tools/formula_package.md 的「從舊 quant-buddy-skill 遷移憑證」)。
入口選擇(先判斷類型)
Agent 路由規則:用戶提到模板市場 / 官方模板 / 公共模板 / 已發布模板 → 先用
scripts/static_page.py templates/template讀取線上公共模板;從template返回的download_url直連 OSS 下載 HTML,替換標的、文案、公式包憑證後,再upload成用戶自己的頁面。用戶要一個具體頁面形態但未指公共模板 → 先看本地examples/(線上模板的離線兜底和模板開發源);用戶要從需求做到鏈接 → 看workflows/;用戶要複雜自定義頁面或遷移舊 HTML → 看guides/。
| 類型 | 展示名 | 入口 | 什麼時候用 |
|---|---|---|---|
| 頁面模板 | 個股速覽 | examples/single-stock/ | 單標的的畫像頁:閱讀摘要 + 最新價/漲跌幅/20日/60日/PE/PB/成交額數字卡 + 價格主圖;必須從 spec.template.json 起步 |
| 頁面模板 | 個股估值體檢 | examples/valuation-financial-profile/ | 單標的的估值財務頁:PE/PB/PCF 歷史水位、財務趨勢、現金流質量、估值變動歸因;配套 page.template.html |
| 頁面模板 | 成分股異動榜 | examples/index-anomaly/ | 指數/股票池成分股異動監控:異動榜單 + 漲跌分佈 + 指數走勢;配套 page.template.html,深色盤面、data-kernel 取數 |
| 頁面模板 | 多因子選股看板 | examples/multi-factor-screener/ | 主題股票池 + 多因子評分 + TopN 榜單 + 回測/rankIC + K 線 + 公式審計;固定角色 RANK / BACKTEST / KLINE_*,RANK 首屏優先渲染 |
| 頁面模板 | 商品多空日報 | examples/commodity-daily/ | 商品期貨日報:板塊多空主導矛盾 + 今日異動 + 頭部品種 sparkline;配套 page.template.html |
| 通用流程 | 標準即時看板 | workflows/dashboard-end-to-end.md | 用戶要“做成可分享看板/鏈接”,但沒有指定固定頁面模板 |
| 開發指南 | 自定義頁面 | guides/bespoke-page.md | build_dashboard 做不出的自定義 HTML/CSS/SVG 頁面,或遷移已有 HTML |
| 遷移工具 | 舊頁套公共外殼 | tools/retrofit_share_shell.md | 已發布/已生成 HTML 需要去掉舊二維碼、舊頁頭、舊頁尾,並保留同一個 page_id 更新 |
硬規則:用戶要“某隻股票/指數畫像頁、個股畫像、單股畫像、單標的的頁面”時,先讀
examples/single-stock/README.md,複製examples/single-stock/spec.template.json作為 spec 起點,保留template: "single-stock"。不要手寫舊版“1 條價格線 + 4 個數字卡”的最小 spec;build_dashboard會拒絕這種舊骨架。 硬規則:用戶問“這隻股票貴不貴 / 基本面是否改善 / 估值與財務畫像 / PE/PB歷史水位 / 財務趨勢 / 現金流質量”並要求做成落地頁或公開鏈接時,先讀examples/valuation-financial-profile/README.md,複製examples/valuation-financial-profile/page.template.html起步,驗證並註冊該模板要求的一套公式包;不要退回普通single-stock卡片頁。 硬規則:用戶要“某指數 / 某股票池 的成分股異動、異動榜、龍虎榜式排行”(如「中證500今天哪些股票異動」「滬深300異動監控」「上證50漲跌幅榜」)時,先讀examples/index-anomaly/README.md,複製examples/index-anomaly/page.template.html起步,替換__INDEX_*__佔位並內聯data-kernel.js再發布;不要手寫一份離題的淺色/通用 HTML。 硬規則:用戶要“主題股票池 / 概念股 / 行業池 + 多因子評分 / TopN / 回測 / rankIC / K線 / 公式審計”的選股工作台頁面時,先讀examples/multi-factor-screener/README.md,複製examples/multi-factor-screener/page.template.html起步;公式包角色固定為RANK/BACKTEST/KLINE_*,RANK必須首屏優先渲染,BACKTEST和KLINE_*允許局部降級。 硬規則:複用公共模板時,模板 HTML 裡的package_id + signature屬於模板原作者;必須按當前用戶目標重新驗證公式、註冊自己的公式包,並替換頁面裡的憑證後再發布。不要把公共模板原憑證直接當成用戶頁面的數據來源。 硬規則:單標的的畫像頁的subtitle和“閱讀摘要”只能使用build_dashboard構建期即時取數結果(最終 outputs)對應的數值。若腳本返回“文案與即時取數結果不一致”,按返回的facts重寫文案後再生成/上傳,不要沿用舊查詢結果或手工估算。 硬規則:所有落地頁必須接入assets/share-shell/公共組件。模板只負責主體內容和getPosterData(),頁頭、頁尾、刷新按鈕、分享海報彈層、複製鏈接、複製/下載 PNG 和海報固定頁頭頁尾都由公共 shell 提供;不要在單個模板裡私自複製或改造舊二維碼塊、舊刷新按鈕或舊分享彈層。 硬規則:分享海報由公共poster.js默認前端截圖頁面主體生成,寧缺毋濫;模板可用data-qb-poster-target標記核心截圖區域,getPosterData()只提供標題/摘要和結構化兜底候選,不要依賴 Agent 手寫海報版式,也不要把整頁內容塞進sections。 硬規則:用戶要“改造已經生成的 HTML / 去掉二維碼 / 去掉當前頁頭頁尾 / 適配固定頁頭頁尾”時,優先使用scripts/retrofit_share_shell.py。不要靠長提示詞讓 Agent 手工刪 DOM;默認保留舊頁面主體 hero 區域,只移除其中的二維碼卡片和舊頁尾,然後在body頂部/底部直接插入公共頁頭頁尾;先生成本地遷移版驗證,再用update:true覆蓋同一個page_id。
-
註冊公式任務包(
scripts/formula_package.py register)formulas:一組"變量名 = 表達式"(沿用 quant-buddy-skill 探索時驗證過的公式)。reads:對外產出清單,每條聲明output(產出名)+read_mode(讀取模式)。- 成功返回
package_id+signature,並自動落盤到output/formula_packages/<package_id>.json。 - ⚠️
signature只在註冊時明文返回一次,本地憑證丟失即不可恢復(可refresh輪換)。
-
生成看板(
scripts/build_dashboard.py)- 寫一份 spec:
title+panels[],每個 panel 把某個output渲染為line/bar/table/number/text/raw。 - 若命中頁面模板,先複製模板目錄裡的
spec.template.json或page.template.html,再替換資產、日期、解讀文案和可選模塊。 - 頁面是即時取數的(見下「取數:即時取數」),spec 裡不用寫
mode。 - 產物默認寫到
output/pages/<slug>.html;傳"upload": true可一步生成並發布。
- 寫一份 spec:
-
發布 / 管理(
scripts/static_page.py)upload:上傳 HTML → 返回page_id+ 公開url;可帶title(缺省取<title>)和description(頁面說明,≤1000 字,列表/詳情展示用)。update:替換已發布頁面的內容,URL / page_id 不變(頁面已分享後想補充/調整時用,訪問者刷新即見新內容,不佔新配額)。也可只改title/description(description傳空串""清空,不傳保留原值)。download:取回已發布頁面的 HTML 再編輯(鑑權拿 url → 直連 OSS 下載,不佔服務端頻寬),改完update覆蓋。list/revoke:列出 / 撤銷我的頁面(活躍頁上限 200,單頁 ≤ 2MB)。thumbnail:給某個已發布頁面設置 / 替換一張純展示封面圖(直傳 PNG/JPG,≤2MB)。只用於列表/詳情/模板牆的<img>預覽,不進入 HTML、不影響取數、不佔活躍頁配額;按 page_id 命名存 OSS,轉模板後仍有效。upload/update可帶thumbnail_file,HTML 成功後再自動上傳封面;縮略圖失敗只返回 warning,不回滾 HTML。templates/template:瀏覽 / 複用公共模板——templates列模板(普通用戶只見 published),template看某模板詳情拿download_url,直連 OSS 取回 HTML,換成自己的標的/文案/公式包後再upload成自己的頁。upload/update發布前會強制檢查公共 share shell;缺公共頁頭/頁尾會自動插入並編譯,主題色只能透過theme/--qb-shell-*變數覆蓋,仍有佔位符或舊二維碼殘留則拒絕發布。- 權限 / 權責:自己的頁面默認僅本人;
is_test用戶可跨 download / update / thumbnail 其他 is_test 用戶頁面、list傳scope=test_all看全部 test 用戶(普通用戶頁面一律FORBIDDEN)。公共模板瀏覽/複用對全員開放(普通用戶唯讀 published);模板的提交/改寫/上下線僅 is_test,把已有頁轉公共模板是後台(growthX)動作——本 skill 側只「讀取 + 複用」模板,不做這些寫操作。
認證只靠
config.json的api_key(query 取數連 api_key 都不需要,憑 package_id + signature)。本技能不維護會話 / task_id。
取數:即時取數
看板是即時取數的:HTML 內嵌 package_id + signature,訪問者打開頁面時即時調用 queryFormulaPackage 拉取最新數據並渲染——底層數據更新即自動重算,頁面打開就是最新,這正是公式任務包的設計目的。spec 不需要寫 mode 字段。
- 頁面是"活"的:數據不焊進 HTML,運行時即時取;構建期只取一次數做質量體檢(數據健康 + 單標的的文案一致性),不內聯。
- 兩個前提(均已滿足):①
queryFormulaPackage端點對頁面域名pages.quantbuddy.cn放開 CORS(當前 https 端點已放開*);②signature隨頁面公開(公式包 query 本就以 signature 作能力令牌、設計上允許嵌入頁面)。 - ⚠️ 協議必須一致:頁面發布在
https://,config.json的endpoint也必須是https://,否則瀏覽器會以 mixed-content 攔截取數。當前 endpoint 已是https://www.quantbuddy.cn/skill。
硬規則
- 中文參數走 @file 或環境變數:Windows PowerShell 命令列直接傳中文會被 GBK 截斷。註冊公式、寫 spec 一律用
@params.json(UTF-8)或FP_PARAMS/BD_PARAMS/SP_PARAMS環境變數。 - 公式必須先驗證再註冊(硬門檻):提交註冊的每一組公式,必須先在 quant-buddy-skill 裡用
runMultiFormulaBatchStream跑一遍並確認出數(公式語法兩邊一致,可原樣驗證),跑成功才允許register。不要憑空發明未驗證的表達式,也不要"直接註冊、錯了再說"——註冊時的服務端試讀只是兜底,不替代這一步。 - 驗證參數也要換乾淨:調用
runMultiFormulaBatchStream時,user_query必須反映當前用戶請求和當前資產;若傳task_id必須為本次新任務。複製示例時不能只替換formulas,卻留下“貴州茅臺 factsheet”等舊user_query,否則後台審計和回放會被污染。 - signature 是憑證:不要打印到面向最終用戶的對話裡;看板會把它寫進公開 HTML 供即時取數,發布前確認可接受。
- 失敗要說清:腳本返回
code != 0時,向用戶複述「卡在哪一步(命令名)+ 錯誤摘要」,不要以空白或純日誌結束。
工具一覽
參數約定:所有腳本參數是一個 JSON 字串位置參數(或
@params.json/ 環境變數),如list '{"scope":"test_all"}'。命令列也兼容--scope test_all/--key=value直覺寫法(僅簡單參數;公式、spec 等複雜結構仍走@file/環境變數以免 GBK 截斷)。
| 腳本 | 命令 | 作用 | 文檔 |
|---|---|---|---|
scripts/formula_package.py | register / query / list / revoke / refresh | 公式任務包:註冊取數能力,憑包憑證流式取數 | tools/formula_package.md |
scripts/build_dashboard.py | (單命令) | spec → live 即時取數看板 HTML | tools/build_dashboard.md |
scripts/compile_bespoke_page.py | (單命令) | 【shell 處理腳本】 bespoke 模板 → 內聯公共 share shell / logo / qr-mini / data-kernel 的自包含 HTML | guides/share-shell.md |
scripts/retrofit_share_shell.py | (單命令) | 【shell 處理腳本】 舊 HTML/已發布頁面 → 刪除舊二維碼/舊頁頭/舊頁尾,套入公共 share shell(assets/share-shell/),可原鏈接 update | tools/retrofit_share_shell.md |
scripts/static_page.py | upload / update / download / list / revoke / thumbnail / templates / template | 發布/替換/下載/管理靜態頁,得到公開鏈接(update 替換內容不換鏈接;download 取回 HTML 再編輯;thumbnail 設展示封面;templates/template 瀏覽複用公共模板;is_test 可跨用戶) | tools/static_page.md |
scripts/verify_page.mjs | (單命令) | 發布前/發布後頁面驗收:1440px、390px、320px 視口,h1、佔位符、橫向溢出、控制台核心錯誤 | — |
scripts/render_cover.py | (被 build_dashboard 調用) | 封面柵格化與合成兜底:capture_page_cover 用系統 Edge/Chrome 無頭截"封面模式頁"為整頁 PNG;合成封面(全幅裸圖/品牌海報)走 瀏覽器 → 純 Python(cairosvg/svglib) → SVG 三層兜底。跨平台、零強依賴,不影響 HTML 發布 | — |
scripts/render_existing_page_thumbnail.py | (單命令) | 給已發布/公共模板 HTML 補封面:下載或讀取 HTML → 解析內嵌公式包憑證 → 先取真實 outputs 並臨時替換 QB.query → 再用系統 Edge/Chrome 截 1200×675 PNG;可帶 upload:true 直接設置 thumbnail_url | tools/static_page.md |
assets/data-kernel.js | (前端內核,非腳本) | 手搓 bespoke 頁共用的「取數 + 清洗 + 容錯」一份;內聯進頁面 <script> 用 | guides/bespoke-page.md |
assets/share-shell/ | (公共組件) | 所有落地頁共用的頁頭、頁尾、刷新按鈕、分享海報彈層、海報 canvas、複製鏈接與複製/下載行為 | guides/share-shell.md |
examples/valuation-financial-profile/page.template.html | (離線參考模板,非腳本) | 個股估值體檢:估值水位、財務趨勢、估值天平歸因 | examples/valuation-financial-profile/README.md |
examples/index-anomaly/page.template.html | (離線參考模板,非腳本) | 成分股異動榜:異動榜單、漲跌分佈、指數 sparkline | examples/index-anomaly/README.md |
examples/commodity-daily/page.template.html | (離線參考模板,非腳本) | 商品多空日報:多空主導、異動榜、板塊條、sparkline | examples/commodity-daily/README.md |
兩條生產路:標準看板走
build_dashboard(聲明式快路);要自定義版式/SVG 的設計頁則手搓 HTML, 數據層統一調assets/data-kernel.js(QB.query取數、QB.series/lastValue/topValues解包清洗),別再每頁各抄fetch/解包、各踩"假 0/缺口"的坑。見 guides/bespoke-page.md。 發布前用scripts/verify_page.mjs <html_file>檢查桌面與 390px/320px 行動端,確保無QB_SHARED_/replace_with_signature/pkg_replace殘留、存在<h1>、無關鍵橫向溢出和核心取數腳本錯誤。
配置
config.json:填入 api_key(從 https://www.quantbuddy.cn/login 取得),或設環境變數 QUANT_BUDDY_API_KEY。可建 config.local.json 覆蓋 endpoint / api_key 等(不入庫)。formula_package.py、build_dashboard.py、static_page.py 共用同一個 endpoint。