查看全课大纲(第 9 / 38 节)

上节课思考题及本节课内容介绍

约 18 分钟

📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)

小象实战讲义 · 初阶量化交易:策略编写及系统搭建 本讲义仅用于编程与量化方法教学,不构成任何投资建议。

在量化交易体系中,许多初学者的关注焦点往往全部集中在量化信号系统(什么时候买、什么时候卖)上。不可否认,精准的择时与信号触发是获取超额收益(Alpha)的前提;然而在专业量化基金中,决定账户能否长期生存、穿越极端牛熊周期的关键,恰恰在于仓位管理(头寸分配)与底层风险控制。

本讲首先深度解答第一课留下的两大经典思考题——剖析看似优异的单次回测收益曲线为何不能轻率上线实盘,并揭示双均线策略在回测代码编写中极易踩中的两大致命工程 Bug(成交量上限假设与状态/交叉信号混淆);随后系统引出第二章的核心主线:四大经典量化择时信号系统(MACD、RSI、BOLL、分形) 的设计与落地逻辑。


💡 核心导读

  • 上节思考题 1:如何客观诊断一份回测收益曲线?
    • 表面指标:年化收益率 23.5%、最大回撤 9.4%、收益回撤比 2.5:1,近 200 次交易看似统计显著;
    • 实盘死穴:仅覆盖单一自然年(2016 年),未经历大牛市与大熊市的跨周期检验,无法排除”幸存者偏差”与特定市场风格红利;必须逐笔排查交易明细中的滑点、流动性与冲击成本。
  • 上节思考题 2:双均线策略的两大隐蔽回测 Bug:
    1. 成交量占比上限设定过高(order_volume_ratio = 1.0):在回测中假设能吃下当日全部成交量,而实盘中即使建仓超过当日成交量的 10% 就会引发严重的市场冲击成本,回测建议严格设为 ≤0.1\le 0.1;
    2. 状态判断(State)误当成交叉触发信号(Cross):判断条件写作 MA5 > MA10。在非 All-in 满仓的分仓策略中,会导致在持续多头排列期间每天重复买入,迅速吃光账户可用资金!正确做法应为边沿触发判定(MA5 上穿 MA10 当日仅触发一次交易)。
  • 量化信号系统在全系统中的战略定位:
    • 信号系统负责回答”何时买卖”的择时问题;
    • 本章将逐一攻克 MACD 金叉/死叉、RSI 超买/超卖、BOLL 轨道突破、分形顶底结构 四大核心技术指标的数学建模与数据库信号生成。
┌─────────────────────────────────────────────────────────────┐
│                    量化交易核心决策分工模型                 │
└──────────────────────────────┬──────────────────────────────┘
                               │
 ┌─────────────────────────────┼─────────────────────────────┐
 ▼                             ▼                             ▼
┌──────────────────┐   ┌──────────────────┐   ┌──────────────────┐
│   信号系统 (When)│   │   头寸管理 (How) │   │   风控系统 (Risk)│
├──────────────────┤   ├──────────────────┤   ├──────────────────┤
│ • 寻找交易时机   │   │ • 决定下注规模   │   │ • 保证账户不穿仓 │
│ • 均线/MACD/RSI  │   │ • 凯利公式/等权  │   │ • 极端止损/分散化│
│• 输出买卖 Trigger│   │• 资金利用率最优化│   │ • 长期生存之命脉 │
└──────────────────┘   └──────────────────┘   └──────────────────┘

一、上节课思考题深度复盘与回测陷阱

1. 2016 单次回测曲线为何不能轻易上实盘?

在回测报告中,年化 23.5%、最大回撤 9.4%、成交近 200 笔看似无可挑剔。但专业量化评估必须警惕:

  • 跨周期适应性不足:A 股市场具有极强的风格轮动(如 2017 年的”漂亮 50”与中小盘分化、2018 年的单边阴跌)。仅凭 1 年的回测数据,无法证明策略在不同宏观环境下的稳健性;
  • 逐笔交易真实性核验:必须逐笔核查 200 笔交易的买卖点位是否存在盘口滑点、停牌股交易或未来函数。

2. 双均线回测代码中的两大致命 Bug

Bug ① 成交量上限假定过宽 (order_volume_ratio = 1.0)
     └─ 假设能吃下当日全部成交量。实盘中超过 10% 就会引发严重滑点冲击,回测必须设为 ≤ 0.1。

Bug ② 状态判断混淆为交叉触发 (MA5 > MA10)
     └─ 只要处于多头排列每天都买入 10%,导致第一只股票几天内吃光所有资金,破坏组合配置!

二、认识量化信号系统

量化信号系统是连接原始行情数据与交易执行路由的桥梁:

数据(价/量/时/空)→技术指标交易信号(Buy/Sell)→组合仲裁实盘报单数据 (价/量/时/空) \xrightarrow{\quad 技术指标 \quad} 交易信号 (Buy/Sell) \xrightarrow{\quad 组合仲裁 \quad} 实盘报单

技术指标的四大底层哲学分类

  1. 均线型(MA, EXPMA, BBI):反映特定周期内的平均持仓成本,体现动态支撑与压力;
  2. 趋势型(MACD, SAR, DMI):捕捉单边行情的启动、发展与趋势反转;
  3. 摆动型(RSI, KDJ, BOLL, WR):适用于震荡行情,度量市场的超买与超卖状态;
  4. 能量型(OBV, VOL, VR):度量量价配合力度,验证价格波动的持续性。

