//+-------------------------------------------------------------------------------------+
//|                                                                   PrevDayEffect.mq4 |
//|                                                                           Scriptong |
//|                                                                                     |
//+-------------------------------------------------------------------------------------+
#property copyright "Scriptong"
#property link      "scriptong@mail.ru"
//---- input parameters
extern double    Lots        = 0.1;                          // Îáúåì îòêðûâàåìîé ïîçèöèè
extern int       TakeProfit = 20;
extern int       OffsetForStop = 15;
extern string    OpenOrderSound = "ok.wav";                  // Çâóê äëÿ îòêðûòèÿ ïîçèöèè
extern int       MagicNumber = 17589 ;                         // Ìàãèê ïîçèöèé ñîâåòíèêà
bool Activate, FreeMarginAlert, FatalError;
double Tick, Spread, StopLevel, MinLot, MaxLot, LotStep, TP, SL;
datetime LastDay, LastBar;
int Signal, TypeOrder, LastType, TicketOrder;
//+-------------------------------------------------------------------------------------+
//| Ôóíêöèÿ èíèöèàëèçàöèè ýêñïåðòà                                                      |
//+-------------------------------------------------------------------------------------+
int init()
  {
//----
   Activate = False;
// - 1 - == Ñáîð èíôîðìàöèè îá óñëîâèÿõ òîðãîâëè ========================================
   Tick = MarketInfo(Symbol(), MODE_TICKSIZE);                         // ìèíèìàëüíûé òèê
   Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point);                  // òåêùèé ñïðýä
   StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point);  // òåêóùèé óðîâåíü ñòîïîâ
   MinLot = MarketInfo(Symbol(), MODE_MINLOT);    // ìèíèìàëüíûé ðàçðåøåííûé îáúåì ñäåëêè
   MaxLot = MarketInfo(Symbol(), MODE_MAXLOT);   // ìàêñèìàëüíûé ðàçðåøåííûé îáúåì ñäåëêè
   LotStep = MarketInfo(Symbol(), MODE_LOTSTEP);          // øàã ïðèðàùåíèÿ îáúåìà ñäåëêè
// - 1 - == Îêîí÷àíèå áëîêà =============================================================
// - 2 - == Ïðèâåäåíèå îáúåìà ñäåëêè ê äîïóñòèìîìó è ïðîâåðêà êîððåêòíîñòè îáúåìà =======
   Lots = MathRound(Lots/LotStep)*LotStep; // îêðóãëåíèå îáúåìà äî áëèæàéøåãî äîïóñòèìîãî
   if(Lots < MinLot || Lots > MaxLot) // îáúåì ñäåëêè íå ìåíüøå MinLot è íå áîëüøå MaxLot
     {
      Comment("Ïàðàìåòðîì Lots áûë çàäàí íåïðàâèëüíûé îáúåì ñäåëêè! Ñîâåòíèê îòêëþ÷åí!");
      return(0);
     }
// - 2 - == Îêîí÷àíèå áëîêà =============================================================
// - 3 - == Ïðîâåðêà êîððåêòíîñòè âõîäíûõ ïàðàìåòðîâ ====================================
   if (TakeProfit <= StopLevel/Point)
     {
      Comment("Ñëèøêîì ìàëîå çíà÷åíèå ïàðàìåòðà TakeProfit. Ñîâåòíèê îòêëþ÷åí!");
      return(0);
     }
