//+------------------------------------------------------------------+ //| ObjectHighLowFiboMove.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.0" #property description "Create fibo lines on highs and lows of specified range of bars and update it on new bars formation." #property indicator_chart_window #property indicator_buffers 0 #property indicator_plots 0 #include "..\..\Include\ColorMix.mqh" input int BarOffset = 0; input int BarCount = 24; const string Prefix = "HighLowFiboMove-"; //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { static datetime now = 0; if(now != iTime(NULL, 0, 0)) // once per bar { const int hh = iHighest(NULL, 0, MODE_HIGH, BarCount, BarOffset); const int ll = iLowest(NULL, 0, MODE_LOW, BarCount, BarOffset); datetime t[2] = {iTime(NULL, 0, hh), iTime(NULL, 0, ll)}; double p[2] = {iHigh(NULL, 0, hh), iLow(NULL, 0, ll)}; DrawFibo(Prefix + "Fibo", t, p, clrGray); now = iTime(NULL, 0, 0); } return rates_total; } //+------------------------------------------------------------------+ //| Helper function for object creation and setup | //+------------------------------------------------------------------+ bool DrawFibo(const string name, const datetime &t[], const double &p[], const color clr) { if(ArraySize(t) != ArraySize(p)) return false; ObjectCreate(0, name, OBJ_FIBO, 0, 0, 0); // binding points for(int i = 0; i < ArraySize(t); ++i) { ObjectMove(0, name, i, t[i], p[i]); } // common settings ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, true); // level settings const int n = (int)ObjectGetInteger(0, name, OBJPROP_LEVELS); for(int i = 0; i < n; ++i) { const color gradient = ColorMix::RotateColors(ColorMix::HSVtoRGB(0), ColorMix::HSVtoRGB(359), n, i); ObjectSetInteger(0, name, OBJPROP_LEVELCOLOR, i, gradient); const double level = ObjectGetDouble(0, name, OBJPROP_LEVELVALUE, i); if(level - (int)level > DBL_EPSILON * level) { ObjectSetInteger(0, name, OBJPROP_LEVELSTYLE, i, STYLE_DOT); ObjectSetInteger(0, name, OBJPROP_LEVELWIDTH, i, 1); } else { ObjectSetInteger(0, name, OBJPROP_LEVELSTYLE, i, STYLE_SOLID); ObjectSetInteger(0, name, OBJPROP_LEVELWIDTH, i, 2); } } return true; } //+------------------------------------------------------------------+ //| Finalization handler | //+------------------------------------------------------------------+ void OnDeinit(const int) { ObjectsDeleteAll(0, Prefix); } //+------------------------------------------------------------------+