MACD BTC Long/Short Strategy v1.0
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Puckapao

//@version=4
strategy(title="MACD", shorttitle="MACD", overlay=true, initial_capital=10000.00, currency="USD", default_qty_type=strategy.cash, default_qty_value=10000.00)
// Getting inputs
reenter_delay = input(title="Re-enter Delay", type=input.integer, defval=2)
sculp_delay = input(title="Sculp Delay", type=input.integer, defval=8)
close_delay = input(title="Close Delay", type=input.integer, defval=1)
ema_period = input(title="EMA Period", type=input.integer, defval=21)
fast_length = input(title="Fast Length", type=input.integer, defval=12)
slow_length = input(title="Slow Length", type=input.integer, defval=26)
src = input(title="Source", type=input.source, defval=close)
signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9)
sma_source = input(title="Simple MA(Oscillator)", type=input.bool, defval=false)
sma_signal = input(title="Simple MA(Signal Line)", type=input.bool, defval=true)

// Date Settings
startDate = input(title="Start Date", type=input.integer,
     defval=19, minval=1, maxval=31)
startMonth = input(title="Start Month", type=input.integer,
     defval=09, minval=1, maxval=12)
startYear = input(title="Start Year", type=input.integer,
     defval=2017, minval=1800, maxval=2100)

endDate = input(title="End Date", type=input.integer,
     defval=31, minval=1, maxval=31)
endMonth = input(title="End Month", type=input.integer,
     defval=3, minval=1, maxval=12)
endYear = input(title="End Year", type=input.integer,
     defval=2021, minval=1800, maxval=2100)
     
inDateRange = (time >= timestamp(syminfo.timezone, startYear,
         startMonth, startDate, 0, 0)) and
     (time < timestamp(syminfo.timezone, endYear, endMonth, endDate, 0, 0))

reenter_cnt = 0
reenter_cnt := nz(reenter_cnt[1])

sculp_cnt = 0
sculp_cnt := nz(sculp_cnt[1])

close_cnt = 0
close_cnt := nz(close_cnt[1])

on_long = false
on_long := nz(on_long[1])

on_short = false
on_short := nz(on_short[1])

sculp = false
reenter = false
slowdown = false
overwater = false
underwater = false

ema = ema(close, ema_period)

// Plot colors
col_grow_above = #26A69A
col_grow_below = #FFCDD2
col_fall_above = #B2DFDB
col_fall_below = #EF5350
col_macd = #0094ff
col_signal = #ff6a00
// Calculating
fast_ma = sma_source ? sma(src, fast_length) : ema(src, fast_length)
slow_ma = sma_source ? sma(src, slow_length) : ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal ? sma(macd, signal_length) : ema(macd, signal_length)
hist = macd - signal
// plot(hist, title="Histogram", style=plot.style_columns, color=(hist>=0 ? (hist[1] < hist ? col_grow_above : col_fall_above) : (hist[1] < hist ? col_grow_below : col_fall_below) ), transp=0 )
// plot(macd, title="MACD", color=col_macd, transp=0)
// plot(signal, title="Signal", color=col_signal, transp=0)

cross_up = crossover(macd, signal)
cross_down = crossunder(macd, signal)


if (inDateRange)

    over_macd = macd > 0 and signal > 0 ? true : false
    under_macd = macd < 0 and signal < 0 ? true : false
    overwater := crossover(close, ema)
    underwater := crossunder(close, ema)
    slowdown := hist >= 0 ? (hist[1] > hist ? true : false) : (hist[1] < hist ? true : false)
    reenter := hist >= 0 ? (hist[1] < hist ? true : false) : (hist[1] > hist ? true : false)
    sculp := (hist >= 0 ? (hist[1] > hist ? true : false) : (hist[1] < hist ? true : false))
    
    if(reenter == true)
        if(reenter_cnt < reenter_delay)
            reenter_cnt := reenter_cnt + 1
    else
        if(reenter_cnt > 0)
            reenter_cnt := reenter_cnt - 1
                    
    if(sculp == true)
        if(sculp_cnt < sculp_delay)
            sculp_cnt := sculp_cnt + 1
    else
        if(sculp_cnt > 0)
            sculp_cnt := sculp_cnt - 1
        
    if(slowdown == true)
        if(close_cnt < close_delay)
            close_cnt := close_cnt + 1
        else
            close_cnt := close_cnt - 1

    // Entry
    if (cross_up == true)
        strategy.entry("long", strategy.long, comment = "long", alert_message = "long")
    if (cross_down == true)
        strategy.entry("short", strategy.short, comment = "short", alert_message = "short")
        
    // Sculp bottom / top
    if (sculp == true and sculp_cnt >= sculp_delay)
        if (hist >= 0)
            strategy.entry("sculp-short", strategy.short, comment = "sculp-short", alert_message = "sculp-short")
        else
            strategy.entry("sculp-long", strategy.long, comment = "sculp-long", alert_message = "sculp-long")
        
        sculp_cnt := 0
        sculp := false
            
    // Re-Entry
    if (reenter == true and reenter_cnt >= reenter_delay)
        if (hist >= 0)
            strategy.entry("re-long", strategy.long, comment = "re-long", alert_message = "re-long")
        else
            strategy.entry("re-short", strategy.short, comment = "re-short", alert_message = "re-short")
            
        reenter_cnt := 0
        reenter := false
        
    // Over EMA
    if (overwater == true)
        strategy.entry("ema-long", strategy.long, comment = "ema-long", alert_message = "ema-long")
        
            
    // Close
    if (slowdown == true and close_cnt >= close_delay)
        strategy.close("long", when = slowdown, comment = "close long", alert_message = "close long")
        strategy.close("short", when = slowdown, comment = "close short", alert_message = "close short")
        strategy.close("re-long", when = slowdown, comment = "close re-long", alert_message = "close re-long")
        strategy.close("re-short", when = slowdown, comment = "close re-short", alert_message = "close re-short")
        if (hist >= 0)
            strategy.close("sculp-long", when = slowdown, comment = "close sculp-long", alert_message = "close sculp-long")
        else
            strategy.close("sculp-short", when = slowdown, comment = "close sculp-short", alert_message = "close sculp-short")
        
        if (slowdown)
            if (hist >= 0)
                on_long := false
            else
                on_short := false
                
        strategy.close("ema-long", when = underwater, comment = "close ema-long", alert_message = "close ema-long")


plotchar(slowdown, "close?", "")
plotchar(close_cnt, "close delay", "")
plotchar(reenter, "reenter?", "")
plotchar(reenter_cnt, "reenter delay", "")
plotchar(sculp, "sculp?", "")
plotchar(sculp_cnt, "sculp delay", "")
plotchar(overwater, "over ema", "")
plotchar(underwater, "under ema", "")