冷清3.7

EA开仓时间窗口控制 - 从入门到避坑

听风入梦 听风入梦
2026-8-10 10:19
17 0 1分钟
XM 推荐平台

覆盖品种全,新手友好,支持多种入金方式

CySEC(塞浦路斯) / ASIC(澳洲) / IFSC(伯利兹) · 最低入金 $5
新汇友(注册会员) 等级 Lv.1 主题 1 帖数 1 积分 970
听风入梦
听风入梦 楼主
2 小时前
1楼
最近在调一个马丁格尔的EA,回测数据挺漂亮,实盘跑了两周突然发现周五晚上22点后它还在开新单,直接把浮亏拉爆了。排查半天,问题就出在时间窗口控制上——我用的是MT4的TimeCurrent(),但没考虑到经纪商服务器时间和本地时间的偏差,结果周五提前收盘那会儿,服务器时间已经过了23:59,我的判断条件还傻乎乎地认为在交易时段内。这坑踩得我肉疼,今天就专门说说这个。
先说最基础的写法。很多人用Hour()和Minute()直接取服务器时间,然后跟预设窗口比较,比如限制只在亚盘和欧盘重叠时段(15:00-23:00)开仓,代码大概这样:

bool IsTradingTime() {
int hour = Hour();
return (hour >= 15 && hour < 23);
}
这写法看着没毛病,但有个致命缺陷——它忽略了分钟精度。假设你设23:00截止,那23:00:30秒开进来的单子照样算数,因为Hour()返回的是23,条件成立。我那个EA就是这么中招的,周五晚上22:59:58发了市价单,正好卡在最后两秒。解决办法很简单,用TimeCurrent()配合MathMod()精确到秒,或者干脆把分钟也纳入判断:

bool IsTradingTime() {
datetime now = TimeCurrent();
int minutes = (int)(now % 3600) / 60;
int hour = (int)(now % 86400) / 3600;
int totalMinutes = hour * 60 + minutes;
return (totalMinutes >= 900 && totalMinutes < 1380); // 15:00~23:00
}
这写法能精确到分钟,但还有个更隐蔽的坑——经纪商的夏令时切换。我用的某平台每年3月和10月服务器时间会跳一小时,如果EA里写死15:00,夏令时后实际对应的本地时间就变成14:00,策略逻辑全乱。处理办法是不要写死,用UTC偏差动态计算。比如先获取服务器与UTC的差值:

int utcOffset = (int)(TimeCurrent() - TimeGMT()) / 3600;
然后基于这个偏移量换算你想要的本地交易时段。这样就算平台切换夏令时,你的窗口也跟着自动调整,不用每年手动改代码。我现在的EA都是这么干的,省心。
再说一个很多人忽略的点:周末和节假日过滤。光控制日内时间不够,还得检查DayOfWeek()和是否处于假期。比如周五晚上23:00后,即便你设了窗口,也可能因为经纪商提前收盘导致点差拉爆,这时候开单纯粹送人头。我的做法是加一个前置判断:

bool IsValidDay() {
int day = DayOfWeek();
if(day == 0 || day == 6) return false; // 周末
if(day == 5 && Hour() >= 22) return false; // 周五22点后禁止
return true;
}
注意这里Hour()用的是服务器时间,所以前面说的夏令时问题同样会影响这个判断,所以还是建议把整段逻辑统一用UTC偏移处理。
最后提个实操建议:如果你要测试时间窗口逻辑,别光靠回测,用MT4的策略测试器里的可视化模式,把速度调慢,盯着右下角的服务器时间看开单点是否精确落在你设定的边界上。我之前就是偷懒直接跑完看报告,结果边界问题全被平均数据掩盖了。另外,如果你同时跑多个EA,记得在全局变量里存一个时间戳,避免不同EA对同一时间点重复判断,引发冲突。
大概就这些,都是血泪教训。你们在写时间窗口控制的时候有没有遇到过别的奇葩情况?比如某些平台周五提前到21:55收盘的,或者非农数据前后延迟开市的,欢迎交流下处理方案。
0 回复 复制
#1
💬
暂无回复,来抢沙发吧!
- THE END -
本帖内容仅供学习交流,不构成任何投资建议。外汇交易存在高风险,请谨慎参与。
← 上一帖 新手求助:点差和滑点怎么理解