一 初步测试
26年2月10日我先初步按教案的提示词,初步建了一个白银期货的双均线策略及回测,跑通了:
但细看收益率不高,还没有超过基准收益。
二 AI分析可提高方向
在PandaAI 回测平台上,通过AI分析,指出了可改进方向:
- 调参测试:系统性搜索均线参数组合,例如将短均线在3–10日、长均线在15–60日范围做网格或贝叶斯优化,看是否能把夏普提升到>1、回撤控制在<10%。
- 增加趋势过滤:如加入成交量、波动率或更长周期均线过滤,只在明确趋势阶段开仓,减少震荡期频繁进出导致的“磨损”。
- 增强仓位管理:目前仓位固定用总权益5%,可以尝试根据波动率或信号强度动态调整仓位,提高趋势段的资金利用率。
- 加入风险控制规则:如单笔止损比例、当日最大亏损/回撤限制,确保在放大收益尝试的同时控制极端风险。
然后我将改进方向,再贴回 回测代码AI助手,进行优化,
PandaAI CQ2 已经可以 进行对原代码进行改进,:
- "为“调参测试”做准备
- 这样你在不同回测配置中,只需在外部给 context 预置不同的参数(或在运行前注入),就能做网格/贝叶斯搜索,例如:
短均线:3–10
长均线:15–60
每组参数跑一次全区间回测,用引擎导出的夏普/回撤结果做筛选。
额外新增可调参数:
trend_filter_window:趋势过滤用的长周期均线长度
vol_window / risk_vol_window:波动率估计窗口
base_risk_fraction / max_notional_fraction / stop_loss_fraction / max_daily_loss_fraction
这些都通过 getattr(context, ‘xxx’, 默认值) 读取,便于统一做超参数搜索。"
2.2. 增加趋势过滤
2.1 长周期趋势过滤均线 & 斜率
新增参数:
context.trend_filter_window(默认 60 日)
context.trend_strength_threshold(默认 0.001,约 0.1% 级别斜率)
在 handle_data 中,用更长周期的均线和斜率判断是否处于明显趋势阶段:
只有当:
短/长均线出现金叉(原有信号),且
trend_ok == True(长周期趋势向上且斜率>阈值)
才允许开多仓:
if golden_cross and trend_ok:
buy_open(…)
这样可减少震荡期反复进出(“磨损”),重点参与较强趋势阶段。
你后续可以在调参时,尝试:
trend_filter_window:30 / 60 / 90
trend_strength_threshold:0.0005 / 0.001 / 0.002
观察对夏普和回撤的影响。
3.动态仓位管理
原逻辑:每次固定使用 5% 总权益换算手数。
新逻辑引入“风险预算 + 波动率”的思想:
3.1 参数
base_risk_fraction:基础风险资本比例(默认 0.02,即每笔承担约 2% 权益风险)
risk_vol_window:估计波动率的窗口长度(默认 20)
max_notional_fraction:单品种最大名义敞口占权益的比例(默认 0.2)
3.2 波动率估计 _calc_atr
简化实现:
对收盘价序列计算日收益率 rets = diff(price)/price 的标准差作为 atr_ratio,近似“每日百分比波动”。
atr_ratio = std(rets)
```
### 3.3 手数计算
1. 风险资本:
```python
risk_capital = total_value * base_risk_fraction
2.估算单手“典型日波动亏损”:
denom = close_price * contract_mul * atr_ratio
3.将风险资本转为目标手数:
target_hands_vol = risk_capital / denom
4.限制名义敞口不超过 max_notional_fraction * total_value:
max_notional = total_value * max_notional_fraction
max_hands_notional = max_notional / (close_price * contract_mul)
target_hands = int(max(1, min(target_hands_vol, max_hands_notional)))
含义:
波动率越高(atr_ratio 越大),同样风险预算下手数自动变小;
趋势稳健、波动适中时,手数有机会放大;
同时通过名义敞口上限防止过度集中在单品种
- 风险控制规则
4.1 当日最大亏损限制(“日内熔断”)
初始化:
在 before_trading 中记录 context.daily_start_value = 当日开盘前权益;
同时 context.daily_loss_locked = False。
在 handle_data 中:
current_value = futures_account.total_value
drawdown = (current_value - daily_start_value) / daily_start_value
if drawdown <= -max_daily_loss_fraction:
context.daily_loss_locked = True
"### 当日禁止再开新仓
在判断开仓前:
if context.daily_loss_locked:
print(“当日已触发最大亏损限制,禁止新开仓”)
return
这样可以防止单日连续受挫导致严重回撤,有利于将整体最大回撤压在 10% 水平附近(具体效果需回测验证)。
4.2 单笔止损
参数:
stop_loss_fraction(默认 0.01)。
逻辑:
有持仓时,取 avg_open_price 与当前 close_price 的跌幅:
price_drawdown = (close_price - avg_open_price) / avg_open_price
用 stop_loss_fraction 定义一个跌幅阈值(简化为固定百分比):
stop_dd_threshold = -context.stop_loss_fraction
当 price_drawdown <= stop_dd_threshold 且 closable_long > 0:
order = sell_close(…, closable_long, …)
并 return,避免同一 bar 再做其他操作。
这等价于单笔浮亏超过约 1% 时执行止损,你可在对比回测中测试 0.5% / 1% / 1.5% 对夏普与回撤的影响。
如果你希望用“ATR 多倍数”作为止损阈值,也可以把 stop_loss_fraction * atr_ratio 显式结合到价格阈值中,这里先用相对简单的百分比止损,方便配合参数搜索。
- 策略逻辑小结
开仓条件(多头)
满足以下全部:
当日未触发最大亏损限制(daily_loss_locked = False);
短均线 > 长均线(原双均线金叉);
长周期趋势过滤通过(趋势斜率 > trend_strength_threshold);
当前无多头持仓。
则按波动率自适应计算 target_hands,以市价买入开多。
平仓条件
止损平仓:
有多头,且 价格跌幅 <= -stop_loss_fraction 时,立即平掉所有可平多头;
死叉平仓:
有多头,短均线 < 长均线(死叉),平掉所有可平多头。
风控限制
单日权益从开盘起回撤超过 max_daily_loss_fraction(默认 3%)后,当日不再允许开新仓,只允许平仓或保持空仓。
三 AI还给了如何配合调参、优化夏普/回撤的建议 (留白)
- 如何配合调参、优化夏普/回撤
“在现有的回测/分析流程中,可以:
重点调的参数组合:
结构类:short_window ∈ [3,10],long_window ∈ [15,60];
趋势过滤:trend_filter_window ∈ [30, 60, 90],trend_strength_threshold ∈ [0.0005, 0.001, 0.002];
风险参数:
base_risk_fraction:1%~3%;
max_notional_fraction:10%~30%;
stop_loss_fraction:0.5%~1.5%;
max_daily_loss_fraction:2%~4%。
评价指标:
年化夏普 > 1;
最大回撤 < 10%;
同时比较换手率 / 交易次数,避免过度频繁交易。
搜索方式:
先用粗网格(步长较大)定位表现较好的区域;
再在该区域内用细网格或简单贝叶斯/随机搜索细调(由你在外部工具实现)。
如果你愿意,我可以在下一步帮你设计具体的“参数网格 + 回测批量运行 + 结果汇总”的脚本结构(在你的回测框架外部),方便一键搜索上述参数空间。”
四. 原策略超参调整后的回测结果
经过超参调整后,收益率比原先 上升不少!