What is wrong with this logic? Trailingstop for half position

 

Hello everyone, what is wrong with this logic? I want to open 2 positions. One will be closed with a target profit, the other one with trailingstop. If i knew how to close just half position and go ahead with trailingstop for the other half i would have done:)

//--- Controllo numero ordini e send buystop
double Spread=Bid-Ask;
int ordtot=OrdersTotal(), ticket, ticketTL;   
 
 if (setupBAR==true && NoTradeFlag==false)
     {
        if (OrdersTotal()<NPosMax)
           {
               //---posizione da chiudersi con target atr  
               ticket=OrderSend(Symbol(),OP_BUY,Lotti/2,prezzo,3,Low[1]-buffer,prezzo+Atr,"Momentum Method",MagicNumber,0);
               //---posizione da chiudersi con trailingstop         
               ticketTL=OrderSend(Symbol(),OP_BUY,Lotti/2,prezzo,3,Low[1]-buffer,0,"Momentum Method",MagicNumber,0);   
           }
     }
   

   
//---Muove stoploss in Be appena è in profitto
if (ordtot>=1){
   if (prezzo>(OrderOpenPrice()+Spread)) 
             {
             OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
             OrderModify(ticket,OrderOpenPrice()+Spread,OrderTakeProfit(),0,Green);
             Print("Order stoploss moved to BE");
             OrderSelect(ticketTL,SELECT_BY_TICKET,MODE_TRADES);
             OrderModify(ticketTL,OrderOpenPrice()+Spread,prezzo+TrailingStop*Punto,0,Green);
             }
             }

prezzo is just bid in case of buy and ask in case of sell. Spread we all know what is it and Punto is to adjust the ea for the number of digits.

Thank you

 
lemming78:
Hello everyone, what is wrong with this logic? I want to open 2 positions. One will be closed with a target profit, the other one with trailingstop. If i knew how to close just half position and go ahead with trailingstop for the other half i would have done:)

You could open 2 positions and manage both differently. I'd set one with a TP and the one with TP=0 use the trailing stop.

Closing half position is not hard. You just have to make sure that the lot size is a multiple of lotstep and at least minlot. See my code. The hard part is making sure you don't partial close again. I use SL < order open price, full amount. Then when it's time to partial close, move SL to OrderOpenPrice and then partial close. Also remember, the ticket number changes on a partial close, you'll have to do a orderSelect loop to get the new one.

//+------------------------------------------------------------------+
//| Partial order close.                                             |
//+------------------------------------------------------------------+
bool    CloseOrder(int ticket=EMPTY, double size=INF){  // INF == entire.
    if      (ticket == EMPTY)   ticket = OrderTicket();
    else if (!OrderSelect(ticket, SELECT_BY_TICKET)){
        Alert("OrderSelect(",ticket,",ticket) failed: ", GetLastError());
                                                                return(false); }
    double  minLot      = MarketInfo(chart.symbol, MODE_MINLOT),
            lotStep     = MarketInfo(chart.symbol, MODE_LOTSTEP),
            sizeCurr    = OrderLots(),
            sizeClose   = MathRound(size/lotStep)*lotStep,
            sizeRem     = sizeCurr - sizeClose;

    if (sizeClose < minLot)                                     return(false);
    if (sizeRem   < minLot){    sizeClose = sizeCurr;   // Close all
        color   op.color    = IfI(Color.Buy, Color.Sell);   }
    else        op.color    = Aqua;

    if (GetTradeContext() < TC_LOCKED)                          return(false);
    if (OrderClose( ticket, sizeClose, OrderClosePrice(),
                    Slippage.Pips*pips2points, op.color )){
        RelTradeContext();                                      return(true);  }
    Alert("OrderClose(ticket=", ticket, ", ...) [1] failed: ", GetLastError());
    RelTradeContext();      // After GetLastError
                                                                return(false);
}
 

Thank you. By the way i'm a noob so i decided to look for a simple way. I modified the code but i don't understand why i see always the error driven by the else at the bottom..

//+------------------------------------------------------------------+
//|                                                  Momentum_v1.mq4 |
//|                                                             Skox |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Skox"
#property link      ""
#property indicator_separate_window

double Punto;
extern bool DisplayInfo=true;
extern string    S1 ="Lotti da aprire, minimo 0.02 ";
extern double Lotti=0.02;
extern string    S2 ="Numero posizioni massime. Minimo 2";
extern int NPosMax=2;
extern   double   StopLoss           = 20;
extern   double   TrailingStep             = 5;

int TF,i;
string cmt;
int New_Bar;
bool NoTradeFlag;
datetime Time_0;


extern int MagicNumber=987569;
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
Time_0=Time[0];

// Compatibility wiht 3,4,5 digits prices
   
   if(Digits>=4) Punto = 0.0001;
   else Punto = 0.01;

//----Gestione TimeFrame, =1 fino a 4h, =2 oltre
if (Period()<=240) TF=1;
else TF=2;
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
 //---Stampa informazioni su CHART
   void PrintInfo;
   {
   bool setupBAR;
   string cmt="";
      cmt = "========================";
      cmt =  cmt + "\nAccount Name: [ " + AccountName() + " ]";            
      cmt =  cmt + "\nAccount Leverage: [ " + DoubleToStr( AccountLeverage(), 0 ) + " ]";      
      cmt =  cmt + "\nMin Lot: [ " + DoubleToStr( MarketInfo(Symbol(),MODE_MINLOT), 3 ) + " ]";      
      cmt =  cmt + "\nLot Step: [ " + DoubleToStr( MarketInfo(Symbol(),MODE_LOTSTEP), 3 ) + " ]";      
      cmt =  cmt + "\nCurrent Profit: [ " + DoubleToStr(AccountEquity()-AccountBalance(),2) + " ]";
      cmt =  cmt + "\nAccount Balance: [ " + DoubleToStr(AccountBalance(),2) + " ]";
      cmt =  cmt + "\nAccount Equity: [ " + DoubleToStr(AccountEquity(),2) + " ]";      
      cmt =  cmt + "\nSetup Bar exist?:  " + setupBAR + " ";
      cmt =  cmt + "\n========================";
      Comment(cmt);
      }

//---Indicatori      
   double Atr=iATR(NULL,0,20,0);
   double fastMA=iMA(NULL,0,20,0,MODE_SMA,PRICE_CLOSE,0);
   double slowMA=iMA(NULL,0,40,0,MODE_SMA,PRICE_CLOSE,0);
   double Adx=iADX(NULL,0,14,PRICE_CLOSE,MODE_MAIN,0);

//---Funzione Buffer
  double buffer;
  if (TF==1) buffer=2*Punto;
  else buffer=0.001*Close[0];
  
//---Controlla se è nata una nuova candela
  New_Bar=0;                                           
    if (Time_0 != Time[0])                                  
      {
      New_Bar = 1; 
      NoTradeFlag=false;                                             
      Time_0 = Time[0]; 
      }
   
   
//--- Se setup bar esiste setupBAR=true, altrimenti false  

   if (Low[1]>fastMA && Low[1]>slowMA && Close[1]>Open[1] && Close[1]>(High[1]-Low[1])*0.7 && High[1]<High[iHighest(Symbol(),0,MODE_HIGH,5,1)] && (Close[1]-Open[1])<1.5*Atr && Adx>25) 
     {setupBAR = true;}
   else{setupBAR = false;}

//--- Se il targetprofit non viene raggiunto entro 5 candele, la posizione si chiude al close della 5°  
   double prezzo;
   datetime open= OrderOpenTime();
   
   if(OrderType()==OP_BUY) prezzo=Ask;
   else prezzo=Bid;
   
//---Gestione stoploss. Prima di piazzarlo in reale ricordarsi di cambiare 10 pips con MarketInfo(Symbol(),MODE_STOPLEVEL)
/*   double StopLoss;
   if(Close[1]-(Low[1]-buffer)<10*Punto)
   {StopLoss=Low[1]-10*Punto;}
   else StopLoss=(Low[1]-buffer);*/


//--- Controllo numero ordini
   double Spread=Bid-Ask;
   int ordtot=OrdersTotal();
   int ticket, ticketTL;
//---Gestione TrailingStop. La variabile TrailingStop è external. Trailing è il nuovo livello di stoploss per ordini con trailingstop 
   //double TSTP=TrailingStop*Punto;
   //double Trailing;
   /*if (OrderType() == OP_BUY)
       {
         if ((Bid - OrderOpenPrice()) > TSTP)
         {
            if (OrderStopLoss() < (Bid - TSTP))
            {
              Trailing=Bid-TSTP;
            }
            }
        
         
       }
      else if (OrderType() == OP_SELL)
       {
         if ((OrderOpenPrice() - Ask) > TSTP)
           {
              if ((OrderStopLoss() > (Ask + TSTP)) || (OrderStopLoss() == 0))
                {
                  Trailing=Ask+TSTP;
                }
           }
       }*/
       
 
 
//---Gestione ordini e modifica di trailingstop e targetprofit 
   if(ordtot<NPosMax)
   {
    if (setupBAR==true && NoTradeFlag==false)
     {
       /*ticket=OrderSend(Symbol(),OP_BUY,Lotti/2,prezzo,3,StopLoss,prezzo+Atr,"Momentum Method",MagicNumber,0);
          OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
            if (ordtot>=1)
               {
                  if(OrderTicket()==ticket)
                    { 
                      if (prezzo>(OrderOpenPrice()+Spread+10*Punto)) 
                        {
                           OrderModify(ticket,OrderOpenPrice(),OrderOpenPrice()+Spread,OrderTakeProfit(),0,Green);
                        }
                    }    
               }*/
       ticketTL=OrderSend(Symbol(),OP_BUY,Lotti/2,prezzo,3,prezzo-StopLoss*Punto,0,"Momentum Method",MagicNumber,0);
         
            
    }
  }
  
  
  if ( OrderSelect(ticketTL,SELECT_BY_TICKET,MODE_TRADES)==true)
                {
                  
                        
                           if(Bid - OrderOpenPrice() > StopLoss * Punto /*&&
                              OrderStopLoss() < Bid - StopLoss * Punto*/ )
                              {
                               OrderModify(OrderTicket(),OrderOpenPrice(),Bid-StopLoss*Punto,OrderTakeProfit(),0,Green);
                               GetLastError();
                               Print ("Trailing stop modified at " +DoubleToStr(OrderStopLoss(),4));
                               }
                            

                        
 
               } 
 else{
 GetLastError();
 Print("Errore selezionamento " +GetLastError());
 }
 
 }
 
lemming78:

Thank you. By the way i'm a noob so i decided to look for a simple way. I modified the code but i don't understand why i see always the error driven by the else at the bottom..

If this is false, (setupBAR==true && NoTradeFlag==false), what is the value of ticketTL ?
 
RaptorUK:
If this is false, (setupBAR==true && NoTradeFlag==false), what is the value of ticketTL ?


It is not the value of ticketTL=ordersend()? I mean, my objective is to verify that this condition is verified

 if (setupBAR==true && NoTradeFlag==false)

If it is, the ea sends an order, that will have a ticketTL ticket

Then want to select this precise order and modify it.

If the the condition you quoted is false, it should not send any order. Thank you for your answers

 
lemming78:


If the the condition you quoted is false, it should not send any order. Thank you for your answers

And if the condition is false what code is executed next ?
 
RaptorUK:
And if the condition is false what code is executed next ?

No code should be executed, because it shouldn't open positions. Hope i selfexplained well.
 
lemming78:

Hello everyone, what is wrong with this logic? I want to open 2 positions. One will be closed with a target profit, the other one with trailingstop. If i knew how to close just half position and go ahead with trailingstop for the other half i would have done:)

prezzo is just bid in case of buy and ask in case of sell. Spread we all know what is it and Punto is to adjust the ea for the number of digits.

Thank you


I should start with Lot1 and Lot2

Lots will become Lot1+lot2

So opening trade with Lots

Stoploss what you wanted in first place TakeProfit you choose by opening 2* takeprofit you wanna close first part

At (Orderopenprice+OrderTakeprofit)/2 you close first part (Lots1) and second part you can go on modifying trailingstop and maybe takeprofit

Read the post of WHRoeder carefully he has the same solution .....

 
lemming78:

No code should be executed, because it shouldn't open positions. Hope i selfexplained well.

That is incorrect . . . . please see you code below . . . read the comments I have added.

//---Gestione ordini e modifica di trailingstop e targetprofit 
   if(ordtot<NPosMax)
      {
      if (setupBAR==true && NoTradeFlag==false)  //<--  if true
         {
         ticketTL=OrderSend(Symbol(),OP_BUY,Lotti/2,prezzo,3,prezzo-StopLoss*Punto,0,"Momentum Method",MagicNumber,0);  //<---  this is executed
         }
      }
                                                 //  if false what is the value of ticketTL  ? ?  because
  
   if ( OrderSelect(ticketTL,SELECT_BY_TICKET,MODE_TRADES)==true)  //<----  this gets executed next with what ticket number ? ?
      {
      if(Bid - OrderOpenPrice() > StopLoss * Punto  )
         {
         OrderModify(OrderTicket(),OrderOpenPrice(),Bid-StopLoss*Punto,OrderTakeProfit(),0,Green);
         GetLastError();                                                                              //<----  what is the point of this ? ?
         Print ("Trailing stop modified at " +DoubleToStr(OrderStopLoss(),4));
         }
      } 
 
      else
         {
         GetLastError();                                       //<----  what is the point of this ? ?
         Print("Errore selezionamento " +GetLastError());              //<----  what is the point of this ? ? you cleared the error on the previous line
         }
 
      }
 
RaptorUK:

That is incorrect . . . . please see you code below . . . read the comments I have added.


I'm sorry i don't understand....

//---Gestione ordini e modifica di trailingstop e targetprofit 
   if(ordtot<NPosMax)
      {
      if (setupBAR==true && NoTradeFlag==false)  //<--  if true
         {
         ticketTL=OrderSend(Symbol(),OP_BUY,Lotti/2,prezzo,3,prezzo-StopLoss*Punto,0,"Momentum Method",MagicNumber,0);  //<---  this is executed   (ok)
         }
      }
                                                 //  if false what is the value of ticketTL  ? ?  because   ( if false there's no ordersend, so there no order with ticket ticketTL right?)
  
   if ( OrderSelect(ticketTL,SELECT_BY_TICKET,MODE_TRADES)==true)  //<----  this gets executed next with what ticket number ? ? ( with ticketTL, as indicated in orderselect)
      {
      if(Bid - OrderOpenPrice() > StopLoss * Punto  )
         {
         OrderModify(OrderTicket(),OrderOpenPrice(),Bid-StopLoss*Punto,OrderTakeProfit(),0,Green);
         GetLastError();                                                                              //<----  what is the point of this ? ?
         Print ("Trailing stop modified at " +DoubleToStr(OrderStopLoss(),4));
         }
      } 
 
      else
         {
         GetLastError();                                       //<----  what is the point of this ? ?
         Print("Errore selezionamento " +GetLastError());              //<----  what is the point of this ? ? you cleared the error on the previous line
         }
 
      }
Edit: tried to assign a ticket also to orderselect, but now it gives to me error 4105..
//---Gestione ordini e modifica di trailingstop e targetprofit 
   if(ordtot<NPosMax)
     {
       if (setupBAR==true && NoTradeFlag==false)
         {
           /*ticket=OrderSend(Symbol(),OP_BUY,Lotti/2,prezzo,3,StopLoss,prezzo+Atr,"Momentum Method",MagicNumber,0);
             OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
                if (ordtot>=1)
                  {
                    if(OrderTicket()==ticket)
                      { 
                        if (prezzo>(OrderOpenPrice()+Spread+10*Punto)) 
                          {
                           OrderModify(ticket,OrderOpenPrice(),OrderOpenPrice()+Spread,OrderTakeProfit(),0,Green);
                          }
                      }    
                  }*/
            ticketTL=OrderSend(Symbol(),OP_BUY,Lotti/2,prezzo,3,prezzo-StopLoss*Punto,0,"Momentum Method",MagicNumber,0);
         }
      
  
    }
  
  
   
    
     result=OrderSelect(ticketTL,SELECT_BY_TICKET,MODE_TRADES);
     if (result==true)
    {
       {
         if(Bid - OrderOpenPrice() > StopLoss * Punto /*&&
                              OrderStopLoss() < Bid - StopLoss * Punto*/ )
                              {
                               OrderModify(ticketTL,OrderOpenPrice(),Bid-StopLoss*Punto,OrderTakeProfit(),0,Green);
                               Print ("Trailing stop modified at " +DoubleToStr(OrderStopLoss(),4));
                               }
       }                        
    }
     else Print("Errore"+GetLastError());                            


	          
 
lemming78:


I'm sorry i don't understand....

You will continue to not understand if you don't read the Documentation for the Functions you are trying to use and understand how to use them correctly.

For example . . . what does this line of code do ?

GetLastError();  

If you can't or won't answer then you will not learn . . .

Reason: