//+------------------------------------------------------------------+
//|                                                FixedPipTrail.mqh |
//+------------------------------------------------------------------+
#ifndef FIXEDPIPTRAIL_MQH
#define FIXEDPIPTRAIL_MQH
#include "ITrailMethod.mqh"
//+------------------------------------------------------------------+
//| CFixedPipTrail                                                   |
//+------------------------------------------------------------------+
class CFixedPipTrail : public ITrailMethod
  {
private:
   double            m_pip_distance;      // distance in pips from current price to the proposed SL

public:
                     CFixedPipTrail(void);
                    ~CFixedPipTrail(void);

   //--- configuration
   void              Configure(const double pip_distance);

   //--- trailing logic
   virtual double    ComputeStopLevel(ulong ticket) override;
   virtual string    MethodName(void) override;
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CFixedPipTrail::CFixedPipTrail(void) : m_pip_distance(20.0)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CFixedPipTrail::~CFixedPipTrail(void)
  {
  }
//+------------------------------------------------------------------+
//| Configure                                                        |
//+------------------------------------------------------------------+
void CFixedPipTrail::Configure(const double pip_distance)
  {
   m_pip_distance = (pip_distance > 0.0 ? pip_distance : 20.0);
  }
//+------------------------------------------------------------------+
//| ComputeStopLevel                                                 |
//| Returns bid - pip_distance * point_size for long positions,      |
//| and ask + pip_distance * point_size for short positions.         |
//+------------------------------------------------------------------+
double CFixedPipTrail::ComputeStopLevel(ulong ticket)
  {
   if(!::PositionSelectByTicket(ticket))
      return(0.0);

   string symbol        = ::PositionGetString(POSITION_SYMBOL);
   long   position_type = ::PositionGetInteger(POSITION_TYPE);
   double point_size    = ::SymbolInfoDouble(symbol, SYMBOL_POINT);

//--- determine pip size: on 5-digit brokers one pip = 10 points
   int digits = (int)::SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   double pip_size = (digits == 3 || digits == 5) ? point_size * 10.0 : point_size;

   if(position_type == POSITION_TYPE_BUY)
     {
      double bid = ::SymbolInfoDouble(symbol, SYMBOL_BID);
      return(bid - m_pip_distance * pip_size);
     }
   else
     {
      double ask = ::SymbolInfoDouble(symbol, SYMBOL_ASK);
      return(ask + m_pip_distance * pip_size);
     }
  }
//+------------------------------------------------------------------+
//| MethodName                                                       |
//+------------------------------------------------------------------+
string CFixedPipTrail::MethodName(void)
  {
   return("FixedPip");
  }
#endif // FIXEDPIPTRAIL_MQH
//+------------------------------------------------------------------+