7 Week Rule
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Amphibiantrading

//@version=5
indicator("7 Week Rule", overlay = true)

// inputs
g1 = 'Moving Average'
len = input.int(10, "MA length", group = g1, inline = '1')
matype = input.string('SMA', 'MA type', options = ['EMA', 'SMA'],  group = g1, inline = '1')
ma_color = input.color(color.red, 'MA Color', group = g1, inline = '2' )
ma_width = input.int(2, 'MA Line Width', 1, 5, 1, group = g1, inline = '2')
g2 = 'Display Options'
show_ma = input.bool(true, 'Show MA',  group = g2, inline = '4')
show_table = input.bool(true,'Show Count Table', group = g2, inline = '5')
table_bg = input.color(color.white, 'Table Background Color', group = g2, inline = '6')
table_text = input.color(color.black, 'Table Background Color', group = g2, inline = '6')
i_tableypos = input.string("top", "Table Position", inline = "i1", options = ["top", "middle", "bottom"], group=g2)
i_tablexpos = input.string("right", "", inline = "i1", options = ["right","center", "left"], group=g2)
hlight = input.bool(true, 'Highlight Background', group = g2,  inline = '7')
hcolor1 = input.color(color.new(color.aqua,85), 'Holding MA Background Color', group = g2, inline = '8')
hcolor2 = input.color(color.new(color.red,85), 'Violation Background Color', group = g2, inline = '8')
show_day_1 = input.bool(true, 'Show Day 1 of Count', group = g2, inline = '9')
label_color = input.color(color.blue, 'Day 1 Label Color', group = g2, inline = '9')

//get the ma value
ma = matype == 'EMA' ? ta.ema(close, len) : ta.sma(close,len)

// variables
macount = 0
var holding = false
var violation_low = 0.0
var label day1_label = na
var table emas = table.new(i_tableypos + "_" +i_tablexpos, 2, 2, table_bg, color.black, 1, color.black, 1)

// for loop to count if 7 weeks above the moving average
for i = 34 to 0
    if close[i] > ma[i]
        macount += 1
    else if close[i] < ma[i] and macount != 35
        macount := 0
    if macount >= 35
        holding := true
    else
        holding := false

// sell signal if holding condition was true
sell_signal = (macount[1] >= 35 and ta.crossunder(close,ma)) or (macount[1]  >= 35 and close < ma)

// set stop below low of bar that closes under the moving average
if sell_signal
    violation_low := low

// trigger the sell signal
trigger_sell_signal = sell_signal[1] and low < violation_low

if sell_signal[1] and low >= violation_low
    holding := true
    macount := 35
if macount[1] == 35 and close > ma
    holding := true
    macount := 35

day1 = macount == 35 ? bar_index - 34 : 0

//plots
plotshape(trigger_sell_signal, 'Sell', shape.triangledown, color=color.red)
plot(show_ma ? ma : na, 'Moving Average', color = ma_color, linewidth = ma_width)
bgcolor(holding and hlight ? hcolor1 : sell_signal and hlight ? hcolor2 : na)
// plotchar(macount, 'Count', "")

//day 1 label
if macount == 35 and macount[1] == 34 and show_day_1
    day1_label := label.new(day1, low[35] * .99, style = label.style_label_up, size = size.tiny, color = label_color)

// table to show counter
if barstate.islast and show_table
    table.cell(emas,0,0, str.upper(matype) + ' ' + str.tostring(len), text_color = table_text, text_halign = text.align_left)
    table.cell(emas,1,0, str.tostring(macount), text_color = table_text)

//alerts
if trigger_sell_signal
    alert('Moving Average Violation', alert.freq_once_per_bar_close)