mirror of
https://github.com/softwaredevelop/mql5.git
synced 2026-08-19 15:28:06 +00:00
169 lines
12 KiB
Plaintext
169 lines
12 KiB
Plaintext
//+------------------------------------------------------------------+
|
||
//| 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);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
//+------------------------------------------------------------------+
|