Pocket Pivots and standard SMA/EMA's
//This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//© @path_to_profit (Twitter Handle) - Special Thanks to DavidOConnorSpain (Pocket Pivot Indicator), and MattDeLong (10-day Swingtrading system)

//@version=4

//@version =3
study(title="Pocket Pivots, SMA/EMA, and Slingshot", shorttitle="Swing Trading Indicators", precision=0,overlay =true)


myMaxVolume = volume
greenDay = close>open
redDay = open>close

//EMA Inputs
emasrc1 = input(high, title="EMA Source 1")
esrc0 = emasrc1, elen0 = input(04, minval=1, title="EMA 1")
emasrc2 = input(close, title="EMA Source 2")
esrc1 = emasrc2, elen1 = input(06, minval=1, title="EMA 2")
emasrc3 = input(close, title="EMA Source 3")
esrc2 = emasrc3, elen2 = input(10, minval=1, title="EMA 3")
emasrc4 = input(close, title="EMA Source 4")
esrc3 = emasrc4, elen3 = input(12, minval=1, title="EMA 4")
emasrc5 = input(close, title="EMA Source 5")
esrc4 = emasrc5, elen4 = input(20, minval=1, title="EMA 5")
ema1 = ema(esrc0, elen0)
ema2 = ema(esrc1, elen1)
ema3 = ema(esrc2, elen2)
ema4 = ema(esrc3, elen3)
ema5 = ema(esrc4, elen4)

//SMA inputs
len1 = input(10, minval=1, title="SMA 10")
out1 = sma(close, len1)
len2 = input(20, minval=1, title="SMA 20")
out2 = sma(close, len2)
len3 = input(50, minval=1, title="SMA 50")
out3 = sma(close, len3)
len4 = input(200, minval=1, title="SMA 200")
out4 = sma(close, len4)

// Plot SMA and EMA
plot(out1, title="SMA 10", linewidth=1, color = color.green, editable=true, display=display.none)
plot(out2, title="SMA 20", linewidth=1, color = color.red, editable=true, display=display.none)
plot(out3, title="SMA 50", linewidth=1, color = color.gray, editable=true)
plot(out4, title="SMA 200", linewidth=1, color = color.black, editable=true, display=display.none)
plot(ema1, title="EMA 1", linewidth=2, color = color.green, editable=true)
plot(ema2, title="EMA 2", linewidth=1, color = color.aqua, editable=true, display=display.none)
plot(ema3, title="EMA 3", linewidth=1, color = #1de5ff, editable=true)
plot(ema4, title="EMA 4", linewidth=1, color = #f57c00, editable=true, display=display.none)
plot(ema5, title="EMA 5", linewidth=2, color = #d32f2f, editable=true)

// Pocket pivot rules
myVolume1 = volume[1]
myVolume2 = volume[2]
myVolume3 = volume[3]
myVolume4 = volume[4]
myVolume5 = volume[5]
myVolume6 = volume[6]
myVolume7 = volume[7]
myVolume8 = volume[8]
myVolume9 = volume[9]
myVolume10 = volume[10]

//make all upday volumes = 0
if close[1]>open[1] 
    myVolume1= 0
if close[2]>open[2] 
    myVolume2= 0
if close[3]>open[3] 
    myVolume3= 0
if close[4]>open[4] 
    myVolume4= 0
if close[5]>open[5] 
    myVolume5= 0
if close[6]>open[6] 
    myVolume6= 0
if close[7]>open[7] 
    myVolume7= 0
if close[8]>open[8] 
    myVolume8= 0
if close[9]>open[9] 
    myVolume9= 0
if close[10]>open[10] 
    myVolume10= 0

// if any down days have volumes greater then the current volume, then it's not a pocket pivot
pocketPivot = myVolume1 < myMaxVolume and myVolume2 < myMaxVolume and myVolume3 < myMaxVolume and
 myVolume4 < myMaxVolume and myVolume5 < myMaxVolume and myVolume6 < myMaxVolume and myVolume7 < myMaxVolume and
 myVolume8 < myMaxVolume and myVolume9 < myMaxVolume and myVolume10 < myMaxVolume
 
insideBar  = (high < high[1]) and (low > low[1] and open > out3 and close > out3)
sellSignal = crossunder(close, ema3) and ema3 > ema5 and ema5>out3 and high[1] > ema3 and close > out2
candleBelow = close < out3

//only show pocket pivots on up days
pocketPivotDay = pocketPivot and greenDay 
barColour = (insideBar) ? color.green : na
resCandle = (candleBelow) ? color.orange : na
slingshot = close > ema1 and close[1] < ema1[1]+(ema1[1]/100*0.5) and close[2] < ema1[2]+(ema1[2]/100*0.5) and close[3] < ema1[3]+(ema1[3]/100*0.5)

plotshape(slingshot? 1:na, style=shape.square, location=location.abovebar, color=#000000, size=size.auto, title="Slingshot", editable=true)
plotshape(pocketPivotDay? 1:na, style=shape.circle, location=location.belowbar, color=#000000, size=size.auto, title="Pocket Pivot Day Color", editable=true)
plotshape(sellSignal, style=shape.circle, location=location.belowbar, color=color.red, size=size.auto, title="Caution Signal Color", editable=true)
//plotshape(sellSignal, style=shape.flag, location=location.abovebar, color=color.gray, size=size.small)
barcolor(color=barColour, title="Inside day bar color", editable=true)
barcolor(color=resCandle, title="Restriction Candles", editable=true)


//---------------------------------------------------------
// Support and Resistance
//----------------------------------------------------------

line_width = input(1, type = input.integer, title="Resistance line width")
level_min_lengh = input(3, type = input.integer, title="Set minimum number of bars from level start to qualify a level")
y  = input("Black", "Line Color", options=["Red", "Lime", "Orange", "Teal", "Yellow", "White", "Black"])
line_extend = input(false, type = input.bool, title = "Extend line Right") ? extend.right : extend.none
sr_tf = input("", type = input.resolution, title="SR Timeframe (Beta)")

//color function
colour(z) => z=="Red"?color.red:z=="Lime"?color.lime:z=="Orange"?color.orange:z=="Teal"?
 color.teal:z=="Yellow"?color.yellow:z=="Black"?color.black:color.white
 
//Legacy RSI calc
rsi_src = close, len = 9
up1 = rma(max(change(rsi_src), 0), len)
down1 = rma(-min(change(rsi_src), 0), len)
legacy_rsi = down1 == 0 ? 100 : up1 == 0 ? 0 : 100 - (100 / (1 + up1 / down1))

//CMO based on HMA
length = 1
src1 = hma(open, 7)[1] // legacy hma(5) calculation gives a resul with one candel shift, thus use hma()[1]
src2 = hma(close, 12)
momm1 = change(src1)
momm2 = change(src2)
f1(m, n) => m >= n ? m : 0.0
f2(m, n) => m >= n ? 0.0 : -m
m1 = f1(momm1, momm2)
m2 = f2(momm1, momm2)
sm1 = sum(m1, length)
sm2 = sum(m2, length)
percent(nom, div) => 100 * nom / div
cmo_new = percent(sm1-sm2, sm1+sm2)

//Legacy Close Pivots calcs.
len5 = 2
h = highest(len5)
h1 = dev(h, len5) ? na : h
hpivot = fixnan(h1)
l = lowest(len5)
l1 = dev(l, len5) ? na : l
lpivot = fixnan(l1)

//Calc Values

rsi_new = rsi(close,5)
lpivot_new =  lpivot  // use legacy pivots calculation as integrated pivotlow/pivothigh functions give very different result
hpivot_new =  hpivot

sup = rsi_new < 25 and cmo_new > 50  and lpivot_new
res = rsi_new > 75 and cmo_new < -50  and hpivot_new
calcXup() =>
    var xup = 0.0
    xup :=  sup ? low : xup[1]
calcXdown() =>
    var xdown = 0.0
    xdown := res ? high : xdown[1]

//Lines drawing variables
tf1 = security(syminfo.tickerid, sr_tf, calcXup(), lookahead=barmerge.lookahead_on)
tf2  = security(syminfo.tickerid, sr_tf, calcXdown(), lookahead=barmerge.lookahead_on)

//Plot Line of Least Resistance
var tf2_line = line.new(0, 0, 0, 0)
var tf2_bi_start = 0
var tf2_bi_end = 0
tf2_bi_start := change(tf2) ? bar_index : tf2_bi_start[1]
tf2_bi_end := change(tf2) ? tf2_bi_start : bar_index
if change(tf2)
    if (line.get_x2(tf2_line) - line.get_x1(tf2_line)) < level_min_lengh
        line.delete(tf2_line)
    tf2_line := line.new(tf2_bi_start, tf2, tf2_bi_end, tf2, color =  colour(y), width = line_width, extend = line_extend, style = line.style_dotted)
line.set_x2(tf2_line, tf2_bi_end)

alertcondition(change(tf1) != 0 or change(tf2) != 0 , message = "New S/R line" )

//---------------------------------------------------------
// 3 Weeks Tight
//----------------------------------------------------------

iThreshold = input(title = "% threshold between closes", type = input.float, minval = .5, defval = 1.0, step = .05)
iShowIndicatorLine = input(title = "Horizontal indicator at tight areas?", type = input.bool, defval = true, group = "Visual Indicators")
iIndicatorStyle =         input(title = " ‎ ‎ ‎ ‎ ‎Style", type=input.string, options=["Solid", "Dotted", "Dashed", "Arrow Left", "Arrow Right", "Arrow Both"], defval="Solid", group = "Visual Indicators")
iIndicatorLineThickness = input(title = " ‎ ‎ ‎ ‎ ‎Thickness", type = input.integer, minval = 1, maxval = 10, defval = 2, group = "Visual Indicators")
iIndicatorLineColor =     input(title = " ‎ ‎ ‎ ‎ ‎Color", type = input.color, defval = #5A98C6, group = "Visual Indicators")
iOffset =                 input(title = " ‎ ‎ ‎ ‎ ‎Offset up/down", type = input.integer, minval = -5, maxval = 5, defval = 1, step = .1, group = "Visual Indicators")
iShowVerticalBars = input(title = "Vertical band at tight areas?", type = input.bool, defval = true, group = "Visual Indicators")
iShowBuyPrice = input(title = "Show buy price at tight area?", type = input.bool, defval = true, group = "Buy Price")
iBuyPriceOffset = input(title = "Buy price offset up/down", type = input.integer, minval = 0, maxval = 15, defval = 5, step = .5, group = "Buy Price")
iTextSizeOption = input(title = "Text size", type = input.string, options=["Normal", "Large", "Huge"], defval = "Normal", group = "Buy Price")

// Only show content if on a weekly timeframe
onWeeklyChart = timeframe.isweekly

highestHigh = max(high, high[1], high[2])

//---------------------------------------------------------
// Calculate % change between closes
//----------------------------------------------------------
percentChange1 = ((close - close[1]) / close[1]) * 100
percentChange2 = ((close[1] - close[2]) / close[2]) * 100

//---------------------------------------------------------
// 3 weeks tight if closes meet threshold
//----------------------------------------------------------
threeWeeksTight = (abs(percentChange1) <= iThreshold) and (abs(percentChange2) <= iThreshold)

lineStyle = (iIndicatorStyle == "Dotted") ? line.style_dotted :
     (iIndicatorStyle == "Dashed") ? line.style_dashed :
     (iIndicatorStyle == "Arrow Left") ? line.style_arrow_left :
     (iIndicatorStyle == "Arrow Right") ? line.style_arrow_right :
     (iIndicatorStyle == "Arrow Both") ? line.style_arrow_both : line.style_solid

//---------------------------------------------------------
// Draw horizontal line above three weeks tight
//----------------------------------------------------------
if (onWeeklyChart and threeWeeksTight and iShowIndicatorLine)
    line.new(bar_index[2], high + iOffset, bar_index, high + iOffset, style = lineStyle, width = iIndicatorLineThickness, color = iIndicatorLineColor)

//---------------------------------------------------------
// Show vertical bar indicating tight area?
//----------------------------------------------------------
bgcolor(onWeeklyChart and iShowVerticalBars and threeWeeksTight ? #5A98C6 : na, editable = false)
bgcolor(onWeeklyChart and iShowVerticalBars and threeWeeksTight ? #5A98C6 : na, offset = -1, editable = false)
bgcolor(onWeeklyChart and iShowVerticalBars and threeWeeksTight ? #5A98C6 : na, offset = -2, editable = false)

//---------------------------------------------------------
// Optional alert when 3 weeks tight is detected
//----------------------------------------------------------
alertcondition(threeWeeksTight, title="3 Weeks Tight", message="3 Weeks Tight pattern has been found.")

//---------------------------------------------------------
// Round to specified number of decimal places
//----------------------------------------------------------
fRound(_number, _decimals) =>
    power = pow(10, _decimals)
    int(_number * power) / power

//---------------------------------------------------------
// Label showing highest high of the tight range
//----------------------------------------------------------
fontSize = (iTextSizeOption == "Normal") ? size.normal :
  (iTextSizeOption == "Large") ? size.large : size.huge

var label labelID = label.new(x = na, y = na, textcolor = color.white, color = #15B72C, size = fontSize, tooltip = "Highest high of the tight area + ten cents.")
    
if (onWeeklyChart and threeWeeksTight and iShowBuyPrice)
    // Notice the buy price is $.1 above the highest high, 
    // the traditional CANSLIM entry to ensure push through resistance
    label.set_text(id = labelID, text = "Buy price: \n" + tostring(fRound(highestHigh + .1, 2)))
    label.set_x(id = labelID, x = bar_index)
    label.set_y(id = labelID, y = high + iBuyPriceOffset)
