Warrior_EA/Trailing/TrailingATR.mqh

174 lines
7.6 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:35:54 +02:00
//+------------------------------------------------------------------+
//| CTrailingATR.mqh |
//| AnimateDread |
//| https://tawarriors.com|
//+------------------------------------------------------------------+
#property copyright "AnimateDread"
#include <Expert\ExpertTrailing.mqh>
// wizard description start
//+----------------------------------------------------------------------+
//| Description of the class |
//| Title=Trailing Stop based on ATR Indicator |
//| Type=Trailing |
//| Name=ATR |
//| Class=CTrailingATR |
//| Page= |
//| Parameter=Multiplier,double,2, ATR Multiplier |
//| Parameter=Periods,int,14, ATR Periods |
//| Parameter=Shift,int,0, ATR Shift |
//+----------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CTrailingATR. |
//| Purpose: Class of trailing stops based on ATR * Multiplier. |
//| Derives from class CExpertTrailing. |
//+------------------------------------------------------------------+
class CTrailingATR : public CExpertTrailing
{
protected:
CiATR m_ATR; // ATR indicator
//--- input parameters
double m_multiplier; // Configurable multiple for ATR
int m_periods; // Configurable periods for ATR
int m_shift; // Configurable shift for ATR
public:
CTrailingATR(void);
~CTrailingATR(void);
//--- methods of initialization of protected data
void Multiplier(double multiplier) { m_multiplier = multiplier; }
void Periods(int periods) { m_periods = periods; }
void Shift(int shift) { m_shift = shift; }
virtual bool InitIndicators(CIndicators* indicators);
virtual bool ValidationSettings();
virtual bool CheckTrailingStopLong(CPositionInfo* position, double& sl, double& tp);
virtual bool CheckTrailingStopShort(CPositionInfo* position, double& sl, double& tp);
protected:
bool AdjustStopLoss(double& sl, double currentPrice, double atrValue, bool isLong);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
void CTrailingATR::CTrailingATR(void) :
m_multiplier(2),
m_periods(14),
m_shift(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
void CTrailingATR::~CTrailingATR(void)
{
}
//+------------------------------------------------------------------+
//| Validation settings protected data. |
//+------------------------------------------------------------------+
bool CTrailingATR::ValidationSettings()
{
if(!CExpertTrailing::ValidationSettings())
return (false);
// Check multiplier
if(m_multiplier <= 0.0 || m_multiplier > 100)
{
printf(__FUNCTION__ + ": multiplier must be greater than 0 and lesser than 100");
return (false);
}
// Check ATR Periods
if(m_periods <= 0 || m_periods > 200)
{
printf(__FUNCTION__ + ": ATR Periods must be greater than 0 and lesser than 200");
return (false);
}
// Check ATR shift
if(m_shift < 0 || m_shift > 200)
{
printf(__FUNCTION__ + ": ATR shift must be 0-200");
return (false);
}
//--- ok
return (true);
}
//+------------------------------------------------------------------+
//| Checking for input parameters and setting protected data. |
//+------------------------------------------------------------------+
bool CTrailingATR::InitIndicators(CIndicators* indicators)
{
if(indicators == NULL)
return (false);
// Add ATR indicator to the collection
if(!indicators.Add(GetPointer(m_ATR)))
{
printf(__FUNCTION__ + ": error adding object");
return (false);
}
// Initialize ATR indicator
if(!m_ATR.Create(m_symbol.Name(), m_period, m_periods))
{
return (false);
}
//--- ok
return (true);
}
//+------------------------------------------------------------------+
//| Common logic for adjusting SL considering freeze level |
//+------------------------------------------------------------------+
bool CTrailingATR::AdjustStopLoss(double& sl, double currentPrice, double atrValue, bool isLong)
{
double freezeLevel = m_symbol.FreezeLevel() * m_symbol.Point();
int digits = m_symbol.Digits(); // Get the number of digits after the decimal for the instrument
// Calculate new SL based on position type (Long or Short)
double new_sl = isLong ? NormalizeDouble(currentPrice - atrValue * m_multiplier, digits)
: NormalizeDouble(currentPrice + atrValue * m_multiplier, digits);
// Calculate the level beyond which SL cannot be set due to freeze level
double level = isLong ? currentPrice - freezeLevel : currentPrice + freezeLevel;
// Check if new SL is in the correct direction and respects the freeze level
bool isSlValid = isLong ? (new_sl > sl && new_sl < level) : (new_sl < sl && new_sl > level);
if(isSlValid)
{
sl = new_sl;
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| Checking trailing stop and/or profit for long position. |
//+------------------------------------------------------------------+
bool CTrailingATR::CheckTrailingStopLong(CPositionInfo* position, double& sl, double& tp)
{
if(position == NULL)
return false;
double atr = m_ATR.Main(m_shift); // Get the current value of ATR
double new_sl = position.StopLoss();
sl = EMPTY_VALUE;
tp = EMPTY_VALUE;
// Adjust SL considering freeze level and ensure it respects the freeze level
if(AdjustStopLoss(new_sl, m_symbol.Bid(), atr, true))
{
sl = new_sl; // Update the reference only if AdjustStopLoss returns true
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| Checking trailing stop and/or profit for short position. |
//+------------------------------------------------------------------+
bool CTrailingATR::CheckTrailingStopShort(CPositionInfo* position, double& sl, double& tp)
{
if(position == NULL)
return false;
double atr = m_ATR.Main(m_shift); // Get the current value of ATR
double new_sl = position.StopLoss();
sl = EMPTY_VALUE;
tp = EMPTY_VALUE;
// Adjust SL considering freeze level and ensure it respects the freeze level
if(AdjustStopLoss(new_sl, m_symbol.Ask(), atr, false))
{
sl = new_sl; // Update the reference only if AdjustStopLoss returns true
return true;
}
return false;
}
//+------------------------------------------------------------------+