Smart Money Index (SMI) Indicator for ThinkorSwim

So I'll take a stab at time based values here. I'm not sure what to anchor the first bar SMI value to, and someone else will likely find a serious flaw in what I've got going on.

This does plot.

This only works on charts 30 min and under. It will do odd things on longer time frames. There is no good way to get intraday information in thinkscript on daily timeframes.

My understanding of the SMI is that it takes the first hour and the last half hour. If the first hour is positive, the label is red, if the last half hour is negative, the label is read. This is intentional.

I tied the first value of the SMI to the close from the day before the chart starts. This is not ideal, perhaps, but gives you a reference for the SMI vs your chart over the length of time displayed on your chart.

Code:
# SMI Attempt 1
# @Mashume
# 2020-02-04

declare lower;
def b = BarNumber();

def opening_bell = if SecondsFromTime(0930) == 0 then open else if SecondsFromTime(0930) > 0 then opening_bell[1] else Double.NaN;

def end_opening_hour = if SecondsFromTime(1030) == 0 then close else if SecondsFromTime(1030) > 0 then end_opening_hour[1] else Double.NaN;

def start_last_thirty = if SecondsFromTime(1500) == 0 then open else if SecondsFromTime(1500) > 0 then start_last_thirty[1] else double.NaN;

def closing_bell = if secondsFromTime(1600) == 0 then close else if secondsFromTime(1600) > 0 then closing_bell[1] else double.nan;
# def closing_bell =  close(period = AggregationPeriod.DAY, priceType = PriceType.LAST);

def morning_change = end_opening_hour - opening_bell;
# AddLabel(yes, "m-o: " + opening_bell + "  1-h: " + end_opening_hour + "  DIFF: " + morning_change, Color.BLACK);
AddLabel(yes, "Morning: " + morning_change, if morning_change > 0 then color.red else color.green);

def afternoon_change = closing_bell - start_last_thirty;
# AddLabel(yes, "a-o: " + opening_bell + "  d-close: " + end_opening_hour + "  DIFF: " + afternoon_change, Color.BLACK);
AddLabel(yes, "Afternoon: " + afternoon_change, if afternoon_change < 0 then color.red else color.green);

def morning = morning_change;
def afternoon = afternoon_change;
plot previous_close = close(period = AggregationPeriod.DAY, priceType = PriceType.LAST)[1];
previous_close.setDefaultColor(color.dark_red);
# original:
def SMI_calc = if b == 1 then previous_close else if !IsNaN(morning) and !IsNaN(afternoon) then SMI_calc[1] - morning + afternoon else SMI_calc[1];

#day frame
# def SMI_calc = if isNaN(SMI_calc[1]) then previous_close else (SMI_calc[1] - morning) + afternoon ;
AddLabel(yes, "SMI: " + SMI_calc, Color.BLUE);
plot SMI = SMI_calc;
SMI.SetDefaultColor(color.blue);
AddCloud(SMI,  previous_close,  Color.LIME,  Color.PINK);

Perhaps this gets one of you closer to a real solution to the problem.

happy trading, mashume
 
Here is the Smart Money Index indicator I converted to ThinkorSwim. Check it out.

OLnsODa.png



Ruby:
#Smart Money Index (50) - SMI(50)
#
#CREDITS
#https://www.tradingview.com/script/YyNeevML-Smart-Money-Index-SMI-Backtest/
#https://www.tradingview.com/u/HPotter/

#CHANGELOG
#2019.11.02 @diazlaz Initial Port

declare lower;

input AggPeriod = AggregationPeriod.HOUR;
input length1  = 50; #MA_Len

def xcloseH1 = close(period = AggPeriod);
def xopenH1  = open(period = AggPeriod);
def nRes = CompoundValue(1, nRes[1] - (open - close) + (xopenH1 - xcloseH1), 1);


plot pSMI = nRes;
pSMI.AssignValueColor(COLOR.LIME);
pSMI.SetLineWeight(2);

plot pMA50 = Average(nRes, length1);
pMA50.AssignValueColor(COLOR.YELLOW);


I've been trying to use this as a scanner through the TOS editor, but am not getting the results I wanted. I want to scan for when the smart money index is just over or completely over the moving average. I tried requesting that through the TOS editor in the scan feature itself, but am still getting results with the complete opposite of what I'm looking for.

Any help would be appreciated!
 
@Docbrown83 Can you please post a screenshot of your scanner and results? Don't know how to upload screenshots to the forum? Here are directions.
Hi MerryDay,

