Modified on 2013/10/14 08:21 by Eugene — Categorized as: Community Indicators


DataSeries SMI (Bars bars, int period1, int period2, int period3, string description)
public static SMI Series(Bars bars, int period1, int period2, int period3)

Parameter Description

barsA Bars object to apply SMI to
period1First smoothing period (for the highest/lowest range)
period2Second smoothing period (for smoothing the distance of today's close from the midpoint of the range)
period3Third smoothing period (final smoothing; usually, period3 is equal to period2)


The Stochastic Momentum Index (SMI) by William Blau is an advancement of the familiar Stochastic Oscillator indicator, that shows the distance between the current close and the midpoint of the recent n-period High/Low range. The SMI ranges between +100 and -100 and is somewhat less erratic than a Stochastic Oscillator over the same period.


According to TAI - Stochastic Momentum Index, the SMI is calculated as follows:

Begin by selecting the desired range. We use n = 10.

Then calculate the midpoint price M of the highest high and the lowest low in the range:

    M = (HighMAX + LowMIN) / 2


HighMAX = the highest high in the range LowMIN = the lowest low in the range

Next calculate the difference (or “distance”) D of today’s closing price from the midpoint of the range:

    D = CPTODAY – M

where CPTODAY = today’s closing price

Then smooth the value of D twice with an exponential moving average. We use a three-period EMA:

    DS1 = EMA(3)(D)
    DS2 = EMA(3)(DS1)

Next, smooth the difference between the maximum high and minimum low twice, using the same EMA as before, and divide the second smoothed result by 2:

    DHL = EMA(3)(HighMAX - LowMIN)
    DHL2 = EMA(3)(DHL) / 2

Finally, calculate the SMI:

SMITODAY = 100 * (DS2 / DHL2)


The output of SMI varies between -100 and +100. When SMI rises above the threshold of +40, a sell signal is indicated. Similarly, if SMI falls below -40, a buy signal is indicated. Another common trading sign is that, when SMI crosses above moving average, a buy signal is generated, and when SMI crosses under moving average, a sell signal is generated.



using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using Community.Indicators;

namespace WealthLab.Strategies { public class SMIDemo : WealthScript { private StrategyParameter paramPeriod1; private StrategyParameter paramPeriod2; private StrategyParameter paramPeriod3; public SMIDemo() { paramPeriod1 = CreateParameter("Period 1", 10, 2, 20, 1); paramPeriod2 = CreateParameter("Period 2", 3, 2, 10, 1); paramPeriod3 = CreateParameter("Period 3", 3, 2, 20, 1); } protected override void Execute() { int per1 = paramPeriod1.ValueInt; int per2 = paramPeriod2.ValueInt; int per3 = paramPeriod3.ValueInt; SMI smi = SMI.Series( Bars,per1,per2,per3 );

for(int bar = GetTradingLoopStartBar(smi.FirstValidValue * 3); bar < Bars.Count; bar++) { if (IsLastPositionActive) { if( CrossUnder( bar, smi, -40 ) ) SellAtMarket( bar+1, LastPosition ); } else { if( CrossOver( bar, smi, 40 ) ) BuyAtMarket( bar+1 ); } } ChartPane sPane = CreatePane( 40,true,true ); PlotSeries( sPane, smi, Color.Fuchsia, LineStyle.Solid, 2 ); DrawHorzLine( sPane, 40, Color.Green, LineStyle.Dashed, 1 ); DrawHorzLine( sPane, -40, Color.Red, LineStyle.Dashed, 1 ); HideVolume(); } } }