//+------------------------------------------------------------------+
//|                                                EA_Based_OHLC.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>

enum Oder_Typeee
  {
   Only_BUY=0,
   Only_SELL=1,
   Both=2,
  };

input string S1=" Chart ";
input ENUM_TIMEFRAMES Time_Frame=PERIOD_CURRENT;
input string S2=" Position Sizing  ";
input double Lot=0.01;
input string S3=" Trade Settings ";
input Oder_Typeee Order_Type=Both;
input bool Use_number_to_close=false; // Use Number of swings to close
input int number_of_H_L=3; // Number of Highs or Lows
input bool Use_Current_Candle_To_Open=false;
input string S4=" SL/TP Settings ";
input bool Use_H_L_To_SL=false; // High or Low Stop Loss
input int Stop_Loss_pips=10;
input int Take_Profit_pips=10;
input string S5=" General Settings ";
input int Magic_Number=1;
input string Comment_="EA_OHLC"; // Comment
input bool Use_Alert=false;
input string S6=" Time Filter ";
input bool Use_Time_Filter=false;
input string Time_Start="15:10";
input string Time_End="22:30";
 
int indic1;
double Buffer[],Buffer1[];

ENUM_TIMEFRAMES Time_Frame_=Time_Frame;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   Time_Frame_=Time_Frame;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

 if( Hourfilter() == true )
  {
   if(Use_Current_Candle_To_Open == true)
     {
      if(pos() == 0 && checkagain() == "ok" /*&& podkkkds() == "ok"*/)
         oitiket();
     }

   if(Use_Current_Candle_To_Open == false && iVolume(Symbol(),Time_Frame_,0) <= 10)
     {
      if(pos() > 0)
         check_closing();

      if(pos() == 0 && checkagain() == "ok" /*&& podkkkds() == "ok"*/)
         oitiket();
   }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string check_indicator()
  {
////////////////////////////////
   double ihighh=iHigh(Symbol(),Time_Frame_,1);
   double ilowee=iLow(Symbol(),Time_Frame_,1);

   double ihighh1=iHigh(Symbol(),Time_Frame_,0);
   double ilowee1=iLow(Symbol(),Time_Frame_,0);

   indic1=iCustom(Symbol(),Time_Frame_,"OHLC Lines");

   ArraySetAsSeries(Buffer,true);
   ArraySetAsSeries(Buffer1,true);

   CopyBuffer(indic1,1,0,2,Buffer);
   CopyBuffer(indic1,2,0,2,Buffer1);

   if(Use_Current_Candle_To_Open == false)
     {
      if(NormalizeDouble(ilowee,_Digits) == NormalizeDouble(Buffer1[1],_Digits))
         return("buy");
      ///
      if(NormalizeDouble(ihighh,_Digits) == NormalizeDouble(Buffer[1],_Digits))
         return("sell");
     }
/////
   if(Use_Current_Candle_To_Open == true)
     {
      if(NormalizeDouble(ilowee1,_Digits) == NormalizeDouble(Buffer1[0],_Digits))
         return("buy");
      ///
      if(NormalizeDouble(ihighh1,_Digits) == NormalizeDouble(Buffer[0],_Digits))
         return("sell");
     }
   return("no");

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void oitiket()
  {
//////////
   if(Order_Type == Only_BUY || Order_Type == Both)
     {
      if(check_indicator() == "buy")
        {
         trade_class(ORDER_TYPE_BUY);
         if(Use_Alert == true)
            Alert("open_buy",(string)Symbol());
        }
     }
////
   if(Order_Type == Only_SELL || Order_Type == Both)
     {
      if(check_indicator() == "sell")
        {
         trade_class(ORDER_TYPE_SELL);
         if(Use_Alert == true)
            Alert("open_sell",(string)Symbol());
        }
     }

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void trade_class(ENUM_ORDER_TYPE order)
  {
   CTrade *Mytrade;
   Mytrade=new CTrade;
   Mytrade.SetExpertMagicNumber(Magic_Number);
   Mytrade.SetDeviationInPoints(1000);
   CSymbolInfo *MySym;
   MySym=new CSymbolInfo;
   MySym.Name(Symbol());
   MySym.Refresh();
   MySym.RefreshRates();
   if(order==ORDER_TYPE_BUY)
     {
      double takp=0;
      double stla=0;
      if(Take_Profit_pips != 0)
         takp=SymbolInfoDouble(Symbol(),SYMBOL_ASK)+(10*Take_Profit_pips*Point());
      if(Stop_Loss_pips != 0)
         stla=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-(10*Stop_Loss_pips*Point());

      if(Use_H_L_To_SL == true && Use_Current_Candle_To_Open == false )
         stla=check_sl(0);

      Mytrade.PositionOpen(Symbol(),ORDER_TYPE_BUY,Lot,SymbolInfoDouble(Symbol(),SYMBOL_ASK),stla,takp,Comment_);
     }
//
   if(order==ORDER_TYPE_SELL)
     {
      double takp1=0;
      double stla1=0;
      if(Take_Profit_pips != 0)
         takp1=SymbolInfoDouble(Symbol(),SYMBOL_BID)-(10*Take_Profit_pips*Point());
      if(Stop_Loss_pips != 0)
         stla1=SymbolInfoDouble(Symbol(),SYMBOL_BID)+(10*Stop_Loss_pips*Point());

      if(Use_H_L_To_SL == true && Use_Current_Candle_To_Open == false )
         stla1=check_sl(1);

      Mytrade.PositionOpen(Symbol(),ORDER_TYPE_SELL,Lot,SymbolInfoDouble(Symbol(),SYMBOL_BID),stla1,takp1,Comment_);
     }
  }
//+------------------------------------------------------------------+
//|  Function close                                                  |
//+------------------------------------------------------------------+
string checkagain()
  {
   int num=0;
   int ibarshh=0;
   int jkblkj=HistoryDealsTotal();
   if(HistorySelect(0, TimeCurrent()))
     {
      for(int i=0; i <= jkblkj ; i++)
        {
         ulong Ticket = HistoryDealGetTicket(i);
         double loot=HistoryDealGetDouble(Ticket,DEAL_VOLUME);
         double profit=HistoryDealGetDouble(Ticket,DEAL_PROFIT);
         long Macik=HistoryDealGetInteger(Ticket,DEAL_MAGIC);
         long typee=HistoryDealGetInteger(Ticket,DEAL_TYPE);
         string symbol=HistoryDealGetString(Ticket,DEAL_SYMBOL);
         ////////
         if(symbol == Symbol() && Macik == Magic_Number)
           {
            num++;
            if(HistoryDealGetInteger(Ticket,DEAL_ENTRY) == DEAL_ENTRY_IN)
              {
               ibarshh=iBarShift(Symbol(),Time_Frame_,(datetime)HistoryDealGetInteger(Ticket,DEAL_TIME));
              }
            ////
           }
        }
     }
//
   if(num == 0)
      return("ok");

   if(num > 0  && ibarshh > 0)
      return("ok");

   return("no");
  }
//+------------------------------------------------------------------+
//|   spread filter                                                  |
//+------------------------------------------------------------------+
string podkkkds()
  {
   int num=0;
   int ibafer=0;
   int forcheck=0;

   int pos=PositionsTotal();
   for(int i=0; i < pos; i++)
     {
      ulong tiket=PositionGetTicket(i);
      string symbol=PositionGetString(POSITION_SYMBOL);
      long Macik=PositionGetInteger(POSITION_MAGIC);
      double volume=PositionGetDouble(POSITION_VOLUME);
      double profit=PositionGetDouble(POSITION_PROFIT);
      long typee=PositionGetInteger(POSITION_TYPE);
      double openprice=PositionGetDouble(POSITION_PRICE_OPEN);
      long opentime=PositionGetInteger(POSITION_TIME);
      if(symbol == Symbol() && Macik == Magic_Number)
        {
         num++;
         ibafer=iBarShift(Symbol(),Time_Frame_,(datetime)opentime);

         if(ibafer == 0)
            forcheck=10;
        }
     }

   if(num == 0)
      return("ok");


   if(num > 0 || forcheck == 0)
      return("ok");

   return("no");

  }
//+------------------------------------------------------------------+
//|  Function close                                                  |
//+------------------------------------------------------------------+
int pos()
  {

   int pos=PositionsTotal();
   int num=0;
   for(int i=0; i < pos; i++)
     {
      ulong tiket=PositionGetTicket(i);
      string symbol=PositionGetString(POSITION_SYMBOL);
      long Macik=PositionGetInteger(POSITION_MAGIC);
      double volume=PositionGetDouble(POSITION_VOLUME);
      double profit=PositionGetDouble(POSITION_PROFIT);
      long typee=PositionGetInteger(POSITION_TYPE);
      double openprice=PositionGetDouble(POSITION_PRICE_OPEN);
      if(symbol == Symbol() && Macik == Magic_Number)
        {
         num++;
        }
      /////

     }
   return(num);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void check_closing()
  {

   if(Use_number_to_close == false)
     {
      if(check_indicator() == "buy" || check_indicator() == "sell")
        {
         if(podkkkds() == "ok")
           {
            close(1);
            close(0);
           }
        }
     }
///
   if(Use_number_to_close == true)
     {
      if(check_indicator() == "buy" || check_indicator() == "sell")
        {
         if(podkkkds() == "ok")
           {
            if(check_indicator() == "sell")
               close(1);

            if(check_indicator() == "buy")
               close(0);

            if(check_indicator() == "buy" &&  check_number() == "close_sell")
               close(1);

            if(check_indicator() == "sell" &&  check_number() == "close_buy")
               close(0);
           }
        }
     }

  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void close(int typical)
  {

   CTrade *MyClose;
   MyClose=new CTrade;

   int ibafer=0;
   int pos=PositionsTotal();
   int num=0;
   for(int i=0; i < pos; i++)
     {
      ulong tiket=PositionGetTicket(i);
      string symbol=PositionGetString(POSITION_SYMBOL);
      long Macik=PositionGetInteger(POSITION_MAGIC);
      long typee=PositionGetInteger(POSITION_TYPE);
      long opentime=PositionGetInteger(POSITION_TIME);
      if(symbol == Symbol() && Macik == Magic_Number && typical == typee)
        {
         ibafer=iBarShift(Symbol(),Time_Frame_,(datetime)opentime);
         if(ibafer > 0)
           {
            MyClose.SetDeviationInPoints(10);
            MyClose.PositionClose(tiket);
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string check_number()
  {

   int ibafer=0;
   int pos=PositionsTotal();
   int num=0;
   long ordertype=10;
   for(int i=0; i < pos; i++)
     {
      ulong tiket=PositionGetTicket(i);
      string symbol=PositionGetString(POSITION_SYMBOL);
      long Macik=PositionGetInteger(POSITION_MAGIC);
      long typee=PositionGetInteger(POSITION_TYPE);
      long opentime=PositionGetInteger(POSITION_TIME);
      if(symbol == Symbol() && Macik == Magic_Number)
        {
         ibafer=iBarShift(Symbol(),Time_Frame_,(datetime)opentime);
         ordertype=typee;
        }
     }
//

   indic1=iCustom(Symbol(),Time_Frame_,"OHLC Lines");

   ArraySetAsSeries(Buffer,true);
   ArraySetAsSeries(Buffer1,true);

   CopyBuffer(indic1,1,0,2,Buffer);
   CopyBuffer(indic1,2,0,2,Buffer1);

//
   int fb=0;
   if(ordertype == POSITION_TYPE_BUY)
     {
      for(int q=ibafer ; q > 0; q--)
        {
         if(NormalizeDouble(iHigh(Symbol(),Time_Frame_,q),_Digits) == NormalizeDouble(Buffer[q],_Digits))
            fb++;
        }
     }
   if(fb == number_of_H_L)
      return("close_buy");
//
   int fs=0;
   if(ordertype == POSITION_TYPE_SELL)
     {
      for(int w=ibafer ; w > 0; w--)
        {
         if(NormalizeDouble(iLow(Symbol(),Time_Frame_,w),_Digits) == NormalizeDouble(Buffer1[w],_Digits))
            fs++;
        }
     }
   if(fs == number_of_H_L)
      return("close_sell");

   return("no");

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double check_sl(int mooode)
  {
////////////////////////////////
   double ihighh=iHigh(Symbol(),Time_Frame_,1);
   double ilowee=iLow(Symbol(),Time_Frame_,1);

   indic1=iCustom(Symbol(),Time_Frame_,"OHLC Lines");

   ArraySetAsSeries(Buffer,true);
   ArraySetAsSeries(Buffer1,true);

   CopyBuffer(indic1,1,0,2,Buffer);
   CopyBuffer(indic1,2,0,2,Buffer1);

   if(mooode == 0)
      return(NormalizeDouble(Buffer1[1],_Digits));
///
   if(mooode == 1)
      return(NormalizeDouble(Buffer[1],_Digits));

   return(0);

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
bool Hourfilter()
  {

   if(Use_Time_Filter==false)
      return(true);

   int houro=10;
   int hourr12=10;

   datetime tm=TimeCurrent();
   MqlDateTime stm;
   TimeToStruct(tm,stm);
//
   datetime tm1=(datetime)StringToTime(Time_Start);
   MqlDateTime stm1;
   TimeToStruct(tm1,stm1);
//
   datetime tm2=(datetime)StringToTime(Time_End);
   MqlDateTime stm2;
   TimeToStruct(tm2,stm2);
//
   if(stm.hour == stm1.hour && stm.min >= stm1.min)
      houro=0;

   if(stm.hour > stm1.hour)
      houro=0;

   if(stm.hour == stm2.hour && stm.min <= stm2.min)
      hourr12=0;


   if(stm.hour < stm2.hour)
      hourr12=0;

   if(houro == 0 && hourr12 == 0)
      return(true);

   return(false);

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+