RollBackInTrend_Expert

Author: Scriptong
Profit factor:
0.74

This script, named "RollBackInTrend_Expert," is designed to automatically trade on the Metatrader platform. It aims to identify opportunities to enter trades that align with the current trend in the market, specifically when the price momentarily pulls back against that trend. Here's a breakdown of how it works:

1. Initial Setup:

  • Defining Parameters: The script starts by defining several adjustable settings (input parameters) that the user can customize. These include:
    • Lots: The size of each trade (e.g., 0.1 lots).
    • FastMACD, SlowMACD, SignalMACD: Settings for the MACD indicator, which helps identify trend direction and potential reversals.
    • OpenOrderSound: The sound to play when a trade is opened.
    • MagicNumber: A unique identifier for trades managed by this script, helping it distinguish its trades from others.
    • Koeff: A percentage used to calculate the profit target (take profit) based on the channel width.
  • Gathering Market Information: The script gathers essential details about the currency pair it's trading, such as the minimum price change (Tick), the spread (difference between buy and sell price), stop levels, and allowable trade sizes.
  • Error Checking: It verifies that the specified trade size (Lots) is within the permissible range allowed by the broker. If not, the script stops running to prevent errors.

2. Identifying the Trend:

  • Using Fractals: The script uses "Fractals," which are patterns on a chart that help identify potential turning points in price. It looks for the two most recent up and down fractals. By comparing the position of the fractals, it tries to determine if the price is generally trending upwards, downwards, or sideways.
  • MACD Confirmation: In addition to Fractals, the script uses the MACD indicator. MACD helps to understand the momentum and strength of a trend. The script looks for specific patterns in the MACD to confirm the trend direction and identify potential pullback opportunities.

3. Determining Entry Signals (Pullbacks):

  • MACD Pullback: The script identifies situations where the MACD indicator suggests a temporary pullback against the prevailing trend.
  • Channel Confirmation: It then attempts to draw a channel based on the identified fractals. A channel represents a potential range within which the price is expected to move. It validates to see the calculated channel contains the price movement.
  • Entry Conditions: The script only considers opening a trade if:
    • The MACD suggests a pullback.
    • A trend can be identified with the Fractals.
    • The current price is within the lower half of the channel (for a buy signal) or the upper half (for a sell signal).

4. Opening Trades:

  • Checking Available Funds: Before opening a trade, the script checks if there are sufficient funds in the trading account to cover the trade.
  • Order Placement: If all conditions are met, the script sends an order to the broker to open a trade in the direction of the trend. The script sets stop-loss and take-profit levels:
    • Stop-loss: The maximum amount of money the script is willing to risk on the trade. It is based on the fractal levels.
    • Take-profit: The target price at which the script will automatically close the trade for a profit. The take profit is a percentage of the channel's width.
  • Sound Alert: Plays a sound to notify the user that a trade has been opened.

5. Managing Existing Trades:

  • Trailing Stop: The script places a pending order that moves the stop-loss to the position stop-loss, creating a "trailing stop." This automatically adjusts the stop-loss level as the price moves in a favorable direction, helping to lock in profits.
  • Closing Opposite Positions: If a new trade signal appears in the opposite direction of an existing trade, the script attempts to close the existing trade before opening the new one.

6. Error Handling:

  • Trade Context: It contains trade context validation and retry.
  • Fatal Error Detection: The script detects critical errors that prevent it from functioning correctly. If such an error occurs, the script stops trading and displays a message.
  • Insufficient Funds Alert: The script shows alert message if there are insufficient funds.

In Summary:

The "RollBackInTrend_Expert" script is an automated trading tool that attempts to capitalize on temporary price pullbacks within established trends. It uses Fractals and MACD to identify trends, waits for a pullback, and then enters a trade in the direction of the trend with pre-defined stop-loss and take-profit levels. The script also includes features to manage existing trades and handle potential errors.

Orders Execution
It automatically opens orders when conditions are reachedChecks for the total of open orders
Indicators Used
FractalsMACD Histogram
Miscellaneous
It plays sound alerts
1 Views
0 Downloads
0 Favorites
RollBackInTrend_Expert
//+-------------------------------------------------------------------------------------+
//|                                       RollBackInTrend_Expert.mq4                    |
//|                                                        Scriptong                    |
//|                                                                                     |
//+-------------------------------------------------------------------------------------+
#property copyright "Scriptong"
#property link      "scriptong@mail.ru"

//---- input parameters
extern double    Lots        = 0.1;                          // Îáúåì îòêðûâàåìîé ïîçèöèè
extern string    A1 = "Ïàðàìåòðû èíäèêàòîðà MACD";
extern int       FastMACD = 12;                                      // Ïåðèîä áûñòðîé ÌÀ
extern int       SlowMACD = 26;                                    // Ïåðèîä ìåäëåííîé ÌÀ
extern int       SignalMACD = 9;                                  // Ïåðèîä ñèãíàëüíîé ÌÀ
extern string    A2 = "=====================================";
extern string    OpenOrderSound = "ok.wav";                  // Çâóê äëÿ îòêðûòèÿ ïîçèöèè
extern int       MagicNumber = 17589 ;                         // Ìàãèê ïîçèöèé ñîâåòíèêà
extern double    Koeff = 0.85;  // ×àñòü øèðèíû êàíàëà, îò êîòîðîé ñ÷èòàåòñÿ öåëü ïîçèöèè
bool Activate, FreeMarginAlert, FatalError;
double Tick, Spread, StopLevel, MinLot, MaxLot, LotStep, UpFractal1, UpFractal2, 
       DownFractal1, DownFractal2, TP, SL;
datetime LastBar;
int Signal, TypeOrder, LastType, TicketOrder, TU1, TU2, TD1, TD2;


//+-------------------------------------------------------------------------------------+
//| Ôóíêöèÿ èíèöèàëèçàöèè ýêñïåðòà                                                      |
//+-------------------------------------------------------------------------------------+
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 - == Îêîí÷àíèå áëîêà =============================================================

   LastBar = 0;
   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);    
}
 
//+-------------------------------------------------------------------------------------+
//| Íàõîäèì äâà ïîñëåäíèõ íèæíèõ è âåðõíèõ ôðàêòàëà, ïî êîòîðûì îïðåäåëÿåì òåêóùèé òðåíä|
//| (0 - íåò, 1 - âîñõîäÿùèé, 2 - íèñõîäÿùèé)                                           |
//+-------------------------------------------------------------------------------------+
int FindFractals()
{
// - 1 - ======= Ïîèñê ôðàêòàëîâ ========================================================
   UpFractal1 = 0;
   UpFractal2 = 0;
   DownFractal1 = 0;
   DownFractal2 = 0;
   int i = 3;
   while ((UpFractal1 == 0 || UpFractal2 == 0 || DownFractal1 == 0 || DownFractal2 == 0)
           && i < Bars)   // öèêë ïðîäîëæàåòñÿ, ïîêà íå áóäóò íàéäåíû âñå ÷åòûðå ôðàêòàëà
     {
      double Up = iFractals(Symbol(), 0, MODE_UPPER, i);               // âåðõíèé ôðàêòàë
      double Dn = iFractals(Symbol(), 0, MODE_LOWER, i);                // íèæíèé ôðàêòàë
      if (Up != 0)                           // åñëè íà òåêóùåì áàðå åñòü âåðõíèé ôðàêòàë
        if (UpFractal1 == 0)                    // è ýòî ïåðâûé íàéäåííûé âåðõíèé ôðàêòàë
          {
           UpFractal1 = Up;                                     // ñîõðàíÿåì åãî çíà÷åíèå
           TU1 = i;                                            // è çàïîìèíàåì íîìåð áàðà
          } 
         else
          if (UpFractal2 == 0)           // åñëè ýòî óæå âòîðîé íàéäåííûé âåðõíèé ôðàêòàë
            {
             UpFractal2 = Up;           // òî ñîõðàíÿåì åãî çíà÷åíèå âî âòîðóþ ïåðåìåííóþ
             TU2 = i;                                    // è ñíîâà çàïîìèíàåì íîìåð áàðà
            } 
      if (Dn != 0)                            // åñëè íà òåêóùåì áàðå åñòü íèæíèé ôðàêòàë
        if (DownFractal1 == 0)                   // è ýòî ïåðâûé íàéäåííûé íèæíèé ôðàêòàë
          { 
           DownFractal1 = Dn;                                   // ñîõðàíÿåì åãî çíà÷åíèå
           TD1 = i;                                            // è çàïîìèíàåì íîìåð áàðà
          } 
         else
          if (DownFractal2 == 0)          // åñëè ýòî óæå âòîðîé íàéäåííûé íèæíèé ôðàêòàë
            {
             DownFractal2 = Dn;         // òî ñîõðàíÿåì åãî çíà÷åíèå âî âòîðóþ ïåðåìåííóþ
             TD2 = i;                                    // è ñíîâà çàïîìèíàåì íîìåð áàðà
            }
      i++;
     }
// - 1 - ======= Îêîí÷àíèå áëîêà ========================================================
      
// - 2 - ======= Àíàëèç ïîëó÷åííûõ ðåçóëüòàòîâ ==========================================
   if (UpFractal1 == 0 || DownFractal1 == 0 ||       // Åñëè íå íàéäåí îäèí èç ôðàêòàëîâ, 
       UpFractal2 == 0 || DownFractal2 == 0)// òî ýòî îøèáêà è ôóíêöèÿ âåðíåò çíà÷åíèå -1
     {
      Print("Îøèáêà â èñòîðèè. Íå íàéäåí îäèí èç ôðàêòàëîâ!");
      return(-1);
     }
     
   // Îïðåäåëåíèå òðåíäà
   if(UpFractal1 > UpFractal2 && DownFractal1 > DownFractal2)
     return(1);   // Âîñõîäÿùèé
     
   if(UpFractal1 < UpFractal2 && DownFractal1 < DownFractal2)
     return(2);   // Íèñõîäÿùèé
// - 2 - ======= Îêîí÷àíèå áëîêà ========================================================
     
   return(0); // íåò òðåíäà
   // ------------------  
}  

//+-------------------------------------------------------------------------------------+
//| Ðàñ÷åò êîýôôèöèåíòîâ K è B â óðàâíåíèè ïðÿìîé ïî äâóì òî÷êàì                        |
//| Óðàâíåíèå ïðÿìîé Y = K*X + B, ïîýòîìó ñîñòàâèâ ñèñòåìó èç äâóõ óðàâíåíèé,           |
//| ìîæíî íàéòè íåèçâåñòíûå K è B, åñëè èçâåñòíû Y1, Y2, X1, X2                         |
//+-------------------------------------------------------------------------------------+
void DirectLineCalc(int XB, double YB, int XE, double YE, double &B, double &K) 
{
 B = (YB*XE - YE*XB)/(XE - XB);
 K = (YE - B)/XE;
} 

//+-------------------------------------------------------------------------------------+
//| Ðàñ÷åò ñèãíàëà ïî MACD è êàíàëó, îáðàçîâàííîãî ôðàêòàëàìè                           |
//+-------------------------------------------------------------------------------------+
void GetSignal()
{
 Signal = 0;                                                         // îáíóëåíèå ñèãíàëà
 
// - 1 - == Áåðåì çíà÷åíèÿ MACD íà 1-4 áàðàõ ============================================
 double MACD1, MACD2, MACD3, MACD4, SMACD;
 MACD1 = iMACD(Symbol(), 0, FastMACD, SlowMACD, SignalMACD, PRICE_CLOSE, MODE_MAIN, 1);
 MACD2 = iMACD(Symbol(), 0, FastMACD, SlowMACD, SignalMACD, PRICE_CLOSE, MODE_MAIN, 2);
 MACD3 = iMACD(Symbol(), 0, FastMACD, SlowMACD, SignalMACD, PRICE_CLOSE, MODE_MAIN, 3);
 MACD4 = iMACD(Symbol(), 0, FastMACD, SlowMACD, SignalMACD, PRICE_CLOSE, MODE_MAIN, 4);
 SMACD = iMACD(Symbol(), 0, FastMACD, SlowMACD, SignalMACD, PRICE_CLOSE, MODE_SIGNAL, 1);
// - 1 - == Îêîí÷àíèå áëîêà =============================================================

// - 2 - == Ñèãíàë îòêðûòèÿ BUY =========================================================
 double DirectB = 0, DirectK = 0;
 if (SMACD < MACD1 && MACD1 < MACD2 && MACD2 > MACD3 && MACD3 > MACD4)   // îòêàò íà MACD
   if (FindFractals() == 1)                                  // ïîñòðîåí âîñõîäÿùèé êàíàë
     {                                      
      double ThirdFractal = DownFractal1;   // â êà÷åñòâå îäíîãî íèæíåãî ôðàêòàëà ñíà÷àëà                 
      int ThirdNumber = TD1;                               // áåðåì ïåðâûé íèæíèé ôðàêòàë
      DirectLineCalc(TU1, UpFractal1, TU2, UpFractal2, DirectB, DirectK); // ðàñ÷åò K è B
      double ParallelB = DownFractal1 - DirectK*TD1;    // Ðàñ÷åò B íèæíåé ãðàíèöû êàíàëà
      if (DownFractal2 < DirectK*TD2+ParallelB)//Åñëè âòîðîé íèæíèé ôðàêòàë íå ïîìåùàåòñÿ
        {                  // â ïîëó÷åííûé êàíàë, òî ïåðåñ÷èòûâàåì íèæíþþ ãðàíèöó ïî íåìó
         ThirdFractal = DownFractal2;
         ThirdNumber = TD2;
         ParallelB = DownFractal2 - DirectK*TD2;
        }           
                   // Ïðîâåðÿåì, ïîïàäàþò ëè öåíû çàêðûòèÿ âñåõ ñâå÷åé â ïîëó÷åííûé êàíàë
      for (int i = MathMax(TD2, TU2); i >= MathMax(TD1, TU1); i--)
        if (Close[i] < DirectK*i+ParallelB || Close[i] > DirectK*i+DirectB)
          {
           DirectK = 0;                      // åñëè íå ïîïàäàþò, òî êàíàë íå ñôîðìèðîâàí
           break;
          } 
      // ---------------
      if (DirectK != 0 && ND(Bid+StopLevel) < ND((DirectB+ParallelB)/2))
        {   // âñå öåíû çàêðûòèÿ ïîïàëè â êàíàë è öåíà íàõîäèòñÿ â íèæíåé ïîëîâèíå êàíàëà
         TP = (DirectB-ParallelB)*Koeff+ParallelB;
         SL = ThirdFractal-2*Tick;
         Signal = 1;                                        // òî ýòî ñèãíàë îòêðûòèÿ BUY
        } 
     } 
// - 2 - == Îêîí÷àíèå áëîêà =============================================================

// - 3 - == Ñèãíàë îòêðûòèÿ SELL ========================================================
 if (SMACD > MACD1 && MACD1 > MACD2 && MACD2 < MACD3 && MACD3 < MACD4)   // îòêàò íà MACD
   if (FindFractals() == 2)                                  // ïîñòðîåí íèñõîäÿùèé êàíàë
     {
      ThirdFractal = UpFractal1;    // â êà÷åñòâå îäíîãî âåðõíåãî ôðàêòàëà ñíà÷àëà  áåðåì
      ThirdNumber = TU1;                                        // ïåðâûé âåðõíèé ôðàêòàë
      DirectLineCalc(TD1, DownFractal1, TD2, DownFractal2, DirectB, DirectK);    // K è B
      ParallelB = UpFractal1 - DirectK*TU1;//Ðàñ÷åò êîýôôèöèåíòà B âåðõíåé ãðàíèöû êàíàëà
      if (UpFractal2 > DirectK*TU2+ParallelB)// Åñëè âòîðîé âåðõíèé ôðàêòàë íå ïîìåùàåòñÿ
        {                 // â ïîëó÷åííûé êàíàë, òî ïåðåñ÷èòûâàåì âåðõíþþ ãðàíèöó ïî íåìó
         ThirdFractal = UpFractal2;
         ThirdNumber = TU2;
         ParallelB = UpFractal2 - DirectK*TU2;
        }           
                   // Ïðîâåðÿåì, ïîïàäàþò ëè öåíû çàêðûòèÿ âñåõ ñâå÷åé â ïîëó÷åííûé êàíàë
      for (i = MathMax(TD2, TU2); i >= MathMax(TD1, TU1); i--)
        if (Close[i] > DirectK*i+ParallelB || Close[i] < DirectK*i+DirectB)
          {
           DirectK = 0;                      // åñëè íå ïîïàäàþò, òî êàíàë íå ñôîðìèðîâàí
           break;
          } 
      // ---------------
      if (DirectK != 0 && ND(Bid-StopLevel) > ND((DirectB+ParallelB)/2))
        {  // âñå öåíû çàêðûòèÿ ïîïàëè â êàíàë è öåíà íàõîäèòñÿ â âåðõíåé ïîëîâèíå êàíàëà
         SL = ThirdFractal + Spread + 2*Tick;
         TP = ParallelB - (ParallelB - DirectB)*Koeff+Spread;
         Signal = 2;                                       // òî ýòî ñèãíàë îòêðûòèÿ SELL
        }
     }   
// - 3 - == Îêîí÷àíèå áëîêà =============================================================
}  

//+-------------------------------------------------------------------------------------+
//| Óäàëÿåò âñå îòëîæåííèêè òèïà Type. Åñëè óäàëèòü íå óäàëîñü, òî âåðíåò 1.            |
//+-------------------------------------------------------------------------------------+
bool CheckPendingsReal(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 (!OrderDelete(OrderTicket()))                  // òî ïûòàåìñÿ óäàëèòü åãî
              return(False);                         // íå óäàëîñü óäàëèòü - âåðíåì False
            }  
           else
            return(False);//âåðíåì False, åñëè íå äîæäàëèñü îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà
         }
        else
         return(False);        // âåðíåì False, åñëè íàéäåí îðäåð íå ñîîòâåòñòâóþùèé Type
 return(True);                                             // åñëè âñå ÎÊ, òî âåðíåì True
}  


//+-------------------------------------------------------------------------------------+
//| Çàêðûâàåò âñå ïîçèöèè òèïà 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
}  

//+-------------------------------------------------------------------------------------+
//| Ïîèñê ïåðâè÷íîé ïîçèöèè è óñòàíîâêà åé îòëîæåííèêà                                  |
//+-------------------------------------------------------------------------------------+
bool AddPending()
{
// - 1 - == Ïîèñê ïåðâè÷íîé ïîçèöèè =====================================================
 for (int i = OrdersTotal()-1; i >= 0; i--)
   if (OrderSelect(i, SELECT_BY_POS))
     if (OrderSymbol() == Symbol() && MathMod(OrderMagicNumber(), 10) == 0 
        && OrderType() < 2)     // ïîèñê ïåðâè÷íîé ïîçèöèè , êîòîðàÿ îòêðûëàñü ïî ñèãíàëó
        {
         bool Res = False;     
         int Type = OrderType();                              // çàïîìèíàåì åå ïàðàìåòðû
         double OpenP = OrderStopLoss();
         double TP = MathAbs(OrderOpenPrice()-OrderStopLoss());
         double SL = OrderTakeProfit();
// - 1 - == Îêîí÷àíèå áëîêà =============================================================

// - 2 - == Ïîèñê îòëîæåííèêà, êîòîðûé äîëæåí áûòü óñòàíîâëåí íà ñòîïå ïîçèöèè ==========
         for (int j = OrdersTotal()-1; j >= 0; j--)
            if (OrderSelect(j, SELECT_BY_POS))
              if (OrderSymbol() == Symbol() && MathMod(OrderMagicNumber(), 10) == 1 
                && OrderType() > 2)       
             {   
              Res = True;               // îòëîæåííèê íàéäåí, íåò íóæäû åãî óñòàíàâëèâàòü
              break;
             } 
// - 2 - == Îêîí÷àíèå áëîêà =============================================================

// - 3 - == Óñòàíîâêà îòëîæåííîãî îðäåðà ================================================
         if (!Res)                          // åñëè îòëîæåííèê íå íàéäåí, òî óñàíîâèì åãî
           {
            if (Type == OP_BUY)                     // åñëè ïåðâè÷íàÿ ïîçèöèÿ äëèííàÿ, òî
              {
               Type = OP_SELLSTOP;                             // óñòàíàâëèâàåì SELL STOP
               TP = OpenP - TP;      // è öåëü îòñòîèò îò öåíû îòêðûòèÿ íà âåëè÷èíó ñòîïà
              } 
             else
              {                                    // åñëè ïåðâè÷íàÿ ïîçèöèÿ êîðîòêàÿ, òî
               Type = OP_BUYSTOP;                               // óñòàíàâëèâàåì BUY STOP
               TP = OpenP + TP;      // è öåëü îòñòîèò îò öåíû îòêðûòèÿ íà âåëè÷èíó ñòîïà
              } 
            if (!OpenOrder(Type, OpenP, SL, TP, 1))         // åñëè óñòàíîâèòü íå óäàëîñü
              return(False);                                          // âîçâðàùàåì False
           }
// - 3 - == Îêîí÷àíèå áëîêà =============================================================
         break;
        }
 return(True);
}

//+-------------------------------------------------------------------------------------+
//| Ïîèñê ïåðâè÷íîé ïîçèöèè è óäàëåíèå ñîîòâåòñòâóþùåãî åé îòëîæåííèêà, åñëè ïîçèöèè íåò|
//+-------------------------------------------------------------------------------------+
void DeletePending()
{
 for (int i = OrdersTotal()-1; i >= 0; i--)
   if (OrderSelect(i, SELECT_BY_POS))
     if (OrderSymbol() == Symbol() && MathMod(OrderMagicNumber(), 10) == 1 
        && OrderType() > 2)                                   // ïîèñê îòëîæåííîãî îðäåðà
        {
         bool Res = False;
         int Ticket = OrderTicket();
         // Ïîèñê ïîçèöèè, ñîîòâåòñòâóþùåé îòëîæåííèêó
         for (int j = OrdersTotal()-1; j >= 0; j--)
            if (OrderSelect(j, SELECT_BY_POS))
              if (OrderSymbol() == Symbol() && MathMod(OrderMagicNumber(), 10) == 0 
                && OrderType() < 2)                        
             {   
              Res = True;
              break;
             } 
         // Åñëè îòëîæåííèêà íåò, òî óäàëÿåì
         if (!Res)
           OrderDelete(Ticket);
         // ------------------------------------   
         break;
        }
}

//+-------------------------------------------------------------------------------------+
//| Ôóíêöèÿ START ýêñïåðòà                                                              |
//+-------------------------------------------------------------------------------------+
int start()
  {
// - 1 -  == Ðàçðåøåíî ëè ñîâåòíèêó ðàáîòàòü? ===========================================
   if (!Activate || FatalError)             // Îòêëþ÷àåòñÿ ðàáîòà ñîâåòíèêà, åñëè ôóíêöèÿ
    return(0);           //  init çàâåðøèëàñü ñ îøèáêîé  èëè èìåëà ìåñòî ôàòàëüíàÿ îøèáêà
// - 1 -  == Îêîí÷àíèå áëîêà ============================================================

// - 2 - == Óäàëåíèå îòëîæåííîãî îðäåðà ïðè çàêðûòèè ïåðâè÷íîé ïîçèöèè ïî ïðîôèòó =======
   DeletePending();
// - 2 -  == Îêîí÷àíèå áëîêà ============================================================

// - 3 -  == Êîíòðîëü îòêðûòèÿ íîâîãî áàðà ==============================================
   if (LastBar == Time[0])     //Åñëè âðåìÿ ïîñ÷èòàííîãî áàðà ðàâíî âðåìåíè òåêóùåãî áàðà
     return(0);                         // òî ýòî îçíà÷àåò, ÷òî íîâûé áàð åùå íå îòêðûëñÿ
// - 3 -  == Îêîí÷àíèå áëîêà ============================================================

// - 4 - == Ñáîð èíôîðìàöèè îá óñëîâèÿõ òîðãîâëè ========================================
   Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point);                  // òåêùèé ñïðýä
   StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point);  // òåêóùèé óðîâåíü ñòîïîâ 
// - 4 -  == Îêîí÷àíèå áëîêà ============================================================
     
// - 5 - == Ðàñ÷åò òåêóùåãî ñèãíàëà =====================================================
   GetSignal();
// - 5 -  == Îêîí÷àíèå áëîêà ============================================================
   
