//+------------------------------------------------------------------+ //| MarketProfile.mq5 | //| Copyright 2009-2025, MetaQuotes Ltd | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property indicator_chart_window #property indicator_plots 0 //--- input parameters input uint InpStartDate =0; // day number to start calculation input uint InpShowDays =3; // number of days to display input int InpMultiplier =1; // histogram length multiplier input color InpAsiaSession =clrGold; // Asian session input color InpEuropeSession =clrBlue; // European session input color InpAmericaSession =clrViolet; // American session input uint InpEuropeStartHour =8; // European session opening hour input uint InpAmericaStartHour=14; // American session opening hour //--- unique prefix to identify indicator objects string ExtPrefixUniq; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- prepare prefix for objects string number=StringFormat("%I64d", GetTickCount64()); ExtPrefixUniq=StringSubstr(number, StringLen(number)-4); Print("Indicator \"Market Profile\" started, prefix=", ExtPrefixUniq); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 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[]) { //--- opening time of the current daily bar datetime static open_time=0; //--- number of the last day for calculations uint lastday=InpStartDate+InpShowDays; //--- if the calculation has already been done if(prev_calculated!=0) { datetime current_open=iTime(Symbol(), PERIOD_D1, 0); //--- no calculation needed for the first day if(InpStartDate!=0) { //--- if the opening time has not been updated if(current_open==open_time) return(rates_total); // no calculation needed, exit } //--- update the opening time open_time=current_open; //--- further in the code calculate only one day lastday=InpStartDate+1; } //--- calculate for the specified number of days for(uint day=InpStartDate; day=InpAmericaStartHour) { for(int ind=start_box; ind=InpEuropeStartHour && hour0) { double price=low_day+ind*point; datetime time1=day_rate[0].time; datetime time2=time1+boxes_asia[ind]*box_length*InpMultiplier; string prefix=ExtPrefixUniq+"_"+day_prefix+"_Asia_"+StringFormat("%.5f", price); DrawBox(prefix, price, time1, time2, InpAsiaSession); } } //--- Europe for(int ind=0; ind0) { double price=low_day+ind*point; datetime time1=day_rate[0].time+boxes_asia[ind]*box_length*InpMultiplier; datetime time2=time1+boxes_europe[ind]*box_length*InpMultiplier; string prefix=ExtPrefixUniq+"_"+day_prefix+"_Europe_"+StringFormat("%.5f", price); DrawBox(prefix, price, time1, time2, InpEuropeSession); } } //--- America for(int ind=0; ind0) { double price=low_day+ind*point; datetime time1=day_rate[0].time+(boxes_asia[ind]+boxes_europe[ind])*box_length*InpMultiplier; datetime time2=time1+boxes_america[ind]*box_length*InpMultiplier; string prefix=ExtPrefixUniq+"_"+day_prefix+"_America_"+StringFormat("%.5f", price); DrawBox(prefix, price, time1, time2, InpAmericaSession); } } } //--- redraw all objects ChartRedraw(0); //--- return value of prev_calculated for the next call return(rates_total); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- delete all our graphical objects after use Print("Indicator \"Market Profile\" stopped, delete all objects with prefix=", ExtPrefixUniq); ObjectsDeleteAll(0, ExtPrefixUniq, 0, OBJ_RECTANGLE); ChartRedraw(0); } //+------------------------------------------------------------------+ //| Draw color box | //+------------------------------------------------------------------+ void DrawBox(string bar_prefix, double price, datetime time1, datetime time2, color clr) { ObjectCreate(0, bar_prefix, OBJ_RECTANGLE, 0, time1, price, time2, price); ObjectSetInteger(0, bar_prefix, OBJPROP_COLOR, clr); ObjectSetInteger(0, bar_prefix, OBJPROP_STYLE, STYLE_SOLID); ObjectSetInteger(0, bar_prefix, OBJPROP_WIDTH, 1); ObjectSetString(0, bar_prefix, OBJPROP_TOOLTIP, "\n"); ObjectSetInteger(0, bar_prefix, OBJPROP_BACK, true); } //+------------------------------------------------------------------+