mirror of
https://github.com/softwaredevelop/mql5.git
synced 2026-07-27 20:47:44 +00:00
refactor:
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -1,103 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Chart_HeikenAshi.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "2.00" // Refactored to use HA_Tools.mqh
|
||||
#property description "Draws Heiken Ashi candles on the main chart."
|
||||
|
||||
//--- Custom Toolkit Include ---
|
||||
#include <MyIncludes\HA_Tools.mqh>
|
||||
|
||||
//--- Indicator Window and Plot Properties ---
|
||||
#property indicator_chart_window // Draw on the main chart window
|
||||
#property indicator_buffers 5 // 4 for OHLC, 1 for color
|
||||
#property indicator_plots 1
|
||||
|
||||
//--- Plot 1: Heiken Ashi Candles
|
||||
#property indicator_type1 DRAW_COLOR_CANDLES
|
||||
#property indicator_color1 clrDodgerBlue, clrMaroon // Up and Down colors
|
||||
#property indicator_label1 "HA Open;HA High;HA Low;HA Close" // Labels for Data Window
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferHA_Open[];
|
||||
double BufferHA_High[];
|
||||
double BufferHA_Low[];
|
||||
double BufferHA_Close[];
|
||||
double BufferColor[]; // Buffer for candle colors
|
||||
|
||||
//--- Global Objects ---
|
||||
CHA_Calculator g_ha_calculator; // Global instance of our Heiken Ashi calculator
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//| Called once when the indicator is first loaded. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- Map the buffers to the indicator's internal memory
|
||||
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);
|
||||
|
||||
//--- Set indicator properties
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits); // Use the same precision as the symbol
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Heiken Ashi");
|
||||
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0); // Define the empty value for the plot
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Heiken Ashi calculation function. |
|
||||
//| Called on every new tick or new bar. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//--- Check if there is enough historical data
|
||||
if(rates_total < 2)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Calculate Heiken Ashi bars using our toolkit
|
||||
// We use a full recalculation (prev_calculated=0) for maximum stability
|
||||
if(!g_ha_calculator.Calculate(rates_total, 0, open, high, low, close))
|
||||
{
|
||||
Print("Heiken Ashi calculation failed in OnCalculate.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
//--- STEP 2: Copy data from the calculator and set colors
|
||||
// The main loop iterates through all bars to ensure data consistency
|
||||
for(int i = 0; i < rates_total; i++)
|
||||
{
|
||||
// Copy the calculated HA values from our toolkit to the indicator's buffers
|
||||
BufferHA_Open[i] = g_ha_calculator.ha_open[i];
|
||||
BufferHA_High[i] = g_ha_calculator.ha_high[i];
|
||||
BufferHA_Low[i] = g_ha_calculator.ha_low[i];
|
||||
BufferHA_Close[i] = g_ha_calculator.ha_close[i];
|
||||
|
||||
//--- Set the color for the current candle
|
||||
// Color index 0 (clrDodgerBlue) for bullish candles
|
||||
// Color index 1 (clrMaroon) for bearish candles
|
||||
if(BufferHA_Open[i] < BufferHA_Close[i])
|
||||
BufferColor[i] = 0.0; // Bullish
|
||||
else
|
||||
BufferColor[i] = 1.0; // Bearish
|
||||
}
|
||||
|
||||
//--- Return value of prev_calculated for the next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,177 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| CutlerRSI_MA_HeikenAshi.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property description "Cutler's RSI (SMA-based) on Heiken Ashi data, with a signal line."
|
||||
|
||||
#include <MovingAverages.mqh>
|
||||
#include <MyIncludes\HA_Tools.mqh>
|
||||
|
||||
//--- Indicator Window and Level Properties ---
|
||||
#property indicator_separate_window
|
||||
#property indicator_minimum 0
|
||||
#property indicator_maximum 100
|
||||
#property indicator_level1 30.0
|
||||
#property indicator_level2 50.0
|
||||
#property indicator_level3 70.0
|
||||
|
||||
//--- Buffers and Plots ---
|
||||
#property indicator_buffers 4 // CutlerRSI_MA, CutlerRSI, Pos, Neg
|
||||
#property indicator_plots 2
|
||||
|
||||
//--- Plot 1: MA line (smoothed)
|
||||
#property indicator_label1 "MA"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrRed
|
||||
#property indicator_style1 STYLE_DOT
|
||||
#property indicator_width1 1
|
||||
|
||||
//--- Plot 2: Cutler's RSI line (raw)
|
||||
#property indicator_label2 "HA_CutlerRSI"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrDodgerBlue
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpPeriodRSI = 14; // RSI Period
|
||||
input group "Signal Line Settings"
|
||||
input int InpPeriodMA = 14; // MA Period
|
||||
input ENUM_MA_METHOD InpMethodMA = MODE_SMA; // MA Method
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferCutlerRSI_MA[];
|
||||
double BufferCutlerRSI[];
|
||||
double BufferAvgPos[];
|
||||
double BufferAvgNeg[];
|
||||
|
||||
//--- Global Objects and Variables ---
|
||||
int ExtPeriodRSI;
|
||||
int ExtPeriodMA;
|
||||
CHA_Calculator g_ha_calculator;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
ExtPeriodRSI = (InpPeriodRSI < 1) ? 1 : InpPeriodRSI;
|
||||
ExtPeriodMA = (InpPeriodMA < 1) ? 1 : InpPeriodMA;
|
||||
|
||||
SetIndexBuffer(0, BufferCutlerRSI_MA, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferCutlerRSI, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, BufferAvgPos, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(3, BufferAvgNeg, INDICATOR_CALCULATIONS);
|
||||
|
||||
ArraySetAsSeries(BufferCutlerRSI_MA, false);
|
||||
ArraySetAsSeries(BufferCutlerRSI, false);
|
||||
ArraySetAsSeries(BufferAvgPos, false);
|
||||
ArraySetAsSeries(BufferAvgNeg, false);
|
||||
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtPeriodRSI + ExtPeriodMA - 2);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, ExtPeriodRSI);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_CutlerRSI(%d,%d)", ExtPeriodRSI, ExtPeriodMA));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Cutler's RSI on Heiken Ashi calculation function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
if(rates_total < ExtPeriodRSI)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Calculate Heiken Ashi bars
|
||||
if(!g_ha_calculator.Calculate(rates_total, 0, open, high, low, close))
|
||||
return(0);
|
||||
|
||||
//--- Create temporary buffers for raw changes
|
||||
double pos_changes[], neg_changes[];
|
||||
ArrayResize(pos_changes, rates_total);
|
||||
ArrayResize(neg_changes, rates_total);
|
||||
|
||||
//--- STEP 2: Calculate and separate price changes based on HA Close
|
||||
for(int i = 1; i < rates_total; i++)
|
||||
{
|
||||
double diff = g_ha_calculator.ha_close[i] - g_ha_calculator.ha_close[i-1];
|
||||
pos_changes[i] = (diff > 0) ? diff : 0;
|
||||
neg_changes[i] = (diff < 0) ? -diff : 0;
|
||||
}
|
||||
|
||||
//--- STEP 3: Smooth changes with SMA
|
||||
for(int i = ExtPeriodRSI; i < rates_total; i++)
|
||||
{
|
||||
BufferAvgPos[i] = SimpleMA(i, ExtPeriodRSI, pos_changes);
|
||||
BufferAvgNeg[i] = SimpleMA(i, ExtPeriodRSI, neg_changes);
|
||||
}
|
||||
|
||||
//--- STEP 4: Calculate final Cutler's RSI value
|
||||
for(int i = ExtPeriodRSI; i < rates_total; i++)
|
||||
{
|
||||
if(BufferAvgNeg[i] > 0)
|
||||
{
|
||||
double rs = BufferAvgPos[i] / BufferAvgNeg[i];
|
||||
BufferCutlerRSI[i] = 100.0 - (100.0 / (1.0 + rs));
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferCutlerRSI[i] = 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
//--- STEP 5: Calculate the signal line (MA of Cutler's RSI)
|
||||
if(rates_total < ExtPeriodRSI + ExtPeriodMA)
|
||||
return(rates_total);
|
||||
|
||||
for(int i = 1; i < rates_total; i++)
|
||||
{
|
||||
if(i < ExtPeriodRSI + ExtPeriodMA - 2)
|
||||
{
|
||||
BufferCutlerRSI_MA[i] = EMPTY_VALUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(InpMethodMA)
|
||||
{
|
||||
case MODE_EMA:
|
||||
if(i == ExtPeriodRSI + ExtPeriodMA - 2)
|
||||
BufferCutlerRSI_MA[i] = SimpleMA(i, ExtPeriodMA, BufferCutlerRSI);
|
||||
else
|
||||
{
|
||||
double pr = 2.0 / (ExtPeriodMA + 1.0);
|
||||
BufferCutlerRSI_MA[i] = BufferCutlerRSI[i] * pr + BufferCutlerRSI_MA[i-1] * (1.0 - pr);
|
||||
}
|
||||
break;
|
||||
case MODE_SMMA:
|
||||
if(i == ExtPeriodRSI + ExtPeriodMA - 2)
|
||||
BufferCutlerRSI_MA[i] = SimpleMA(i, ExtPeriodMA, BufferCutlerRSI);
|
||||
else
|
||||
BufferCutlerRSI_MA[i] = (BufferCutlerRSI_MA[i-1] * (ExtPeriodMA - 1) + BufferCutlerRSI[i]) / ExtPeriodMA;
|
||||
break;
|
||||
case MODE_LWMA:
|
||||
BufferCutlerRSI_MA[i] = LinearWeightedMA(i, ExtPeriodMA, BufferCutlerRSI);
|
||||
break;
|
||||
default: // MODE_SMA
|
||||
BufferCutlerRSI_MA[i] = SimpleMA(i, ExtPeriodMA, BufferCutlerRSI);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,187 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| FisherTransform_HeikenAshi.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property description "Fisher Transform Oscillator on Heiken Ashi data"
|
||||
|
||||
//--- Custom Toolkit Include ---
|
||||
#include <MyIncludes\HA_Tools.mqh>
|
||||
|
||||
//--- Indicator Window and Level Properties ---
|
||||
#property indicator_separate_window
|
||||
#property indicator_level1 1.5
|
||||
#property indicator_level2 0.75
|
||||
#property indicator_level3 0.0
|
||||
#property indicator_level4 -0.75
|
||||
#property indicator_level5 -1.5
|
||||
#property indicator_levelstyle STYLE_DOT
|
||||
|
||||
//--- Buffers and Plots ---
|
||||
#property indicator_buffers 3 // Fisher, Trigger, and 1 calculation buffer
|
||||
#property indicator_plots 2
|
||||
|
||||
//--- Plot 1: Fisher line
|
||||
#property indicator_label1 "HA_Fisher"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBlue
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//--- Plot 2: Trigger line
|
||||
#property indicator_label2 "HA_Trigger"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrOrange
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpLength = 9; // Length
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferHA_Fisher[];
|
||||
double BufferHA_Trigger[];
|
||||
double BufferValue[]; // Calculation buffer for the intermediate 'value'
|
||||
|
||||
//--- Global Objects and Variables ---
|
||||
int ExtLength;
|
||||
CHA_Calculator g_ha_calculator;
|
||||
|
||||
//--- Forward declarations for helper functions ---
|
||||
double Highest(const double &array[], int period, int current_pos);
|
||||
double Lowest(const double &array[], int period, int current_pos);
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- Validate and store input
|
||||
ExtLength = (InpLength < 1) ? 1 : InpLength;
|
||||
|
||||
//--- Map the buffers
|
||||
SetIndexBuffer(0, BufferHA_Fisher, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferHA_Trigger, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, BufferValue, INDICATOR_CALCULATIONS);
|
||||
|
||||
//--- Set all buffers to non-timeseries for stable calculation
|
||||
ArraySetAsSeries(BufferHA_Fisher, false);
|
||||
ArraySetAsSeries(BufferHA_Trigger, false);
|
||||
ArraySetAsSeries(BufferValue, false);
|
||||
|
||||
//--- Set indicator properties
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, 4);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtLength);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, ExtLength + 1);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_Fisher(%d)", ExtLength));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fisher Transform on Heiken Ashi calculation function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//--- Check for enough data
|
||||
if(rates_total < ExtLength)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Calculate Heiken Ashi bars using our toolkit
|
||||
if(!g_ha_calculator.Calculate(rates_total, 0, open, high, low, close))
|
||||
return(0);
|
||||
|
||||
//--- STEP 2: Create a buffer for Heiken Ashi HL2 price
|
||||
double ha_hl2[];
|
||||
ArrayResize(ha_hl2, rates_total);
|
||||
for(int i=0; i<rates_total; i++)
|
||||
{
|
||||
ha_hl2[i] = (g_ha_calculator.ha_high[i] + g_ha_calculator.ha_low[i]) / 2.0;
|
||||
}
|
||||
|
||||
//--- STEP 3: Main calculation loop
|
||||
for(int i = 1; i < rates_total; i++)
|
||||
{
|
||||
if(i < ExtLength)
|
||||
{
|
||||
BufferValue[i] = 0;
|
||||
BufferHA_Fisher[i] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get Highest/Lowest of Heiken Ashi HL2
|
||||
double high_ = Highest(ha_hl2, ExtLength, i);
|
||||
double low_ = Lowest(ha_hl2, ExtLength, i);
|
||||
|
||||
double range = high_ - low_;
|
||||
if(range < _Point)
|
||||
range = _Point;
|
||||
|
||||
// Calculate the intermediate 'value'
|
||||
double price_pos = 0;
|
||||
if(range > 0)
|
||||
price_pos = (ha_hl2[i] - low_) / range - 0.5;
|
||||
|
||||
BufferValue[i] = 0.33 * 2 * price_pos + 0.67 * BufferValue[i-1];
|
||||
|
||||
if(BufferValue[i] > 0.999)
|
||||
BufferValue[i] = 0.999;
|
||||
if(BufferValue[i] < -0.999)
|
||||
BufferValue[i] = -0.999;
|
||||
|
||||
// Calculate the Fisher Transform value
|
||||
double log_val = 0.5 * MathLog((1 + BufferValue[i]) / (1 - BufferValue[i]));
|
||||
BufferHA_Fisher[i] = log_val + 0.5 * BufferHA_Fisher[i-1];
|
||||
|
||||
// The trigger is the previous Fisher value
|
||||
BufferHA_Trigger[i] = BufferHA_Fisher[i-1];
|
||||
}
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the highest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Highest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res < array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the lowest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Lowest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res > array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,160 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Gann_HiLo_HeikenAshi.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property description "Gann HiLo Activator on Heiken Ashi data with selectable MA"
|
||||
|
||||
#include <MovingAverages.mqh>
|
||||
#include <MyIncludes\HA_Tools.mqh>
|
||||
|
||||
//--- Indicator Window and Plot Properties ---
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 1
|
||||
|
||||
//--- Plot 1: Gann HiLo line
|
||||
#property indicator_label1 "HA_Gann_HiLo"
|
||||
#property indicator_type1 DRAW_COLOR_LINE
|
||||
#property indicator_color1 clrDodgerBlue, clrTomato
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 2
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpPeriod = 10; // Period for High/Low averages
|
||||
input ENUM_MA_METHOD InpMAMethod = MODE_SMA; // Method for High/Low averages
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferHA_GannHiLo[];
|
||||
double BufferColor[];
|
||||
double BufferHiAvg[];
|
||||
double BufferLoAvg[];
|
||||
double BufferTrend[];
|
||||
|
||||
//--- Global Objects and Variables ---
|
||||
int ExtPeriod;
|
||||
CHA_Calculator g_ha_calculator;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
ExtPeriod = (InpPeriod < 1) ? 1 : InpPeriod;
|
||||
|
||||
SetIndexBuffer(0, BufferHA_GannHiLo, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferColor, INDICATOR_COLOR_INDEX);
|
||||
SetIndexBuffer(2, BufferHiAvg, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(3, BufferLoAvg, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(4, BufferTrend, INDICATOR_CALCULATIONS);
|
||||
|
||||
ArraySetAsSeries(BufferHA_GannHiLo, false);
|
||||
ArraySetAsSeries(BufferColor, false);
|
||||
ArraySetAsSeries(BufferHiAvg, false);
|
||||
ArraySetAsSeries(BufferLoAvg, false);
|
||||
ArraySetAsSeries(BufferTrend, false);
|
||||
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtPeriod - 1);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_Gann_HiLo(%d)", ExtPeriod));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Gann HiLo on Heiken Ashi calculation function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
if(rates_total < ExtPeriod)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Calculate Heiken Ashi bars using our toolkit
|
||||
if(!g_ha_calculator.Calculate(rates_total, 0, open, high, low, close))
|
||||
return(0);
|
||||
|
||||
//--- STEP 2: Calculate the two moving averages on HA High and HA Low
|
||||
for(int i = 1; i < rates_total; i++)
|
||||
{
|
||||
if(i < ExtPeriod - 1)
|
||||
continue;
|
||||
|
||||
switch(InpMAMethod)
|
||||
{
|
||||
case MODE_EMA:
|
||||
if(i == ExtPeriod - 1)
|
||||
{
|
||||
BufferHiAvg[i] = SimpleMA(i, ExtPeriod, g_ha_calculator.ha_high);
|
||||
BufferLoAvg[i] = SimpleMA(i, ExtPeriod, g_ha_calculator.ha_low);
|
||||
}
|
||||
else
|
||||
{
|
||||
double pr = 2.0 / (ExtPeriod + 1.0);
|
||||
BufferHiAvg[i] = g_ha_calculator.ha_high[i] * pr + BufferHiAvg[i-1] * (1.0 - pr);
|
||||
BufferLoAvg[i] = g_ha_calculator.ha_low[i] * pr + BufferLoAvg[i-1] * (1.0 - pr);
|
||||
}
|
||||
break;
|
||||
case MODE_SMMA:
|
||||
if(i == ExtPeriod - 1)
|
||||
{
|
||||
BufferHiAvg[i] = SimpleMA(i, ExtPeriod, g_ha_calculator.ha_high);
|
||||
BufferLoAvg[i] = SimpleMA(i, ExtPeriod, g_ha_calculator.ha_low);
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferHiAvg[i] = (BufferHiAvg[i-1] * (ExtPeriod - 1) + g_ha_calculator.ha_high[i]) / ExtPeriod;
|
||||
BufferLoAvg[i] = (BufferLoAvg[i-1] * (ExtPeriod - 1) + g_ha_calculator.ha_low[i]) / ExtPeriod;
|
||||
}
|
||||
break;
|
||||
case MODE_LWMA:
|
||||
BufferHiAvg[i] = LinearWeightedMA(i, ExtPeriod, g_ha_calculator.ha_high);
|
||||
BufferLoAvg[i] = LinearWeightedMA(i, ExtPeriod, g_ha_calculator.ha_low);
|
||||
break;
|
||||
default: // MODE_SMA
|
||||
BufferHiAvg[i] = SimpleMA(i, ExtPeriod, g_ha_calculator.ha_high);
|
||||
BufferLoAvg[i] = SimpleMA(i, ExtPeriod, g_ha_calculator.ha_low);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//--- STEP 3 & 4: Determine trend and set the final Gann HiLo value
|
||||
for(int i = 1; i < rates_total; i++)
|
||||
{
|
||||
if(i < ExtPeriod -1)
|
||||
continue;
|
||||
|
||||
// Use HA Close to determine the trend
|
||||
if(g_ha_calculator.ha_close[i] > BufferHiAvg[i])
|
||||
BufferTrend[i] = 1; // Up trend
|
||||
else
|
||||
if(g_ha_calculator.ha_close[i] < BufferLoAvg[i])
|
||||
BufferTrend[i] = -1; // Down trend
|
||||
else
|
||||
BufferTrend[i] = BufferTrend[i-1];
|
||||
|
||||
if(BufferTrend[i] == 1)
|
||||
{
|
||||
BufferHA_GannHiLo[i] = BufferLoAvg[i];
|
||||
BufferColor[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferHA_GannHiLo[i] = BufferHiAvg[i];
|
||||
BufferColor[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,158 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| McGinleyDynamic_HeikenAshi.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.01" // Corrected array handling
|
||||
#property description "McGinley Dynamic Indicator on Heiken Ashi data"
|
||||
|
||||
#include <MovingAverages.mqh>
|
||||
#include <MyIncludes\HA_Tools.mqh>
|
||||
|
||||
//--- Indicator Window and Plot Properties ---
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 1
|
||||
#property indicator_plots 1
|
||||
|
||||
//--- Plot 1: McGinley Dynamic line
|
||||
#property indicator_label1 "HA_McGinley"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrCrimson
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 2
|
||||
|
||||
//--- Enum for selecting Heiken Ashi price source ---
|
||||
enum ENUM_HA_APPLIED_PRICE
|
||||
{
|
||||
HA_PRICE_CLOSE, // Heiken Ashi Close
|
||||
HA_PRICE_OPEN, // Heiken Ashi Open
|
||||
HA_PRICE_HIGH, // Heiken Ashi High
|
||||
HA_PRICE_LOW, // Heiken Ashi Low
|
||||
};
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpLength = 14;
|
||||
input ENUM_HA_APPLIED_PRICE InpAppliedPrice = HA_PRICE_CLOSE;
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferHA_McGinley[];
|
||||
|
||||
//--- Global Objects and Variables ---
|
||||
int ExtLength;
|
||||
CHA_Calculator g_ha_calculator;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
ExtLength = (InpLength < 1) ? 1 : InpLength;
|
||||
|
||||
SetIndexBuffer(0, BufferHA_McGinley, INDICATOR_DATA);
|
||||
ArraySetAsSeries(BufferHA_McGinley, false);
|
||||
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtLength);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_McGinley(%d)", ExtLength));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| McGinley Dynamic on Heiken Ashi calculation function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
if(rates_total < ExtLength)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Calculate Heiken Ashi bars using our toolkit
|
||||
if(!g_ha_calculator.Calculate(rates_total, 0, open, high, low, close))
|
||||
return(0);
|
||||
|
||||
//--- STEP 2: Main calculation loop
|
||||
for(int i = 1; i < rates_total; i++)
|
||||
{
|
||||
if(i < ExtLength)
|
||||
{
|
||||
BufferHA_McGinley[i] = EMPTY_VALUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Select the source price for the current bar 'i'
|
||||
double source_price = 0;
|
||||
switch(InpAppliedPrice)
|
||||
{
|
||||
case HA_PRICE_OPEN:
|
||||
source_price = g_ha_calculator.ha_open[i];
|
||||
break;
|
||||
case HA_PRICE_HIGH:
|
||||
source_price = g_ha_calculator.ha_high[i];
|
||||
break;
|
||||
case HA_PRICE_LOW:
|
||||
source_price = g_ha_calculator.ha_low[i];
|
||||
break;
|
||||
default:
|
||||
source_price = g_ha_calculator.ha_close[i];
|
||||
break;
|
||||
}
|
||||
|
||||
// --- Initialization Step ---
|
||||
if(i == ExtLength)
|
||||
{
|
||||
// The first McGinley value is an SMA of the source HA price
|
||||
// We need to create a temporary array for the SMA function
|
||||
double temp_price_array[];
|
||||
switch(InpAppliedPrice)
|
||||
{
|
||||
case HA_PRICE_OPEN:
|
||||
ArrayCopy(temp_price_array, g_ha_calculator.ha_open);
|
||||
break;
|
||||
case HA_PRICE_HIGH:
|
||||
ArrayCopy(temp_price_array, g_ha_calculator.ha_high);
|
||||
break;
|
||||
case HA_PRICE_LOW:
|
||||
ArrayCopy(temp_price_array, g_ha_calculator.ha_low);
|
||||
break;
|
||||
default:
|
||||
ArrayCopy(temp_price_array, g_ha_calculator.ha_close);
|
||||
break;
|
||||
}
|
||||
BufferHA_McGinley[i] = SimpleMA(i, ExtLength, temp_price_array);
|
||||
continue;
|
||||
}
|
||||
|
||||
// --- Recursive Calculation Step ---
|
||||
double prev_mg = BufferHA_McGinley[i-1];
|
||||
|
||||
if(prev_mg == 0)
|
||||
{
|
||||
BufferHA_McGinley[i] = source_price;
|
||||
continue;
|
||||
}
|
||||
|
||||
double ratio = source_price / prev_mg;
|
||||
double denominator = ExtLength * MathPow(ratio, 4);
|
||||
|
||||
if(denominator == 0)
|
||||
{
|
||||
BufferHA_McGinley[i] = prev_mg;
|
||||
continue;
|
||||
}
|
||||
|
||||
BufferHA_McGinley[i] = prev_mg + (source_price - prev_mg) / denominator;
|
||||
}
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -1,241 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SMI_HeikenAshi.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property description "Stochastic Momentum Index (SMI) on Heiken Ashi data"
|
||||
|
||||
// --- Custom Toolkit Include ---
|
||||
#include <MyIncludes\HA_Tools.mqh>
|
||||
|
||||
//--- Indicator Window and Level Properties ---
|
||||
#property indicator_separate_window
|
||||
#property indicator_level1 40.0
|
||||
#property indicator_level2 0.0
|
||||
#property indicator_level3 -40.0
|
||||
#property indicator_levelstyle STYLE_DOT
|
||||
|
||||
//--- Buffers and Plots ---
|
||||
#property indicator_buffers 8 // SMI, Signal, and 6 calculation buffers
|
||||
#property indicator_plots 2
|
||||
|
||||
//--- Plot 1: SMI line
|
||||
#property indicator_label1 "HA_SMI"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBlue
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//--- Plot 2: Signal line (EMA of SMI)
|
||||
#property indicator_label2 "HA_Signal"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrOrange
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpLengthK = 10; // %K Length
|
||||
input int InpLengthD = 3; // %D Length (for double smoothing)
|
||||
input int InpLengthEMA = 3; // EMA Length (for signal line)
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferSMI[];
|
||||
double BufferSignal[];
|
||||
double BufferHighestHigh[];
|
||||
double BufferLowestLow[];
|
||||
double BufferHighestLowestRange[];
|
||||
double BufferRelativeRange[];
|
||||
double BufferEmaEma_Relative[];
|
||||
double BufferEmaEma_Range[];
|
||||
|
||||
//--- Global Objects and Variables ---
|
||||
int ExtLengthK, ExtLengthD, ExtLengthEMA;
|
||||
CHA_Calculator g_ha_calculator;
|
||||
|
||||
//--- Forward declarations for helper functions ---
|
||||
double Highest(const double &array[], int period, int current_pos);
|
||||
double Lowest(const double &array[], int period, int current_pos);
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- Validate and store inputs
|
||||
ExtLengthK = (InpLengthK < 1) ? 1 : InpLengthK;
|
||||
ExtLengthD = (InpLengthD < 1) ? 1 : InpLengthD;
|
||||
ExtLengthEMA = (InpLengthEMA < 1) ? 1 : InpLengthEMA;
|
||||
|
||||
//--- Map the buffers
|
||||
SetIndexBuffer(0, BufferSMI, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferSignal, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, BufferHighestHigh, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(3, BufferLowestLow, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(4, BufferHighestLowestRange, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(5, BufferRelativeRange, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(6, BufferEmaEma_Relative, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(7, BufferEmaEma_Range, INDICATOR_CALCULATIONS);
|
||||
|
||||
//--- Set all buffers to non-timeseries manually ---
|
||||
ArraySetAsSeries(BufferSMI, false);
|
||||
ArraySetAsSeries(BufferSignal, false);
|
||||
ArraySetAsSeries(BufferHighestHigh, false);
|
||||
ArraySetAsSeries(BufferLowestLow, false);
|
||||
ArraySetAsSeries(BufferHighestLowestRange, false);
|
||||
ArraySetAsSeries(BufferRelativeRange, false);
|
||||
ArraySetAsSeries(BufferEmaEma_Relative, false);
|
||||
ArraySetAsSeries(BufferEmaEma_Range, false);
|
||||
|
||||
//--- Set indicator properties
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtLengthK + ExtLengthD - 2);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, ExtLengthK + ExtLengthD + ExtLengthEMA - 3);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_SMI(%d,%d,%d)", ExtLengthK, ExtLengthD, ExtLengthEMA));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Stochastic Momentum Index calculation function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//--- Check for enough data
|
||||
if(rates_total < ExtLengthK + ExtLengthD)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Calculate Heiken Ashi bars using our toolkit
|
||||
if(!g_ha_calculator.Calculate(rates_total, 0, open, high, low, close))
|
||||
return(0);
|
||||
|
||||
//--- STEP 2-4: Calculate Highest, Lowest, and Ranges using HA data
|
||||
for(int i = ExtLengthK - 1; i < rates_total; i++)
|
||||
{
|
||||
// Use HA High and HA Low from our calculator
|
||||
BufferHighestHigh[i] = Highest(g_ha_calculator.ha_high, ExtLengthK, i);
|
||||
BufferLowestLow[i] = Lowest(g_ha_calculator.ha_low, ExtLengthK, i);
|
||||
BufferHighestLowestRange[i] = BufferHighestHigh[i] - BufferLowestLow[i];
|
||||
// Use HA Close from our calculator
|
||||
BufferRelativeRange[i] = g_ha_calculator.ha_close[i] - (BufferHighestHigh[i] + BufferLowestLow[i]) / 2.0;
|
||||
}
|
||||
|
||||
//--- STEP 5: Double EMA Smoothing (Robust Manual Calculation)
|
||||
double temp_ema_relative[], temp_ema_range[];
|
||||
ArrayResize(temp_ema_relative, rates_total);
|
||||
ArrayResize(temp_ema_range, rates_total);
|
||||
double pr = 2.0 / (ExtLengthD + 1.0);
|
||||
|
||||
for(int i = 1; i < rates_total; i++)
|
||||
{
|
||||
if(i < ExtLengthK - 1)
|
||||
continue;
|
||||
if(i == ExtLengthK - 1)
|
||||
{
|
||||
temp_ema_relative[i] = BufferRelativeRange[i];
|
||||
temp_ema_range[i] = BufferHighestLowestRange[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_ema_relative[i] = BufferRelativeRange[i] * pr + temp_ema_relative[i-1] * (1.0 - pr);
|
||||
temp_ema_range[i] = BufferHighestLowestRange[i] * pr + temp_ema_range[i-1] * (1.0 - pr);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 1; i < rates_total; i++)
|
||||
{
|
||||
if(i < ExtLengthK + ExtLengthD - 2)
|
||||
continue;
|
||||
if(i == ExtLengthK + ExtLengthD - 2)
|
||||
{
|
||||
double sum_rel=0, sum_ran=0;
|
||||
for(int j=i-ExtLengthD+1; j<=i; j++)
|
||||
{
|
||||
sum_rel += temp_ema_relative[j];
|
||||
sum_ran += temp_ema_range[j];
|
||||
}
|
||||
BufferEmaEma_Relative[i] = sum_rel / ExtLengthD;
|
||||
BufferEmaEma_Range[i] = sum_ran / ExtLengthD;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferEmaEma_Relative[i] = temp_ema_relative[i] * pr + BufferEmaEma_Relative[i-1] * (1.0 - pr);
|
||||
BufferEmaEma_Range[i] = temp_ema_range[i] * pr + BufferEmaEma_Range[i-1] * (1.0 - pr);
|
||||
}
|
||||
}
|
||||
|
||||
//--- STEP 6: Calculate final SMI value
|
||||
for(int i = ExtLengthK + ExtLengthD - 2; i < rates_total; i++)
|
||||
{
|
||||
if(BufferEmaEma_Range[i] != 0)
|
||||
BufferSMI[i] = 200 * (BufferEmaEma_Relative[i] / BufferEmaEma_Range[i]);
|
||||
else
|
||||
BufferSMI[i] = 0;
|
||||
}
|
||||
|
||||
//--- STEP 7: Calculate the signal line (EMA of SMI)
|
||||
double pr_signal = 2.0 / (ExtLengthEMA + 1.0);
|
||||
for(int i = 1; i < rates_total; i++)
|
||||
{
|
||||
if(i < ExtLengthK + ExtLengthD + ExtLengthEMA - 3)
|
||||
continue;
|
||||
if(i == ExtLengthK + ExtLengthD + ExtLengthEMA - 3)
|
||||
{
|
||||
double sum_smi=0;
|
||||
for(int j=i-ExtLengthEMA+1; j<=i; j++)
|
||||
sum_smi += BufferSMI[j];
|
||||
BufferSignal[i] = sum_smi / ExtLengthEMA;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferSignal[i] = BufferSMI[i] * pr_signal + BufferSignal[i-1] * (1.0 - pr_signal);
|
||||
}
|
||||
}
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the highest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Highest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res < array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the lowest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Lowest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res > array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,183 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| StochRSI_Fast_HeikenAshi.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property description "Fast Stochastic on a Heiken Ashi based RSI"
|
||||
|
||||
//--- Indicator Window and Level Properties ---
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 2 // %K and %D
|
||||
#property indicator_plots 2
|
||||
#property indicator_level1 20.0
|
||||
#property indicator_level2 80.0
|
||||
#property indicator_minimum -10.0 // Allow for overshoots
|
||||
#property indicator_maximum 110.0 // Allow for overshoots
|
||||
|
||||
//--- Plot 1: %K line
|
||||
#property indicator_label1 "HA_%K"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBlue
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//--- Plot 2: %D line
|
||||
#property indicator_label2 "HA_%D"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrOrange
|
||||
#property indicator_style2 STYLE_SOLID
|
||||
#property indicator_width2 1
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpLengthRSI = 14; // RSI Length
|
||||
input int InpLengthStoch = 14; // Stochastic Length (%K Period)
|
||||
input int InpSmoothD = 3; // %D Smoothing (Signal Line)
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferK[];
|
||||
double BufferD[];
|
||||
double BufferHA_RSI[]; // Buffer to store the Heiken Ashi RSI values
|
||||
|
||||
//--- Global Variables ---
|
||||
int ExtLengthRSI, ExtLengthStoch, ExtSmoothD;
|
||||
int handle_ha_rsi; // Handle for our custom RSI_HeikenAshi indicator
|
||||
|
||||
//--- Forward declarations for helper functions ---
|
||||
double Highest(const double &array[], int period, int current_pos);
|
||||
double Lowest(const double &array[], int period, int current_pos);
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
ExtLengthRSI = (InpLengthRSI < 1) ? 1 : InpLengthRSI;
|
||||
ExtLengthStoch = (InpLengthStoch < 1) ? 1 : InpLengthStoch;
|
||||
ExtSmoothD = (InpSmoothD < 1) ? 1 : InpSmoothD;
|
||||
|
||||
SetIndexBuffer(0, BufferK, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferD, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, BufferHA_RSI, INDICATOR_CALCULATIONS);
|
||||
|
||||
ArraySetAsSeries(BufferK, false);
|
||||
ArraySetAsSeries(BufferD, false);
|
||||
ArraySetAsSeries(BufferHA_RSI, false);
|
||||
|
||||
//--- Create a handle to our custom RSI_HeikenAshi indicator ---
|
||||
// The path must be relative to the MQL5/Indicators/ folder
|
||||
// We assume it's in the MyIndicators subfolder
|
||||
string indicator_path = "MyIndicators\\RSI_HeikenAshi";
|
||||
handle_ha_rsi = iCustom(_Symbol, _Period, indicator_path,
|
||||
InpLengthRSI, // Pass RSI Period
|
||||
14, // Pass default MA Period (not used by the RSI line itself)
|
||||
MODE_SMA // Pass default MA Method (not used)
|
||||
);
|
||||
if(handle_ha_rsi == INVALID_HANDLE)
|
||||
Print("Error creating iCustom handle for RSI_HeikenAshi.");
|
||||
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtLengthRSI + ExtLengthStoch - 2);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, ExtLengthRSI + ExtLengthStoch + ExtSmoothD - 3);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_StochRSI_Fast(%d,%d,%d)", ExtLengthRSI, ExtLengthStoch, ExtSmoothD));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fast StochRSI on Heiken Ashi calculation function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
if(rates_total < ExtLengthRSI + ExtLengthStoch)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Get Heiken Ashi RSI values from our custom indicator
|
||||
if(BarsCalculated(handle_ha_rsi) < rates_total)
|
||||
return(0);
|
||||
// We need the raw HA_RSI line, which is in buffer #1 of the RSI_HeikenAshi indicator
|
||||
if(CopyBuffer(handle_ha_rsi, 1, 0, rates_total, BufferHA_RSI) <= 0)
|
||||
return(0);
|
||||
|
||||
//--- Main calculation loop
|
||||
for(int i = 0; i < rates_total; i++)
|
||||
{
|
||||
//--- STEP 2: Calculate Fast %K on the HA_RSI buffer ---
|
||||
if(i >= ExtLengthRSI + ExtLengthStoch - 2)
|
||||
{
|
||||
double highest_ha_rsi = Highest(BufferHA_RSI, ExtLengthStoch, i);
|
||||
double lowest_ha_rsi = Lowest(BufferHA_RSI, ExtLengthStoch, i);
|
||||
|
||||
double range = highest_ha_rsi - lowest_ha_rsi;
|
||||
if(range > 0.00001)
|
||||
BufferK[i] = (BufferHA_RSI[i] - lowest_ha_rsi) / range * 100.0;
|
||||
else
|
||||
BufferK[i] = (i > 0) ? BufferK[i-1] : 50.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferK[i] = 0;
|
||||
}
|
||||
|
||||
//--- STEP 3: Calculate %D (Signal Line) as an SMA of %K ---
|
||||
if(i >= ExtLengthRSI + ExtLengthStoch + ExtSmoothD - 3)
|
||||
{
|
||||
double sum = 0;
|
||||
for(int j = 0; j < ExtSmoothD; j++)
|
||||
{
|
||||
sum += BufferK[i-j];
|
||||
}
|
||||
BufferD[i] = sum / ExtSmoothD;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferD[i] = 0;
|
||||
}
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the highest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Highest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res < array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the lowest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Lowest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res > array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,201 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| StochRSI_Slow_HeikenAshi.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property description "Slow Stochastic on a Heiken Ashi based RSI"
|
||||
|
||||
//--- Indicator Window and Level Properties ---
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 4 // %K, %D, RawK, and HA_RSI buffer
|
||||
#property indicator_plots 2
|
||||
#property indicator_level1 20.0
|
||||
#property indicator_level2 80.0
|
||||
#property indicator_minimum -10.0
|
||||
#property indicator_maximum 110.0
|
||||
|
||||
//--- Plot 1: %K line (Slow)
|
||||
#property indicator_label1 "HA_%K"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrLightSeaGreen
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//--- Plot 2: %D line (Signal)
|
||||
#property indicator_label2 "HA_%D"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrRed
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpLengthRSI = 14; // RSI Length
|
||||
input int InpLengthStoch = 14; // Stochastic %K Period
|
||||
input int InpSlowing = 3; // Slowing Period
|
||||
input int InpSmoothD = 3; // %D Smoothing Period
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferK[];
|
||||
double BufferD[];
|
||||
double BufferHA_RSI[];
|
||||
double BufferRawStochK[];
|
||||
|
||||
//--- Global Variables ---
|
||||
int ExtLengthRSI, ExtLengthStoch, ExtSlowing, ExtSmoothD;
|
||||
int handle_ha_rsi; // Handle for our custom RSI_HeikenAshi indicator
|
||||
|
||||
//--- Forward declarations for helper functions ---
|
||||
double Highest(const double &array[], int period, int current_pos);
|
||||
double Lowest(const double &array[], int period, int current_pos);
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
ExtLengthRSI = (InpLengthRSI < 1) ? 1 : InpLengthRSI;
|
||||
ExtLengthStoch = (InpLengthStoch < 1) ? 1 : InpLengthStoch;
|
||||
ExtSlowing = (InpSlowing < 1) ? 1 : InpSlowing;
|
||||
ExtSmoothD = (InpSmoothD < 1) ? 1 : InpSmoothD;
|
||||
|
||||
SetIndexBuffer(0, BufferK, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferD, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, BufferHA_RSI, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(3, BufferRawStochK, INDICATOR_CALCULATIONS);
|
||||
|
||||
ArraySetAsSeries(BufferK, false);
|
||||
ArraySetAsSeries(BufferD, false);
|
||||
ArraySetAsSeries(BufferHA_RSI, false);
|
||||
ArraySetAsSeries(BufferRawStochK, false);
|
||||
|
||||
//--- Create a handle to our custom RSI_HeikenAshi indicator
|
||||
string indicator_path = "MyIndicators\\RSI_HeikenAshi";
|
||||
handle_ha_rsi = iCustom(_Symbol, _Period, indicator_path,
|
||||
ExtLengthRSI, // Pass RSI Period
|
||||
14, // Pass default MA Period
|
||||
MODE_SMA // Pass default MA Method
|
||||
);
|
||||
if(handle_ha_rsi == INVALID_HANDLE)
|
||||
Print("Error creating iCustom handle for RSI_HeikenAshi.");
|
||||
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtLengthRSI + ExtLengthStoch + ExtSlowing - 3);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, ExtLengthRSI + ExtLengthStoch + ExtSlowing + ExtSmoothD - 4);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_StochRSI_Slow(%d,%d,%d,%d)", ExtLengthRSI, ExtLengthStoch, ExtSlowing, ExtSmoothD));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Slow StochRSI on Heiken Ashi calculation function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
if(rates_total < ExtLengthRSI + ExtLengthStoch)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Get Heiken Ashi RSI values from our custom indicator
|
||||
if(BarsCalculated(handle_ha_rsi) < rates_total)
|
||||
return(0);
|
||||
// We need the raw HA_RSI line, which is in buffer #1 of the RSI_HeikenAshi indicator
|
||||
if(CopyBuffer(handle_ha_rsi, 1, 0, rates_total, BufferHA_RSI) <= 0)
|
||||
return(0);
|
||||
|
||||
//--- Main calculation loop
|
||||
for(int i = 0; i < rates_total; i++)
|
||||
{
|
||||
//--- STEP 2: Calculate Raw Stochastic %K on the HA_RSI buffer ---
|
||||
if(i >= ExtLengthRSI + ExtLengthStoch - 2)
|
||||
{
|
||||
double highest_ha_rsi = Highest(BufferHA_RSI, ExtLengthStoch, i);
|
||||
double lowest_ha_rsi = Lowest(BufferHA_RSI, ExtLengthStoch, i);
|
||||
|
||||
double range = highest_ha_rsi - lowest_ha_rsi;
|
||||
if(range > 0.00001)
|
||||
BufferRawStochK[i] = (BufferHA_RSI[i] - lowest_ha_rsi) / range * 100.0;
|
||||
else
|
||||
BufferRawStochK[i] = (i > 0) ? BufferRawStochK[i-1] : 50.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferRawStochK[i] = 0;
|
||||
}
|
||||
|
||||
//--- STEP 3: Calculate Slow %K (Main Line) by smoothing Raw %K ---
|
||||
if(i >= ExtLengthRSI + ExtLengthStoch + ExtSlowing - 3)
|
||||
{
|
||||
double sum = 0;
|
||||
for(int j = 0; j < ExtSlowing; j++)
|
||||
{
|
||||
sum += BufferRawStochK[i-j];
|
||||
}
|
||||
BufferK[i] = sum / ExtSlowing;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferK[i] = 0;
|
||||
}
|
||||
|
||||
//--- STEP 4: Calculate %D (Signal Line) by smoothing Slow %K ---
|
||||
if(i >= ExtLengthRSI + ExtLengthStoch + ExtSlowing + ExtSmoothD - 4)
|
||||
{
|
||||
double sum = 0;
|
||||
for(int j = 0; j < ExtSmoothD; j++)
|
||||
{
|
||||
sum += BufferK[i-j];
|
||||
}
|
||||
BufferD[i] = sum / ExtSmoothD;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferD[i] = 0;
|
||||
}
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the highest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Highest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res < array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the lowest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Lowest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res > array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,172 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| StochasticFast_HeikenAshi.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property description "Fast Stochastic Oscillator on Heiken Ashi data"
|
||||
|
||||
//--- Custom Toolkit Include ---
|
||||
#include <MyIncludes\HA_Tools.mqh>
|
||||
|
||||
//--- Indicator Window and Level Properties ---
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 2 // %K (Main) and %D (Signal)
|
||||
#property indicator_plots 2
|
||||
#property indicator_level1 20.0
|
||||
#property indicator_level2 80.0
|
||||
#property indicator_minimum 0.0
|
||||
#property indicator_maximum 100.0
|
||||
|
||||
//--- Plot 1: %K line (Fast)
|
||||
#property indicator_label1 "HA_%K"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrLightSeaGreen
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//--- Plot 2: %D line (Signal)
|
||||
#property indicator_label2 "HA_%D"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrRed
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpKPeriod = 14; // %K Period (Stochastic period)
|
||||
input int InpDPeriod = 3; // %D Period (signal line smoothing)
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferHA_K[]; // Plotted buffer for the main %K line
|
||||
double BufferHA_D[]; // Plotted buffer for the signal %D line
|
||||
|
||||
//--- Global Objects and Variables ---
|
||||
int ExtKPeriod, ExtDPeriod;
|
||||
CHA_Calculator g_ha_calculator;
|
||||
|
||||
//--- Forward declarations for helper functions ---
|
||||
double Highest(const double &array[], int period, int current_pos);
|
||||
double Lowest(const double &array[], int period, int current_pos);
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- Validate and store input periods
|
||||
ExtKPeriod = (InpKPeriod < 1) ? 1 : InpKPeriod;
|
||||
ExtDPeriod = (InpDPeriod < 1) ? 1 : InpDPeriod;
|
||||
|
||||
//--- Map the buffers and set as non-timeseries
|
||||
SetIndexBuffer(0, BufferHA_K, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferHA_D, INDICATOR_DATA);
|
||||
ArraySetAsSeries(BufferHA_K, false);
|
||||
ArraySetAsSeries(BufferHA_D, false);
|
||||
|
||||
//--- Set indicator display properties
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtKPeriod - 1);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, ExtKPeriod + ExtDPeriod - 2);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_Fast_Stoch(%d,%d)", ExtKPeriod, ExtDPeriod));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fast Stochastic on Heiken Ashi calculation function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//--- Check if there is enough historical data
|
||||
if(rates_total < ExtKPeriod + ExtDPeriod)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Calculate Heiken Ashi bars using our toolkit
|
||||
if(!g_ha_calculator.Calculate(rates_total, 0, open, high, low, close))
|
||||
return(0);
|
||||
|
||||
//--- Main calculation loop, iterating from past to present
|
||||
for(int i = 0; i < rates_total; i++)
|
||||
{
|
||||
//--- STEP 2: Calculate Raw %K using Heiken Ashi data ---
|
||||
if(i >= ExtKPeriod - 1)
|
||||
{
|
||||
// Use HA High and HA Low from our calculator
|
||||
double highest_ha_high = Highest(g_ha_calculator.ha_high, ExtKPeriod, i);
|
||||
double lowest_ha_low = Lowest(g_ha_calculator.ha_low, ExtKPeriod, i);
|
||||
|
||||
double range = highest_ha_high - lowest_ha_low;
|
||||
if(range > 0)
|
||||
// Use HA Close from our calculator
|
||||
BufferHA_K[i] = (g_ha_calculator.ha_close[i] - lowest_ha_low) / range * 100.0;
|
||||
else
|
||||
BufferHA_K[i] = (i > 0) ? BufferHA_K[i-1] : 50.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferHA_K[i] = 0; // Not enough data yet
|
||||
}
|
||||
|
||||
//--- STEP 3: Calculate %D (Signal Line) as an SMA of %K ---
|
||||
if(i >= ExtKPeriod + ExtDPeriod - 2)
|
||||
{
|
||||
double sum = 0;
|
||||
for(int j = 0; j < ExtDPeriod; j++)
|
||||
{
|
||||
sum += BufferHA_K[i-j];
|
||||
}
|
||||
BufferHA_D[i] = sum / ExtDPeriod;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferHA_D[i] = 0; // Not enough data yet
|
||||
}
|
||||
}
|
||||
//--- Return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the highest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Highest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res < array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the lowest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Lowest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res > array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,190 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| StochasticSlow_HeikenAshi.mq5|
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property description "Slow Stochastic Oscillator on Heiken Ashi data"
|
||||
|
||||
#include <MyIncludes\HA_Tools.mqh>
|
||||
|
||||
//--- Indicator Window and Level Properties ---
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 3 // %K, %D, and Raw %K for calculation
|
||||
#property indicator_plots 2
|
||||
#property indicator_level1 20.0
|
||||
#property indicator_level2 80.0
|
||||
#property indicator_minimum 0.0
|
||||
#property indicator_maximum 100.0
|
||||
|
||||
//--- Plot 1: %K line (Slow)
|
||||
#property indicator_label1 "HA_%K"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrLightSeaGreen
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//--- Plot 2: %D line (Signal)
|
||||
#property indicator_label2 "HA_%D"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrRed
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpKPeriod = 5; // %K Period
|
||||
input int InpDPeriod = 3; // %D Period (signal line smoothing)
|
||||
input int InpSlowing = 3; // Slowing (initial %K smoothing)
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferHA_K[]; // Plotted buffer for the main (Slow) %K line
|
||||
double BufferHA_D[]; // Plotted buffer for the signal %D line
|
||||
double BufferRawK[]; // Calculation buffer for raw %K before slowing
|
||||
|
||||
//--- Global Objects and Variables ---
|
||||
int ExtKPeriod, ExtDPeriod, ExtSlowing;
|
||||
CHA_Calculator g_ha_calculator;
|
||||
|
||||
//--- Forward declarations for helper functions ---
|
||||
double Highest(const double &array[], int period, int current_pos);
|
||||
double Lowest(const double &array[], int period, int current_pos);
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- Validate and store input periods
|
||||
ExtKPeriod = (InpKPeriod < 1) ? 1 : InpKPeriod;
|
||||
ExtDPeriod = (InpDPeriod < 1) ? 1 : InpDPeriod;
|
||||
ExtSlowing = (InpSlowing < 1) ? 1 : InpSlowing;
|
||||
|
||||
//--- Map the buffers and set as non-timeseries
|
||||
SetIndexBuffer(0, BufferHA_K, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferHA_D, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, BufferRawK, INDICATOR_CALCULATIONS);
|
||||
|
||||
ArraySetAsSeries(BufferHA_K, false);
|
||||
ArraySetAsSeries(BufferHA_D, false);
|
||||
ArraySetAsSeries(BufferRawK, false);
|
||||
|
||||
//--- Set indicator display properties
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtKPeriod + ExtSlowing - 2);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, ExtKPeriod + ExtSlowing + ExtDPeriod - 3);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_Slow_Stoch(%d,%d,%d)", ExtKPeriod, ExtDPeriod, ExtSlowing));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Slow Stochastic on Heiken Ashi calculation function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//--- Check if there is enough historical data
|
||||
if(rates_total < ExtKPeriod + ExtSlowing + ExtDPeriod)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Calculate Heiken Ashi bars
|
||||
if(!g_ha_calculator.Calculate(rates_total, 0, open, high, low, close))
|
||||
return(0);
|
||||
|
||||
//--- Main calculation loop, iterating from past to present
|
||||
for(int i = 0; i < rates_total; i++)
|
||||
{
|
||||
//--- STEP 2: Calculate Raw %K using Heiken Ashi data ---
|
||||
if(i >= ExtKPeriod - 1)
|
||||
{
|
||||
double highest_ha_high = Highest(g_ha_calculator.ha_high, ExtKPeriod, i);
|
||||
double lowest_ha_low = Lowest(g_ha_calculator.ha_low, ExtKPeriod, i);
|
||||
|
||||
double range = highest_ha_high - lowest_ha_low;
|
||||
if(range > 0)
|
||||
BufferRawK[i] = (g_ha_calculator.ha_close[i] - lowest_ha_low) / range * 100.0;
|
||||
else
|
||||
BufferRawK[i] = (i > 0) ? BufferRawK[i-1] : 50.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferRawK[i] = 0;
|
||||
}
|
||||
|
||||
//--- STEP 3: Calculate Slow %K (Main Line) by smoothing Raw %K ---
|
||||
if(i >= ExtKPeriod + ExtSlowing - 2)
|
||||
{
|
||||
double sum = 0;
|
||||
for(int j = 0; j < ExtSlowing; j++)
|
||||
{
|
||||
sum += BufferRawK[i-j];
|
||||
}
|
||||
BufferHA_K[i] = sum / ExtSlowing;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferHA_K[i] = 0;
|
||||
}
|
||||
|
||||
//--- STEP 4: Calculate %D (Signal Line) by smoothing Slow %K ---
|
||||
if(i >= ExtKPeriod + ExtSlowing + ExtDPeriod - 3)
|
||||
{
|
||||
double sum = 0;
|
||||
for(int j = 0; j < ExtDPeriod; j++)
|
||||
{
|
||||
sum += BufferHA_K[i-j];
|
||||
}
|
||||
BufferHA_D[i] = sum / ExtDPeriod;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferHA_D[i] = 0;
|
||||
}
|
||||
}
|
||||
//--- Return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the highest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Highest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res < array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the lowest value in a given period of an array. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Lowest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res > array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,235 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Stochastic_HeikenAshi.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.10" // Added selectable MA for Signal Line
|
||||
#property description "Stochastic Oscillator on Heiken Ashi data with selectable MA for %D line."
|
||||
|
||||
// --- Standard and Custom Includes ---
|
||||
#include <MyIncludes\HA_Tools.mqh>
|
||||
#include <MovingAverages.mqh>
|
||||
|
||||
//--- Indicator Window and Level Properties ---
|
||||
#property indicator_separate_window
|
||||
#property indicator_buffers 5 // %K, %D, and 3 calculation buffers
|
||||
#property indicator_plots 2
|
||||
#property indicator_level1 20.0
|
||||
#property indicator_level2 80.0
|
||||
#property indicator_minimum 0.0
|
||||
#property indicator_maximum 100.0
|
||||
|
||||
//--- Plot 1: %K line (Main)
|
||||
#property indicator_label1 "HA_%K"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrLightSeaGreen
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
|
||||
//--- Plot 2: %D line (Signal)
|
||||
#property indicator_label2 "HA_%D"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrRed
|
||||
#property indicator_style2 STYLE_DOT
|
||||
#property indicator_width2 1
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpKPeriod = 5; // %K Period
|
||||
input int InpSlowing = 3; // Slowing (initial %K smoothing)
|
||||
input group "Signal Line Settings"
|
||||
input int InpDPeriod = 3; // %D Period (signal line smoothing)
|
||||
input ENUM_MA_METHOD InpMAMethod = MODE_SMA; // MA Method for %D line
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferHA_K[]; // Plotted buffer for the main %K line
|
||||
double BufferHA_D[]; // Plotted buffer for the signal %D line
|
||||
double BufferRawK[]; // Calculation buffer for raw %K before slowing
|
||||
double BufferHighest[]; // Calculation buffer for Highest HA_High in period
|
||||
double BufferLowest[]; // Calculation buffer for Lowest HA_Low in period
|
||||
|
||||
//--- Global Objects and Variables ---
|
||||
int ExtKPeriod, ExtDPeriod, ExtSlowing;
|
||||
CHA_Calculator g_ha_calculator; // Global instance of our Heiken Ashi calculator
|
||||
|
||||
//--- Forward declarations for helper functions ---
|
||||
double Highest(const double &array[], int period, int current_pos);
|
||||
double Lowest(const double &array[], int period, int current_pos);
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//| Called once when the indicator is first loaded. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
//--- Validate and store input periods
|
||||
ExtKPeriod = (InpKPeriod < 1) ? 1 : InpKPeriod;
|
||||
ExtDPeriod = (InpDPeriod < 1) ? 1 : InpDPeriod;
|
||||
ExtSlowing = (InpSlowing < 1) ? 1 : InpSlowing;
|
||||
|
||||
//--- Map the buffers to the indicator's internal memory
|
||||
SetIndexBuffer(0, BufferHA_K, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferHA_D, INDICATOR_DATA);
|
||||
SetIndexBuffer(2, BufferRawK, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(3, BufferHighest, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(4, BufferLowest, INDICATOR_CALCULATIONS);
|
||||
|
||||
//--- Set all buffers to work as regular arrays (non-timeseries)
|
||||
ArraySetAsSeries(BufferHA_K, false);
|
||||
ArraySetAsSeries(BufferHA_D, false);
|
||||
ArraySetAsSeries(BufferRawK, false);
|
||||
ArraySetAsSeries(BufferHighest, false);
|
||||
ArraySetAsSeries(BufferLowest, false);
|
||||
|
||||
//--- Set indicator display properties
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtKPeriod + ExtSlowing - 2);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, ExtKPeriod + ExtSlowing + ExtDPeriod - 3);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_Stoch(%d,%d,%d)", ExtKPeriod, ExtDPeriod, ExtSlowing));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Stochastic Oscillator on Heiken Ashi calculation function. |
|
||||
//| Performs a full recalculation on every call for stability. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
//--- Check if there is enough historical data for all calculations
|
||||
if(rates_total < ExtKPeriod + ExtSlowing + ExtDPeriod)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Calculate Heiken Ashi bars using our toolkit
|
||||
if(!g_ha_calculator.Calculate(rates_total, 0, open, high, low, close))
|
||||
return(0);
|
||||
|
||||
//--- Main calculation loop, iterating from past to present
|
||||
for(int i = 0; i < rates_total; i++)
|
||||
{
|
||||
//--- STEP 2 & 3: Calculate Highest, Lowest, and Raw %K ---
|
||||
if(i >= ExtKPeriod - 1)
|
||||
{
|
||||
BufferHighest[i] = Highest(g_ha_calculator.ha_high, ExtKPeriod, i);
|
||||
BufferLowest[i] = Lowest(g_ha_calculator.ha_low, ExtKPeriod, i);
|
||||
|
||||
double range = BufferHighest[i] - BufferLowest[i];
|
||||
if(range > 0)
|
||||
BufferRawK[i] = (g_ha_calculator.ha_close[i] - BufferLowest[i]) / range * 100.0;
|
||||
else
|
||||
BufferRawK[i] = (i > 0) ? BufferRawK[i-1] : 50.0; // Avoid division by zero
|
||||
}
|
||||
else
|
||||
{
|
||||
// Initialize early bars to 0
|
||||
BufferHighest[i] = 0;
|
||||
BufferLowest[i] = 0;
|
||||
BufferRawK[i] = 0;
|
||||
}
|
||||
|
||||
//--- STEP 4: Calculate Slow %K (Main Line) by smoothing Raw %K with SMA
|
||||
if(i >= ExtKPeriod + ExtSlowing - 2)
|
||||
{
|
||||
double sum = 0;
|
||||
for(int j = 0; j < ExtSlowing; j++)
|
||||
sum += BufferRawK[i-j];
|
||||
BufferHA_K[i] = sum / ExtSlowing;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferHA_K[i] = 0;
|
||||
}
|
||||
|
||||
//--- STEP 5: Calculate %D (Signal Line) with user-selectable MA
|
||||
if(i >= ExtKPeriod + ExtSlowing + ExtDPeriod - 3)
|
||||
{
|
||||
switch(InpMAMethod)
|
||||
{
|
||||
case MODE_EMA:
|
||||
if(i == ExtKPeriod + ExtSlowing + ExtDPeriod - 3) // First EMA is an SMA
|
||||
BufferHA_D[i] = SimpleMA(i, ExtDPeriod, BufferHA_K);
|
||||
else
|
||||
{
|
||||
double pr = 2.0 / (ExtDPeriod + 1.0);
|
||||
BufferHA_D[i] = BufferHA_K[i] * pr + BufferHA_D[i-1] * (1.0 - pr);
|
||||
}
|
||||
break;
|
||||
case MODE_SMMA:
|
||||
if(i == ExtKPeriod + ExtSlowing + ExtDPeriod - 3) // First SMMA is an SMA
|
||||
BufferHA_D[i] = SimpleMA(i, ExtDPeriod, BufferHA_K);
|
||||
else
|
||||
BufferHA_D[i] = (BufferHA_D[i-1] * (ExtDPeriod - 1) + BufferHA_K[i]) / ExtDPeriod;
|
||||
break;
|
||||
case MODE_LWMA:
|
||||
BufferHA_D[i] = LinearWeightedMA(i, ExtDPeriod, BufferHA_K);
|
||||
break;
|
||||
default: // MODE_SMA
|
||||
{
|
||||
double sum = 0;
|
||||
for(int j = 0; j < ExtDPeriod; j++)
|
||||
sum += BufferHA_K[i-j];
|
||||
BufferHA_D[i] = sum / ExtDPeriod;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferHA_D[i] = 0;
|
||||
}
|
||||
}
|
||||
//--- Return value of prev_calculated for next call
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the highest value in a given period of an array. |
|
||||
//| INPUT: array[] - The data array to search in. |
|
||||
//| period - The number of elements to look back. |
|
||||
//| current_pos - The starting position (index) to search from.|
|
||||
//| RETURN: The highest value found in the specified range. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Highest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res < array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Finds the lowest value in a given period of an array. |
|
||||
//| INPUT: array[] - The data array to search in. |
|
||||
//| period - The number of elements to look back. |
|
||||
//| current_pos - The starting position (index) to search from.|
|
||||
//| RETURN: The lowest value found in the specified range. |
|
||||
//+------------------------------------------------------------------+
|
||||
double Lowest(const double &array[], int period, int current_pos)
|
||||
{
|
||||
double res = array[current_pos];
|
||||
for(int i = 1; i < period; i++)
|
||||
{
|
||||
int index = current_pos - i;
|
||||
if(index < 0)
|
||||
break;
|
||||
if(res > array[index])
|
||||
res = array[index];
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -1,140 +0,0 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Supertrend_HeikenAshi.mq5 |
|
||||
//| Copyright 2025, xxxxxxxx |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2025, xxxxxxxx"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
#property description "Supertrend Indicator on Heiken Ashi data"
|
||||
|
||||
#include <MyIncludes\HA_Tools.mqh>
|
||||
|
||||
//--- Indicator Window and Plot Properties ---
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 5 // Supertrend, Color, ATR, UpperBand, LowerBand
|
||||
#property indicator_plots 1
|
||||
|
||||
//--- Plot 1: Supertrend line
|
||||
#property indicator_label1 "HA_Supertrend"
|
||||
#property indicator_type1 DRAW_COLOR_LINE
|
||||
#property indicator_color1 clrLimeGreen, clrTomato
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 2
|
||||
|
||||
//--- Input Parameters ---
|
||||
input int InpAtrPeriod = 10;
|
||||
input double InpFactor = 3.0;
|
||||
|
||||
//--- Indicator Buffers ---
|
||||
double BufferSupertrend[];
|
||||
double BufferColor[];
|
||||
double BufferATR[];
|
||||
double BufferUpperBand[];
|
||||
double BufferLowerBand[];
|
||||
|
||||
//--- Global Objects and Variables ---
|
||||
int ExtAtrPeriod;
|
||||
double ExtFactor;
|
||||
int handle_atr;
|
||||
CHA_Calculator g_ha_calculator;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function. |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnInit()
|
||||
{
|
||||
ExtAtrPeriod = (InpAtrPeriod < 1) ? 1 : InpAtrPeriod;
|
||||
ExtFactor = (InpFactor <= 0) ? 3.0 : InpFactor;
|
||||
|
||||
SetIndexBuffer(0, BufferSupertrend, INDICATOR_DATA);
|
||||
SetIndexBuffer(1, BufferColor, INDICATOR_COLOR_INDEX);
|
||||
SetIndexBuffer(2, BufferATR, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(3, BufferUpperBand, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(4, BufferLowerBand, INDICATOR_CALCULATIONS);
|
||||
|
||||
ArraySetAsSeries(BufferSupertrend, false);
|
||||
ArraySetAsSeries(BufferColor, false);
|
||||
ArraySetAsSeries(BufferATR, false);
|
||||
ArraySetAsSeries(BufferUpperBand, false);
|
||||
ArraySetAsSeries(BufferLowerBand, false);
|
||||
|
||||
// ATR is calculated on standard candles, as it measures true volatility
|
||||
handle_atr = iATR(_Symbol, _Period, ExtAtrPeriod);
|
||||
if(handle_atr == INVALID_HANDLE)
|
||||
Print("Error creating iATR handle.");
|
||||
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtAtrPeriod);
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_Supertrend(%d, %.1f)", ExtAtrPeriod, ExtFactor));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Supertrend on Heiken Ashi calculation function. |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnCalculate(const int rates_total,
|
||||
const int prev_calculated,
|
||||
const datetime &time[],
|
||||
const double &open[],
|
||||
const double &high[],
|
||||
const double &low[],
|
||||
const double &close[],
|
||||
const long &tick_volume[],
|
||||
const long &volume[],
|
||||
const int &spread[])
|
||||
{
|
||||
if(rates_total < ExtAtrPeriod)
|
||||
return(0);
|
||||
|
||||
//--- STEP 1: Calculate Heiken Ashi bars
|
||||
if(!g_ha_calculator.Calculate(rates_total, 0, open, high, low, close))
|
||||
return(0);
|
||||
|
||||
//--- STEP 2: Get ATR values
|
||||
if(BarsCalculated(handle_atr) < rates_total)
|
||||
return(0);
|
||||
if(CopyBuffer(handle_atr, 0, 0, rates_total, BufferATR) <= 0)
|
||||
return(0);
|
||||
|
||||
//--- STEP 3: Main calculation loop
|
||||
for(int i = 1; i < rates_total; i++)
|
||||
{
|
||||
double ha_hl2 = (g_ha_calculator.ha_high[i] + g_ha_calculator.ha_low[i]) / 2.0;
|
||||
|
||||
double upper_basic = ha_hl2 + (ExtFactor * BufferATR[i]);
|
||||
double lower_basic = ha_hl2 - (ExtFactor * BufferATR[i]);
|
||||
|
||||
// Stair-step logic
|
||||
if(upper_basic < BufferUpperBand[i-1] || g_ha_calculator.ha_close[i-1] > BufferUpperBand[i-1])
|
||||
BufferUpperBand[i] = upper_basic;
|
||||
else
|
||||
BufferUpperBand[i] = BufferUpperBand[i-1];
|
||||
|
||||
if(lower_basic > BufferLowerBand[i-1] || g_ha_calculator.ha_close[i-1] < BufferLowerBand[i-1])
|
||||
BufferLowerBand[i] = lower_basic;
|
||||
else
|
||||
BufferLowerBand[i] = BufferLowerBand[i-1];
|
||||
|
||||
// Trend direction
|
||||
int trend = 0;
|
||||
if(BufferSupertrend[i-1] == BufferUpperBand[i-1])
|
||||
trend = (g_ha_calculator.ha_close[i] > BufferUpperBand[i]) ? 1 : -1;
|
||||
else
|
||||
trend = (g_ha_calculator.ha_close[i] < BufferLowerBand[i]) ? -1 : 1;
|
||||
|
||||
if(trend == 1) // Uptrend
|
||||
{
|
||||
BufferSupertrend[i] = BufferLowerBand[i];
|
||||
BufferColor[i] = 0; // Green
|
||||
}
|
||||
else // Downtrend
|
||||
{
|
||||
BufferSupertrend[i] = BufferUpperBand[i];
|
||||
BufferColor[i] = 1; // Red
|
||||
}
|
||||
}
|
||||
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user