MQL4 EA函数异常:无法获取指定时段内的真实高低点
修复MT4 EA特定时段高低点获取函数
原代码核心问题
- 24小时时间范围计算错误:依赖
Time[BarsInDay]获取过去24小时起点,但外汇周末休市会导致K线数量不足,无法准确对应24小时跨度。 - 跨天时段判断失效:若目标时段跨自然日(如22:00至次日02:00),原代码的时间区间判断会漏掉跨天部分的K线。
- 初始值逻辑错误:用
StartBar对应的K线高低值初始化,若该K线不在目标时段内,会引入无效初始值干扰结果。 - 冗余的
iBarShift调用:转换时间到K线索引的步骤多余,直接基于时间范围遍历更可靠。
修正后的代码
void FindHighLowWithinTimeFrame(int FunctStartHour, int FunctEndHour, double& FunctHighestHigh, double& FunctLowestLow) { int period = Period(); datetime currentTime = Time[0]; datetime past24hStart = currentTime - 86400; // 过去24小时的起点,86400秒=24小时 // 计算目标时段在过去24小时内的时间区间 datetime targetStart = past24hStart + FunctStartHour * 3600; datetime targetEnd = past24hStart + FunctEndHour * 3600; // 初始化极端值,确保任何有效K线都能覆盖初始值 double TempHighestHigh = -DBL_MAX; double TempLowestLow = DBL_MAX; bool hasValidBar = false; // 遍历过去24小时内的所有K线 for(int i = 0; i < Bars; i++) { // 超出过去24小时范围则停止遍历 if(Time[i] < past24hStart) break; bool isInTargetPeriod = false; // 处理跨天时段(如22点到次日2点) if(FunctEndHour > FunctStartHour) { isInTargetPeriod = (Time[i] >= targetStart && Time[i] <= targetEnd); } else { isInTargetPeriod = (Time[i] >= targetStart || Time[i] <= targetEnd); } if(isInTargetPeriod) { hasValidBar = true; if(High[i] > TempHighestHigh) TempHighestHigh = High[i]; if(Low[i] < TempLowestLow) TempLowestLow = Low[i]; } } // 若未找到有效K线,返回当前价格(或根据需求调整默认值) if(!hasValidBar) { FunctHighestHigh = Ask; FunctLowestLow = Bid; } else { FunctHighestHigh = TempHighestHigh; FunctLowestLow = TempLowestLow; } }
关键修改说明
- 准确的24小时范围:用
currentTime - 86400直接计算过去24小时起点,不受休市导致的K线数量变化影响。 - 跨天时段处理:通过判断
FunctEndHour和FunctStartHour的大小,调整时间区间的判断逻辑,覆盖跨自然日的时段。 - 安全的初始值:用
-DBL_MAX和DBL_MAX初始化高低值,确保第一个有效K线的高低值能正确替换初始值,避免无效初始值干扰结果。 - 高效遍历:从最新K线往回遍历,一旦超出过去24小时范围就停止,减少不必要的循环。
- 异常处理:添加
hasValidBar判断,避免目标时段内无K线时返回错误的极端值,可根据需求调整默认返回值。
内容的提问来源于stack exchange,提问作者Hammons2012
相关产品推荐
相关产品推荐

