PENDING ORDER is the best solution to Open a position few Pips less than Ask price?

 

Hi, 

I´m developing this mql4 EA, long story short, I´m stuck trying to place a pending order when all the condition are satisfied, and with an open price 10 pips less that the Ask value when all the condition are satisfied.

The EA works well until the opening price is "Ask". I did a couple of try modifing "Ticket=OrderSend(Symb,OP_BUY,Lts,Ask,2,SL,TP)" with "Ticket=OrderSend(Symb,OP_BUYLIMIT,Lts,"New variable for opening 10 pips less than Ask",2,SL,TP)" and the position is opened as expected but the closing no, basically the trade is close late and with a logic that I cannot understand actually.

Someone have an idea how to fix it? Or a better way to implement my idea?

Thanks

extern double TakeProfit =580;
extern double Tral_Stop =30;
extern double StopLoss =20;      
extern double Lots       =0.1;     
extern double Prots      =0.07;    
extern double StopEAlowLIMIT = 980.00;
extern double VolumeDoji = 35;
extern double Thres=5;
extern double OMBRAlow=7;
bool Work=true;                    
string Symb;                       

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsNewBar()
  {
   static datetime lastbar;
   datetime curbar = (datetime)SeriesInfoInteger(_Symbol,_Period,SERIES_LASTBAR_DATE);
   if(lastbar != curbar)
     {
      lastbar = curbar;
      return true;
     }
   return false;
  }


//--------------------------------------------------------------- 2 --
int start()
  {
   int
   Total,                           
   Tip=-1,                          
   Ticket,                          
   Period_MA_3=160;
   double
   Lot,                             
   Lts,                             
   Min_Lot,                         
   Step,                            
   Free,                            
   One_Lot,                         
   Price,                           
   SL,                              
   TP;                             
   bool
   Ans  =false,                     
   Cls_B=false,                     
   Cls_S=false,                     
   Opn_B=false,                     
   Opn_S=false;

   string start = "9:30";

   string finish = "18:00";

   datetime curT = TimeCurrent();
   datetime DayWeek = DayOfWeek();
   datetime s_time = StringToTime(TimeToString(curT, TIME_DATE) + " " + start);

   datetime f_time = StringToTime(TimeToString(curT, TIME_DATE) + " " + finish);

   if(curT <  s_time)
     {
      return false;   //--wait till time is ok to open
     }
   if(curT >= f_time)
     {
      return false;   //--stop if finish time is reached
     }
   if(DayWeek==0 || DayWeek==6)
     {
      return false;
     }


//--------------------------------------------------------------- 3 --

// Preliminary processing
   if(Bars < Period_MA_3)                       // Not enough bars
     {
      Alert("Not enough bars in the window. EA doesn't work.");
      return false;                                   // Exit start()
     }
   if(Work==false)                              // Critical error
     {
      Alert("Critical error. EA doesn't work.");
      return false;                                   // Exit start()
     }
   if(AccountEquity()<=StopEAlowLIMIT)
     {
      Alert("Stop EA: DROWDOWN limit reached");
      return false;                                   // Exit start()
     }


//--------------------------------------------------------------- 4 --
// Orders accounting
   Symb=Symbol();                               // Security name.
   Total=0;
// Amount of orders
   for(int i=1; i<=OrdersTotal(); i++)          // Loop through orders
     {
      if(OrderSelect(i-1,SELECT_BY_POS)==true)  // If there is the next one
        {
         // Analyzing orders:
         if(OrderSymbol()!=Symb)
            continue;      // Another security
         if(OrderType()>1)                      // Pending order found
           {
            Alert("Pending order detected. EA doesn't work.");
            return false;                             // Exit start()
           }
         Total++;                               // Counter of market orders
         if(Total>1)                            // No more than one order
           {
            Alert("Several market orders. EA doesn't work.");
            return false;                             // Exit start()
           }
         Ticket=OrderTicket();                  // Number of selected order
         Tip   =OrderType();                    // Type of selected order
         Price =OrderOpenPrice();               // Price of selected order
         SL    =OrderStopLoss();                // SL of selected order
         TP    =OrderTakeProfit();              // TP of selected order
         Lot   =OrderLots();                    // Amount of lots
        }
     }



//-------Trailling SL--------------------------------------------------

   for(int j=1; j<=OrdersTotal(); j++)
     {
      if(OrderSelect(j-1,SELECT_BY_POS)==true)
        {
         Tip=OrderType();
         if(OrderSymbol()!=Symb||Tip>1)
            continue;
         SL=OrderStopLoss();
         //------------------------------------------------------ 3 --
         while(true)
           {
            double TS=Tral_Stop;
            int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL);
            if(TS<Min_Dist)
               TS=Min_Dist;
            //--------------------------------------------------- 4 --
            bool Modify=false;
            switch(Tip)
              {
               case 0 :
                  if(NormalizeDouble(SL,Digits)<
                     NormalizeDouble(Bid-TS*Point,Digits))
                    {
                     SL=Bid-TS*Point;
                     string Text="Buy ";
                     Modify=true;
                    }
                  break;
               case 1 :
                  if(NormalizeDouble(SL,Digits)>
                     NormalizeDouble(Ask+TS*Point,Digits)
                     || NormalizeDouble(SL,Digits)==0)
                    {
                     SL=Ask+TS*Point;
                     Text="Sell ";
                     Modify=true;
                    }
              }
            if(Modify==false)
               break;


            //--------------------------------------------------- 5 --------------------------

            TP    =OrderTakeProfit();
            Price =OrderOpenPrice();
            Ticket=OrderTicket();

            Alert("Modification ",Text,Ticket,". Awaiting response..");
            bool Ans2=OrderModify(Ticket,Price,SL,TP,0);//Modify it!

            //--------------------------------------------------- 6 --------------------------
            if(Ans2==true)                       // Got it! :)
              {
               Alert("Order ",Text,Ticket," is modified:)");
               break;                           // From modification cycle.
              }

           }
         int Error=GetLastError();           // Failed :(
         switch(Error)                       // Overcomable errors
           {
            case 130:
               Alert("Wrong stops. Retrying.");
               RefreshRates();               // Update data
               continue;                     // At the next iteration
            case 136:
               Alert("No prices. Waiting for a new tick..");
               while(RefreshRates()==false)  // To the new tick
                  Sleep(1);                  // Cycle delay
               continue;                     // At the next iteration
            case 146:
               Alert("Trading subsystem is busy. Retrying ");
               Sleep(500);                   // Simple solution
               RefreshRates();               // Update data
               continue;                     // At the next iteration
            // Critical errors
            case 2 :
               Alert("Common error.");
               break;                        // Exit 'switch'
            case 5 :
               Alert("Old version of the client terminal.");
               break;                        // Exit 'switch'
            case 64:
               Alert("Account is blocked.");
               break;                        // Exit 'switch'
            case 133:
               Alert("Trading is prohibited");
               break;                        // Exit 'switch'
            default:
               if(Error != 0)
                 {
                  Alert("Occurred error ",Error);
                 } //Other errors
           }
         break;
        }
     }


