forked from nique_372/MQLArticles
		
	
		
			
				
	
	
		
			545 lines
		
	
	
		
			No EOL
		
	
	
		
			36 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
			
		
		
	
	
			545 lines
		
	
	
		
			No EOL
		
	
	
		
			36 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
//+------------------------------------------------------------------+
 | 
						|
//|                                                          Atr.mqh |
 | 
						|
//|                                  Copyright 2025, Niquel Mendoza. |
 | 
						|
//|                     https://www.mql5.com/es/users/nique_372/news |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#property copyright "Copyright 2025, Niquel Mendoza."
 | 
						|
#property link      "https://www.mql5.com/es/users/nique_372/news"
 | 
						|
#property strict
 | 
						|
 | 
						|
#ifndef UTILS_FA_ATR_MQH
 | 
						|
#define UTILS_FA_ATR_MQH
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Includes                                                         |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#include "SimpleLogger.mqh"
 | 
						|
#include "BarControler.mqh"
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Resources                                                        |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#resource "AtrCts.ex5"
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Class to handle the atr                                          |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
class CAtr : public CLoggerBase
 | 
						|
 {
 | 
						|
private:
 | 
						|
  double             arr[];
 | 
						|
  int                handle;
 | 
						|
  inline bool        IsIdxValid(const int idx) const;
 | 
						|
 | 
						|
public:
 | 
						|
                    ~CAtr();
 | 
						|
                     CAtr();
 | 
						|
 | 
						|
  void               SetAsSeries(bool flag);
 | 
						|
  inline void        CopyData(int start, int count);
 | 
						|
  inline void        CopyData(int count);
 | 
						|
 | 
						|
  void               Create(ENUM_TIMEFRAMES tf, string symb, int period, bool execute_on_bar, bool hide_indicator = true);
 | 
						|
  inline int         Handle() const { return handle; }
 | 
						|
  void               Create(int handle_);
 | 
						|
  void               Free() { ArrayFree(arr); }
 | 
						|
 | 
						|
  double             operator[](int _index) const { return IsIdxValid(_index) ? arr[_index] : 0.00; }
 | 
						|
 };
 | 
						|
 
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Contructor and Destructor                                        |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
CAtr::CAtr(void)
 | 
						|
  : handle(INVALID_HANDLE)
 | 
						|
 {
 | 
						|
  ArrayResize(arr, 0);
 | 
						|
 }
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
CAtr::~CAtr()
 | 
						|
 {
 | 
						|
  if(handle != INVALID_HANDLE)
 | 
						|
    IndicatorRelease(handle);
 | 
						|
  Free();
 | 
						|
 } 
 | 
						|
 
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Check index                                                      |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
inline bool        CAtr::IsIdxValid(const int idx) const
 | 
						|
 {
 | 
						|
  if((int)arr.Size() > idx && idx >= 0)
 | 
						|
    return true;
 | 
						|
  else
 | 
						|
   {
 | 
						|
    LogError(StringFormat("Acceso al array de atr denegado, indice %d fuera de rango, tamaño del array = %u", idx, arr.Size()), FUNCION_ACTUAL);
 | 
						|
    return false;
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
inline void CAtr::CopyData(int start, int count)
 | 
						|
 {
 | 
						|
  ResetLastError();
 | 
						|
  if(CopyBuffer(handle, 0, start, count, arr) < count)
 | 
						|
   {
 | 
						|
    LogError(StringFormat("No se pudo copiar data del indicador de atr [start %d -> count: %d], ultimo error = %d", start, count, GetLastError()), FUNCION_ACTUAL);
 | 
						|
    // FastLog(FUNCION_ACTUAL, INFO_TEXT, StringFormat("El handle del indicador es %s", (handle == INVALID_HANDLE ? "invalido" : "valido")));
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
inline void CAtr::CopyData(int count)
 | 
						|
 {
 | 
						|
  ResetLastError();
 | 
						|
  if(CopyBuffer(handle, 0, 0, count, arr) < count)
 | 
						|
   {
 | 
						|
    LogError(StringFormat("No se pudo copiar data del indicador de atr [0 -> count: %d], ultimo error = %d", count, GetLastError()), FUNCION_ACTUAL);
 | 
						|
    //FastLog(FUNCION_ACTUAL, INFO_TEXT, StringFormat("El handle del indicador es %s", (handle == INVALID_HANDLE ? "invalido" : "valido")));
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CAtr::Create(ENUM_TIMEFRAMES tf, string symb, int period, bool execute_on_bar, bool hide_indicator = true)
 | 
						|
 {
 | 
						|
  ResetLastError();
 | 
						|
 | 
						|
  if(hide_indicator)
 | 
						|
    TesterHideIndicators(true);
 | 
						|
 | 
						|
  int handle_ = iCustom(symb, tf, "::AtrCts.ex5", period, execute_on_bar);
 | 
						|
 | 
						|
  if(hide_indicator)
 | 
						|
    TesterHideIndicators(false);
 | 
						|
 | 
						|
  Create(handle_);
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CAtr::Create(int handle_)
 | 
						|
 {
 | 
						|
  if(handle_ == INVALID_HANDLE)
 | 
						|
   {
 | 
						|
    LogFatalError(StringFormat("No se pudo crear el handle para el indicador atr, ultimo error = %d", GetLastError()), FUNCION_ACTUAL);
 | 
						|
    Remover();
 | 
						|
    return;
 | 
						|
   }
 | 
						|
 | 
						|
  this.handle = handle_;
 | 
						|
 | 
						|
  int atemps = 1000;
 | 
						|
  double dummy[];
 | 
						|
  bool is = false;
 | 
						|
  ArrayResize(dummy, 0);
 | 
						|
  ArraySetAsSeries(dummy, true);
 | 
						|
 | 
						|
  while(atemps-- > 0)
 | 
						|
   {
 | 
						|
    CopyBuffer(handle, 0, 0, 500, dummy);
 | 
						|
    is = DataIsValid(dummy);
 | 
						|
 | 
						|
    if(is)
 | 
						|
      break;
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CAtr::SetAsSeries(bool flag)
 | 
						|
 {
 | 
						|
  ArraySetAsSeries(this.arr, flag);
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
bool DataIsValid(const double &arr[])
 | 
						|
 {
 | 
						|
  for(int i = 0; i < (int)arr.Size(); i++)
 | 
						|
   {
 | 
						|
    if(arr[i] == 0.00 || arr[i] == EMPTY_VALUE)
 | 
						|
      return false;
 | 
						|
   }
 | 
						|
 | 
						|
  return true;
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Base class to implement the atr                                  | 
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
class CAtrOptimized : public CLoggerBase
 | 
						|
 {
 | 
						|
protected:
 | 
						|
  ENUM_TIMEFRAMES    m_timeframe;
 | 
						|
  string             m_symbol;
 | 
						|
  int                m_index;
 | 
						|
  int                m_period;
 | 
						|
  double             m_atr_value;  // Valor ATR específico para m_index
 | 
						|
  double             wilder_factor;
 | 
						|
  double             inv_period;
 | 
						|
 | 
						|
  //---
 | 
						|
  double             high[];
 | 
						|
  double             low[];
 | 
						|
  double             close[];
 | 
						|
  double             atr[];
 | 
						|
 | 
						|
  //---
 | 
						|
  CBarControler*     controler_curr;
 | 
						|
  inline double      CalculeTrueRange(int idx);
 | 
						|
  inline double      CalculeTrueRangeForIndexCts(int index);
 | 
						|
  bool               CopyData();
 | 
						|
 | 
						|
public:
 | 
						|
                     CAtrOptimized(ENUM_TIMEFRAMES tf, string symbol, int index, int period);
 | 
						|
                    ~CAtrOptimized(void);
 | 
						|
 | 
						|
  virtual inline double GetAtrValue(datetime curr_time) = 0;
 | 
						|
 };
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Constructor and destructor                                       |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
CAtrOptimized::CAtrOptimized(ENUM_TIMEFRAMES tf, string symbol, int index, int period)
 | 
						|
 {
 | 
						|
  bool custom = false;
 | 
						|
  if(SymbolExist(symbol, custom) == false)
 | 
						|
   {
 | 
						|
    LogFatalError(StringFormat("El simbolo %s, es invalido", symbol), FUNCION_ACTUAL);
 | 
						|
    Remover();
 | 
						|
    return;
 | 
						|
   }
 | 
						|
 | 
						|
  if(period <= 0)
 | 
						|
   {
 | 
						|
    LogFatalError(StringFormat("El periodo del atr %d, es invalido", period), FUNCION_ACTUAL);
 | 
						|
    Remover();
 | 
						|
    return;
 | 
						|
   }
 | 
						|
 | 
						|
 | 
						|
  m_timeframe = tf;
 | 
						|
  m_symbol = symbol;
 | 
						|
  m_index = index;
 | 
						|
  m_period = period;
 | 
						|
  m_atr_value = 0.0;
 | 
						|
  controler_curr = new CBarControler(tf, symbol);
 | 
						|
  wilder_factor = (double)(m_period - 1) / m_period;  // 13/14 para período 14
 | 
						|
  inv_period = 1.0 / m_period;                        // 1/14 para período 14
 | 
						|
 | 
						|
  ArraySetAsSeries(high, true);
 | 
						|
  ArraySetAsSeries(low, true);
 | 
						|
  ArraySetAsSeries(close, true);
 | 
						|
  ArrayResize(high, 0);
 | 
						|
  ArrayResize(low, 0);
 | 
						|
  ArrayResize(close, 0);
 | 
						|
  ArrayResize(atr, m_period + 2);
 | 
						|
 }
 | 
						|
 
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
CAtrOptimized::~CAtrOptimized(void)
 | 
						|
 {
 | 
						|
  ArrayFree(high);
 | 
						|
  ArrayFree(low);
 | 
						|
  ArrayFree(close);
 | 
						|
  ArrayFree(atr);
 | 
						|
 | 
						|
  if(CheckPointer(controler_curr) == POINTER_DYNAMIC && controler_curr != NULL)
 | 
						|
    delete controler_curr;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#define CopyAtrExtraValue 3
 | 
						|
#define CopyAtr(p) p*2+CopyAtrExtraValue
 | 
						|
 | 
						|
//---
 | 
						|
bool CAtrOptimized::CopyData()
 | 
						|
 {
 | 
						|
  int to_copy = CopyAtr(m_period);
 | 
						|
 | 
						|
  if(CopyHigh(this.m_symbol, this.m_timeframe, m_index, to_copy, high) < to_copy)
 | 
						|
   {
 | 
						|
    LogError(StringFormat("Al copiar data de los highs, start = %d - count = %d", m_index, to_copy), FUNCION_ACTUAL);
 | 
						|
    return false;
 | 
						|
   }
 | 
						|
 | 
						|
  if(CopyClose(this.m_symbol, this.m_timeframe, m_index, to_copy, close) < to_copy)
 | 
						|
   {
 | 
						|
    LogError(StringFormat("Al copiar data de los closes start = %d - count = %d", m_index, to_copy), FUNCION_ACTUAL);
 | 
						|
    return false;
 | 
						|
   }
 | 
						|
 | 
						|
  if(CopyLow(this.m_symbol, this.m_timeframe, m_index, to_copy, low) < to_copy)
 | 
						|
   {
 | 
						|
    LogError(StringFormat("Al copiar data de los lows, start = %d - count = %d", m_index, to_copy), FUNCION_ACTUAL);
 | 
						|
    return false;
 | 
						|
   }
 | 
						|
 | 
						|
  return true;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
inline double CAtrOptimized::CalculeTrueRange(int idx)
 | 
						|
 {
 | 
						|
  return MaxValue(high[idx], close[idx + 1]) - MinValue(low[idx], close[idx + 1]);
 | 
						|
 }
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
inline double CAtrOptimized::CalculeTrueRangeForIndexCts(int index)
 | 
						|
 {
 | 
						|
  double prev_close = iClose(m_symbol, m_timeframe, index + 1);
 | 
						|
  return MaxValue(iHigh(m_symbol, m_timeframe, index), prev_close) - MinValue(iLow(m_symbol, m_timeframe, index), prev_close);
 | 
						|
 }
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
template<typename T>
 | 
						|
inline T MinValue(const T val, const T val2)
 | 
						|
 {
 | 
						|
  return val > val2 ? val2 : val;
 | 
						|
 }
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
template<typename T>
 | 
						|
inline T MaxValue(const T val, const T val2)
 | 
						|
 {
 | 
						|
  return val < val2 ? val2 : val;
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
class CAtrOptimizedZero : public CAtrOptimized
 | 
						|
 {
 | 
						|
private:
 | 
						|
  double               CalculateAtrForIndexComplete();  
 | 
						|
  double               CalculateAtrForIndexFast();
 | 
						|
 | 
						|
  //---
 | 
						|
  double             cached_prev_atr;
 | 
						|
  double             cached_tr_period;
 | 
						|
 | 
						|
public:
 | 
						|
                     CAtrOptimizedZero(ENUM_TIMEFRAMES tf, string symbol, int period);
 | 
						|
  inline double      GetAtrValue(datetime curr_time) override;
 | 
						|
 };
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
CAtrOptimizedZero::CAtrOptimizedZero(ENUM_TIMEFRAMES tf, string symbol, int period)
 | 
						|
  : CAtrOptimized(tf, symbol, 0, period)
 | 
						|
 {
 | 
						|
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
inline double CAtrOptimizedZero::GetAtrValue(datetime curr_time)
 | 
						|
 {
 | 
						|
  if(controler_curr.IsNewBar(curr_time))
 | 
						|
   {
 | 
						|
    if(controler_curr.GetNextPrevBarTime() + controler_curr.PeriodsInSeconds() < curr_time) //hubo suspension
 | 
						|
      return CalculateAtrForIndexComplete();
 | 
						|
    else
 | 
						|
      return CalculateAtrForIndexFast();
 | 
						|
   }
 | 
						|
 | 
						|
  m_atr_value = cached_prev_atr + (CalculeTrueRangeForIndexCts(0) - cached_tr_period) * inv_period;
 | 
						|
  return m_atr_value;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
double CAtrOptimizedZero::CalculateAtrForIndexComplete(void)
 | 
						|
 {
 | 
						|
  if(!CopyData())
 | 
						|
    return 0.00;
 | 
						|
 | 
						|
  double sum = 0;
 | 
						|
  for(int i = 1; i <= m_period; i++)  // Empezar desde 1, evitar la barra actual
 | 
						|
    sum += CalculeTrueRange(i);
 | 
						|
 | 
						|
  sum *= inv_period;
 | 
						|
  double current_atr = sum;
 | 
						|
 | 
						|
  for(int i = m_period - 1; i >= 1; i--)  // Desde m_period-1 hacia 1
 | 
						|
   {
 | 
						|
    double tr = CalculeTrueRange(i);
 | 
						|
    current_atr = current_atr * wilder_factor + tr * inv_period;
 | 
						|
   }
 | 
						|
 | 
						|
  cached_prev_atr = current_atr;
 | 
						|
  cached_tr_period = CalculeTrueRange(m_period); // TR que se usará en fast
 | 
						|
 | 
						|
 | 
						|
  double tr_current = CalculeTrueRange(0);
 | 
						|
  m_atr_value = current_atr + (tr_current - cached_tr_period) * inv_period;
 | 
						|
  return m_atr_value;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
double CAtrOptimizedZero::CalculateAtrForIndexFast(void)
 | 
						|
 {
 | 
						|
  this.cached_prev_atr = this.m_atr_value;
 | 
						|
  this.cached_tr_period = CalculeTrueRangeForIndexCts(m_period); // no sumamos m_index por que eso zero
 | 
						|
  m_atr_value = cached_prev_atr + (CalculeTrueRangeForIndexCts(0) - cached_tr_period) * inv_period;
 | 
						|
  return m_atr_value;
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
class CAtrOptimizedNonZero : public CAtrOptimized
 | 
						|
 {
 | 
						|
  double             CalculateAtrForIndexComplete();  // Calcular solo para el índice específico
 | 
						|
  double             CalculateAtrForIndexFast();
 | 
						|
  double             cached_prev_atr;
 | 
						|
 | 
						|
public:
 | 
						|
                     CAtrOptimizedNonZero(ENUM_TIMEFRAMES tf, string symbol, int index, int period);
 | 
						|
  inline double      GetAtrValue(datetime curr_time) override;
 | 
						|
 };
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
CAtrOptimizedNonZero::CAtrOptimizedNonZero(ENUM_TIMEFRAMES tf, string symbol, int index, int period)
 | 
						|
  : CAtrOptimized(tf, symbol, index, period)
 | 
						|
 {
 | 
						|
 | 
						|
 }
 | 
						|
 
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
inline double CAtrOptimizedNonZero::GetAtrValue(datetime curr_time)
 | 
						|
 {
 | 
						|
  if(controler_curr.IsNewBar(curr_time))
 | 
						|
   {
 | 
						|
    if(controler_curr.GetNextPrevBarTime() + controler_curr.PeriodsInSeconds() < curr_time) //hubo suspension
 | 
						|
      return CalculateAtrForIndexComplete();
 | 
						|
    else
 | 
						|
      return CalculateAtrForIndexFast();
 | 
						|
   }
 | 
						|
 | 
						|
  return this.m_atr_value;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
double CAtrOptimizedNonZero::CalculateAtrForIndexFast(void)
 | 
						|
 {
 | 
						|
  this.cached_prev_atr = m_atr_value;
 | 
						|
  double tr_current = CalculeTrueRangeForIndexCts(m_index);
 | 
						|
  double cached_prev_tr_period = CalculeTrueRangeForIndexCts(m_index + m_period);
 | 
						|
  m_atr_value = cached_prev_atr + (tr_current - cached_prev_tr_period) * inv_period;
 | 
						|
  return m_atr_value;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
double CAtrOptimizedNonZero::CalculateAtrForIndexComplete(void)
 | 
						|
 {
 | 
						|
  if(!CopyData())
 | 
						|
    return 0.00;
 | 
						|
 | 
						|
  double sum = 0;
 | 
						|
  for(int i = 0; i <= m_period; i++)
 | 
						|
    sum += CalculeTrueRange(i);
 | 
						|
 | 
						|
  double initial_atr = sum * inv_period;
 | 
						|
  double current_atr = initial_atr;
 | 
						|
 | 
						|
  for(int i = m_period - 1; i >= 0; i--)
 | 
						|
   {
 | 
						|
    double tr = CalculeTrueRange(i);
 | 
						|
    current_atr = current_atr * wilder_factor + tr * inv_period;
 | 
						|
 | 
						|
    if(i == 1)  // Guardar ATR[1] para el cache
 | 
						|
      cached_prev_atr = current_atr;
 | 
						|
   }
 | 
						|
 | 
						|
  m_atr_value = current_atr;  // current_atr ahora es ATR[0]
 | 
						|
  return m_atr_value;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
class CAtrUltraOptimized
 | 
						|
 {
 | 
						|
private:
 | 
						|
  ENUM_TIMEFRAMES    m_timeframe;
 | 
						|
  string             m_symbol;
 | 
						|
  int                m_index;
 | 
						|
  int                m_period;
 | 
						|
 | 
						|
 | 
						|
public:
 | 
						|
                     CAtrUltraOptimized();
 | 
						|
                    ~CAtrUltraOptimized();
 | 
						|
 | 
						|
  //---
 | 
						|
  CAtrOptimized*     base;
 | 
						|
 | 
						|
  //---
 | 
						|
  void               SetVariables(ENUM_TIMEFRAMES tf, string symbol_, int index_, int period_);
 | 
						|
 | 
						|
  //---
 | 
						|
  void               Period(int new_value) { this.m_period = new_value; }
 | 
						|
  void               Symbol(string new_value) { this.m_symbol = new_value; }
 | 
						|
  void               Index(int new_value) { this.m_index = new_value; }
 | 
						|
  void               Timeframe(ENUM_TIMEFRAMES new_value) { this.m_timeframe = new_value; }
 | 
						|
 | 
						|
  //---
 | 
						|
  inline int         Period() const {  return m_period; }
 | 
						|
  inline string      Symbol() const { return m_symbol; }
 | 
						|
  inline int         Index() const { return m_index; }
 | 
						|
  inline             ENUM_TIMEFRAMES Timeframe() const { return m_timeframe; }
 | 
						|
 | 
						|
  //---
 | 
						|
  bool               SetInternalPointer();
 | 
						|
 };
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
CAtrUltraOptimized::CAtrUltraOptimized(void)
 | 
						|
  : base(NULL), m_timeframe(::Period()), m_symbol(::Symbol()), m_index(0), m_period(14)
 | 
						|
 {
 | 
						|
 | 
						|
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
CAtrUltraOptimized::~CAtrUltraOptimized()
 | 
						|
 {
 | 
						|
  if(::CheckPointer(base) == POINTER_DYNAMIC)
 | 
						|
    delete base;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
bool CAtrUltraOptimized::SetInternalPointer(void)
 | 
						|
 {
 | 
						|
  if(::CheckPointer(base) == POINTER_DYNAMIC)
 | 
						|
    delete base;
 | 
						|
 | 
						|
  if(this.m_index == 0)
 | 
						|
    base = new CAtrOptimizedZero(this.m_timeframe, this.m_symbol, this.m_period);
 | 
						|
  else
 | 
						|
    base = new CAtrOptimizedNonZero(this.m_timeframe, this.m_symbol, this.m_index, this.m_period);
 | 
						|
 | 
						|
  return (::CheckPointer(base) == POINTER_DYNAMIC);
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CAtrUltraOptimized::SetVariables(ENUM_TIMEFRAMES tf, string symbol_, int index_, int period_)
 | 
						|
 {
 | 
						|
  this.m_timeframe = tf;
 | 
						|
  this.m_symbol = symbol_;
 | 
						|
  this.m_index = index_;
 | 
						|
  this.m_period = period_;
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
#endif  |