diff --git a/Indicators/MyIndicators/Chart_HeikinAshi.mq5 b/Indicators/MyIndicators/Chart_HeikinAshi.mq5 index 7896fe6..eb78f07 100644 --- a/Indicators/MyIndicators/Chart_HeikinAshi.mq5 +++ b/Indicators/MyIndicators/Chart_HeikinAshi.mq5 @@ -3,66 +3,64 @@ //| Copyright 2025, xxxxxxxx | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, xxxxxxxx" -#property link "" -#property version "3.01" // Added DRAW_NONE plot to hide main series and prevent flickering +#property version "3.05" // Refactored to strict 10-param calculation #property description "Draws Heikin Ashi candles on the main chart." -//--- Custom Toolkit Include --- +//--- Include the strict, optimized toolkit #include -//--- Indicator Window and Plot Properties --- #property indicator_chart_window -#property indicator_buffers 8 // 4 for HA candles, 4 for the hidden main series -#property indicator_plots 2 // 1 for HA candles, 1 hidden plot +#property indicator_buffers 9 // 4 HA + 1 Color + 4 Hidden +#property indicator_plots 2 -//--- Plot 1: Heikin Ashi Candles (Visible) +//--- Plot 1: Heikin Ashi Candles #property indicator_type1 DRAW_COLOR_CANDLES -#property indicator_color1 clrCornflowerBlue, clrChocolate // Up and Down colors +#property indicator_color1 clrCornflowerBlue, clrChocolate #property indicator_label1 "HA Open;HA High;HA Low;HA Close" +#property indicator_width1 1 //--- Plot 2: Main Price Series (Hidden) +//--- Used to keep the chart scaled correctly to the real price, even if HA differs slightly #property indicator_type2 DRAW_NONE -#property indicator_label2 "OHLC" // Label for Data Window +#property indicator_label2 "OHLC" -//--- Indicator Buffers --- -// Buffers for Heikin Ashi +//--- Buffers double BufferHA_Open[]; double BufferHA_High[]; double BufferHA_Low[]; double BufferHA_Close[]; double BufferColor[]; -// Buffers for the hidden main series plot double BufferMain_Open[]; double BufferMain_High[]; double BufferMain_Low[]; double BufferMain_Close[]; - -//--- Global Objects --- +//--- Global Calculator CHeikinAshi_Calculator *g_ha_calculator; //+------------------------------------------------------------------+ -//| Custom indicator initialization function. | +//| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { -//--- Map the Heikin Ashi buffers +//--- Map HA Buffers SetIndexBuffer(0, BufferHA_Open, INDICATOR_DATA); SetIndexBuffer(1, BufferHA_High, INDICATOR_DATA); SetIndexBuffer(2, BufferHA_Low, INDICATOR_DATA); SetIndexBuffer(3, BufferHA_Close, INDICATOR_DATA); SetIndexBuffer(4, BufferColor, INDICATOR_COLOR_INDEX); - PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 1); // Start drawing HA from the second bar -//--- Map the hidden main series buffers +//--- Map Hidden Buffers SetIndexBuffer(5, BufferMain_Open, INDICATOR_DATA); SetIndexBuffer(6, BufferMain_High, INDICATOR_DATA); SetIndexBuffer(7, BufferMain_Low, INDICATOR_DATA); SetIndexBuffer(8, BufferMain_Close, INDICATOR_DATA); -// No PLOT_DRAW_BEGIN needed for DRAW_NONE -//--- Set all buffers to non-timeseries for stable calculation +//--- Drawing settings + PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 1); + +//--- CRITICAL: Set all arrays as non-timeseries for standard 0..total indexing ArraySetAsSeries(BufferHA_Open, false); ArraySetAsSeries(BufferHA_High, false); ArraySetAsSeries(BufferHA_Low, false); @@ -73,35 +71,29 @@ int OnInit() ArraySetAsSeries(BufferMain_Low, false); ArraySetAsSeries(BufferMain_Close, false); -//--- Set indicator properties +//--- Indicator Info IndicatorSetInteger(INDICATOR_DIGITS, _Digits); - IndicatorSetString(INDICATOR_SHORTNAME, "Heikin Ashi"); + IndicatorSetString(INDICATOR_SHORTNAME, "Heikin Ashi Pro"); -//--- Create the calculator instance +//--- Initialize Calculator g_ha_calculator = new CHeikinAshi_Calculator(); if(CheckPointer(g_ha_calculator) == POINTER_INVALID) - { - Print("Error creating CHeikinAshi_Calculator object"); return(INIT_FAILED); - } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ -//| Custom indicator deinitialization function. | +//| Deinitialization | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(CheckPointer(g_ha_calculator) != POINTER_INVALID) - { delete g_ha_calculator; - g_ha_calculator = NULL; - } } //+------------------------------------------------------------------+ -//| Heikin Ashi calculation function. | +//| Iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, @@ -117,26 +109,45 @@ int OnCalculate(const int rates_total, if(rates_total < 2) return(0); -//--- STEP 1: Hide the main series by copying data to the DRAW_NONE plot - ArrayCopy(BufferMain_Open, open, 0, 0, rates_total); - ArrayCopy(BufferMain_High, high, 0, 0, rates_total); - ArrayCopy(BufferMain_Low, low, 0, 0, rates_total); - ArrayCopy(BufferMain_Close, close, 0, 0, rates_total); +//--- 1. Determine Start Index (Optimization Logic) + int start_index; -//--- STEP 2: Calculate Heikin Ashi bars - g_ha_calculator.Calculate(rates_total, open, high, low, close, - BufferHA_Open, BufferHA_High, BufferHA_Low, BufferHA_Close); - -//--- STEP 3: Set the colors for the Heikin Ashi candles - for(int i = 0; i < rates_total; i++) + if(prev_calculated == 0) { - if(BufferHA_Open[i] < BufferHA_Close[i]) - BufferColor[i] = 0; // Index for the first color (clrCornflowerBlue) - else - BufferColor[i] = 1; // Index for the second color (clrChocolate) + start_index = 0; + } + else + { + // Start from the last calculated bar to update it as it forms + start_index = prev_calculated - 1; } +//--- 2. Copy Hidden Data (Optimized Loop) +//--- Instead of ArrayCopy for the whole history, we only update the new bars + for(int i = start_index; i < rates_total; i++) + { + BufferMain_Open[i] = open[i]; + BufferMain_High[i] = high[i]; + BufferMain_Low[i] = low[i]; + BufferMain_Close[i] = close[i]; + } + +//--- 3. Calculate Heikin Ashi (Strict 10-Parameter Call) +//--- We explicitly pass 'start_index' to comply with the new tool signature + g_ha_calculator.Calculate(rates_total, start_index, open, high, low, close, + BufferHA_Open, BufferHA_High, BufferHA_Low, BufferHA_Close); + +//--- 4. Update Colors (Optimized Loop) + for(int i = start_index; i < rates_total; i++) + { + // Simple logic: Bullish if Close > Open + if(BufferHA_Close[i] > BufferHA_Open[i]) + BufferColor[i] = 0; // Bullish Color (clrCornflowerBlue) + else + BufferColor[i] = 1; // Bearish Color (clrChocolate) + } + +//--- Return new rates_total for the next call return(rates_total); } //+------------------------------------------------------------------+ -//+------------------------------------------------------------------+