//+------------------------------------------------------------------+
//|                                            TimedExecution_v1.mq4 |
//|                                             Copyright 2021,Pipa1 |
//|                               https://www.forexfactory.com/pipa1 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021,Pipa1"
#property link      "https://www.forexfactory.com/pipa1"
#property description "Edited by JBlanked - Software Developer and Music Producer"
#property strict
enum orderType
  {
   LIMIT_ORDER,
   STOP_ORDER
  };
enum entryType
  {
   LONG_ENTRY,
   SHORT_ENTRY,
   LONG_SHORT_ENTRY
  };
extern string Info1 = " Single execution every day based on setings"; // -------------->

input string filter_settings = "=====FILTER SETTINGS====="; // ----------------->

extern int EntryHour = 14; // Entry Hour
extern int EntryMinute = 29; // Entry Minute
extern orderType OrderTypeToExecute = LIMIT_ORDER; // Order Type
extern entryType OrderEntryToExecute = LONG_SHORT_ENTRY; // Order Entry
extern double EntryDistance = 30; // Buy Distance
extern double EntryTolerance = 5; // Entry Tolerance

input bool   close_orders = false; // Close orders at time?
input string close_time = "16:00"; // Close Time


input string order_settings = "=====ORDER SETTINGS====="; // ----------------->

extern double StopLoss = 25; // Stop loss (pips)
extern double TakeProfit = 50; // Take profit (pips)
extern bool TrailingStopActivate = false; // Use trailing stop?
extern double TrailingStop = 35; // Trailing stop
extern double Lots = 0.01; // Lot size
input int buyMagic = 9989; // Buy magic number
input int sellMagic = 8989; // Sell magic number

double POC =0, sellPOC = 0,buyPOC = 0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool isBuyOrderActivated()
  {
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS,MODE_TRADES))
         break;
      if(OrderSymbol() == Symbol())
         if(OrderMagicNumber() == buyMagic)
            switch(OrderType())
              {
               case OP_BUY  :
                  return true;
              }

     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool isSellOrderActivated()
  {
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS,MODE_TRADES))
         break;
      if(OrderSymbol() == Symbol())
         if(OrderMagicNumber() == sellMagic)
            switch(OrderType())
              {
               case OP_SELL :
                  return true;
              }

     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool OrderTrailingStop()
  {
   bool result = false;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS))
         break;
      if(OrderSymbol() == Symbol())
         if(OrderMagicNumber() == buyMagic || OrderMagicNumber() == sellMagic)
            switch(OrderType())
              {
               case OP_BUY  :
                  if(Bid - TrailingStop  > OrderStopLoss())
                     if(OrderModify(OrderTicket(),Ask,Bid - TrailingStop,OrderOpenPrice()+TakeProfit,0,Green))
                        result = true;
               case OP_SELL :
                  if(Bid + TrailingStop  < OrderStopLoss())
                     if(OrderModify(OrderTicket(),Bid,Bid + TrailingStop,OrderOpenPrice()-TakeProfit,0,Red))
                        result = true;
              }

     }
   return result;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int BuyOrder()
  {
   int ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Ask  - StopLoss,Ask + TakeProfit,NULL,buyMagic,0,clrGreen);
   string msg = (ticket != -1) ?"Buy order placed corectly!": "Failed to place buy order!";
   Alert(msg);
   return ticket;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int SellOrder()
  {
   int ticket = OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Bid + StopLoss,Bid  - TakeProfit,NULL,sellMagic,0,clrRed);
   string msg = (ticket != -1) ?"Sell order placed corectly!": "Failed to place sell order!";
   Alert(msg);
   return ticket;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(TrailingStop < StopLoss)
      TrailingStop = StopLoss;
   if(Digits == 3 || Digits == 5)
     {
      TrailingStop *=(Point*10);
      EntryDistance *=(Point*10);
      StopLoss *=(Point*10);
      TakeProfit *=(Point*10);
      EntryTolerance *=(Point*10);
     }
   else
     {
      TrailingStop *=Point;
      EntryDistance *=Point;
      StopLoss *=Point;
      TakeProfit *=Point;
      EntryTolerance *=Point;
     }
// adjust values to Stoplevel
   double StopLevel = MathMin(MarketInfo(Symbol(),MODE_STOPLEVEL),MarketInfo(Symbol(),MODE_FREEZELEVEL));
   if(TrailingStop < StopLevel)
      TrailingStop = StopLevel;
   if(StopLoss < StopLevel)
      StopLoss = StopLevel;
   if(TakeProfit < StopLevel)
      TakeProfit = StopLevel;

//---
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawLine(string name,double position, color col)
  {
   ObjectDelete(name);
   ObjectCreate(0,name,OBJ_HLINE,0,Time[0],position);
   ObjectSet(name,OBJPROP_STYLE,2);
   ObjectSet(name,OBJPROP_COLOR,col);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(close_orders && (TimeCurrent() > StringToTime(close_time) && TimeCurrent() < (StringToTime(close_time) + 2)))
   {
   CloseOrders(sellMagic);
   CloseOrders(buyMagic);
   }
   
    
// Reset POC if didn't executed any entry for 24 hours
   if(Hour() == EntryHour && Minute() == EntryMinute && !isBuyOrderActivated())
      buyPOC = POC;
   if(Hour() == EntryHour && Minute() == EntryMinute && !isSellOrderActivated())
      sellPOC = POC;

// Record the Bid at given EntryTime
   if(Hour() == EntryHour && Minute() == EntryMinute && buyPOC == POC)
      POC = Bid;
   if(Hour() == EntryHour && Minute() == EntryMinute && sellPOC == POC)
      POC = Bid;



// Draw the POC and simulated Limit/Stop orders on screen
   if(POC !=0)
     {
      DrawLine("Poc",POC,DodgerBlue);
      if(OrderTypeToExecute == LIMIT_ORDER)
        {
         DrawLine("bPoc",POC - EntryDistance,LimeGreen);
         DrawLine("bPocTol",POC - EntryDistance - EntryTolerance,Green);
         DrawLine("sPoc",POC + EntryDistance,Red);
         DrawLine("sPocTol",POC + EntryDistance + EntryTolerance,FireBrick);
        }

      else
         if(OrderTypeToExecute == STOP_ORDER)
           {
            DrawLine("bPoc",POC + EntryDistance,LimeGreen);
            DrawLine("bPocTol",POC + EntryDistance + EntryTolerance,Green);
            DrawLine("sPoc",POC - EntryDistance,Red);
            DrawLine("sPocTol",POC - EntryDistance - EntryTolerance,FireBrick);
           }
     }

// Execute entry if price go above/ below BuyPOC/SellPOC the amount of EntryDistance pips
// Buy Entries
   if(!isBuyOrderActivated() && POC != 0 && buyPOC != POC)
     {
      if(OrderEntryToExecute == LONG_ENTRY || OrderEntryToExecute == LONG_SHORT_ENTRY)
        {
         // Limit orders
         if(OrderTypeToExecute == LIMIT_ORDER)
           {
            if(Bid <= POC - EntryDistance && Bid >= POC - EntryDistance - EntryTolerance)
              {
              CloseOrders(sellMagic);
               BuyOrder();
               buyPOC = POC;
              }
           }
         // Stop orders
         else
            if(OrderTypeToExecute == STOP_ORDER)
              {
               if(Bid >= POC + EntryDistance && Bid <= POC + EntryDistance + EntryTolerance)
                 {
                 CloseOrders(sellMagic);
                  BuyOrder();
                  buyPOC = POC;
                 }
              }
        }
     }

// Sell entries
   if(!isSellOrderActivated() && POC != 0 && sellPOC != POC)
     {
      if(OrderEntryToExecute == SHORT_ENTRY || OrderEntryToExecute == LONG_SHORT_ENTRY)
        {
         // Limit orders
         if(OrderTypeToExecute == LIMIT_ORDER)
           {
            if(Bid >= POC + EntryDistance && Bid <= POC + EntryDistance + EntryTolerance)
              {
              CloseOrders(buyMagic);
               SellOrder();
               sellPOC = POC;
              }
           }
         // Stop orders
         else
            if(OrderTypeToExecute == STOP_ORDER)
              {
               if(Bid <= POC - EntryDistance && Bid >= POC - EntryDistance - EntryTolerance)
                 {
                  CloseOrders(buyMagic);
                  SellOrder();
                  sellPOC = POC;
                 }
              }
        }
     }

// Trailing Stop if activated
   if(TrailingStopActivate)
   
      OrderTrailingStop();
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
   void CloseOrders(int MagicNumber)
     {
      for(int i=OrdersTotal(); i>=0; i--)
        {
         bool SelectBuys= OrderSelect(i,SELECT_BY_POS);
         if(SelectBuys)
           {
            if(OrderMagicNumber()== MagicNumber)
              {
               if(OrderType()==OP_BUY)
               {
               double ClosePrice=SymbolInfoDouble(OrderSymbol(),SYMBOL_BID);
               bool OClose= OrderClose(OrderTicket(),OrderLots(),ClosePrice,3,Blue);
               }
               else if(OrderType()==OP_SELL)
               {
               double ClosePrice=SymbolInfoDouble(OrderSymbol(),SYMBOL_ASK);
               bool OClose= OrderClose(OrderTicket(),OrderLots(),ClosePrice,3,Blue);
               }
              }
           }
        }
     }
//+------------------------------------------------------------------+