⚠️ 信号逻辑正确 ≠ 策略盈利:本讲演示的是”状态判断 vs 边沿交叉”这一逻辑正确性问题(避免重复买入耗尽资金),并不意味着金叉本身能预测涨跌。本节代码与输出均基于内置合成行情,仅演示信号的计算口径,不构成任何买卖建议,也不代表信号在真实市场的胜率或收益;技术指标在震荡市可能频繁假信号,信号参数(周期/阈值)过度贴合某段历史即过拟合,实盘还须计入滑点、佣金与冲击成本。回测偏差的系统讨论见 3.7、5.4。


📝 动手练一练

下面我们通过 Python 代码,复现并验证状态持续追买(State-driven)与交叉瞬时触发(Cross-driven) 的逻辑差异,直观展示为何判断条件必须使用边沿触发:

import pandas as pd
# 保证宽表在任意终端宽度下都完整打印(不折叠中间列),使输出确定、可复现
pd.set_option("display.width", 250)
pd.set_option("display.max_columns", None)
pd.set_option("display.max_rows", None)

def demonstrate_cross_vs_state_signal():
    """
    演示量化回测中的经典逻辑 Bug:
    1. 错误逻辑 (State-driven): 只要 MA_Fast > MA_Slow 每日都触发买入 -> 资金被单一标的过快耗尽
    2. 正确逻辑 (Cross-driven): 仅在 MA_Fast 上穿 MA_Slow 的金叉发生当日触发一次买入指令
    """
    # 构造一条均线由死叉转金叉的价格时序
    dates = pd.date_range("2023-01-01", periods=8, freq="D")
    prices = pd.Series([12.0, 11.5, 11.0, 10.5, 11.2, 12.0, 12.8, 13.5], index=dates)
    
    ma3 = prices.rolling(3).mean()  # 快线
    ma5 = prices.rolling(5).mean()  # 慢线
    
    df = pd.DataFrame({'Close': prices, 'MA3': ma3, 'MA5': ma5})
    
    # 1. 错误逻辑: 状态判断 (只要处于上方每天都买)
    df['State_Buy'] = df['MA3'] > df['MA5']
    
    # 2. 正确逻辑: 边沿触发 (前一日在下方且当日穿到上方)
    df['Cross_Buy'] = (df['MA3'] > df['MA5']) & (df['MA3'].shift(1) <= df['MA5'].shift(1))
    
    print("================ 均线信号判定: 状态判断 vs 交叉触发 ================")
    print(df[['Close', 'MA3', 'MA5', 'State_Buy', 'Cross_Buy']])
    print("------------------------------------------------------------------")
    print(f"错误逻辑 (State-driven) 触发买入天数: {df['State_Buy'].sum()} 天 (持续吃光账户资金)")
    print(f"正确逻辑 (Cross-driven) 触发买入天数: {df['Cross_Buy'].sum()} 天 (仅在突破首日精准建仓)")
    print("==================================================================")
demonstrate_cross_vs_state_signal()

运行结果输出:

================ 均线信号判定: 状态判断 vs 交叉触发 ================
            Close        MA3    MA5  State_Buy  Cross_Buy
2023-01-01   12.0        NaN    NaN      False      False
2023-01-02   11.5        NaN    NaN      False      False
2023-01-03   11.0  11.500000    NaN      False      False
2023-01-04   10.5  11.000000    NaN      False      False
2023-01-05   11.2  10.900000  11.24      False      False
2023-01-06   12.0  11.233333  11.24      False      False
2023-01-07   12.8  12.000000  11.50       True       True
2023-01-08   13.5  12.766667  12.00       True      False
------------------------------------------------------------------
错误逻辑 (State-driven) 触发买入天数: 2 天 (持续吃光账户资金)
正确逻辑 (Cross-driven) 触发买入天数: 1 天 (仅在突破首日精准建仓)
==================================================================

👉 点击查看解析

本练习用合成价格序列对比两种信号写法:状态判断(MA3 > MA5 为真就每天发买入)会在多头排列期间连续重复下单、迅速耗尽资金;边沿交叉(用 shift(1) 比较前后两日)只在金叉发生当日触发一次。核心要点是回测/实盘的买卖触发必须用交叉逻辑而非状态逻辑。

本章小结

  1. 客观对待单次回测表现:回测曲线良好绝不等于实盘盈利,必须检验跨周期稳健性与流动性冲击。
  2. 严防状态与边沿信号混淆:在多资产配置策略中,信号判定必须采用 shift(1) 前后对比的交叉触发逻辑,切忌使用状态判断导致连续重复下单。
  3. 信号与风控协同运行:信号解决时机问题,仓位与风控解决生死存亡问题,两者相辅相成。

📋 行动清单 (Action Checklist)

  • 运行本讲模拟代码,观察第 7 天与第 8 天 State_Buy 与 Cross_Buy 的布尔值变化;
  • 检查自己现有的策略逻辑,核实是否存在将”均线多头排列”误写为”每日重复买入”的隐蔽 Bug;
  • 预习下一讲技术指标分类体系,明确趋势型与摆动型指标的适用市场环境。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第2章课件:认识量化信号系统
    PDF · 2.1MB
    下载
  • 第2章配套代码包:技术指标与交易信号开发
    ZIP · 9KB
    下载
  • 开发环境准备:软件安装指导
    PDF · 0.9MB · 建议第3章动手实践前先通读
    下载
  • 量化入门推荐书单
    PDF · 318KB
    下载