diff --git a/Indicators/MyIndicators/Authors/Kaufman/KAMA_Pro.mq5 b/Indicators/MyIndicators/Authors/Kaufman/KAMA_Pro.mq5 index 5b08e5e..b1d7355 100644 --- a/Indicators/MyIndicators/Authors/Kaufman/KAMA_Pro.mq5 +++ b/Indicators/MyIndicators/Authors/Kaufman/KAMA_Pro.mq5 @@ -1,15 +1,16 @@ //+------------------------------------------------------------------+ -//| KAMA_Pro.mq5| -//| Copyright 2025, xxxxxxxx| +//| KAMA_Pro.mq5 | +//| Copyright 2026, xxxxxxxx| //+------------------------------------------------------------------+ -#property copyright "Copyright 2025, xxxxxxxx" -#property version "2.10" // Optimized for incremental calculation +#property copyright "Copyright 2026, xxxxxxxx" +#property version "3.10" // Optimized Single-Line KAMA #property description "Perry Kaufman's Adaptive Moving Average (KAMA)." -#property description "Adapts its speed based on market volatility." #property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 + +//--- Plot Definition #property indicator_label1 "KAMA" #property indicator_type1 DRAW_LINE #property indicator_color1 clrCrimson @@ -19,54 +20,72 @@ #include //--- Input Parameters --- -input int InpErPeriod = 10; // Efficiency Ratio Period -input int InpFastEmaPeriod = 2; // Fastest EMA Period -input int InpSlowEmaPeriod = 30; // Slowest EMA Period -input ENUM_APPLIED_PRICE_HA_ALL InpSourcePrice = PRICE_CLOSE_STD; +input group "KAMA Core Settings" +input int InpErPeriod = 10; // Efficiency Ratio Period +input int InpFastEmaPeriod = 2; // Fastest EMA Period +input int InpSlowEmaPeriod = 30; // Slowest EMA Period +input ENUM_APPLIED_PRICE_HA_ALL InpSourcePrice = PRICE_CLOSE_STD; // Price Source (Standard / HA) + +input group "Visual Settings" +input color InpColorKAMA = clrCrimson; // Line Color +input ENUM_LINE_STYLE InpStyleKAMA = STYLE_SOLID; // Line Style +input int InpWidthKAMA = 2; // Line Width //--- Indicator Buffers --- -double BufferKAMA[]; +double BufferKAMA[]; -//--- Global calculator object --- -CKamaCalculator *g_calculator; +//--- Global Calculator Object --- +CKamaCalculator *g_calculator = NULL; +//+------------------------------------------------------------------+ +//| OnInit | //+------------------------------------------------------------------+ int OnInit() { - SetIndexBuffer(0, BufferKAMA, INDICATOR_DATA); - ArraySetAsSeries(BufferKAMA, false); - - if(InpSourcePrice <= PRICE_HA_CLOSE) - { - g_calculator = new CKamaCalculator_HA(); - IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("KAMA HA(%d,%d,%d)", InpErPeriod, InpFastEmaPeriod, InpSlowEmaPeriod)); - } - else - { - g_calculator = new CKamaCalculator(); - IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("KAMA(%d,%d,%d)", InpErPeriod, InpFastEmaPeriod, InpSlowEmaPeriod)); - } - - if(CheckPointer(g_calculator) == POINTER_INVALID || !g_calculator.Init(InpErPeriod, InpFastEmaPeriod, InpSlowEmaPeriod)) - { - Print("Failed to initialize KAMA Calculator."); - return(INIT_FAILED); - } + SetIndexBuffer(0, BufferKAMA, INDICATOR_DATA); + ArraySetAsSeries(BufferKAMA, false); + ArrayInitialize(BufferKAMA, EMPTY_VALUE); +// Configure Visuals + PlotIndexSetInteger(0, PLOT_LINE_COLOR, InpColorKAMA); + PlotIndexSetInteger(0, PLOT_LINE_STYLE, InpStyleKAMA); + PlotIndexSetInteger(0, PLOT_LINE_WIDTH, InpWidthKAMA); PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, InpErPeriod); + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); +// Initialize Engine + g_calculator = new CKamaCalculator(); + if(CheckPointer(g_calculator) == POINTER_INVALID || !g_calculator.Init(InpErPeriod, InpFastEmaPeriod, InpSlowEmaPeriod, InpSourcePrice)) + { + Print("Error: Failed to initialize KAMA Calculator."); + return INIT_FAILED; + } + + string ha_tag = (InpSourcePrice <= PRICE_HA_CLOSE) ? " HA" : ""; + string short_name = StringFormat("KAMA%s(%d,%d,%d)", ha_tag, InpErPeriod, InpFastEmaPeriod, InpSlowEmaPeriod); + IndicatorSetString(INDICATOR_SHORTNAME, short_name); + return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ -void OnDeinit(const int reason) { if(CheckPointer(g_calculator) != POINTER_INVALID) delete g_calculator; } +//| OnDeinit | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { + if(CheckPointer(g_calculator) != POINTER_INVALID) + { + delete g_calculator; + g_calculator = NULL; + } + } //+------------------------------------------------------------------+ -//| Custom indicator calculation function | +//| OnCalculate | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, - const int prev_calculated, // <--- Now used! + const int prev_calculated, const datetime &time[], const double &open[], const double &high[], @@ -76,17 +95,18 @@ int OnCalculate(const int rates_total, const long &volume[], const int &spread[]) { - if(CheckPointer(g_calculator) == POINTER_INVALID) + if(rates_total <= InpErPeriod || CheckPointer(g_calculator) == POINTER_INVALID) return 0; - ENUM_APPLIED_PRICE price_type; - if(InpSourcePrice <= PRICE_HA_CLOSE) - price_type = (ENUM_APPLIED_PRICE)(-(int)InpSourcePrice); - else - price_type = (ENUM_APPLIED_PRICE)InpSourcePrice; +// Chronological Safety + ArraySetAsSeries(time, false); + ArraySetAsSeries(open, false); + ArraySetAsSeries(high, false); + ArraySetAsSeries(low, false); + ArraySetAsSeries(close, false); -//--- Delegate calculation with prev_calculated optimization - g_calculator.Calculate(rates_total, prev_calculated, price_type, open, high, low, close, BufferKAMA); +// High-Performance Incremental O(1) Calculation + g_calculator.Calculate(rates_total, prev_calculated, open, high, low, close, BufferKAMA); return(rates_total); }