I cannot add it via the attachment link for some odd reason, even after posting it through imgur and getting the BBcode..... it won't let me do so which is strange?

Anyways, here is what I had for the scan:

#Smart Money Index (50) - SMI(50)
#
#CREDITS
#https://www.tradingview.com/script/YyNeevML-Smart-Money-Index-SMI-Backtest/
#https://www.tradingview.com/u/HPotter/


#CHANGELOG
#2019.11.02 @diazlaz Initial Port

declare lower;

input AggPeriod = AggregationPeriod.four_days;
input pma1 = 50; #MA_Len

def xcloseH1 = close(period = AggPeriod);
def xopenH1 = open(period = AggPeriod);
def nRes = CompoundValue(1, nRes[1] - (open - close) + (xopenH1 - xcloseH1), 1);


def pSMI = nRes;


def pMA50 = Average(nRes, pma1);



def UpSignal = if pSMI crosses below pma50 then pma50 else Double.NaN;
def DownSignal = if psMI crosses above pma50 then pma50 else Double.NaN;

plot scan = Dowsignal;






I have the aggregation for four days and made sure to put that in for the scan as well?

Any help would be appreciated
 
@Docbrown83
The SMI Smart Money Indicator study that you shared in your post requires looking at a higher time period chart (4 days) and comparing it to whatever timeframe you are scanning on. Unfortunately, multiple time periods are not allowed to be used in scans on the TOS platform.
So this script cannot be used to scan.

The Peculiarities Of Secondary Aggregations
The secondary aggregation period can not be referenced in scans on the TOS platform.
https://tlc.thinkorswim.com/center/...hapter-11---Referencing-Secondary-Aggregation
 
@Docbrown83 I think you're making inserting an image to be more complicated than it has to be... Once you click on the BBCode (message boards and forums) Copy button all you need to do is Paste the link into your post and it will initially display a line similar to what was displayed in the BBCode box... The code for the mage below has the link code [ATTACH=full]11694[/ATTACH]... That image was from a previous answer elsewhere here in these forums... It's just Copy & Paste except using the Copy button in imgur and Pasting here...

s3VMa3q.png
 
So I'll take a stab at time based values here. I'm not sure what to anchor the first bar SMI value to, and someone else will likely find a serious flaw in what I've got going on.

This does plot.

This only works on charts 30 min and under. It will do odd things on longer time frames. There is no good way to get intraday information in thinkscript on daily timeframes.

My understanding of the SMI is that it takes the first hour and the last half hour. If the first hour is positive, the label is red, if the last half hour is negative, the label is read. This is intentional.

I tied the first value of the SMI to the close from the day before the chart starts. This is not ideal, perhaps, but gives you a reference for the SMI vs your chart over the length of time displayed on your chart.

Code:
# SMI Attempt 1
# @Mashume
# 2020-02-04

declare lower;
def b = BarNumber();

def opening_bell = if SecondsFromTime(0930) == 0 then open else if SecondsFromTime(0930) > 0 then opening_bell[1] else Double.NaN;

def end_opening_hour = if SecondsFromTime(1030) == 0 then close else if SecondsFromTime(1030) > 0 then end_opening_hour[1] else Double.NaN;

def start_last_thirty = if SecondsFromTime(1500) == 0 then open else if SecondsFromTime(1500) > 0 then start_last_thirty[1] else double.NaN;

def closing_bell = if secondsFromTime(1600) == 0 then close else if secondsFromTime(1600) > 0 then closing_bell[1] else double.nan;
# def closing_bell =  close(period = AggregationPeriod.DAY, priceType = PriceType.LAST);

def morning_change = end_opening_hour - opening_bell;
# AddLabel(yes, "m-o: " + opening_bell + "  1-h: " + end_opening_hour + "  DIFF: " + morning_change, Color.BLACK);
AddLabel(yes, "Morning: " + morning_change, if morning_change > 0 then color.red else color.green);

def afternoon_change = closing_bell - start_last_thirty;
# AddLabel(yes, "a-o: " + opening_bell + "  d-close: " + end_opening_hour + "  DIFF: " + afternoon_change, Color.BLACK);
AddLabel(yes, "Afternoon: " + afternoon_change, if afternoon_change < 0 then color.red else color.green);

