SMI_Correct-1

Download script
Author:
SMI_Correct-1

This script is a technical analysis tool designed to help traders visualize market momentum and identify potential trend shifts. It functions by calculating a "Stochastic Momentum Index" (SMI), which measures the relationship between current prices and recent price extremes (the highest highs and lowest lows over a specific timeframe).

Core Logic and Workflow

The script processes market data through four distinct layers to refine the information before presenting it on your chart:

1. Data Foundation (Price Positioning) First, the tool looks at a set number of previous candles to identify the highest peak and the lowest valley. It calculates two primary values:

  • The current distance between the closing price and the midpoint of that high-low range.
  • The total "height" (range) of that high-low area.

2. Smoothing Layer (Removing Noise) Because raw price action can be jagged and "noisy," the script applies a series of Exponential Moving Averages (EMA). It takes the values from Step 1 and smooths them out multiple times. This ensures that the indicator reacts to actual trends rather than temporary, insignificant price spikes.

3. The SMI Calculation The core SMI value is then derived by comparing the smoothed price position against the smoothed total range. By dividing these two figures and scaling them by a factor of 100, the script produces a normalized number. This allows traders to see where the current price sits relative to its recent history on a consistent scale (ranging from -100 to 100).

4. The Signal Line Finally, the script creates a "Signal" line. This is an additional moving average applied specifically to the SMI value itself.

How to Read the Results

The tool provides two primary lines on your chart:

  • SMI Line: Represents the current momentum of the market.
  • Signal Line: Acts as a reference point for the SMI.

By observing these two lines together, traders can look for "crossovers"—points where the momentum line moves above or below the signal line—which are often used to identify potential entry or exit points in a trade. The indicator also features horizontal levels (at 50, 0, and -50) to help determine if the market is currently in an overbought, oversold, or neutral state.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
11 Views
0 Downloads
0 Favorites
SMI_Correct-1
//+------------------------------------------------------------------+
//|                                                  SMI_Correct.mq4 |
//|                                      re-write by transport_david |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
//----
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 White
//----
#property indicator_maximum 100
#property indicator_minimum -100
//----
#property indicator_level1 50
#property indicator_level2 0
#property indicator_level3 -50
//---- input parameters
// MetaStock uses H/L (13) , 1st EMA(25) , 2nd EMA(2) , no signal line
// fmlabs does not recommend any settings
extern int Period_Q= 13; // HH LL
extern int Period_R= 25; // 1st EMA
extern int Period_S=  2; // 2nd EMA
extern int Signal=5; // Signal EMA
extern int ShowBars=1000;
//---- 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);
   SetIndexEmptyValue(0,0.0);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,Signal_Buffer);
   SetIndexLabel(0,"Signal SMI");
   //
   SetIndexEmptyValue(1,0.0);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,SMI_Buffer);
   SetIndexLabel(1,"SMI");
   //
   SetIndexEmptyValue(2,0.0);
   SetIndexBuffer(2,SM_Buffer);
   SetIndexStyle(2,DRAW_NONE);
   //
   SetIndexEmptyValue(3,0.0);
   SetIndexBuffer(3,EMA_SM);
   SetIndexStyle(3,DRAW_NONE);
   //
   SetIndexEmptyValue(4,0.0);
   SetIndexBuffer(4,EMA2_SM);
   SetIndexStyle(4,DRAW_NONE);
   //
   SetIndexEmptyValue(5,0.0);
   SetIndexBuffer(5,EMA_HQ);
   SetIndexStyle(5,DRAW_NONE);
   //
   SetIndexEmptyValue(6,0.0);
   SetIndexBuffer(6,EMA2_HQ);
   SetIndexStyle(6,DRAW_NONE);
   //
   SetIndexEmptyValue(7,0.0);
   SetIndexBuffer(7,HQ_Buffer);
   SetIndexStyle(7,DRAW_NONE);
   IndicatorShortName("SMI_Correct("+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 limit;
   int i;
//----
   limit=ShowBars;
   if (limit>=Bars - 1) limit=Bars - 1;
   for(i=limit;i>=0;i--)
     {                                                                                                                         // found at http://www.fmlabs.com/reference/default.htm?url=SMI.htm
      //                      highesthigh - lowestlow
      SM_Buffer[i]=Close[i]-((High[iHighest(Symbol(),0,MODE_HIGH,Period_Q,i)]+Low[iLowest(Symbol(),0,MODE_LOW,Period_Q,i)])/2); // SM_Buffer = Close - -------------------------
      //                                 2
      HQ_Buffer[i]=High[iHighest(Symbol(),0,MODE_HIGH,Period_Q,i)]-Low[iLowest(Symbol(),0,MODE_LOW,Period_Q,i)];                // HQ_Buffer = highesthigh - lowestlow
     }
   for(i=limit-Period_R;i>=0;i--)
     {
      EMA_SM[i]=iMAOnArray(SM_Buffer,0,Period_R,0,MODE_EMA,i);                                                                  // EMA_SM = EMA(SM_Buffer)
      EMA_HQ[i]=iMAOnArray(HQ_Buffer,0,Period_R,0,MODE_EMA,i);                                                                  // EMA_HQ = EMA(HQ_Buffer)
     }
   for(i=limit-Period_R-Period_S;i>=0;i--)
     {
      EMA2_SM[i]=iMAOnArray(EMA_SM,0,Period_S,0,MODE_EMA,i);                                                                    // EMA2_SM = EMA(EMA(SM_Buffer))
      EMA2_HQ[i]=iMAOnArray(EMA_HQ,0,Period_S,0,MODE_EMA,i);                                                                    // EMA2_HQ = EMA(EMA(HQ_Buffer))
     }
   for(i=limit-Period_R-Period_S-Signal;i>=0;i--)
     {                                                                                                                         //                  EMA2_SM
      SMI_Buffer[i]=100*(EMA2_SM[i]/(EMA2_HQ[i]/2));                                                                            // SMI = 100 x ( ------------- )
     }                                                                                                                         //                EMA2_HQ / 2
   for(i=limit-Period_R-Period_S;i>=0;i--)
     {
      Signal_Buffer[i]=iMAOnArray(SMI_Buffer,0,Signal,0,MODE_EMA,i);                                                            // Signal_Buffer = EMA(SMI_Buffer)
     }
//---- TODO: add your code here
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments