用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/SZWzz/AStockPursue --skill strategy-generate命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | strategy-generate |
| description | Create, modify, and optimize quantitative trading strategies, then backtest and evaluate them. |
| category | strategy |
config.jsoncode/signal_engine.py (following the SignalEngine contract)bash("python -c \"import ast; ast.parse(open('code/signal_engine.py').read()); print('OK')\"")backtest tool (built into the engine; no need to write run_backtest.py)artifacts/metrics.csv and judge by the review criteriaedit_file → run backtest → re-evaluateYou only need to write signal_engine.py and config.json. The backtest tool automatically handles data loading and backtest execution.
Extract the following from the user's description:
start_date=2016-06-03, end_date=2026-06-03). You MUST compute the actual date — do NOT copy example dates from this document.If critical information is missing, you must ask the user instead of guessing:
Write config.json first, then write code. config.json must be placed in the root of run_dir.
Before writing code, think through these 5 questions:
pe/pb/roe, or statement fields such as income_total_revenue / fina_indicator_roe?), data frequency (daily), and market (which determines the data source)There is no need to output a JSON design document. Express these design decisions directly in code.
SignalEngine Contractclass SignalEngine:
def generate(self, data_map: Dict[str, pd.DataFrame]) -> Dict[str, pd.Series]:
"""
Args:
data_map: code -> DataFrame (columns: open, high, low, close, volume, DatetimeIndex)
If config.extra_fields is specified, pe, pb, roe, and similar daily_basic columns will also be present.
If config.fundamental_fields is specified, PIT-safe statement columns such as
income_total_revenue, income_n_income, and fina_indicator_roe will also be present.
Returns:
code -> signal Series, value range [-1.0, 1.0]
1.0 = fully long, 0.5 = half position, 0.0 = flat, -1.0 = fully short
Portfolio strategy: selected stocks split weights equally (for example top 10 -> each 0.1)
Legacy integer signals {-1, 0, 1} remain compatible (treated as -100% / 0% / 100%)
"""
Hard constraints:
Series index must align exactly with the input DataFrame indexnumpy, pandas, and so on)config.json)if __name__ == "__main__" blockSelf-check after writing signal_engine.py:
numpy, pandas, typing, and so on)fillna(0) or skip[-1.0, 1.0]600/601/603 → .SH, all others → .SZ.US, such as AAPL.US (yfinance converts automatically).HK, such as 700.HK (yfinance converts automatically)BTC-USDT format (OKX spot pairs, must use the hyphen -, not slash /)
BTC/USDT, but config.json must use "BTC-USDT"XXX-USDT (uppercase + hyphen), such as BTC-USDT and ETH-USDT"okx"null (OKX does not support fundamentals)DataLoader has already normalized the output to match China A-shares exactly: open, high, low, close, volume + DatetimeIndexsignal_engine.py should be written the same way as for China A-shares; do not add extra data conversion for OKX| Pattern | Market | Free Sources (no token) | Token Sources | Extra Fields |
|---|---|---|---|---|
^\d{6}\.(SZ|SH|BJ)$ | China A-shares | mootdx, eastmoney, tencent, baidu, akshare | tushare, twelvedata, futu | extra_fields: pe, pb, pe_ttm, ps_ttm, dv_ttm, total_mv, circ_mv, roe (tushare only); fundamental_fields: income/balancesheet/cashflow/fina_indicator (tushare only) |
^[A-Z]+\.US$ | US stocks | yfinance | twelvedata, finnhub | - |
^\d{3,5}\.HK$ | Hong Kong stocks | yfinance, tencent | futu, twelvedata | - |
^[A-Z]+-USDT$ | Cryptocurrency | okx, ccxt | - | - |
CRITICAL — match the source to your backtest date range. The engine auto-paginates and auto-falls-back, but choosing the right source avoids surprises:
| Source | Approx. History Depth | Best For |
|---|---|---|
| mootdx (TDX TCP) | ~2-3 years (free server dependent) | Recent backtests ≤ 2yr; fastest |
| eastmoney (HTTP) | ~10+ years | Long-history backtests 3-10yr; free, paginated |
| tencent (HTTP) | ~10+ years (2000 bars/req) | Medium-history backtests; real-time quotes |
| baidu (HTTP) | Variable (server-capped) | Quick K-line with MA indicators |
| tushare | 1990-present (full history) | Full-history backtests; fundamentals (requires token) |
| akshare | Full history (multi-source) | Fallback for any market; free |
Source selection rules:
"source": "auto" — auto-detects market and tries mootdx first, falls back through the chain"source": "eastmoney" (free) or "source": "tushare" (needs token). mootdx free servers typically don't retain data beyond ~3 years"source": "tushare" + extra_fields / fundamental_fields (requires TUSHARE_TOKEN)start_date and end_date in config.json — the engine fetches all available dataextra_fields selection logic: only China A-shares (tushare) support daily valuation fields. If the strategy needs PE/PB/ROE and similar daily_basic fields, specify them in config.json.extra_fields and DataLoader will retrieve them automatically. Hong Kong stocks, US stocks, and crypto do not support extra_fields.
fundamental_fields selection logic: use this for China A-share financial statement pre-filters. The runner queries income, balancesheet, cashflow, and/or fina_indicator through the Tushare fundamental provider, then merges rows into daily bars only after their announcement/disclosure date. Output columns are prefixed by table name, for example income_total_revenue, income_n_income, balancesheet_total_hldr_eqy_exc_min_int, and fina_indicator_roe.
config.json Format{
"source": "auto",
"codes": ["000001.SZ"],
"start_date": "<YYYY-MM-DD>",
"end_date": "<YYYY-MM-DD>",
"interval": "1D",
"initial_cash": 1000000,
"commission": 0.001,
"extra_fields": null,
"fundamental_fields": null,
"optimizer": null,
"optimizer_params": {},
"engine": "daily",
"slippage": null,
source: "auto" (recommended, auto-select by code format with fallback) / "mootdx" (fastest, ~2-3yr history) / "eastmoney" (free, ~10yr+ history) / "tencent" (free, ~10yr+ history) / "baidu" (free, K-line+MA) / "tushare" (full history + fundamentals, needs token) / "yfinance" / "okx" / "akshare" / "ccxt" / "twelvedata"
"eastmoney" or "tushare" — mootdx free servers may not retain data that far back"mootdx" or "auto" is fastest"auto" supports mixed instruments and auto-falls-back when data coverage is insufficient"auto" supports mixed instruments. For example, ["000001.SZ", "BTC-USDT"] will be automatically routed to tushare and okx"IF2406.CFFEX", "ESZ4") and forex pairs (e.g. "EUR/USD") are also auto-routedinterval: candlestick interval, default "1D". Supported values: "1m" / "5m" / "15m" / "30m" / "1H" / "4H" / "1D"
source (252 trading days for China A-shares, 365 calendar days for crypto)1m, or 1 year for 1Hextra_fields: China A-shares can use values such as ["pe", "pb", "roe"]; other markets should use nullfundamental_fields: optional China A-share statement fields, such as {"income": ["total_revenue", "n_income"], "fina_indicator": ["roe"]}; use null unless the strategy needs financial statement pre-filteringpassed=false)artifacts/metrics.csv exists and is non-emptyartifacts/equity.csv exists and is non-emptyexit_code == 0 (backtest exits normally)equity column in equity.csv contains no NaN valuestrade_count > 0 (zero trades = signal bug)score ≥ 60 → passedscore ≥ 60 = passed=truetrade_count=0): signal-logic bug, conditions may be too strictaction_items FormatIf improvements are needed after evaluation, write action_items:
"Change X from A to B" or "Add X logic in signal_engine.py""Change short MA from 5 to 10 days to reduce whipsaw signals""Add stop-loss: force close when loss exceeds 5%""Add volume filter in signal_engine.py: only trigger buy on high volume"When the user requests a backtest with codes from different markets (e.g. ["000001.SZ", "BTC-USDT"]):
source: "auto" in config.jsonCompositeEngine handles calendar alignment, shared capital, and per-market rules automaticallyoptimizer: optional, one of "equal_volatility" / "risk_parity" / "mean_variance" / "max_diversification" / null (equal-weight by default)optimizer_params: optimizer parameters, such as {"lookback": 60}. mean_variance additionally supports {"risk_free": 0.0}engine: backtest engine, default "daily". For options strategies, set "options" (requires OptionsSignalEngine)initial_cash: default 1,000,000commission: default 0.1%slippage: optional, default engine-specific (A-shares 0.001, crypto 0.0005). Decimal fraction, e.g. 0.002 = 0.2%slippage_mode: optional, "fixed" (default, constant percentage) or "volume" (tiered by notional: <¥50万→0.3%, ¥50~500万→0.15%, >¥500万→0.05%)benchmark: optional, benchmark ticker for excess-return / information-ratio / beta. "auto" (default) infers from market (CSI 300 for A-shares, S&P 500 for US, BTC for crypto)validation: optional statistical validation after backtest completes. Omit to skip. Example:
"validation": {
"monte_carlo": {"n_simulations": 1000},
"bootstrap": {"n_bootstrap": 1000, "confidence": 0.95},
"walk_forward": {"n_windows": 5}
}
monte_carlo: permutation test — shuffles trade order to compute p-value (is Sharpe significantly better than random?)bootstrap: resamples daily returns to compute Sharpe 95% confidence intervalwalk_forward: splits equity curve into N windows, checks performance consistencypython -m backtest.validation <run_dir>