248 lines
18 KiB
MQL5
248 lines
18 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| 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.50"
|
|
#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 g_day_to_del;
|
|
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);
|
|
|
|
|
|
//---
|
|
// 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);
|
|
|
|
//---
|
|
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);
|
|
ICTGlobalManager::OnNewBarM1(curr_time, new_day);
|
|
|
|
//--- Day
|
|
if(new_day && TESTER_FLAG)
|
|
{
|
|
static int counter = 0;
|
|
counter++;
|
|
|
|
if(counter >= g_day_to_del)
|
|
{
|
|
strategy.DeleteAll();
|
|
counter=0;
|
|
}
|
|
}
|
|
|
|
//--- Current
|
|
if(rates_total > prev_calculated)
|
|
{
|
|
//---
|
|
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);
|
|
}
|
|
//+------------------------------------------------------------------+
|