//+------------------------------------------------------------------+ //| TrailingClassic.mqh | //| Copyright 2016, Vasiliy Sokolov. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, Vasiliy Sokolov." #property link "http://www.mql5.com" #include "Trailing.mqh" //+------------------------------------------------------------------+ //| интегрируем параметры трейлинг-стопа прямо в список параметров | //| эксперта | //+------------------------------------------------------------------+ #ifdef SHOW_TRAILING_CLASSIC_PARAMS input double PointsModify=0.00100; input double StepModify=0.00005; #endif //+------------------------------------------------------------------+ //| Классический трейлинг-стоп | //+------------------------------------------------------------------+ class CTrailingClassic : public CTrailing { private: double m_diff_extremum; // Расстояние в пунктах от достигнутого экстремума до стоп-лосса позиции double m_step_modify; // Минимальное количество пунктов для изменения стоп-лосса double FindExtremum(CPosition *pos); public: CTrailingClassic(void); void SetDiffExtremum(double points); double GetDiffExtremum(void); void SetStepModify(double points_step); double GetStepModify(void); virtual bool Modify(void); virtual CTrailing *Copy(void); }; //+------------------------------------------------------------------+ //| Конструктор. Инициализирует параметры по-умолчанию | //+------------------------------------------------------------------+ CTrailingClassic::CTrailingClassic(void) : m_diff_extremum(0.0), m_step_modify(0.0) { #ifdef SHOW_TRAILING_CLASSIC_PARAMS m_diff_extremum=PointsModify; m_step_modify=StepModify; #endif } //+------------------------------------------------------------------+ //| Возвращает копию экземпляра | //+------------------------------------------------------------------+ CTrailing *CTrailingClassic::Copy(void) { CTrailingClassic *tral=new CTrailingClassic(); tral.SetDiffExtremum(m_diff_extremum); tral.SetStepModify(m_step_modify); tral.SetPosition(m_position); return tral; } //+------------------------------------------------------------------+ //| Устанавливает количество пунктов от достигнутого экстремума | //+------------------------------------------------------------------+ void CTrailingClassic::SetDiffExtremum(double points) { m_diff_extremum=points; } //+------------------------------------------------------------------+ //| Устанавливает величину минимальной модификации в пунктах | //+------------------------------------------------------------------+ void CTrailingClassic::SetStepModify(double points_step) { m_step_modify=points_step; } //+------------------------------------------------------------------+ //| Возвращает количество пунктов от достигнутого экстремума | //+------------------------------------------------------------------+ double CTrailingClassic::GetDiffExtremum(void) { return m_diff_extremum; } //+------------------------------------------------------------------+ //| Возвращает величину минимальной модификации в пунктах | //+------------------------------------------------------------------+ double CTrailingClassic::GetStepModify(void) { return m_step_modify; } //+------------------------------------------------------------------+ //| Модифицирует трейлинг-стоп согласно логике классического | //| трейлинга | //+------------------------------------------------------------------+ bool CTrailingClassic::Modify(void) { if(CheckPointer(m_position)==POINTER_INVALID) { string text="Invalid position for current trailing-stop. Set position with 'SetPosition' method"; CMessage *msg=new CMessage(MESSAGE_WARNING,__FUNCTION__,text); Log.AddMessage(msg); return false; } if(m_diff_extremum<=0.0) { string text="Set points trailing-stop with 'SetDiffExtremum' method"; CMessage *msg=new CMessage(MESSAGE_WARNING,__FUNCTION__,text); Log.AddMessage(msg); return false; } double extremum=FindExtremum(m_position); if(extremum == 0.0)return false; double n_sl = 0.0; if(m_position.Direction()==POSITION_TYPE_BUY) { n_sl=extremum-m_diff_extremum; if(n_sl-m_position.StopLossValue()>m_step_modify) return m_position.StopLossValue(n_sl); } else { n_sl=extremum+m_diff_extremum; if(m_position.StopLossValue()-n_sl>m_step_modify) return m_position.StopLossValue(n_sl); } return false; } //+------------------------------------------------------------------+ //| Возвращает достигнутый экстремум цены за время удеражания | //| позиции. Для длинной позиции будет возвращена максимально | //| достигнутая цена. Для короктой - минимальная цена, которая была | //| достигнута. | //+------------------------------------------------------------------+ double CTrailingClassic::FindExtremum(CPosition *pos) { double prices[]; if(pos.Direction()==POSITION_TYPE_BUY) { if(CopyHigh(pos.Symbol(),PERIOD_M1,pos.TimeOpen(),TimeCurrent(),prices)>1) return prices[ArrayMaximum(prices)]; } else { if(CopyLow(pos.Symbol(),PERIOD_M1,pos.TimeOpen(),TimeCurrent(),prices)>1) return prices[ArrayMinimum(prices)]; } return 0.0; } //+------------------------------------------------------------------+