DataWhale—量化金融(task5: 策略回测)

📈 策略回测专题

目录

  1. 什么是回测
  2. 回测的核心指标
  3. 回测的陷阱
  4. 兆易创新双均线策略回测
  5. NVDA策略vs大盘
  6. 1年vs5年最大回撤对比
  7. 什么是胜率
  8. 作业解答
  9. 本期学习总结与个人感悟
  10. 完整代码附录

一、什么是回测

回测(Backtesting)是指:用历史数据模拟交易策略在过去的表现,评估策略的有效性、稳健性和风险特征的过程。

通俗地说:

"假设我在2024年1月1日就开始用这个策略交易,到今天我会赚多少钱?中间最多亏过多少?胜率是多少?"

回测是连接"理论策略"与"实盘交易"的桥梁。

不做回测的风险 做回测的好处
策略可能只是运气 验证策略是否真的有"优势"
不知道最大亏损 了解最坏情况下会亏多少
参数选择凭感觉 科学优化参数,避免过拟合
心理没底,拿不住 增强信心,知道策略的"性格"
真金白银做实验 用历史数据做实验,零成本

二、回测的核心指标

收益率类

  • 总收益率(Total Return):策略整个周期的盈亏比例
  • 年化收益率(Annualized Return):换算成年化后的收益率
  • 超额收益(Alpha):策略收益 - 基准收益

风险类

  • 最大回撤(Max Drawdown) :从峰值到谷底的最大亏损幅度
    • 公式:MDD = max(Peak - Trough) / Peak
  • 波动率(Volatility):收益率的标准差
  • 夏普比率(Sharpe Ratio):(策略收益 - 无风险收益) / 波动率

交易质量类

  • 胜率(Win Rate):盈利交易次数 / 总交易次数
  • 盈亏比(Profit/Loss Ratio):平均盈利 / 平均亏损
  • 交易次数(Trade Count):策略触发的买卖次数

三、回测的陷阱

过拟合(Overfitting)

策略在历史数据上表现极好,但未来失效。原因:参数调得太多,恰好适应了历史数据的噪声。防范:样本外测试、交叉验证、简化策略。

未来函数(Look-ahead Bias)

用"未来的信息"做"现在的决策"。例子:用当天的收盘价决定当天的买卖。防范:严格按时间顺序,只用已知信息。

幸存者偏差(Survivorship Bias)

只测试现在还活着的股票,忽略了已经退市的。结果:策略表现被人为高估。

交易成本忽略

回测时没算手续费、滑点、印花税。结果:实盘收益远低于回测。


四、兆易创新双均线策略回测

4.1 回测设置

参数 数值
初始资金 ¥100,000
策略 MA5/MA20 双均线
手续费 万3
滑点 0.1%

4.2 回测结果

指标 数值
最终资产 ¥165,264.78
策略总收益率 +65.26%
买入持有收益率 +69.03%
超额收益(Alpha) -3.77%
最大回撤 -28.16%
交易次数 2次
完成交易对 1对
胜率 100%

4.3 交易明细

日期 类型 价格 说明
2026-05-18 买入 ¥400.40 金叉▲买入
2026-07-09 卖出 ¥662.83 死叉▼卖出

4.4 回测可视化

上图:策略净值(绿色)vs 买入持有(蓝色虚线),红色区域=策略跑输,绿色区域=策略跑赢

中图:回撤对比,策略最大回撤-28.2%,大盘最大回撤-44.9%

下图:日收益率分布,策略日收益更集中在0附近(空仓期无波动)


五、NVDA策略vs大盘

5.1 回测结果

指标 数值
策略最终净值 $164,053.92
大盘最终净值 $153,993.86
策略收益率 +64.05%
大盘收益率 +53.99%
超额收益 +10.06%
策略最大回撤 -8.55%
大盘最大回撤 -36.0%
交易次数 4次
胜率 100%

5.2 策略vs大盘净值图

上图:绿色=策略净值,蓝色虚线=买入持有净值。绿色填充=策略跑赢区域,红色填充=策略跑输区域

下图:回撤对比,策略最大回撤仅-8.5%,而大盘回撤-36%,策略有效控制了风险


六、1年vs5年最大回撤对比

对比维度 1年 5年
最大回撤 -63.8% -65.4%
包含周期 仅高位震荡回调 完整牛熊周期
信息完整性 局部视角 全局视角

结论:5年最大回撤更深,因为包含了2022年的大熊市和2025年的高位回调。我更能接受5年视角,虽然回撤深,但了解完整周期有助于坚持策略。


七、什么是胜率

胜率(Win Rate)= 盈利交易次数 / 总交易次数 × 100%

胜率反映的是策略"猜对方向"的概率,但高胜率不等于高收益:

场景 胜率 结果
高频小额盈利,低频大额亏损 90% 可能最终亏损
低频大额盈利,高频小额亏损 40% 可能最终盈利

关键公式

期望收益 = 胜率 × 平均盈利 - (1-胜率) × 平均亏损

索普的启示:51%的胜率,配合1:1的盈亏比,长期就能盈利。胜率不是越高越好,关键是期望收益为正。


八、作业解答

作业1:NVDA策略跑赢还是跑输?

答案:策略跑赢大盘10.06个百分点!

策略收益率+64.05%,大盘收益率+53.99%。MA5/MA20策略在NVDA上产生了正超额收益,且最大回撤远小于大盘(-8.5% vs -36%)。

作业2:1年vs5年最大回撤哪个更深?

答案:5年最大回撤更深(-65.4% vs -63.8%)。

5年包含了完整的牛熊周期,2022年大熊市和2025年高位回调都被纳入。我更能接受5年视角,因为它展示了策略在极端情况下的表现,有助于建立合理预期。

作业3:三句话解释回测

回测就是用历史数据"彩排"你的交易策略,看看如果早几年用这个策略,能赚多少钱、最多亏多少,避免用真金白银去试错的笨办法。


九、本期学习总结与个人感悟

9.1 本期核心内容回顾

主题 关键收获
回测定义 用历史数据验证策略,零成本实验
核心指标 收益率、最大回撤、夏普比率、胜率
回测陷阱 过拟合、未来函数、幸存者偏差、交易成本
兆易创新回测 策略+65%,但跑输买入持有-3.77%
NVDA回测 策略+64%,跑赢大盘+10%,回撤仅-8.5%
1年vs5年 长期视角回撤更深但更真实

9.2 个人感悟

  1. 回测不是万能的,但没有回测是万万不能的。回测不能保证未来收益,但能排除明显糟糕的策略。

  2. 胜率只是故事的一半。100%胜率听起来很美,但如果只交易了1次,样本量太小毫无意义。关键是期望收益为正。

  3. 回撤比收益更重要。NVDA策略收益+64%,但最大回撤仅-8.5%,这意味着我可以安心睡觉。相比之下,大盘-36%的回撤足以让人割肉离场。

  4. 参数周期影响巨大。MA5/MA20在兆易创新上跑输大盘,但在NVDA上跑赢。没有放之四海而皆准的参数,必须针对具体标的优化。

  5. 5年视角让我清醒。看到-65%的最大回撤,我明白了为什么量化投资需要严格的风险管理。这不是游戏,是真金白银。


十、完整代码附录

10.1 回测引擎核心代码

python 复制代码
def backtest_ma_strategy(df, short_window, long_window, initial_capital=100000, 
                         commission_rate=0.0003, slippage=0.001):
    data = df.copy()
    data['short_ma'] = data['收盘'].rolling(window=short_window).mean()
    data['long_ma'] = data['收盘'].rolling(window=long_window).mean()

    data['signal'] = 0
    data.loc[data.index[long_window:], 'signal'] = np.where(
        data['short_ma'].iloc[long_window:] > data['long_ma'].iloc[long_window:], 1, 0
    )
    data['position_change'] = data['signal'].diff()

    capital = initial_capital
    position = 0
    trades = []
    daily_values = []

    for i in range(len(data)):
        row = data.iloc[i]
        price = row['收盘']
        signal_change = row['position_change']

        if signal_change == 1 and position == 0:
            buy_price = price * (1 + slippage)
            max_shares = int(capital * (1 - commission_rate) / buy_price)
            if max_shares > 0:
                cost = max_shares * buy_price * (1 + commission_rate)
                capital -= cost
                position = max_shares
                trades.append({'date': row['日期'], 'type': '买入', 
                              'price': buy_price, 'shares': max_shares})

        elif signal_change == -1 and position > 0:
            sell_price = price * (1 - slippage)
            revenue = position * sell_price * (1 - commission_rate)
            capital += revenue
            trades.append({'date': row['日期'], 'type': '卖出',
                          'price': sell_price, 'shares': position})
            position = 0

        stock_value = position * price
        daily_values.append({
            'date': row['日期'], 'total_value': capital + stock_value,
            'position': position
        })

    values_df = pd.DataFrame(daily_values)
    total_return = (values_df['total_value'].iloc[-1] / initial_capital - 1) * 100

    peak = values_df['total_value'].cummax()
    drawdown = (values_df['total_value'] - peak) / peak * 100
    max_drawdown = drawdown.min()

    return {
        'total_return': total_return,
        'max_drawdown': max_drawdown,
        'trades_df': pd.DataFrame(trades),
        'values_df': values_df
    }

相关推荐
kels88998 小时前
单连接动态增减订阅:股票行情API后端降负载实战方案
开发语言·笔记·python·信息可视化·金融
Old Uncle Tom1 天前
银行用户画像 -- 金融目标与需求意图
前端·人工智能·金融
期权汇小韩1 天前
科技大涨后,最新行情操作思路
金融
keke.shengfengpolang2 天前
金融工程毕业能干什么?银行、证券、数据岗怎么选
数学建模·金融
我怎么又饿了呀4 天前
DataWhale—量化金融(task3:移动平均线策略)
金融
hqyjzsb4 天前
非计算机专业学生怎么进入AI相关方向
人工智能·职场和发展·金融·数据挖掘·数据分析·aigc·业界资讯
龙虾PRO4 天前
金融 AI 分析系统:人工智能驱动的金融行情分析系统落地方案
人工智能·金融
longxibo5 天前
第 14 章 金融行业私有化AI落地案例
人工智能·金融·aigc
2401_891409265 天前
CMES金融数据下载中心:期货、期权行情数据全解析
金融