Can you spot any errors in this TrailingStop function ?

Pilot65
696
Pilot65  

It seems to work ok on test, not getting any errors. But still not 100% sure its ok. Can you check it over ?

//---------- Trailing Stop ---------------------------
void  TrailingStop(double TrailingStop, double TrailingStart, int TrailInterval)//This TrailingStop function must be called every tick!
{
/*By DayTrader (eikarlse@online.no)

Description:
General purpose routine (module) for Trailing Stop functionality. Can be included or dropped into any EA code and handles all TS related tasks.

Usage:
Call with external TS parameters at tick interval like this: "TrailingStop(TrailingStop, TrailingStart, TrailInterval);"
Pipvalues are entered as decimal pips, 4-digit broker style...
<TrailingStop> (distance) can be any value. A value of -1 or lower will deactivate the TS function.
A value lower than the broker's StopLevel will result in the StopLevel being used.
In other words TrailingStop = 0 will result in the tightest possible TS.
<TrailingStart> sets the minimum profit in decimal pips before trailing stop kicks in.
<TrailInterval> sets the minimum time in seconds between each time the order is modified

External parameters:
extern   double   TrailingStop  = 0.0;//Any value. Deactivate TS by using -1
extern   double   TrailingStart = 0.0;//Pips of profit required before TS kicks in
extern   int      TrailInterval = 10;//Minimum number of seconds to pass before a new stop can be sent.

Global variables:
int   TStime, PrevTStime, ReadyFlag;//Used by TrailingStop functions
*/
TrailTimer(TrailInterval);//Always keep the TrailingStop timer running at tick frequency
   if( ! TimeToTrail() || ( TrailingStop <= -1) ) return(0);//TrailingStop deactivated, or not enough time has passed since the previous TS order was sent
   //Clamp to minimum allowed levels:
   double StopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL)/SymbolDigits();   
   if (TrailingStop < StopLevel) TrailingStop = StopLevel;//Closest allowable stop
   TrailingStop = TrailingStop * SymbolDigits();//Bring back to true pips
   
   for(int cnt = OrdersTotal()-1; cnt >= 0 ; cnt-- )// Scan through all orders on the account
      {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);//Select an order from the pool      
      if( ! (OrderMagicNumber() == MagicNumber) && OrderSymbol() == Symbol() ) return(0);//Dont touch any orders that belong to other charts or EAs!
//-------
         if( (OrderType() == OP_BUY) && (OrderProfit() > 0) )//We'll be dealing only with profitable Long orders
            if( Bid - OrderOpenPrice() >= (TrailingStop + (TrailingStart * SymbolDigits()) ) * Point)
               if( OrderStopLoss() < (Bid - TrailingStop * Point) ) 
                  {                  
                  OrderModify(OrderTicket(), OrderOpenPrice(), Bid - TrailingStop * Point, OrderTakeProfit(), OrderExpiration(), White);               
                  return(0);
                  }
//-------
         if( (OrderType() == OP_SELL) && (OrderProfit() > 0) )//We'll be dealing only with profitable Short orders 
            if( OrderOpenPrice() - Ask >= (TrailingStop + (TrailingStart * SymbolDigits()) ) * Point)
               if( OrderStopLoss() > (Ask + TrailingStop * Point) )
                  {            
                  OrderModify(OrderTicket(), OrderOpenPrice(), Ask + TrailingStop * Point, OrderTakeProfit(), OrderExpiration(), White);
                  return(0);                          
                  }
      } 
return(0);     
}
//-------------------- TimeToTrail -------------------
int  TimeToTrail() {
/*
We can not trail stops based only on price as this will often lead to
an excessive amount of orders in a short time, often one order pr tick.
This would not be practically feasable, and the broker would choke on
all thesse order anyhow. So before we can send a new TS order (OrderModify)
we introduce a minimum time in seconds that has to pass since the previous
TS order. 
*/
   if(ReadyFlag == 1) {//If the Timer has timed out and set the ReadyFlag:
      ReadyFlag = 0;//Clear the timeout flag and start a new timing cycle
      return(true);//flag that a new TS order is now allowed
      }
return (false);//Not enough time has passed since the previous TS order was sent
}
//-------------------- TrailTimer --------------------
void  TrailTimer(int SecInterval) {
/*
This timer must be called at tick frequency. It measures if a given number of 
seconds has passed, and if so sets a flag to indicate it.
*/
   TStime = TimeCurrent();//Capture seconds and compare to previous capture
      if( ( (TStime - PrevTStime)) >= SecInterval)//If greater than set interval:
         {         
         ReadyFlag = 1;//Set the timeout flag. Flag is used by TimeToTrail()
         PrevTStime = TStime;//Reset timer
         }
return (false);
}
//-------------------- SymbolDigits ------------------
int  SymbolDigits() {
/*
Disregarding broker digits, we ONLY consider actual Symbol digits
All pip values are entered as decimal pips, 4-digit broker style..
E.g: 20.5 (20.5 pips) This goes for 2,3,5 digit symbols for both
4-digit and 5-digit brokers. The decimal denotes true pip for
5-digit brokers only. For 4-digit brokers the decimal should be
set to "0", in any case only the integer part will be considered.
*/
   int SymbolPointMul=1;
   if(Digits==2) SymbolPointMul=1;
   if(Digits==3) SymbolPointMul=10;
   if(Digits==4) SymbolPointMul=1;
   if(Digits==5) SymbolPointMul=10;
return (SymbolPointMul);
}
//-----------------------------------------------------