MQLArticles/Utils/FA/DiffCalc.mqh
Nique_372 9efbea764e
2026-02-14 17:50:39 -05:00

274 lines
9.1 KiB
MQL5

//+------------------------------------------------------------------+
//| DiffCalc.mqh |
//| Copyright 2026, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property strict
#ifndef MQLARTICLES_UTILS_FA_DIFFCALC_MQH
#define MQLARTICLES_UTILS_FA_DIFFCALC_MQH
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include "Atr.mqh"
//+------------------------------------------------------------------+
//| Clase CDiff - Defines |
//+------------------------------------------------------------------+
enum ENUM_MODE_DIFF
{
MODE_DIFF_BY_FIXED_POITNS = 0, // By Points
MODE_DIFF_BY_ATR // By Atr
};
//--- Flags
#define MQLARTICLES_DIFFCALC_FLAG_SUPPORT_HISTORIAL (1)
#define MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE (2)
#define MQLARTICLES_DIFFCALC_ALL_FLAG (MQLARTICLES_DIFFCALC_FLAG_SUPPORT_HISTORIAL|MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE)
//+------------------------------------------------------------------+
//| class CDiff |
//+------------------------------------------------------------------+
class CDiff : public CLoggerBase
{
protected:
//---
const ENUM_MODE_DIFF m_type; // Differene type
uint8_t m_flags; // Flags
double m_diff; // Calculated difference value
public:
CDiff(const ENUM_MODE_DIFF type, const uint8_t flags) : m_type(type), m_diff(0.00), m_flags(flags) {}
~CDiff() {}
//--- Method to update on new candle
virtual void OnNewBar() {}
//---
__forceinline ENUM_MODE_DIFF GetTypeDiff() const { return m_type; }
__forceinline double Diff() const { return m_diff; }
//--- Flags
__forceinline bool HasFlags(const int flags) const { return (m_flags & flags) != 0; }
__forceinline bool HasAllFlags(const int flags) const { return (m_flags & flags) == flags; }
__forceinline uint8_t GetFlags() const { return m_flags; }
//--- Modo historial
virtual void SetNewIdx(const int bar_idx) {}
virtual void OnHistorialCopyData(const int start, const int count) {}
};
//+------------------------------------------------------------------+
//| class CDiffPoint |
//+------------------------------------------------------------------+
class CDiffPoint : public CDiff
{
private:
string symbol; // Symbol for point calculation
public:
CDiffPoint(void) : CDiff(MODE_DIFF_BY_FIXED_POITNS, MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE) {}
~CDiffPoint(void) {}
//---
void Set(string symbol_, int min_diff_points_);
//---
inline void DiffPoints(int new_diff_points) { this.m_diff = new_diff_points * SymbolInfoDouble(this.symbol, SYMBOL_POINT); }
inline int DiffPoints() const { return (int)(this.m_diff / SymbolInfoDouble(this.symbol, SYMBOL_POINT)); }
};
//+------------------------------------------------------------------+
//| Configures calculation by points |
//+------------------------------------------------------------------+
void CDiffPoint::Set(string symbol_, int min_diff_points_)
{
//--
this.symbol = symbol_;
//--
static bool c;
if(symbol_ == "" || !SymbolExist(symbol_, c))
{
LogFatalError(StringFormat("Invalid symbol in SetPoint: %s", symbol_), __FUNCTION__);
Remover();
return;
}
//---
this.m_diff = SymbolInfoDouble(this.symbol, SYMBOL_POINT) * min_diff_points_;
}
//+------------------------------------------------------------------+
//| class CDiffAtr |
//+------------------------------------------------------------------+
class CDiffAtr : public CDiff
{
private:
int idx; // Index for ATR
CAtr* atr; // Pointer to ATR object
double mul; // Multiplier for ATR
public:
CDiffAtr(void) : CDiff(MODE_DIFF_BY_ATR, MQLARTICLES_DIFFCALC_ALL_FLAG),
idx(0), atr(NULL), mul(0.00) {}
~CDiffAtr(void) {}
//--- General setterr
void Set(CAtr * atr_, int idx_, double mul_);
//---
void OnNewBar() override final;
//--- Nuevo idx
void SetNewIdx(const int bar_idx) override final;
//--- Atr
inline CAtr* GetAtrPointer() const { return atr; }
//--- Atr mul
inline double AtrMul() const { return mul; }
void AtrMul(double new_value);
//---
void OnHistorialCopyData(const int start, const int count) override final { atr.CopyData(start, count); }
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CDiffAtr::OnNewBar(void)
{
if((m_flags & MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE) != 0)
m_diff = mul * atr[idx];
}
//+------------------------------------------------------------------+
//| Updates difference value based on ATR |
//+------------------------------------------------------------------+
void CDiffAtr::SetNewIdx(const int bar_idx)
{
if((m_flags & MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE) != 0)
this.m_diff = atr[bar_idx] * mul;
}
//+------------------------------------------------------------------+
//| Changes the ATR multiplier |
//+------------------------------------------------------------------+
void CDiffAtr::AtrMul(double new_value)
{
//--
this.mul = new_value;
//--
if(mul <= 0.00)
{
// Here forze print
FastLog(FUNCION_ACTUAL, WARNING_TEXT, StringFormat("Invalid ATR multiplier %f, disabling the class to avoid meaningless calls to OnNewBar, etc.", mul));
m_diff = 0.00;
MQLARTICLES_FUNC_REMOVE_FLAG(m_flags, MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE);
}
else
{
if(!CheckPointer(atr))
{
LogError("Atr is invalid", FUNCION_ACTUAL);
Remover();
return;
}
m_flags |= MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE;
}
}
//+------------------------------------------------------------------+
//| Configures calculation by ATR |
//+------------------------------------------------------------------+
void CDiffAtr::Set(CAtr* atr_, int idx_, double mul_)
{
//---
if(mul_ <= 0.00)
{
FastLog(FUNCION_ACTUAL, WARNING_TEXT, StringFormat("Invalid ATR multiplier %f, disabling the class to avoid meaningless calls to OnNewBar, etc.", mul_));
MQLARTICLES_FUNC_REMOVE_FLAG(m_flags, MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE);
m_diff = 0.00;
return;
}
//---
if(!CheckPointer(atr_))
{
LogCriticalError("Invalid ATR pointer in SetAtr", __FUNCTION__);
Remover();
return;
}
//---
if(atr_.Handle() == INVALID_HANDLE)
{
LogFatalError("The passed handle is invalid", FUNCION_ACTUAL);
Remover();
return;
}
//---
if(idx_ < 0)
{
LogWarning(StringFormat("Invalid ATR index %d, adjusting to 0", idx_), __FUNCTION__);
idx_ = 0;
}
//---
this.atr = atr_;
this.idx = idx_;
this.mul = mul_;
m_flags |= MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE;
}
//+------------------------------------------------------------------+
//| Creates a CDiff object on the heap and returns its pointer |
//+------------------------------------------------------------------+
CDiff* CreateDiffptr(ENUM_MODE_DIFF diff_mod, string symbol_, CAtr* atr_, int idx_, double mul_or_points)
{
//---
CDiff* obj = NULL;
//---
switch(diff_mod)
{
case MODE_DIFF_BY_FIXED_POITNS:
{
obj = new CDiffPoint();
CDiffPoint* diff_point = (CDiffPoint*)obj;
diff_point.Set(symbol_, int(mul_or_points));
break;
}
case MODE_DIFF_BY_ATR:
{
obj = new CDiffAtr();
CDiffAtr* diff_atr = (CDiffAtr*)obj;
diff_atr.Set(atr_, idx_, mul_or_points);
break;
}
default:
FastLog(FUNCION_ACTUAL, CRITICAL_ERROR_TEXT, StringFormat("Invalid type of Diff = %s", EnumToString(diff_mod)));
return NULL;
}
//--
return obj;
}
#endif // MQLARTICLES_UTILS_FA_DIFFCALC_MQH
//+------------------------------------------------------------------+