//+------------------------------------------------------------------+ //| DonchianChannelBreakoutFilteredL1.mq5 | //| Copyright 2000-2026, MetaQuotes Ltd. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2000-2026, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" //--- Donchian breakout parameters input int DonchianPeriod = 21; //--- trade volume input double TradeLot = 0.1; // Lot size //--- L1 filter parameters input int L1TotalBars = 1000; // Total bars for L1 filter input bool L1FilterOpen = false; // Use filter for Open input bool L1FilterClose = false; // Use filter for Close input double L1CoefLambda = 0.2; // Lambda in lambda_max units //--- save statistics input bool SaveStatistics = false; // Save statistics to file //--- #define DONCHIAN_MAGIC 1234501 #include CTrade ExtTrade; bool ExtHedging = false; string ExtStrategyName="Donchian"; string ExtStrategyFileName=""; //+------------------------------------------------------------------+ //| Check new bar | //+------------------------------------------------------------------+ bool IsNewBar() { static datetime last_time = 0; datetime t[1]; if(CopyTime(_Symbol,_Period,0,1,t) > 0) { if(t[0] != last_time) { last_time = t[0]; return true; } } else { Print("CopyTime error: ", GetLastError()); ResetLastError(); } return false; } //+------------------------------------------------------------------+ //| CheckTrendL1 | //+------------------------------------------------------------------+ double CheckTrendL1() { int max_bars=L1TotalBars; MqlRates rates_data[]; ArrayResize(rates_data,max_bars); ArraySetAsSeries(rates_data,false); if(CopyRates(_Symbol,_Period,0,max_bars,rates_data) != max_bars) { Print("CopyRates failed for L1Trend"); return 0; } //--- prepare data (close prices vector) int data_count=max_bars; vector data_close; data_close.Resize(data_count); for(int i=0; i data_filtered; data_filtered.Resize(data_count); double delta=0.0; bool res=data_close.L1TrendFilter(L1CoefLambda,true,data_filtered); if(res) delta = data_filtered[data_count-1] - data_filtered[data_count-2]; //--- return delta; } //+------------------------------------------------------------------+ //| GetTradeSignal | //+------------------------------------------------------------------+ bool GetTradeSignal(ENUM_ORDER_TYPE &signal) { signal=WRONG_VALUE; MqlRates bars[]; ArraySetAsSeries(bars,true); if(CopyRates(_Symbol,_Period,1,DonchianPeriod+1,bars)<=DonchianPeriod) return false; double high=bars[1].high; double low=bars[1].low; for(int i=2;i<=DonchianPeriod;i++) { if(bars[i].high>high) high=bars[i].high; if(bars[i].lowhigh) signal=ORDER_TYPE_BUY; if(bars[0].close 0) { signal = WRONG_VALUE; //PrintFormat("Open SELL signal cancelled by L1 trend delta=%.5f", delta); } } //--- if(signal == WRONG_VALUE) return; //--- if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || Bars(_Symbol,_Period) 0) { close_signal = false; //PrintFormat("Close BUY signal cancelled by L1 trend delta=%.5f", delta); } if(type == POSITION_TYPE_SELL && delta < 0) { close_signal = false; //PrintFormat("Close SELL signal cancelled by L1 trend delta=%.5f", delta); } } //--- if(close_signal && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>=L1TotalBars) ExtTrade.PositionClose(_Symbol,3); } //+------------------------------------------------------------------+ //| SelectPosition | //+------------------------------------------------------------------+ bool SelectPosition() { bool res = false; if(ExtHedging) { uint total = PositionsTotal(); for(uint i=0; i