// - 3 - == Îêîí÷àíèå áëîêà =============================================================
// - 4 - == Îáíîâëåíèå äàííûõ ñ äíåâíîãî è ìèíóòíîãî òàéìôðåéìîâ =======================
   Comment("Ïîäîæäèòå, èäåò îíîâëåíèå äàííûõ äíåâíîãî òàéìôðåéìà...");
   int P = 0;
   while (P < 120)
     {
      iTime(Symbol(), PERIOD_D1, 0);
      if (GetLastError() != 4066) break;
      Sleep(1000);
      P++;
     }
   if (P == 120)
     {
      Comment("Îáíîâëåíèå äàííûõ çàâåðøèëîñü ñ îøèáêîé. Ñîâåòíèê îòêëþ÷åí!");
      return(0);
     }  
   Comment("Ïîäîæäèòå, èäåò îíîâëåíèå äàííûõ ìèíóòíîãî òàéìôðåéìà...");
   P = 0;
   while (P < 120)
     {
      iTime(Symbol(), PERIOD_M1, 0);
      if (GetLastError() != 4066) break;
      Sleep(1000);
      P++;
     }
   if (P == 120)
     {
      Comment("Îáíîâëåíèå äàííûõ çàâåðøèëîñü ñ îøèáêîé. Ñîâåòíèê îòêëþ÷åí!");
      return(0);
     }  
   Comment("");
   LastDay = 0;
   LastBar = 0;
// - 4 - == Îêîí÷àíèå áëîêà =============================================================
// - 5 - == Ðàáîòàëè óæå â ýòîò äåíü èëè íåò? ===========================================
   for (int i = OrdersTotal()-1; i >= 0; i--)
     if (OrderSelect(i, SELECT_BY_POS))
       if (OrderSymbol() == Symbol())
         if (MathFloor(OrderMagicNumber()/10) == MagicNumber &&
             MathMod(OrderMagicNumber(), 10) == 0)
           {
            LastDay = iTime(Symbol(), PERIOD_D1, 0);
            break;
           }  
   if (LastDay == 0)        
     for (i = OrdersHistoryTotal()-1; i >= 0; i--)
       if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
         if (OrderSymbol() == Symbol())
           if (MathFloor(OrderMagicNumber()/10) == MagicNumber &&
               MathMod(OrderMagicNumber(), 10) == 0 && 
               OrderOpenTime() >= iTime(Symbol(), PERIOD_D1, 0))
             {
              LastDay = iTime(Symbol(), PERIOD_D1, 0);
              break;
             }  
// - 5 - == Îêîí÷àíèå áëîêà =============================================================
   Activate = True; // Âñå ïðîâåðêè óñïåøíî çàâåðøåíû, âîçâîäèì ôëàã àêòèâèçàöèè ýêñïåðòà
   
//----
   return(0);
  }
//+-------------------------------------------------------------------------------------+
//| Ôóíêöèÿ äåèíèöèàëèçàöèè ýêñïåðòà                                                    |
//+-------------------------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");
//----
   return(0);
}
//+-------------------------------------------------------------------------------------+
//| Ïðèâåäåíèå çíà÷åíèé ê òî÷íîñòè îäíîãî ïóíêòà                                        |
//+-------------------------------------------------------------------------------------+
double ND(double A)
{
 return(NormalizeDouble(A, Digits));
}  
 
//+-------------------------------------------------------------------------------------+
//| Ðàñøèôðîâêà ñîîáùåíèÿ îá îøèáêå                                                     |
//+-------------------------------------------------------------------------------------+
string ErrorToString(int Error)
{
 switch(Error)
   {
    case 2: return("çàôèêñèðîâàíà îáùàÿ îøèáêà, îáðàòèòåñü â òåõïîääåðæêó."); 
    case 5: return("ó âàñ ñòàðàÿ âåðñèÿ òåðìèíàëà, îáíîâèòå åå."); 
    case 6: return("íåò ñâÿçè ñ ñåðâåðîì, ïîïðîáóéòå ïåðåçàãðóçèòü òåðìèíàë."); 
    case 64: return("ñ÷åò çàáëîêèðîâàí, îáðàòèòåñü â òåõïîääåðæêó.");
    case 132: return("ðûíîê çàêðûò."); 
    case 133: return("òîðãîâëÿ çàïðåùåíà."); 
    case 149: return("çàïðåùåíî ëîêèðîâàíèå."); 
   }
}
  
