SMM VERSION 5.0
SMM VERSION 5.0
************************************************
//
// These metrics are not to be reproduced, copied, or distributed to anyone besides
the original owner.
// Doing so is in direct violation of Simple Market Metrics policies, and penalties
will apply.
//
// https://simplemarketmetrics.gumroad.com/l/ddcud
//
//
***********************************************************************************
*****************
//@version=5
indicator("Simple Market Metrics v5", max_lines_count=500, max_labels_count=500,
behind_chart=false) // SMM v5
var const string tpRules = "\n\n2. How to exit a trade:\n• Take profit when the
price reaches the profit target line"
var const string exitRules = "\n• Stop out of the trade if the white dot remains on
the opposite side of the profit wave only when the candle has closed."
var const string exitExample = "\n\ne.g. If you are in a long trade, and a candle
closes with the white dot below the profit wave, close the trade."
var const string tradingRules = titleRules + signalRules + entryRules + tpRules +
exitRules + exitExample
var const string finalNotes = "Some final notes:\n\nThe Simple Market Metrics
trading system has been built specifically for trading the ES & NQ Futures markets,
with the goal of small but consistent daily profits."
var const string finalNotes1 = "\n\nAlthough you may trade any market and timeframe
you wish, it is up to you to determine the best settings for other markets and
timeframes."
var const string finalNotes2 = "\n\nTrading is risky, do not trade with money you
are not comfortable losing.\nControl your risk by managing your position size
accordingly, and please practice on a sim account before using real money."
var const string finalNotes3 = "\n\nIf you need further assistance, contact us at
simplemarketmetrics@gmail.com"
var const string notesText = finalNotes + finalNotes1 + finalNotes2 + finalNotes3
//Signals Inputs
var signalsGroupName = '----- Signal Settings -----'
enableBuySellSignals = input.bool(true,title='Enable Buy & Sell Signals',
group=signalsGroupName)
startHour = input.int(9, title="Start Time (HH:mm)", minval=0, maxval=23,
group=signalsGroupName, inline="startTime")
startMinute = input.int(0, title=":", minval=0, maxval=59, group=signalsGroupName,
inline="startTime", tooltip="This time is based on timezone of the exchange, NOT
the timezone your chart is set to. So please adjust accordingly. e.g. The exchange
for NQ & ES are in the Central Timezone.")
endHour = input.int(11, title="End Time (HH:mm)", minval=0, maxval=23,
group=signalsGroupName, inline="endTime")
endMinute = input.int(0, title=":", minval=0, maxval=59, group=signalsGroupName,
inline="endTime")
// Profit Inputs
var profitWaveGroupName = '----- Profit Settings -----'
enableProfitLines = input.bool(true, title='Enable Profit Target Lines',
group=profitWaveGroupName)
profitTarget = input.int(20, title='Profit Target (Ticks/Pips/Cents)',
group=profitWaveGroupName, tooltip='Profit target value is based on the minimum
move of the instrument. For Futures that is ticks, FX is pips, Stocks are cents,
etc.')
profitTargetMaxLines = input.int(10, title='Max Profit Target Lines',
group=profitWaveGroupName, tooltip='Maximum amount of profit target lines to
display on your chart.')
profitTargetColor = input.color(color.new(color.yellow, 0),'Profit Target Lines
Color', group=profitWaveGroupName)
enableProfitWave = input.bool(true, "Enable Profit Wave",
group=profitWaveGroupName)
profitWaveUpperBullishColor = input.color(color.new(#00ff8480, 50),'Profit Wave
Bullish Top Color', group=profitWaveGroupName)
profitWaveLowerBullishColor = input.color(color.new(color.green, 50), 'Profit Wave
Bullish Bottom Color', group=profitWaveGroupName)
profitWaveLowerBearishColor = input.color(color.new(#8c0000, 50), 'Profit Wave
Bearish Top Color', group=profitWaveGroupName)
profitWaveUpperBearishColor = input.color(color.new(#ff0000, 50),'Profit Wave
Bearish Bottom Color', group=profitWaveGroupName)
// Matrix Inputs
var matrixGroupName = '----- Matrix Settings -----'
var matrixInlineName = "matrixInlineName"
matrixStyle = input.string("Horizontal", "Layout Style", options=["Horizontal",
"Vertical"], group=matrixGroupName)
matrixPosition = input.string("Bottom Right", "Location On Chart", options=["Top
Left", "Top Center", "Top Right", "Bottom Left", "Bottom Center", "Bottom Right"],
group=matrixGroupName)
// Dashboard Inputs
var dashboardSettings = "----- Dashboard Settings -----"
positionMatrixOnTop = input.bool(true, "Show Matrix History Above Money Flow?",
group=dashboardSettings)
enableMatrixDashboard1 = input.bool(true, "Enable Matrix History for Timeframe 1",
group=dashboardSettings)
enableMatrixDashboard2 = input.bool(true, "Enable Matrix History for Timeframe 2",
group=dashboardSettings)
enableMatrixDashboard3 = input.bool(true, "Enable Matrix History for Timeframe 3",
group=dashboardSettings)
enableMatrixDashboardLabels = input.bool(true, "Enable Matrix Timeframe Labels",
group=dashboardSettings)
// Others
disableWarning := input.bool(false, title="Disable Heikin Ashi Warning",
group="Other Settings")
//
-----------------------------------------------------------------------------------
-----------------------------------------------
startTime = timestamp(year, month, dayofmonth, startHour, startMinute)
endTime = timestamp(year, month, dayofmonth, endHour, endMinute)
isValidTimeRange = (time >= startTime and time < endTime)
if na(myLabel)
myLabel := label.new(x=middle_bar_index, y=middle_price, text=warningText,
xloc=xloc.bar_index, yloc=yloc.price, style=label.style_label_center,
color=color.red, textcolor=color.white, size=size.huge,
textalign=text.align_center, force_overlay=true)
else
myLabel.set_x(middle_bar_index)
myLabel.set_y(middle_price)
labelDisplayed := true
srcHlc3 = hlc3
srcOpen = open
srcHigh = high
srcLow = low
srcClose = close
profitWaveEmaFast = ta.ema(srcClose, 8)
profitWaveEmaMedium = ta.ema(srcClose, 13)
profitWaveEmaSlow = ta.ema(srcClose, 21)
chopSensitivity = 1
trueRange = math.max(math.max(high-low, math.abs(high-nz(close[1]))), math.abs(low-
nz(close[1])))
diPlusCalculation = high-nz(high[1]) > nz(low[1])-low ? math.max(high-nz(high[1]),
0): 0
diMinusCalculation = nz(low[1])-low > high-nz(high[1]) ? math.max(nz(low[1])-low,
0): 0
smoothedTrueRange = 0.0
smoothedTrueRange := nz(smoothedTrueRange[1]) -
(nz(smoothedTrueRange[1])/chopSensitivity) + trueRange
smoothedDiPlus = 0.0
smoothedDiPlus := nz(smoothedDiPlus[1]) - (nz(smoothedDiPlus[1])/chopSensitivity) +
diPlusCalculation
smoothedDiMinus = 0.0
smoothedDiMinus := nz(smoothedDiMinus[1]) -
(nz(smoothedDiMinus[1])/chopSensitivity) + diMinusCalculation
float trendUp = na
float trendDown = na
trendSwitch = 0
backgroundTrendColor = color.white
if (trendDirection == trendUp)
backgroundTrendColor := bgTrendBullishCol
else if (trendDirection == trendDown)
backgroundTrendColor := bgTrendBearishCol
else
backgroundTrendColor := backgroundTrendColor[1]
enum Mode
buy = "Buy Mode"
sell = "Sell Mode"
none = "none"
if (backgroundTrendColor != backgroundTrendColor[1])
currentMode := Mode.none
// Bullish signals
maFilterBuy = enableMaFilter ? srcOpen > maFilter : true
mfiBuy = enableChopFilter ? mfl > 52 : true
buy_con = buySignal and backgroundTrendColor == bgTrendBullishCol and
strongBullishCandle and currentMode != Mode.buy and mfiBuy and canBuy
if (buy_con and enableBuySellSignals)
currentMode := Mode.buy
if isValidTimeRange and maFilterBuy
label.new(bar_index, low, style=label.style_label_up, color=buySignalColor,
size=size.normal, yloc=yloc.belowbar, text="Buy"+realClosePriceText,
textcolor=color.white, force_overlay=true)
currentSignalBarIndex := bar_index
// Bearish signals
maFilterSell = enableMaFilter ? srcOpen < maFilter : true
mfiSell = enableChopFilter ? mfl < 52 : true
sell_con = sellSignal and backgroundTrendColor == bgTrendBearishCol and
strongBearishCandle and currentMode != Mode.sell and mfiSell and canSell
if (sell_con and enableBuySellSignals)
currentMode := Mode.sell
if isValidTimeRange and maFilterSell
label.new(bar_index, high, style=label.style_label_down,
color=sellSignalColor, size=size.normal, yloc=yloc.abovebar,
text="Sell"+realClosePriceText, textcolor=color.white, force_overlay=true)
currentSignalBarIndex := bar_index
// Signal Alerts
alertcondition(condition=buy_con and canBuy,title='Buy alert', message='Buy')
alertcondition(condition=sell_con and canSell,title='Sell alert', message='Sell')
// Function to manage line limits (removing the oldest line if limit is exceeded)
f_manage_line_limit(array<line> linesArray, array<int> touchBarsArray) =>
if array.size(linesArray) > maxSrLines
// Delete the first (oldest) line
line.delete(array.shift(linesArray))
// Remove the first touch bar value
array.shift(touchBarsArray)
// Loop through the resistance lines and stop their extension if the price touches
them
if array.size(resistanceLines) > 0
resLineStop = extendLinesType == 'Close' ? srcClose : srcHigh
for i = 0 to array.size(resistanceLines) - 1
line currentResistanceLine = array.get(resistanceLines, i)
resistancePrice = line.get_y1(currentResistanceLine)
touchBar = array.get(resistanceTouchBars, i)
// Check if the price touches the resistance and we haven't already stopped
the line
if na(touchBar) and resLineStop >= resistancePrice
line.set_x2(currentResistanceLine, bar_index)
line.set_extend(currentResistanceLine, extend.none)
array.set(resistanceTouchBars, i, bar_index) // Store the bar where
the price touched
// Loop through the support lines and stop their extension if the price touches
them
if array.size(supportLines) > 0
supLineStop = extendLinesType == 'Close' ? srcClose : srcLow
for i = 0 to array.size(supportLines) - 1
line currentSupportLine = array.get(supportLines, i)
supportPrice = line.get_y1(currentSupportLine)
touchBar = array.get(supportTouchBars, i)
// Check if the price touches the support and we haven't already stopped
the line
if na(touchBar) and supLineStop <= supportPrice
line.set_x2(currentSupportLine, bar_index)
line.set_extend(currentSupportLine, extend.none)
array.set(supportTouchBars, i, bar_index) // Store the bar where the
price touched
bottom_1 = hline(enableDashboard ? 0 :
na,color=color.new(#047200,50),linestyle=hline.style_solid)
bottom_2 = hline(enableDashboard ? 10 :
na,color=color.new(#047e00,50),linestyle=hline.style_solid)
bottom_3 = hline(enableDashboard ? 20 :
na,color=color.new(#048900,50),linestyle=hline.style_solid)
bottom_4 = hline(showInsideLines and enableDashboard ? 30 :
na,color=color.new(#059f00,50),linestyle=hlineStyle)
bottom_5 = hline(showInsideLines and enableDashboard ? 40 :
na,color=color.new(#06b200,50),linestyle=hlineStyle)
bottom_6 = hline(showInsideLines and enableDashboard ? 50 :
na,color=color.new(#06b200,100),linestyle=hlineStyle)
getMatrixTrendData(timeframe) =>
[mTrendDirection, mTrendUp, mTrendDown] = request.security(syminfo.tickerid,
timeframe, GetTrendDirection(srcHigh, srcLow))
mBackgroundTrendColor = color.gray
mTrendTextColor = color.white
mTrendStatus = ""
if (mTrendDirection == mTrendUp)
mBackgroundTrendColor := matrixBullishColor
mTrendTextColor := matrixBullishTextColor
mTrendStatus := "Bullish"
else if (mTrendDirection == mTrendDown)
mBackgroundTrendColor := matrixBearishColor
mTrendTextColor := matrixBearishTextColor
mTrendStatus := "Bearish"
else
mBackgroundTrendColor := mBackgroundTrendColor[1]
mTrendTextColor := mTrendTextColor[1]
mTrendStatus := mTrendStatus[1]
[mTrendStatus, mBackgroundTrendColor, mTrendTextColor]
[mCandleStatus, mCandleColor]
getMatrixMfiData(timeframe) =>
mMfi = request.security(syminfo.tickerid, timeframe, ta.mfi(srcHlc3, 10))
mMfiColor = color.gray
mMfiTextColor = color.white
mMfiStatus = ""
if (mMfi > 50)
mMfiColor := matrixBullishColor
mMfiTextColor := matrixBullishTextColor
mMfiStatus := "Bullish"
else if (mMfi < 50)
mMfiColor := matrixBearishColor
mMfiTextColor := matrixBearishTextColor
mMfiStatus := "Bearish"
else
mMfiColor := mMfiColor[1]
mMfiTextColor := mMfiTextColor[1]
mMfiStatus := mMfiStatus[1]
getMatrixAtr(timeframe) =>
atrValue = request.security(syminfo.tickerid, timeframe,
ta.atr(matrixAtrLength))
str.tostring(atrValue, "#.#")
getMatrixHeaderCol(col) =>
matrixStyle == "Vertical" ? 0 : col
getMatrixHeaderRow(row) =>
matrixStyle == "Vertical" ? row : 0
getMatrixTfCol(col) =>
matrixStyle == "Vertical" ? col : 0
getMatrixTfRow(tf, row) =>
matrixStyle == "Vertical" ? row : tf
getMatrixDataCol(tf, col) =>
matrixStyle == "Vertical" ? tf : col
getMatrixDataRow(tf, row) =>
matrixStyle == "Vertical" ? row : tf
var columns = 6
var rows = 4
if matrixStyle == "Vertical"
columns := 4
rows := 6
if enableMatrixTF1
m1Atr = getMatrixAtr(matrixTF1)
[m1CandleStatus, m1CandleColor] = getMatrixCandleData(matrixTF1,
m1TrendStatus, m1ProfitWaveStatus)
if enableMatrixTF2
m2Atr = getMatrixAtr(matrixTF2)
[m2CandleStatus, m2CandleColor] = getMatrixCandleData(matrixTF2,
m2TrendStatus, m2ProfitWaveStatus)
if enableMatrixTF3
m3Atr = getMatrixAtr(matrixTF3)
[m3CandleStatus, m3CandleColor] = getMatrixCandleData(matrixTF3,
m3TrendStatus, m3ProfitWaveStatus)
lw_plots = 4
plotStyle = plot.style_stepline
if positionMatrixOnTop
md1Trend := enableMatrixDashboard1 ? md1Profit + 5 : 100
md1Profit := enableMatrixDashboard1 ? md1Mfi + 5 : 100
md1Mfi := enableMatrixDashboard1 ? md2Trend + 10 : 100
md2Trend := enableMatrixDashboard2 ? md2Profit + 5 : md3Trend
md2Profit := enableMatrixDashboard2 ? md2Mfi + 5 : md3Profit
md2Mfi := enableMatrixDashboard2 ? md3Trend + 10 : md3Mfi
md3Trend := enableMatrixDashboard3 ? 120 : 100
md3Profit := enableMatrixDashboard3 ? 115 : 100
md3Mfi := enableMatrixDashboard3 ? 110 : 100