// 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 SPY Option Strategy", overlay=true, pyramiding=1, initial_capital=5000, commission_type=strategy.commission.cash_per_contract, commission_value = 0.0625) // ******************** 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 = time(timeframe.period, "0930-1545:23456") window = time >= timestart and time <= timefinish and t1 ? true : false // ***************************************************** trade_options = input.bool(defval=true,title="Trading Options only", group = "Trading Options") option_amt = input.int(defval=10,title="# of options per trade", group = "Trading Options") option_multiplier = input.float(0.006, title="Multiplier for trading options (adjust to approx. options P&L)", step=0.001, group = "Trading Options") reinvest = input.bool(defval=false,title="Reinvest profit", group = "Trading Options") trade_trailing = input.bool(defval=true, title = "Trade trailing SL after PT", group = "Trading Options") trailing_stop = false TS = 0 trade_earlyexit = input.bool(defval=true,title="Trade exit early", group = "Trading Options") closeEnough_Percent = input.float(3, minval=1, maxval=100, step=0.5, title="% ATR to use for early exits, if price bounce close to PT", group = "Trading Options") trade_counter = input.bool(defval=true,title="Trade opposite trend if SL hit", group = "Trading Options") no_longat10 = input.bool(true, title="No entry between 10 - 10:30", group = "Trading Options") trade_bias = input.bool(true, title="Trade daily trend bias", group = "Trading Options") src = close price_lookback_period = input.int(60, "Price lookback period", group = "Pause trade on significant price movement") price_change_thres = input.float(1.0, "Price % change threshold", step=0.1, group = "Pause trade on significant price movement") price_lookback_shortterm = input.int(10, "Price pullback lookback period", group = "Pause trade on significant price movement") price_lookback_highest = ta.highest(close,price_lookback_period) price_lookback_lowest = ta.lowest(close,price_lookback_period) closest_high = ta.highest(close,price_lookback_shortterm) closest_low = ta.lowest(close,price_lookback_shortterm) // plot(price_lookback_highest, "price_lookback_highest") // plot(price_lookback_lowest, "price_lookback_lowest") // plot(closest_high,"closest_high") // plot(closest_low,"closest_low") // ***************************************************************************************************** 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") // Logic percentage = iPercent * 0.01 datr = request.security(syminfo.tickerid, "1D", ta.rma(ta.tr, atrlen)) datrp = datr * percentage // datrp = ta.rma(ta.tr,200) plot(datr,"Daily ATR") plot(datrp, "Daily % ATR") // ***************************************************************************************************************** Moving Averages ************************ len0 = input.int(8, minval=1, title='Fast EMA', group= "Moving Averages") ema1 = ta.ema(src, len0) len1 = input.int(21, minval=1, title='Fast SMMA', group= "Moving Averages") smma1 = 0.0 sma_1 = ta.sma(src, len1) smma1 := na(smma1[1]) ? sma_1 : (smma1[1] * (len1 - 1) + src) / len1 len2 = input.int(50, minval=1, title='Slow SMMA', group= "Moving Averages") smma2 = 0.0 sma_2 = ta.sma(src, len2) smma2 := na(smma2[1]) ? sma_2 : (smma2[1] * (len2 - 1) + src) / len2 len3 = input.int(200, minval=1, title='Slow SMMA', group= "Moving Averages") 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(ma_bull? 1 : 0, "MA bull") // plot(ma_bear? 1 : 0 , "MA bear") // **************************************************************************************************************** Linear Regression ************************* //Input clen = input.int(defval = 50, minval = 1, title = "LR Period", group = "Linear Regression") slen = input.int(defval=50, minval=1, title="LR EMA Period" , group = "Linear Regression") // glen = input.int(defval=14, minval=1, title="LR Signal Period", group = "Linear Regression") LR_thres = input.float(3, minval=0, step=0.1, title="LR Threshold for Ranging vs Trending" , group = "Linear Regression") slow_lr_len = input.int(defval = 100, title = "Slow LR Period (for trend bias)", step=10, group = "Linear Regression") LR_thres2 = input.float(1, minval=0, step=0.1, title="LR Threshold for Trend bias" , group = "Linear Regression") //Linear Regression Curve lrc = ta.linreg(src, clen, 0) * 100 //Linear Regression Slope lrs = (lrc-lrc[1])/1 //Smooth Linear Regression Slope slrs = ta.ema(lrs, slen) //Linear Regression Curve lrc2 = ta.linreg(src, slow_lr_len, 0) * 100 //Linear Regression Slope lrs2 = (lrc2-lrc2[1])/1 //Smooth Linear Regression Slope slrs2 = ta.ema(lrs2, slow_lr_len) LR_ranging = math.abs(slrs) <= LR_thres LR_trending = math.abs(slrs) > LR_thres LR_bull = slrs > LR_thres LR_bear = slrs < -LR_thres trend_biasBull = slrs2 > LR_thres2 trend_biasBear = slrs2 < -LR_thres2 plot(slrs, "LR slope") plot(LR_trending?1:0, "LR Trending") plot(trend_biasBull ? 1 : trend_biasBear ? -1 : 0, "Trend Bias") // ***************************************************************************************************************** Fractals ******************************** n = 2 //input.int(title="Periods", defval=2, minval=2) // UpFractal bool upflagDownFrontier = true bool upflagUpFrontier0 = true bool upflagUpFrontier1 = true bool upflagUpFrontier2 = true bool upflagUpFrontier3 = true bool upflagUpFrontier4 = true for i = 1 to n upflagDownFrontier := upflagDownFrontier and (high[n-i] < high[n]) upflagUpFrontier0 := upflagUpFrontier0 and (high[n+i] < high[n]) upflagUpFrontier1 := upflagUpFrontier1 and (high[n+1] <= high[n] and high[n+i + 1] < high[n]) upflagUpFrontier2 := upflagUpFrontier2 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+i + 2] < high[n]) upflagUpFrontier3 := upflagUpFrontier3 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+3] <= high[n] and high[n+i + 3] < high[n]) upflagUpFrontier4 := upflagUpFrontier4 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+3] <= high[n] and high[n+4] <= high[n] and high[n+i + 4] < high[n]) flagUpFrontier = upflagUpFrontier0 or upflagUpFrontier1 or upflagUpFrontier2 or upflagUpFrontier3 or upflagUpFrontier4 upFractal = (upflagDownFrontier and flagUpFrontier) // downFractal bool downflagDownFrontier = true bool downflagUpFrontier0 = true bool downflagUpFrontier1 = true bool downflagUpFrontier2 = true bool downflagUpFrontier3 = true bool downflagUpFrontier4 = true for i = 1 to n downflagDownFrontier := downflagDownFrontier and (low[n-i] > low[n]) downflagUpFrontier0 := downflagUpFrontier0 and (low[n+i] > low[n]) downflagUpFrontier1 := downflagUpFrontier1 and (low[n+1] >= low[n] and low[n+i + 1] > low[n]) downflagUpFrontier2 := downflagUpFrontier2 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+i + 2] > low[n]) downflagUpFrontier3 := downflagUpFrontier3 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+3] >= low[n] and low[n+i + 3] > low[n]) downflagUpFrontier4 := downflagUpFrontier4 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+3] >= low[n] and low[n+4] >= low[n] and low[n+i + 4] > low[n]) flagDownFrontier = downflagUpFrontier0 or downflagUpFrontier1 or downflagUpFrontier2 or downflagUpFrontier3 or downflagUpFrontier4 downFractal = (downflagDownFrontier and flagDownFrontier) // *********************************************************************************************************************************** Candle conditions ************************** bull_3s = close[3] <= open[3] and close[2] <= close[3] and close[2] <= open[2] and close[1] <= close[2] and close[1] <= open[1] and close > close[2] bear_3s = close[3] >= open[3] and close[2] >= close[3] and close[2] >= open[2] and close[1] >= close[2] and close[1] >= open[1] and close < close[2] 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') // **************************************************************************************************************************************** Trade Pauses **************************************** bool trade_pause = false bool trade_pause2 = false trade_pause := false if no_longat10 and time(timeframe.period, "1000-1030:23456") trade_pause2 := true else trade_pause2 := false too_bull = (closest_high - price_lookback_lowest) / closest_high > price_change_thres /100 too_bear = (closest_low - price_lookback_highest) / closest_low < -price_change_thres /100 // ************************************************************************************************************************************ Entry conditions ************************** L_entry1 = bull_3s and ma_bull and LR_trending and not(too_bull) S_entry1 = bear_3s and ma_bear and LR_trending and not(too_bear) // ************************************************************************************************************************************ Entry orders ***************************** cntrTrade_L = ta.barssince(strategy.position_size != 0) < 2 and strategy.position_size == 0 and strategy.closedtrades.profit(strategy.closedtrades-1) < 0 and close > close[ta.barssince(strategy.position_size != 0)] and strategy.closedtrades.size(strategy.closedtrades-1) < 0 and not(LR_bear) cntrTrade_S = ta.barssince(strategy.position_size != 0) < 2 and strategy.position_size == 0 and strategy.closedtrades.profit(strategy.closedtrades-1) < 0 and close < close[ta.barssince(strategy.position_size != 0)] and strategy.closedtrades.size(strategy.closedtrades-1) > 0 and not(LR_bull) profit = strategy.netprofit trade_amount = math.floor(strategy.initial_capital / close) if trade_options if strategy.netprofit > 0 and reinvest// and strategy.closedtrades.profit(strategy.closedtrades-1) > 0 trade_amount := math.floor(strategy.initial_capital * option_multiplier) * (option_amt + math.floor((profit/strategy.initial_capital)*10)) else trade_amount := math.floor(strategy.initial_capital * option_multiplier) * option_amt if not(trade_pause) and not(trade_pause2) and time(timeframe.period, "0930-1530:23456") if trade_bias if trend_biasBull strategy.entry("Long", strategy.long, trade_amount, when = L_entry1 and window, comment="Long 3s") strategy.entry("Short", strategy.short, trade_amount/2, when = S_entry1 and window, comment = "Short 3s") if trade_counter strategy.entry("Short_cntr", strategy.short, trade_amount/2, when = cntrTrade_S and window, comment = "Short Counter Trade") strategy.entry("Long_cntr", strategy.long, trade_amount, when = cntrTrade_L and window, comment="Long Counter Trade") else if trend_biasBear strategy.entry("Long", strategy.long, trade_amount/2, when = L_entry1 and window, comment="Long 3s") strategy.entry("Short", strategy.short, trade_amount, when = S_entry1 and window, comment = "Short 3s") if trade_counter strategy.entry("Short_cntr", strategy.short, trade_amount, when = cntrTrade_S and window, comment = "Short Counter Trade") strategy.entry("Long_cntr", strategy.long, trade_amount/2, when = cntrTrade_L and window, comment="Long Counter Trade") else strategy.entry("Long", strategy.long, trade_amount, when = L_entry1 and window, comment="Long 3s") strategy.entry("Short", strategy.short, trade_amount, when = S_entry1 and window, comment = "Short 3s") if trade_counter strategy.entry("Short_cntr", strategy.short, trade_amount, when = cntrTrade_S and window, comment = "Short Counter Trade") strategy.entry("Long_cntr", strategy.long, trade_amount, when = cntrTrade_L and window, comment="Long Counter Trade") else strategy.entry("Long", strategy.long, trade_amount, when = L_entry1 and window, comment="Long 3s") strategy.entry("Short", strategy.short, trade_amount, when = S_entry1 and window, comment = "Short 3s") if trade_counter strategy.entry("Short_cntr", strategy.short, trade_amount, when = cntrTrade_S and window, comment = "Short Counter Trade") strategy.entry("Long_cntr", strategy.long, trade_amount, when = cntrTrade_L and window, comment="Long Counter Trade") // ***************************************************************************************************************************************** SL & PT *********************************** RR = input.float(3.0, minval = 1, step = 0.1, title="Target Reward to Risk Ratio", group = "Trading Options") SL_offset = input.int(-15, minval=-100, maxval = 100, title ="% Stop loss reduction(+ve)/increase(-ve), no impact to PT", group = "Trading Options") barsSinceLastEntry()=> strategy.opentrades > 0 ? (bar_index - strategy.opentrades.entry_bar_index(strategy.opentrades-1)) : na // plot(barsSinceLastEntry(),"BSLE") inLong = false inShort = false last_high = high[1] last_low = low[1] long_SL = last_low - datrp short_SL = last_high + datrp long_PT = last_high + math.abs(high[1]-low[1]) short_PT = last_low - math.abs(high[1]-low[1]) long_CT_PT = long_PT short_CT_PT = short_PT last_entry = strategy.opentrades.entry_price(strategy.opentrades-1) L_risk = last_entry - long_SL S_risk = short_SL - last_entry if strategy.opentrades > 0 and not(trailing_stop) long_SL := math.min(long_SL[barsSinceLastEntry()], last_low) short_SL := math.max(short_SL[barsSinceLastEntry()], last_high) L_risk := last_entry - long_SL S_risk := short_SL - last_entry long_PT := last_entry + L_risk * RR short_PT := last_entry - S_risk * RR long_SL := long_SL + (L_risk * SL_offset * 0.01) short_SL := short_SL - (S_risk * SL_offset * 0.01) if strategy.opentrades.size(0) > 0 and barsSinceLastEntry() > 0 inLong := true else if strategy.opentrades.size(0) < 0 and barsSinceLastEntry() > 0 inShort := true else long_PT := last_high + math.abs(high-long_SL) short_PT := last_low - math.abs(short_SL-low) // ************************************************************************************************************************************** Exit Conditions ******************************** exit0 = true closeEnough_thres = datr * closeEnough_Percent/100 plot(closeEnough_thres, "Distance from PT to exit early") L_exit1 = upFractal and long_PT - high[n] < closeEnough_thres S_exit1 = downFractal and low[n] - short_PT < closeEnough_thres plot(L_exit1 ? 1 : S_exit1? -1 : 0, "Exit early") // ************************************************************************************************************************************ Exit orders ***************************** if not(trade_trailing) and window strategy.exit("Exit", "Long", stop= long_SL, limit = long_PT, comment = "Exit Long SL/PT hit") strategy.exit("Exit", "Short", stop= short_SL, limit = short_PT, comment = "Exit Short SL/PT hit") strategy.exit("Exit","Long_cntr",stop= long_SL, limit = long_PT, comment="Exit long Counter Trade") strategy.exit("Exit","Short_cntr",stop= short_SL, limit = short_PT, comment="Exit short Counter Trade") if trade_earlyexit and strategy.opentrades.profit(strategy.opentrades-1) > 0 strategy.close("Long", when = L_exit1, comment = "Exit - Take profit") strategy.close("Short", when = S_exit1, comment = "Exit - Take profit") strategy.close("Long_cntr", when = L_exit1, comment = "Exit - Take profit") strategy.close("Short_cntr", when = S_exit1, comment = "Exit - Take profit") // *************** Trailing SL ******************************************* if trade_trailing and (high > long_PT or TS[1] == 1) and window long_SL := math.max(long_SL[1], low - datrp) trailing_stop := true strategy.exit("Exit", "Long", when = exit0 and window, stop= long_SL, comment = "Exit Long Trailing SL") strategy.exit("Exit","Long_cntr",stop= long_SL, comment="Exit long Counter Trade") if trade_trailing and not(trailing_stop) and window strategy.exit("Exit", "Long", stop= long_SL, comment = "Exit Long SL/PT hit") strategy.exit("Exit","Long_cntr",stop= long_SL, comment="Exit long Counter Trade") if trade_trailing and (low < short_PT or TS[1] == 1) and window short_SL := math.min(short_SL[1], high + datrp) trailing_stop := true strategy.exit("Exit", "Short", when= exit0 and window, stop= short_SL, comment = "Exit Short Trailing SL") strategy.exit("Exit","Short_cntr",stop= short_SL, comment="Exit short Counter Trade") if trade_trailing and not(trailing_stop) and window strategy.exit("Exit", "Short", stop= short_SL, comment = "Exit Short SL/PT hit") strategy.exit("Exit","Short_cntr",stop= short_SL, comment="Exit short Counter Trade") if time(timeframe.period, "1550-1551:246") strategy.close_all() if time(timeframe.period, "1550-1551:35") strategy.close("Long", qty_percent = 50, comment="Close 1/2 EOD") strategy.close("Short", qty_percent = 50, comment="Close 1/2 EOD") strategy.close("Long_cntr", qty_percent = 50, comment="Close 1/2 EOD") strategy.close("Short_cntr", qty_percent = 50, comment="Close 1/2 EOD") if strategy.opentrades == 0 trailing_stop := false TS := trailing_stop? 1:0 SSL = plot(short_SL,title = "Short SL", color= inShort ? color.red: color.new(color.red,100), linewidth = 3) LSL = plot(long_SL,title = "Long SL", color= inLong ? color.red: color.new(color.red,100), linewidth = 3) LPT = plot(long_PT,title = "Long PT", color= inLong ? color.green: color.new(color.green,100), linewidth = 3) SPT = plot(short_PT,title = "Short PT", color= inShort ? color.green: color.new(color.green,100), linewidth = 3) LE = plot(last_entry, title = "Last entry", color = strategy.opentrades > 0 ? color.gray : color.new(color.gray,100)) 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)