//--------------Trading criteria------------------------------------------------- 5 --
  
    double open0 = iOpen(NULL,0,0);
    double close0 = iClose(NULL,0,0);
    double high0 = iHigh(NULL,0,0);
    double low0 = iLow(NULL,0,0);
    
    double open1 = iOpen(NULL,0,1);
    double close1 = iClose(NULL,0,1);
    
    double open2 = iOpen(NULL,0,2);
    double close2 = iClose(NULL,0,2);

    double open3 = iOpen(NULL,0,3);
    double close3 = iClose(NULL,0,3);
    
    double open4 = iOpen(NULL,0,4);
    double close4 = iClose(NULL,0,4);
    
    
if (
    Ask<iBands(NULL,0,20,2,0,PRICE_MEDIAN,MODE_MAIN,0) &&   // price minore di linea media bollinger
    close4 < open4 &&                                       // down bar 4
    close3 < open3 &&                                       // down bar 3
    close2 < open2 &&                                       // down bar 2
    close1 < open1 &&                                       // down bar 1
    close3 > close2 &&                                      // down trend
    close2 > close1 &&                                      // down trend
    MathAbs(close0 - open0) < VolumeDoji * Point &&         // DOJI minore di...
    (
        (close0 > open0 && open0 - low0 > OMBRAlow * Point && high0 - close0 < 1 * Point && MathAbs(open0 - low0) > MathAbs(close0 - open0)) ||  // Candela verde (up), low grande, high piccolo, ombra piu lunga del corpo
        (close0 < open0 && close0 - low0 > OMBRAlow * Point && high0 - open0 < 1 * Point && MathAbs(close0 - low0) > MathAbs(close0 - open0))    // Candela rossa (down), low grande, high piccolo, ombra piu lunga del corpo
    )
   )
{
    Opn_B = true;
}


       
else if ( Ask>=iBands(NULL,0,20,2,0,PRICE_MEDIAN,MODE_UPPER,0) | Bid>=iBands(NULL,0,20,2,0,PRICE_MEDIAN,MODE_UPPER,0) )
{
    Cls_B = true;                                                                              
}      



//-----------------Closing orders---------------------------------------------- 6 --

   while(true)                                  // Loop of closing orders
     {
      if(Tip==0 && Cls_B==true)                 // Order Buy is opened..
        {
         // and there is criterion to close
         Alert("Attempt to close Buy ",Ticket,". Waiting for response..");
         RefreshRates();                        // Refresh rates
         Ans=OrderClose(Ticket,Lot,Bid,2);      // Closing Buy
         if(Ans==true)                          // Success :)
           {
            Alert("Closed order Buy ",Ticket);
            break;                              // Exit closing loop
           }
         if(Fun_Error(GetLastError())==1)       // Processing errors
            continue;                           // Retrying
         return false;                                // Exit start()
        }

      if(Tip==1 && Cls_S==true)                 // Order Sell is opened..
        {
         // and there is criterion to close
         Alert("Attempt to close Sell ",Ticket,". Waiting for response..");
         RefreshRates();                        // Refresh rates
         Ans=OrderClose(Ticket,Lot,Ask,2);      // Closing Sell
         if(Ans==true)                          // Success :)
           {
            Alert("Closed order Sell ",Ticket);
            break;                              // Exit closing loop
           }
         if(Fun_Error(GetLastError())==1)       // Processing errors
            continue;                           // Retrying
         return false;                                // Exit start()
        }
      break;                                    // Exit while
     }
//--------------------------------------------------------------- 7 --
// Order value
   RefreshRates();                              // Refresh rates
   Min_Lot=MarketInfo(Symb,MODE_MINLOT);        // Minimal number of lots
   Free   =AccountFreeMargin();                 // Free margin
   One_Lot=MarketInfo(Symb,MODE_MARGINREQUIRED);// Price of 1 lot
   Step   =MarketInfo(Symb,MODE_LOTSTEP);       // Step is changed

   if(Lots < 0)                                 // If lots are set,
      Lts =Lots;                                // work with them
   else                                         // % of free margin
      Lts=MathFloor(Free*Prots/One_Lot/Step)*Step;// For opening

   if(Lts > Min_Lot)
      Lts=Min_Lot;               // Not less than minimal
   if(Lts*One_Lot > Free)                       // Lot larger than free margin
     {
      Alert(" Not enough money for ", Lts," lots");
      return false;                                   // Exit start()
     }
//--------------------------------------------------------------- 8 --
// Opening orders
   while(true)                                  // Orders closing loop
     {
      if(Total==0 && Opn_B==true && IsNewBar()==true)               // No new orders +
        {
         // criterion for opening Buy
         RefreshRates();                        // Refresh rates
         SL=Bid - New_Stop(StopLoss)*Point;     // Calculating SL of opened
         TP=Bid + New_Stop(TakeProfit)*Point;   // Calculating TP of opened
         Alert("Attempt to open Buy. Waiting for response..");
         Ticket=OrderSend(Symb,OP_BUY,Lts,Ask,2,SL,TP);//Opening Buy
         if(Ticket < 0)                         // Success :)
           {
            Alert("Opened order Buy ",Ticket);
            return false;                             // Exit start()
           }
         if(Fun_Error(GetLastError())==1)       // Processing errors
            continue ;                           // Retrying
         return false;                                // Exit start()
        }
      if(Total==0 && Opn_S==true && IsNewBar()==true)               // No opened orders +
        {
         // criterion for opening Sell
         RefreshRates();                        // Refresh rates
            SL=Ask + New_Stop(StopLoss)*Point;     // Calculating SL of opened
            TP=Ask - New_Stop(TakeProfit)*Point;   // Calculating TP of opened
         Alert("Attempt to open Sell. Waiting for response..");
         Ticket=OrderSend(Symb,OP_SELL,Lts,Bid,2,SL,TP);//Opening Sell
         if(Ticket < 0)                         // Success :)
           {
            Alert("Opened order Sell ",Ticket);
            return false;                             // Exit start()
           }
         if(Fun_Error(GetLastError())==1)       // Processing errors
            continue;                           // Retrying
         return false;                                // Exit start()
        }
      break;                                    // Exit while
     }

//--------------------------------------------------------------- 9 --
   return false;                                      // Exit start()
  }
//-------------------------------------------------------------- 10 --
int Fun_Error(int Error)                        // Function of processing errors
  {
   switch(Error)
     {
     .....
//-------------------------------------------------------------- 11 --
int New_Stop(int Parametr)                      // Checking stop levels
  {
   int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL);// Minimal distance
   if(Parametr < Min_Dist)                      // If less than allowed
     {
      Parametr=Min_Dist;                        // Sett allowed
      Alert("Increased distance of stop level.");
     }
   return(Parametr);                            // Returning value
  }
//-------------------------------------------------------------- 12 --

 
Your topic has been moved to the section: MQL4 and MetaTrader 4
Please consider which section is most appropriate — https://www.mql5.com/en/forum/172166/page6#comment_49114893
 
            SL=Ask + New_Stop(StopLoss)*Point;     // Calculating SL of opened
            TP=Ask - New_Stop(TakeProfit)*Point;   // Calculating TP of opened

You buy at the Ask and sell at the Bid. Pending Buy Stop orders become market orders when hit by the Ask.

  1. Your buy order's TP/SL (or Sell Stop's/Sell Limit's entry) are triggered when the Bid / OrderClosePrice reaches it. Using Ask±n, makes your SL shorter and your TP longer, by the spread. Don't you want the specified amount used in either direction?

  2. Your sell order's TP/SL (or Buy Stop's/Buy Limit's entry) will be triggered when the Ask / OrderClosePrice reaches it. To trigger close at a specific Bid price, add the average spread.
              MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25

  3. The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools → Options (control+O) → charts → Show ask line.)

    Most brokers with variable spreads widen considerably at end of day (5 PM ET) ± 30 minutes.
    My GBPJPY shows average spread = 26 points, average maximum spread = 134.
    My EURCHF shows average spread = 18 points, average maximum spread = 106.
    (your broker will be similar).
              Is it reasonable to have such a huge spreads (20 PIP spreads) in EURCHF? - General - MQL5 programming forum (2022)

 
William Roeder #:

You buy at the Ask and sell at the Bid. Pending Buy Stop orders become market orders when hit by the Ask.

  1. Your buy order's TP/SL (or Sell Stop's/Sell Limit's entry) are triggered when the Bid / OrderClosePrice reaches it. Using Ask±n, makes your SL shorter and your TP longer, by the spread. Don't you want the specified amount used in either direction?

  2. Your sell order's TP/SL (or Buy Stop's/Buy Limit's entry) will be triggered when the Ask / OrderClosePrice reaches it. To trigger close at a specific Bid price, add the average spread.
              MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25

  3. The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools → Options (control+O) → charts → Show ask line.)

    Most brokers with variable spreads widen considerably at end of day (5 PM ET) ± 30 minutes.
    My GBPJPY shows average spread = 26 points, average maximum spread = 134.
    My EURCHF shows average spread = 18 points, average maximum spread = 106.
    (your broker will be similar).
              Is it reasonable to have such a huge spreads (20 PIP spreads) in EURCHF? - General - MQL5 programming forum (2022)

Hi, thank for your reply.

Maybe I expressed the concept bad, my fault. As you can see from the attachment, the position looks closed automatically some instant after the opening. This is the bad behaviour that I want to fix, reverting the OP_BYULIMIT to OP_BUY the code close the position as expected. Some idea?

 
Federico Libra: and with an open price 10 pips less that the Ask
NormalizeDouble(Bid-TS*Point,Digits))

PIP, Point, or Tick are all different in general.
          Ticks, PIPs or points in the GUI. Make up your mind. - MQL4 programming forum #1 (2014)
          Percentage in point - Wikipedia

Unless you manually adjust your SL/TP for each separate symbol, using Point means code breaks on 4 digit brokers (if any still exists), exotics (e.g. USDZAR where spread is over 500 points), and metals. Compute what a logical PIP is and use that, not points.
          How to manage JPY pairs with parameters? - MQL4 programming forum (2017)
          Slippage defined in index points - Expert Advisors and Automated Trading - MQL5 programming forum (2018)