def morning = morning_change;
def afternoon = afternoon_change;
plot previous_close = close(period = AggregationPeriod.DAY, priceType = PriceType.LAST)[1];
previous_close.setDefaultColor(color.dark_red);
# original:
def SMI_calc = if b == 1 then previous_close else if !IsNaN(morning) and !IsNaN(afternoon) then SMI_calc[1] - morning + afternoon else SMI_calc[1];

#day frame
# def SMI_calc = if isNaN(SMI_calc[1]) then previous_close else (SMI_calc[1] - morning) + afternoon ;
AddLabel(yes, "SMI: " + SMI_calc, Color.BLUE);
plot SMI = SMI_calc;
SMI.SetDefaultColor(color.blue);
AddCloud(SMI,  previous_close,  Color.LIME,  Color.PINK);

Perhaps this gets one of you closer to a real solution to the problem.

happy trading, mashume


According to Lindas book, this is the formula for SMI


"
Here is how you create the index.

  1. Take the net change for the first hour in the Dow. Multiply it by -1. For example, if yesterday's close in the Dow was 4980 and after the first hour of trading today the Dow closes at 4985, it would have a net change of +5. Multiply this by -1 to get -5.
  2. Take the net change for the last hour in the Dow and add it to the final number in rule 1. For example, if the Dow is at 4990 at 3:00 EST and closes the day at 4984 (4:00 EST), we add the last hour's net change of -6 to –5 for a total of -11 on the day.

  3. A running summation index of the first hour (inverted) net change and the last hour's net change is logged "
 
Hello I have taken a stab at creating an SMI-esque indicator based on the following but wanted to have an option to use S&P thus the inputs for symbols. I think it's almost there. Issue is collecting the last hour of the previous day....not sure if it is correct. I have looked at it for too long and hope that someone who's much better at coding than I am will have the time to take a look.

Thanks

How are the SMI and SMFI calculated?​

The Smart Money Flow Index (SMFI) and the Smart Money Indicator (SMI) are both indicators used to identify the buying behavior of institutional investors. However, their calculation methods are different. The Smart Money Flow Index (SMFI) formula is proprietary and not publicly available, while the SMI formula, developed by Don Hays, is as follows:
  1. Calculate the Dow Jones Industrial Average’s gain or loss in points after the first half hour of trading (9:30 a.m. – 10 a.m.)
  2. Calculate the Dow Jones Industrial Average’s gain or loss in points during the last hour of trading (3 p.m. – 4 p.m.)
  3. Today’s Smart Money Index = yesterday’s Smart Money Index – the market’s gain/loss in the first half hour of trading today + the market’s gain/loss in the last hour of trading today. As first value for the Smart Money Index just use yesterday’s closing price of the Dow Jones Industrial on that day.
For example, if the Smart Money Index’s value yesterday was 100, and the Dow Jones Industrial Average gained 20 points in the first half hour and lost 40 points in the last hour, the Smart Money Index’s latest value would be 100 – 20 + (-40) = 80. The Smart Money Index by Don Hays can be calculated for any security.






declare lower;

input marketOpenTime = 0930; # Market open time (9:30 a.m. ET)
input marketCloseTime = 1600; # Market close time (4:00 p.m. ET)
input volumePeriod = 20; # Period for calculating average volume
input stockSymbol = "AAPL"; # Stock symbol of your choice
input sp500Symbol = "SPY"; # S&P 500 symbol (for example, using SPY ETF)

def isFirst30Mins = SecondsFromTime(marketOpenTime) <= 0;
def isLastHour = SecondsTillTime(marketCloseTime) <= 0;

# Fetch historical data for the stock
def stockPriceFirst30Mins = if isFirst30Mins then close(stockSymbol) else stockPriceFirst30Mins[1];
def stockGainLossFirst30Mins = close(stockSymbol) - stockPriceFirst30Mins;

def stockPriceLastHour = if isLastHour then close(stockSymbol) else stockPriceLastHour[1];
def stockGainLossLastHour = close(stockSymbol) - stockPriceLastHour;

# Fetch historical data for the S&P 500 (SPY)
def sp500PriceFirst30Mins = if isFirst30Mins then close(sp500Symbol) else sp500PriceFirst30Mins[1];
def sp500GainLossFirst30Mins = close(sp500Symbol) - sp500PriceFirst30Mins;

def sp500PriceLastHour = if isLastHour then close(sp500Symbol) else sp500PriceLastHour[1];
def sp500GainLossLastHour = close(sp500Symbol) - sp500PriceLastHour;

def calculatedSMIStock = stockGainLossLastHour - stockGainLossFirst30Mins;
def calculatedSMISp500 = sp500GainLossLastHour - sp500GainLossFirst30Mins;

# Plot SMI lines
plot SMIStock = calculatedSMIStock;
SMIStock.AssignValueColor(if calculatedSMIStock > calculatedSMIStock[1] then Color.GREEN else Color.RED);
SMIStock.SetLineWeight(2);

plot SMISp500 = calculatedSMISp500;
SMISp500.AssignValueColor(if calculatedSMISp500 > calculatedSMISp500[1] then Color.GREEN else Color.RED);
SMISp500.SetLineWeight(2);

# Calculate SMI Divergence
def priceHigh = high(stockSymbol);
def priceLow = low(stockSymbol);
def SMIHigh = SMIStock[1];
def SMILow = SMIStock[1];
def bearishDivergence = priceHigh > priceHigh[1] and SMIStock < SMIHigh;
def bullishDivergence = priceLow < priceLow[1] and SMIStock > SMILow;

# Calculate Overbought and Oversold Levels
def overboughtLevel = 100;
def oversoldLevel = -100;
def isOverbought = SMIStock > overboughtLevel;
def isOversold = SMIStock < oversoldLevel;

# Calculate Crosses of Zero Line
def crossesAboveZero = SMIStock > 0 and SMIStock[1] <= 0;
def crossesBelowZero = SMIStock < 0 and SMIStock[1] >= 0;

# Calculate Average Volume
def avgVolume = Average(volume(stockSymbol), volumePeriod);

# Calculate Volume Analysis
def volumeThreshold = avgVolume * 1.5; # Define your volume threshold (e.g., 1.5 times the average volume)
def highVolume = volume(stockSymbol) >= volumeThreshold;
def lowVolume = volume(stockSymbol) < volumeThreshold;

# Add labels to display signals and SMI values for the stock
AddLabel(yes, "Stock: Smart Money Index: $" + AsPrice(calculatedSMIStock), if calculatedSMIStock > calculatedSMIStock[1] then Color.GREEN else Color.RED);
AddLabel(bullishDivergence, "Bullish Divergence", Color.GREEN);
AddLabel(bearishDivergence, "Bearish Divergence", Color.RED);
AddLabel(isOverbought, "Stock: Overbought", Color.RED);
AddLabel(isOversold, "Stock: Oversold", Color.GREEN);
AddLabel(crossesAboveZero, "Stock: Cross Above Zero", Color.GREEN);
AddLabel(crossesBelowZero, "Stock: Cross Below Zero", Color.RED);
AddLabel(highVolume, "Stock: High Volume", Color.GREEN);
AddLabel(lowVolume, "Stock: Low Volume", Color.RED);

# Calculate SMI Divergence for S&P 500
def SMIHighSp500 = SMISp500[1];
def SMILowSp500 = SMISp500[1];
def bearishDivergenceSp500 = priceHigh > priceHigh[1] and SMISp500 < SMIHighSp500;
def bullishDivergenceSp500 = priceLow < priceLow[1] and SMISp500 > SMILowSp500;

# Calculate Overbought and Oversold Levels for S&P 500
def isOverboughtSp500 = SMISp500 > overboughtLevel;
def isOversoldSp500 = SMISp500 < oversoldLevel;

# Calculate Crosses of Zero Line for S&P 500
def crossesAboveZeroSp500 = SMISp500 > 0 and SMISp500[1] <= 0;
def crossesBelowZeroSp500 = SMISp500 < 0 and SMISp500[1] >= 0;

# Add labels to display signals and SMI values for S&P 500
AddLabel(yes, "S&P 500: Smart Money Index: $" + AsPrice(calculatedSMISp500), if calculatedSMISp500 > calculatedSMISp500[1] then Color.GREEN else Color.RED);
AddLabel(bullishDivergenceSp500, "S&P 500: Bullish Divergence", Color.GREEN);
AddLabel(bearishDivergenceSp500, "S&P 500: Bearish Divergence", Color.RED);
AddLabel(isOverboughtSp500, "S&P 500: Overbought", Color.RED);
AddLabel(isOversoldSp500, "S&P 500: Oversold", Color.GREEN);
AddLabel(crossesAboveZeroSp500, "S&P 500: Cross Above Zero", Color.GREEN);
AddLabel(crossesBelowZeroSp500, "S&P 500: Cross Below Zero", Color.RED);

# Plot zeroline
Plot zeroline = 0;
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
182 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top