Author: Copyright � 2005, MetaQuotes Software Corp.
WPR_001

This script is a custom technical analysis tool designed to measure the momentum of a financial asset by tracking its price movement relative to its recent history. It provides traders with a visual representation of whether a market is currently "overextended" in either direction, helping to identify potential reversal points.

Core Logic and Functionality

1. Range Analysis The tool looks back at a specific number of historical price candles (defined by the user, default is 14). It identifies two key data points within this timeframe: the highest price reached and the lowest price hit. By calculating the difference between these two extremes, the script establishes the "trading range."

2. Position Tracking The script then determines where the current closing price sits within that specific range. It converts this position into a percentage value.

  • If the price is near the top of the recent high, the indicator moves toward the upper limit.
  • If the price is near the bottom of the recent low, the indicator moves toward the lower limit.

3. Visual Representation The result is displayed as a line in a separate window on your trading chart. This allows you to see the "pulse" of the market independently of the price candles. The tool includes pre-set visual levels (levels such as -20, -50, and -80) to help traders quickly identify when the price has moved aggressively into extreme territory.

4. Automated Notifications Beyond just providing a visual line, the script features an intelligent alerting system. It monitors the price action in real-time and will trigger a notification if specific conditions are met:

  • Buy Alerts: Triggered when the indicator falls into an extremely low zone (indicating the price may be "oversold").
  • Sell Alerts: Triggered when the indicator rises into an extremely high zone (indicating the price may be "overbought").

To ensure you aren't overwhelmed with constant notifications, the script is programmed to recognize the start of a new candle. It will only evaluate the conditions and send an alert once at the beginning of a new time period, rather than repeating the alert every second the price remains in that zone.

5. User Customization The logic is flexible, allowing users to adjust:

  • Lookback Period: Change how many candles the tool considers for its calculation.
  • Sensitivity Levels: Define exactly which percentage points trigger a "Buy" or "Sell" alert.
  • Alert Toggles: Easily turn the notification system on or off depending on your trading style.
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screen
17 Views
0 Downloads
0 Favorites
WPR_001
//+------------------------------------------------------------------+
//|                                      Williams’ Percent Range.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
#property indicator_level3 -50
//---- input parameters
extern int ExtWPRPeriod = 14;
extern string note = "turn on Alert = true; turn off = false";
extern bool AlertOn = true;
extern int       BullLevel=-80;
extern int       BearLevel=-20;
//---- buffers
double ExtWPRBuffer[];
// Show regular timeframe string (HCY)
string AlertPrefix;
string GetTimeFrameStr() {
   switch(Period())
   {
      case 1 : string TimeFrameStr="M1"; break;
      case 5 : TimeFrameStr="M5"; break;
      case 15 : TimeFrameStr="M15"; break;
      case 30 : TimeFrameStr="M30"; break;
      case 60 : TimeFrameStr="H1"; break;
      case 240 : TimeFrameStr="H4"; break;
      case 1440 : TimeFrameStr="D1"; break;
      case 10080 : TimeFrameStr="W1"; break;
      case 43200 : TimeFrameStr="MN1"; break;
      default : TimeFrameStr="CUR";
   } 
   return (TimeFrameStr);
   }
//+------------------------------------------------------------------+
//| 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);
//----
   AlertPrefix=Symbol()+" ("+GetTimeFrameStr()+"):  ";
   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--;
     }
//----
   // ======= Alert =========
   if(AlertOn && NewBar()){
      if((ExtWPRBuffer[0] <= BullLevel) && (ExtWPRBuffer[0] <=-indicator_minimum))
         Alert(AlertPrefix+" %R("+ExtWPRPeriod+") Buy Alert "+ ExtWPRBuffer[0]);
      else
      if((ExtWPRBuffer[0] >= BearLevel) && (ExtWPRBuffer[0] <=indicator_maximum))
         Alert(AlertPrefix+" %R("+ExtWPRPeriod+") Sell Alert "+ ExtWPRBuffer[0]);
      }
   // ======= Alert Ends =========
   return(0);
  }
//+------------------------------------------------------------------+
//| Ôóíêöèÿ ñðàíåíèÿ äâóõ âåùåñòâåííûõ ÷èñåë.                        |
//+------------------------------------------------------------------+
bool CompareDouble(double Number1, double Number2)
  {
    bool Compare = NormalizeDouble(Number1 - Number2, 8) == 0;
    return(Compare);
  } 
//+------------------------------------------------------------------+ 
bool NewBar()
{
   static datetime lastbar;
   datetime curbar = Time[0];
   //Print("NewBar(). lastbar="+TimeToStr(lastbar,TIME_DATE|TIME_MINUTES)+"  curbar="+TimeToStr(curbar,TIME_DATE|TIME_MINUTES));
   if(lastbar!=curbar)
   {
      lastbar=curbar;
      return (true);
   }
   else
   {
      return(false);
   }
} 

Comments