Author: Copyright � 2007, MetaQuotes Software Corp.
UOSA

This technical tool, known as the Ultimate Oscillator, is designed to provide traders with a visual representation of momentum in the financial markets. Rather than looking at price alone, this script analyzes the relationship between the "lows" of current price action and the "closes" of previous price periods to determine the underlying strength of a market move.

How the Logic Works

The indicator operates through a multi-layered calculation process to filter out market "noise" and provide a clearer picture of trends:

1. Establishing the Base Value The script begins by identifying a specific price point for every candle on the chart. It compares the lowest price reached during the current period against the closing price of the previous period. By calculating the difference between these two points, the tool establishes a raw measurement of how much "room" there is between previous market activity and current price movements.

2. Smoothing the Data To prevent the indicator from reacting too wildly to minor, insignificant price flickers, the script applies three different smoothing layers (Fast, Middle, and Slow). Each layer uses different time horizons:

  • The Fast Layer: Tracks immediate, short-term momentum.
  • The Middle Layer: Provides a balanced view of recent activity.
  • The Slow Layer: Offers a broader perspective of the long-term trend.

3. Adjusting for Volatility A key feature of this logic is that it doesn't just average these values; it adjusts them based on market volatility. By factoring in the Average True Range (ATR), the script "normalizes" the data. This means that if the market becomes extremely volatile, the indicator scales its response accordingly, ensuring that the resulting line remains readable and consistent regardless of how much the price is swinging.

4. The Final Output Finally, the script combines these three smoothed and volatility-adjusted layers into a single weighted value. This final figure is converted into a percentage-based scale (ranging from -25 to 125).

What this means for the user

The resulting pink line on your chart serves as a momentum gauge. Because it balances short-term speed with long-term stability while accounting for market volatility, it helps identify when a move has enough strength to be sustained or when a trend is becoming overextended and may be losing its "fuel."

Indicators Used
Moving average indicatorIndicator of the average true range
Miscellaneous
Implements a curve of type %1
12 Views
0 Downloads
0 Favorites
UOSA
//+------------------------------------------------------------------+
//|                                          Ultimate Oscillator.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.ru/"
//----
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Pink

#property indicator_levelcolor LightPink
#property indicator_maximum 125
#property indicator_minimum -25
//---- input parameters
extern int fastperiod = 7;
extern int middleperiod = 14;
extern int slowperiod = 28;
extern int fastK = 3;
extern int middleK = 3;
extern int slowK = 3;
//---- buffers
double UOBuffer[];
double BPBuffer[];
double divider;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   string name;
   name="UOS(" + fastperiod + ", " + middleperiod + ", " + slowperiod + ")";
   IndicatorBuffers(2);
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, UOBuffer);
   SetIndexDrawBegin(0, slowperiod);
   SetIndexBuffer(1, BPBuffer);
   IndicatorShortName(name);
   IndicatorDigits(1);
   divider = fastK + middleK + slowK;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int counted_bars = IndicatorCounted();
//----
   int i, limit, limit2;
   double TL, RawUO;
   if(counted_bars == 0) 
     {
       limit = Bars - 2;
       limit2 = Bars - slowperiod;
     }
   if(counted_bars > 0) 
     {
       limit = Bars - counted_bars;
       limit2 = limit;
     }
   for(i = limit; i >= 0; i--)
     {
       TL = MathMin(Low[i], Close[i+1]);
       BPBuffer[i] = Close[i] - TL;
     }
   for(i = limit2; i >= 0; i--)
     {
       RawUO = fastK*iMAOnArray(BPBuffer, 0, fastperiod, 0, MODE_SMA, i) / 
               iATR(NULL, 0, fastperiod, i) +
               middleK*iMAOnArray(BPBuffer, 0, middleperiod, 0, MODE_SMA, i) /
               iATR(NULL, 0, middleperiod, i) +
               slowK*iMAOnArray(BPBuffer, 0, slowperiod, 0, MODE_SMA, i) / 
               iATR(NULL, 0, slowperiod, i);
       UOBuffer[i] = RawUO / divider*100;
     }     
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments