查看全课大纲(第 53 / 59 节)
- 1.量化投资必备基础知识
- 2.趋势型策略及模型原理
- 3.均值回复型策略及模型原理
- 4.配对交易策略及模型原理
- 5.量化策略研发流程与基本技能
- 6.常用的量化平台概述及如何选择
- 7.如何量化一个主观策略思路
- 8.常用技术指标及指标计算过程
- 9.如何编写指标代码
- 10.指标的物理意义
- 11.技术指标的应用技巧
- 12.更多的交易决策
- 13.编写程序去量化一个趋势型技术指标
- 14.编写趋势型技术指标的性能评价
- 15.策略对交易成本和持仓周期的影响
- 16.股票池策略的原理及基本框架
- 17.基于多因子分析的股票池设计与实现
- 18.股票池的性能评估
- 19.使用定制化财务因子构建股票池
- 20.趋势型策略原理及股票池机制的设计
- 21.趋势型择时信号的设计方法与编程实现
- 22.趋势型策略的回测与性能评估
- 23.优化趋势型策略的思路及方法
- 24.量化体系中的风险控制思想
- 25.风险的度量-波动率
- 26.常用的风险控制方法
- 27.实现止盈止损模块以提高策略性能
- 28.策略性能的评估与优化
- 29.探讨波动率与风险的关系
- 30.量化策略中的经典资金管理模型
- 31.用python编程实现资金管理模块
- 32.构建一个完善的量化交易策略
- 33.趋势型量化策略必备的期货知识
- 34.期货量化工具介绍
- 35.商品期货趋势型策略原理
- 36.用TB编写商品期货趋势型策略(上)
- 37.用TB编写商品期货趋势型策略(下)
- 38.分析优化商品期货趋势型策略的方法思路
- 39.期货交易策略的注意事项
- 40.均值回复型策略的原理
- 41.A股市场有没有稳定的均值回复效应?
- 42.编写一个均值回复型股票量化策略
- 43.编写多空组合策略进行策略改进
- 44.在策略中实现头寸管理进行策略优化
- 45.套利策略原理及常见套利类型
- 46.用MC开发一个跨品种套利交易策略(上)
- 47.用MC开发一个跨品种套利交易策略(下)
- 48.统计套利之股票配对交易策略
- 49.实盘中的细节问题:加减仓
- 50.关于高频交易
- 51.如何评价实盘量化策略的性能
- 52.量化系统的工作过程及研发流程
- 53.运气or实力
- 54.量化实盘交易需要满足什么条件
- 55.未来函数的坑
- 56.实盘数据接口异常的自动报警
- 57.交易系统的压力测试
- 58.自动运行的交易策略,什么时候需要人工干预
- 59.预案准备和实盘心理建设
运气or实力
约 12 分钟
📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)
小象实战讲义 · 进阶量化交易实战:迭代式的量化策略研发 本讲义仅用于编程与量化方法教学,不构成任何投资建议。
在随机游走的金融市场中,短期大赚究竟是策略具备真实 Alpha(实力),还是仅仅碰巧赶上了市场风格(运气)?本节深入剖析假设检验、-统计量、拔靴法(Bootstrap 重抽样)以及蒙特卡洛随机置换检验,教你用严密统计学工具剥离运气的幻觉。
💡 核心导读
- 辨别量化实力与运气的四大统计学工具:
- -统计量与 -value 检验:检验策略超额收益均值是否显著大于 0(单侧检验:, );
- 拔靴法重抽样(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│ │ • 识破过拟合假象 │
└─────────────────────────┘ └─────────────────────────┘ └─────────────────────────┘一、夏普比率 -统计量与置信度检验数学推导
设策略拥有 笔独立交易记录,样本均值为 ,标准差为 。检验零假设 的 -统计量为:
当交易笔数 时,即便年化收益很高, 统计量往往也无法突破单侧检验临界值 (无法排除纯运气成分)。(临界值口径:/ 是大样本正态近似值;小样本(如 )应改用自由度 的 分布临界值,如单侧 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 次以收窄蒙特卡洛误差),计算夏普比率在 置信度下的最悲观下界。(假设提示:标准 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
============================================================👉 点击查看解析
本练习通过模拟随机事件,直观展示了单次或少量尝试中运气会掩盖实力差距;随着尝试次数增加,真实水平的影响逐渐占据主导。
本章小结
- 用统计大数定律剥离运气:单笔或少量交易的大赚往往纯属运气,唯有 的大样本才能证明实力。
- 以 Bootstrap 下界评估风险:关注夏普比率在 置信度下的悲观下界,做好实盘降速心理准备。
- 警惕样本量过小的欺骗性:策略评估至少需要累积 100 笔以上独立交易样本,杜绝基于三五次交易妄下结论。
📋 行动清单 (Action Checklist)
- 运行显著性检验代码,测试样本量缩减至 20 笔时的 统计量变化;
- 编写时序随机置换检验(Permutation Test)脚本;
- 预习下一节,掌握量化策略上线实盘所需满足的硬性条件。
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载第10章课件:实盘中的细节问题讨论PDF · 1.7MB