tqx
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTQX Quant — Factor Analysis & Strategy Backtest
TQX 量化工具 — 因子分析与策略回测
TQX (https://www.tqx.trade) is a HK/US stock quant platform. This skill drives it through the official pip package.
tqx-cliTQX(https://www.tqx.trade)是一款港美股量化平台。本Skill通过官方的`tqx-cli` pip包调用该平台功能。
Official TQX skills (source of truth — read these first)
官方TQX Skill(权威来源 — 请先阅读)
TQX publishes two official skills. Fetch the raw URLs directly (the repo UI is a JS SPA; only URLs return content):
/-/git/raw/1. tqx-research — factor analysis, strategy backtest, workflow management (Python , email/password login):
tqx-cli- Main:
https://cnb.cool/liangyunzhijing/clis/-/git/raw/main/skills/tqx-research/SKILL.md - References (read before generating code — do NOT guess APIs):
- commands:
.../skills/tqx-research/references/commands.md - strategy templates:
.../skills/tqx-research/references/strategy_templates.md - US API:
.../skills/tqx-research/references/stock_us_api.md - HK API:
.../skills/tqx-research/references/stock_hk_api.md - tqx_data: (replace
.../skills/tqx-research/references/tqx_data_usage.mdwith...)https://cnb.cool/liangyunzhijing/clis/-/git/raw/main
- commands:
2. tqx-trading — account/positions/orders/trades queries + authorized order placement (TypeScript , API-key auth, pin the version):
@tqx-ai/cli@0.1.3- Main:
https://cnb.cool/liangyunzhijing/clis/-/git/raw/main/skills/tqx-trading/SKILL.md - OpenAPI: (interactive:
https://www.tqx.trade/openapi/v1/openapi.json)/openapi/v1/scalar
Routing rule: research/backtest/factor work → tqx-research (, Python). Live account state & order execution → tqx-trading (, TS CLI). They use DIFFERENT CLIs and DIFFERENT auth (email login vs ) — don't mix them. This skill below adds what the official docs don't cover: verified onboarding, failure-mode table, and agent-automation patterns.
tqx-clitqxTQX_API_KEYTQX发布了两款官方Skill。请直接获取原始URL(仓库UI是JS单页应用;只有开头的URL会返回内容):
/-/git/raw/1. tqx-research — 因子分析、策略回测、工作流管理(基于Python的,邮箱/密码登录):
tqx-cli- 主文档:
https://cnb.cool/liangyunzhijing/clis/-/git/raw/main/skills/tqx-research/SKILL.md - 参考文档(生成代码前请阅读 — 请勿猜测API):
- 命令说明:
.../skills/tqx-research/references/commands.md - 策略模板:
.../skills/tqx-research/references/strategy_templates.md - 美股API:
.../skills/tqx-research/references/stock_us_api.md - 港股API:
.../skills/tqx-research/references/stock_hk_api.md - tqx_data使用:(将
.../skills/tqx-research/references/tqx_data_usage.md替换为...)https://cnb.cool/liangyunzhijing/clis/-/git/raw/main
- 命令说明:
2. tqx-trading — 账户/持仓/订单/交易查询 + 授权下单(基于TypeScript的,API密钥认证,请固定版本):
@tqx-ai/cli@0.1.3- 主文档:
https://cnb.cool/liangyunzhijing/clis/-/git/raw/main/skills/tqx-trading/SKILL.md - OpenAPI文档:(交互式页面:
https://www.tqx.trade/openapi/v1/openapi.json)/openapi/v1/scalar
路由规则:研究/回测/因子相关工作 → 使用tqx-research(,Python)。实盘账户状态查询与订单执行 → 使用tqx-trading(,TS CLI)。两者使用不同的CLI和认证方式(邮箱登录 vs )—— 请勿混淆。本Skill补充了官方文档未覆盖的内容:经验证的新手入门流程、故障模式表以及Agent自动化模式。
tqx-clitqxTQX_API_KEYUser onboarding (first-time setup, ~3 minutes)
用户入门(首次设置,约3分钟)
-
Register at https://www.tqx.trade (email signup). A PAPER (simulation) account is provisioned automatically — all workflows below are safe to run on it. Paper and live are the SAME API:reports
tqx trading accountor"mode": "PAPER", and every command ("mode": "LIVE",positions,orders place|modify|cancel) is identical on both. Switching to real money is an account-level change on TQX, not a different code path — which is exactly why order-size caps and the human-approval rule below matter.tradesTrading competition: TQX runs an agent trading competition — entry and rules at https://luma.com/dawwrdxk?tk=adzfZA. Competition accounts are created from the same dashboard (https://www.tqx.trade/hk/competition-manage?catalog=2), which is also where thefor the trading CLI is issued.TQX_API_KEY -
Collect credentials securely: agents must usefor
request_env_inputandTQX_EMAIL— never ask for credentials in chat.TQX_PASSWORD -
Install + login + verify:
bash
pip install tqx-cli
tqx-cli login --email "$TQX_EMAIL" --password "$TQX_PASSWORD"
tqx-cli --json balance # non-error response = onboarding completeToken is cached in .
~/.tqx/config.yaml- First quick win (recommended demo): run the "5d momentum" factor analysis from §1 below — completes in ~1–2 min and produces IC/IR/Sharpe numbers you can show immediately.
⚠️ Token expiry gotcha: both accessToken AND refresh_token can expire together. Do NOT only match one specific error string — re-login on ANY response containing , , or . A strict matcher silently fails and every later call returns auth errors.
LOGIN_REQUIRED均已失效Please log in to continue-
注册:访问https://www.tqx.trade(邮箱注册)。系统会自动为你创建一个PAPER(模拟)账户 — 以下所有工作流在该账户上运行都是安全的。模拟账户与实盘账户使用相同的API:命令会返回
tqx trading account或"mode": "PAPER",且所有命令("mode": "LIVE"、positions、orders place|modify|cancel)在两种账户上的用法完全一致。切换到实盘交易是在TQX平台上的账户级别设置变更,无需修改代码 — 这也正是下文提到的订单限额和人工审核规则至关重要的原因。trades -
安全收集凭证:Agent必须使用来获取
request_env_input和TQX_EMAIL— 绝不能在聊天中直接索要凭证。TQX_PASSWORD -
安装 + 登录 + 验证:
bash
pip install tqx-cli
tqx-cli login --email "$TQX_EMAIL" --password "$TQX_PASSWORD"
tqx-cli --json balance # 返回无错误响应即表示入门设置完成Token会缓存到中。
~/.tqx/config.yaml- 快速上手演示(推荐):运行下文§1中的“5日动量”因子分析 — 约1-2分钟即可完成,并生成可即时展示的IC/IR/Sharpe指标。
⚠️ Token过期陷阱:accessToken和refresh_token可能同时过期。请勿仅匹配某一特定错误字符串 — 只要响应中包含、或,就需要重新登录。严格匹配单一错误字符串会导致静默失败,后续所有调用都会返回认证错误。
LOGIN_REQUIRED均已失效Please log in to continueCLI command map
CLI命令映射
factor_create / factor_run / factor_result / factor_list / factor_delete
strategy_create / strategy_run / strategy_result / strategy_list / strategy_delete
backtest_result # per-backtest detail: summary/account/position/profit/trade/log sections
workflow_list / workflow_stop / balanceAdd for machine-readable output.
--jsonfactor_create / factor_run / factor_result / factor_list / factor_delete
strategy_create / strategy_run / strategy_result / strategy_list / strategy_delete
backtest_result # 单回测详情:包含summary/account/position/profit/trade/log等板块
workflow_list / workflow_stop / balance添加参数可获取机器可读格式的输出。
--json1. Factor analysis (cross-sectional IC/IR)
1. 因子分析(横截面IC/IR)
bash
tqx-cli --json factor_create --market us --name "5d momentum" \
--formula "close/ref(close,5)-1" \
--start-date 20250101 --end-date 20250701 --group-number 2
tqx-cli --json factor_run <factor_id> # waits and returns resultsResult parsing gotcha: the result JSON has TWO formats depending on backend version — legacy and current root-level . Handle both. Key metrics: IC mean, IR, t-stat, annualized group returns, Sharpe.
nodes[].result_jsonfactor_analysisbash
tqx-cli --json factor_create --market us --name "5d momentum" \
--formula "close/ref(close,5)-1" \
--start-date 20250101 --end-date 20250701 --group-number 2
tqx-cli --json factor_run <factor_id> # 等待并返回结果结果解析陷阱:返回的结果JSON有两种格式,取决于后端版本 — 旧版为,新版为根层级的。需要兼容两种格式。关键指标:IC均值、IR、t统计量、年化分组收益、Sharpe比率。
nodes[].result_jsonfactor_analysis2. Strategy backtest (panda_backtest engine)
2. 策略回测(panda_backtest引擎)
bash
tqx-cli --json strategy_create --market us --name "AAPL SMA cross" \
--code "$(cat strategy.py)" \
--start-date 20250101 --end-date 20250701 \
--start-capital 1000000 --commission-rate 0.0003 --slippage 0.001 --frequency 1d
tqx-cli --json strategy_run <strategy_id>bash
tqx-cli --json strategy_create --market us --name "AAPL SMA cross" \
--code "$(cat strategy.py)" \
--start-date 20250101 --end-date 20250701 \
--start-capital 1000000 --commission-rate 0.0003 --slippage 0.001 --frequency 1d
tqx-cli --json strategy_run <strategy_id>Strategy code contract
策略代码约定
python
from panda_backtest.api.api import * # common trading API — MANDATORY
from panda_backtest.api.stock_us_api import * # US market data API — MANDATORYpython
from panda_backtest.api.api import * # 通用交易API — 必须导入
from panda_backtest.api.stock_us_api import * # 美股数据API — 必须导入HK market: from panda_backtest.api.stock_hk_api import *
港股市场:from panda_backtest.api.stock_hk_api import *
import tqx_data
def initialize(context):
# Account ID is per-user — discover it once, do NOT hardcode.
# The '8888' from CN-market docs does NOT exist for HK/US backtests.
context.account = list(context.stock_account_dict.keys())[0]
context.symbol = 'AAPL.NB' # symbol format: US = TICKER.NB (NOT .US!), HK = 00700.HK
context.closes = []
def handle_data(context, data):
account = context.stock_account_dict.get(context.account)
if account is None:
return
bar = data.get(context.symbol)
# bar CAN be None — with a WRONG suffix it is None EVERY day (silent 0-trade run)
if bar is None or getattr(bar, 'close', None) is None or float(bar.close) <= 0:
return
price = float(bar.close)
context.closes.append(price)
if len(context.closes) < 20:
return
fast = sum(context.closes[-5:]) / 5
slow = sum(context.closes[-20:]) / 20
position = account.positions.get(context.symbol)
quantity = 0 if position is None else position.quantity
sellable = 0 if position is None else position.sellable
if fast > slow and quantity == 0:
buy_qty = int(account.cash * 0.9 // price)
if buy_qty > 0:
order_shares(context.account, context.symbol, buy_qty, style=MarketOrderStyle)
print(f"BUY {buy_qty} @ {price:.2f}") # print() = strategy log; SRLog is FORBIDDEN
elif fast < slow and quantity > 0 and sellable > 0:
order_shares(context.account, context.symbol, -sellable, style=MarketOrderStyle)
print(f"SELL {sellable} @ {price:.2f}")
Reference run: this exact code on AAPL.NB, 20250101–20251231, produces 18 real fills (check with `backtest_result <backtest_id> --section trade --all-pages`).
Hard rules learned from real failures:
| Symptom | Root cause | Fix |
|---|---|---|
| `禁止使用危险函数 dir()` | Security filter blocks introspection | Never use `dir()`/`eval()`/`exec`; to inspect context, `raise Exception(str(...))` and read the error_detail in run logs |
| `访问了不存在的键` on order | Wrong account ID (e.g. `'8888'`) | Use `list(context.stock_account_dict.keys())[0]` |
| `order_shares() missing 1 required positional argument` | Called with 2 args | Signature is `order_shares(account, symbol, quantity)` |
| `股票X不属于当前股票回测市场` | Wrong symbol suffix | US = `TICKER.NB` (NOT `.US`!), HK = `XXXXX.HK`; `.O`/`.N`/bare tickers are rejected |
| Backtest SUCCESS but 0 trades, 0 log lines, profit = 0.0 | Symbol suffix `.US` (or any wrong suffix) → every bar returns None → defensive guard skips all days silently | Use `TICKER.NB` for US stocks. ALWAYS verify via `backtest_result <id> --section trade` — SUCCESS ≠ trades executed |
| Run FAILED immediately (~0.3s, node failed) | `SRLog` is not a valid API in strategy code | Use plain `print()` for strategy logging (visible in `--section log`) |
| Run status FAILED but NO failed node (all nodes success/pending) | Transient TQX queue/scheduler error, not your code | Resubmit the same workflow once — typically succeeds in ~30s. Only debug strategy code if a node actually failed |
| Backtest SUCCESS but 0 trades, `标的不在当前回测数据集内` | Date range beyond ingested market data (recent months may not be loaded even though the benchmark series exists) | Shift the window earlier (e.g. use last year's range); verify trades>0 in the `trade` section before trusting metrics |
| `frequency` rejected | Only `1d` and `1M` are valid | — |import tqx_data
def initialize(context):
# 账户ID为用户专属 — 需动态获取,请勿硬编码。
# 国内市场文档中的'8888'在港美股回测中不存在。
context.account = list(context.stock_account_dict.keys())[0]
context.symbol = 'AAPL.NB' # 代码格式:美股 = TICKER.NB(不是.US!),港股 = 00700.HK
context.closes = []
def handle_data(context, data):
account = context.stock_account_dict.get(context.account)
if account is None:
return
bar = data.get(context.symbol)
# bar可能为None — 如果后缀错误,每天的bar都会是None(导致无交易的静默回测)
if bar is None or getattr(bar, 'close', None) is None or float(bar.close) <= 0:
return
price = float(bar.close)
context.closes.append(price)
if len(context.closes) < 20:
return
fast = sum(context.closes[-5:]) / 5
slow = sum(context.closes[-20:]) / 20
position = account.positions.get(context.symbol)
quantity = 0 if position is None else position.quantity
sellable = 0 if position is None else position.sellable
if fast > slow and quantity == 0:
buy_qty = int(account.cash * 0.9 // price)
if buy_qty > 0:
order_shares(context.account, context.symbol, buy_qty, style=MarketOrderStyle)
print(f"BUY {buy_qty} @ {price:.2f}") # print()用于记录策略日志;禁止使用SRLog
elif fast < slow and quantity > 0 and sellable > 0:
order_shares(context.account, context.symbol, -sellable, style=MarketOrderStyle)
print(f"SELL {sellable} @ {price:.2f}")
参考回测:上述代码用于AAPL.NB,时间范围20250101–20251231,会产生18次实际成交(可通过`backtest_result <backtest_id> --section trade --all-pages`查看)。
从实际故障中总结的严格规则:
| 症状 | 根本原因 | 修复方案 |
|---|---|---|
| `禁止使用危险函数 dir()` | 安全过滤器阻止了自省操作 | 永远不要使用`dir()`/`eval()`/`exec`;如需检查context,可`raise Exception(str(...))`并在运行日志中查看error_detail |
| `访问了不存在的键`(下单时) | 账户ID错误(例如`'8888'`) | 使用`list(context.stock_account_dict.keys())[0]`动态获取 |
| `order_shares() missing 1 required positional argument` | 调用时只传了2个参数 | 正确签名为`order_shares(account, symbol, quantity)` |
| `股票X不属于当前股票回测市场` | 代码后缀错误 | 美股 = `TICKER.NB`(不是.US!),港股 = `XXXXX.HK`;`.O`/`.N`或无后缀的代码会被拒绝 |
| 回测显示SUCCESS但0交易、0日志行、收益=0.0 | 代码后缀为`.US`(或其他错误后缀)→ 每天的bar都返回None → 防御性检查跳过了所有交易日 | 美股使用`TICKER.NB`。务必通过`backtest_result <id> --section trade`验证 — SUCCESS不代表有交易执行 |
| 运行立即失败(约0.3秒,节点失败) | 策略代码中使用了无效API `SRLog` | 使用普通`print()`记录策略日志(可在`--section log`中查看) |
| 运行状态显示FAILED但无失败节点(所有节点为success/pending) | TQX队列/调度器的临时错误,与代码无关 | 重新提交同一工作流一次 — 通常约30秒后会成功。只有当确实有节点失败时才需要调试策略代码 |
| 回测显示SUCCESS但0交易,提示`标的不在当前回测数据集内` | 时间范围超出了已加载的市场数据(即使基准序列存在,最近几个月的数据可能未加载) | 将时间窗口提前(例如使用去年的范围);在信任指标前务必验证`trade`板块的交易数>0 |
| `frequency`参数被拒绝 | 仅支持`1d`和`1M` | — |Reading results
结果解读
strategy_runstrategy_resultBacktestNodeIdentifier:bash
tqx-cli --json backtest_result <backtest_id> --section summary # profit, alpha, beta, sharpe, IR
tqx-cli --json backtest_result <backtest_id> --section trade # ⚠️ always check trades executed
tqx-cli --json backtest_result <backtest_id> --section log # per-order rejection reasonsA run can report SUCCESS with zero trades (orders silently rejected day by day). Always confirm the section is non-empty before reporting performance numbers.
tradestrategy_runstrategy_resultBacktestNodeIdentifier:bash
tqx-cli --json backtest_result <backtest_id> --section summary # 收益、alpha、beta、Sharpe比率、IR
tqx-cli --json backtest_result <backtest_id> --section trade # ⚠️ 务必检查是否有交易执行
tqx-cli --json backtest_result <backtest_id> --section log # 每笔订单的拒绝原因回测可能显示SUCCESS但实际无交易(订单每天被静默拒绝)。在报告业绩指标前,务必确认板块非空。
tradeDaily equity curve (--section profit
)
--section profit每日权益曲线(--section profit
)
--section profitThe section is the day-by-day NAV series — one row per trading day with (YYYYMMDD), (cumulative strategy return, decimal) and (cumulative benchmark return, decimal).
profitgmt_createstrategy_profitcsi_stockbash
undefinedprofitgmt_createstrategy_profitcsi_stockbash
undefined⚠️ --all-pages does NOT work for the profit section: it silently returns only page 1 (100 rows).
⚠️ --all-pages参数对profit板块无效:会静默返回仅第1页(100行)的数据。
tqx-cli --json backtest_result <backtest_id> --section profit --page-size 1000
tqx-cli --json backtest_result <backtest_id> --section profit --page-size 1000
-> pagination {total: 252, page: 1, page_size: 1000, total_pages: 1} ✅ full year in one call
-> 分页信息 {total: 252, page: 1, page_size: 1000, total_pages: 1} ✅ 一次调用获取全年数据
Two more behaviours to handle (reference: AAPL.NB, full-year 2025 = 252 rows):
- Rows come back **unsorted** — always sort by `gmt_create` ascending before plotting; do not assume the API order.
- Values are **decimals, not percent** (`-0.1174` = −11.74%) and are already cumulative, so plot them directly; don't compound them again.
- The last row must match the `summary` section's total return — use that as your correctness check.
Cache the series locally (one file per run) instead of re-fetching: the call costs ~2–4 s and the data is immutable once the run is done.
需要处理的两种特殊情况(参考:AAPL.NB,2025全年=252行):
- 返回的行是**未排序**的 — 绘图前务必按`gmt_create`升序排序;不要假设API返回的顺序是正确的。
- 值为**小数而非百分比**(`-0.1174` = −11.74%),且已为累计值,可直接绘图;无需再次计算复利。
- 最后一行的值必须与`summary`板块的总收益一致 — 以此作为正确性校验。
将序列本地缓存(每个运行对应一个文件),避免重复获取:该调用耗时约2-4秒,且数据一旦生成即为不可变。Debugging failed runs
失败运行的调试
Error details are NOT in the top-level status — fetch run logs and read , which includes the exact strategy line number and exception message:
error_detailpython
from tqx_cli.config import load_config
from tqx_cli.auth import require_login
from tqx_cli.workflow import get_run_logs
cfg = load_config(); token, uid, _ = require_login(cfg, cfg.get("_config_path"))
for l in get_run_logs(cfg, token, uid, run_id).get("logs") or []:
if l.get("error_detail"): print(l["error_detail"])错误详情不在顶层状态中 — 获取运行日志并查看,其中包含策略代码的具体行号和异常信息:
error_detailpython
from tqx_cli.config import load_config
from tqx_cli.auth import require_login
from tqx_cli.workflow import get_run_logs
cfg = load_config(); token, uid, _ = require_login(cfg, cfg.get("_config_path"))
for l in get_run_logs(cfg, token, uid, run_id).get("logs") or []:
if l.get("error_detail"): print(l["error_detail"])Cost & pacing
成本与 pacing
Backtests are billed in TQX compute credits (). A 6-month daily-frequency single-stock backtest takes ~2 minutes wall time. Poll every 3s; don't fire concurrent runs of the same workflow.
tqx-cli balancestrategy_result回测按TQX计算积分计费(可通过查询)。一次6个月日频单股票回测耗时约2分钟。每3秒轮询一次;不要并发运行同一工作流的多个实例。
tqx-cli balancestrategy_result3. Templates (copy-paste starting points)
3. 模板(可直接复制粘贴的起点)
T1 — Momentum factor (cross-sectional, whole market)
T1 — 动量因子(横截面,全市场)
bash
tqx-cli --json factor_create --market us --name "5d momentum" \
--formula "close/ref(close,5)-1" \
--start-date 20250101 --end-date 20250701 --group-number 5Other verified formulas: mean reversion , volume surge .
Factor mode is whole-market cross-sectional only () — it CANNOT target one stock; for single-stock questions use a strategy backtest (T2).
-(close/ref(close,5)-1)volume/mean(volume,20)--market hk|usbash
tqx-cli --json factor_create --market us --name "5d momentum" \
--formula "close/ref(close,5)-1" \
--start-date 20250101 --end-date 20250701 --group-number 5其他经验证的公式:均值回归 、成交量激增 。
因子模式仅支持全市场横截面()—— 无法针对单只股票;单股票相关问题请使用策略回测(T2)。
-(close/ref(close,5)-1)volume/mean(volume,20)--market hk|usT2 — Single-stock backtest (SMA cross on AAPL)
T2 — 单股票回测(AAPL均线交叉策略)
Use the strategy code contract in §2 verbatim — it IS the template. Change and the signal logic only. Keep the None-bar guard and dynamic account discovery.
context.symbol直接使用§2中的策略代码约定 — 这就是模板。仅修改和信号逻辑即可。保留bar为None的防御性检查和动态账户发现逻辑。
context.symbolT3 — Agent-driven automated trading loop
T3 — Agent驱动的自动化交易循环
Pattern verified over a 10-round live run (~21 min, end-to-end):
loop every N minutes:
1. fetch live positions + account state
2. compute signal (factor value or strategy rule)
3. decide: buy / sell / hold ← agent reasoning step
4. place order (paper account, small fixed qty during development)
5. journal the decision: {ts, reasoning, tool_calls, params, result, position_delta}Hard rules for automation:
- PAPER account by default. Live trading uses the identical command surface, so nothing in the code stops a live order — only your gating does. Require an explicit user approval before pointing the loop at a live account, keep a hard order-size cap, and always pass so a retry can never double-fill.
--idempotencyKey - Journal every decision (JSONL is enough) — users must be able to audit why each trade happened.
- Re-login on ANY auth-ish error string (see token gotcha above); a mid-loop token expiry must self-heal, not kill the loop.
- Check compute balance before each backtest-class call to avoid silent overdraft.
经10轮实盘运行验证的模式(约21分钟,端到端):
每N分钟循环一次:
1. 获取实时持仓 + 账户状态
2. 计算信号(因子值或策略规则)
3. 决策:买入 / 卖出 / 持有 ← Agent推理步骤
4. 下单(开发阶段使用模拟账户,固定小订单量)
5. 记录决策日志:{ts, reasoning, tool_calls, params, result, position_delta}自动化严格规则:
- 默认使用模拟账户。实盘交易使用完全相同的命令接口,因此代码本身无法阻止实盘订单 — 只有你的管控可以。在将循环指向实盘账户前,必须获得用户明确批准,设置严格的订单限额,且始终传递,避免重试导致重复下单。
--idempotencyKey - 记录每一次决策(JSONL格式即可)— 用户必须能够审计每笔交易的决策原因。
- 任何类似认证错误的响应都要重新登录(见上文Token陷阱);循环中的Token过期必须自动恢复,不能终止循环。
- 每次调用回测类命令前检查计算积分余额,避免静默透支。
T4 — Studio: ready-to-run companion UI (templates/studio/
)
templates/studio/T4 — Studio:可直接运行的配套UI(templates/studio/
)
templates/studio/A complete, tested web workbench ships with this skill — do NOT build a dashboard from scratch. Copy into the user's workspace, start it, and adapt.
templates/studio/Files:
| File | Role |
|---|---|
| Stdlib HTTP backend (port 8090, no pip deps). Proxies |
| Single-file frontend: factor analysis, backtest submit/history, positions, agent decision timeline |
| Agent trading loop (LLM via |
| Disk persistence modules (see data spec below) |
UI language: the template ships English-only. Any Chinese you see at runtime comes from the TQX API itself (metric key names, error strings) — do not translate those, they are matched against.
Run: from the studio dir (background), then on it. Credentials come from / env vars (collect via secure input — never hardcode).
python3 server.pypreview(action="serve")TQX_EMAILTQX_PASSWORDDesign spec (keep when restyling):
- Minimalist quant-tech aesthetic: dark-first, monospace numerals, dense tables, no decorative graphics. Avoid bright or cyberpunk themes.
- History rows must be loadable: clicking Load on any history record re-displays its full result in the top result area (factor runs → factor metrics/charts via ; strategy runs → dedicated strategy-result card via
loadBt: return vs benchmark, annualized, Sharpe, max drawdown, trade count, params + code link). A history table that only lists rows without load-back is incomplete.loadStgBt - UI exposes only high-frequency params (formula, market, date range, groups, rebalance, direction) + account switcher + NAV curve + decision timeline. Everything complex (custom strategy code, stock pools, commission/slippage) stays in the conversation layer — the agent has the full CLI surface, the UI must not duplicate it.
- Amounts: format gold/cash values with a single dedicated formatter two competing formatters produce inconsistent output. Check dark-mode contrast on every card.
Persistence & paths (why the two directories):
tqx-cli/root/.tqx/config.yaml/data/workspace/data/workspace/.tqx/sync_tqx_config()server.py_sync_tqx_config()agent.pyThese paths are intentionally fixed, not a portability oversight: every agent has the identical layout — = persistent volume, = ephemeral. Keep the rule when extending the studio: anything that must survive a restart is written under the workspace, never under or . In-studio state (, , ) is already -relative, so it inherits persistence as long as the studio itself is copied into the workspace. If you ever run this outside a Starchild machine, override the persistent root — nothing else in the code assumes an absolute path.
/data/workspace/root/root/tmpdata/backtestsdata/journaldata/strategies__file__Data storage spec:
- + one JSON per run — MUST persist the full strategy code string (not a truncated preview) so any run can be reloaded and re-edited.
data/backtests/index.json - — one line per agent decision, tagged
data/journal/*.jsonl, append-only, never rewritten.source: manual | agent - — named saved strategies. All state is plain JSON on disk; no DB.
data/strategies/
Testing spec (before declaring the studio 'working'):
- (or any GET route) returns JSON — backend alive.
curl localhost:8090/api/health - Submit one REAL backtest through the UI and confirm it appears in the history panel with full code + metrics. A rendered page alone is NOT verification.
- Verify fills exist via — SUCCESS status with 0 trades means a symbol-suffix bug (see failure table).
backtest_result <id> --section trade - Kill/restart and confirm history persists (disk, not memory).
server.py
本Skill附带一个完整的、经过测试的Web工作台 — 无需从零构建仪表板。将复制到用户工作区,启动后即可按需调整。
templates/studio/文件说明:
| 文件 | 作用 |
|---|---|
| 标准库HTTP后端(端口8090,无需额外pip依赖)。代理 |
| 单页前端:因子分析、回测提交/历史记录、持仓、Agent决策时间线 |
| Agent交易循环(通过 |
| 磁盘持久化模块(详见下文数据规范) |
UI语言:模板默认仅支持英文。运行时出现的中文内容来自TQX API本身(指标键名、错误字符串)—— 请勿翻译这些内容,它们用于匹配校验。
运行方式:在studio目录下执行(后台运行),然后对其执行。凭证来自 / 环境变量(通过安全输入收集 — 请勿硬编码)。
python3 server.pypreview(action="serve")TQX_EMAILTQX_PASSWORD设计规范(调整样式时需遵守):
- 极简量化科技风格:优先深色模式等宽数字、密集表格,无装饰性图形。避免亮色或赛博朋克主题。
- 历史记录行必须可加载:点击任何历史记录的Load按钮,需在顶部结果区域重新展示其完整结果(因子运行 → 通过展示因子指标/图表;策略运行 → 通过
loadBt展示专属策略结果卡片:收益 vs 基准、年化收益、Sharpe比率、最大回撤、交易次数、参数 + 代码链接)。仅列出行而无法加载详情的历史表格是不完整的。loadStgBt - UI仅暴露高频参数(公式、市场、时间范围、分组、调仓、方向)+ 账户切换器 + 净值曲线 + 决策时间线。所有复杂配置(自定义策略代码、股票池、佣金/滑点)保留在对话层 — Agent拥有完整的CLI接口,UI无需重复实现。
- 金额格式化:使用统一的格式化工具处理资金数值,避免多个格式化工具导致输出不一致。检查每个卡片在深色模式下的对比度。
持久化与路径(为何使用两个目录):
tqx-cli/root/.tqx/config.yaml/data/workspace/data/workspace/.tqx/server.pysync_tqx_config()agent.py_sync_tqx_config()这些路径是固定的,并非可移植性疏忽:每个Agent都拥有相同的布局 — = 持久化卷, = 临时层。扩展studio时请遵守该规则:任何需要在重启后保留的内容都必须写入workspace目录下,绝不能写入或。studio内的状态(、、)已基于相对路径存储,因此只要studio本身被复制到workspace,就会自动继承持久化特性。如果在Starchild机器外运行该工具,只需覆盖持久化根目录 — 代码中其他部分不依赖绝对路径。
/data/workspace/root/root/tmpdata/backtestsdata/journaldata/strategies__file__数据存储规范:
- + 每个运行对应一个JSON文件 — 必须持久化完整的策略代码字符串(而非截断预览),以便任何运行都能被重新加载和编辑。
data/backtests/index.json - — 每行对应一个Agent决策,标记
data/journal/*.jsonl,仅追加写入,永不改写。source: manual | agent - — 命名保存的策略。所有状态均以纯JSON格式存储在磁盘上;无需数据库。
data/strategies/
测试规范(确认studio可正常运行前需完成):
- (或任何GET路由)返回JSON — 后端正常运行。
curl localhost:8090/api/health - 通过UI提交一次真实回测,并确认其出现在历史面板中,包含完整代码 + 指标。仅渲染页面不足以验证功能正常。
- 通过确认存在成交记录 — SUCCESS状态但0交易意味着代码后缀错误(见故障表)。
backtest_result <id> --section trade - 终止并重启,确认历史记录仍存在(存储在磁盘而非内存中)。
server.py