The Stochastic Money Flow Index (SMFI) is a technical indicator that combines the Stochastic Momentum Index (SMI) with the Money Flow Index (MFI).
Its purpose is to provide a deeper insight into market dynamics by incorporating buying and selling pressure into momentum calculations, rather than relying solely on price movements.
The MFI is used as the input for the SMI, allowing the SMFI to capture momentum based on money flow rather than just price action. This approach helps traders better understand market sentiment and potential reversals.
Input Basis:
By default, the MFI calculation uses the symbol's trading volume.
Alternatively, traders can use the daily VIX (volatility index) to analyze the broader market sentiment effect on the individual stock momentum.
use of the daily vix can cause repainting until the daily vix closes
How to Use the SMFI:
This study indicates reversals (which are defined by the Stoch smooth k crossing smooth d).
The reversals are highlighted with green and red verticals.
Oscillators have other possible entry and exit points as explained here:
https://usethinkscript.com/threads/how-to-read-an-oscillator-in-thinkorswim.11497/
You may need to untick the extended-hours if you selected "VIX" from the indicator settings.
CSS:
#/ Stochastic Money Flow Index for TOS
# based on indicator('Open Interest Stochastic Money Flow Index')
# Converted by Sam4Cok@Samer800 - 01/2025
declare lower;
input lights = yes;
input src = close;
input reverse = no;
input adaptiveType = {Default "Volume", "VIX" };
input mfiLength = 14; # 'MFI Period') // You can use non integer or mutable variables too !!
input StochLength = 14;
input OverSold = 20; # 'Oversold') // You can use non integer or mutable variables too !!
input OverBought = 80; # 'Overbought') // You can use non integer or mutable variables too !!
def na = Double.NaN;
def last = isNaN(close);
def dPos = Double.POSITIVE_INFINITY;
def dNeg = Double.NEGATIVE_INFINITY;
def time = GetTime();
def t1 = time >= RegularTradingStart(GetYYYYMMDD()) and time <= RegularTradingEND(GetYYYYMMDD());
def _switchable;
Switch (adaptiveType) {
Case "Volume" : _switchable = volume;
Default : _switchable = if t1 then close(Symbol = "VIX", Period = "DAY") else na;
}
#--- Color -----
DefineGlobalColor("up" , CreateColor(0, 127, 255));
DefineGlobalColor("dn" , CreateColor(255, 127, 0));
#// Essential Functions :
Script f_ema {
input _src = close;
input _length = 14;
def _length_adjusted = if _length < 1 then 1 else _length;
def _multiplier = 2 / (_length_adjusted + 1);
def _return = if !_return[1] then _src else (_src - _return[1]) * _multiplier + _return[1];
plot out = _return;
}
Script f_sum {
input _src = close;
input _length = 14;
def _length_adjusted = if _length < 1 then 1 else _length;
def _output = fold i = 0 to _length_adjusted with p do
p + _src[i];
plot out = _output;
}
#// FUNCTION HIGHEST AND LOWEST ( All Efforts goes to RicardoSantos )
Script f_highest {
input _src = high;
input _length = 14;
def _adjusted_length = if _length < 1 then 1 else _length;
def _value = fold _i = 0 to _adjusted_length with p = _src do
if _src[_i] >= p then _src[_i] else p;
plot _return = _value;
}
Script f_lowest {
input _src = high;
input _length = 14;
def _adjusted_length = if _length < 1 then 1 else _length;
def _value = fold _i = 0 to _adjusted_length with p = _src do
if _src[_i] <= p then _src[_i] else p;
plot _return = _value;
}
Script f_stoch {
input _src = hl2;
input _length = 14;
def ll = f_lowest(f_lowest(_src, 1), _length);
def hh = f_highest(f_highest(_src, 1), _length);
def f_stoch = 100 * (_src - ll) / (hh - ll);
plot out = f_stoch;
}
def change = src - src[1];
def upper_s = f_sum(_switchable * (if change <= 0 then 0 else src), mfiLength);
def lower_s = f_sum(_switchable * (if change >= 0 then 0 else src), mfiLength);
def _mfi = 100.0 - 100.0 / (1.0 + upper_s / lower_s);
#// Open Interest Stochastic Money Flow Index
def smoothK = floor(mfiLength / 3);
def smoothD = floor(StochLength / 3);
#// Definition : Variables K3 and D
def k3 = f_ema(f_stoch(_mfi, StochLength), smoothK);
def d = f_ema(k3, smoothD);
def pos_moment = (k3 Crosses Above d);
def neg_moment = (k3 Crosses Below d);
def col_bg = if pos_moment then 1 else if neg_moment then -1 else 0;
AddCloud(if col_bg>0 or col_bg[-1]>0 then dPos else na, dNeg, Color.DARK_GREEN);
AddCloud(if col_bg<0 or col_bg[-1]<0 then dPos else na, dNeg, Color.DARK_RED);
#// Plot data
plot kLine = k3; #, color = color.new(#0070FF, 0), title = 'K-line', linewidth = 1)
plot dLine = d; #, color = color.new(#FF8C00, 0), title = 'D-line', linewidth = 1)
plot os = if !last then OverSold else na; #, color = #C0C0C0, title = 'Oversold Level')
plot ob = if !last then OverBought else na; #, color = #C0C0C0, title = 'Overbought Level')
plot md = if !last then 50 else na;
kLine.SetDefaultColor(GlobalColor("up"));
dLine.SetDefaultColor(GlobalColor("dn"));
os.SetDefaultColor(Color.GRAY);
ob.SetDefaultColor(Color.GRAY);
md.SetDefaultColor(Color.DARK_GRAY);
os.SetPaintingStrategy(PaintingStrategy.DASHES);
ob.SetPaintingStrategy(PaintingStrategy.DASHES);
md.SetPaintingStrategy(PaintingStrategy.DASHES);
#// Barcolor (All efforts goes to Hpotter)
def pos = if k3 > d then 1 else -1;
def iff_1 = if reverse and pos == -1 then 1 else pos;
def possig = if reverse and pos == 1 then -1 else iff_1;
#// Switchable Barcolor Preference
def _lights = if lights then 1 else if !lights then -1 else 0;
def bcolor_on = _lights == 1.00;
def bcolor_off = _lights == -1.00;
input paintCandles = no ;
AssignPriceColor(if !paintCandles then color.current else
if possig == -1 and bcolor_on then Color.RED else
if possig == 1 and bcolor_on then Color.GREEN else Color.CURRENT);
# End of CODE
Last edited by a moderator: