SMI_v1
Download scriptThis 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_RandPeriod_Ssettings. - 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.
//+------------------------------------------------------------------+
//| 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