Williams’ Percent Range indicator - WPR (%R)

Profesional Forex Market Indicator

Technical Indicator
WPR - (%R)
Dynamic technical indicator
WPR - (%R)
Fx Market Indicator
WPR - (%R)
How to trade?
WPR - How to trade





Williams’ Percent Range - WPR Technical Indicator (%R) is a dynamic technical indicator, which determines whether the market is overbought or oversold.
This system attempts to measure overbought and oversold market conditions. The Williams’ Percent Range - WPR (%R) always falls between a value of 100 and 0. There are two horizontal lines in the study that represent the 20% and 80% overbought and oversold levels. The WPR (%R) indicator is designed to show the difference between the period high and today’s closing price with the trading range of the specified period. The indicator therefore shows the relative situation of the closing price within the observation period. WPR (%R) is very similar to the Stochastic Oscillator and Relative Strength Index (RSI). The only difference is that WPR (%R) has an upside down scale.

Williams’ Percent Range - WPR (%R) Mathematical Formula:
1. Choose a period “N” for “%R” (Standard is “14”)
2. %R = 100 * (HN – CCP)/(HN – LN) where CCP = Current Closing Price, LN = lowest low of past “N” periods, HN = highest high of past “N” periods



Williams’ Percent Range indicator - WPR  (%R) MQ4 Code Base (Copy Code)
//+------------------------------------------------------------------+
//|                                Williams’ Percent Range - WPR.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
//----
#property indicator_separate_window
#property indicator_minimum -100
#property indicator_maximum 0
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
#property indicator_level1 -20
#property indicator_level2 -80
//---- input parameters
extern int ExtWPRPeriod = 14;
//---- buffers
double ExtWPRBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string sShortName;
//---- indicator buffer mapping
   SetIndexBuffer(0, ExtWPRBuffer);
//---- indicator line
   SetIndexStyle(0, DRAW_LINE);
//---- name for DataWindow and indicator subwindow label
   sShortName="%R(" + ExtWPRPeriod + ")";
   IndicatorShortName(sShortName);
   SetIndexLabel(0, sShortName);
//---- first values aren't drawn
   SetIndexDrawBegin(0, ExtWPRPeriod);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Williams’ Percent Range                                          |
//+------------------------------------------------------------------+
int start()
  {
   int i, nLimit, nCountedBars;  
//---- insufficient data
   if(Bars <= ExtWPRPeriod) 
       return(0);
//---- bars count that does not changed after last indicator launch.
   nCountedBars = IndicatorCounted();
//----Williams’ Percent Range calculation
   i = Bars - ExtWPRPeriod - 1;
   if(nCountedBars > ExtWPRPeriod) 
       i = Bars - nCountedBars - 1;  
   while(i >= 0)
     {
       double dMaxHigh = High[Highest(NULL, 0, MODE_HIGH, ExtWPRPeriod, i)];
       double dMinLow = Low[Lowest(NULL, 0, MODE_LOW, ExtWPRPeriod, i)];      
       if(!CompareDouble((dMaxHigh - dMinLow), 0.0))
           ExtWPRBuffer[i] = -100*(dMaxHigh - Close[i]) / (dMaxHigh - dMinLow);
       i--;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Функция сранения двух вещественных чисел.                        |
//+------------------------------------------------------------------+
bool CompareDouble(double Number1, double Number2)
  {
    bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0;
    return(Compare);
  } 
//+------------------------------------------------------------------+


Williams’ Percent Range indicator - WPR  (%R) MQ5 Code Base (Copy Code)
//+------------------------------------------------------------------+
//|                                Williams’ Percent Range - WPR.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2009, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property description "Larry Williams' Percent Range"
//---- indicator settings
#property indicator_separate_window
#property indicator_level1     -20.0
#property indicator_level2     -80.0
#property indicator_levelstyle STYLE_DOT
#property indicator_levelcolor Silver
#property indicator_levelwidth 1
#property indicator_maximum    0.0
#property indicator_minimum    -100.0
#property indicator_buffers    1
#property indicator_plots      1
#property indicator_type1      DRAW_LINE
#property indicator_color1     DodgerBlue
//---- input parameters
input int InpWPRPeriod=14; // Period
//---- buffers
double    ExtWPRBuffer[];
//--- global variables
int       ExtPeriodWPR;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- check for input value
   if(InpWPRPeriod<3)
     {
      ExtPeriodWPR=14;
      Print("Incorrect InpWPRPeriod value. Indicator will use value=",ExtPeriodWPR);
     }
   else ExtPeriodWPR=InpWPRPeriod;
//---- name for DataWindow and indicator subwindow label
   IndicatorSetString(INDICATOR_SHORTNAME,"%R"+"("+string(ExtPeriodWPR)+")");
//---- indicator's buffer   
   SetIndexBuffer(0,ExtWPRBuffer);
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodWPR-1);
//--- digits   
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//----
  }
//+------------------------------------------------------------------+
//| Williams’ Percent Range                                          |
//+------------------------------------------------------------------+
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 &TickVolume[],
                const long &Volume[],
                const int &Spread[])
  {
//---- insufficient data
   if(rates_total<ExtPeriodWPR)
      return(0);
//--- start working
   int i=prev_calculated-1;
//--- correct position
   if(i<ExtPeriodWPR-1) i=ExtPeriodWPR-1;
//---  main cycle
   while(i<rates_total && !IsStopped())
     {
      //--- calculate maximum High
      double dMaxHigh=MaxAr(High,ExtPeriodWPR,i);
      //--- calculate minimum Low
      double dMinLow=MinAr(Low,ExtPeriodWPR,i);
      //--- calculate WPR
      if(dMaxHigh!=dMinLow)
         ExtWPRBuffer[i]=-(dMaxHigh-Close[i])*100/(dMaxHigh-dMinLow);
      else
         ExtWPRBuffer[i]=ExtWPRBuffer[i-1];
      //--- increment i for next iteration
      i++;
     }
   //--- return new prev_calculated value
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Maximum High                                                     |
//+------------------------------------------------------------------+
double MaxAr(const double &array[],int period,int cur_position)
  {
   double Highest=array[cur_position];
   for(int i=cur_position-1;i>cur_position-period;i--)
     {
      if(Highest<array[i]) Highest=array[i];
     }
   return(Highest);
  }
//+------------------------------------------------------------------+
//| Minimum Low                                                      |
//+------------------------------------------------------------------+
double MinAr(const double &array[],int period,int cur_position)
  {
   double Lowest=array[cur_position];
   for(int i=cur_position-1;i>cur_position-period;i--)
     {
      if(Lowest>array[i]) Lowest=array[i];
     }
   return(Lowest);
  }
//+------------------------------------------------------------------+