3 Candle Strike Stretegy
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © platsn
//
// *****************************************************************************************************************************************************************************************************

//@version=5
strategy("3 Candle Strike Strategy", overlay=true, pyramiding=1, initial_capital=5000)

// ******************** Period **************************************
startY = input(title='Start Year', defval=2011, group = "Trading window")
startM = input.int(title='Start Month', defval=1, minval=1, maxval=12, group = "Trading window")
startD = input.int(title='Start Day', defval=1, minval=1, maxval=31, group = "Trading window")
finishY = input(title='Finish Year', defval=2050, group = "Trading window")
finishM = input.int(title='Finish Month', defval=12, minval=1, maxval=12, group = "Trading window")
finishD = input.int(title='Finish Day', defval=31, minval=1, maxval=31, group = "Trading window")
timestart = timestamp(startY, startM, startD, 00, 00)
timefinish = timestamp(finishY, finishM, finishD, 23, 59)

t1_session = input.session("0930-1554:23456", "Entry Session", group="Sessions", tooltip = "Entry Signal only generated within this period.") 
t1 = time(timeframe.period, t1_session)
window = time >= timestart and time <= timefinish and t1 ? true : false 

src = close

margin_req = input.float(10, title="Margin Requirement / Leverage", step=0.1, group = "Trading Options")
qty_per_trade = input.float(100, title = "% of initial capital per trade", group = "Trading Options")
reinvest = input.bool(defval=false,title="Reinvest profit", group = "Trading Options")
reinvest_percent = input.float(defval=20, title = "Reinvest percentage", group="Trading Options")

profit = strategy.netprofit 

trade_amount = math.floor(strategy.initial_capital*margin_req / close) 

if strategy.netprofit > 0 and reinvest
    trade_amount := math.floor((strategy.initial_capital* (qty_per_trade/100)+(profit*reinvest_percent*0.01))*margin_req/ close) 
else
    trade_amount := math.floor(strategy.initial_capital* (qty_per_trade/100)*margin_req / close)  

trade_amount := math.min(trade_amount, 1000)

// ***************************************************************************************************** Daily ATR *****************************************************
// Inputs
atrlen = input.int(14, minval=1, title="ATR period", group = "Daily ATR")
iPercent = input.float(5, minval=1, maxval=100, step=0.1, title="% ATR to use for SL / PT", group = "Daily ATR")
// PTPercent = input.int(100, minval=1, title="% ATR for PT")

// Logic
percentage = iPercent * 0.01
datr = request.security(syminfo.tickerid, "1D", ta.rma(ta.tr, atrlen))
datrp = datr * percentage
// datrPT = datr * PTPercent * 0.01

plot(datr,"Daily ATR")
plot(datrp, "Daily % ATR")

// ***************************************************************************************************************** Moving Averages ************************

show_ema1 = input.bool(false, "", group = "Moving Averages", inline = "ema1")
len0 = input.int(8, minval=1, title='Fast EMA', group= "Moving Averages", inline = "ema1")
ema1 = ta.ema(src, len0)

show_smma1 = input.bool(false, "", group = "Moving Averages", inline = "smma1")
len1 = input.int(21, minval=1, title='Fast SMMA', group= "Moving Averages", inline = "smma1")
smma1 = 0.0
sma_1 = ta.sma(src, len1)
smma1 := na(smma1[1]) ? sma_1 : (smma1[1] * (len1 - 1) + src) / len1

show_smma2 = input.bool(false, "", group = "Moving Averages", inline = "smma2")
len2 = input.int(50, minval=1, title='Medium SMMA', group= "Moving Averages", inline = "smma2")
smma2 = 0.0
sma_2 = ta.sma(src, len2)
smma2 := na(smma2[1]) ? sma_2 : (smma2[1] * (len2 - 1) + src) / len2

show_smma3 = input.bool(false, "", group = "Moving Averages", inline = "smma3")
len3 = input.int(200, minval=1, title='Slow SMMA', group= "Moving Averages", inline = "smma3")
smma3 = 0.0
sma_3 = ta.sma(src, len3)
smma3 := na(smma3[1]) ? sma_3 : (smma3[1] * (len3 - 1) + src) / len3

ma_bull = smma1 > smma2 and smma1 > smma1[1]
ma_bear = smma1 < smma2 and smma1 < smma1[1]

ma_bull_macro = smma1 > smma3 and smma2 > smma3
ma_bear_macro = smma1 < smma3 and smma2 < smma3

plot(show_ema1 ? ema1 : na, 'Fast EMA', color.white, linewidth = 2)
plot(show_smma1 ? smma1 : na, 'Fast SMMA', color.yellow, linewidth = 2)
plot(show_smma2 ? smma2 : na, 'Medium SMMA', color.orange, linewidth = 2)
plot(show_smma3 ? smma3 : na, 'Fast SMMA', color.red, linewidth = 2)

// **************************************************************************************************************** Linear Regression *************************

//Input
clen = input.int(defval = 50, minval = 1, title = "Linear Regression Period", group = "Linear Regression")
slen = input.int(defval=50, minval=1, title="LR Slope Period" , group = "Linear Regression")
glen = input.int(defval=14, minval=1, title="LR Signal Period", group = "Linear Regression")
LR_thres = input.float(0.03, minval=0, step=0.001, title="LR Threshold for Ranging vs Trending" , group = "Linear Regression")
 
//Linear Regression Curve
lrc = ta.linreg(src, clen, 0)
//Linear Regression Slope
lrs = (lrc-lrc[1])/1
//Smooth Linear Regression Slope
slrs = ta.ema(lrs, slen)
//Signal Linear Regression Slope
alrs = ta.sma(slrs, glen)

up_accel = lrs > alrs and lrs > 0 
down_accel = lrs < alrs and lrs < 0 

LR_ranging  = math.abs(slrs) <= LR_thres
LR_trending = math.abs(slrs) > LR_thres

// plot(slrs, "LR slope")
// plot(LR_trending?1:0, "LR Trending")

barcolor(LR_ranging? color.gray : na, title = "Ranging")

// *********************************************************************************************************************************** Candle conditions **************************

bull_3s = close[3] <= open[3] and close[2] <= open[2] and close[1] <= open[1] and close > open[1]
bear_3s = close[3] >= open[3] and close[2] >= open[2] and close[1] >= open[1] and close < open[1]

plotshape(bull_3s, style=shape.triangleup, color=color.new(color.green, 0), location=location.belowbar, size=size.small, text='3s-Bull', title='3 Line Strike Up')
plotshape(bear_3s, style=shape.triangledown, color=color.new(color.red, 0), location=location.abovebar, size=size.small, text='3s-Bear', title='3 Line Strike Down')

if barstate.isconfirmed 
    if bull_3s
        alert(message = "3s Bull")
    if bear_3s
        alert(message = "3s Bear")

// ***************************************************************************************************************************************** SL & PT ***********************************
RR = input.float(3.0, minval = 0.1, step = 0.1, title="Reward to Risk Ratio", group = "Trading Options")
trade_trailing = input.bool(true, "Switch to trailing SL after TP hit", group = "Trading Options", tooltip = "Set SL to previous low after TP hit")

barsSinceLastEntry()=>
    strategy.opentrades > 0 ? (bar_index - strategy.opentrades.entry_bar_index(strategy.opentrades-1)) : na

// plot(barsSinceLastEntry(),"BSLE")

last_high = math.max(high, high[1], high[2], high[3])
last_low = math.min(low, low[1], low[2], low[3])

long_SL = last_low - datrp
short_SL = last_high + datrp

long_PT = last_high
short_PT = last_low

last_entry = strategy.opentrades.entry_price(strategy.opentrades-1)
risk = last_entry - long_SL

if strategy.opentrades > 0
    long_SL := math.min(long_SL[barsSinceLastEntry()], last_low)
    short_SL := math.max(short_SL[barsSinceLastEntry()], last_high)
    risk := last_entry - long_SL
    long_PT := last_entry + (last_entry - long_SL) * RR
    short_PT := last_entry - (short_SL - last_entry) * RR

var PT_hit = false

if trade_trailing
    if high > long_PT
        long_SL := low
        PT_hit := true
    if low < short_PT
        short_SL := high
        PT_hit := true
    if PT_hit
        long_SL := math.max(low[1], long_SL[1])
        short_SL := math.min(high[1], short_SL[1])

PT_hit := strategy.opentrades == 0 ? false : PT_hit

SSL = plot(short_SL,title = "Short SL", color= strategy.opentrades.size(0) < 0 and barsSinceLastEntry() > 0 ? color.red: na, linewidth = 3, style = plot.style_linebr)
LSL = plot(long_SL,title = "Long SL", color= strategy.opentrades.size(0) > 0 and barsSinceLastEntry() > 0 ? color.red: na, linewidth = 3, style = plot.style_linebr)
LPT = plot(long_PT,title = "Long PT", color= strategy.opentrades.size(0) > 0 and barsSinceLastEntry() > 0 ? color.green: na, linewidth = 3, style = plot.style_linebr)
SPT = plot(short_PT,title = "Short PT", color= strategy.opentrades.size(0) < 0 and barsSinceLastEntry() > 0 ? color.green: na, linewidth = 3, style = plot.style_linebr)
LE = plot(last_entry, title = "Last entry", color = strategy.opentrades > 0 ? color.gray : na, style = plot.style_linebr)
plot(risk, title = "Risk")


fill(LPT, LE, color = strategy.opentrades.size(0) > 0 ? color.new(color.green,90) : na)
fill(LE, LSL, color = strategy.opentrades.size(0) > 0 ? color.new(color.red,90): na)

fill(SPT, LE, color = strategy.opentrades.size(0) < 0 ? color.new(color.green,90) : na)
fill(LE, SSL, color = strategy.opentrades.size(0) < 0 ? color.new(color.red,90) : na)


// **************************************************************************************************************************************** Trade Pauses ****************************************
bool trade_pause = false
bool trade_pause2 = false

no_entry = input.bool(true, title="No entry between:", group = "Trading Options", inline = 'no_entry')
t2_session = input.session("1000-1030",'', group = "Trading Options", inline = 'no_entry', tooltip = "To avoid high volatility")
t2 = time(timeframe.period, t2_session)

if high - low > datr*0.3
    trade_pause := true
else
    trade_pause := false

if no_entry and t2
    trade_pause2 := true
else
    trade_pause2 := false
    
// ************************************************************************************************************************************ Entry conditions **************************

trade_3s = input.bool(title='Trade 3s candle pattern', defval=true, group = "Trading Options", tooltip = "Can use alert() function calls for all 3 Candle strike signals")
L_entry1 = trade_3s and bull_3s and ma_bull and LR_trending
S_entry1 = trade_3s and bear_3s and ma_bear and LR_trending

trade_ma_reversal = input.bool(title='Trade MA Cross Reversal Signal', defval=true, group = "Trading Options")
L_entry2 = trade_ma_reversal and ma_bear_macro and ema1 > smma1 and bull_3s and ta.barssince(ta.cross(ema1,smma1)) < 10
S_entry2 = trade_ma_reversal and ma_bull_macro and ema1 < smma1 and bear_3s and ta.barssince(ta.cross(ema1,smma1)) < 10

// ************************************************************************************************************************************** Exit Conditions ********************************
 
L_exit1 = bear_3s
S_exit1 = bull_3s

// ************************************************************************************************************************************ Entry and Exit orders *****************************

if not trade_pause and not trade_pause2 and window
    if L_entry1
        strategy.entry("Long", strategy.long, trade_amount, comment="Long 3s")
    if L_entry2
        strategy.entry("Long", strategy.long, trade_amount, comment="Long MA cross")
    
    if S_entry1
        strategy.entry("Short", strategy.short, trade_amount, comment = "Short 3s")
    if S_entry2
        strategy.entry("Short", strategy.short, trade_amount, comment = "Short MA corss")


if trade_trailing
    strategy.exit("Exit", "Long", stop= long_SL, comment = "Exit Long SL hit")
    strategy.exit("Exit", "Short", stop= short_SL, comment = "Exit Short SL hit")
else if barsSinceLastEntry() > 0
    strategy.exit("Exit", "Long",limit = long_PT, stop= long_SL, comment_profit = "Exit Long PT hit", comment_loss = "Exit Long SL hit")
    strategy.exit("Exit", "Short",limit = short_PT, stop= short_SL, comment_profit = "Exit Short PT hit", comment_loss = "Exit Short SL hit")

if strategy.opentrades > 0 and not t1
    strategy.close_all(comment = 'End of day')

// ************************************************************************************************************************************ Alerts *****************************

