Please Help, Trailing Stop

 

Hi to All

Before I disclose the problem, I wish to thank WHRoeder for the help with this problem earkier in the, but the problem has not been solved. A disclosure: A code I have been working on, does work. It is for experimenting so please, use it as such.

I brought this code to the forum last week, because I found that the code does work, but when I inserted a block for trailing stop purposes, it does not perform properly. The earlier thread was titled, 'Trailg Stop Problem, Help'. With the solutions I recieved, I believe I put them into the code correctly. The code with correction are inserted below. Corrections are noted with '//--------------correction 'x' WHRoeder-----------' so as to help pinpoint

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                        
//----
}

//+------------------------------------------------------------------+

further advise and critic. It may be of help to others as well as me.

Cheers and good tradeing

 

Huckleberry:


[....] it does not perform properly.


what error u get ?
 

Prblem is that the result will display that a when a trade has a SL, it is actually a small profit.??? There are many small profitable trades that are displayed as SL???? When there is a true negative trade, the trade is hugh. I swapped values in the TrailStop from 55.0 to 0.00055 with no change while backtesting. Can you or anyone see where I have failed??

 
ho, it's not real time ? u r talking on BT ?
 

This is Backtesting. Just because I inserted a block for trailing stop, the backtest should still perform properly. The code otherwise has not been changed. The SL in the results shows a profit????? after a backtest. trade that has SL, it should be negative. Not a profit.

 
You have a trailing SL ! ! Do you assume that a trailing SL will always be on the negative side of the entry price ? so that if it is hit it will always produce a loss ?
 
OrderClose(OrderTicket(),OrderLots(),Ask,3,Blue);
if(OrderOpenPrice()-Ask>Point*TrailStop)
           {
            if((OrderStopLoss()>(Ask+Point*TrailStop))||(OrderStopLoss()==0))
             {
              OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailStop,
              OrderTakeProfit(),0,Red); return;
EA's MUST adjust TP, SL, and slippage for 4/5 digit brokers
//++++ These are adjusted for 5 digit brokers.
int     pips2points;    // slippage  3 pips    3=points    30=points
double  pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)
int     init(){
     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
}
 

Hello RaptorUK

Thank you for your time and response. I have worked with trailing stops, but not coded trail stops. Trading manually, I have followed the market while in a trend and produced profits as well as my share of losses with a trailing stop. The trailing stop does need to overcome the initial SL and past the entry price before profit is accomplished. We know this. I am sorry that MY coding is not up to snuff. In this code, when backtesting, the results in the SL column shows the SL at only 1 pip or so away from the entry price. The SL is hit quite often which looks terrific if you want to look at %. When a trade makes a close, not just a SL, the close is hugh. And in turn, eats all the profits the SL produced. Not what I had in mind. The TrailStop I was hoping would be 20 pips or greater from the entry price. Then when the ma would cross, a close would create the profits as well. Hope that helps clear up any misunderstanding. And again thank you for your input. I find it helpful.

 

Hello WHRoeder

Thank you once again. I am in a firewall, whereas I can not get to the MetaTrader platform at this moment. I will study the info you sent later tonight. All you folks, I tip my hat off to. Thank you for all your advise and critic. I can not read all your threads, but you take so much time out for helping others. At sometime, I hope to return the favor. Thanks again WHRoeder

 

Thank You WHRoeder

Finally piecing it together. There are now values in the SL colunm. More realistic trades are being performed. Just thought I would let you know.

Cheers

 

Thank you All especially WHRoeder and RaptorUK

I have tried from your critic and advise to put a readable code together. Here is what I have so far, thanks to you. The conditions for entry is not complete but I am beginning to realize how the blocks can be repeated from one code to another: LotsOptimized, Adjusting for 4/5 brokers, etc. Please have a look and give your advise and critic when you have the time.

      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 DMaddarraStop       = 55;

   //++++ 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);
//---- 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 WHRoeder
               lotStep    =MarketInfo(Symbol(),MODE_LOTSTEP);//-------------------correction WHRoeder
      if(losses>0) lot=lot-lot*losses/DecreaseFactor;       //--------------------correction WHRoeder
      
      lot=MathRound(lot/lotStep)*lotStep;  //-------------------------------------correction WHRoeder
      if (lot<minLot)//-----------------------------------------------------------correction WHRoeder
      lot=minLot;//---------------------------------------------------------------correction 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
  static datetime Time0;//----------------------------------------correction WHRoeder
  if (Time0 == Time[0]) return; Time0 = Time[0];//----------------correction 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);
  
//---- sell conditions
   if( maPri>maSec && Low[1]<Low[2] && Low[2]<Low[3] && Low[3]<Low[4] )
  // if(Low[1]<maSec&&maSec<maPri)  
     {
      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
   
static datetime Time0;  //--------------------------------------------------correction WHRoeder
  if (Time0 ==Time[0]) 
return; 
  Time0 = Time[0];  //---------------------------correction 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)
        { 
        if (maPri<maSec)
         OrderClose(OrderTicket(),OrderLots(),Ask,3,Blue);
         }

//+---------------Maddarra Trailing Stop Function----------
          if(OrderOpenPrice()+Ask>pips2dbl*DMaddarraStop)
           {
            if((OrderStopLoss()>(Ask+pips2dbl*DMaddarraStop))||(OrderStopLoss()==0))
             {
              OrderModify(OrderTicket(),OrderOpenPrice(),Ask+pips2dbl*DMaddarraStop,
              OrderTakeProfit(),0,Red);
              Print( "Maddarra Trailing Stop :", OrderClosePrice());
              return;
             }
           }
         }
       }
                   
//+------------------------------------------------------------------+
//| Start function                                                   |
//+------------------------------------------------------------------+
void start()
  {
//---- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false)
   return;
//---- calculate open orders by current symbol
   
   if(CalculateCurrentOrders(Symbol())==0)
    CheckForOpen();
   else                                   
    CheckForClose();                              
//----
}

//+------------------------------------------------------------------+

Cheers

Reason: