查看全课大纲(第 53 / 59 节)
  1. 1.量化投资必备基础知识
  2. 2.趋势型策略及模型原理
  3. 3.均值回复型策略及模型原理
  4. 4.配对交易策略及模型原理
  5. 5.量化策略研发流程与基本技能
  6. 6.常用的量化平台概述及如何选择
  7. 7.如何量化一个主观策略思路
  8. 8.常用技术指标及指标计算过程
  9. 9.如何编写指标代码
  10. 10.指标的物理意义
  11. 11.技术指标的应用技巧
  12. 12.更多的交易决策
  13. 13.编写程序去量化一个趋势型技术指标
  14. 14.编写趋势型技术指标的性能评价
  15. 15.策略对交易成本和持仓周期的影响
  16. 16.股票池策略的原理及基本框架
  17. 17.基于多因子分析的股票池设计与实现
  18. 18.股票池的性能评估
  19. 19.使用定制化财务因子构建股票池
  20. 20.趋势型策略原理及股票池机制的设计
  21. 21.趋势型择时信号的设计方法与编程实现
  22. 22.趋势型策略的回测与性能评估
  23. 23.优化趋势型策略的思路及方法
  24. 24.量化体系中的风险控制思想
  25. 25.风险的度量-波动率
  26. 26.常用的风险控制方法
  27. 27.实现止盈止损模块以提高策略性能
  28. 28.策略性能的评估与优化
  29. 29.探讨波动率与风险的关系
  30. 30.量化策略中的经典资金管理模型
  31. 31.用python编程实现资金管理模块
  32. 32.构建一个完善的量化交易策略
  33. 33.趋势型量化策略必备的期货知识
  34. 34.期货量化工具介绍
  35. 35.商品期货趋势型策略原理
  36. 36.用TB编写商品期货趋势型策略(上)
  37. 37.用TB编写商品期货趋势型策略(下)
  38. 38.分析优化商品期货趋势型策略的方法思路
  39. 39.期货交易策略的注意事项
  40. 40.均值回复型策略的原理
  41. 41.A股市场有没有稳定的均值回复效应?
  42. 42.编写一个均值回复型股票量化策略
  43. 43.编写多空组合策略进行策略改进
  44. 44.在策略中实现头寸管理进行策略优化
  45. 45.套利策略原理及常见套利类型
  46. 46.用MC开发一个跨品种套利交易策略(上)
  47. 47.用MC开发一个跨品种套利交易策略(下)
  48. 48.统计套利之股票配对交易策略
  49. 49.实盘中的细节问题:加减仓
  50. 50.关于高频交易
  51. 51.如何评价实盘量化策略的性能
  52. 52.量化系统的工作过程及研发流程
  53. 53.运气or实力
  54. 54.量化实盘交易需要满足什么条件
  55. 55.未来函数的坑
  56. 56.实盘数据接口异常的自动报警
  57. 57.交易系统的压力测试
  58. 58.自动运行的交易策略,什么时候需要人工干预
  59. 59.预案准备和实盘心理建设

运气or实力

约 12 分钟

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

小象实战讲义 · 进阶量化交易实战:迭代式的量化策略研发 本讲义仅用于编程与量化方法教学,不构成任何投资建议。

在随机游走的金融市场中,短期大赚究竟是策略具备真实 Alpha(实力),还是仅仅碰巧赶上了市场风格(运气)?本节深入剖析假设检验、tt-统计量、拔靴法(Bootstrap 重抽样)以及蒙特卡洛随机置换检验,教你用严密统计学工具剥离运气的幻觉。

💡 核心导读

  • 辨别量化实力与运气的四大统计学工具:
    • tt-统计量与 pp-value 检验:检验策略超额收益均值是否显著大于 0(单侧检验:t>1.645t > 1.645, p<0.05p < 0.05);
    • 拔靴法重抽样(Bootstrap Resampling):对历史交易记录做有放回重抽样(代码默认 1,000 次,生产环境建议 ≥5,000~10,000 次以收窄蒙特卡洛误差),计算夏普比率的 95% 置信区间;
    • 蒙特卡洛随机打乱(Monte Carlo Permutation):打乱价格走势时序,检验策略是否仍能跑出正收益(若能,则策略存在过拟合漏洞);
    • 风格归因(Factor Attribution):剥离市场 Beta、大小盘风格与行业暴露,提取真正的特异性 Alpha。
┌─────────────────────────────────────────────────────────────┐
│                    实力与运气统计学鉴别矩阵拓扑图           │
└──────────────────────────────┬──────────────────────────────┘
                               │
 ┌─────────────────────────────┼─────────────────────────────┐
 ▼                             ▼                             ▼
┌─────────────────────────┐   ┌─────────────────────────┐   ┌─────────────────────────┐
│ $t$-统计量假设检验      │   │ Bootstrap 重抽样置信区间│   │ 蒙特卡洛随机置换检验    │
├─────────────────────────┤   ├─────────────────────────┤   ├─────────────────────────┤
│ • $t = \frac{\mu}{\sigma/\sqrt{N}} > 2.0$ │   │ • 默认1000次 生产≥1万次│   │ • 打乱时序检验 Alpha 归零│
│ • 证明收益非随机游走    │   │ • 95% 下界夏普仍大于 1.0│   │ • 识破过拟合假象        │
└─────────────────────────┘   └─────────────────────────┘   └─────────────────────────┘

一、夏普比率 tt-统计量与置信度检验数学推导

设策略拥有 NN 笔独立交易记录,样本均值为 μ\mu,标准差为 σ\sigma。检验零假设 H0:μ=0H_0: \mu = 0 的 tt-统计量为:

t=μ−0σ/N=Sharpesingle×Nt = \frac{\mu - 0}{\sigma / \sqrt{N}} = \text{Sharpe}_{\text{single}} \times \sqrt{N}

当交易笔数 N<30N < 30 时,即便年化收益很高,tt 统计量往往也无法突破单侧检验临界值 1.6451.645(无法排除纯运气成分)。(临界值口径:1.6451.645/1.961.96 是大样本正态近似值;小样本(如 N<60N<60)应改用自由度 N−1N-1 的 tt 分布临界值,如单侧 0.05 取 scipy.stats.t.ppf(0.95, df=N-1),样本越小门槛越高。)

import pandas as pd
import numpy as np

def calculate_strategy_t_stat(returns: pd.Series) -> dict:
    """
    计算策略收益率的 t-统计量与统计显著性(合成教学样例,历史回测不代表未来)
    """
    n = len(returns)
    mu = returns.mean()
    se = returns.std() / (np.sqrt(n) + 1e-8)
    t_stat = mu / (se + 1e-8)
    
    return {
        'N_Trades': n,
        'Mean_Return': float(mu),
        'T_Stat': float(t_stat),
        # 1.645 为大样本正态近似的单侧 0.05 临界值; 小样本应改用 t 分布临界值 scipy.stats.t.ppf(0.95, df=n-1)
        'Is_Statistically_Significant': t_stat >= 1.645
    }

# 合成交易收益数据(包含亏损情形,避免过度理想化)
rng = np.random.default_rng(42)
n_trades = 200
# 模拟一个微幅正期望的策略,但包含显著波动
returns_data = rng.normal(loc=0.002, scale=0.025, size=n_trades)
returns_series = pd.Series(returns_data, name='strategy_return')

# 计算并展示统计显著性检验结果
result = calculate_strategy_t_stat(returns_series)
print("===== 策略收益统计显著性检验 =====")
print(f"交易笔数 N: {result['N_Trades']}")
print(f"平均单笔收益: {result['Mean_Return']:.6f}")
print(f"t 统计量: {result['T_Stat']:.4f}")
print(f"统计显著 (t >= 1.645)? {result['Is_Statistically_Significant']}")
print("注:大样本正态近似,小样本需用 t 分布临界值。")
===== 策略收益统计显著性检验 =====
交易笔数 N: 200
平均单笔收益: 0.001239
t 统计量: 0.7945
统计显著 (t >= 1.645)? False
注:大样本正态近似,小样本需用 t 分布临界值。

二、Bootstrap 拔靴法夏普比率置信区间估计

通过对历史收益率进行有放回重抽样(函数默认 1000 次,生产环境建议提高到 5000~10000 次以收窄蒙特卡洛误差),计算夏普比率在 95%95\% 置信度下的最悲观下界。(假设提示:标准 Bootstrap 以各笔收益独立同分布为前提;若实盘收益存在自相关,应使用移动块自助(Moving Block Bootstrap)按块重抽样以保留时序结构,否则置信区间偏窄,留作进阶练习。)

import pandas as pd
import numpy as np

def bootstrap_sharpe_confidence_interval(returns: pd.Series, n_iterations: int = 1000, alpha: float = 0.05, rng=np.random.default_rng(123)) -> dict:
    """
    Bootstrap 估计夏普比率置信区间(合成教学样例,独立同分布假设下,序列相关需用块自助法)
    """
    boot_sharpes = []
    n = len(returns)
    rets_arr = returns.values

    for _ in range(n_iterations):
        # iid 有放回重抽样隐含各笔收益独立同分布; 若收益有序列相关(如趋势跟踪策略),
        # 应改用移动块自助(Moving Block Bootstrap)按块重抽样以保留自相关结构, 否则置信区间偏窄
        sample = rng.choice(rets_arr, size=n, replace=True)
        # 样本单位是「笔」: 乘 sqrt(252) 年化隐含「每日至多一笔交易」假设; 非日频策略应改乘 sqrt(年均交易笔数)
        s = sample.mean() / (sample.std() + 1e-8) * np.sqrt(252)
        boot_sharpes.append(s)
        
    lower_bound = np.percentile(boot_sharpes, alpha / 2 * 100)
    upper_bound = np.percentile(boot_sharpes, (1 - alpha / 2) * 100)
    
    return {'Sharpe_Mean': float(np.mean(boot_sharpes)), 'Sharpe_Lower_95': float(lower_bound), 'Sharpe_Upper_95': float(upper_bound)}

# 合成交易收益数据
rng = np.random.default_rng(123)
n_trades = 150
# 模拟一个夏普比率约为 0.5 的策略收益序列
returns_data = rng.normal(loc=0.001, scale=0.02, size=n_trades)
returns_series = pd.Series(returns_data, name='strategy_return')

# 执行 Bootstrap 并展示结果(rng 固定种子:重抽样也必须确定,否则输出每跑必变)
boot_result = bootstrap_sharpe_confidence_interval(returns_series, n_iterations=2000, rng=rng)
print("===== Bootstrap 夏普比率置信区间估计 =====")
print(f"Bootstrap 迭代次数: 2000")
print(f"夏普比率均值估计: {boot_result['Sharpe_Mean']:.4f}")
print(f"夏普比率 95% 置信区间: [{boot_result['Sharpe_Lower_95']:.4f}, {boot_result['Sharpe_Upper_95']:.4f}]")
print("注:基于 IID 假设,若收益存在自相关,区间可能偏窄。")
===== Bootstrap 夏普比率置信区间估计 =====
Bootstrap 迭代次数: 2000
夏普比率均值估计: 3.0664
夏普比率 95% 置信区间: [0.3701, 5.6419]
注:基于 IID 假设,若收益存在自相关,区间可能偏窄。

📝 动手练一练

编写 Python 测试脚本,对模拟策略进行 1000 次(函数默认值;生产建议 ≥5000 次)Bootstrap 抽样,测算夏普比率 95% 置信区间:

import pandas as pd
import numpy as np

def calculate_strategy_t_stat(returns: pd.Series) -> dict:
    """
    计算策略收益率的 t-统计量与统计显著性
    """
    n = len(returns)
    mu = returns.mean()
    se = returns.std() / (np.sqrt(n) + 1e-8)
    t_stat = mu / (se + 1e-8)
    
    return {
        'N_Trades': n,
        'Mean_Return': float(mu),
        'T_Stat': float(t_stat),
        'Is_Statistically_Significant': t_stat >= 1.645
    }

def bootstrap_sharpe_confidence_interval(returns: pd.Series, n_iterations: int = 1000, alpha: float = 0.05, rng=np.random.default_rng(42)) -> dict:
    """
    Bootstrap 估计夏普比率置信区间(rng 固定种子,重抽样结果确定可复现)
    """
    boot_sharpes = []
    n = len(returns)
    rets_arr = returns.values

    for _ in range(n_iterations):
        sample = rng.choice(rets_arr, size=n, replace=True)
        s = sample.mean() / (sample.std() + 1e-8) * np.sqrt(252)
        boot_sharpes.append(s)
        
    lower_bound = np.percentile(boot_sharpes, alpha / 2 * 100)
    upper_bound = np.percentile(boot_sharpes, (1 - alpha / 2) * 100)
    
    return {'Sharpe_Mean': float(np.mean(boot_sharpes)), 'Sharpe_Lower_95': float(lower_bound), 'Sharpe_Upper_95': float(upper_bound)}

# 模拟 200 笔具备稳定正期望的交易收益(合成数据,历史回测不代表未来)
rng = np.random.default_rng(42)
trades = pd.Series(rng.normal(0.005, 0.02, 200))

t_info = calculate_strategy_t_stat(trades)
boot_info = bootstrap_sharpe_confidence_interval(trades, n_iterations=1000, rng=rng)

print("================ 运气 vs 实力:统计显著性检验 ================")
print(f"交易样本量 N: {t_info['N_Trades']} 笔")
print(f"平均单笔收益: {t_info['Mean_Return']:.6f}")
print(f"超额收益 t 统计量: {t_info['T_Stat']:.4f} (临界值 1.645)")
print(f"统计显著性判定   : {t_info['Is_Statistically_Significant']} (排除纯运气)")
print(f"夏普 95% 置信区间: [{boot_info['Sharpe_Lower_95']:.2f}, {boot_info['Sharpe_Upper_95']:.2f}]")
# 断言仅用于教学演示,实际策略需结合经济逻辑与样本外测试
assert t_info['Is_Statistically_Significant'], "策略未能通过统计显著性检验!"
print("✅ 统计学假设检验与 Bootstrap 置信区间测试 PASS")
print("============================================================")

运行结果输出:

================ 运气 vs 实力:统计显著性检验 ================
交易样本量 N: 200 笔
平均单笔收益: 0.004391
超额收益 t 统计量: 3.5205 (临界值 1.645)
统计显著性判定   : True (排除纯运气)
夏普 95% 置信区间: [1.76, 6.11]
✅ 统计学假设检验与 Bootstrap 置信区间测试 PASS
============================================================
👉 点击查看解析

本练习通过模拟随机事件,直观展示了单次或少量尝试中运气会掩盖实力差距;随着尝试次数增加,真实水平的影响逐渐占据主导。

本章小结

  1. 用统计大数定律剥离运气:单笔或少量交易的大赚往往纯属运气,唯有 t>1.645t > 1.645 的大样本才能证明实力。
  2. 以 Bootstrap 下界评估风险:关注夏普比率在 95%95\% 置信度下的悲观下界,做好实盘降速心理准备。
  3. 警惕样本量过小的欺骗性:策略评估至少需要累积 100 笔以上独立交易样本,杜绝基于三五次交易妄下结论。

📋 行动清单 (Action Checklist)

  • 运行显著性检验代码,测试样本量缩减至 20 笔时的 tt 统计量变化;
  • 编写时序随机置换检验(Permutation Test)脚本;
  • 预习下一节,掌握量化策略上线实盘所需满足的硬性条件。

—— 小象教研组

配套资料 · 直接下载

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

  • 第10章课件:实盘中的细节问题讨论
    PDF · 1.7MB
    下载