Files
my_ai_agent_celue_/docs/策略自动化框架.md

45 KiB
Raw Permalink Blame History

策略自动化框架

RaptorBT v0.5.0+ 内置的 AI 友好策略自动化框架

RaptorBT 策略自动化框架覆盖从策略开发到交付的完整流程:

scaffold 生成模板 → 编写信号逻辑 → optimize 参数优化
→ walkforward 验证 → acceptance 验收 → deliver 生成交付包

设计目标:让 AI agent 能自主完成策略研发、优化、验证、交付的全流程,无需人工干预。


目录


快速开始

环境准备

# 1. 安装依赖
pip install -r requirements.txt

# 2. 设置 Mt5Bridge (可选, 用于最终验证)
set MT5_BRIDGE_URL=http://61.164.252.86:13485
set MT5_BRIDGE_KEY=your-api-key

编译 RaptorBT 引擎 (换电脑必读)

策略自动化框架依赖 raptorbt 原生扩展。项目已内置 vendor/ferro-ta-main/80+ 指标的 Rust 源码,随项目提交),换电脑或部署新环境后只需按以下步骤编译:

前置依赖

依赖 版本 说明
Rust toolchain 1.70+ cargorustc(从 https://rustup.rs 安装)
Python 3.10+ 与编译时 Python 版本一致
maturin latest pip install maturinRust → Python 扩展构建工具
vendor/ferro-ta-main/ 已随项目提交Cargo.toml 通过 path 引用,无需联网拉取

编译方式

# 方式 A: 构建 whl 包 (推荐, 全局安装)
maturin build --release
# 产物: target/wheels/raptorbt-0.4.1-cp312-cp312-win_amd64.whl
pip install --force-reinstall target/wheels/raptorbt-*.whl

# 方式 B: 虚拟环境开发模式 (需先激活 venv/conda)
maturin develop --release
# 编译到 python/raptorbt/_raptorbt.*.pyd

⚠️ maturin develop 需要虚拟环境:必须在已激活的 venv/conda 环境中运行,否则会报 "Couldn't find a virtualenv or conda environment"。全局安装请用 maturin build + pip install 方式。

💡 可移植性保障Cargo.tomlferro_ta_core 通过 path = "vendor/ferro-ta-main/crates/ferro_ta_core" 引用源码,vendor/ 目录必须随项目提交(已在 .gitignore 中注明不可忽略)。换电脑 clone 项目后无需联网拉取外部 crate,直接 maturin build --release 即可编译。

数据准备

框架支持两种数据源,默认使用 CSV 离线数据(适合策略研究):

  • CSV(默认):把 MT5 History Center / quant data manager 导出的 M1 CSV 放到项目根目录的 data/ 目录。文件名需包含品种代码(如 XAUUSD)和时区信息(如 UTCPlus02),加载器会自动识别品种、时区并重采样到目标周期。spread 列会自动转为 slippage。
  • Mt5Bridge:用 --source mt5 切换,从远程 MT5 拉取实时数据。适合最终策略验证,不建议用于参数搜索阶段。
# data/ 目录示例
# data/2021.7.6-2026.07.03M1XAUUSD_TICK_UTCPlus02.csv
# data/2021.7.6-2026.07.03M1EURUSD_TICK_UTCPlus02.csv

python -m app.main list   # 会自动列出 data/ 下可用的 CSV 品种

30 秒体验

# 列出所有策略
python -m app.main list

# 生成一个 RSI 策略模板
python -m app.main scaffold --name my_rsi --template mean_reversion

# 优化 SMA 交叉策略参数 (默认用 CSV 离线数据)
python -m app.main optimize --strategy sma_cross \
    --param fast=5,10,15 --param slow=20,30,40 --export

# 生成完整交付包
python -m app.main deliver --strategy sma_cross \
    --param fast=5,10 --param slow=20,30

CLI 命令参考

1. list — 列出所有策略 / 可用指标

python -m app.main list                  # 列出策略
python -m app.main list --indicators     # 列出所有可用指标 (80 个)
python -m app.main list --indicators --json  # JSON 结构化输出 (供 AI agent 解析)
参数 默认 说明
--indicators false 列出所有可用指标及签名 (供 AI agent 查询)
--json false 输出 JSON (供 AI agent 解析)

输出示例 (策略):

可用策略 (4 个):
════════════════════════════════════════════════════════════
  atr_stop_rr            SMA(10/20) 交叉 + 2.0×ATR(14) 止损 + 2.0:1 风险回报止盈
  rsi_mean_reversion     RSI(14) 均值回归, 买入<30.0/卖出>70.0, 3% 追踪止损
  sar_adx_cci            SAR(0.02/0.2) + ADX(14)>25.0 + CCI(20)±100.0, 2.5×ATR 止损/4% 止盈
  sma_cross              SMA(10)/SMA(20) 双均线交叉, 2% 止损/4% 止盈
════════════════════════════════════════════════════════════

输出示例 (指标 --indicators):

可用指标目录 (80 个)
════════════════════════════════════════════════════════════
调用方式: import raptorbt; raptorbt.<name>(numpy_array, ...)
输入约定: close/high/low/open/volume 都是 float64 numpy array

── 趋势 (8 个) ──
  sma(close, period)
    → 1 array
    简单移动平均, 最基础的趋势指标
  ...
── 动量 (13 个) ──
  ...

💡 AI agent 开发策略前建议先 list --indicators --json,获取 80 个指标的完整签名、输入需求、默认值和返回值结构,详见 指标目录 章节。

2. run — 运行单个策略

python -m app.main run --strategy sma_cross \
    --symbol XAUUSD --timeframe H1 --bars 500 --export
参数 默认 说明
--strategy (必填) 策略名称
--symbol XAUUSD 交易品种
--timeframe H1 K 线周期
--bars 500 K 线数量
--source csv 数据源 (csv 离线 / mt5 实时)
--data-file None 显式指定 CSV 文件路径 (默认按 symbol 自动查找)
--export false 导出 CSV 结果 (trades/curves/metrics)
--json false 输出 JSON (含 metrics + 前 50 条 trades, 供 AI agent 解析)

3. compare — 对比所有策略

python -m app.main compare --symbol XAUUSD --bars 500 --export

在相同数据上跑所有策略,输出对比表格。

4. optimize — 参数网格搜索

python -m app.main optimize --strategy sma_cross \
    --param fast=5,10,15,20 --param slow=20,30,40,50 \
    --metric sharpe_ratio --symbol XAUUSD --bars 1000 --export
参数 默认 说明
--param (必填,可多次) 参数空间,格式 name=v1,v2,v3
--metric sharpe_ratio 优化目标指标
--export false 导出完整响应面到 CSV
--json false 输出 JSON (含 best_params + Top 10 组合, 供 AI agent 解析)

支持的 metricsharpe_ratiototal_return_pctmax_drawdown_pct(最小化)、profit_factorwin_rate_pctsortino_ratio 等。

5. walkforward — Walk-Forward 验证

python -m app.main walkforward --strategy sma_cross \
    --param fast=5,10 --param slow=20,30 \
    --bars 1000 --train-size 300 --test-size 100 --export
参数 默认 说明
--train-size 300 训练窗口大小 (bars)
--test-size 100 测试窗口大小 (bars)
--export false 导出逐窗口明细到 CSV
--json false 输出 JSON (含逐窗口 IS/OOS 明细, 供 AI agent 解析)

输出包含:IS/OOS 夏普对比、衰减比、过拟合判定、参数稳定性分布。

6. validate — 策略验收

python -m app.main validate --strategy sma_cross \
    --param fast=5,10 --param slow=20,30 --bars 1000

执行 Walk-Forward + 三层盈利优先验收标准检查(L1 盈利性必须 / L2 风险可控 / L3 健壮性),输出通过/失败判定。

参数 默认 说明
--json false 输出 JSON (含 lookahead + walk_forward + acceptance, 供 AI agent 解析)

💡 失败诊断:当某条标准未通过时,输出会附带该标准的 suggestions 修复建议(每条标准 5 条具体可执行建议,按 L1/L2/L3 分级)。L1 失败时建议是根本性调整(换策略/换品种),不要在参数上浪费时间。AI agent 可直接读取建议决定下一步调整方向。详见 验收检查 章节。

7. scaffold — 生成策略模板

python -m app.main scaffold --name my_rsi \
    --template mean_reversion \
    --description "RSI 超卖反弹策略"
参数 默认 说明
--name (必填) 策略名称 (snake_case)
--template custom 模板类型
--description "" 策略描述
--overwrite false 覆盖已存在文件

模板类型

  • crossover — 均线交叉 (SMA)
  • mean_reversion — RSI 均值回归
  • trend_following — ADX 趋势跟踪
  • breakout — Donchian 通道突破
  • custom — 空白模板

8. deliver — 生成交付包

python -m app.main deliver --strategy sma_cross \
    --param fast=5,10 --param slow=20,30 \
    --symbol XAUUSD --bars 1000

一键执行:优化 → Walk-Forward → 验收 → 导出交付包。

参数 默认 说明
--json false 输出 JSON (含 lookahead + optimization + walk_forward + acceptance + package_path)

⚠️ 强制前视检测:deliver 在执行前会强制运行前视偏差静态扫描,若检测到 HIGH 级别前视模式(如 .shift(-N)、负索引访问未来 bar),会拒绝生成交付包JSON 中 delivered=falseerror 字段说明原因。详见 前视偏差防护 章节。

9. check — 前视偏差检测 ★

# 静态扫描所有策略
python -m app.main check --strategy all

# 静态扫描 + 动态验证单个策略 (修改未来 bar, 看历史信号是否变化)
python -m app.main check --strategy sma_cross --dynamic \
    --symbol XAUUSD --timeframe H1 --bars 500
参数 默认 说明
--strategy (必填) 策略名称,或 all 扫描所有策略
--dynamic false 启用动态扰动验证(修改未来 bar,检查历史信号是否变化)
--symbol XAUUSD 品种(动态验证用)
--timeframe H1 周期(动态验证用)
--bars 500 K 线数量(动态验证用)
--source csv 数据源
--data-file None CSV 文件路径
--json false 输出 JSON (单个策略含 issues + fix_suggestions; all 含所有策略汇总)

输出示例(检测到前视):

🔴 L27: 使用 .shift(-N) 访问未来 bar, 这是明确的前视偏差
   ...future_close = df["close"].shift(-1)...

总结: ❌ 未通过

策略框架 (strategies/)

Strategy 基类

所有策略继承 Strategy 基类(位于 strategies/base.py):

class Strategy(ABC):
    name: str  # 策略唯一标识

    @abstractmethod
    def warmup_bars(self) -> int:
        """返回指标预热所需的最小 bar 数"""

    @abstractmethod
    def generate_signals(self, df: pd.DataFrame) -> SignalResult:
        """根据 K 线数据生成入场/出场信号"""

    @abstractmethod
    def build_config(self) -> raptorbt.PyBacktestConfig:
        """构建回测配置 (止损/止盈/资金/费率)"""

    def description(self) -> str:
        """策略描述 (用于 list 和报告)"""

SignalResult

@dataclass
class SignalResult:
    entries: np.ndarray    # bool 数组, True=入场
    exits: np.ndarray      # bool 数组, True=出场
    direction: int = 1     # 1=做多, -1=做空
    extra: dict = None     # 可选: 附加指标数据

内置辅助方法

# 交叉信号
entries = self.cross_above(ma_fast, ma_slow)  # fast 上穿 slow
exits = self.cross_below(ma_fast, ma_slow)    # fast 下穿 slow

# 预热期处理 (预热期内的信号置 False)
entries, exits = self.apply_warmup(entries, exits)

自动注册机制

strategies/__init__.py 实现自动发现:扫描 strategies/ 目录下所有 .py 文件,若文件中定义了 STRATEGY_CLASS 常量,则自动注册。

新增策略只需 3 步

  1. strategies/ 下创建 .py 文件
  2. 继承 Strategy 实现子类
  3. 在文件末尾添加 STRATEGY_CLASS = YourStrategy

无需修改任何注册代码,python -m app.main list 立即可见。

完整策略示例

"""my_strategy — 我的策略描述"""

from __future__ import annotations
import numpy as np
import raptorbt
from .base import Strategy, SignalResult


class MyStrategy(Strategy):
    """我的策略描述"""
    name = "my_strategy"

    def __init__(self, period: int = 14, threshold: float = 30.0):
        self.period = period
        self.threshold = threshold

    def warmup_bars(self) -> int:
        return self.period + 1

    def generate_signals(self, df) -> SignalResult:
        close = df["close"].values.astype(np.float64)
        rsi = raptorbt.rsi(close, period=self.period)

        entries = (rsi < self.threshold).astype(bool)
        exits = (rsi > 70).astype(bool)
        entries, exits = self.apply_warmup(entries, exits)

        return SignalResult(
            entries=entries, exits=exits, direction=1,
            extra={"rsi": rsi},
        )

    def build_config(self) -> raptorbt.PyBacktestConfig:
        config = raptorbt.PyBacktestConfig(
            initial_capital=100000.0, fees=0.001, slippage=0.0005,
        )
        config.set_fixed_stop(0.02)
        config.set_fixed_target(0.04)
        return config

    def description(self) -> str:
        return f"RSI({self.period}) < {self.threshold} 入场"


STRATEGY_CLASS = MyStrategy

CSV 数据加载器 (data_loader.py)

app/data_loader.py 加载 MT5 History Center / quant data manager 导出的 M1 CSV,支持自动品种识别、时区处理、多周期重采样、spread→slippage 自动转换。

CSV 格式

加载器期望 9 列无表头格式(MT5 History Center 标准):

date,time,open,high,low,close,vol,vol_real,spread
2021.07.06,01:00,1791.37,1791.37,1790.55,1791.27,25850.0,25850.0,98
说明
date / time 日期和时间,格式 YYYY.MM.DD / HH:MM
open / high / low / close OHLC
vol tick volume
vol_real real volume(加载时丢弃)
spread 点差点数(自动转 slippage

文件名约定

文件名应包含品种代码和时区,加载器自动解析:

2021.7.6-2026.07.03M1XAUUSD_TICK_UTCPlus02.csv
                  ^^^^^                ^^^^^^^^
                  品种                  时区 UTC+2
  • 品种识别:内置 17 个常见品种(XAUUSD、EURUSD、USDJPY 等),按长度降序匹配,避免子串误匹配。
  • 时区识别:从 UTCPlusNN / UTCMINUSNN 提取,未识别时默认 UTC。
  • 自动查找find_csv_for_symbol("XAUUSD") 优先匹配 M1 文件,回退到任意匹配。

多周期重采样

加载 M1 后可重采样到 13 种周期:

from app.data_loader import load_csv

# 加载并重采样到 H1
df = load_csv("data/XAUUSD.csv", symbol="XAUUSD", timeframe="H1")

支持周期:M1M5M15M30H1H2H4H6H8H12D1W1MN1

重采样规则(pandas 风格,label="left", closed="left"):

  • open = 窗口第一根
  • high = 窗口最高
  • low = 窗口最低
  • close = 窗口最后一根
  • tick_volume = 求和
  • spread = 平均

spread → slippage 自动转换

CSV 模式下,fetch_klines 会自动计算 slippage 并注入 PyBacktestConfig

slippage = (avg_spread × tick_size) / avg_price

示例:XAUUSD avg_spread=98tick_size=0.01avg_price=1791slippage ≈ 0.000547 (0.055%)

内置 17 个品种的 tick_size 配置(SYMBOL_TICK_SIZE 字典)。未识别品种回退到 0.0001

Python API

from app.data_loader import (
    load_csv, find_csv_for_symbol, compute_slippage,
    list_available_symbols, get_tick_size,
)

# 1. 自动查找 + 加载
path = find_csv_for_symbol("XAUUSD")   # 在 data/ 下查找
df = load_csv(path, timeframe="H1")

# 2. 显式指定文件
df = load_csv("data/XAUUSD.csv", symbol="XAUUSD", timeframe="H1")

# 3. 列出所有可用品种
for symbol, filename in list_available_symbols():
    print(symbol, filename)

# 4. 单独计算 slippage
slippage = compute_slippage(df["spread"], df["close"], "XAUUSD")

周末数据处理

quant data manager 导出的外汇 CSV 已自动过滤周末(外汇市场周六周日休市),因此 load_csv 默认 drop_weekend=False。若你的 CSV 含周末数据(如加密货币),调用时传 drop_weekend=True

df = load_csv("data/BTCUSD.csv", timeframe="H1", drop_weekend=True)

返回 DataFrame 列:timeopenhighlowclosetick_volumespreadtime 列为带时区的 datetime64[ns, tz]


参数优化器 (optimizer.py)

app/optimizer.py 提供策略参数网格搜索。

Python API

from app.optimizer import StrategyOptimizer
from strategies.sma_cross import SmaCrossStrategy

opt = StrategyOptimizer(metric="sharpe_ratio")
result = opt.optimize(
    strategy_class=SmaCrossStrategy,
    df=df,
    param_grid={"fast": [5, 10, 15], "slow": [20, 30, 40]},
    symbol="XAUUSD",
)

print(result.best_params)    # {"fast": 10, "slow": 30}
print(result.best_score)    # 1.234
print(result.summary())      # 优化完成: 9 个组合, ...
print(result.top_n(5))       # 前 5 个参数组合 DataFrame

result.export("optimization.csv")  # 导出完整响应面

优化方向

  • sharpe_ratiototal_return_pctprofit_factorwin_rate_pct → 最大化
  • max_drawdown_pct → 最小化
  • 其他指标自动推断方向

错误恢复

优化器内置错误恢复:参数组合导致 0 信号或回测异常时,记录 error 字段但不中断搜索,对应 metric 设为 NaN。


Walk-Forward 验证 (walk_forward.py)

app/walk_forward.py 提供滚动窗口验证。

验证流程

数据: |----train1----|--test1--|----train2----|--test2--|----train3----|--test3--|

每个窗口:

  1. train 上跑参数优化 → 得到最优参数 (IS)
  2. 用最优参数在 test 上回测 → 得到 OOS 指标
  3. 记录 IS/OOS 对比

Python API

from app.walk_forward import WalkForwardValidator
from strategies.sma_cross import SmaCrossStrategy

wf = WalkForwardValidator(train_size=300, test_size=100)
result = wf.validate(
    strategy_class=SmaCrossStrategy,
    df=df,
    param_grid={"fast": [5, 10], "slow": [20, 30]},
    metric="sharpe_ratio",
)

print(result.is_sharpe_avg)      # IS 平均夏普
print(result.oos_sharpe_avg)    # OOS 平均夏普
print(result.decay_ratio)       # 衰减比 OOS/IS
print(result.is_overfit)        # 是否过拟合 (< 0.5)
print(result.param_stability)   # 参数频次分布
print(result.summary())         # 完整报告

result.export("walkforward.csv")

过拟合判定

  • 衰减比 = OOS 平均夏普 / IS 平均夏普
  • 衰减比 < 0.5 → 判定过拟合
  • 衰减比 ≥ 0.5 → 非过拟合

参数稳定性

输出各参数值被选中的频次分布。若同一参数值在多个窗口被频繁选中,说明参数稳定;若参数值频繁变化,说明对数据过拟合。


验收检查 (acceptance.py)

app/acceptance.py 采用盈利优先三层结构的量化验收标准。

设计哲学

策略的最终目的是赚钱,不是为了优化指标而优化指标。

"当一个指标变成目标时,它就不再是好指标。" — Goodhart 法则

旧的"4 条平等标准"有一个根本问题:全部是过程质量指标,没有一条直接验证"是否赚钱"。这会导致两类误判:

  • 假阳性:Sharpe=1.06 、衰减比=3.0 看似通过,但年化收益只有 2.5%(跑不赢通胀),根本没赚到钱
  • 假阴性:PF=1.8、年化 25% 的策略因 Sharpe=0.8 被拒收(实际是赚钱策略,只是曲线不够平滑)
  • 误导性通过:IS/OOS 都在亏损的策略,衰减比反而很高(3.09),这个"通过"毫无意义

新标准把盈利性(PF/收益/期望)放到 L1 必须层,先确认策略真的赚钱,再看风险和健壮性。

三层默认标准

层级 标准 阈值 说明
L1 盈利性(必须) oos_profit_factor_min 1.3 OOS 盈利因子下限(总盈利/总亏损多 30%)
oos_return_min_pct 0.0 OOS 平均收益率下限(真赚到钱)
oos_expectancy_min 0.0 OOS 每笔期望值下限(平均每单为正)
L2 风险可控(应该) oos_max_drawdown_max_pct 20.0 OOS 最大回撤上限(%)(放宽原 15%)
L3 健壮性(建议) oos_sharpe_min 0.7 OOS 夏普比率下限(放宽原 1.0,降为参考)
oos_total_trades_min 30 OOS 总交易数下限(统计显著性)
is_oos_decay_min 0.5 IS/OOS 衰减比下限(非过拟合)

判定逻辑:

  • passed = L1 全过 AND L2 全过 AND L3 全过(保持严格)
  • l1_passed=False 时直接拒收,不再看 L2/L3
  • 分层让 AI agent 一眼看出"问题严重程度",优先解决 L1

Python API

from app.acceptance import StrategyAcceptance

# 使用默认三层标准
checker = StrategyAcceptance()
report = checker.check(wf_result)

# 自定义标准 (可只覆盖某几条)
checker = StrategyAcceptance(criteria={
    "oos_profit_factor_min": 1.5,   # L1 更严格
    "oos_max_drawdown_max_pct": 15.0,  # L2 更紧
    # 其他条目用默认值
})
report = checker.check(wf_result)

print(report.passed)       # 总判定
print(report.l1_passed)    # L1 盈利性是否全过 (最关键)
print(report.l2_passed)    # L2 风险可控
print(report.l3_passed)    # L3 健壮性
print(report.summary())    # 分层人类可读报告

验收报告(分层)

验收结果: ❌ 未通过 (L1 盈利性未达标 — 策略不赚钱, 无需看 L2/L3)
──────────────────────────────────────────────────────────────────────
  [L1 盈利性] 必须 — 策略是否真的赚钱, 任一失败即拒收 ✗
  ──────────────────────────────────────────────────────────────────
    OOS 盈利因子           阈值=    1.30  实际=     0.00  ✗
      └ 总盈利/总亏损 = 0.00, < 阈值 1.3 (亏损或勉强盈利)
      └ 修复建议:
         1. 策略逻辑本身可能不盈利, 重新审视入场/出场条件是否真的捕捉到正向期望
         2. 切换策略类型 (趋势跟踪在震荡市会持续亏 PF<1, 均值回归在趋势市会亏)
         3. 切换品种或周期 (当前 XAUUSD M5 可能不适合本策略逻辑)
         ...
    OOS 净收益率           阈值=    0.00  实际=   -0.02  ✗
    OOS 每笔期望           阈值=    0.00  实际= -119.53  ✗
  [L2 风险可控] 应该 — 回撤是否在可接受范围 ✓
  ──────────────────────────────────────────────────────────────────
    OOS 最大回撤           阈值=   20.00  实际=    0.46  ✓
  [L3 健壮性] 建议 — 统计显著性和非过拟合, 参考性指标 ✗
  ──────────────────────────────────────────────────────────────────
    OOS 夏普比率           阈值=    0.70  实际=   -0.39  ✗
    OOS 总交易数           阈值=   30.00  实际=   11.00  ✗
    IS/OOS 衰减比         阈值=    0.50  实际=  -21.01  ✗
      └ OOS/IS = -2101.3%, 过拟合风险 (注意: 若 IS 也是亏损, 高衰减比不代表策略好)
──────────────────────────────────────────────────────────────────────

失败诊断建议(按层分级) ★

L1 失败的建议是根本性调整(换策略/换市场/换周期),不是小修小补;L2 是风控调整;L3 是统计性问题。

失败标准 建议方向
OOS 盈利因子 < 1.3 L1 重新审视信号逻辑、切换策略类型(趋势↔均值回归)、切换品种/周期、检查止损是否过紧、尝试反向信号
OOS 净收益 ≤ 0 L1 检查 IS 是否也亏(若也亏=逻辑问题)、评估交易成本侵蚀、减少交易频率、切换顺势品种/周期、反向信号
OOS 每笔期望 ≤ 0 L1 检查胜率×盈亏比、盈亏比失衡→放大止盈/追踪止损、胜率低→加过滤、止损过紧→放宽或换 ATR 止损
OOS 最大回撤 > 20% L2 收紧止损、ATR 动态止损、追踪止损、降仓位、加趋势过滤
OOS 夏普 < 0.7 L3 放宽止损、加趋势过滤、切大周期、加成交量过滤(注:已降为参考,L1 全过时可接受略低)
OOS 交易数 < 30 L3 缩短指标周期、降低入场阈值、切更小周期、放宽过滤、检查 warmup
衰减比 < 0.5 L3 缩小参数空间、增加 WF 窗口数、简化策略、用中位数参数、检查前视

⚠️ 关键提示:衰减比高不代表策略好。若 IS 和 OOS 都在亏损,衰减比反而会很高(如 3.0),这个"通过"是假象。必须先看 L1 的 PF/收益/期望,L1 通过后衰减比才有意义

JSON 输出

AcceptanceReport.to_dict() 返回分层结构的 JSON,CLI 加 --json 标志后直接输出:

{
  "passed": false,
  "l1_passed": false,
  "l2_passed": true,
  "l3_passed": false,
  "verdict": "L1 盈利性未达标 — 策略不赚钱, 无需看 L2/L3",
  "criteria": [
    {
      "name": "OOS 盈利因子",
      "layer": "L1",
      "layer_name": "盈利性",
      "level": "必须",
      "threshold": 1.3,
      "actual": 0.0,
      "passed": false,
      "description": "总盈利/总亏损 = 0.00, < 阈值 1.3 (亏损或勉强盈利)",
      "suggestions": [
        "策略逻辑本身可能不盈利, 重新审视入场/出场条件是否真的捕捉到正向期望",
        "切换策略类型 (趋势跟踪在震荡市会持续亏 PF<1, 均值回归在趋势市会亏)",
        ...
      ]
    },
    {
      "name": "OOS 最大回撤",
      "layer": "L2",
      "layer_name": "风险可控",
      "level": "应该",
      "threshold": 20.0,
      "actual": 0.46,
      "passed": true,
      "description": "低于最大回撤限制 20.0%",
      "suggestions": []
    }
  ]
}

AI agent 决策逻辑:

1. 调用 validate --json
2. 检查 l1_passed:
   - False → 策略不赚钱, 不要在参数上浪费时间, 按 L1 suggestions 换策略逻辑/品种/周期
   - True  → 进入 L2/L3 检查
3. 检查 l2_passed: False → 按 L2 suggestions 调整风控 (止损/仓位)
4. 检查 l3_passed: False → 按 L3 suggestions 处理统计性问题
5. 全过 → deliver --json 生成交付包

💡 通过的标准 suggestions 为空数组,未通过的才填充建议。NaN/Inf 已自动转为 null


策略模板生成器 (scaffold.py)

app/scaffold.py 生成符合框架约定的策略模板。

Python API

from app.scaffold import scaffold_strategy

# 生成 RSI 均值回归模板
path = scaffold_strategy(
    name="my_rsi",
    template="mean_reversion",
    description="RSI 超卖反弹策略",
)
print(f"模板已生成: {path}")

# 覆盖已存在文件
path = scaffold_strategy(
    name="my_rsi",
    template="mean_reversion",
    overwrite=True,
)

模板类型

模板 策略逻辑 适用场景
crossover SMA 双均线交叉 趋势市场
mean_reversion RSI 超卖买入/超买卖出 震荡市场
trend_following ADX + DI 方向确认 强趋势市场
breakout Donchian 通道突破 突破行情
custom 空白模板 自定义逻辑

生成的模板已包含完整的 Strategy 子类骨架,包括 __init__warmup_barsgenerate_signalsbuild_configdescriptionSTRATEGY_CLASS 常量。


交付包导出 (exporter.py)

app/exporter.py 生成完整的策略交付包。

Python API

from app.exporter import StrategyExporter

exporter = StrategyExporter()
pkg_path = exporter.deliver(
    strategy_name="sma_cross",
    df=df,
    symbol="XAUUSD",
    opt_result=opt_result,
    wf_result=wf_result,
    accept_report=accept_report,
    param_grid={"fast": [5, 10], "slow": [20, 30]},
    data_info={
        "source": "Mt5Bridge",
        "range": "2026-01-01 ~ 2026-06-30",
        "bars": 1000,
        "timeframe": "H1",
    },
)

交付包结构

deliverables/{strategy_name}_{timestamp}/
├── {strategy_name}.py          策略源文件 (从 strategies/ 复制)
├── STRATEGY_REPORT.md          完整交付报告 (8 个章节)
├── optimization.csv             参数优化响应面
├── walkforward.csv             Walk-Forward 逐窗口明细
└── backtest_metrics.csv        最优参数回测指标

Markdown 报告章节

  1. 策略概述 (名称/描述/标的/最优参数/预热期)
  2. 参数优化 (目标/组合数/Top 5 参数表)
  3. Walk-Forward 验证 (IS/OOS 对比/衰减比/过拟合判定/参数稳定性)
  4. 验收结果 (三层盈利优先标准/L1-L2-L3 分层)
  5. 最优参数完整回测指标
  6. 数据信息 (来源/范围/K 线数/周期)
  7. 风险提示 (5 条)
  8. 复现方式 (CLI 命令)

前视偏差防护 (lookahead_check.py)

app/lookahead_check.py 是防止 AI agent 在自动开发策略时引入前视偏差的核心防护层。两层防护:静态 AST 扫描 + 动态扰动验证。

为什么需要前视防护

前视偏差(look-ahead bias)是量化策略最隐蔽的 bug:策略生成信号时使用了未来才能获取的数据,回测结果虚高,实盘后立即崩溃。常见诱因:

  • .shift(-N) — 访问未来第 N 根 bar
  • close[-1] / high[-1] — 负索引访问(numpy 从数组末尾取,等价于未来)
  • df.iloc[i+N:] — 切片到未来索引
  • rolling(...).mean().shift(-1) — 滚动统计后向未来偏移
  • np.roll — 把末尾元素循环到开头(本项目曾因此 bug 修复)

静态扫描规则

11 条正则 + AST 检测,分三级严重度:

严重度 含义 示例
🔴 HIGH 确定前视,拒绝交付 .shift(-1)close[-1]iloc[i+10:]
🟡 MEDIUM 可疑模式,需人工确认 future/lookahead 关键词、np.roll.shift(0)
🟢 LOW 建议检查 values[i + N] 基于索引访问

判定规则:只要存在 HIGH 级别问题就判定失败

动态扰动验证

原理:策略只用过去 + 当前数据生成信号,所以修改未来 bar 不应影响历史信号。

1. 用原始数据生成基准信号 → base_entries[:N]
2. 修改 bar N+1..N+K 的 OHLC ±5% → 生成扰动信号 perturbed_entries[:N]
3. 比较 base_entries[:N] 与 perturbed_entries[:N]
4. 若有差异 → 存在前视偏差

参数:check_bars=50(检查前 50 根)、perturb_range=10(扰动 10 根未来 bar)。

Python API

from app.lookahead_check import (
    check_strategy_code, check_strategy_file, check_all_strategies,
    dynamic_check, full_check,
)

# 1. 静态扫描源码字符串
report = check_strategy_code(code, "my_strategy.py")
print(report.passed)      # True/False
print(report.summary())   # 人类可读报告

# 2. 静态扫描文件
report = check_strategy_file("strategies/sma_cross.py")

# 3. 批量扫描 strategies/ 目录
for path, report in check_all_strategies("strategies"):
    print(os.path.basename(path), report.passed)

# 4. 动态验证 (需策略类 + 数据)
result = dynamic_check(
    SmaCrossStrategy, df,
    params={"fast": 10, "slow": 20},
    check_bars=50, perturb_range=10,
)
print(result.passed, result.reason)

# 5. 综合检查 (静态 + 动态)
report = full_check(
    SmaCrossStrategy, "strategies/sma_cross.py",
    df=df, params={"fast": 10, "slow": 20}, run_dynamic=True,
)
print(report.summary())

强制集成点

前视检测已在三处强制接入,AI agent 无法绕过:

集成点 行为
check 命令 单独运行静态 + 动态检测
validate 命令 前置检测,未通过则终止验收
deliver 命令 前置检测,未通过则拒绝生成交付包
scaffold 模板 生成的策略文件头部自带 ⚠️ 前视警告,列出禁用模式

scaffold 模板的前视警告

scaffold 生成的策略文件头部会自动包含警告块:

"""my_strategy — RSI 超卖反弹策略

⚠️ 前视偏差 (Look-Ahead Bias) 注意事项:
  信号生成时只能用当前 bar 及之前的数据, 严禁使用未来 bar。
  以下模式会引入前视偏差, 必须避免:
    - .shift(-N)          # 访问未来 bar (N>0)
    - close[-1] / high[-1]  # 负索引访问未来
    - df.iloc[i+N:]        # 切片到未来索引
    - 滚动统计后 shift 负值
  正确做法:
    - 用 cross_above / cross_below (基类已内置前视安全)
    - 信号在 bar 收盘后生成, 用 close 成交 (引擎默认 upon_bar_close=True)
    - 检测: python -m app.main check my_strategy
"""

引擎层的前视防护

RaptorBT 引擎层已内置前视防护:PyBacktestConfig(upon_bar_close=True)(默认)确保信号在 bar 收盘后生成、以 close 价成交,杜绝同一根 bar 内的信号→成交前视。


自定义指标库 (indicators.py)

app/indicators.py 提供自定义指标库,全部转发到 ferro-ta Rust 原生实现以获得亚毫秒级性能。

可用指标

函数 转发到 说明
typical_price(h, l, c) raptorbt.typprice 典型价格
cci(h, l, c, period) raptorbt.cci 商品通道指数
williams_r(h, l, c, period) raptorbt.willr 威廉指标
roc(data, period) raptorbt.roc 变化率
trix(data, period) raptorbt.trix 三重指数平滑变化率
dmi(h, l, c, period) raptorbt.adx_all DMI (ADX + DI)
ichimoku(h, l, c, ...) raptorbt.ichimoku 一目均衡表
parabolic_sar(h, l, ...) raptorbt.sar 抛物线 SAR
mfi(h, l, c, v, period) raptorbt.mfi 资金流量指数
obv(c, v) raptorbt.obv 能量潮
awesome_oscillator(h, l, ...) sma(medprice) 组合 震荡指标 (原生组合)

用法

from app.indicators import cci, williams_r, dmi

cci_vals = cci(high, low, close, period=20)
willr_vals = williams_r(high, low, close, period=14)
adx, plus_di, minus_di = dmi(high, low, close, period=14)

指标目录 (indicator_catalog.py)

app/indicator_catalog.py 提供 80 个原生指标的完整目录,让 AI agent 在不读完整手册的情况下也能快速查询可用指标、签名、输入需求和返回值结构。

覆盖范围

分类 数量 代表指标
趋势 8 sma / ema / wma / dema / tema / kama / supertrend / sar
动量 13 rsi / macd / cci / stochastic / willr / roc / mom / trix / cmo / bop / ultosc / stochrsi / ppo
强度 7 adx / adx_all / plus_di / minus_di / adxr / aroon / aroonosc
波动率 6 atr / natr / trange / bollinger_bands / stddev / var
成交量 4 obv / mfi / ad / adosc
统计 7 linearreg / linearreg_slope / linearreg_intercept / linearreg_angle / tsf / beta / correl
滚动 2 rolling_min / rolling_max
量价 1 vwap
价格变换 6 typprice / medprice / avgprice / wclprice / midpoint / midprice
高阶均线 5 t3 / trima / vwma / hull_ma / apo
通道 4 donchian / chandelier_exit / ichimoku / pivot_points
Hilbert 6 ht_trendline / ht_dcperiod / ht_dcphase / ht_phasor / ht_sine / ht_trendmode
市场状态 5 choppiness_index / regime_adx / regime_combined / detect_breaks_cusum / rolling_variance_break
投资组合 6 rolling_beta / drawdown_series / zscore_series / relative_strength / spread / ratio

IndicatorInfo 字段

每个指标记录 9 个字段:

字段 说明 示例
name 函数名 (raptorbt.xxx) adx_all
category 分类 强度
inputs 输入数组需求 ["high", "low", "close"]
params 参数名列表 ["period"]
defaults 参数默认值 (与 params 一一对应, "—" 为必填) ["—"]
returns 返回说明 "3 arrays (adx, plus_di, minus_di)"
description 简短中文说明 "ADX + +DI - DI, 一次拿全方向信息"
signature() 可读签名 adx_all(high, low, close, period)
usage 完整调用示例 adx, plus_di, minus_di = raptorbt.adx_all(...)

CLI 查询

# 文本版 (人读, 按分类展示)
python -m app.main list --indicators

# JSON 版 (AI agent 解析)
python -m app.main list --indicators --json

JSON 结构:

{
  "total": 48,
  "categories": {
    "趋势": [{...}, ...],
    "动量": [{...}, ...],
    ...
  },
  "all_names": ["sma", "ema", "wma", ...],
  "usage_note": "调用方式: import raptorbt; raptorbt.<name>(numpy_array, ...)"
}

Python API

from app.indicator_catalog import CATALOG, list_by_category, find, format_text, format_json

# 1. 按名称查找单个指标
info = find("adx_all")
print(info.signature())  # adx_all(high, low, close, period)
print(info.returns)      # 3 arrays (adx, plus_di, minus_di)
print(info.usage)        # adx, plus_di, minus_di = raptorbt.adx_all(high, low, close, period=14)

# 2. 按分类遍历
for cat, inds in list_by_category().items():
    print(f"{cat}: {len(inds)} 个")

# 3. 获取所有指标名称 (快速判断某指标是否存在)
all_names = [i.name for i in CATALOG]  # ['sma', 'ema', 'wma', ...]

# 4. 生成文本/JSON 目录
print(format_text())
payload = format_json()

AI agent 集成指南

推荐工作流

AI agent 可按以下流程自主开发策略:

0. list --indicators --json 查询可用指标 (80 个, 含签名/默认值/返回值)
   ↓
1. scaffold 生成策略模板 (自带前视警告头部)
   ↓
2. 编辑模板,填入信号生成逻辑 (用 raptorbt.<指标名> 调用)
   ↓
3. check 前视偏差检测 (静态 + 动态)  ★ 强制
   ↓
4. optimize 搜索参数空间
   ↓
5. walkforward 验证泛化能力
   ↓
6. acceptance 检查是否达标 (失败时自动给修复建议)
   ↓
7. 若未通过 → 读取 suggestions 调整逻辑或参数, 回到 2/4
   若通过 → 继续 8
   ↓
8. deliver 生成交付包 (再次强制前视检测, 失败则拒绝生成)

⚠️ 前视检测是强制门槛:步骤 3 和 8 都会运行前视偏差检测。即使 AI agent 在步骤 2 不小心引入了 .shift(-N) 等前视模式,也会在交付前被拦截。详见 前视偏差防护 章节。

💡 步骤 0 的价值:AI agent 在编写策略前先查询指标目录,可以避免调用不存在的指标或用错参数签名。JSON 输出中 all_names 数组可快速判断某指标是否存在,usage 字段提供完整调用示例。

通过 CLI 调用 (推荐)

AI agent 可通过 RunCommand 工具直接调用 CLI

# 0. 查询可用指标 (AI agent 开发策略前先了解工具箱)
python -m app.main list --indicators --json

# 1. 生成模板 (自带前视警告头部)
python -m app.main scaffold --name ai_strategy_v1 --template breakout

# 2. (AI 编辑 strategies/ai_strategy_v1.py 填入逻辑)

# 3. 前视偏差检测 (静态 + 动态) — 强制门槛
python -m app.main check --strategy ai_strategy_v1 --dynamic --bars 500

# 4. 参数优化
python -m app.main optimize --strategy ai_strategy_v1 \
    --param period=10,15,20,25 --param threshold=0.5,1.0,1.5

# 5. Walk-Forward 验证
python -m app.main walkforward --strategy ai_strategy_v1 \
    --param period=10,15,20 --bars 2000

# 6. 验收
python -m app.main validate --strategy ai_strategy_v1 \
    --param period=10,15,20 --bars 2000

# 7. 交付 (内置强制前视检测, 失败则拒绝生成)
python -m app.main deliver --strategy ai_strategy_v1 \
    --param period=10,15 --bars 2000

JSON 输出 + 失败驱动迭代 ★

所有命令支持 --json 标志,输出结构化 JSON(自动清理 NaN/Inf,不转义中文),AI agent 可直接解析无需正则匹配表格:

# 推荐: AI agent 用 --json 获取结构化输出
python -m app.main validate --strategy ai_strategy_v1 \
    --param period=10,15,20 --bars 2000 --json

失败驱动的自动迭代:当 validate 未通过时,JSON 中 acceptance.criteria 数组的每条失败标准都带 suggestions 字段(5 条具体可执行建议)。AI agent 可按以下逻辑自动调整:

1. 调用 validate --json
2. 解析 JSON, 找到 passed=false 的标准
3. 读取该标准的 suggestions 数组
4. 根据 suggestions 修改策略 (如 "缩短指标周期" → 把 RSI 14 改为 7)
5. 重新 check → optimize → validate, 直到全部通过
6. 通过后 deliver --json 生成交付包

各命令的 JSON 结构:

命令 JSON 关键字段
list --indicators --json total + categories (按分类) + all_names (快速判断指标是否存在) + usage_note
run --json metrics (33 项指标) + trades (前 50 条) + n_trades
optimize --json best_params + best_score + top_10 (Top 10 参数组合)
walkforward --json is_sharpe_avg + oos_sharpe_avg + decay_ratio + is_overfit + windows (逐窗口明细)
validate --json lookahead + walk_forward + acceptance (含 suggestions)
check --json 单个策略: passed + issues + fix_suggestions; all: n_pass + n_fail + strategies
deliver --json delivered + package_path + lookahead + optimization + walk_forward + acceptance

💡 NaN 处理:JSON 输出已自动把所有 NaN/Inf 转为 nullAI agent 无需特殊处理。

通过 Python API 调用

from app.optimizer import StrategyOptimizer
from app.walk_forward import WalkForwardValidator
from app.acceptance import StrategyAcceptance
from app.exporter import StrategyExporter

# 完整流程
opt = StrategyOptimizer(metric="sharpe_ratio")
opt_result = opt.optimize(...)

wf = WalkForwardValidator(train_size=300, test_size=100)
wf_result = wf.validate(...)

checker = StrategyAcceptance()
report = checker.check(wf_result)

if report.passed:
    exporter = StrategyExporter()
    pkg = exporter.deliver(...)

验收通过判据

策略通过验收需满足盈利优先三层全部标准:

  • L1 盈利性(必须,任一失败即拒收)
    1. OOS 盈利因子 ≥ 1.3(总盈利比总亏损多 30%)
    2. OOS 净收益率 > 0%(样本外真的赚到钱)
    3. OOS 每笔期望 > 0(平均每单为正)
  • L2 风险可控(应该) 4. OOS 最大回撤 ≤ 20%
  • L3 健壮性(建议) 5. OOS 夏普比率 ≥ 0.7(已降为参考) 6. OOS 总交易数 ≥ 30 7. IS/OOS 衰减比 ≥ 0.5(注意:IS 也亏时高衰减比无意义)

优先级:L1 失败 = 策略根本不赚钱,不要在参数优化上浪费时间,直接换策略逻辑或品种/周期。详见 验收检查 章节。

通过后 deliver 生成的交付包可作为最终交付物。


环境变量

变量 默认 说明
MT5_BRIDGE_URL http://61.164.252.86:13485 Mt5Bridge 服务地址
MT5_BRIDGE_KEY (内置默认) Mt5Bridge API Key

安全建议:生产环境务必通过环境变量设置 MT5_BRIDGE_KEY,不要硬编码到代码中。