//+------------------------------------------------------------------+ //| FractalLines | //| Copyright 2024, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property strict #property indicator_chart_window #property indicator_buffers 0 #property indicator_color1 clrRed #property indicator_color2 clrBlue #property indicator_width1 2 #property indicator_width2 2 #property indicator_style1 STYLE_SOLID #property indicator_style2 STYLE_SOLID input int FractalBars = 5; // Количество баров для расчета фрактала //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Удаление всех объектов типа OBJ_TREND при удалении индикатора for (int i = ObjectsTotal() - 1; i >= 0; i--) { string objName = ObjectName(i); if (ObjectGetInteger(0, objName, OBJPROP_TYPE) == OBJ_TREND) { ObjectDelete(objName); } } } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { // Обрабатываем все бары, начиная с бара с индексом FractalBars до предпоследнего for (int i = FractalBars; i < rates_total - 2; i++) { if (IsFractalUp(i, FractalBars)) { for (int j = i + 1; j < rates_total - 2; j++) { if (IsFractalUp(j, FractalBars)) { if (high[i] > high[j]) { DrawLine("UpFractal_" + TimeToString(time[i]) + "_" + TimeToString(time[j]), time[j], high[j], time[i], high[i], clrRed); } break; } } } if (IsFractalDown(i, FractalBars)) { for (int j = i + 1; j < rates_total - 2; j++) { if (IsFractalDown(j, FractalBars)) { if (low[i] < low[j]) { DrawLine("DownFractal_" + TimeToString(time[i]) + "_" + TimeToString(time[j]), time[j], low[j], time[i], low[i], clrBlue); } break; } } } } return(rates_total); } //+------------------------------------------------------------------+ //| Function to check if a fractal up | //+------------------------------------------------------------------+ bool IsFractalUp(int i, int bars) { if (i < bars || i >= Bars - bars) return(false); for (int k = 1; k <= bars; k++) { if (High[i] <= High[i - k]) return(false); } for (int k = 1; k <= bars; k++) { if (High[i] <= High[i + k]) return(false); } return(true); } //+------------------------------------------------------------------+ //| Function to check if a fractal down | //+------------------------------------------------------------------+ bool IsFractalDown(int i, int bars) { if (i < bars || i >= Bars - bars) return(false); for (int k = 1; k <= bars; k++) { if (Low[i] >= Low[i - k]) return(false); } for (int k = 1; k <= bars; k++) { if (Low[i] >= Low[i + k]) return(false); } return(true); } //+------------------------------------------------------------------+ //| Function to draw lines between fractals | //+------------------------------------------------------------------+ void DrawLine(string name, datetime time1, double price1, datetime time2, double price2, color lineColor) { if (ObjectFind(0, name) == -1) { ObjectCreate(0, name, OBJ_TREND, 0, time1, price1, time2, price2); ObjectSetInteger(0, name, OBJPROP_COLOR, lineColor); ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, true); ObjectSetInteger(0, name, OBJPROP_WIDTH, 1); } else { ObjectMove(0, name, 0, time1, price1); ObjectMove(0, name, 1, time2, price2); } }
Defort
Defort