//+------------------------------------------------------------------+ //| Multi Strategy Ranges Indicator.mq5 | //| Copyright 2025, Niquel and Leo | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Niquel and Leo" #property link "https://www.mql5.com" #property version "1.40" #property indicator_chart_window #property strict #property icon "Logo-Empresa-Nique.ico" #property description "Detects consolidation ranges and generates signals based on three strategies:" #property description "Direct breakout, breakout with retest, and false breakout with re-entry." #property description "Fully customizable in size, color, and style." #property indicator_buffers 2 #property indicator_plots 2 #property indicator_label1 "Buy Signal" #property indicator_type1 DRAW_ARROW #property indicator_color1 clrLimeGreen #property indicator_width1 1 #property indicator_label2 "Sell Signal" #property indicator_type2 DRAW_ARROW #property indicator_color2 clrFireBrick #property indicator_width2 1 //+------------------------------------------------------------------+ //| Include | //+------------------------------------------------------------------+ #include "Src\\MultyEstrategieRange.mqh" //+------------------------------------------------------------------+ //| Inputs | //+------------------------------------------------------------------+ sinput group "--- General ---" input ENUM_MODE_STRATEGY_RANGE strategy_mod = RANGE_STRATEGY_BREAKOUT; //Select the type of strategy: input ENUM_TIMEFRAMES strategy_tf = PERIOD_CURRENT; //Select the strategy timeframe: sinput group "--> Range breakout and retest strategy " input int max_espera_reetest = 40; //Maximum wait for retest in range (in bars) input ENUM_TYPE_RETEST_RANGE type_retest = RETEST_NO_STRICT; //is retesting in range strict? sinput group "--> Range breakout and re-entry strategy 'manipulation' " input int max_espera_re_entry = 40; //Maxima waits for range re-entry (in bars) sinput group " " sinput group "-------- Range -------- " sinput group "--- Min/Max ---" input ENUM_GET_SWING inp_type_get_swing = PURE_SWINGS; //Mode to obtain maximum and minimum values sinput group "-- Get Min/Max By Swings lows/highs " input short lenth_swing = 3; //High and low swing (number of candles) sinput group "-- Get Min/Max By ZigZag" input short period_zz = 4; //ZigZag period sinput group " " sinput group "----- Max diff -----" input string coment1 = "Maximum difference between swings high or swings low to detect the range"; // Rules of range: input ENUM_MODE_DIFF inp_type_max_diff = MODE_DIFF_BY_ATR; //Type Max diff sinput group "--- Max Diff ATR ---" input double inp_atr_multiplier = 1.05; //Atr multiplier input int inp_atr_period = 50; //Atr period //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ sinput group "--- Max Diff Fixed (in points) ---" input double max_diff_in_high_lows_range_in_points = 120;//Max diff in points sinput group "--- Graphic configurations of the rectangle ---" input bool fill_rect_range = true; //Fill Rectangle? input color clr_range = clrBisque; //Color of Rectangle input ENUM_LINE_STYLE style_range = STYLE_SOLID; //Rectangle Style input int width_range = 1; //Line Width of Rectangle sinput group "--- Alerts ----" input bool enable_alerts = true; //Enable alerts? input string range_alerts_flasg = "Notification|Alert"; //Select the type of alert: //+------------------------------------------------------------------+ //| Global Variables | //+------------------------------------------------------------------+ CRangeEstrategie strategy(_Symbol, strategy_tf, 0, 0, true, strategy_mod); double Buy[]; double Sell[]; int max_heigh_r; bool tester_flag; bool high_tmf; datetime tiempo_ultima_vela_1; int8_t idx_new_day; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- ICTGlobalManager::OnInitEvent(&bar_manager); bar_manager.GetPosExecute(PERIOD_D1, idx_new_day); //--- high_tmf = PeriodIsBig(strategy_tf); int16_t l = inp_type_get_swing == PURE_SWINGS ? lenth_swing : period_zz; double mul = inp_type_max_diff == MODE_DIFF_BY_ATR ? inp_atr_multiplier : max_diff_in_high_lows_range_in_points; CAtr* h = new CAtr(); h.Create(strategy_tf, _Symbol, inp_atr_period, true); h.SetAsSeries(true); strategy.SetProperties(clr_range, width_range, fill_rect_range, style_range, l, inp_type_get_swing, 500, CreateDiffptr(inp_type_max_diff, _Symbol, h, 1, mul)); strategy.SetPropertiesRangeByRestest(type_retest); strategy.SetAlertas(range_alerts_flasg, enable_alerts); if(strategy_mod == RANGE_STRATEGY_BREAKOUT_AND_RETEST) { strategy.SetEspera(max_espera_reetest); } else if(strategy_mod == RANGE_STRATEGY_REENTRY) { strategy.SetEspera(max_espera_re_entry); } ICTGlobalManager::AddAtrToContainer(h); //--- indicator buffers mapping IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("%s[%d]", "Multi Strategy Ranges Indicator", l)); IndicatorSetInteger(INDICATOR_DIGITS, _Digits); SetIndexBuffer(0, Buy, INDICATOR_DATA); ArraySetAsSeries(Buy, true); PlotIndexSetString(0, PLOT_LABEL, "Buy Signal"); PlotIndexSetInteger(0, PLOT_ARROW, 233); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0); SetIndexBuffer(1, Sell, INDICATOR_DATA); ArraySetAsSeries(Sell, true); PlotIndexSetString(1, PLOT_LABEL, "Sell Signal"); PlotIndexSetInteger(1, PLOT_ARROW, 234); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { //--- const datetime curr_time = TimeCurrent(); bar_manager.Execute(curr_time); //--- if(prev_calculated == 0 && rates_total > 500) { SignalRange signals[]; strategy.InitPrev(490, signals); //ArrayPrint(signals); for(int i = 0 ; i <= 500 ; i++) { Buy[i] = 0.0; Sell[i] = 0.0; } for(int i = 0; i < ArraySize(signals) ; i++) { int index = iBarShift(_Symbol, _Period, signals[i].entry_time); //Print("index: " , index ," time: " , signals[i].entry_time ); if(index == -1) continue; // Print("Tipo de la señal: " , EnumToString(signals[i].type_signal)); if(signals[i].type_signal == SIGNAL_ENTRY_BUY) { Buy[index] = signals[i].entry_price; continue; } else if(signals[i].type_signal == SIGNAL_ENTRY_SELL) { Sell[index] = signals[i].entry_price; continue; } } } //--- if(CNewBarManager_IsNewBarM1(bar_manager)) { const bool new_day = CNewBarManager_IsNewBar(bar_manager, idx_new_day); if(rates_total > prev_calculated) { ICTGlobalManager::OnNewBarM1(curr_time, new_day); //--- if(new_day) { if(tester_flag && high_tmf == false) { static int counter = 0; counter++; if(counter >= 3) { strategy.DeleteAll(); } } } //--- strategy.OnNewBar(curr_time); //--- if(strategy.GetBuyPrice() > 0) { Buy[0] = iLow(_Symbol, _Period, 1); } else if(strategy.GetSellPrice() > 0) { Sell[0] = iHigh(_Symbol, _Period, 1); } } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- ICTGlobalManager::OnDeinitEvent(reason); } //+------------------------------------------------------------------+