Files
mql5/Indicators/MyIndicators/WPR_HeikenAshi.mq5
T
2025-08-11 12:06:31 +02:00

169 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//+------------------------------------------------------------------+
//| WPR_HeikenAshi.mq5 |
//| Copyright 2024, Your Name (Based on MetaQuotes WPR) |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Your Name"
#property link ""
#property description "Larry Williams' Percent Range based on Heiken Ashi candles"
//--- indicator settings
#property indicator_separate_window
#property indicator_level1 -20.0
#property indicator_level2 -80.0
#property indicator_levelstyle STYLE_DOT
#property indicator_levelcolor clrSilver
#property indicator_levelwidth 1
#property indicator_maximum 0.0
#property indicator_minimum -100.0
//--- Buffers and Plots
#property indicator_buffers 5 // WPR, HA_Open, HA_High, HA_Low, HA_Close
#property indicator_plots 1
//--- Plot 1: WPR line
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
//--- input parameters
input int InpWPRPeriod=14; // Period
//--- Indicator Buffers
// Plotted buffer
double BufferHA_WPR[];
// Calculation buffers for Heiken Ashi
double BufferHA_Open[];
double BufferHA_High[];
double BufferHA_Low[];
double BufferHA_Close[];
//--- global variables
int ExtPeriodWPR;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- Validate input
ExtPeriodWPR = (InpWPRPeriod < 1) ? 1 : InpWPRPeriod;
//--- Indicator buffers mapping
SetIndexBuffer(0, BufferHA_WPR, INDICATOR_DATA);
SetIndexBuffer(1, BufferHA_Open, INDICATOR_CALCULATIONS);
SetIndexBuffer(2, BufferHA_High, INDICATOR_CALCULATIONS);
SetIndexBuffer(3, BufferHA_Low, INDICATOR_CALCULATIONS);
SetIndexBuffer(4, BufferHA_Close, INDICATOR_CALCULATIONS);
//--- Set drawing start position
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtPeriodWPR - 1);
//--- Set name for DataWindow and indicator subwindow label
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_WPR(%d)", ExtPeriodWPR));
//--- Set display precision
IndicatorSetInteger(INDICATOR_DIGITS, 2);
}
//+------------------------------------------------------------------+
//| Williams Percent Range on Heiken Ashi |
//+------------------------------------------------------------------+
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 data
if(rates_total < ExtPeriodWPR)
return(0);
//====== STEP 1: CALCULATE HEIKEN ASHI BARS ======
// Calculate the very first HA bar
BufferHA_Open[0] = (open[0] + close[0]) / 2.0;
BufferHA_Close[0] = (open[0] + high[0] + low[0] + close[0]) / 4.0;
BufferHA_High[0] = MathMax(high[0], MathMax(BufferHA_Open[0], BufferHA_Close[0]));
BufferHA_Low[0] = MathMin(low[0], MathMin(BufferHA_Open[0], BufferHA_Close[0]));
// Loop to calculate all subsequent HA bars
for(int i = 1; i < rates_total; i++)
{
BufferHA_Open[i] = (BufferHA_Open[i-1] + BufferHA_Close[i-1]) / 2.0;
BufferHA_Close[i] = (open[i] + high[i] + low[i] + close[i]) / 4.0;
BufferHA_High[i] = MathMax(high[i], MathMax(BufferHA_Open[i], BufferHA_Close[i]));
BufferHA_Low[i] = MathMin(low[i], MathMin(BufferHA_Open[i], BufferHA_Close[i]));
}
//====== STEP 2: CALCULATE WPR BASED ON HEIKEN ASHI BARS ======
// Determine starting bar for calculation
int start_pos;
if(prev_calculated > 0)
start_pos = prev_calculated - 1;
else
start_pos = ExtPeriodWPR - 1;
// Main calculation loop
for(int i = start_pos; i < rates_total && !IsStopped(); i++)
{
// Find the highest HA_High and lowest HA_Low over the WPR period
double max_ha_high = Highest(BufferHA_High, ExtPeriodWPR, i);
double min_ha_low = Lowest(BufferHA_Low, ExtPeriodWPR, i);
// Calculate WPR using the current HA_Close
if(max_ha_high != min_ha_low)
BufferHA_WPR[i] = - (max_ha_high - BufferHA_Close[i]) * 100.0 / (max_ha_high - min_ha_low);
else
// If max high equals min low, avoid division by zero
BufferHA_WPR[i] = (i > 0) ? BufferHA_WPR[i-1] : -50.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];
// Loop backwards from the previous bar for 'period'-1 bars
for(int i = 1; i < period; i++)
{
int index = current_pos - i;
if(index < 0)
break; // Stop if we go out of bounds
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];
// Loop backwards from the previous bar for 'period'-1 bars
for(int i = 1; i < period; i++)
{
int index = current_pos - i;
if(index < 0)
break; // Stop if we go out of bounds
if(res > array[index])
res = array[index];
}
return(res);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+