// ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— \\ //@version=5 library('BACKTEST', overlay=false) // @description TODO: Regroupement of useful functions for backtesting round_price(x) => xx = int(x / syminfo.mintick) xx * syminfo.mintick // ========================================================================================================================================================================================================================================================================================== // @function switch case return exact @timezone for timezone input // @param string tz(timezone input). // @returns syminfo.timezone or tz export ex_timezone(simple string tz) => switch tz 'Exchange' => syminfo.timezone => tz // @function if_in_date_range : check if @time_close is range [fromDate, toDate] // @param bool usefromDate. // @param int fromDate. // @param bool usetoDate. // @param int toDate. // @param string src_timezone. // @param string dst_timezone. // @returns true if @time_close is range [fromDate, toDate] export if_in_date_range(simple bool usefromDate, simple int fromDate, simple bool usetoDate, simple int toDate, simple string src_timezone, simple string dst_timezone) => var int t = time_close var src_tz = ex_timezone(src_timezone) var dst_tz = ex_timezone(dst_timezone) var fromDateTz = timestamp(src_tz, year(fromDate, dst_tz), month(fromDate, dst_tz), dayofmonth(fromDate, dst_tz), hour(fromDate, dst_tz), minute(fromDate, dst_tz), second(fromDate, dst_tz)) var toDateTz = timestamp(src_tz, year(toDate, dst_tz), month(toDate, dst_tz), dayofmonth(toDate, dst_tz), hour(toDate, dst_tz), minute(toDate, dst_tz), second(toDate, dst_tz)) (usefromDate ? t >= fromDateTz : true) and (usetoDate ? t < toDateTz : true) // @function if_in_session : check if @time_close is range [(sessionStartHour, sessionStartMinute), (sessionEndHour, sessionEndMinute)] // @param bool useSessionStart. // @param int sessionStartHour. // @param int sessionStartMinute. // @param bool useSessionEnd. // @param int sessionEndHour. // @param int sessionEndMinute. // @param bool useSessionDay. // @param bool mon. // @param bool tue. // @param bool wed. // @param bool thu. // @param bool fri. // @param bool sat. // @param bool sun. // @param string src_timezone. // @param string dst_timezone. // @returns true if @time_close is range [(sessionStartHour, sessionStartMinute), (sessionEndHour, sessionEndMinute)] export if_in_session(simple bool useSessionStart, simple int sessionStartHour, simple int sessionStartMinute, simple bool useSessionEnd, simple int sessionEndHour, simple int sessionEndMinute, simple bool useSessionDay, simple bool mon, simple bool tue, simple bool wed, simple bool thu, simple bool fri, simple bool sat, simple bool sun, simple string src_timezone, simple string dst_timezone) => var int t = time_close var one_day = 86400000 var utc_tz = 'UTC' var src_tz = ex_timezone(src_timezone) var dst_tz = ex_timezone(dst_timezone) start_hr = sessionStartHour + (hour(t, dst_tz) - hour(t, src_tz)) start_min = sessionStartMinute + (minute(t, dst_tz) - minute(t, src_tz)) end_hr = sessionEndHour + (hour(t, dst_tz) - hour(t, src_tz)) end_min = sessionEndMinute + (minute(t, dst_tz) - minute(t, src_tz)) time_start_session = timestamp(dst_tz, year(t, src_tz), month(t, src_tz), dayofmonth(t, src_tz), start_hr, start_min, second(t, src_tz)) time_end_session = timestamp(dst_tz, year(t, src_tz), month(t, src_tz), dayofmonth(t, src_tz), end_hr, end_min, second(t, src_tz)) var bool isOvernight = time_start_session >= time_end_session // in overnight sessions increase end time by one day if (useSessionStart and useSessionEnd and isOvernight) time_end_session := time_end_session + one_day isSessionDay = switch dayofweek(t, src_tz) dayofweek.monday => mon dayofweek.tuesday => tue dayofweek.wednesday => wed dayofweek.thursday => thu dayofweek.friday => fri dayofweek.saturday => sat dayofweek.sunday => sun => false (useSessionDay ? isSessionDay : true) and (useSessionStart ? t >= time_start_session : true) and (useSessionEnd ? t < time_end_session : true) // @function if_in_session : Check if the SL/TP is reached // @param float lvl. // @param float entry. // @param bool isTake. // @param bool inLong. // @param bool inShort. // @param bool inTrade. // @returns float level export CheckLevels(float lvl, float entry, bool isTake, bool inLong, bool inShort, bool inTrade) => // Check if the SL/TP is reached var float level = na // TP if isTake and ((inLong and high >= lvl) or (inShort and low <= lvl)) level := entry //SL if not isTake and ((inLong and low <= lvl) or (inShort and high >= lvl)) level := entry if not inTrade level := na level // @function if_in_session : Check if the SL/TP is reached // @param float lvl. // @param bool isTake. // @param bool inLong. // @param bool inShort. // @param bool inTrade. // @returns bool achievement_status export CheckLevels2(float lvl, bool isTake, bool inLong, bool inShort, bool inTrade) => // Check if the SL/TP is reached var bool touched = false // TP if isTake and ((inLong and high >= lvl) or (inShort and low <= lvl)) touched := true //SL if not isTake and ((inLong and low <= lvl) or (inShort and high >= lvl)) touched := true if not inTrade touched := na touched // @function Expected Growth Calculation // @param int riskRewardRatio // @param float winRate // @param float riskPerTrade // @param int tradesPerDay // @param int tradingDaysPerMonth // @returns float expectedGrowthPerMonth export calculateExpectedGrowth(int riskRewardRatio, float winRate, float riskPerTrade, int tradesPerDay, int tradingDaysPerMonth) => // Calculate profit percentage per trade profitPerTrade = riskRewardRatio * riskPerTrade // Calculate win and loss rates lossRate = 1 - winRate // Calculate expected growth per trade expectedGrowthPerTrade = (winRate * profitPerTrade) - (lossRate * riskPerTrade) // Calculate number of trades per month tradesPerMonth = tradesPerDay * tradingDaysPerMonth // Calculate expected growth per month expectedGrowthPerMonth = expectedGrowthPerTrade * tradesPerMonth // Return the result expectedGrowthPerMonth // expectedGrowthPerMonth = calculateExpectedGrowth(riskRewardRatio, winRate, riskPerTrade, tradesPerDay, tradingDaysPerMonth) // @function if strategy return table strategy table // @param bool showTable. // @param bool darkTheme. // @returns table strategy table export strategy_table(bool showTable, bool darkTheme, int riskRewardRatio, float winRate, float riskPerTrade, int tradesPerDay, int tradingDaysPerMonth) => // ———————[ Table ]——————— var hodl = 0. var firstClose = 0. var firstCoin = 0. var trades = 5 var isFirst = 0 // // { // if isFirst == 1 and isFirst[1] == 0 // if showHodl // line.new(bar_index, low, bar_index, high, extend=extend.both) firstClose := close firstCoin := strategy.initial_capital / firstClose var tableau = table.new(position = position.top_right, columns = 4, rows =20, bgcolor = color.new(color.yellow, 100), border_width = 1) if barstate.islastconfirmedhistory and showTable initialcap = strategy.initial_capital hodl := math.round((firstCoin * close) , 2) Currenteq = math.round(strategy.equity , 2) // (strategy.initial_capital + strategy.netprofit + strategy.openprofit). closedtrades = strategy.closedtrades opentrades = strategy.opentrades grossprofit = math.round(strategy.grossprofit , 2) grossloss = math.round(strategy.grossloss , 2) netprofit = math.round(strategy.netprofit , 2) openprofit = math.round(strategy.openprofit , 2) max_drawdown = math.round(strategy.max_drawdown, 2) wintrades = strategy.wintrades losstrades = strategy.losstrades eventrades = strategy.eventrades PF = math.round( grossprofit/grossloss , 3) avgTrade = math.round( netprofit /closedtrades, 2) prcProf = math.round(100/(closedtrades/wintrades) , 2) // growth = calculateExpectedGrowth(riskRewardRatio, winRate, riskPerTrade, tradesPerDay, tradingDaysPerMonth) colEq = Currenteq > initialcap ? color.lime : Currenteq < initialcap ? #FF0000 : darkTheme ? color.white : color.black coBaH = hodl > initialcap ? color.lime : hodl < initialcap ? #FF0000 : darkTheme ? color.white : color.black coAVG = avgTrade > 0 ? color.lime : avgTrade < 0 ? #FF0000 : darkTheme ? color.white : color.black bgCEq = Currenteq >= hodl ? color.lime : color.silver bgBaH = Currenteq >= hodl ? color.silver : color.lime colGP = grossprofit > 0 ? color.lime : color.blue colGL = grossloss > 0 ? #FF0000 : color.blue colNP = netprofit > 0 ? color.lime : netprofit < 0 ? #FF0000 : color.blue colOP = openprofit > 0 ? color.lime : color.blue // dartheme txt_color = darkTheme ? color.new(color.white , 10) : color.new(color.black , 10) lbl_color = color.new(color.blue , 10) wrng_clr = color.new(color.red , 10) tds_color = darkTheme ? color.new(color.yellow, 10) : color.new(color.blue , 10) tds_bg_clr = darkTheme ? color.new(color.yellow, 80) : color.new(color.yellow, 80) grey_color = darkTheme ? color.new(color.yellow, 80) : color.new(color.yellow, 80) // table.cell(table_id = tableau, column = 0, row = 1, text = 'INITIAL CAPITAL: ' , text_color = txt_color, bgcolor=grey_color) table.cell(table_id = tableau, column = 0, row = 2, text = 'CURRENT EQUITY: ' , text_color = txt_color, bgcolor=color.new(bgCEq , 90)) table.cell(table_id = tableau, column = 0, row = 3, text = 'BUY AND HOLD: ' , text_color = txt_color, bgcolor=color.new(bgBaH , 90)) table.cell(table_id = tableau, column = 0, row = 4, text = 'MAX DRAWDOWN: ' , text_color = wrng_clr, bgcolor=grey_color) table.cell(table_id = tableau, column = 0, row = 5, text = 'GROSS PROFIT: ' , text_color = lbl_color, bgcolor=grey_color) table.cell(table_id = tableau, column = 0, row = 6, text = 'GROSS LOSS: ' , text_color = lbl_color, bgcolor=grey_color) table.cell(table_id = tableau, column = 0, row = 7, text = 'NET PROFIT: ' , text_color = lbl_color, bgcolor=grey_color) table.cell(table_id = tableau, column = 0, row = 8, text = 'OPEN PROFIT: ' , text_color = lbl_color, bgcolor=grey_color) table.cell(table_id = tableau, column = 0, row = 9, text = 'EXPECTED GROWTH: ' , text_color = lbl_color, bgcolor=grey_color) // table.cell(table_id = tableau, column = 1, row = 1, text = str.tostring(initialcap) , text_color = txt_color, bgcolor=grey_color) table.cell(table_id = tableau, column = 1, row = 2, text = str.tostring(Currenteq) , text_color = color.new(colEq , 10), bgcolor=color.new(bgCEq , 90)) table.cell(table_id = tableau, column = 1, row = 3, text = str.tostring(hodl) , text_color = color.new(coBaH , 10), bgcolor=color.new(bgBaH , 90)) table.cell(table_id = tableau, column = 1, row = 4, text = str.tostring(max_drawdown), text_color = wrng_clr, bgcolor=grey_color) table.cell(table_id = tableau, column = 1, row = 5, text = str.tostring(grossprofit) , text_color = color.new(colGP , 10), bgcolor=grey_color) table.cell(table_id = tableau, column = 1, row = 6, text = str.tostring(grossloss) , text_color = color.new(colGL , 10), bgcolor=grey_color) table.cell(table_id = tableau, column = 1, row = 7, text = str.tostring(netprofit) , text_color = color.new(colNP , 10), bgcolor=grey_color) table.cell(table_id = tableau, column = 1, row = 8, text = str.tostring(openprofit) , text_color = color.new(colOP , 10), bgcolor=grey_color) table.cell(table_id = tableau, column = 1, row = 9, text = str.tostring(growth)+" %" , text_color = color.new(colOP , 10), bgcolor=grey_color) // table.cell(table_id = tableau, column = 2, row = 1, text = 'PROFIT FACTOR: ' , text_color = txt_color, bgcolor=grey_color) table.cell(table_id = tableau, column = 2, row = 2, text = '% PROFITABLE: ' , text_color = txt_color, bgcolor=grey_color) table.cell(table_id = tableau, column = 2, row = 3, text = 'AVG TRADES: ' , text_color = txt_color, bgcolor=grey_color) table.cell(table_id = tableau, column = 2, row = 4, text = 'CLOSED TRADES: ' , text_color = txt_color, bgcolor=tds_bg_clr) table.cell(table_id = tableau, column = 2, row = 5, text = 'WIN TRADES: ' , text_color = txt_color, bgcolor=tds_bg_clr) table.cell(table_id = tableau, column = 2, row = 6, text = 'LOSS TRADES: ' , text_color = txt_color, bgcolor=tds_bg_clr) table.cell(table_id = tableau, column = 2, row = 7, text = 'EVEN TRADES: ' , text_color = txt_color, bgcolor=tds_bg_clr) table.cell(table_id = tableau, column = 2, row = 8, text = 'OPEN TRADES: ' , text_color = txt_color, bgcolor=tds_bg_clr) // table.cell(table_id = tableau, column = 3, row = 1, text = str.tostring(PF) , text_color = txt_color, bgcolor=grey_color) table.cell(table_id = tableau, column = 3, row = 2, text = str.tostring(prcProf) , text_color = txt_color, bgcolor=grey_color) table.cell(table_id = tableau, column = 3, row = 3, text = str.tostring(avgTrade) , text_color = color.new(coAVG , 10), bgcolor=grey_color) table.cell(table_id = tableau, column = 3, row = 4, text = str.tostring(closedtrades), text_color = tds_color, bgcolor=tds_bg_clr) table.cell(table_id = tableau, column = 3, row = 5, text = str.tostring(wintrades) , text_color = color.new(color.lime , 10), bgcolor=tds_bg_clr) table.cell(table_id = tableau, column = 3, row = 6, text = str.tostring(losstrades) , text_color = color.new(#FF0000 , 10), bgcolor=tds_bg_clr) table.cell(table_id = tableau, column = 3, row = 7, text = str.tostring(eventrades) , text_color = tds_color, bgcolor=tds_bg_clr) table.cell(table_id = tableau, column = 3, row = 8, text = str.tostring(opentrades) , text_color = tds_color, bgcolor=tds_bg_clr) tableau // // } // @function Track TakeProfits and StopLoss achievement for one or many of your buy/sell conditions. CHECK the commented section: "Function @manageTrade" (lines: 14 - 64) for Description // @param bool goLong. // @param bool goShort. // @param float entry. // @param float tp1x. // @param float tp2x. // @param float tp3x. // @param float tp4x. // @param float tp5x. // @param float tp6x. // @param float slx. // @returns TP_achievment status for 6 tps: [trade_started, tp1_touched, tp2_touched, tp3_touched, tp4_touched, tp5_touched, tp6_touched, sl_touched, entry_hit, tp1_hit, tp2_hit, tp3_hit, tp4_hit, tp5_hit, tp6_hit] export quick_tp_check(bool goLong, bool goShort, float entry, float tp1, float tp2, float tp3, float tp4, float tp5, float tp6, float sl) => long = goLong short = goShort pos = 0.0 pos := long? 1 : short? -1 : pos[1] longCond1 = long and pos[1]!= 1 shortCond1 = short and pos[1]!=-1 buySignal = long and longCond1 sellSignal = short and shortCond1 var int trade_state = 0 var float tp1l = na var float tp2l = na var float tp3l = na var float tp4l = na var float tp5l = na var float tp6l = na var float sll = na var float entry1l = na var entry_hit = false var tp1_hit = false var tp2_hit = false var tp3_hit = false var tp4_hit = false var tp5_hit = false var tp6_hit = false var sl_hit = false // ======================================================================================================================================================================================= if trade_state == 1 if sellSignal trade_state := 0 if entry_hit == false and ta.cross(low ,entry1l) or ta.cross(high, entry1l) entry_hit := true // line.new(bar_index, tp6l, bar_index,sll, color = color.yellow, width=2) //DEBUG if entry_hit == true and tp1_hit == false and high >= tp1l tp1_hit := true if entry_hit == true and tp2_hit == false and high >= tp2l tp2_hit := true if entry_hit == true and tp3_hit == false and high >= tp3l tp3_hit := true if entry_hit == true and tp4_hit == false and high >= tp4l tp4_hit := true if entry_hit == true and tp5_hit == false and high >= tp5l tp5_hit := true if entry_hit == true and tp6_hit == false and high >= tp6l tp6_hit := true if entry_hit == true and low <= sll trade_state := 0 sl_hit := low <= sll if trade_state == -1 if buySignal trade_state := 0 if entry_hit == false and ta.cross(low ,entry1l) or ta.cross(high, entry1l) entry_hit := true // line.new(bar_index, tp6l, bar_index,sll, color = color.yellow, width=3) //DEBUG if entry_hit == true and tp1_hit == false and low <= tp1l tp1_hit := true if entry_hit == true and tp2_hit == false and low <= tp2l tp2_hit := true if entry_hit == true and tp3_hit == false and low <= tp3l tp3_hit := true if entry_hit == true and tp4_hit == false and low <= tp4l tp4_hit := true if entry_hit == true and tp5_hit == false and low <= tp5l tp5_hit := true if entry_hit == true and tp6_hit == false and low <= tp6l tp6_hit := true if entry_hit == true and high >= sll trade_state := 0 sl_hit := high >= sll // ======================================================================================================================================================================================= if trade_state == 0 if buySignal trade_state := 1 entry_hit := false tp1_hit := false tp2_hit := false tp3_hit := false tp4_hit := false tp5_hit := false tp6_hit := false sl_hit := false entry1l := entry tp1l := tp1 tp2l := tp2 tp3l := tp3 tp4l := tp4 tp5l := tp5 tp6l := tp6 sll := sl // line.new(bar_index, tp6l, bar_index,sll, color = color.aqua, width=1) //DEBUGG if sellSignal trade_state := -1 entry_hit := false tp1_hit := false tp2_hit := false tp3_hit := false tp4_hit := false tp5_hit := false tp6_hit := false sl_hit := false entry1l := entry tp1l := tp1 tp2l := tp2 tp3l := tp3 tp4l := tp4 tp5l := tp5 tp6l := tp6 sll := sl // line.new(bar_index, tp6l, bar_index,sll, color = color.red, width=1) //DEBUGG trade_started = not entry_hit[1] and entry_hit tp1_touched = not tp1_hit[1] and tp1_hit tp2_touched = not tp2_hit[1] and tp2_hit tp3_touched = not tp3_hit[1] and tp3_hit tp4_touched = not tp4_hit[1] and tp4_hit tp5_touched = not tp5_hit[1] and tp5_hit tp6_touched = not tp6_hit[1] and tp6_hit sl_touched = not sl_hit[1] and sl_hit [trade_started, tp1_touched, tp2_touched, tp3_touched, tp4_touched, tp5_touched, tp6_touched, sl_touched, entry_hit, tp1_hit, tp2_hit, tp3_hit, tp4_hit, tp5_hit, tp6_hit] // @function Plots TakeProfits and StopLoss achievement // @param bool darkTheme. // @param bool useSignal. // @param bool b_gameOVer. // @param bool b_gameOVer. // @param bool TP1_touched. // @param bool TP2_touched. // @param bool TP3_touched. // @param bool TP4_touched. // @param bool TP5_touched. // @param bool TP6_touched. // @param bool SL_touched. // @returns PLOTS export plot_tpz(bool darkTheme, bool useSignal, bool inLong, bool inShort, bool TP1_touched, bool TP2_touched, bool TP3_touched, bool TP4_touched, bool TP5_touched, bool TP6_touched, bool SL_touched) => label lb_TP1 = na label lb_TP2 = na label lb_TP3 = na label lb_TP4 = na label lb_TP5 = na label lb_TP6 = na label lb_buySL = na if inLong and useSignal if TP1_touched lb_TP1 := label.new(bar_index, na, text="TP1",color=color.green, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.abovebar, textalign=text.align_left,size=size.normal) if TP2_touched lb_TP2 := label.new(bar_index, na, text="TP2",color=color.yellow, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.abovebar, textalign=text.align_left,size=size.normal) if TP3_touched lb_TP3 := label.new(bar_index, na, text="TP3",color=color.orange, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.abovebar, textalign=text.align_left,size=size.normal) if TP4_touched lb_TP4 := label.new(bar_index, na, text="TP4",color=color.gray, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.abovebar, textalign=text.align_left,size=size.normal) if TP5_touched lb_TP5 := label.new(bar_index, na, text="TP5",color=color.lime, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.abovebar, textalign=text.align_left,size=size.normal) if TP6_touched lb_TP6 := label.new(bar_index, na, text="TP6",color=color.fuchsia, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.abovebar, textalign=text.align_left,size=size.normal) if SL_touched lb_buySL := label.new(bar_index, na, text= "SL",color=color.red, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.belowbar, textalign=text.align_left,size=size.normal) if inShort and useSignal if TP1_touched lb_TP1 := label.new(bar_index, na, text="TP1",color=color.green, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.belowbar, textalign=text.align_left,size=size.normal) if TP2_touched lb_TP2 := label.new(bar_index, na, text="TP2",color=color.yellow, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.belowbar, textalign=text.align_left,size=size.normal) if TP3_touched lb_TP3 := label.new(bar_index, na, text="TP3",color=color.orange, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.belowbar, textalign=text.align_left,size=size.normal) if TP4_touched lb_TP4 := label.new(bar_index, na, text="TP4",color=color.gray, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.belowbar, textalign=text.align_left,size=size.normal) if TP5_touched lb_TP5 := label.new(bar_index, na, text="TP5",color=color.lime, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.belowbar, textalign=text.align_left,size=size.normal) if TP6_touched lb_TP6 := label.new(bar_index, na, text="TP6",color=color.fuchsia, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.belowbar, textalign=text.align_left,size=size.normal) if SL_touched lb_buySL := label.new(bar_index, na, text= "SL",color=color.red, textcolor=not darkTheme ? color.black: color.white, style=label.style_cross,xloc = xloc.bar_index, yloc=yloc.abovebar, textalign=text.align_left,size=size.normal) // @function TP_SL_MATH // @param string tpType // @param bool b_gameOVer. // @param bool b_gameOVer. // @param bool useTp1. // @param bool useTp2. // @param bool useTp3. // @param bool useTp4. // @param bool useTp5. // @param bool useTp6. // @param float rr_pt. // @param float reward. // @param float tp1x. // @param float tp2x. // @param float tp3x. // @param float tp4x. // @param float tp5x. // @param float tp6x. // @param float slr. // @returns PLOTS export TP_SL_math(string tpType, bool useTp2, bool useTp3, bool useTp4, bool useTp5, bool useTp6, float rr_pt, float reward, float tp1x, float tp2x, float tp3x, float tp4x, float tp5x, float tp6x, float slr, float perc_from_sl) => useT2 = tpType == 'SL R:R' ? na : tpType == 'R:R' ? na : tpType == 'Extra R:R' or tpType == 'SL Extra R:R' or tpType == 'FIXED %' or tpType == 'Splitted R:R' or tpType == 'SL Splitted R:R' ? useTp2 : false useT3 = tpType == 'SL R:R' ? na : tpType == 'R:R' ? na : tpType == 'Extra R:R' or tpType == 'SL Extra R:R' or tpType == 'FIXED %' or tpType == 'Splitted R:R' or tpType == 'SL Splitted R:R' ? useTp3 : false useT4 = tpType == 'SL R:R' ? na : tpType == 'R:R' ? na : tpType == 'Extra R:R' or tpType == 'SL Extra R:R' or tpType == 'FIXED %' or tpType == 'Splitted R:R' or tpType == 'SL Splitted R:R' ? useTp4 : false useT5 = tpType == 'SL R:R' ? na : tpType == 'R:R' ? na : tpType == 'Extra R:R' or tpType == 'SL Extra R:R' or tpType == 'FIXED %' or tpType == 'Splitted R:R' or tpType == 'SL Splitted R:R' ? useTp5 : false useT6 = tpType == 'SL R:R' ? na : tpType == 'R:R' ? na : tpType == 'Extra R:R' or tpType == 'SL Extra R:R' or tpType == 'FIXED %' or tpType == 'Splitted R:R' or tpType == 'SL Splitted R:R' ? useTp6 : false tp1_r = tpType == 'SL R:R' ? perc_from_sl * reward : tpType == 'R:R' ? rr_pt * reward : tpType == 'Extra R:R' ? rr_pt * reward : tpType == 'SL Extra R:R' ? (perc_from_sl * reward) : tpType == 'Splitted R:R' ? ((rr_pt * reward) / 6) : tpType == 'SL Splitted R:R' ? ((perc_from_sl * reward) / 6) : tpType == 'FIXED %' ? tp1x : na tp2_r = tpType == 'SL R:R' ? na : tpType == 'R:R' ? na : tpType == 'Extra R:R' ? 2 * (rr_pt * reward) : tpType == 'SL Extra R:R' ? 2 * (perc_from_sl * reward) : tpType == 'Splitted R:R' ? 2 * ((rr_pt * reward) / 6) : tpType == 'SL Splitted R:R' ? 2 * ((perc_from_sl * reward) / 6) : tpType == 'FIXED %' ? tp2x : na tp3_r = tpType == 'SL R:R' ? na : tpType == 'R:R' ? na : tpType == 'Extra R:R' ? 3 * (rr_pt * reward) : tpType == 'SL Extra R:R' ? 3 * (perc_from_sl * reward) : tpType == 'Splitted R:R' ? 3 * ((rr_pt * reward) / 6) : tpType == 'SL Splitted R:R' ? 3 * ((perc_from_sl * reward) / 6) : tpType == 'FIXED %' ? tp3x : na tp4_r = tpType == 'SL R:R' ? na : tpType == 'R:R' ? na : tpType == 'Extra R:R' ? 4 * (rr_pt * reward) : tpType == 'SL Extra R:R' ? 4 * (perc_from_sl * reward) : tpType == 'Splitted R:R' ? 4 * ((rr_pt * reward) / 6) : tpType == 'SL Splitted R:R' ? 4 * ((perc_from_sl * reward) / 6) : tpType == 'FIXED %' ? tp4x : na tp5_r = tpType == 'SL R:R' ? na : tpType == 'R:R' ? na : tpType == 'Extra R:R' ? 5 * (rr_pt * reward) : tpType == 'SL Extra R:R' ? 5 * (perc_from_sl * reward) : tpType == 'Splitted R:R' ? 5 * ((rr_pt * reward) / 6) : tpType == 'SL Splitted R:R' ? 5 * ((perc_from_sl * reward) / 6) : tpType == 'FIXED %' ? tp5x : na tp6_r = tpType == 'SL R:R' ? na : tpType == 'R:R' ? na : tpType == 'Extra R:R' ? 6 * (rr_pt * reward) : tpType == 'SL Extra R:R' ? 6 * (perc_from_sl * reward) : tpType == 'Splitted R:R' ? 6 * ((rr_pt * reward) / 6) : tpType == 'SL Splitted R:R' ? 6 * ((perc_from_sl * reward) / 6) : tpType == 'FIXED %' ? tp6x : na slx = tpType == 'SL R:R' ? perc_from_sl : tpType == 'R:R' ? rr_pt : tpType == 'Extra R:R' ? rr_pt : tpType == 'SL Extra R:R' ? (perc_from_sl * reward) : tpType == 'Splitted R:R' ? rr_pt : tpType == 'SL Splitted R:R' ? perc_from_sl : tpType == 'FIXED %' ? slr : na [useT2, useT3, useT4, useT5, useT6, tp1_r, tp2_r, tp3_r, tp4_r, tp5_r, tp6_r, slx] // @function TP_SL_MATH // @param string exit_strategy // @param string ID. // @param bool inTrade. // @param float entry1. // @param float tp1. // @param float tp2. // @param float tp3. // @param float tp4. // @param float tp5. // @param float sl. // @param float tp1y. // @param float tp2y. // @param float tp3y. // @param float tp4y. // @param float tp5y. // @param float tp6y. // @param bool tp1_hit. // @param bool tp2_hit. // @param bool tp3_hit. // @param bool tp4_hit. // @param bool tp5_hit. // @param bool tp6_hit. // @param bool tp1_touched. // @param bool tp2_touched. // @param bool tp3_touched. // @param bool tp4_touched. // @param bool tp5_touched. // @param bool tp6_touched. // @param bool inShort. // @param bool inLong. // @returns PLOTS STRATEGY ACTIONS export exit_strategy(string exit_strategy, bool inTrade, string ID, float entry1, float tp1, float tp2, float tp3, float tp4, float tp5, float sl, float tp1y, float tp2y, float tp3y, float tp4y, float tp5y, float tp6y, bool tp1_hit, bool tp2_hit, bool tp3_hit, bool tp4_hit, bool tp5_hit, bool tp6_hit, bool tp1_touched, bool tp2_touched, bool tp3_touched, bool tp4_touched, bool tp5_touched,bool tp6_touched, bool inShort, bool inLong) => if inTrade and barstate.isconfirmed if exit_strategy == "Simple" strategy.exit(id=ID, from_entry=ID, stop=sl, limit=tp1, comment='TP', comment_loss='SL') if exit_strategy == "Trail From BreakEven" if tp1_hit if ((inLong and low <= entry1) or (inShort and high >= entry1)) strategy.close(ID, qty_percent=100, comment='TR1') if tp2_hit if ((inLong and low <= tp1) or (inShort and high >= tp1)) strategy.close(ID, qty_percent=100, comment='TR2') if tp3_hit if ((inLong and low <= tp2) or (inShort and high >= tp2)) strategy.close(ID, qty_percent=100, comment='TR3') if tp4_hit if ((inLong and low <= tp3) or (inShort and high >= tp3)) strategy.close(ID, qty_percent=100, comment='TR4') if tp5_hit if ((inLong and low <= tp4) or (inShort and high >= tp4)) strategy.close(ID, qty_percent=100, comment='TR5') if tp6_hit if ((inLong and low <= tp5) or (inShort and high >= tp5)) strategy.close(ID, qty_percent=100, comment='TR6') strategy.exit(id="SL", from_entry=ID, stop=sl, comment='SL') if exit_strategy == "Partial Take" strategy.exit(id="SL", stop=sl, comment='SL') if tp1_touched strategy.close(ID, qty_percent=tp1y, comment='PT1') if tp2_touched strategy.close(ID, qty_percent=tp2y, comment='PT2') if tp3_touched strategy.close(ID, qty_percent=tp3y, comment='PT3') if tp4_touched strategy.close(ID, qty_percent=tp4y, comment='PT4') if tp5_touched strategy.close(ID, qty_percent=tp5y, comment='PT5') if tp6_touched strategy.close(ID, qty_percent=tp6y, comment='PT6') if exit_strategy == "Trail&Split" if tp1_touched strategy.close(ID, qty_percent=tp1y, comment='PT1') if tp1_hit and ((inLong and low <= entry1) or (inShort and high >= entry1)) strategy.close(ID, qty_percent=100, comment='TR1') if tp2_touched strategy.close(ID, qty_percent=tp2y, comment='PT2') if tp2_hit and ((inLong and low <= tp1) or (inShort and high >= tp1)) strategy.close(ID, qty_percent=100, comment='TR2') if tp3_touched strategy.close(ID, qty_percent=tp3y, comment='PT3') if tp3_hit and ((inLong and low <= tp2) or (inShort and high >= tp2)) strategy.close(ID, qty_percent=100, comment='TR3') if tp4_touched strategy.close(ID, qty_percent=tp4y, comment='PT4') if tp4_hit and ((inLong and low <= tp3) or (inShort and high >= tp3)) strategy.close(ID, qty_percent=100, comment='TR4') if tp5_touched strategy.close(ID, qty_percent=tp5y, comment='PT5') if tp5_hit and ((inLong and low <= tp4) or (inShort and high >= tp4)) strategy.close(ID, qty_percent=100, comment='TR5') if tp6_touched strategy.close(ID, qty_percent=tp6y, comment='PT6') if tp6_hit and ((inLong and low <= tp5) or (inShort and high >= tp5)) strategy.close(ID, qty_percent=100, comment='TR6') strategy.exit(id="SL", from_entry=ID, stop=sl, comment='SL') // @function Draw_Session_Switch_candle is designed to draw session switch indicators on a chart. // @param color colorSess // @param bool route_cond. // @param bool newDaySession. // @param float newsessionPerc. // @param bool separateDays. // @param color Day_Bg. // @param color route_color2. // @param string retxt_color. // @param float low_route. // @param float high_route. // @param float dailyLow. // @param float dailyHigh. // @param int linewidth // @param int linewidth_nwsessCande // Return nothing: void function to plot label and line export Draw_Session_Switch_candle(bool colorSess, bool route_cond, bool newDaySession, float newsessionPerc, bool separateDays, color Day_Bg, color route_color2, string retxt_color, float low_route, float high_route, float dailyLow, float dailyHigh, int linewidth_nwday, int linewidth_nwsessCande) => label lb_high = na label lb_low = na label lb_high2 = na label lb_low2 = na float ylow = na float yhigh = na float ylow2 = na float yhigh2 = na if colorSess if route_cond ylow := (low_route[1] * (1 - (newsessionPerc / 100))) yhigh := (high_route[1] * (1 + (newsessionPerc / 100))) ylow2 := (low_route[1] * (1 - ((newsessionPerc + (newsessionPerc) / 2) / 100))) yhigh2 := (high_route[1] * (1 + ((newsessionPerc + (newsessionPerc) / 2) / 100))) lb_high := label.new(bar_index, yhigh, color=route_color2, textcolor=route_color2, style=label.style_triangledown, xloc=xloc.bar_index, textalign=text.align_center, size=size.tiny) lb_low := label.new(bar_index, ylow, color=route_color2, textcolor=route_color2, style=label.style_triangleup, xloc=xloc.bar_index, textalign=text.align_center, size=size.tiny) lb_high2 := label.new(bar_index, yhigh2, color=route_color2, textcolor=color.white, text=retxt_color, style=label.style_label_down, textalign=text.align_center, size=size.normal) lb_low2 := label.new(bar_index, ylow2, color=route_color2, textcolor=color.white, text=retxt_color, style=label.style_label_up, textalign=text.align_center, size=size.normal) line.new(x1=bar_index, y1=ylow, x2=bar_index, y2=yhigh, color=route_color2, width=linewidth_nwsessCande, style=line.style_solid) if newDaySession ylow := (dailyLow[1] * (1 - (newsessionPerc / 100))) yhigh := (dailyHigh[1] * (1 + (newsessionPerc / 100))) ylow2 := (dailyLow[1] * (1 - ((newsessionPerc + (newsessionPerc) / 2) / 100))) yhigh2 := (dailyHigh[1] * (1 + ((newsessionPerc + (newsessionPerc) / 2) / 100))) daily_lab_high = label.new(not separateDays ? na : bar_index, yhigh, color=Day_Bg, textcolor=route_color2, style=label.style_triangledown, xloc=xloc.bar_index, textalign=text.align_center, size=size.tiny) daily_lab_low = label.new(not separateDays ? na : bar_index, ylow, color=Day_Bg, textcolor=route_color2, style=label.style_triangleup, xloc=xloc.bar_index, textalign=text.align_center, size=size.tiny) daily_lab_high2 = label.new(not separateDays ? na : bar_index, yhigh2, color=Day_Bg, textcolor=color.white, text="NEW DAILY SESSION", style=label.style_label_down, xloc=xloc.bar_index, textalign=text.align_center, size=size.normal) daily_lab_low2 = label.new(not separateDays ? na : bar_index, ylow2, color=Day_Bg, textcolor=color.white, text="NEW DAILY SESSION", style=label.style_label_up, xloc=xloc.bar_index, textalign=text.align_center, size=size.normal) line.new(x1=not separateDays ? na : bar_index, y1=dailyLow[1], x2=not separateDays ? na : bar_index, y2=dailyHigh[1], color=Day_Bg, width=linewidth_nwday, style=line.style_solid)