Files
mql5/Indicators/MyIndicators/WPR_HeikenAshi.mq5
T

165 lines
13 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 2025, xxxxxxxx (Based on MetaQuotes WPR) |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, xxxxxxxx"
#property link ""
#property version "2.00" // Refactored to use HA_Tools.mqh
#property description "Larry Williams' Percent Range based on Heiken Ashi candles"
//--- Custom Toolkit Include ---
#include <MyIncludes\HA_Tools.mqh>
//--- Indicator Window and Level Properties ---
#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 1 // Only one buffer is needed for the WPR line
#property indicator_plots 1
//--- Plot 1: WPR line
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
#property indicator_label1 "HA_WPR"
//--- Input Parameters ---
input int InpWPRPeriod=14; // Period for WPR calculation
//--- Indicator Buffers ---
double BufferHA_WPR[]; // The only buffer, for the final WPR values
//--- Global Objects and Variables ---
int ExtPeriodWPR;
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 the WPR period
ExtPeriodWPR = (InpWPRPeriod < 1) ? 1 : InpWPRPeriod;
//--- Map the buffer to the indicator's internal memory
SetIndexBuffer(0, BufferHA_WPR, INDICATOR_DATA);
//--- Set indicator properties
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, ExtPeriodWPR - 1);
IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("HA_WPR(%d)", ExtPeriodWPR));
IndicatorSetInteger(INDICATOR_DIGITS, 2);
}
//+------------------------------------------------------------------+
//| Williams Percent Range on Heiken Ashi. |
//| 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 < ExtPeriodWPR)
return(0);
//--- STEP 1: Calculate Heiken Ashi bars using our toolkit
if(!g_ha_calculator.Calculate(rates_total, prev_calculated, open, high, low, close))
{
Print("Heiken Ashi calculation failed.");
return(0);
}
//--- STEP 2: Calculate WPR based on the results from the HA calculator
int start_pos;
if(prev_calculated > 0)
start_pos = prev_calculated - 1; // Optimization for subsequent calls
else
start_pos = ExtPeriodWPR - 1; // Start from the first bar with enough data
//--- 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
// using the calculator's public buffers
double max_ha_high = Highest(g_ha_calculator.ha_high, ExtPeriodWPR, i);
double min_ha_low = Lowest(g_ha_calculator.ha_low, ExtPeriodWPR, i);
// Calculate WPR using the current HA_Close from the calculator
if(max_ha_high != min_ha_low)
BufferHA_WPR[i] = - (max_ha_high - g_ha_calculator.ha_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 value of prev_calculated for the 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];
//--- Loop backwards from the current position for 'period' 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. |
//| 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];
//--- Loop backwards from the current position for 'period' 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);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+