//+------------------------------------------------------------------+ //| Pool.mqh | //| Copyright 2025, Niquel Mendoza. | //| https://www.mql5.com/es/users/nique_372 | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Niquel Mendoza." #property link "https://www.mql5.com/es/users/nique_372" #property strict #ifndef MQLARTICLES_INDICATORSCTS_POOL_MQH #define MQLARTICLES_INDICATORSCTS_POOL_MQH //+------------------------------------------------------------------+ //| Include | //+------------------------------------------------------------------+ #include "Main.mqh" //+------------------------------------------------------------------+ //| Defines \ Global \ Structs | //+------------------------------------------------------------------+ //--- string g_indicator_cache_key = ""; //--- #define INDICATOR_CACHE_DBL_DIG (4) //--- struct IndicatorCacheExtraData { string key; int ref_count; }; //+------------------------------------------------------------------+ //| Cache de indicadores | //+------------------------------------------------------------------+ class CIndicatorCache { private: //--- static CHashMap* s_hash_str_to_int; static bool s_is_active; //--- RSI static CiRsi* s_rsi[]; static int s_rsi_size; static IndicatorCacheExtraData s_rsi_data[]; //--- MA static CiMa* s_ma[]; static int s_ma_size; static IndicatorCacheExtraData s_ma_data[]; //--- CCI static CiCci* s_cci[]; static int s_cci_size; static IndicatorCacheExtraData s_cci_data[]; //--- Stochastic static CiStocastic* s_stochastic[]; static int s_stochastic_size; static IndicatorCacheExtraData s_stochastic_data[]; //--- VIDyA static CiVIDyA* s_vidya[]; static int s_vidya_size; static IndicatorCacheExtraData s_vidya_data[]; //--- Bollinger Bands static CiBands* s_bands[]; static int s_bands_size; static IndicatorCacheExtraData s_bands_data[]; //--- SuperTrend static CiSuperTrend* s_supertrend[]; static int s_supertrend_size; static IndicatorCacheExtraData s_supertrend_data[]; //--- VWAP static CiVwapChange* s_vwap[]; static int s_vwap_size; static IndicatorCacheExtraData s_vwap_data[]; //--- AD static CiAD* s_ad[]; static int s_ad_size; static IndicatorCacheExtraData s_ad_data[]; //--- OBV static CiObv* s_obv[]; static int s_obv_size; static IndicatorCacheExtraData s_obv_data[]; //--- Standard Deviation static CiStandartDeviation* s_stddev[]; static int s_stddev_size; static IndicatorCacheExtraData s_stddev_data[]; //--- SAR static CiSar* s_sar[]; static int s_sar_size; static IndicatorCacheExtraData s_sar_data[]; //--- ADX static CiAdx* s_adx[]; static int s_adx_size; static IndicatorCacheExtraData s_adx_data[]; //--- ADX Wilder static CiAdxWilder* s_adx_wilder[]; static int s_adx_wilder_size; static IndicatorCacheExtraData s_adx_wilder_data[]; //--- Funcion template para remover template static bool RemoveFromArray(T* &element, T* &array[], IndicatorCacheExtraData &data[], int &size); public: CIndicatorCache(void) {} ~CIndicatorCache(void) {} //--- Init - Deinit static void Init(); static void Deinit(const int reason); //--- IsActive static __forceinline bool IsActive() { return s_is_active; } //--- RSI static CiRsi* GetRsi(ENUM_TIMEFRAMES timeframe, string symbol, int period, ENUM_APPLIED_PRICE applied, bool series, bool hide); static __forceinline bool RemoveRsi(CiRsi* element) { return RemoveFromArray(element, s_rsi, s_rsi_data, s_rsi_size); } //--- MA static CiMa* GetMa(ENUM_TIMEFRAMES timeframe, string symbol, int period, ENUM_APPLIED_PRICE applied, int ma_shift, ENUM_MA_METHOD ma_method, bool series, bool hide); static __forceinline bool RemoveMa(CiMa* element) { return RemoveFromArray(element, s_ma, s_ma_data, s_ma_size); } //--- CCI static CiCci* GetCci(ENUM_TIMEFRAMES timeframe, string symbol, int period, ENUM_APPLIED_PRICE applied, bool series, bool hide); static __forceinline bool RemoveCci(CiCci* element) { return RemoveFromArray(element, s_cci, s_cci_data, s_cci_size); } //--- Stochastic static CiStocastic* GetStochastic(ENUM_TIMEFRAMES timeframe, string symbol, int kperiod, int dperiod, int slowing, ENUM_MA_METHOD ma_method, ENUM_STO_PRICE sto_price, bool series, bool hide); static __forceinline bool RemoveStochastic(CiStocastic* element) { return RemoveFromArray(element, s_stochastic, s_stochastic_data, s_stochastic_size); } //--- VIDyA static CiVIDyA* GetVidya(ENUM_TIMEFRAMES timeframe, string symbol, int cmo_period, int ema_period, int ma_shift, ENUM_APPLIED_PRICE applied, bool series, bool hide); static __forceinline bool RemoveVidya(CiVIDyA* element) { return RemoveFromArray(element, s_vidya, s_vidya_data, s_vidya_size); } //--- Bollinger Bands static CiBands* GetBands(ENUM_TIMEFRAMES timeframe, string symbol, int bands_period, int bands_shift, double deviation, ENUM_APPLIED_PRICE applied_price, bool series, bool hide); static __forceinline bool RemoveBands(CiBands* element) { return RemoveFromArray(element, s_bands, s_bands_data, s_bands_size); } //--- SuperTrend static CiSuperTrend* GetSuperTrend(ENUM_TIMEFRAMES timeframe, string symbol, int cci_period, ENUM_APPLIED_PRICE applied, int atr_period, bool series, bool hide); static __forceinline bool RemoveSuperTrend(CiSuperTrend* element) { return RemoveFromArray(element, s_supertrend, s_supertrend_data, s_supertrend_size); } //--- VWAP static CiVwapChange* GetVwap(ENUM_TIMEFRAMES timeframe, string symbol, VWAP_Period period, ENUM_APPLIED_PRICE applied, bool series, bool hide); static __forceinline bool RemoveVwap(CiVwapChange* element) { return RemoveFromArray(element, s_vwap, s_vwap_data, s_vwap_size); } //--- AD static CiAD* GetAD(ENUM_TIMEFRAMES timeframe, string symbol, ENUM_APPLIED_VOLUME applied, bool series, bool hide); static __forceinline bool RemoveAD(CiAD* element) { return RemoveFromArray(element, s_ad, s_ad_data, s_ad_size); } //--- OBV static CiObv* GetObv(ENUM_TIMEFRAMES timeframe, string symbol, ENUM_APPLIED_VOLUME applied, bool series, bool hide); static __forceinline bool RemoveObv(CiObv* element) { return RemoveFromArray(element, s_obv, s_obv_data, s_obv_size); } //--- Standard Deviation static CiStandartDeviation* GetStdDev(ENUM_TIMEFRAMES timeframe, string symbol, int ma_period, int ma_shift, ENUM_MA_METHOD ma_method, ENUM_APPLIED_PRICE applied, bool series, bool hide); static __forceinline bool RemoveStdDev(CiStandartDeviation* element) { return RemoveFromArray(element, s_stddev, s_stddev_data, s_stddev_size); } //--- SAR static CiSar* GetSar(ENUM_TIMEFRAMES timeframe, string symbol, double step, double maximum, bool series, bool hide); static __forceinline bool RemoveSar(CiSar* element) { return RemoveFromArray(element, s_sar, s_sar_data, s_sar_size); } //--- ADX static CiAdx* GetAdx(ENUM_TIMEFRAMES timeframe, string symbol, int ma_period, bool series, bool hide); static __forceinline bool RemoveAdx(CiAdx* element) { return RemoveFromArray(element, s_adx, s_adx_data, s_adx_size); } //--- ADX Wilder static CiAdxWilder* GetAdxWilder(ENUM_TIMEFRAMES timeframe, string symbol, int ma_period, bool series, bool hide); static __forceinline bool RemoveAdxWilder(CiAdxWilder* element) { return RemoveFromArray(element, s_adx_wilder, s_adx_wilder_data, s_adx_wilder_size); } }; //+------------------------------------------------------------------+ //| Init | //+------------------------------------------------------------------+ static void CIndicatorCache::Init(void) { if(s_is_active) return; //--- s_hash_str_to_int = new CHashMap(); s_is_active = true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template static bool CIndicatorCache::RemoveFromArray(T* &element, T* &array[], IndicatorCacheExtraData &data[], int &size) { //--- const ENUM_POINTER_TYPE ptr_type = CheckPointer(element); if(ptr_type == POINTER_INVALID) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("se esta intentando eliminar un elemento INVALIDO, type = %s", typename(T))); return false; } //--- Find int idx = -1; for(int i = 0; i < size; i++) { if(array[i] == element) { idx = i; break; } } //--- Verificamos si existe if(idx == -1) { FastLog(FUNCION_ACTUAL, ERROR_TEXT, "El puntero que se busca eliminar ya no existe"); return false; } //--- Reducimos y comparamos, en caso ser menor o igual a 0 se termino para esta "key" lo eliminamos if(--data[idx].ref_count <= 0) { //--- Eliminar objeto, solo si es DINAMICO if(ptr_type == POINTER_DYNAMIC) delete array[idx]; //--- Removemos del hashmap if(!s_hash_str_to_int.Remove(data[idx].key)) { FastLog(FUNCION_ACTUAL, CRITICAL_ERROR_TEXT, StringFormat("No se pudo eliminar el key = '%s'", data[idx].key)); return false; } //--- Swap con el ultimo elemento const int last = --size; if(last != idx) { array[idx] = array[last]; data[idx] = data[last]; // Nota aqui el objeto que estaba en LAST ahora estara en la posicion IDX por loq ue key es de LAST s_hash_str_to_int.TrySetValue(data[idx].key, idx); } //--- Resize ArrayResize(array, size); ArrayResize(data, size); //--- return true; } //--- return false; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiRsi* CIndicatorCache::GetRsi(ENUM_TIMEFRAMES timeframe, string symbol, int period, ENUM_APPLIED_PRICE applied, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "RSI_" + symbol + "_" + string(int(timeframe)) + "_" + string(period) + "_" + string(int(applied)) + "_" + string(int(series)); //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_rsi_size; //--- Array ArrayResize(s_rsi, ++s_rsi_size); s_rsi[idx] = new CiRsi(); if(!s_rsi[idx].Create(timeframe, symbol, period, applied, series, hide)) { delete s_rsi[idx]; s_rsi_size--; ArrayResize(s_rsi, s_rsi_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_rsi_data, s_rsi_size); s_rsi_data[idx].key = g_indicator_cache_key; s_rsi_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_rsi_data[idx].ref_count++; //--- Retornamos puntero return s_rsi[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiMa* CIndicatorCache::GetMa(ENUM_TIMEFRAMES timeframe, string symbol, int period, ENUM_APPLIED_PRICE applied, int ma_shift, ENUM_MA_METHOD ma_method, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "MA_" + symbol + "_" + string(int(timeframe)) + "_" + string(period) + "_" + string(int(applied)) + "_" + string(ma_shift) + "_" + string(int(ma_method)) + "_" + string(int(series)) ; //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_ma_size; //--- Array ArrayResize(s_ma, ++s_ma_size); s_ma[idx] = new CiMa(); if(!s_ma[idx].Create(timeframe, symbol, period, applied, ma_shift, ma_method, series, hide)) { delete s_ma[idx]; s_ma_size--; ArrayResize(s_ma, s_ma_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_ma_data, s_ma_size); s_ma_data[idx].key = g_indicator_cache_key; s_ma_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_ma_data[idx].ref_count++; //--- Retornamos puntero return s_ma[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiCci* CIndicatorCache::GetCci(ENUM_TIMEFRAMES timeframe, string symbol, int period, ENUM_APPLIED_PRICE applied, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "CCI_" + symbol + "_" + string(int(timeframe)) + "_" + string(period) + "_" + string(int(applied)) + "_" + string(int(series)) ; //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_cci_size; //--- Array ArrayResize(s_cci, ++s_cci_size); s_cci[idx] = new CiCci(); if(!s_cci[idx].Create(timeframe, symbol, period, applied, series, hide)) { delete s_cci[idx]; s_cci_size--; ArrayResize(s_cci, s_cci_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_cci_data, s_cci_size); s_cci_data[idx].key = g_indicator_cache_key; s_cci_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_cci_data[idx].ref_count++; //--- Retornamos puntero return s_cci[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiStocastic* CIndicatorCache::GetStochastic(ENUM_TIMEFRAMES timeframe, string symbol, int kperiod, int dperiod, int slowing, ENUM_MA_METHOD ma_method, ENUM_STO_PRICE sto_price, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "STOCH_" + symbol + "_" + string(int(timeframe)) + "_" + string(kperiod) + "_" + string(dperiod) + "_" + string(slowing) + "_" + string(int(ma_method)) + "_" + string(int(sto_price)) + "_" + string(int(series)); //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_stochastic_size; //--- Array ArrayResize(s_stochastic, ++s_stochastic_size); s_stochastic[idx] = new CiStocastic(); if(!s_stochastic[idx].Create(timeframe, symbol, kperiod, dperiod, slowing, ma_method, sto_price, series, hide)) { delete s_stochastic[idx]; s_stochastic_size--; ArrayResize(s_stochastic, s_stochastic_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_stochastic_data, s_stochastic_size); s_stochastic_data[idx].key = g_indicator_cache_key; s_stochastic_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_stochastic_data[idx].ref_count++; //--- Retornamos puntero return s_stochastic[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiVIDyA* CIndicatorCache::GetVidya(ENUM_TIMEFRAMES timeframe, string symbol, int cmo_period, int ema_period, int ma_shift, ENUM_APPLIED_PRICE applied, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "VIDYA_" + symbol + "_" + string(int(timeframe)) + "_" + string(cmo_period) + "_" + string(ema_period) + "_" + string(ma_shift) + "_" + string(int(applied)) + "_" + string(int(series)) ; //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_vidya_size; //--- Array ArrayResize(s_vidya, ++s_vidya_size); s_vidya[idx] = new CiVIDyA(); if(!s_vidya[idx].Create(timeframe, symbol, cmo_period, ema_period, ma_shift, applied, series, hide)) { delete s_vidya[idx]; s_vidya_size--; ArrayResize(s_vidya, s_vidya_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_vidya_data, s_vidya_size); s_vidya_data[idx].key = g_indicator_cache_key; s_vidya_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_vidya_data[idx].ref_count++; //--- Retornamos puntero return s_vidya[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiBands* CIndicatorCache::GetBands(ENUM_TIMEFRAMES timeframe, string symbol, int bands_period, int bands_shift, double deviation, ENUM_APPLIED_PRICE applied_price, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "BANDS_" + symbol + "_" + string(int(timeframe)) + "_" + string(bands_period) + "_" + string(bands_shift) + "_" + DoubleToString(deviation, INDICATOR_CACHE_DBL_DIG) + "_" + string(int(applied_price)) + "_" + string(int(series)); //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_bands_size; //--- Array ArrayResize(s_bands, ++s_bands_size); s_bands[idx] = new CiBands(); if(!s_bands[idx].Create(timeframe, symbol, bands_period, bands_shift, deviation, applied_price, series, hide)) { delete s_bands[idx]; s_bands_size--; ArrayResize(s_bands, s_bands_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_bands_data, s_bands_size); s_bands_data[idx].key = g_indicator_cache_key; s_bands_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_bands_data[idx].ref_count++; //--- Retornamos puntero return s_bands[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiSuperTrend* CIndicatorCache::GetSuperTrend(ENUM_TIMEFRAMES timeframe, string symbol, int cci_period, ENUM_APPLIED_PRICE applied, int atr_period, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "SUPERTREND_" + symbol + "_" + string(int(timeframe)) + "_" + string(cci_period) + "_" + string(int(applied)) + "_" + string(atr_period) + "_" + string(int(series)); //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_supertrend_size; //--- Array ArrayResize(s_supertrend, ++s_supertrend_size); s_supertrend[idx] = new CiSuperTrend(); if(!s_supertrend[idx].Create(timeframe, symbol, series, hide, cci_period, applied, atr_period)) { delete s_supertrend[idx]; s_supertrend_size--; ArrayResize(s_supertrend, s_supertrend_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_supertrend_data, s_supertrend_size); s_supertrend_data[idx].key = g_indicator_cache_key; s_supertrend_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_supertrend_data[idx].ref_count++; //--- Retornamos puntero return s_supertrend[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiVwapChange* CIndicatorCache::GetVwap(ENUM_TIMEFRAMES timeframe, string symbol, VWAP_Period period, ENUM_APPLIED_PRICE applied, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "VWAP_" + symbol + "_" + string(int(timeframe)) + "_" + string(int(period)) + "_" + string(int(applied)) + "_" + string(int(series)); //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_vwap_size; //--- Array ArrayResize(s_vwap, ++s_vwap_size); s_vwap[idx] = new CiVwapChange(); if(!s_vwap[idx].Create(timeframe, symbol, period, applied, series, hide)) { delete s_vwap[idx]; s_vwap_size--; ArrayResize(s_vwap, s_vwap_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_vwap_data, s_vwap_size); s_vwap_data[idx].key = g_indicator_cache_key; s_vwap_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_vwap_data[idx].ref_count++; //--- Retornamos puntero return s_vwap[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiAD* CIndicatorCache::GetAD(ENUM_TIMEFRAMES timeframe, string symbol, ENUM_APPLIED_VOLUME applied, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "AD_" + symbol + "_" + string(int(timeframe)) + "_" + string(int(applied)) + "_" + string(int(series)) ; //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_ad_size; //--- Array ArrayResize(s_ad, ++s_ad_size); s_ad[idx] = new CiAD(); if(!s_ad[idx].Create(timeframe, symbol, applied, series, hide)) { delete s_ad[idx]; s_ad_size--; ArrayResize(s_ad, s_ad_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_ad_data, s_ad_size); s_ad_data[idx].key = g_indicator_cache_key; s_ad_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_ad_data[idx].ref_count++; //--- Retornamos puntero return s_ad[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiObv* CIndicatorCache::GetObv(ENUM_TIMEFRAMES timeframe, string symbol, ENUM_APPLIED_VOLUME applied, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "OBV_" + symbol + "_" + string(int(timeframe)) + "_" + string(int(applied)) + "_" + string(int(series)) ; //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_obv_size; //--- Array ArrayResize(s_obv, ++s_obv_size); s_obv[idx] = new CiObv(); if(!s_obv[idx].Create(timeframe, symbol, applied, series, hide)) { delete s_obv[idx]; s_obv_size--; ArrayResize(s_obv, s_obv_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_obv_data, s_obv_size); s_obv_data[idx].key = g_indicator_cache_key; s_obv_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_obv_data[idx].ref_count++; //--- Retornamos puntero return s_obv[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiStandartDeviation* CIndicatorCache::GetStdDev(ENUM_TIMEFRAMES timeframe, string symbol, int ma_period, int ma_shift, ENUM_MA_METHOD ma_method, ENUM_APPLIED_PRICE applied, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "STDDEV_" + symbol + "_" + string(int(timeframe)) + "_" + string(ma_period) + "_" + string(ma_shift) + "_" + string(int(ma_method)) + "_" + string(int(applied)) + "_" + string(int(series)) ; //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_stddev_size; //--- Array ArrayResize(s_stddev, ++s_stddev_size); s_stddev[idx] = new CiStandartDeviation(); if(!s_stddev[idx].Create(timeframe, symbol, ma_period, ma_shift, ma_method, applied, series, hide)) { delete s_stddev[idx]; s_stddev_size--; ArrayResize(s_stddev, s_stddev_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_stddev_data, s_stddev_size); s_stddev_data[idx].key = g_indicator_cache_key; s_stddev_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_stddev_data[idx].ref_count++; //--- Retornamos puntero return s_stddev[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiSar* CIndicatorCache::GetSar(ENUM_TIMEFRAMES timeframe, string symbol, double step, double maximum, bool series, bool hide) { //--- Normalizamos timeframe if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- Key g_indicator_cache_key = "SAR_" + symbol + "_" + string(int(timeframe)) + "_" + DoubleToString(step, INDICATOR_CACHE_DBL_DIG) + "_" + DoubleToString(maximum, INDICATOR_CACHE_DBL_DIG) + "_" + string(int(series)) ; //--- Verificamos si existe en caso no existe lo creamos int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { idx = s_sar_size; //--- Array ArrayResize(s_sar, ++s_sar_size); s_sar[idx] = new CiSar(); if(!s_sar[idx].Create(timeframe, symbol, step, maximum, series, hide)) { delete s_sar[idx]; s_sar_size--; ArrayResize(s_sar, s_sar_size); return NULL; } //--- Hashmap s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- Extra data ArrayResize(s_sar_data, s_sar_size); s_sar_data[idx].key = g_indicator_cache_key; s_sar_data[idx].ref_count = 0; } //--- Nueva referencia creada a esta configuracion s_sar_data[idx].ref_count++; //--- Retornamos puntero return s_sar[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiAdx* CIndicatorCache::GetAdx(ENUM_TIMEFRAMES timeframe, string symbol, int ma_period, bool series, bool hide) { //--- if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- g_indicator_cache_key = "ADX_" + symbol + "_" + string(int(timeframe)) + "_" + string(ma_period) + "_" + string(int(series)) ; //--- int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { //--- idx = s_adx_size; //--- ArrayResize(s_adx, ++s_adx_size); s_adx[idx] = new CiAdx(); //--- if(!s_adx[idx].Create(timeframe, symbol, ma_period, series, hide)) { delete s_adx[idx]; s_adx_size--; ArrayResize(s_adx, s_adx_size); return NULL; } //--- s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- ArrayResize(s_adx_data, s_adx_size); s_adx_data[idx].key = g_indicator_cache_key; s_adx_data[idx].ref_count = 0; } //--- s_adx_data[idx].ref_count++; //--- return s_adx[idx]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static CiAdxWilder* CIndicatorCache::GetAdxWilder(ENUM_TIMEFRAMES timeframe, string symbol, int ma_period, bool series, bool hide) { //--- if(timeframe == PERIOD_CURRENT) timeframe = _Period; //--- g_indicator_cache_key = "ADXWILDER_" + symbol + "_" + string(int(timeframe)) + "_" + string(ma_period) + "_" + string(int(series)) ; //--- int idx = -1; if(!s_hash_str_to_int.TryGetValue(g_indicator_cache_key, idx)) { //--- idx = s_adx_wilder_size; //--- ArrayResize(s_adx_wilder, ++s_adx_wilder_size); s_adx_wilder[idx] = new CiAdxWilder(); if(!s_adx_wilder[idx].Create(timeframe, symbol, ma_period, series, hide)) { delete s_adx_wilder[idx]; s_adx_wilder_size--; ArrayResize(s_adx_wilder, s_adx_wilder_size); return NULL; } //--- s_hash_str_to_int.Add(g_indicator_cache_key, idx); //--- ArrayResize(s_adx_wilder_data, s_adx_wilder_size); s_adx_wilder_data[idx].key = g_indicator_cache_key; s_adx_wilder_data[idx].ref_count = 0; } //--- s_adx_wilder_data[idx].ref_count++; //--- return s_adx_wilder[idx]; } //+------------------------------------------------------------------+ //| Deinit | //+------------------------------------------------------------------+ static void CIndicatorCache::Deinit(const int reason) { //--- if(!s_is_active) return; //--- if(CheckPointer(s_hash_str_to_int) == POINTER_DYNAMIC) delete s_hash_str_to_int; //--- RSI if(s_rsi_size) { for(int i = 0; i < s_rsi_size; i++) if(CheckPointer(s_rsi[i]) == POINTER_DYNAMIC) delete s_rsi[i]; s_rsi_size = ArrayResize(s_rsi, 0); ArrayResize(s_rsi_data, 0); } //--- MA if(s_ma_size) { for(int i = 0; i < s_ma_size; i++) if(CheckPointer(s_ma[i]) == POINTER_DYNAMIC) delete s_ma[i]; s_ma_size = ArrayResize(s_ma, 0); ArrayResize(s_ma_data, 0); } //--- CCI if(s_cci_size) { for(int i = 0; i < s_cci_size; i++) if(CheckPointer(s_cci[i]) == POINTER_DYNAMIC) delete s_cci[i]; s_cci_size = ArrayResize(s_cci, 0); ArrayResize(s_cci_data, 0); } //--- Stochastic if(s_stochastic_size) { for(int i = 0; i < s_stochastic_size; i++) if(CheckPointer(s_stochastic[i]) == POINTER_DYNAMIC) delete s_stochastic[i]; s_stochastic_size = ArrayResize(s_stochastic, 0); ArrayResize(s_stochastic_data, 0); } //--- VIDyA if(s_vidya_size) { for(int i = 0; i < s_vidya_size; i++) if(CheckPointer(s_vidya[i]) == POINTER_DYNAMIC) delete s_vidya[i]; s_vidya_size = ArrayResize(s_vidya, 0); ArrayResize(s_vidya_data, 0); } //--- Bollinger Bands if(s_bands_size) { for(int i = 0; i < s_bands_size; i++) if(CheckPointer(s_bands[i]) == POINTER_DYNAMIC) delete s_bands[i]; s_bands_size = ArrayResize(s_bands, 0); ArrayResize(s_bands_data, 0); } //--- SuperTrend if(s_supertrend_size) { for(int i = 0; i < s_supertrend_size; i++) if(CheckPointer(s_supertrend[i]) == POINTER_DYNAMIC) delete s_supertrend[i]; s_supertrend_size = ArrayResize(s_supertrend, 0); ArrayResize(s_supertrend_data, 0); } //--- VWAP if(s_vwap_size) { for(int i = 0; i < s_vwap_size; i++) if(CheckPointer(s_vwap[i]) == POINTER_DYNAMIC) delete s_vwap[i]; s_vwap_size = ArrayResize(s_vwap, 0); ArrayResize(s_vwap_data, 0); } //--- AD if(s_ad_size) { for(int i = 0; i < s_ad_size; i++) if(CheckPointer(s_ad[i]) == POINTER_DYNAMIC) delete s_ad[i]; s_ad_size = ArrayResize(s_ad, 0); ArrayResize(s_ad_data, 0); } //--- OBV if(s_obv_size) { for(int i = 0; i < s_obv_size; i++) if(CheckPointer(s_obv[i]) == POINTER_DYNAMIC) delete s_obv[i]; s_obv_size = ArrayResize(s_obv, 0); ArrayResize(s_obv_data, 0); } //--- Standard Deviation if(s_stddev_size) { for(int i = 0; i < s_stddev_size; i++) if(CheckPointer(s_stddev[i]) == POINTER_DYNAMIC) delete s_stddev[i]; s_stddev_size = ArrayResize(s_stddev, 0); ArrayResize(s_stddev_data, 0); } //--- SAR if(s_sar_size) { for(int i = 0; i < s_sar_size; i++) if(CheckPointer(s_sar[i]) == POINTER_DYNAMIC) delete s_sar[i]; s_sar_size = ArrayResize(s_sar, 0); ArrayResize(s_sar_data, 0); } //--- ADX if(s_adx_size) { for(int i = 0; i < s_adx_size; i++) if(CheckPointer(s_adx[i]) == POINTER_DYNAMIC) delete s_adx[i]; s_adx_size = ArrayResize(s_adx, 0); ArrayResize(s_adx_data, 0); } //--- ADX Wilder if(s_adx_wilder_size) { for(int i = 0; i < s_adx_wilder_size; i++) if(CheckPointer(s_adx_wilder[i]) == POINTER_DYNAMIC) delete s_adx_wilder[i]; s_adx_wilder_size = ArrayResize(s_adx_wilder, 0); ArrayResize(s_adx_wilder_data, 0); } //--- s_is_active = false; } //+------------------------------------------------------------------+ //| Inicializacion de variables estaticas | //+------------------------------------------------------------------+ CHashMap* CIndicatorCache::s_hash_str_to_int = NULL; bool CIndicatorCache::s_is_active = false; //--- RSI CiRsi* CIndicatorCache::s_rsi[] = {}; int CIndicatorCache::s_rsi_size = 0; IndicatorCacheExtraData CIndicatorCache::s_rsi_data[] = {}; //--- MA CiMa* CIndicatorCache::s_ma[] = {}; int CIndicatorCache::s_ma_size = 0; IndicatorCacheExtraData CIndicatorCache::s_ma_data[] = {}; //--- CCI CiCci* CIndicatorCache::s_cci[] = {}; int CIndicatorCache::s_cci_size = 0; IndicatorCacheExtraData CIndicatorCache::s_cci_data[] = {}; //--- Stochastic CiStocastic* CIndicatorCache::s_stochastic[] = {}; int CIndicatorCache::s_stochastic_size = 0; IndicatorCacheExtraData CIndicatorCache::s_stochastic_data[] = {}; //--- VIDyA CiVIDyA* CIndicatorCache::s_vidya[] = {}; int CIndicatorCache::s_vidya_size = 0; IndicatorCacheExtraData CIndicatorCache::s_vidya_data[] = {}; //--- Bollinger Bands CiBands* CIndicatorCache::s_bands[] = {}; int CIndicatorCache::s_bands_size = 0; IndicatorCacheExtraData CIndicatorCache::s_bands_data[] = {}; //--- SuperTrend CiSuperTrend* CIndicatorCache::s_supertrend[] = {}; int CIndicatorCache::s_supertrend_size = 0; IndicatorCacheExtraData CIndicatorCache::s_supertrend_data[] = {}; //--- VWAP CiVwapChange* CIndicatorCache::s_vwap[] = {}; int CIndicatorCache::s_vwap_size = 0; IndicatorCacheExtraData CIndicatorCache::s_vwap_data[] = {}; //--- AD CiAD* CIndicatorCache::s_ad[] = {}; int CIndicatorCache::s_ad_size = 0; IndicatorCacheExtraData CIndicatorCache::s_ad_data[] = {}; //--- OBV CiObv* CIndicatorCache::s_obv[] = {}; int CIndicatorCache::s_obv_size = 0; IndicatorCacheExtraData CIndicatorCache::s_obv_data[] = {}; //--- Standard Deviation CiStandartDeviation* CIndicatorCache::s_stddev[] = {}; int CIndicatorCache::s_stddev_size = 0; IndicatorCacheExtraData CIndicatorCache::s_stddev_data[] = {}; //--- SAR CiSar* CIndicatorCache::s_sar[] = {}; int CIndicatorCache::s_sar_size = 0; IndicatorCacheExtraData CIndicatorCache::s_sar_data[] = {}; //--- ADX CiAdx* CIndicatorCache::s_adx[] = {}; int CIndicatorCache::s_adx_size = 0; IndicatorCacheExtraData CIndicatorCache::s_adx_data[] = {}; //--- ADX Wilder CiAdxWilder* CIndicatorCache::s_adx_wilder[] = {}; int CIndicatorCache::s_adx_wilder_size = 0; IndicatorCacheExtraData CIndicatorCache::s_adx_wilder_data[] = {}; //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ #endif // MQLARTICLES_INDICATORSCTS_POOL_MQH