如何修复EA交易中Close[1]、Close[2]价格判断导致的开仓信号错误问题
问题排查与修复方案
核心问题定位
- 水平位计算基准与开仓判断基准不匹配:
check_nearest_levels函数原本基于Close[2]的价格区间计算上下水平位,但开仓判断时用的是Close[1]和Close[2]的相对位置,当Close[1]已经脱离Close[2]所在的价格区间时,旧区间计算出的Nearest_Up_Level/Nearest_Down_Level已经失效,直接用于判断会触发错误开仓。 - 数组越界风险:原
check_nearest_levels的循环逻辑中未对i+1做边界校验,当i等于ArraySize(Price_Levels)-1时,访问Price_Levels[i+1]会读取到无效值,进一步导致水平位计算错误。 - 开仓判断逻辑冗余:原代码中
isAvailableOrder()重复判断,可合并简化逻辑提升运行效率。
修复后代码
1. 修正check_nearest_levels函数
void check_nearest_levels(){ int size = ArraySize(Price_Levels); // 新增边界校验,避免数组越界 if(size < 2) return; // 改用Close[1]作为区间计算基准,匹配开仓判断的最新已收盘K线 double referencePrice = Close[1]; for (int i = 0; i < size - 1; i++){ // 循环上限改为size-1,避免i+1越界 if (referencePrice > Price_Levels[i] && referencePrice < Price_Levels[i + 1]){ Nearest_Down_Level = Price_Levels[i]; Nearest_Up_Level = Price_Levels[i + 1]; BUY_TP_Price = 0; if (size > i + 2) BUY_TP_Price = Price_Levels[i + 2]; else BUY_TP_Price = Nearest_Up_Level + StepPips * Point * mp; Next_BUY_TP_Price = 0; if (size > i + 3) Next_BUY_TP_Price = Price_Levels[i + 3]; else Next_BUY_TP_Price = BUY_TP_Price + StepPips * Point * mp; SELL_TP_Price = 0; if (i >= 1) SELL_TP_Price = Price_Levels[i - 1]; else SELL_TP_Price = Nearest_Down_Level - StepPips * Point * mp; Next_SELL_TP_Price = 0; if (i >= 2) Next_SELL_TP_Price = Price_Levels[i - 2]; else Next_SELL_TP_Price = SELL_TP_Price - StepPips * Point * mp; break; } } }
2. 修正OnTimer中的开仓判断逻辑
void OnTimer() { if (currBars != Bars){ calculate_price_levels(); check_nearest_levels(); if (is_session() && isAvailableOrder()){ // 基于最新计算的有效水平位判断两根收盘K线的穿越有效性 if (Close[2] < Nearest_Up_Level && Close[1] >= Nearest_Up_Level){ double lot = _get_lot_size(Stop_Loss); OpenTrade(Symbol(), OP_BUY, lot); } if (Close[2] > Nearest_Down_Level && Close[1] <= Nearest_Down_Level){ double lot = _get_lot_size(Stop_Loss); OpenTrade(Symbol(), OP_SELL, lot); } } currBars = Bars; } if (Trailing_Stop > 0) trail_sl(); int trades_number = _get_number_of_trades(); if (trades_number < Trades_Number_0) check_last_trade_result(); Trades_Number_0 = trades_number; }
可选优化建议
- 可在开仓判断中新增对
High[1]/Low[1]的校验,比如做多可增加条件Low[1] < Nearest_Up_Level,避免影线假突破导致的误开仓。 - 新增日志打印逻辑,输出每次新K线生成时的
Nearest_Up_Level、Nearest_Down_Level、Close[1]、Close[2]数值,方便后续问题排查。
内容的提问来源于stack exchange,提问作者comandante993fp
相关产品推荐
相关产品推荐

