Trailing Stop Help

 

Hi You All

Been working on a code where the Trailing Stop is not working. The code is built so that it will SELL only. The liquidation of positions is by trailing stop, or by a Moving Average cross, which ever occurs first. But the Traing Stop (TrailStop) is not recognized. Code is attached, but please use as test material. The code has not been profitable. More as a study project. Anyone out there that can have a look and give advise or critic? Problem is located in//------------- New TrailStop Function--------------

Thank you in advance.

Cheers

       double Lots               = 0.1;
       double stopLoss;      
extern double MaximumRisk        = 0.1;
extern double DecreaseFactor     = 1;
extern double MovingPeriodPri    = 20;
extern double MovingPeriodSec    = 10;
       double MovingShift        = 1;
       int    MAGICMA            = 20110818;
extern double TrailStop       = 0.0;

   //++++ These are adjusted for 5 digit brokers.
double  pips2points,    // slippage  3 pips        3=points        30=points
                pips2dbl;          // Stoploss 15 pips     0.0015          0.00150
int        Digits.pips; // DoubleToStr(dbl/pips2dbl, Digits.pips)
int      init()
         {
          if (Digits == 3 || Digits == 5)
           {            // Adjust for five (5) digit brokers.
                pips2dbl        = Point*10;     pips2points = 10;       Digits.pips = 1;
        }
       else 
         {
           pips2dbl     = Point;        pips2points =  1;       Digits.pips = 0;
        }
        }//Thank You WHRoder
      
//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
//----
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
//---- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double LotsOptimized()
  {
   double lot=Lots;
   int    orders=HistoryTotal();     // history orders total
   int    losses=0;                  // number of losses orders without a break
//---- select lot size
   lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/250.0,1);
//---- calculate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      for(int i=orders-1;i>=0;i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;
         //----
         if(OrderProfit()>0) break;
         if(OrderProfit()<0) losses++;
        }
      if(losses>0) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//---- return lot size
   if(lot<0.1) lot=0.1;
   return(lot);
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {
   double maPri;
   double maSec;
   int    res;
//---- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//---- get Moving Average 
   maPri=iMA(NULL,0,MovingPeriodPri,MovingShift,MODE_SMA,PRICE_CLOSE,0);
   maSec=iMA(NULL,0,MovingPeriodSec,MovingShift,MODE_SMA,PRICE_CLOSE,0);
//---- sell conditions
   if(maPri>maSec)  
     {
      res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
      return;
     }
//----
  }
//+------------------------------------------------------------------+
//| Check for close order conditions                                 |
//+------------------------------------------------------------------+
void CheckForClose()
  {
   double maPri;
   double maSec;
//---- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//---- get Moving Average 
   maPri=iMA(NULL,0,MovingPeriodPri,MovingShift,MODE_SMA,PRICE_CLOSE,0);
   maSec=iMA(NULL,0,MovingPeriodSec,MovingShift,MODE_SMA,PRICE_CLOSE,0);
//----
int pos;
for(pos = OrdersTotal()-1; pos >= 0 ; pos--) 
if ( OrderSelect(pos, SELECT_BY_POS)                 // Only my orders w/
    &&  OrderMagicNumber()  == MAGICMA             // my magic number
    &&  OrderSymbol()       == Symbol())                 // and my pair.
    {

//--------------------------------------------------------------------------------

      if(OrderType()==OP_SELL)
        {
       // double dAsk = MarketInfo(Symbol(), MODE_ASK);
       // double dHighest = MarketInfo(Symbol(),MODE_ASK); 
        if (maPri<maSec)
         OrderClose(OrderTicket(),OrderLots(),Ask,3,Blue);
         return;
         }
      }
  }
//-------------------------------------

/*       A pending order price can be no closer to the current price, than this
         amount.        On IBFX it's equal to 30 (3.0 pips.) A TP or SL, can be no
         closer to the order price (open, limit, or stop) or closing price (filled
         order) than this amount.
        
        double minGap.stops;
        double order.SL;
        minGap.stops    = MarketInfo( Symbol(), MODE_STOPLEVEL )*Point;
        order.SL        = MathMin( Bid  - TrailStop * pips2dbl, Bid - minGap.stops);
   double newStopLoss;
*/
//+---------------NEW TRAILSTOP FUNCTION---------------

int TrailingStop()

{
  if(TrailStop>0)
   {
    int total=OrdersTotal();
    for (int i=0; i<total; i++)
     {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderSymbol()==Symbol()&&OrderMagicNumber()==MAGICMA)
       {
  /*      if(OrderType()==OP_BUY)
         {
          if(Bid-OrderOpenPrice()>Point*TrailStop)
           {
            if(OrderStopLoss()<Bid-Point*TrailStop)
             {
              OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailStop,
              OrderTakeProfit(),0,Lime);
             } 
           }
         }
        else */
        if (OrderType()==OP_SELL)
         {
          if(OrderOpenPrice()-Ask>Point*TrailStop)
           {
            if((OrderStopLoss()>(Ask+Point*TrailStop))||(OrderStopLoss()==0))
             {
              OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailStop,
              OrderTakeProfit(),0,Red); return;
             }
           }
         }
       }
     }
   }
}                  
//+------------------------------------------------------------------+
//| Start function                                                   |
//+------------------------------------------------------------------+
void start()
  {
//---- check for history and trading and TrailingStop
   if(Bars<100 || IsTradeAllowed()==false) // || TrailingStop()==0)
   return;
//---- calculate open orders by current symbol
   
   if(CalculateCurrentOrders(Symbol())==0)
    CheckForOpen();
   else                                   
    CheckForClose();
    
  if (TrailingStop()>0)
  
   //{ TrailStop };
  return (TrailStop);                               
//----
   //}
}
 
Huckleberry:
can have a look and give advise or critic?
  1.       if(losses>0) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
         }
    //---- return lot size
       if(lot<0.1) lot=0.1;
    This assumes lot step = 0.1 and also minlot = 0.1. IBFX for example as lot step=0.01. Do it right, don't hard code numbers.
        double  minLot      = MarketInfo(Symbol(), MODE_MINLOT),
                lotStep     = MarketInfo(Symbol(), MODE_LOTSTEP),
          if(losses>0) lot=lot-lot*losses/DecreaseFactor;
       lot=MathRound(lot/lotStep)*lotStep;
       if(lot<minLot) lot=minLot;

  2. //---- go trading only for first tiks of new bar
       if(Volume[0]>1) return;
    Volume is unreliable, you can miss ticks. Bars is unreliable, won't change once you get to max bars on chart. Always use time.
    static datetime Time0;
    if (Time0 == Time[0]) return; Time0 = Time[0];

  3.  res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
    OrderClose(OrderTicket(),OrderLots(),Ask,3,Blue);
    EA's must adjust for 4/5 digit brokers, including SLIPPAGE.
         if (Digits % 2 == 1){      // DE30=1/JPY=3/EURUSD=5 forum.mql4.com/43064#515262
                    pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
        } else {    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; }
        // OrderSend(... Slippage.Pips * pips2points, Bid - StopLossPips * pips2dbl
    
    On closing you can use OrderClosePrice() for a buy and sell and drop the IF.
  4. minGap.stops    = MarketInfo( Symbol(), MODE_STOPLEVEL )*Point;
    order.SL        = MathMin( Bid  - TrailStop * pips2dbl, Bid - minGap.stops);
    For a Sell order, stops are relative to the ASK and SL is ABOVE the price.
  5.     for (int i=0; i<total; i++)
         {
          OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
          if(OrderSymbol()==Symbol()&&OrderMagicNumber()==MAGICMA)
    Count down always, especially if the EA could open more than one. Always test return codes.
        for(pos = OrdersTotal()-1; pos >= 0 ; pos--) if (
            OrderSelect(pos, SELECT_BY_POS)                 // Only my orders w/
        &&  OrderMagicNumber()  == MAGICMA                  // my magic number
        &&  OrderSymbol()       == Symbol()                 // and my pair.
        ){
    

  6.   if (TrailingStop()>0)
      
       //{ TrailStop };
      return (TrailStop);        
    Don't comment out the body of an IF, now the IF connects to the return. Whereas before it was always executed. Comment out both together.
 

Thanks again WHRoeder. I'll put the info into the code and get back later. Your advise and critic is always appreciated.

Cheers

 

Wow. You added on more info. It will take alittle time to digest. But I am sure that I will have a few questions so that I can understand exactly everything you gave. I do see a few recognizable lines you gave that is in many of your past comments to others.

Thank you. Will be back.

 

OK . Thank you very much, WHRoeder. I believe I have inserted all the instructions. Actually, I did many adjustments so as to learn just what you meant.

This is now how I see the situation. After a backtest, the 'results', S/L shows values as small winners. win % is 98.1. But Dollar loss is 4,990.00. Two trades produced the losses. This is the original problem. I have attached the code with all the deletetions and the new lines with '//---------correction ' x' WHRoeder.

Have you any other ideas, I am open to advise and critic.

Thak you again for your time.

double LotsOptimized()
  {
   double lot=Lots;
   int    orders=HistoryTotal();     // history orders total
   int    losses=0;                  // number of losses orders without a break
//---- select lot size
   lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/250.0,1);
//---- calcuulate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      for(int i=orders-1;i>=0;i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;
         //----
         if(OrderProfit()>0) break;
         if(OrderProfit()<0) losses++;
        }
        double minLot     =MarketInfo(Symbol(),MODE_MINLOT),//--------------------correction 1 WHRoeder
               lotStep    =MarketInfo(Symbol(),MODE_LOTSTEP);//-------------------correction 1 WHRoeder
      if(losses>0) lot=lot-lot*losses/DecreaseFactor;       //--------------------correction 1 WHRoeder
      
      lot=MathRound(lot/lotStep)*lotStep;  //-------------------------------------correction 1 WHRoeder
      if (lot<minLot)//-----------------------------------------------------------correction 1 WHRoeder
      lot=minLot;//---------------------------------------------------------------correction 1 WHRoeder
     }
//---- return lot size
   return(lot);//                      
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {
   double maPri;
   double maSec;
   int    res;
//---- go trading only for first tiks of new bar
  // if(Volume[0]>1) return;
  static datetime Time0;//----------------------------------------correction 2 WHRoeder
  if (Time0 == Time[0]) return; Time0 = Time[0];//----------------correction 2 WHRoeder
//---- get Moving Average 
   maPri=iMA(NULL,0,MovingPeriodPri,MovingShift,MODE_SMA,PRICE_CLOSE,0);
   maSec=iMA(NULL,0,MovingPeriodSec,MovingShift,MODE_SMA,PRICE_CLOSE,0);
  
//----

//-----------Adjusts for 4/5 digit Brokers-------------------------------------

if (Digits % 2 == 1){      // DE30=1/JPY=3/EURUSD=5 forum.mql4.com/43064#515262//--------correction 3 WHRoeder
double  pips2points,    // slippage  3 pips        3=points        30=points//------------------correction 3 WHRoeder
                pips2dbl;          // Stoploss 15 pips     0.0015          0.00150//--------------------correction 3 WHRoeder
int        Digits.pips; // DoubleToStr(dbl/pips2dbl, Digits.pips)//----------------------correction 3 WHRoeder
                pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;//-----------correction 3 WHRoeder
    } else {    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; }//---------correction 3 WHRoeder

   
//---- sell conditions
   if(maPri>maSec)  
     {
    //  res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,(Bid+(TrailStop*Point)),0,"",MAGICMA,0,Red);//---SOMETHING IN HERE???
                                                           //--I'M sure this is not right because this gives zero P/L
   // res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,(TrailStop*Point),0,"",MAGICMA,0,Red); //--This gives P/L, No TrailStop
     res= OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);    //--  This gives P/L, No TrailStop, Except
                                                                                // when optomized. S/L shows in the result as a 
                                                                                //many small winners. Win 98.1%, but a 4,990.00
                                                                                //loss                                                
      return;
     }
