//+------------------------------------------------------------------+
//|                                                     ModernAR.mq4 |
//|                        Copyright 2022, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "??? ????? ?. aka KimIV"
#property link      "http://www.kimiv.ru"

#property indicator_chart_window
#include<StrategyFix.mqh>
#include <STAsianIncludes.mqh>
#include <MQL4Functions.mqh>
#include <STSettings.mqh>
//------- ??????? ????????? ?????????? -------------------------------
 int    NumberOfDays = 1;        // ?????????? ????
 int AsiaBegin    = 1;   // ???????? ????????? ??????
 int AsiaEnd      = 10;   // ???????? ????????? ??????
 int AsianWidth=2;
 color  AsiaColor    = clrGoldenrod; // ???? ????????? ??????
 string EurBegin     = "00:00";   // ???????? ??????????? ??????
 string EurEnd       = "00:00";   // ???????? ??????????? ??????
 color  EurColor     = clrTan;       // ???? ??????????? ??????
 string USABegin     = "00:00";   // ???????? ???????????? ??????
 string USAEnd       = "00:00";   // ???????? ???????????? ??????
 color  USAColor     = clrPaleGreen; // ???? ???????????? ??????
 color fibcolour =clrYellowGreen;
 int HLWidth=2;
  color fibcolourM =clrDarkViolet;
static  datetime prev_time;
static datetime prev_time1Hr,prev_time4Hr;
int period=1;
int left_margin=10;
int font_size=8;
string dow[10];
color font_colour=clrWhite;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
     DeleteObjects();
       getperiod();
Print("period jjj ",period);
     if(period<PERIOD_H1) 
     {
     
  for (int i=0; i<NumberOfDays; i++) {
    CreateObjects("AS"+i, AsiaColor);
    }
    dow[0]="Sunday";
    dow[1]="Monday";
    dow[2]="Tuesday";
    dow[3]="Wednesday";
    dow[4]="Thursday";
    dow[5]="Friday";
    dow[6]="Saturday";
    
  //  CreateObjects("EU"+i, EurColor);
  //  CreateObjects("US"+i, USAColor);
  }
//---
  core_program();
   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[])
  {
//---
    core_program();
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
 
  }
//+------------------------------------------------------------------+
void deinit() {
  DeleteObjects();
  //Comment("");
}

void CreateObjects(string no, color cl) {
  ObjectCreate(no, OBJ_HLINE, 0, 0,0, 0,0);
  ObjectSet(no, OBJPROP_STYLE, STYLE_SOLID);
  ObjectSet(no, OBJPROP_COLOR, cl);
  ObjectSet(no, OBJPROP_BACK, True);
}

void DeleteObjects() {
  for (int i=0; i<NumberOfDays; i++) {
    ObjectDelete("AsianLow");
    ObjectDelete("AsianHigh"+IntegerToString(i));
    ObjectDelete("AsianLow"+IntegerToString(i));
      ObjectDelete("AsianHighFib1");
      ObjectDelete("AsianLowFib1");
      ObjectDelete("AsianHighFib2");
      ObjectDelete("AsianLowFib2");
      ObjectDelete("AsianHighFib3");
      ObjectDelete("AsianLowFib3");
      ObjectDelete("AsianHighFib3");
      ObjectDelete("AsianLowFib3");
       ObjectDelete("AsianHighFib4");
      ObjectDelete("AsianLowFib4");
      ObjectDelete("AsianHighFibE");
      ObjectDelete("AsianLowFibE");
      ObjectDelete("AsianHighFibM");
      ObjectDelete("1 Hour Low");
      ObjectDelete("1 Hour High");
          ObjectDelete("4 Hour Low");
      ObjectDelete("4 Hour High");
      ObjectDelete("US"+i);
  }
}
void DrawObjects(datetime dt, string no, string tb, string te) {
  datetime t1, t2;
  double   p1, p2;
  int      b1, b2;

  t1=StrToTime(TimeToStr(dt, TIME_DATE)+" "+tb);
  t2=StrToTime(TimeToStr(dt, TIME_DATE)+" "+te);
  b1=iBarShift(NULL, 0, t1);
  b2=iBarShift(NULL, 0, t2);
  p1=High[Highest(NULL, 0, MODE_HIGH, b1-b2, b2)];
  p2=Low [Lowest (NULL, 0, MODE_LOW , b1-b2, b2)];
  p1=p1();
  p2=p2();
  //Print("P1 ",p1," P2 ",p2);
 // Comment(p1);
  color line_colour;
  line_colour=clrGoldenrod;
  double range_level[10];
    range_level[1]=15;
  range_level[2]=30;
  range_level[3]=60;
  if(daily_average(2)<100)
  {
  range_level[1]=15;
  range_level[2]=30;
  range_level[3]=60;
  }
  if(daily_average(2)>=100 && daily_average(2)<=150)
  {
  range_level[1]=40;
  range_level[2]=60;
  range_level[3]=90;
  }
  if(daily_average(2)>=150 && daily_average(2)<=200)
  {
  range_level[1]=120;
  range_level[2]=140;
  range_level[3]=160;
  }
  if(daily_average(2)>=200 && daily_average(2)<=2000)
  {
  range_level[1]=140;
  range_level[2]=160;
  range_level[3]=180;
  }
  //above is overridden by below
  double range_percentage=0;
  int average=daily_average(5);
  if(average<10)
  {
   average=10;
  }
  range_percentage=(((p1-p2)/Point/10))/average*100;
 // Print("range perc",range_percentage);
  range_level[1]=10*(range_percentage);
  range_level[2]=20*(range_percentage);
  range_level[3]=40*(range_percentage);
  range_level[1]=range_level[1]*Point*10;
  range_level[2]=range_level[2]*Point*10;
  range_level[3]= range_level[3]*Point*10;
  string signal;
 // Print("Low H1   " ,(iLow(Symbol(),PERIOD_H1,0)));
  if((iLow(Symbol(),PERIOD_H1,0)<iLow(Symbol(),PERIOD_H1,1) && iHigh(Symbol(),PERIOD_H1,0)>iHigh(Symbol(),PERIOD_H1,1))) // && prev_time1Hr!=iTime(Symbol(),PERIOD_M5,0))
  {
   signal=" 1Hr Engulfing";
   prev_time1Hr=iTime(Symbol(),PERIOD_M5,0);
   
    label_xy("H1D",signal,1200,25,15,clrCrimson);
   //  HR1Double=DoubleToString(iLow(Symbol(),PERIOD_H1,0));
  }
   else
   {
    signal="";

    label_xy("H1D",signal,1200,25,15,clrCrimson);
   }
   string HR1DoubleEnd=signal;
   if((iLow(Symbol(),PERIOD_H4,0)<iLow(Symbol(),PERIOD_H4,1) && iHigh(Symbol(),PERIOD_H4,0)>iHigh(Symbol(),PERIOD_H4,1)))//&& prev_time1Hr!=iTime(Symbol(),PERIOD_M5,0))
  {
   signal=" 4Hr Engulfing ";
  // Print("4 hr Double Ender");

   label_xy("H4D",signal,1200,0,15,clrCrimson);
   prev_time4Hr=iTime(Symbol(),PERIOD_M5,0);
  }
   else
   {
    signal="";
    label_xy("H4D",signal,1200,0,20,clrCrimson);
   }
   string HR4DoubleEnd=signal;
    
  if(iLow(Symbol(),PERIOD_H1,1)>iLow(Symbol(),PERIOD_H1,2) && 
     iHigh(Symbol(),PERIOD_H1,1)<iHigh(Symbol(),PERIOD_H1,2) && 
     (iHigh(Symbol(),PERIOD_H1,0)>iHigh(Symbol(),PERIOD_H1,1) ||
      iLow(Symbol(),PERIOD_H1,0)<iLow(Symbol(),PERIOD_H1,1)))// && prev_time1Hr!=iTime(Symbol(),PERIOD_M5,0))
  {
   if(iLow(Symbol(),PERIOD_H1,0)<iLow(Symbol(),PERIOD_H1,1))
   {
    signal=" 1Hr Breakout Short";
   }
   if(iHigh(Symbol(),PERIOD_H1,0)>iHigh(Symbol(),PERIOD_H1,1))
     {
    signal=" 1Hr Breakout Long";
   }
   prev_time1Hr=iTime(Symbol(),PERIOD_M5,0);
 label_xy("H1B",signal,1400,25,15,clrCrimson);
  }
   else
   {
   signal="";
    label_xy("H1B",signal,1400,25,15,clrCrimson);
   }
  if(iLow(Symbol(),PERIOD_H4,1)>iLow(Symbol(),PERIOD_H4,2) && 
     iHigh(Symbol(),PERIOD_H4,1)<iHigh(Symbol(),PERIOD_H4,2) && 
     (iHigh(Symbol(),PERIOD_H4,0)>iHigh(Symbol(),PERIOD_H4,1) ||
      iLow(Symbol(),PERIOD_H4,0)<iLow(Symbol(),PERIOD_H4,1)))
   {
      if(iLow(Symbol(),PERIOD_H1,0)<iLow(Symbol(),PERIOD_H1,1))
   {
    signal=" 4Hr Breakout Short";
   }
      if(iHigh(Symbol(),PERIOD_H4,0)>iHigh(Symbol(),PERIOD_H4,1))
     {
    signal=" 4Hr Breakout Long";
   }
   prev_time1Hr=iTime(Symbol(),PERIOD_M5,0);
      label_xy("H4B",signal,1400,0,15,clrCrimson);
   //  HR1Double=DoubleToString(iLow(Symbol(),PERIOD_H1,0));
  }
   else
   {
   signal="";
     label_xy("H4B",signal,1400,0,15,clrCrimson);
    
   }
    string time;
    int hour=TimeHour(iTime(Symbol(),5,0));
    int minute=TimeMinute(iTime(Symbol(),5,0));
    if(minute<10)
    {
      time=IntegerToString(hour-2)+":0"+IntegerToString(minute);
    }
    else
    {
      time=IntegerToString(hour-2)+":"+IntegerToString(minute);
    }
   // time=TimeGMT(iTime(Symbol(),5,0));
  //  time=time+":"+TimeMinute(iTime(Symbol(),5,0));
    Comment("Today Spread ",DoubleToString(day_spread(0),0)," Yesterday Spread ",DoubleToString(day_spread(1),0)," Daily Ave 2 ",daily_average(2)
    ," Daily Av 5 ",daily_average(5)," Todays Range ",DoubleToString((p1-p2)/Point/10,0),
    " Range % " ,DoubleToString(range_percentage,0)," Spreads ",DoubleToString(day_spread(1),0),"  ",DoubleToString(day_spread(2),0),"  ",DoubleToString(day_spread(3),0)
    ,"  ",DoubleToString(day_spread(4),0),"  ",DoubleToString(day_spread(5),0),"    Time ",time,"  ",dow[TimeDayOfWeek(iTime(Symbol(),60,0))],HR4DoubleEnd,HR1DoubleEnd);
 //Comment(iLow(Symbol(),PERIOD_D1,0),"   ",iHigh(Symbol(),PERIOD_D1,0));
   double factor=1;
  if(range_percentage<=25)
  {
    line_colour=clrGreen;
  }
  if(range_percentage>=25 && range_percentage<50)
  {
    line_colour=clrYellow;
  
  
  }
     if(range_percentage>=50 && range_percentage<75)
  {
  factor=0.5;
    line_colour=clrBrown;
  }
  
       if(range_percentage>=75 )
  {
    line_colour=clrRed;
  }
  string objnameHigh="AsianHigh"+IntegerToString(no);
   string objnameLow="AsianLow"+IntegerToString(no);
   int firstbar=WindowFirstVisibleBar();
  Create_Trend_Level(objnameHigh,line_colour,AsianWidth,firstbar,p1);
  Create_Trend_Level(objnameLow,line_colour,AsianWidth,firstbar,p2);
//  ObjectSet("AsianHigh", OBJPROP_TIME , t1);
  ObjectSet(objnameHigh, OBJPROP_PRICE, p1);
  ObjectSet(objnameHigh, OBJPROP_WIDTH, HLWidth);
 // ObjectSet(no, OBJPROP_TIME , t2);
  ObjectSet(objnameLow, OBJPROP_PRICE, p2);
  ObjectSet(objnameLow, OBJPROP_WIDTH, HLWidth);
  double range_size=p1-p2;
  double fh1,fl1,fh2,fl2,fh3,fl3,fh4,fl4,fhM;
  fh1=p1+(range_size*1*factor);
  fl1=p2-(range_size*1*factor);
  Create_Trend_Level("AsianHighFib1",fibcolour,AsianWidth,firstbar,fh1);
  ObjectSet("AsianHighFib1", OBJPROP_PRICE, fh1);
  Create_Trend_Level("AsianLowFib1",fibcolour,AsianWidth,firstbar,fl1);
  ObjectSet("AsianLowFib1", OBJPROP_PRICE, fl1);
  
  fh2=p1+(range_size*2*factor);
  fl2=p2-(range_size*2*factor);
  Create_Trend_Level("AsianHighFib2",fibcolour,AsianWidth,firstbar,fh2);
  ObjectSet("AsianHighFib2", OBJPROP_PRICE, fh2);
  Create_Trend_Level("AsianLowFib2",fibcolour,AsianWidth,firstbar,fl2);
  ObjectSet("AsianLowFib2", OBJPROP_PRICE, fl2);
  fh3=p1+(range_size*3*factor);
  fl3=p2-(range_size*3*factor);
  Create_Trend_Level("AsianHighFib3",fibcolour,AsianWidth,firstbar,fh3);
  ObjectSet("AsianHighFib3", OBJPROP_PRICE, fh3);
  Create_Trend_Level("AsianLowFib3",fibcolour,AsianWidth,firstbar,fl3);
  ObjectSet("AsianLowFib3", OBJPROP_PRICE, fl3);
  fh4=p1+(range_size*4*factor);
  fl4=p2-(range_size*4*factor);
  Create_Trend_Level("AsianHighFib4",fibcolour,AsianWidth,firstbar,fh4);
  ObjectSet("AsianHighFib4", OBJPROP_PRICE, fh4);
  Create_Trend_Level("AsianLowFib4",fibcolour,AsianWidth,firstbar,fl4);
  ObjectSet("AsianLowFib4", OBJPROP_PRICE, fl4);
  
  
  fhM=p2+((p1-p2)/2);
  Create_Trend_Level("AsianHighFibM",fibcolourM,AsianWidth,firstbar,fhM);
  ObjectSet("AsianHighFibM", OBJPROP_PRICE, fhM);
 
  double Hour4Low;
  Hour4Low=(iLow(Symbol(),PERIOD_H4,1));
  ObjectDelete("4 Hour Low");
  get_4hour_candle();
  //Print("h4 can ff",get_4hour_candle());
  Create_Trend_Level("4 Hour Low",clrLightSkyBlue,AsianWidth,get_4hour_candle(),Hour4Low);
  ObjectSet("4 Hour Low",OBJPROP_RAY,false);
  double Hour4High;
  Hour4High=(iHigh(Symbol(),PERIOD_H4,1));
  ObjectDelete("4 Hour High");
  Create_Trend_Level("4 Hour High",clrLightSkyBlue,AsianWidth,get_4hour_candle(),Hour4High);
  ObjectSet("4 Hour High",OBJPROP_RAY,false);
  
  double Hour1Low;
  Hour1Low=(iLow(Symbol(),PERIOD_H1,1));
  ObjectDelete("1 Hour Low");
  get_1hour_candle();
  //Print("h4 can ff",get_4hour_candle());
  Create_Trend_Level("1 Hour Low",clrLightSkyBlue,AsianWidth,get_1hour_candle(),Hour1Low);
  ObjectSet("1 Hour Low",OBJPROP_RAY,false);
  double Hour1High;
  Hour1High=(iHigh(Symbol(),PERIOD_H1,1));
  ObjectDelete("1 Hour High");
  Create_Trend_Level("1 Hour High",clrLightSkyBlue,AsianWidth,get_1hour_candle(),Hour1High);
  ObjectSet("1 Hour High",OBJPROP_RAY,false);
 
  
  
  double AsianLowBelow=0.0;
  AsianLowBelow=p2-(TodaysHighAboveAsianHigh()-p1);
  ObjectDelete("Below Asian Low");
  //if(TodaysHighAboveAsianHigh()>p1+0.0001 && p2-0.0001<TodaysLowBelowAsianLow())
  {
 // Create_Trend_Level("Below Asian Low",clrRosyBrown,AsianWidth,80,  AsianLowBelow);
  }
  ObjectSet("Below Asian Low",OBJPROP_RAY,false);
  double AsianHighAbove=0.0;
  AsianHighAbove=p1+(p2-TodaysLowBelowAsianLow());
 // Print(AsianHighAbove);
  ObjectDelete("Above Asian High");
//  if(TodaysLowBelowAsianLow()<p2-0.0001 && p1+0.0001>TodaysHighAboveAsianHigh())
  {
 //  Create_Trend_Level("Above Asian High",clrRosyBrown,AsianWidth,80,  AsianHighAbove);
   }
  ObjectSet("Above Asian High",OBJPROP_RAY,false);
}

datetime decDateTradeDay (datetime dt) {
  int ty=TimeYear(dt);
  int tm=TimeMonth(dt);
  int td=TimeDay(dt);
  int th=TimeHour(dt);
  int ti=TimeMinute(dt);

  td--;
  if (td==0) {
    tm--;
    if (tm==0) {
      ty--;
      tm=12;
    }
    if (tm==1 || tm==3 || tm==5 || tm==7 || tm==8 || tm==10 || tm==12) td=31;
    if (tm==2) if (MathMod(ty, 4)==0) td=29; else td=28;
    if (tm==4 || tm==6 || tm==9 || tm==11) td=30;
  }
  return(StrToTime(ty+"."+tm+"."+td+" "+th+":"+ti));
}

void  Create_Trend_Level(string objName,color level_color,int width,int length,double price)
{
if(ObjectFind(objName)<0)
  {
  if(3+no_of_candles>0 && length>=0 && length<=8000)
  {
 // Print("length",length);
  ObjectCreate(objName,OBJ_TREND,NULL,Time[3+no_of_candles],price,Time[length],price);
  }
  ObjectSetInteger(0,objName,OBJPROP_COLOR,level_color);
   ObjectSetInteger(0,objName,OBJPROP_WIDTH,width);
  if(objName=="LevelTop" || objName=="LevelBottom")
  {
   ObjectSetInteger(0,objName,OBJPROP_WIDTH,3);
  }
 
  ObjectSetDouble(0,objName,OBJPROP_PRICE,price);
  if(objName=="Levelask" || objName=="Levelbid")
  {
    ObjectSetInteger(0,objName,OBJPROP_STYLE,STYLE_DASHDOT);
  }
  else
  {
    ObjectSetInteger(0,objName,OBJPROP_STYLE,STYLE_SOLID);
   }

 }

  }
  
double p1()
{
 double high=0;
 int i=0;
 int hour=TimeHour(iTime(Symbol(),period,i));
 while(hour>=AsiaEnd)
 {   
   hour=TimeHour(iTime(Symbol(),period,i));
   i++;
 }
 while(hour>=AsiaBegin)
 {
   if(iHigh(Symbol(),period,i)>high)
   {
     high=iHigh(Symbol(),period,i);
   }
   hour=TimeHour(iTime(Symbol(),period,i));
   i++;
   }
   
 return (high);
 //Print (high);
}

double p2()
{
 double low=99999;
 int i=0;
 int hour=TimeHour(iTime(Symbol(),period,i));
 while(hour>=AsiaEnd)
 {   
   hour=TimeHour(iTime(Symbol(),period,i));
   i++;
 }
 while(hour>=AsiaBegin)
 {
   if(iLow(Symbol(),period,i)<low)
   {
     low=iLow(Symbol(),period,i);
   }
   hour=TimeHour(iTime(Symbol(),period,i));
   i++;
   }
   
 return (low);
 //Print (low);
}

void label(string obj_name,string text,int font_size,color font_colour,int ypos)

{
  ObjectDelete(obj_name);
  ObjectCreate(obj_name,OBJ_LABEL,NULL,Time[WindowFirstVisibleBar()-5],ypos);
  //   ObjectSet(obj_name,OBJPROP_ANCHOR,ANCHOR_RIGHT_UPPER);
  //if(int(obj_name)==0)
  {
   ObjectSetText(obj_name,text);
  }
  ObjectSet(obj_name,OBJPROP_XDISTANCE,left_margin);
  ObjectSet(obj_name,OBJPROP_COLOR,font_colour);
  ObjectSet(obj_name,OBJPROP_FONTSIZE,font_size);
  ObjectSet(obj_name,OBJPROP_YDISTANCE,ypos);
}
void label_xy(string obj_name,string text,int xpos,int ypos,int font_size,color colour)

{
   ObjectCreate(obj_name, OBJ_LABEL, 1, 0, 0);
   ObjectSetText(obj_name,text,font_size, "Trebuchet MS", clrWhite);
   ObjectSet(obj_name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSet(obj_name, OBJPROP_XDISTANCE, xpos);
   ObjectSet(obj_name, OBJPROP_YDISTANCE, ypos);
   ObjectSetInteger(0,obj_name,OBJPROP_COLOR,colour);
   ObjectSetInteger(0,obj_name,OBJPROP_FONTSIZE,font_size);
}

void core_program()
{
 period=getperiod();
Print("period ",period," ",period<PERIOD_H1);

if(period<PERIOD_H1 ) 
{
Print("period x ",period);
int hour=TimeHour(iTime(Symbol(),period,0));
string onoff=ObjectGetString(0,"OnOff",OBJPROP_TEXT,0);
//Print("OF",onoff);
//if(prev_time!=iTime(Symbol(),period,0)) // || (hour>8 &&  hour<21))
if(onoff!="Off" || prev_time!=iTime(Symbol(),period,0))
{
Print("period xyz ",period);
   DeleteObjects();
  datetime dt=CurTime();

  for (int i=0; i<=NumberOfDays; i++)
   {
   Print("i day ",period);
    DrawObjects(dt, "AS"+i, AsiaBegin, AsiaEnd);
   // DrawObjects(dt, "EU"+i, EurBegin, EurEnd);
  //  DrawObjects(dt, "US"+i, USABegin, USAEnd);
    dt=decDateTradeDay(dt);
    while (TimeDayOfWeek(dt)>5) dt=decDateTradeDay(dt);
  }
  prev_time=iTime(Symbol(),period,0);
  }
  }
  else
  {
  DeleteObjects();
  Print("dekete");
  }
}