// - 6 - == Îòêðûòèå äëèííîé  ïîçèöèè ===================================================
   if (Signal == 1)
     {
      int Res = CheckOrdersReal(OP_SELL);            // Ïðîòèâîïîëîæíóþ ïîçèöèþ - çàêðûòü
      if (Res == 0)                                          // åñëè íåò îòêðûòûõ ïîçèöèé
        {
         if (!CheckPendingsReal(OP_BUYSTOP)) return(0);       // è íåò îòëîæåííûõ îðäåðîâ
         RefreshRates();
         if (ND(Bid-SL-StopLevel) > 0)
           if (!OpenOrder(OP_BUY, ND(Ask), ND(SL), ND(TP), 0)) // åñëè íå óäàëîñü îòêðûòü
             return(0);                                // òî ïîïðîáóåì ñî ñëåäóþùèì òèêîì
        }
      if(Res == 1) return(0); //çàêðûòü ïðîòèâîïîëîæíóþ íå âûøëî, æäåì äî ñëåäóþùåãî òèêà
     }
// - 6 -  == Îêîí÷àíèå áëîêà ============================================================
     
// - 7 - == Îòêðûòèå êîðîòêîé ïîçèöèè ===================================================
   if (Signal == 2)
     {
      Res = CheckOrdersReal(OP_BUY);                 // Ïðîòèâîïîëîæíóþ ïîçèöèþ - çàêðûòü
      if (Res == 0)                                          // åñëè íåò îòêðûòûõ ïîçèöèé
        {
         if (!CheckPendingsReal(OP_SELLSTOP)) return(0);               // è íåò SELL STOP
         RefreshRates();
         if (ND(SL-Ask-StopLevel) > 0)
           if (!OpenOrder(OP_SELL, ND(Bid), ND(SL), ND(TP), 0))// åñëè íå óäàëîñü îòêðûòü
             return(0);                                // òî ïîïðîáóåì ñî ñëåäóþùèì òèêîì
        }
      if (Res == 1) return(0);//çàêðûòü ïðîòèâîïîëîæíóþ íå âûøëî, æäåì äî ñëåäóþùåãî òèêà 
     }
// - 7 -  == Îêîí÷àíèå áëîêà ============================================================

// - 8 - == Äîáàâëåíèå îòëîæåííîãî îðäåðà ê ïåðâè÷íîé ïîçèöèè ===========================
    if (!AddPending()) return(0);
// - 8 -  == Îêîí÷àíèå áëîêà ============================================================

   LastBar = Time[0];                                            // íîâûé áàð "ïîñ÷èòàëè"
  
//----
   return(0);
  }
//+------------------------------------------------------------------+

Profitability Reports

EUR/USD Jan 2025 - Jul 2025
1.04
Total Trades 99
Won Trades 53
Lost trades 46
Win Rate 53.54 %
Expected payoff 0.48
Gross Profit 1285.20
Gross Loss -1238.00
Total Net Profit 47.20
-100%
-50%
0%
50%
100%
AUD/USD Jan 2025 - Jul 2025
0.80
Total Trades 94
Won Trades 51
Lost trades 43
Win Rate 54.26 %
Expected payoff -2.73
Gross Profit 1020.00
Gross Loss -1276.20
Total Net Profit -256.20
-100%
-50%
0%
50%
100%
USD/CAD Oct 2024 - Jan 2025
1.13
Total Trades 51
Won Trades 32
Lost trades 19
Win Rate 62.75 %
Expected payoff 0.92
Gross Profit 405.48
Gross Loss -358.58
Total Net Profit 46.90
-100%
-50%
0%
50%
100%
NZD/USD Oct 2024 - Jan 2025
0.56
Total Trades 46
Won Trades 20
Lost trades 26
Win Rate 43.48 %
Expected payoff -4.58
Gross Profit 269.90
Gross Loss -480.40
Total Net Profit -210.50
-100%
-50%
0%
50%
100%
GBP/USD Oct 2024 - Jan 2025
0.49
Total Trades 48
Won Trades 21
Lost trades 27
Win Rate 43.75 %
Expected payoff -12.50
Gross Profit 566.30
Gross Loss -1166.20
Total Net Profit -599.90
-100%
-50%
0%
50%
100%
AUD/USD Oct 2024 - Jan 2025
0.73
Total Trades 47
Won Trades 0
Lost trades 0
Win Rate 0.00 %
Expected payoff -3.41
Gross Profit 425.80
Gross Loss -586.20
Total Net Profit -160.40
-100%
-50%
0%
50%
100%

Comments