//----
  }
//+------------------------------------------------------------------+
//| Check for close order conditions                                 |
//+------------------------------------------------------------------+
void CheckForClose()
  {
   double maPri;
   double maSec;
//---- go trading only for first tiks of new bar
    // if(Volume[0]>1) return;
  static datetime Time0;  //--------------------------------------------------correction 2 WHRoeder
  if (Time0 ==Time[0]) return; Time0 = Time[0];  //---------------------------correction 2 WHRoeder
//---- get Moving Average 
   maPri=iMA(NULL,0,MovingPeriodPri,MovingShift,MODE_SMA,PRICE_CLOSE,0);
   maSec=iMA(NULL,0,MovingPeriodSec,MovingShift,MODE_SMA,PRICE_CLOSE,0);
//----
int pos;
for(pos = OrdersTotal()-1; pos >= 0 ; pos--) 
if ( OrderSelect(pos, SELECT_BY_POS)                 // Only my orders w/
    &&  OrderMagicNumber()  == MAGICMA             // my magic number
    &&  OrderSymbol()       == Symbol())                 // and my pair.
    {

//--------------------------------------------------------------------------------

if(OrderType()==OP_SELL)
   {      
//------------------------Adjusts for 4/5 digits Brokers------------------
if (Digits % 2 == 1){      // DE30=1/JPY=3/EURUSD=5 forum.mql4.com/43064#515262//------correction 3 WHRoeder
double  pips2points,    // slippage  3 pips        3=points        30=points
                pips2dbl;          // Stoploss 15 pips     0.0015          0.00150
int        Digits.pips; // DoubleToStr(dbl/pips2dbl, Digits.pips)
                pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
    } else {    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; }        
        if (maPri<maSec)
         OrderClose(OrderTicket(),OrderLots(),Ask,3,Blue);
         return;
         }
      }
  }

//+---------------NEW TRAILSTOP FUNCTION---------------

int TrailingStop()
{
   double pips2dbl;
   double minGap.stops;//--------------------------------------------------correction 4 WHRoeder
        double order.SL;//------------------------------------------------------correction 4 WHRoeder
        minGap.stops    = MarketInfo( Symbol(), MODE_STOPLEVEL )*Point;//--------correction 4 WHRoeder
        order.SL        = MathMin( Bid  - TrailStop * pips2dbl, Bid - minGap.stops);//-correction 4 WHRoeder
   double newStopLoss;//---------------------------------------------------correction 4 WHRoeder
// {
  if(TrailStop>0)
   {
    int pos;
    int total=OrdersTotal();
     for(pos = OrdersTotal()-1; pos >= 0 ; pos--) //-------------------correction 5 WHRoeder
     if ( OrderSelect(pos, SELECT_BY_POS)         // Only my orders w/
     &&  OrderMagicNumber()  == MAGICMA           // my magic number
     &&  OrderSymbol()       == Symbol())         // and my pair.
      {


        if (OrderType()==OP_SELL)
         {
          if(OrderOpenPrice()-Ask>Point*TrailStop)
           {
            if((OrderStopLoss()>(Ask+Point*TrailStop))||(OrderStopLoss()==0))
             {
              OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailStop,
              OrderTakeProfit(),0,Red); return;
             }
           }
         }
       }
     }
   }
//}                  
//+------------------------------------------------------------------+
//| Start function                                                   |
//+------------------------------------------------------------------+
void start()
  {
//---- check for history and trading and TrailingStop
   if(Bars<100 || IsTradeAllowed()==false)
   return;
//---- calculate open orders by current symbol
   
   if(CalculateCurrentOrders(Symbol())==0)
    CheckForOpen();
   else                                   
    CheckForClose();
    
  if (TrailingStop()>0)
  return (TrailStop);       //-------------------------correction 6 WHRoeder                        
//----
}

//+------------------------------------------------------------------+
Reason: