MultirangesInd/Multi Strategy Ranges Indicator.mq5

245 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"
#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<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);
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);
}
//+------------------------------------------------------------------+