//+-------------------------------------------------------------------------------------+
//| Îòêðûòèå ïîçèöèè                                                                    |
//| Âîçâðàùàåò:                                                                         |
//|   True - Ïîçèöèÿ îòêðûòà óñïåøíî                                                    |
//|   False - Îøèáêà îòêðûòèÿ                                                           |
//+-------------------------------------------------------------------------------------+
bool OpenOrder(int Type, double Price, double SL, double TP, int Num)
{
 // Áëîê ïðîâåðêè äîñòàòî÷íîñòè ñâîáîäíûõ ñðåäñòâ
 if(AccountFreeMarginCheck(Symbol(), OP_BUY, Lots) <= 0 || GetLastError() == 134) 
  {
   if(!FreeMarginAlert)
    {
     Print("Íåäîñòàòî÷íî ñðåäñòâ äëÿ îòêðûòèÿ ïîçèöèè. Free Margin = ", 
           AccountFreeMargin());
     FreeMarginAlert = True;
    } 
   return(False);  
  }
 FreeMarginAlert = False;  
 // ---------------------------------------------
 switch (Type)
   {
    case OP_BUY: string S = "BUY"; break;
    case OP_SELL: S = "SELL"; break;
    case OP_BUYSTOP: S = "BUYSTOP"; break;
    case OP_SELLSTOP: S = "SELLSTOP"; break;
    case OP_BUYLIMIT: S = "BUYLIMIT"; break;
    case OP_SELLLIMIT: S = "SELLLIMIT"; break;
   }
 if(WaitForTradeContext())  // îæèäàíèå îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà
   {  
    Comment("Îòïðàâëåí çàïðîñ íà îòêðûòèå îðäåðà ", S, " ...");
    int ticket=OrderSend(Symbol(), Type, Lots, Price, 0, 
               SL, TP, NULL, MagicNumber*10+Num, 0, CLR_NONE);        // îòêðûòèå ïîçèöèè
    // Ïîïûòêà îòêðûòèÿ ïîçèöèè çàâåðøèëàñü íåóäà÷åé
    if(ticket<0)
      {
       int Error = GetLastError();
       if(Error == 2 || Error == 5 || Error == 6 || Error == 64 
          || Error == 132 || Error == 133 || Error == 149)     // ñïèñîê ôàòàëüíûõ îøèáîê
         {
          Comment("Ôàòàëüíàÿ îøèáêà ïðè îòêðûòèè ïîçèöèè ò. ê. "+
                   ErrorToString(Error)+" Ñîâåòíèê îòêëþ÷åí!");
          FatalError = True;
         }
        else 
         Comment("Îøèáêà îòêðûòèÿ ïîçèöèè ", S, ": ", Error);       // íåôàòàëüíàÿ îøèáêà
       return(False);
      }
    // ---------------------------------------------
    
    // Óäà÷íîå îòêðûòèå ïîçèöèè   
    Comment("Ïîçèöèÿ ", S, " îòêðûòà óñïåøíî!"); 
    PlaySound(OpenOrderSound); 
    return(True); 
    // ------------------------
   }
  else
   {
    Comment("Âðåìÿ îæèäàíèÿ îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà èñòåêëî!");
    return(False);  
   } 
}
//+-------------------------------------------------------------------------------------+
//| Îæèäàíèå òîðãîâîãî ïîòîêà. Åñëè ïîòîê ñâîáîäåí, òî ðåçóëüòàò True, èíà÷å - False    |
//+-------------------------------------------------------------------------------------+  
bool WaitForTradeContext()
{
 int P = 0;
 // öèêë "ïîêà"
 while(IsTradeContextBusy() && P < 5)
   {
    P++;
    Sleep(1000);
   }
 // -------------  
 if(P == 5)
   return(False);
 return(True);    
}
//+-------------------------------------------------------------------------------------+
//| Ðàñ÷åò ñèãíàëà ïî ïðåäûäóùåìó äíþ                                                   |
//+-------------------------------------------------------------------------------------+
void GetSignal()
{
 Signal = 0;                                                         // îáíóëåíèå ñèãíàëà
 
// - 1 - == Íàõîæäåíèå ïîñëåäíåãî ïðîáèòèÿ ïðåäûäóùåãî äíÿ ==============================
 double HighD = iHigh(Symbol(), PERIOD_D1, 1);
 double LowD = iLow(Symbol(), PERIOD_D1, 1);
 for (int i = 1; i <= iBarShift(Symbol(), PERIOD_M1, iTime(Symbol(), PERIOD_D1, 0)); i++)
   if (ND(iHigh(Symbol(), PERIOD_M1, i)) > HighD+Tick ||
       ND(iLow(Symbol(), PERIOD_M1, i)) < LowD-Tick) 
      break;
// - 1 - == Îêîí÷àíèå áëîêà =============================================================
// - 2 - == Ñèãíàë îòêðûòèÿ BUY =========================================================
 if (ND(iHigh(Symbol(), PERIOD_M1, i)) > HighD+Tick)         // ñèãíàë ïðîáèòèÿ äíÿ ââåðõ
   if (Close[1] < Low[2])   // Ïðîèçîøåë îòêàò ñ çàêðûòèåì ñâå÷è íèæå ìèíèìóìà ïðåäûäóùåé
     {
      SL = MathMin(iLow(Symbol(), PERIOD_D1, 0), iLow(Symbol(), PERIOD_D1, 1)) - 
           OffsetForStop*Tick;
      Signal = 1;
      return;
     }
// - 2 - == Îêîí÷àíèå áëîêà =============================================================
// - 3 - == Ñèãíàë îòêðûòèÿ SELL ========================================================
 if (ND(iLow(Symbol(), PERIOD_M1, i)) < LowD-Tick)            // ñèãíàë ïðîáèòèÿ äíÿ âíèç
   if (Close[1] > High[2]) // Ïðîèçîøåë îòêàò ñ çàêðûòèåì ñâå÷è âûøå ìàêñèìóìà ïðåäûäóùåé
     {
      SL = MathMax(iHigh(Symbol(), PERIOD_D1, 0), iHigh(Symbol(), PERIOD_D1, 1)) + Spread
           + OffsetForStop*Tick;
      Signal = 2;
      return;
     }
// - 3 - == Îêîí÷àíèå áëîêà =============================================================
}  
//+-------------------------------------------------------------------------------------+
//| Çàêðûâàåò âñå ïîçèöèè òèïà Type. Åñëè çàêðûòü íå óäàëîñü çàêðûòü, òî 1.             |
//| Åñëè ïðèñóòñòâóåò ïðîòèâîïîëîæíàÿ, òî âîçâðàùàåò 2.  ñëó÷àå óñïåõà 0.              |
//+-------------------------------------------------------------------------------------+
int CheckOrdersReal(int Type)
{
 for (int i = OrdersTotal()-1; i >= 0; i--)
   if(OrderSelect(i, SELECT_BY_POS))
     if(OrderSymbol() == Symbol() && MathFloor(OrderMagicNumber()/10) == MagicNumber 
        && OrderType() < 2)                                       // ïîèñê "ñâîåé" ñäåëêè
       if(OrderType() == Type)                                  // Åñëè ïîçèöèÿ òèïà Type
         {
          if (WaitForTradeContext())  
            {
             if(Type == OP_BUY)
               double Pr = ND(MarketInfo(Symbol(), MODE_BID));
              else
               Pr = ND(MarketInfo(Symbol(), MODE_ASK));
             if (!OrderClose(OrderTicket(), OrderLots(), Pr, 3))// òî ïûòàåìñÿ çàêðûòü åå
              return(1);                                 // íå óäàëîñü çàêðûòü - âåðíåì 1
            }  
           else
            return(1);//âåðíåì 1, åñëè íå óäàëîñü äîæäàòüñÿ îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà
         }
        else
         return(2);          // âåðíåì 2, åñëè îòêðûòà ïîçèöèÿ, ïðîòèâîïîëîæíàÿ óêàçàííîé
 return(0);                                                   // åñëè âñå ÎÊ, òî âåðíåì 0
}  
//+-------------------------------------------------------------------------------------+
//| Äîáàâëåíèå èëè óäàëåíèå ðàçâîðîòíîãî îðäåðà                                         |
//+-------------------------------------------------------------------------------------+
void AddOrDeleteReverse()
{
 int BaseTicket = -1, ReverseTicket = -1;
 double BaseSL = 0, BaseOpen = 0, ReverseOpen = 0, ReverseSL = 0;
 int BaseType = -1, ReverseType = -1;
 datetime BaseOOT = 0;
// - 1 - == Ïîèñê îñíîâíîãî è ðàçâîðîòíîãî îðäåðîâ ======================================
 for (int i = OrdersTotal()-1; i >= 0; i--)
   if (OrderSelect(i, SELECT_BY_POS))
     if (OrderSymbol() == Symbol() && 
         MathFloor(OrderMagicNumber()/10) == MagicNumber)         // ïîèñê "ñâîåé" ñäåëêè
       if (MathMod(OrderMagicNumber(), 10) == 0)
         {
          BaseTicket = OrderTicket();
          BaseSL = OrderStopLoss();
          BaseOpen = OrderOpenPrice();
          BaseType = OrderType();
          BaseOOT = OrderOpenTime();
         }
        else
         {
          ReverseTicket = OrderTicket();
          ReverseSL = OrderStopLoss();
          ReverseType = OrderType();
          ReverseOpen = OrderOpenPrice();
         } 
// - 1 - == Îêîí÷àíèå áëîêà =============================================================
// - 2 - == Çàêðûòèå îñíîâíîé ïîçèöèè â íà÷àëå ñëåäóþùèõ ñóòîê ==========================
  if (BaseTicket > 0 && BaseOOT < iTime(Symbol(), PERIOD_D1, 0))
    {
     if (BaseType == OP_BUY)
       double price = ND(Bid);
      else
       price = ND(Ask);
     if (WaitForTradeContext())   
       OrderClose(BaseTicket, Lots, price, 3);   
     return;  
    }
// - 2 - == Îêîí÷àíèå áëîêà =============================================================
// - 3 - == Äîáàâëåíèå ðàçâîðîòíîãî îðäåðà ==============================================
  if (BaseTicket > 0 && ReverseTicket < 0)
    {
     if (BaseType == OP_BUY)
       {
        ReverseType = OP_SELLSTOP;
        double sl = BaseOpen;//ND(iHigh(Symbol(), PERIOD_D1, 0)+Spread+Tick);
        double tp = ND(BaseSL - (BaseOpen - BaseSL));
       }
      else
       {
        ReverseType = OP_BUYSTOP;
        sl = BaseOpen;//ND(iLow(Symbol(), PERIOD_D1, 0)-Tick);
        tp = ND(BaseSL + (BaseSL - BaseOpen));
       } 
     OpenOrder(ReverseType, BaseSL, sl, tp, 1);  
    } 
// - 3 - == Îêîí÷àíèå áëîêà =============================================================
// - 4 - == Óäàëåíèå   ðàçâîðîòíîãî îðäåðà ==============================================
  if (ReverseTicket > 0 && ReverseType > 1 && (BaseTicket < 0 ||
      (BaseTicket > 0 && ND(ReverseOpen) != ND(BaseSL))))
    if (WaitForTradeContext())
      OrderDelete(ReverseTicket);
// - 4 - == Îêîí÷àíèå áëîêà =============================================================   
}
//+-------------------------------------------------------------------------------------+
//| Ôóíêöèÿ START ýêñïåðòà                                                              |
//+-------------------------------------------------------------------------------------+
int start()
  {
// - 1 -  == Ðàçðåøåíî ëè ñîâåòíèêó ðàáîòàòü? ===========================================
   if (!Activate || FatalError)             // Îòêëþ÷àåòñÿ ðàáîòà ñîâåòíèêà, åñëè ôóíêöèÿ
    return(0);           //  init çàâåðøèëàñü ñ îøèáêîé  èëè èìåëà ìåñòî ôàòàëüíàÿ îøèáêà
// - 1 -  == Îêîí÷àíèå áëîêà ============================================================
// - 2 - == Ñáîð èíôîðìàöèè îá óñëîâèÿõ òîðãîâëè ========================================
   Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point);                  // òåêùèé ñïðýä
   StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point);  // òåêóùèé óðîâåíü ñòîïîâ 
// - 2 -  == Îêîí÷àíèå áëîêà ============================================================
     
// - 3 - == Óäàëåíèå èëè äîáàâëåíèå îòëîæåííîãî îðäåðà ==================================
   AddOrDeleteReverse();
// - 3 -  == Îêîí÷àíèå áëîêà ============================================================
     
// - 4 - == Ðàñ÷åò òåêóùåãî ñèãíàëà =====================================================
   if (LastDay == iTime(Symbol(), PERIOD_D1, 0)) return(0);
   
   if (LastBar != Time[0]) 
     {
      GetSignal();
      LastBar = Time[0];
     } 
// - 4 -  == Îêîí÷àíèå áëîêà ============================================================
   
// - 5 - == Îòêðûòèå äëèííîé  ïîçèöèè ===================================================
   if (Signal == 1)
     {
      int Res = CheckOrdersReal(OP_SELL);            // Ïðîòèâîïîëîæíóþ ïîçèöèþ - çàêðûòü
      if (Res == 0)                                          // åñëè íåò îòêðûòûõ ïîçèöèé
        {
         RefreshRates();
         TP = Ask + TakeProfit*Tick;
         if (ND(Bid-SL) > StopLevel)
           if (!OpenOrder(OP_BUY, ND(Ask), ND(SL), ND(TP), 0)) // åñëè íå óäàëîñü îòêðûòü
             return(0);                                // òî ïîïðîáóåì ñî ñëåäóþùèì òèêîì
            else
             LastDay = iTime(Symbol(), PERIOD_D1, 0);            // íîâûé áàð "ïîñ÷èòàëè"
        }
      if(Res == 1) return(0); //çàêðûòü ïðîòèâîïîëîæíóþ íå âûøëî, æäåì äî ñëåäóþùåãî òèêà
     }
// - 5 -  == Îêîí÷àíèå áëîêà ============================================================
     
// - 6 - == Îòêðûòèå êîðîòêîé ïîçèöèè ===================================================
   if (Signal == 2)
     {
      Res = CheckOrdersReal(OP_BUY);                 // Ïðîòèâîïîëîæíóþ ïîçèöèþ - çàêðûòü
      if (Res == 0)                                          // åñëè íåò îòêðûòûõ ïîçèöèé
        {
         RefreshRates();
         TP = Bid - TakeProfit*Tick;
         if (ND(SL-Ask) > StopLevel)
           if (!OpenOrder(OP_SELL, ND(Bid), ND(SL), ND(TP), 0))// åñëè íå óäàëîñü îòêðûòü
             return(0);                                // òî ïîïðîáóåì ñî ñëåäóþùèì òèêîì
            else
             LastDay = iTime(Symbol(), PERIOD_D1, 0);            // íîâûé áàð "ïîñ÷èòàëè"
        }
      if (Res == 1) return(0);//çàêðûòü ïðîòèâîïîëîæíóþ íå âûøëî, æäåì äî ñëåäóþùåãî òèêà 
     }
// - 6 -  == Îêîí÷àíèå áëîêà ============================================================
  
//----
   return(0);
  }
//+------------------------------------------------------------------+
             
            
Comments