2026-02-13 11:39:20 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| 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
|
|
|
|
|
};
|
|
|
|
|
|
2026-02-14 17:00:45 -05:00
|
|
|
//--- 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)
|
|
|
|
|
|
|
|
|
|
|
2026-02-13 11:39:20 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| class CDiff |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
class CDiff : public CLoggerBase
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
//---
|
2026-02-14 17:00:45 -05:00
|
|
|
const ENUM_MODE_DIFF m_type; // Differene type
|
|
|
|
|
uint8_t m_flags; // Flags
|
|
|
|
|
double m_diff; // Calculated difference value
|
2026-02-13 11:39:20 -05:00
|
|
|
|
|
|
|
|
public:
|
2026-02-14 17:00:45 -05:00
|
|
|
CDiff(const ENUM_MODE_DIFF type, const uint8_t flags) : m_type(type), m_diff(0.00), m_flags(flags) {}
|
2026-02-13 11:39:20 -05:00
|
|
|
~CDiff() {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//--- Method to update on new candle
|
|
|
|
|
virtual void OnNewBar() {}
|
|
|
|
|
|
|
|
|
|
//---
|
2026-02-14 17:00:45 -05:00
|
|
|
__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) {}
|
2026-02-13 11:39:20 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| class CDiffPoint |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
class CDiffPoint : public CDiff
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
string symbol; // Symbol for point calculation
|
|
|
|
|
|
|
|
|
|
public:
|
2026-02-14 17:00:45 -05:00
|
|
|
CDiffPoint(void) : CDiff(MODE_DIFF_BY_FIXED_POITNS, MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE) {}
|
2026-02-13 11:39:20 -05:00
|
|
|
~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:
|
2026-02-14 17:00:45 -05:00
|
|
|
int idx; // Index for ATR
|
|
|
|
|
CAtr* atr; // Pointer to ATR object
|
|
|
|
|
double mul; // Multiplier for ATR
|
2026-02-13 11:39:20 -05:00
|
|
|
|
|
|
|
|
public:
|
2026-02-14 17:00:45 -05:00
|
|
|
CDiffAtr(void) : CDiff(MODE_DIFF_BY_ATR, MQLARTICLES_DIFFCALC_ALL_FLAG),
|
|
|
|
|
idx(0), atr(NULL), mul(0.00) {}
|
2026-02-13 11:39:20 -05:00
|
|
|
~CDiffAtr(void) {}
|
|
|
|
|
|
|
|
|
|
//--- General setterr
|
|
|
|
|
void Set(CAtr * atr_, int idx_, double mul_);
|
|
|
|
|
|
|
|
|
|
//---
|
2026-02-14 17:50:39 -05:00
|
|
|
void OnNewBar() override final;
|
2026-02-13 11:39:20 -05:00
|
|
|
|
|
|
|
|
//--- Nuevo idx
|
2026-02-14 17:00:45 -05:00
|
|
|
void SetNewIdx(const int bar_idx) override final;
|
2026-02-13 11:39:20 -05:00
|
|
|
|
|
|
|
|
//--- Atr
|
|
|
|
|
inline CAtr* GetAtrPointer() const { return atr; }
|
|
|
|
|
|
|
|
|
|
//--- Atr mul
|
|
|
|
|
inline double AtrMul() const { return mul; }
|
|
|
|
|
void AtrMul(double new_value);
|
|
|
|
|
|
2026-02-14 17:00:45 -05:00
|
|
|
//---
|
|
|
|
|
void OnHistorialCopyData(const int start, const int count) override final { atr.CopyData(start, count); }
|
2026-02-13 11:39:20 -05:00
|
|
|
};
|
|
|
|
|
|
2026-02-14 17:50:39 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void CDiffAtr::OnNewBar(void)
|
|
|
|
|
{
|
|
|
|
|
if((m_flags & MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE) != 0)
|
|
|
|
|
m_diff = mul * atr[idx];
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-13 11:39:20 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Updates difference value based on ATR |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-02-14 17:00:45 -05:00
|
|
|
void CDiffAtr::SetNewIdx(const int bar_idx)
|
2026-02-13 11:39:20 -05:00
|
|
|
{
|
2026-02-14 17:00:45 -05:00
|
|
|
if((m_flags & MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE) != 0)
|
|
|
|
|
this.m_diff = atr[bar_idx] * mul;
|
2026-02-13 11:39:20 -05:00
|
|
|
}
|
2026-02-14 17:50:39 -05:00
|
|
|
|
2026-02-13 11:39:20 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Changes the ATR multiplier |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void CDiffAtr::AtrMul(double new_value)
|
|
|
|
|
{
|
|
|
|
|
//--
|
|
|
|
|
this.mul = new_value;
|
|
|
|
|
|
|
|
|
|
//--
|
|
|
|
|
if(mul <= 0.00)
|
|
|
|
|
{
|
2026-02-14 17:50:39 -05: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));
|
2026-02-13 11:39:20 -05:00
|
|
|
m_diff = 0.00;
|
2026-02-14 17:00:45 -05:00
|
|
|
MQLARTICLES_FUNC_REMOVE_FLAG(m_flags, MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE);
|
2026-02-13 11:39:20 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(!CheckPointer(atr))
|
|
|
|
|
{
|
|
|
|
|
LogError("Atr is invalid", FUNCION_ACTUAL);
|
|
|
|
|
Remover();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-02-14 17:00:45 -05:00
|
|
|
m_flags |= MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE;
|
2026-02-13 11:39:20 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Configures calculation by ATR |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void CDiffAtr::Set(CAtr* atr_, int idx_, double mul_)
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(mul_ <= 0.00)
|
|
|
|
|
{
|
2026-02-14 17:50:39 -05:00
|
|
|
FastLog(FUNCION_ACTUAL, WARNING_TEXT, StringFormat("Invalid ATR multiplier %f, disabling the class to avoid meaningless calls to OnNewBar, etc.", mul_));
|
2026-02-14 17:00:45 -05:00
|
|
|
MQLARTICLES_FUNC_REMOVE_FLAG(m_flags, MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE);
|
2026-02-13 11:39:20 -05:00
|
|
|
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_;
|
2026-02-14 17:00:45 -05:00
|
|
|
m_flags |= MQLARTICLES_DIFFCALC_FLAG_IS_ACTIVE;
|
2026-02-13 11:39:20 -05:00
|
|
|
}
|
|
|
|
|
|
2026-02-14 17:50:39 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-02-13 11:39:20 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| 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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-14 17:00:45 -05:00
|
|
|
#endif // MQLARTICLES_UTILS_FA_DIFFCALC_MQH
|
|
|
|
|
//+------------------------------------------------------------------+
|