Author: Copyright � 2005, MetaQuotes Software Corp.
SMI_v1

This script is designed as a custom technical analysis tool for the MetaTrader platform. It generates a specialized visual indicator, known as the Stochastic Momentum Index (SMI), which helps traders understand the relationship between price momentum and the overall range of market movement.

Core Logic Overview

The tool functions by analyzing three primary components of market data: the highest price reached, the lowest price reached, and the current closing price over specific timeframes. It processes these figures through a multi-layered smoothing calculation to filter out "market noise" and highlight significant trends.

Step-by-Step Process

1. Range and Position Analysis First, the script looks back at a defined number of historical candles (controlled by the Period_Q setting). It identifies the highest peak and the lowest trough within that window to establish the total price range. Simultaneously, it calculates where the current closing price sits relative to the midpoint of that high-low range.

2. Momentum Calculation The script then focuses on the difference between the current price and that calculated midpoint. This helps determine whether the price is currently pushing toward the top of its recent range or falling toward the bottom, providing a snapshot of "momentum."

3. Multi-Layer Smoothing (EMA) To ensure the indicator doesn't react too sharply to every tiny price flicker, the script applies several rounds of Exponential Moving Averages (EMAs). It smooths the momentum data through multiple passes:

  • It calculates averages based on the Period_R and Period_S settings.
  • This "double-smoothing" process cleans up the data, making it easier to identify the underlying trend rather than temporary spikes.

4. Final Index Generation The final SMI value is produced by dividing the smoothed momentum by the smoothed price range. This result is then scaled by a factor of 100 to provide a readable percentage-like figure on your chart.

5. The Signal Line In addition to the main SMI line, the script calculates a "Signal" line. This is an additional moving average of the SMI itself. By plotting both lines, traders can look for moments where the main indicator crosses over the signal line, which is often used to identify potential turning points in market direction.

Visual Output

The result is displayed in a separate window below your main price chart. It features two distinct lines:

  • SMI Line: Shows the primary momentum strength.
  • Signal SMI: Acts as a secondary reference point to confirm trend changes and filter out false signals.
Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
18 Views
0 Downloads
0 Favorites
SMI_v1
//+------------------------------------------------------------------+
//|                                                          SMI.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_buffers 2
#property indicator_color1 White
#property indicator_color2 Red
#property indicator_level1 0
//---- input parameters
extern int       Period_Q=2;
extern int       Period_R=8;
extern int       Period_S=5;
extern int       Signal=5;
//---- buffers
double SMI_Buffer[];
double Signal_Buffer[];
double SM_Buffer[];
double EMA_SM[];
double EMA2_SM[];
double EMA_HQ[];
double EMA2_HQ[];
double HQ_Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(8);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,SMI_Buffer);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,Signal_Buffer);
   SetIndexLabel(0,"SMI");
   SetIndexLabel(1,"Signal SMI");
   SetIndexBuffer(2,SM_Buffer);
   SetIndexBuffer(3,EMA_SM);
   SetIndexBuffer(4,EMA2_SM);
   SetIndexBuffer(5,EMA_HQ);
   SetIndexBuffer(6,EMA2_HQ);
   SetIndexBuffer(7,HQ_Buffer);

   IndicatorShortName("SMI("+Period_Q+","+Period_R+","+Period_S+","+Signal+")");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- TODO: add your code here
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
   int limit;
   int i;
//   double Median_Q[];
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   limit=Bars-Period_Q-counted_bars;
   if(counted_bars>0) counted_bars--;
//   ArrayResize(Median_Q,limit);
//   ArrayResize(HQ_Buffer,limit);
//   ArraySetAsSeries(Median_Q,true);
//   ArraySetAsSeries(HQ_Buffer,true);
   for (i=limit;i>=0;i--)
      {
      //Median_Q[i]=(High[Highest(NULL,0,MODE_HIGH,0,i)]+Low[Lowest(NULL,0,MODE_HIGH,0,i)])/2;
      HQ_Buffer[i]=High[Highest(NULL,0,MODE_HIGH,Period_Q,i)]-Low[Lowest(NULL,0,MODE_LOW,Period_Q,i)];
      SM_Buffer[i]=Close[i]-(High[Highest(NULL,0,MODE_HIGH,Period_Q,i)]+Low[Lowest(NULL,0,MODE_LOW,Period_Q,i)])/2;//Median_Q[i];
      }
//   for (i=limit;i>=0;i--)
//      {
//      SM_Buffer[i]=Close[i]-(High[Highest(NULL,0,MODE_HIGH,0,i)]+Low[Lowest(NULL,0,MODE_HIGH,0,i)])/2;//Median_Q[i];
//      }
   for (i=limit-Period_R;i>=0;i--)
      {
      EMA_SM[i]=iMAOnArray(SM_Buffer,0,Period_R,0,MODE_EMA,i);
      EMA_HQ[i]=iMAOnArray(HQ_Buffer,0,Period_R,0,MODE_EMA,i);
      }
   for (i=limit-Period_R-Period_S;i>=0;i--)
      {
      EMA2_SM[i]=iMAOnArray(EMA_SM,0,Period_S,0,MODE_EMA,i);
      EMA2_HQ[i]=iMAOnArray(EMA_HQ,0,Period_S,0,MODE_EMA,i);
      }
   for (i=limit-Period_R-Period_S-Signal;i>=0;i--)
      {
      SMI_Buffer[i]=100*EMA2_SM[i]/0.5/EMA2_HQ[i];
      }
   for (i=limit-Period_R-Period_S;i>=0;i--)
      {
      Signal_Buffer[i]=iMAOnArray(SMI_Buffer,0,Signal,0,MODE_EMA,i);
      }

//---- TODO: add your code here
   
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments