//æææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ
// AG_AT.mq4                                             
// Ïîëüçîâàòåëüñêàÿ ôóíêöèÿ Àâòîìàòè÷åñêîé Òîðãîâëè.
// Èñïîëüçóåòñÿ ïðè ïîñòðîåíèè ôóíêöèè àâòîìàòè÷åñêîé òîðãîâëè äëÿ ïðèëîæåíèÿ AutoGraf 4
// ðåàëèçàöèÿ ñòðàòåãèè "Ïîääåðæêè è ñîïðîòèâëåíèÿ" (Support&Resistance)
// Èãîðü Ãåðàñüêî, Äíåïðîäçåðæèíñê, scriptong@mail.ru
//ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ 0 ææ
#property library   
 
#import "AG_Lib.ex4"
   int AG_Message(string& Message[], string _Text);// Çàïèñü ñîîáùåíèé â ìàññèâ Message[]
#import
color     SupportColor = Blue;                            // Öâåò óðîâíÿ ïîääåðæêè
color     ResistanceColor = Red;                      // Öâåò óðîâíÿ ñîïðîòèâëåíèÿ
double Spread, StopLevel, Tick, Lots, FreezeLevel, Supp, Resis;
bool IsSell, IsBuy, FreeMarginAlert = False, FatalError = False;
int TakeProfit, StopLoss, Signal, ChanStart;
datetime LastBar = 0;
string SName, RName;
int MagicNumber = 34840;
//ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ 1 ææ
int AG_AT(int Parol_AT, double Order[][], string Object[], double Instrument[][][][], 
          int Ddraw_Object[][], double& Tuning[], double& Manager[][], string& Message[])
   {     
   SName = "Support"+MagicNumber;                    // Èìÿ äëÿ îáúåêòà "ëèíèÿ ïîääåðæêè"
   RName = "Resistance"+MagicNumber;             // Èìÿ äëÿ îáúåêòà "ëèíèÿ ñîïðîòèâëåíèÿ"
   if (FatalError) return(0); 
   
   string Comm = "AG_AT";                          // Êîììåíòàðèé (ðåêîìåíäóåòñÿ "AG_AT")
// - 1 - == Ïîëó÷åíèå íàñòðîåê AutoGraf =================================================
   Lots = NormalizeDouble(Tuning[1],2);                                 // Çíà÷åíèå ëîòîâ
   StopLoss = NormalizeDouble(Tuning[4],0);                         // StopLoss (ïóíêòîâ)
   TakeProfit = NormalizeDouble(Tuning[5],0);                     // TakeProfit (ïóíêòîâ)
// - 1 - == Îêîí÷àíèå áëîêà =============================================================
// - 2 - == Ñáîð èíôîðìàöèè îá óñëîâèÿõ òîðãîâëè ========================================
   Tick = MarketInfo(Symbol(), MODE_TICKSIZE);                         // ìèíèìàëüíûé òèê
   Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point);                  // òåêùèé ñïðýä
   StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point);  // òåêóùèé óðîâåíü ñòîïîâ 
   FreezeLevel = ND(MarketInfo(Symbol(), MODE_FREEZELEVEL)*Point);   // óðîâåíü çàìîðîçêè
// - 2 -  == Îêîí÷àíèå áëîêà ============================================================
   if (LastBar == Time[0])
     return(1);
   
// - 3 - == Ðàñ÷åò ïîñëåäíèõ ïîääåðæêè è ñîïðîòèâëåíèÿ ==================================
   GetLevels();
// - 3 -  == Îêîí÷àíèå áëîêà ============================================================
// - 4 - == Óñòàíîâêà îðäåðîâ ===========================================================
   if (Supp != 0 && Resis != 0)       // Óñòàíîâêà îðäåðîâ òîëüêî, åñëè îïðåäåëåíû óðîâíè
     if (!SetOrders(Message)) return(1);
// - 4 -  == Îêîí÷àíèå áëîêà ============================================================
   LastBar = Time[0];
   return(1);
   }
   
//+-------------------------------------------------------------------------------------+
//| Ïðèâåäåíèå çíà÷åíèé ê òî÷íîñòè îäíîãî òèêà                                          |
//+-------------------------------------------------------------------------------------+
double ND(double A)
{
 return(NormalizeDouble(A, Digits));
}  
//+-------------------------------------------------------------------------------------+
//| Ïðèâåäåíèå çíà÷åíèé ê òî÷íîñòè îäíîãî òèêà                                          |
//+-------------------------------------------------------------------------------------+
double NP(double A)
{
 return(MathFloor(A/Tick)*Tick);
} 
//+-------------------------------------------------------------------------------------+
//| Ðàñøèôðîâêà ñîîáùåíèÿ îá îøèáêå                                                     |
//+-------------------------------------------------------------------------------------+
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 WaitForTradeContext()
{
 int P = 0;
 // öèêë "ïîêà"
 while(IsTradeContextBusy() && P < 5)
   {
    P++;
    Sleep(1000);
   }
 // -------------  
 if(P == 5)
   return(False);
 return(True);    
}
  
//+-------------------------------------------------------------------------------------+
//| "Ïðàâèëüíîå" îòêðûòèå ïîçèöèè                                                       |
//|  îòëè÷èå îò OpenOrder ïðîâåðÿåò ñîîòíîøåíèå òåêóùèõ óðîâíåé è óñòàíàâëèâàåìûõ      |
//| Âîçâðàùàåò:                                                                         |
//|   0 - íåò îøèáîê                                                                    |
//|   1 - Îøèáêà îòêðûòèÿ                                                               |
//|   2 - Îøèáêà çíà÷åíèÿ Price                                                         |
//|   3 - Îøèáêà çíà÷åíèÿ SL                                                            |
//|   4 - Îøèáêà çíà÷åíèÿ TP                                                            |
//|   5 - Îøèáêà çíà÷åíèÿ Lot                                                           |
//+-------------------------------------------------------------------------------------+
int OpenOrderCorrect(string& Message[], int Type, double Price, double SL, double TP, 
                     int MN, bool Redefinition = True)
// Redefinition - ïðè True äîîïðåäåëÿòü ïàðàìåòðû äî ìèíèìàëüíî äîïóñòèìûõ
//                ïðè False - âîçâðàùàòü îøèáêó
{
// - 1 - == Ïðîâåðêà äîñòàòî÷íîñòè ñâîáîäíûõ ñðåäñòâ ====================================
 if(AccountFreeMarginCheck(Symbol(), OP_BUY, Lots) <= 0 || GetLastError() == 134) 
  {
   if(!FreeMarginAlert)
    {
     Print("Íåäîñòàòî÷íî ñðåäñòâ äëÿ îòêðûòèÿ ïîçèöèè. Free Margin = ", 
           AccountFreeMargin());
     FreeMarginAlert = True;
    } 
   return(5);  
  }
 FreeMarginAlert = False;  
// - 1 - == Îêîí÷àíèå áëîêà =============================================================
// - 2 - == Êîððåêòèðîâêà çíà÷åíèé Price, SL è TP èëè âîçâðàò îøèáêè ====================   
 RefreshRates();
 switch (Type)
   {
    case OP_BUY: 
                string S = "BUY"; 
                if (MathAbs(Price-Ask)/Point > 3)
                  if (Redefinition) Price = ND(Ask);
                  else              return(2);
                if (ND(TP-Bid) < StopLevel && TP != 0)
                  if (Redefinition) TP = ND(Bid+StopLevel);
                  else              return(4);
                if (ND(Bid-SL) < StopLevel)
                  if (Redefinition) SL = ND(Bid-StopLevel);
                  else              return(3);
                break;
    case OP_SELL: 
                 S = "SELL"; 
                 if (MathAbs(Price-Bid)/Point > 3)
                   if (Redefinition) Price = ND(Bid);
                   else              return(2);
                 if (ND(Ask-TP) < StopLevel) 
                   if (Redefinition) TP = ND(Ask-StopLevel);
                   else              return(4);
                 if (ND(SL-Ask) < StopLevel && SL != 0)
                   if (Redefinition) SL = ND(Ask+StopLevel);
                   else              return(3);
                 break;
    case OP_BUYSTOP: 
                    S = "BUYSTOP";
                    if (ND(Price-Ask) < StopLevel)
                      if (Redefinition) Price = ND(Ask+StopLevel);
                      else              return(2);
                    if (ND(TP-Price) < StopLevel && TP != 0)
                      if (Redefinition) TP = ND(Price+StopLevel);
                      else              return(4);
                    if (ND(Price-SL) < StopLevel)
                      if (Redefinition) SL = ND(Price-StopLevel);
                      else              return(3);
                    break;
    case OP_SELLSTOP: 
                     S = "SELLSTOP";
                     if (ND(Bid-Price) < StopLevel)
                       if (Redefinition) Price = ND(Bid-StopLevel);
                       else              return(2);
                     if (ND(Price-TP) < StopLevel)
                       if (Redefinition) TP = ND(Price-StopLevel);
                       else              return(4);
                     if (ND(SL-Price) < StopLevel && SL != 0)
                       if (Redefinition) SL = ND(Price+StopLevel);
                       else              return(3);
                     break;
    case OP_BUYLIMIT: 
                     S = "BUYLIMIT";
                     if (ND(Ask-Price) < StopLevel)
                      if (Redefinition) Price = ND(Ask-StopLevel);
                      else              return(2);
                     if (ND(TP-Price) < StopLevel && TP != 0)
                       if (Redefinition) TP = ND(Price+StopLevel);
                       else              return(4);
                     if (ND(Price-SL) < StopLevel)
                       if (Redefinition) SL = ND(Price-StopLevel);
                       else              return(3);
                     break;
    case OP_SELLLIMIT: 
                     S = "SELLLIMIT";
                     if (ND(Price - Bid) < StopLevel) 
                       if (Redefinition) Price = ND(Bid+StopLevel);
                       else              return(2);
                     if (ND(Price-TP) < StopLevel)
                       if (Redefinition) TP = ND(Price-StopLevel);
                       else              return(4);
                     if (ND(SL-Price) < StopLevel && SL != 0)
                       if (Redefinition) SL = ND(Price+StopLevel);
                       else              return(3);
                     break;
   }
// - 2 - == Îêîí÷àíèå áëîêà =============================================================
 
// - 3 - == Îòêðûòèå îðäåðà ñ îæèäàíèå òîðãîâîãî ïîòîêà =================================   
 if(WaitForTradeContext())  // îæèäàíèå îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà
   {  
    AG_Message(Message, "Îòïðàâëåí çàïðîñ íà îòêðûòèå îðäåðà "+S+" ...");  
    int ticket=OrderSend(Symbol(), Type, Lots, Price, 3, 
               SL, TP, "AG_AT", MN, 0);// îòêðûòèå ïîçèöèè
    // Ïîïûòêà îòêðûòèÿ ïîçèöèè çàâåðøèëàñü íåóäà÷åé
    if(ticket<0)
      {
       int Error = GetLastError();
       if(Error == 2 || Error == 5 || Error == 6 || Error == 64 
          || Error == 132 || Error == 133 || Error == 149)     // ñïèñîê ôàòàëüíûõ îøèáîê
         {
          AG_Message(Message, "Ôàòàëüíàÿ îøèáêà ïðè îòêðûòèè ïîçèöèè ò. ê. "+
                   ErrorToString(Error)+" Ñîâåòíèê îòêëþ÷åí!");
          FatalError = True;
         }
        else 
         AG_Message(Message, "Îøèáêà îòêðûòèÿ ïîçèöèè "+S+": "+Error); // íåôàòàëüíàÿ îøèáêà
       return(1);
      }
    // ---------------------------------------------
    
    // Óäà÷íîå îòêðûòèå ïîçèöèè   
    AG_Message(Message, "Ïîçèöèÿ "+S+" îòêðûòà óñïåøíî!"); 
    return(0); 
    // ------------------------
   }
  else
   {
    AG_Message(Message, "Âðåìÿ îæèäàíèÿ îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà èñòåêëî!");
    return(1);  
   } 
// - 3 - == Îêîí÷àíèå áëîêà =============================================================
   
}
//+-------------------------------------------------------------------------------------+
//| Îòîáðàæåíèå ëèíèé ïîääåðæêè è ñîïðîòèâëåíèÿ                                         |
//+-------------------------------------------------------------------------------------+
void ShowChannel()
{
 if (Supp != 0 && Resis != 0)                                   // Åñëè óðîâíè îïðåäåëåíû
   {
    if (ObjectFind(SName) < 0)      // è îáúåêòà ïîääåðæêè íåò, òî ðèñóåì ëèíèþ ïîääåðæêè
      {
       ObjectCreate(SName, OBJ_TREND, 0, ChanStart, Supp, Time[0], Supp); 
       ObjectSet(SName, OBJPROP_RAY, False);
       ObjectSet(SName, OBJPROP_COLOR, SupportColor);
      }
     else      // åñëè ëèíèÿ ïîääåðæêè óæå åñòü, òî ïðîñòî ïåðåíîñèì åå íà íóæíûé óðîâåíü
      {
       ObjectMove(SName, 0, ChanStart, Supp);
       ObjectMove(SName, 1, Time[0], Supp);
      } 
    if (ObjectFind(RName) < 0)   // åñëè ñîïðîòèâëåíèÿ íåò, òî ðèñóåì ëèíèþ ñîïðîòèâëåíèÿ
      {
       ObjectCreate(RName, OBJ_TREND, 0, ChanStart, Resis, Time[0], Resis);
       ObjectSet(RName, OBJPROP_RAY, False);
       ObjectSet(RName, OBJPROP_COLOR, ResistanceColor);
      }
     else  // åñëè ëèíèÿ ñîïðîòèâëåíèÿ óæå åñòü, òî ïðîñòî ïåðåíîñèì åå íà íóæíûé óðîâåíü
      {
       ObjectMove(RName, 0, ChanStart, Resis);
       ObjectMove(RName, 1, Time[0], Resis);
      } 
   }
  else           // åñëè óðîâíè íå îïðåäåëåíû, òî óäàëÿåì ëèíèè ïîääåðæêè è ñîïðîòèâëåíèÿ
   {
    if (ObjectFind(SName) == 0)
      ObjectDelete(SName);
    if (ObjectFind(RName) == 0)
      ObjectDelete(RName);
   } 
}
//+-------------------------------------------------------------------------------------+
//| Ðàñ÷åò óðîâíåé ïîääåðæêè è ñîïðîòèâëåíèÿ                                            |
//+-------------------------------------------------------------------------------------+
void GetLevels()
{
 Supp = 0;
 Resis = 0;
// - 1 - == Ðàñ÷åò äàííûõ èíäèêàòîðà ÀÎ =================================================
 double AO1 = iAO(Symbol(), 0, 1);
 double AO2 = iAO(Symbol(), 0, 2); 
 double AO3 = iAO(Symbol(), 0, 3); 
// - 1 - == Îêîí÷àíèå áëîêà =============================================================
// - 2 - == Ïîèñê ñîïðîòèâëåíèÿ è ïîääåðæêè â ïîëîæèòåëüíîé çîíå èíäèêàòîðà ÀÎ ==========
 if (AO1 > 0)
   if (AO1 < AO2 && AO2 > AO3)                   // Áûëà êîððåêöèÿ âíèç ïîñëå âîñõîæäåíèÿ
     {
      // Ïîèñê áàðà, íà êîòîðîì çíà÷åíèå ÀÎ ñòàíîâèòñÿ îòðèöàòåëüíûì
      int i = 4;   
      while (AO3 > 0 && i < Bars)
        {
         AO3 = iAO(Symbol(), 0, i);
         i++;
        }
      if (i == Bars) return;                // åñëè äîøëè äî êîíöà èñòîðèè, òî ýòî îøèáêà
      // Ðàñ÷åò óðîâíåé
      Supp = Low[iLowest(Symbol(), 0, MODE_LOW, i-1)];
      Resis = High[iHighest(Symbol(), 0, MODE_HIGH, i-1)];
      ChanStart = Time[i-2];              // Çàïîìèíàåì âðåìÿ íà÷àëà äëÿ èíäèêàöèè êàíàëà
     }
// - 2 - == Îêîí÷àíèå áëîêà =============================================================
// - 3 - == Ïîèñê ñîïðîòèâëåíèÿ è ïîääåðæêè â îòðèöàòåëüíîé çîíå èíäèêàòîðà ÀÎ ==========
 if (AO1 < 0)
   if (AO1 > AO2 && AO2 < AO3)                      // Áûëà êîððåêöèÿ ââåðõ ïîñëå ïàäåíèÿ
     {
      // Ïîèñê áàðà, íà êîòîðîì çíà÷åíèå ÀÎ ñòàíîâèòñÿ ïîëîæèòåëüíûì
      i = 4;
      while (AO3 < 0 && i < Bars)
        {
         AO3 = iAO(Symbol(), 0, i);
         i++;
        } 
      if (i == Bars) return;                // åñëè äîøëè äî êîíöà èñòîðèè, òî ýòî îøèáêà
      // Ðàñ÷åò óðîâíåé
      Supp = Low[iLowest(Symbol(), 0, MODE_LOW, i-1)];
      Resis = High[iHighest(Symbol(), 0, MODE_HIGH, i-1)];
      ChanStart = Time[i-2];              // Çàïîìèíàåì âðåìÿ íà÷àëà äëÿ èíäèêàöèè êàíàëà
     }
// - 3 - == Îêîí÷àíèå áëîêà =============================================================
 
 ShowChannel();                                                    // Îòîáðàæåíèå óðîâíåé
}
//+-------------------------------------------------------------------------------------+
//| Óñòàíîâêà îðäåðîâ, ïîäòÿæêà ñòîïîâ                                                  |
//+-------------------------------------------------------------------------------------+
bool SetOrders(string& Message[])
{
// - 1 - == Ðàñ÷åò óðîâíåé âõîäà è âûõîäà èç ñäåëîê =====================================
 bool Buy = False, Sell = False;                                 // Ñäåëêè åùå íå íàéäåíû
 double BuyStop = NP(Resis + Spread + Tick);// Öåíà îòêðûòèÿ äëÿ BuyStop è ñòîïà äëÿ Sell
 double SellStop = NP(Supp - Tick);         // Öåíà îòêðûòèÿ äëÿ SellStop è ñòîïà äëÿ Buy
 double BuyTake = NP(2*BuyStop - SellStop);                       // Öåíà äëÿ ïðîôèòà Buy
 double SellTake = NP(2*SellStop - BuyStop);                     // Öåíà äëÿ ïðîôèòà Sell
// - 1 -  == Îêîí÷àíèå áëîêà ============================================================
// - 2 - == Ïîèñê ñâîèõ îðäåðîâ/ïîçèöèé =================================================
 for (int i = OrdersTotal()-1; i >= 0; i--)
   if (OrderSelect(i, SELECT_BY_POS))
     if (OrderSymbol() == Symbol() && (OrderMagicNumber() == MagicNumber ||
         OrderMagicNumber() == MagicNumber+1))
// - 2 -  == Îêîí÷àíèå áëîêà ============================================================
// - 3 - == Íàéäåí BUY ==================================================================
       {
        RefreshRates();
        if (OrderType() == OP_BUY)
          {
           Buy = True;
           // Åñëè ó BUY óñòàíîâëåí íåâåðíûé ñòîï, òî èçìåíÿåì ñòîï è ïðîôèò
           if (ND(OrderStopLoss() - SellStop) != 0 && ND(Bid - StopLevel - SellStop) > 0
               && ND(BuyTake - Bid - StopLevel) > 0)
             if (WaitForTradeContext())
               if (!OrderModify(OrderTicket(), 0, SellStop, BuyTake, 0))
                 return(False);
          }       
// - 3 -  == Îêîí÷àíèå áëîêà ============================================================
// - 4 - == Íàéäåí BUYSTOP ==============================================================
        if (OrderType() == OP_BUYSTOP)
          {
           Buy = True;
           // Åñëè ó îðäåðà íåïðàâèëüíàÿ öåíà îòêðûòèÿ, òî èçìåíÿåì öåíó, ñòîï è ïðîôèò
           if (ND(OrderOpenPrice() - BuyStop) != 0 && ND(BuyStop - Ask - StopLevel) > 0
               && ND(OrderOpenPrice() - Ask - FreezeLevel) > 0)
             if (WaitForTradeContext())
               if (!OrderModify(OrderTicket(), BuyStop, SellStop, BuyTake, 0))
                 return(False);
          }       
// - 4 -  == Îêîí÷àíèå áëîêà ============================================================
// - 5 - == Íàéäåí SELL =================================================================
        if (OrderType() == OP_SELL)
          {
           Sell = True;
           if (ND(OrderStopLoss() - BuyStop) != 0 && ND(BuyStop - Ask - StopLevel) > 0 &&
               ND(Bid - StopLevel - SellTake) > 0)
             if (WaitForTradeContext())
               if (!OrderModify(OrderTicket(), 0, BuyStop, SellTake, 0))
                 return(False);
          }       
// - 5 -  == Îêîí÷àíèå áëîêà ============================================================
// - 6 - == Íàéäåí SELLSTOP =============================================================
        if (OrderType() == OP_SELLSTOP)
          {
           Sell = True;
           if (ND(OrderOpenPrice() - SellStop) != 0 && ND(Bid - SellStop - StopLevel) > 0
               && ND(Bid - OrderOpenPrice() - FreezeLevel) > 0)
             if (WaitForTradeContext())
               if (!OrderModify(OrderTicket(), SellStop, BuyStop, SellTake, 0))
                 return(False);
          }       
       }
// - 6 - === Îêîí÷àíèå áëîêà ============================================================
       
// - 7 - == BuyStop èëè Buy íå íàéäåíû - óñòàíîâêà BuyStop ==============================
 if (!Buy && Ask < Resis)
   if (OpenOrderCorrect(Message, OP_BUYSTOP, BuyStop, SellStop, BuyTake, MagicNumber) > 0)
     return(False);
// - 7 - === Îêîí÷àíèå áëîêà ============================================================
 
// - 8 - == SellStop èëè Sell íå íàéäåíû - óñòàíîâêà SellStop ===========================
 if (!Sell && Bid > Supp)
   if (OpenOrderCorrect(Message, OP_SELLSTOP, SellStop, BuyStop, SellTake,
       MagicNumber+1) > 0)
     return(False);
// - 8 - === Îêîí÷àíèå áëîêà ============================================================
}
   
             
            
            
            
Comments