//+------------------------------------------------------------------+ //| StopLossATR.mqh | //| Copyright 2024 - Dev.Solve LTDA | //+------------------------------------------------------------------+ #include "..\ExpertStopLoss.mqh" //+------------------------------------------------------------------+ //| Class CStopLossATR. | //| Purpose: Class of stop loss based on ATR indicator. | //| Derives from class CExpertStopLoss. | //+------------------------------------------------------------------+ class CStopLossATR : public CExpertStopLoss { protected: CiATR *m_ATR; // pointer of ATR indicator //--- input parameters ENUM_TIMEFRAMES m_timeframe_atr_stoploss; // time frame of the atr stop loss int m_period_atr_stoploss; // period of the atr stop loss double m_multiplier_atr_stoploss; // multiplier factor of the atr stop loss bool m_active_ex; public: CStopLossATR(void); ~CStopLossATR(void); //--- methods of initialization of protected data void SetTimeFrame(ENUM_TIMEFRAMES vlr) { m_timeframe_atr_stoploss=vlr; }; void SetPeriod(int vlr) { m_period_atr_stoploss=vlr; }; void SetMultiplier(double vlr) { m_multiplier_atr_stoploss=vlr; }; virtual bool InitIndicators(CIndicators *indicators); virtual bool ValidationSettings(void); //--- virtual bool CheckStopLossLong(CPositionInfo *position,double &sl,double &tp); virtual bool CheckStopLossLong(double &price,double &sl,double &tp); virtual bool CheckStopLossShort(CPositionInfo *position,double &sl,double &tp); virtual bool CheckStopLossShort(double &price,double &sl,double &tp); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ void CStopLossATR::CStopLossATR(void) : m_timeframe_atr_stoploss(WRONG_VALUE), m_period_atr_stoploss(-1), m_multiplier_atr_stoploss(0), m_active_ex(false) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ void CStopLossATR::~CStopLossATR(void) { } //+------------------------------------------------------------------+ //| Validation settings protected data. | //+------------------------------------------------------------------+ bool CStopLossATR::ValidationSettings(void) { if(!CEngineBase::ValidationSettings()) return(false); //--- initial data checks if(m_timeframe_atr_stoploss==WRONG_VALUE) { printf(ERROR_SUFFIX+"erro, o Time Frame escolhido para o stop loss atr é inválido."); return(false); } //--- check case PERIOD_CURRENT in atr time frame if(m_timeframe_atr_stoploss==PERIOD_CURRENT) m_timeframe_atr_stoploss=m_period; //--- if(m_period_atr_stoploss<=0) { printf(ERROR_SUFFIX+"erro, o período escolhido para o stop loss atr é inválido. Escolha um valor maior que 0."); return(false); } if(m_multiplier_atr_stoploss<=0) { printf(ERROR_SUFFIX+"erro, multiplicador escolhido para o stop loss atr é inválido. Escolha um valor maior que 0."); return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| Init Indicators | //+------------------------------------------------------------------+ bool CStopLossATR::InitIndicators(CIndicators *indicators) { //--- check if(indicators==NULL) return(false); //--- create ATR indicator if(m_ATR==NULL) if((m_ATR=new CiATR)==NULL) { printf(ERROR_SUFFIX+"erro ao criar indicador ATR."); return(false); } //--- add ATR indicator to collection if(!indicators.Add(m_ATR)) { printf(ERROR_SUFFIX+"erro ao adicionar objeto ATR à coleção."); delete m_ATR; return(false); } //--- initialize ATR indicator if(!m_ATR.Create(m_other_ticker,m_timeframe_atr_stoploss,m_period_atr_stoploss)) { printf(ERROR_SUFFIX+"erro ao inicializar o indicador ATR."); return(false); } m_ATR.BufferResize(2); //--- ok return(true); } //+------------------------------------------------------------------+ //| Checking stop loss for long position. | //+------------------------------------------------------------------+ bool CStopLossATR::CheckStopLossLong(CPositionInfo *position,double &sl,double &tp) { //--- no activate exhaust if(!m_active_ex) return(false); //--- check if(position==NULL) return(false); //--- double atr =m_ATR.Main(1); //--- MqlRates rates[]; //--- check if is new bar in chart if(IsNewBar()) { ResetLastError(); //--- copy the rates for candles checking if(CopyRates(m_symbol.Name(),m_period,1,1,rates)<1) { printf(ERROR_SUFFIX+"erro, falha na obtenção das cotações das barras solicitadas. Código do erro: %d",GetLastError()); return(false); } //--- checking if the candle closed negative and above last atr if(MathAbs(rates[0].high-rates[0].low)>atr*m_multiplier_atr_stoploss) { sl=-2; tp=-2; //--- free memory ArrayFree(rates); return(true); } //--- free memory ArrayFree(rates); } //--- return(false); } //+------------------------------------------------------------------+ //| Checking stop loss for long pending order | //+------------------------------------------------------------------+ bool CStopLossATR::CheckStopLossLong(double &price,double &sl,double &tp) { //--- double delta; double base=price; double atr=m_ATR.Main(1); //--- if(atr==-1) { sl=-2; tp=-2; return(true); } //--- delta=atr*m_multiplier_atr_stoploss; sl=base-delta; //--- return(true); } //+------------------------------------------------------------------+ //| Checking stop loss for short position. | //+------------------------------------------------------------------+ bool CStopLossATR::CheckStopLossShort(CPositionInfo *position,double &sl,double &tp) { //--- no activate exhaust if(!m_active_ex) return(false); //--- check if(position==NULL) return(false); //--- double atr =m_ATR.Main(1); //--- MqlRates rates[]; //--- check if is new bar in chart if(IsNewBar()) { ResetLastError(); //--- copy the rates for candles checking if(CopyRates(m_symbol.Name(),m_period,1,1,rates)<1) { printf(ERROR_SUFFIX+"erro, falha na obtenção das cotações das barras solicitadas. Código do erro: %d",GetLastError()); return(false); } //--- checking if the candle closed negative and above last atr if(MathAbs(rates[0].high-rates[0].low)>atr*m_multiplier_atr_stoploss) { sl=-2; tp=-2; //--- free memory ArrayFree(rates); return(true); } //--- free memory ArrayFree(rates); } //--- return(false); } //+------------------------------------------------------------------+ //| Checking stop loss for short pending order | //+------------------------------------------------------------------+ bool CStopLossATR::CheckStopLossShort(double &price,double &sl,double &tp) { //--- double delta; double base=price; double atr=m_ATR.Main(1); //--- if(atr==-1) { sl=-2; tp=-2; return(true); } delta=atr*m_multiplier_atr_stoploss; sl=base+delta; //--- return(true); } //+------------------------------------------------------------------+