因子类别 | 具体因子 | 计算方法 | 典型表现 |
---|---|---|---|
价值 | PE | 股价/每股收益 | 低PE长期超额收益 |
PB | 股价/每股净资产 | 低PB长期超额收益 | |
动量 | 收益率动量 | 过去N月收益率 | 12个月-1个月动量效应 |
ROE动量 | ROE环比变化 | 盈利改善超额收益 | |
质量 | ROE | 净利润/净资产 | 高ROE超额收益 |
毛利率 | 毛利/营收 | 高毛利率优势 | |
成长 | 营收增长 | 营收同比增长率 | 高增长溢价 |
流动性 | 换手率 | 成交量/流通股本 | 低换手率溢价 |
波动率 | 历史波动率 | 收益率标准差 | 低波动率异象 |
基本原理:寻找均值回归的价格关系
配对交易(Pairs Trading)
# 简化的配对交易逻辑
spread = stock_a - hedge_ratio * stock_b
if spread > upper_threshold: # 价差过大
sell_a_buy_b() # 卖A买B
elif spread < lower_threshold: # 价差过小
buy_a_sell_b() # 买A卖B
# 基本数据处理
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_csv('stock_data.csv')
# 计算技术指标
import talib as ta
data['sma20'] = ta.SMA(data['close'].values, 20)
data['rsi'] = ta.RSI(data['close'].values, 14)
# 可视化
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 6))
plt.plot(data['close'])
plt.plot(data['sma20'])
plt.show()
# Backtrader示例
class MyStrategy(bt.Strategy):
params = (('sma_period', 20),)
def __init__(self):
self.sma = bt.indicators.SMA(
self.data.close,
period=self.params.sma_period
)
def next(self):
if self.data.close[0] > self.sma[0]:
self.buy()
elif self.data.close[0] < self.sma[0]:
self.sell()
Zipline (前Quantopian平台)
vn.py
QuantConnect / Lean
自建系统
免费数据:
付费数据:
专业数据:
互联网数据:
社交媒体和新闻分析
卫星图像数据
定位数据
网络抓取数据
支付和交易数据
# 考虑涨跌停的买入函数示例
def buy_stock_cn(stock, price, amount):
# 检查涨跌停
high_limit = stock.prev_close * 1.1
low_limit = stock.prev_close * 0.9
if price >= high_limit:
price = high_limit
print("涨停限制")
# 实际下单逻辑
# ...
策略创意生成
代码生成与优化
研报/文档总结
数据检索与清洗
财报分析
新闻情感分析
社交媒体挖掘
策略动态调整
# Backtrader 核心对象
cerebro = bt.Cerebro() # 回测大脑
data = bt.feeds.XXXData() # 行情数据
strategy = bt.Strategy # 交易策略
broker = cerebro.broker # 交易代理
analyzer = bt.analyzers # 绩效分析
数据源类型
|
数据加载示例
|
策略类结构
|
策略关键方法
|
import backtrader as bt
# 1. 创建回测引擎
cerebro = bt.Cerebro()
# 2. 加载数据
data = bt.feeds.XXXData(dataname='data.csv')
cerebro.adddata(data)
# 3. 添加策略
cerebro.addstrategy(MyStrategy)
# 4. 设置初始资金
cerebro.broker.setcash(100000)
# 5. 设置手续费
cerebro.broker.setcommission(commission=0.001)
# 6. 添加分析器
cerebro.addanalyzer(bt.analyzers.SharpeRatio)
# 7. 运行回测
results = cerebro.run()
SharpeRatio
: 夏普比率DrawDown
: 最大回撤TradeAnalyzer
: 交易统计Returns
: 收益率PyFolio
: 组合分析# 添加多个分析器
cerebro.addanalyzer(bt.analyzers.SharpeRatio)
cerebro.addanalyzer(bt.analyzers.DrawDown)
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer)
# 绘制回测结果
cerebro.plot(
style='candlestick', # 蜡烛图样式
barup='green', # 上涨颜色
bardown='red' # 下跌颜色
)
# 保存回测图像
plt.savefig('backtest_result.png')
灵感来源
好的假设特征
买入条件:短期均线 < 长期均线
卖出条件:短期均线 > 长期均线
• 捕捉中长期趋势
• 降低频繁交易成本
缺失值处理
异常值处理
前视偏差避免
生存偏差修正
常见特征工程方法
# Z-score标准化
df['feature_z'] = (df['feature'] - df['feature'].mean())
/ df['feature'].std()
# MinMax归一化
df['feature_norm'] = (df['feature'] - df['feature'].min())
/ (df['feature'].max() - df['feature'].min())
# 交叉特征示例
df['vol_price_ratio'] = df['volume'] / df['close']
# 周期性时间特征
df['day_of_week'] = df.index.dayofweek
df['month'] = df.index.month
# 每个时间点的横截面排序
df['rank'] = df.groupby('date')['feature'].rank(pct=True)
常见信号生成方法
# RSI超买超卖信号
def rsi_signal(price, period=14, overbought=70, oversold=30):
rsi = ta.RSI(price, timeperiod=period)
signal = np.zeros(len(price))
signal[rsi < oversold] = 1 # 超卖买入信号
signal[rsi > overbought] = -1 # 超买卖出信号
return signal
# 移动平均交叉
def ma_cross(price, fast=5, slow=20):
fast_ma = ta.SMA(price, timeperiod=fast)
slow_ma = ta.SMA(price, timeperiod=slow)
signal = np.zeros(len(price))
signal[fast_ma > slow_ma] = 1 # 金叉买入
signal[fast_ma < slow_ma] = -1 # 死叉卖出
return signal
# 动量因子选股
def momentum_select(returns, n=10):
top_stocks = returns.nlargest(n)
return top_stocks.index.tolist()
回测设置
关键绩效指标
(收益-无风险)/波动率
(收益-无风险)/下行风险
年化收益/最大回撤
指标 | 计算方法 | 标准值 | 深度解读 |
---|---|---|---|
Sharpe比率 | >1: 良好 >2: 优秀 |
过高(>3)通常不可持续 应关注不同市场环境下的表现 |
|
最大回撤 | <20%: 一般接受 <15%: 优秀 |
关注回撤恢复时间 多次接近最大回撤是危险信号 |
|
Sortino比率 | >1.5: 良好 >2.5: 优秀 |
相比Sharpe更关注下行风险 大幅高于Sharpe说明收益非对称 |
|
Calmar比率 | >0.5: 一般 >1: 优秀 |
衡量承担回撤风险的回报 关注历史最差时期表现 |
|
胜率 | >55%: 高频策略预期 >40%: 趋势策略预期 |
高胜率低盈亏比vs低胜率高盈亏比 结合换手率分析 |
|
盈亏比 | >1.5: 良好 >2: 优秀 |
观察是否依赖少数极端盈利 结合持仓时间分析 |
# 网格搜索示例
best_sharpe = -np.inf
best_params = {}
for fast in range(5, 21, 5):
for slow in range(20, 101, 20):
if fast >= slow:
continue
params = {'fast': fast, 'slow': slow}
sharpe = backtest(params)
if sharpe > best_sharpe:
best_sharpe = sharpe
best_params = params
贝叶斯优化
遗传算法
样本外测试
交叉验证(时间序列折叠)
# 时间序列交叉验证
def time_series_cv(data, n_splits=5):
results = []
fold_size = len(data) // n_splits
for i in range(1, n_splits):
train = data[:(i * fold_size)]
test = data[(i * fold_size):((i+1) * fold_size)]
sharpe = backtest(train, test)
results.append(sharpe)
return results # 观察稳定性
参数敏感性测试
多市场、多周期验证
参数过拟合
回测周期选择性偏差
多重测试谬误
过拟合的代价:
头寸限制
止损策略
# 移动止损示例
def trailing_stop(current_price, high_since_entry, stop_percent=0.1):
stop_price = high_since_entry * (1 - stop_percent)
if current_price < stop_price:
return True # 触发止损
return False
固定分数法
# 固定分数资金管理
def position_size(account_equity, risk_per_trade=0.01):
return account_equity * risk_per_trade
波动率调整法
# 波动率调整仓位
def volatility_sized_position(equity, volatility, target_vol=0.2):
"""根据波动率调整持仓"""
leverage = target_vol / volatility
leverage = min(max(leverage, 0.5), 2.0) # 限制杠杆范围
return equity * leverage
Kelly准则及其变种
# Kelly准则仓位
def kelly_position(win_rate, win_loss_ratio):
"""
win_rate: 胜率
win_loss_ratio: 平均盈利/平均亏损
"""
kelly = win_rate - (1 - win_rate) / win_loss_ratio
# 通常使用半Kelly或更保守的分数
return max(0, kelly * 0.5)
恒定风险模型 (风险平价)
流动性与冲击成本
系统延迟
交易机制
执行系统
数据系统
策略监控指标
风险监控
系统监控
预定义干预条件
灾备系统
# 简单监控报警示例
def monitor_drawdown(equity_curve, max_drawdown_alert=0.15):
"""当回撤超过阈值时发出警报"""
current_drawdown = calculate_drawdown(equity_curve)
if current_drawdown > max_drawdown_alert:
send_alert(f"警告: 回撤达到{current_drawdown:.2%}")
建议分工
技术分析策略
动量/反转策略
多因子策略
事件驱动策略
行业/板块轮动策略
策略设计阶段
"我想开发一个基于[动量/均值回归]的策略,
针对[A股/美股]市场。
请帮我分析这种策略的优缺点和关键参数选择。"
编码实现阶段
"请帮我用Backtrader实现一个[策略名称],
需要包含以下功能:
1. [具体功能要求]
2. [风险控制机制]
3. [性能评估指标]"
问题解决阶段
"我在实现[具体功能]时遇到了[具体问题],
错误信息是[错误详情],如何解决这个问题?"
结果分析阶段
"我的策略回测结果如下:[提供关键指标]
请分析这些结果,并提出可能的改进方向。"
记住:大语言模型是辅助工具,最终决策和理解应由小组成员主导!
每组展示5-7分钟,应包含以下内容:
### 量化优势示例 期货CTA策略中,人工很难24小时监控所有品种,而量化系统可以同时监控数十种品种并快速响应。
--- # Backtrader:Python量化交易回测框架 ## 全面解析量化策略开发利器
--- ## 目录 1. Backtrader 简介 2. 框架核心组件 3. 数据处理 4. 策略开发 5. 回测流程 6. 高级特性 7. 实战案例
可滚动代码区域
<div style="overflow-y: auto; max-height: 400px; border: 1px solid #ddd; border-radius: 4px; background-color: #f5f5f5; padding: 8px; font-family: monospace; font-size: 14px; line-height: 1.4;">
</div>
## 实战案例:均线策略
可滚动代码区域
<div style="overflow-y: auto; max-height: 400px; border: 1px solid #ddd; border-radius: 4px; background-color: #f5f5f5; padding: 8px; font-family: monospace; font-size: 14px; line-height: 1.4;"> ```python class MACrossStrategy(bt.Strategy): params = ( ('short_period', 10), ('long_period', 30), ) def __init__(self): self.sma_short = bt.indicators.SMA( self.data.close, period=self.p.short_period ) self.sma_long = bt.indicators.SMA( self.data.close, period=self.p.long_period ) self.crossover = bt.indicators.CrossOver( self.sma_short, self.sma_long ) def next(self): if not self.position: if self.crossover > 0: self.buy() else: if self.crossover < 0: self.close() ``` </div>
```python # 异常值处理示例 def winsorize(s, limits=(0.05, 0.05)): """ 限制数列极端值 """ lower = s.quantile(limits[0]) upper = s.quantile(1 - limits[1]) s_winsorized = s.clip(lower=lower, upper=upper) return s_winsorized ```
--- ## 实例演示:均值回归A股单因子策略 <div style="display: flex; justify-content: space-between;"> <div style="width: 55%;"> ```python import backtrader as bt import pandas as pd import numpy as np import matplotlib.pyplot as plt # 策略定义 class MeanReversionStrategy(bt.Strategy): params = ( ('lookback', 20), # 均值回归周期 ('std_dev', 2.0), # 标准差阈值 ('pct_position', 0.95), # 仓位比例 ('stop_loss', 0.05), # 止损比例 ) def __init__(self): # 计算移动平均和标准差 self.sma = bt.indicators.SMA(self.data.close, period=self.p.lookback) self.stddev = bt.indicators.StdDev(self.data.close, period=self.p.lookback) # 跟踪最新价格,用于移动止损 self.highest_price = 0 def next(self): # 计算Z-score z_score = (self.data.close[0] - self.sma[0]) / self.stddev[0] # 均值回归信号 # 价格显著低于均值,买入信号 if z_score < -self.p.std_dev and not self.position: size = int(self.broker.getcash() * self.p.pct_position / self.data.close[0]) self.buy(size=size) self.highest_price = self.data.close[0] # 价格回归均值,或显著高于均值,卖出信号 elif (z_score > 0 or z_score > self.p.std_dev) and self.position: self.close() # 移动止损检查 if self.position: if self.data.close[0] > self.highest_price: self.highest_price = self.data.close[0] # 如果从最高点下跌超过止损比例,则止损 if self.data.close[0] < self.highest_price * (1 - self.p.stop_loss): self.close() ``` </div> <div style="width: 42%;"> ```python # 回测执行 cerebro = bt.Cerebro() cerebro.addstrategy(MeanReversionStrategy) # 加载数据 data = bt.feeds.YahooFinanceData( dataname='600519.SS', # 贵州茅台 fromdate=datetime(2018, 1, 1), todate=datetime(2022, 12, 31) ) cerebro.adddata(data) # 设置资金和佣金 cerebro.broker.setcash(100000.0) cerebro.broker.setcommission(commission=0.0003) # 万三佣金 # 添加分析器 cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe') cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown') cerebro.addanalyzer(bt.analyzers.Returns, _name='returns') cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='trades') # 执行回测 results = cerebro.run() strat = results[0] # 打印结果 print(f"夏普比率: {strat.analyzers.sharpe.get_analysis()['sharperatio']:.2f}") print(f"最大回撤: {strat.analyzers.drawdown.get_analysis()['max']['drawdown']:.2f}%") print(f"年化收益: {strat.analyzers.returns.get_analysis()['year']:.2f}%") # 绘制结果 cerebro.plot(style='candlestick') ``` </div> </div>
## 评分标准与各阶段建议 ### 评分标准 (100分) - **策略创新性**(20%):策略思路的原创性与合理性 - **实现完整度**(20%):代码质量与完整性,风险控制机制 - **回测效果**(15%):Sharpe比率、最大回撤等指标 - **展示质量**(15%):表达清晰度、答疑能力 - **课堂参与**(30%):小组内协作、对他组的建设性意见 ### 各阶段时间建议 1. **小组形成**(5分钟) 2. **策略构思**(15分钟) - 确定交易标的、策略类型和核心假设 - 讨论理论依据和预期效果 3. **编码实现**(45分钟) - 数据获取与处理 - 信号生成与策略实现 - 回测框架搭建 4. **结果分析与展示准备**(15分钟) - 绩效评估与可视化 - 准备展示要点 ---