diff --git a/Indicators/MyIndicators/AMA_TrendActivity_Pro.mq5 b/Indicators/MyIndicators/AMA_TrendActivity_Pro.mq5 index 730daf6..bc192c9 100644 --- a/Indicators/MyIndicators/AMA_TrendActivity_Pro.mq5 +++ b/Indicators/MyIndicators/AMA_TrendActivity_Pro.mq5 @@ -3,7 +3,7 @@ //| Copyright 2025, xxxxxxxx| //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" -#property version "2.10" // Optimized for incremental calculation +#property version "3.00" // Refactored to use Composition Pattern #property description "Measures the trend activity (slope) of an AMA line using Arctan normalization." #property description "Selectable price source (Standard or Heikin Ashi) for both AMA and ATR calculations." @@ -27,6 +27,7 @@ input int InpAmaPeriod = 10; input int InpFastEmaPeriod = 2; input int InpSlowEmaPeriod = 30; input ENUM_APPLIED_PRICE_HA_ALL InpSourcePrice = PRICE_CLOSE_STD; + input group "Activity Calculation Settings" input int InpAtrPeriod = 14; input int InpSmoothingPeriod = 5; @@ -34,7 +35,7 @@ input int InpSmoothingPeriod = 5; //--- Indicator Buffers --- double BufferActivity[]; -//--- Global calculator object (as a base class pointer) --- +//--- Global calculator object --- CActivityCalculator *g_calculator; //+------------------------------------------------------------------+ @@ -46,25 +47,25 @@ int OnInit() SetIndexBuffer(0, BufferActivity, INDICATOR_DATA); ArraySetAsSeries(BufferActivity, false); -//--- Dynamically create the appropriate calculator instance - if(InpSourcePrice <= PRICE_HA_CLOSE) // Heikin Ashi source selected - { - g_calculator = new CActivityCalculator_HA(); - IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("AMA Activity HA(%d,%d,%d)", InpAmaPeriod, InpAtrPeriod, InpSmoothingPeriod)); - } - else // Standard price source selected - { - g_calculator = new CActivityCalculator(); - IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("AMA Activity(%d,%d,%d)", InpAmaPeriod, InpAtrPeriod, InpSmoothingPeriod)); - } +//--- Create the calculator instance + g_calculator = new CActivityCalculator(); -//--- Check if creation was successful and initialize - if(CheckPointer(g_calculator) == POINTER_INVALID || !g_calculator.Init(InpAmaPeriod, InpFastEmaPeriod, InpSlowEmaPeriod, InpAtrPeriod, InpSmoothingPeriod)) +//--- Determine if Heikin Ashi is needed + bool use_ha = (InpSourcePrice <= PRICE_HA_CLOSE); + +//--- Initialize the calculator +//--- Note: We pass 'use_ha' here, and the calculator handles the sub-engines internally. + if(CheckPointer(g_calculator) == POINTER_INVALID || + !g_calculator.Init(InpAmaPeriod, InpFastEmaPeriod, InpSlowEmaPeriod, InpAtrPeriod, InpSmoothingPeriod, use_ha)) { Print("Failed to create or initialize Activity Calculator object."); return(INIT_FAILED); } +//--- Set Short Name + string type = use_ha ? " HA" : ""; + IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("AMA Activity%s(%d,%d,%d)", type, InpAmaPeriod, InpAtrPeriod, InpSmoothingPeriod)); + //--- Set indicator display properties int draw_begin = InpAmaPeriod + InpAtrPeriod + InpSmoothingPeriod; PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, draw_begin); @@ -99,16 +100,18 @@ int OnCalculate(const int rates_total, const long &volume[], const int &spread[]) { +//--- Ensure the calculator object is valid if(CheckPointer(g_calculator) == POINTER_INVALID) return 0; +//--- Convert our custom enum to the standard ENUM_APPLIED_PRICE ENUM_APPLIED_PRICE price_type; if(InpSourcePrice <= PRICE_HA_CLOSE) price_type = (ENUM_APPLIED_PRICE)(-(int)InpSourcePrice); else price_type = (ENUM_APPLIED_PRICE)InpSourcePrice; -//--- Delegate calculation with prev_calculated optimization +//--- Delegate the calculation with incremental optimization g_calculator.Calculate(rates_total, prev_calculated, open, high, low, close, price_type, BufferActivity); return(rates_total);