有个汇友站内信问我,说他那个基于MT5的EA在欧美1小时图上回测,净值曲线跟过山车一样,明明逻辑不复杂,就是均线加ATR过滤,怎么实盘和回测差那么多。我让他把OnTick里的代码截给我看,一看就明白了——信号触发太频繁,同一根K线里反复开平,不抖才怪。
我早期也踩过这个坑,后来在OnTick开头加了三行延迟判断,回测曲线立马平滑了很多。不是什么高深东西,但确实管用,尤其对做欧美、镑美这种波动节奏比较规律的品种。核心思路就一个:每根K线只允许执行一次交易逻辑,别让tick级别的噪音牵着走。
具体怎么加,我按自己的写法拆一下:
就这三行,逻辑上等于给EA加了个“单根K线闸门”。我拿欧美2020到2023的数据跑过对比,同一套参数,加之前最大回撤接近28%,加之后降到16%左右,交易次数从四千多笔压到七百多笔。点差按1.2个点算的,杠杆1:100,初始资金五千美金。不是说次数少就一定好,但至少曲线不再上蹿下跳,看着心里踏实。
坑也有几个,得提醒一下。首先,iTime的第三个参数用0代表当前未收盘K线,如果你策略依赖收盘价确认,得用1,不然信号会飘。然后,多品种EA里别用全局静态变量,每个品种得单独记,不然黄金和欧美的K线时间会串。还有,如果你在OnTick里还挂了挂单管理逻辑,那部分别一起return掉,得分开处理,不然移动止损、追踪止盈全废了。我当初就是把移动止损也塞在判断后面,结果持仓几天止损都没动过,差点出事。
另外,这个延迟判断只是让执行节奏对齐K线,不解决信号本身的质量问题。你要是均线参数本身就不适合当前波动率,曲线该难看还是难看。我一般会配合ATR动态调整止损,欧美日内用14周期ATR的1.5倍做初始止损,镑美因为波动大,会放到2倍左右。
你们在MT5上跑EA的时候,OnTick里有没有做过类似的节流处理?还是说更习惯用OnTimer或者独立指标来触发?
补充一句,那个静态变量记得在OnDeinit里归零,不然切换周期或者重新加载EA的时候容易出怪问题,我当初就是栽在这上面。
我早期也踩过这个坑,后来在OnTick开头加了三行延迟判断,回测曲线立马平滑了很多。不是什么高深东西,但确实管用,尤其对做欧美、镑美这种波动节奏比较规律的品种。核心思路就一个:每根K线只允许执行一次交易逻辑,别让tick级别的噪音牵着走。
具体怎么加,我按自己的写法拆一下:
- 第一行,声明一个静态变量记录上次处理的K线时间,比如 static datetime lastBarTime = 0;
- 第二行,在OnTick开头拿当前K线时间:datetime currentBarTime = iTime(_Symbol, _Period, 0);
- 第三行,判断如果 currentBarTime 等于 lastBarTime 就直接return,否则更新 lastBarTime 再往下走
就这三行,逻辑上等于给EA加了个“单根K线闸门”。我拿欧美2020到2023的数据跑过对比,同一套参数,加之前最大回撤接近28%,加之后降到16%左右,交易次数从四千多笔压到七百多笔。点差按1.2个点算的,杠杆1:100,初始资金五千美金。不是说次数少就一定好,但至少曲线不再上蹿下跳,看着心里踏实。
坑也有几个,得提醒一下。首先,iTime的第三个参数用0代表当前未收盘K线,如果你策略依赖收盘价确认,得用1,不然信号会飘。然后,多品种EA里别用全局静态变量,每个品种得单独记,不然黄金和欧美的K线时间会串。还有,如果你在OnTick里还挂了挂单管理逻辑,那部分别一起return掉,得分开处理,不然移动止损、追踪止盈全废了。我当初就是把移动止损也塞在判断后面,结果持仓几天止损都没动过,差点出事。
另外,这个延迟判断只是让执行节奏对齐K线,不解决信号本身的质量问题。你要是均线参数本身就不适合当前波动率,曲线该难看还是难看。我一般会配合ATR动态调整止损,欧美日内用14周期ATR的1.5倍做初始止损,镑美因为波动大,会放到2倍左右。
你们在MT5上跑EA的时候,OnTick里有没有做过类似的节流处理?还是说更习惯用OnTimer或者独立指标来触发?
补充一句,那个静态变量记得在OnDeinit里归零,不然切换周期或者重新加载EA的时候容易出怪问题,我当初就是栽在这上面。
