MultirangesInd/Multi Strategy Ranges Indicator.mq5

249 lines
18 KiB
MQL5
Raw Permalink Normal View History

2026-04-15 07:12:09 -05:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| 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"
2026-04-16 07:16:24 -05:00
#property version "1.50"
2026-04-15 07:12:09 -05:00
#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[];
2026-04-15 10:11:20 -05:00
int g_day_to_del;
2026-04-15 07:12:09 -05:00
int8_t idx_new_day;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
ICTGlobalManager::OnInitEvent(&bar_manager);
bar_manager.GetPosExecute(PERIOD_D1, idx_new_day);
//---
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);
2026-04-15 10:11:20 -05:00
//---
// 9960
// La idea es eliminar luego de 9960 velas (esto lo saque de M1 considero que 7 dias en m1 ya podemos ir eliminado...)
// asi que lo tome de referencioa enotnces la idea es esta:
// priomero claculos 9960 velas por la duracion en seugndos del tf y aesot le divido 86400 que es el numero de seugndo en un dia
// con esto nos da el numero de dias que tendremos que esperar
g_day_to_del = int((9960 * PeriodSecondsFastSeg(_Period)) / 86400);
2026-04-15 07:12:09 -05:00
//---
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<00>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);
2026-04-15 10:11:20 -05:00
ICTGlobalManager::OnNewBarM1(curr_time, new_day);
//--- Day
if(new_day && TESTER_FLAG)
2026-04-15 07:12:09 -05:00
{
2026-04-15 10:11:20 -05:00
static int counter = 0;
counter++;
2026-04-15 07:12:09 -05:00
2026-04-15 10:11:20 -05:00
if(counter >= g_day_to_del)
2026-04-15 07:12:09 -05:00
{
2026-04-15 10:11:20 -05:00
strategy.DeleteAll();
counter=0;
2026-04-15 07:12:09 -05:00
}
2026-04-15 10:11:20 -05:00
}
2026-04-15 07:12:09 -05:00
2026-04-15 10:11:20 -05:00
//--- Current
if(rates_total > prev_calculated)
{
2026-04-15 07:12:09 -05:00
//---
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);
}
//+------------------------------------------------------------------+