// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © fluxchart
//@version=6
indicator('ORB Algo | Flux Charts', overlay = true, max_boxes_count = 500, max_labels_count = 500, max_lines_count = 500, max_bars_back = 5000)
const bool DEBUG = false
int maxBarsBack = last_bar_index
int renderMaxBarsBack = 5000
const float minimumProfitPercent = 0.20
const float minimumProfitIncrementPercent = 0.075
const float stopLossPercent = 1.0 // Only when SL Method "Fixed"
const float atrTP1Mult = 0.75
const float atrTP2Mult = 1.5
const float atrTP3Mult = 2.25
const float atrTotalMult = 1.0
orbTimeStr = input.timeframe('30', 'ORB Timeframe', group = 'Algorithm', display = display.none)
sensitivity = input.string('Medium', 'Sensitivity', options = ['High', 'Medium', 'Low', 'Lowest'], group = 'Algorithm', display = display.none)
breakoutCondition = input.string('Close', 'Breakout Condition', options = ['Close', 'EMA'], group = 'Algorithm', display = display.none)
tpMethod = input.string('Dynamic', 'TP Method', options = ['Dynamic', 'ATR'], group = 'Algorithm', display = display.none)
emaLength = input.int(9, 'EMA Length', options = [4, 9, 13, 20, 34], group = 'Algorithm', display = display.none)
slMethod = input.string('Balanced', 'Stop-Loss', options = ['Safer', 'Balanced', 'Risky'], group = 'Algorithm', display = display.none)
adaptiveSL = input.bool(true, 'Adaptive SL', group = 'Algorithm', display = display.none)
customSessionEnabled = input.bool(false, 'Enabled', group = 'Custom Session', display = display.none)
customSessionTime = input.session('1000-1100', 'Session', group = 'Custom Session', display = display.none)
orbDisplayEnabled = input.bool(true, 'Enabled', group = 'ORB Dashboard', display = display.none)
orbLocation = input.string('Top Right', 'Position', options = ['Top Right', 'Right Center', 'Top Center'], group = 'ORB Dashboard', display = display.none)
backtestDisplayEnabled = input.bool(true, 'Enabled', group = 'Backtesting', display = display.none)
backtestingLocation = input.string('Top Center', 'Position', options = ['Top Right', 'Right Center', 'Top Center'], group = 'Backtesting', display = display.none)
backtestingExitRatios = input.string('90% | 5% | 5%', 'Backtesting Exit Ratios', ['75% | 15% | 10%', '50% | 25% | 25%', '34% | 33% | 33%', '90% | 5% | 5%', '100% | 0% | 0%', '0% | 100% | 0%', '0% | 0% | 100%'], tooltip = 'TP 1 | TP 2 | TP 3', group = 'Backtesting', display = display.none)
showORBZones = input.bool(true, 'Draw ORB Zones', group = 'Visuals', display = display.none, inline = 'group1')
plotEMA = input.bool(false, 'Plot EMA', group = 'Visuals', display = display.none, inline = 'group1')
showHistoricZones = DEBUG ? input.bool(true, 'Show Historic Zones', group = 'Visuals', display = display.none) : true
highColor = input.color(color.green, 'High', inline = 'colors', group = 'Visuals')
lowColor = input.color(color.red, 'Low', inline = 'colors', group = 'Visuals')
float backtestTP1Exit = 0.0
float backtestTP2Exit = 0.0
float backtestTP3Exit = 0.0
backtestTP1Exit := str.tonumber(str.replace(array.get(str.split(backtestingExitRatios, ' | '), 0), '%', '')) / 100.0
backtestTP2Exit := str.tonumber(str.replace(array.get(str.split(backtestingExitRatios, ' | '), 1), '%', '')) / 100.0
backtestTP3Exit := str.tonumber(str.replace(array.get(str.split(backtestingExitRatios, ' | '), 2), '%', '')) / 100.0
retestsNeededForEntry = sensitivity == 'High' ? 0 : sensitivity == 'Medium' ? 1 : sensitivity == 'Low' ? 2 : 3
if timeframe.in_seconds() > timeframe.in_seconds('15')
runtime.error('ORB Algo only works on timeframes lower than 15 min.')
type Breakout
bool isBullish
int startIndex
int endIndex
bool failed = false
int retests = 0
type ORB
float h
float l
int startTime
int startIndex
int endIndex
bool isLastSession
string state = 'Opening Range'
array<Breakout> breakouts
bool foundEntryTick = false
bool entryBullish
int entryIndex
float entryPrice
float entryATR
int tp1Index
float tp1Price
bool tp1FoundTick = false
int tp2Index
float tp2Price
bool tp2FoundTick = false
int tp3Index
float tp3Price
bool tp3FoundTick = false
int slIndex
float slPrice
bool slFoundTick = false
bool isExitTrade = false
bool exitTradeFoundTick = false
line hLine
line lLine
label entryLabel
getPosition(positionText) =>
if positionText == 'Top Right'
position.top_right
else if positionText == 'Top Center'
position.top_center
else if positionText == 'Right Center'
position.middle_right
else
position.middle_left
createORB(float h, float l, int sT, int sI, int eI) =>
newORB = ORB.new(h, l, sT, sI, eI)
newORB.breakouts := array.new<Breakout>(0)
newORB
safeDeleteORB(ORB orb) =>
line.delete(orb.hLine)
line.delete(orb.lLine)
label.delete(orb.entryLabel)
orbColor = #3b3b3b43
var orbList = array.new<ORB>(0)
ema = ta.ema((high + low) / 2.0, emaLength)
atr = ta.atr(12)
plot(plotEMA ? ema : na)
diffPercent(float val1, float val2) =>
math.abs(val1 - val2) / val2 * 100.0
renderORB(ORB orb) =>
if orb.startIndex > last_bar_index - renderMaxBarsBack
if showORBZones
orb.hLine := line.new(orb.startIndex, orb.h, nz(orb.endIndex, last_bar_index), orb.h, color = highColor, width = 2)
orb.lLine := line.new(orb.startIndex, orb.l, nz(orb.endIndex, last_bar_index), orb.l, color = lowColor, width = 2)
orb.lLine
if not na(orb.entryIndex)
orb.entryLabel := label.new(orb.entryIndex, orb.entryPrice + orb.entryATR * 3 * (orb.entryBullish ? -1 : 1), orb.entryBullish ? 'Buy' : 'Sell', color = orb.entryBullish ? color.green : color.red, textcolor = color.white, style = orb.entryBullish ? label.style_label_up : label.style_label_down)
orb.entryLabel
ORB lastORB = na
ORB previousORB = na
if orbList.size() > 0
lastORB := orbList.get(0)
lastORB.tp1FoundTick := false
lastORB.tp2FoundTick := false
lastORB.tp3FoundTick := false
lastORB.slFoundTick := false
lastORB.foundEntryTick := false
lastORB.exitTradeFoundTick := false
if last_bar_time - time < 60 * 60 * 8 * 1000
lastORB.isLastSession := true
lastORB.isLastSession
else
lastORB.isLastSession := false
lastORB.isLastSession
sessionBegins(sess) =>
t = time('1440', sess)
is_first = na(t[1]) and not na(t) or t[1] < t
is_first
lastClose = close[1]
if barstate.isconfirmed and last_bar_index - bar_index < maxBarsBack
// New ORB
if not customSessionEnabled and session.isfirstbar_regular or customSessionEnabled and sessionBegins(customSessionTime)
// End Last ORB
if not na(lastORB)
lastORB.endIndex := bar_index - 1
// Exit Last ORB if
if not na(lastORB.entryIndex) and na(lastORB.slIndex)
lastORB.slPrice := lastClose
lastORB.slIndex := bar_index - 1
lastORB.exitTradeFoundTick := true
previousORB := lastORB
previousORB
newORB = createORB(na, na, time, bar_index, na)
orbList.unshift(newORB)
lastORB := orbList.get(0)
lastORB
// ORB High & Low
if not na(lastORB)
if lastORB.state == 'Opening Range' and time < lastORB.startTime + timeframe.in_seconds(orbTimeStr) * 1000
lastORB.h := math.max(nz(lastORB.h, 0), high)
lastORB.l := math.min(nz(lastORB.l, low), low)
lastORB.l
if lastORB.state == 'Opening Range' and time >= lastORB.startTime + timeframe.in_seconds(orbTimeStr) * 1000
lastORB.state := 'Waiting For Breakouts'
lastORB.state
// Wait For Retests
if not na(lastORB)
if lastORB.state == 'Waiting For Breakouts'
conditionPrice = breakoutCondition == 'EMA' ? ema : close
if conditionPrice > lastORB.h or conditionPrice < lastORB.l
newBreakout = Breakout.new(conditionPrice > lastORB.h, bar_index, na)
lastORB.breakouts.unshift(newBreakout)
lastORB.state := 'In Breakout'
lastORB.state
// Handle Breakouts
if not na(lastORB)
if lastORB.state == 'In Breakout'
curBreakout = lastORB.breakouts.get(0)
// Failed Breakout
if curBreakout.isBullish and close < lastORB.h or not curBreakout.isBullish and close > lastORB.l
curBreakout.failed := true
curBreakout.endIndex := bar_index
lastORB.state := 'Waiting For Breakouts'
lastORB.state
// Breakout Retest
if bar_index > curBreakout.startIndex and (curBreakout.isBullish and close > lastORB.h and low < lastORB.h or not curBreakout.isBullish and close < lastORB.l and high > lastORB.l)
curBreakout.retests := curBreakout.retests + 1
curBreakout.retests
if curBreakout.retests >= retestsNeededForEntry
curBreakout.endIndex := bar_index
lastORB.state := 'Entry Taken'
lastORB.entryATR := atr
lastORB.foundEntryTick := true
lastORB.entryIndex := bar_index
lastORB.entryPrice := close
lastORB.entryBullish := curBreakout.isBullish
if slMethod == 'Fixed'
if curBreakout.isBullish
lastORB.slPrice := lastORB.entryPrice * ((100.0 - stopLossPercent) / 100.0)
lastORB.slPrice
else
lastORB.slPrice := lastORB.entryPrice * ((100.0 + stopLossPercent) / 100.0)
lastORB.slPrice
center = (lastORB.h + lastORB.l) / 2.0
if slMethod == 'Safer'
lastORB.slPrice := lastORB.entryBullish ? (center + lastORB.h) / 2.0 : (center + lastORB.l) / 2.0
lastORB.slPrice
if slMethod == 'Balanced'
lastORB.slPrice := center
lastORB.slPrice
if slMethod == 'Risky'
lastORB.slPrice := lastORB.entryBullish ? (center + lastORB.l) / 2.0 : (center + lastORB.h) / 2.0
lastORB.slPrice
// Handle Entry
if not na(lastORB)
if lastORB.state == 'Entry Taken'
// Take Profits
isProfitable = lastORB.entryBullish and ema > lastORB.entryPrice or not lastORB.entryBullish and ema < lastORB.entryPrice
if tpMethod == 'Dynamic'
if isProfitable and diffPercent(ema, lastORB.entryPrice) >= minimumProfitPercent
if na(lastORB.slIndex) and na(lastORB.tp1Index) and (lastORB.entryBullish and close < ema or not lastORB.entryBullish and close > ema)
lastORB.tp1Index := bar_index
lastORB.tp1Price := ema
lastORB.tp1FoundTick := true
if adaptiveSL
lastORB.slPrice := lastORB.entryPrice
lastORB.slPrice
else if na(lastORB.slIndex) and not na(lastORB.tp1Index) and na(lastORB.tp2Index) and (lastORB.entryBullish and close < ema or not lastORB.entryBullish and close > ema)
if (lastORB.entryBullish and ema > lastORB.tp1Price or not lastORB.entryBullish and ema < lastORB.tp1Price) and diffPercent(ema, lastORB.tp1Price) >= minimumProfitIncrementPercent
lastORB.tp2Index := bar_index
lastORB.tp2Price := ema
lastORB.tp2FoundTick := true
lastORB.tp2FoundTick
else if na(lastORB.slIndex) and not na(lastORB.tp2Index) and na(lastORB.tp3Index) and (lastORB.entryBullish and close < ema or not lastORB.entryBullish and close > ema)
if (lastORB.entryBullish and ema > lastORB.tp2Price or not lastORB.entryBullish and ema < lastORB.tp2Price) and diffPercent(ema, lastORB.tp2Price) >= minimumProfitIncrementPercent
lastORB.tp3Index := bar_index
lastORB.tp3Price := ema
lastORB.tp3FoundTick := true
lastORB.slIndex := -1
lastORB.slIndex
if tpMethod == 'ATR'
float tp1Price = lastORB.entryPrice + lastORB.entryATR * atrTP1Mult * atrTotalMult * (lastORB.entryBullish ? 1 : -1)
float tp2Price = lastORB.entryPrice + lastORB.entryATR * atrTP2Mult * atrTotalMult * (lastORB.entryBullish ? 1 : -1)
float tp3Price = lastORB.entryPrice + lastORB.entryATR * atrTP3Mult * atrTotalMult * (lastORB.entryBullish ? 1 : -1)
if na(lastORB.slIndex) and na(lastORB.tp1Index) and (lastORB.entryBullish and high >= tp1Price or not lastORB.entryBullish and low <= tp1Price)
lastORB.tp1Index := bar_index
lastORB.tp1Price := tp1Price
lastORB.tp1FoundTick := true
if adaptiveSL
lastORB.slPrice := lastORB.entryPrice
lastORB.slPrice
else if na(lastORB.slIndex) and not na(lastORB.tp1Index) and na(lastORB.tp2Index) and (lastORB.entryBullish and high >= tp2Price or not lastORB.entryBullish and low <= tp2Price)
lastORB.tp2Index := bar_index
lastORB.tp2Price := tp2Price
lastORB.tp2FoundTick := true
lastORB.tp2FoundTick
else if na(lastORB.slIndex) and not na(lastORB.tp2Index) and na(lastORB.tp3Index) and (lastORB.entryBullish and high >= tp3Price or not lastORB.entryBullish and low <= tp3Price)
lastORB.tp3Index := bar_index
lastORB.tp3Price := tp3Price
lastORB.tp3FoundTick := true
lastORB.slIndex := -1
lastORB.slIndex
// Stop Loss
if not na(lastORB.slPrice) and na(lastORB.slIndex) and (lastORB.entryBullish and low < lastORB.slPrice or not lastORB.entryBullish and high > lastORB.slPrice)
if not(bar_index == lastORB.tp1Index or bar_index == lastORB.tp2Index or bar_index == lastORB.tp3Index)
lastORB.slFoundTick := true
lastORB.slIndex := bar_index
lastORB.slIndex
//#region Plots
isClose = bar_index > last_bar_index - renderMaxBarsBack
plotshape(na(lastORB) ? na : lastORB.tp1FoundTick and lastORB.entryBullish and isClose and (showHistoricZones or lastORB.isLastSession) ? close : na, 'TP 1', shape.xcross, size = size.tiny, text = 'TP 1', textcolor = color.white, location = location.abovebar)
plotshape(na(lastORB) ? na : lastORB.tp1FoundTick and not lastORB.entryBullish and isClose and (showHistoricZones or lastORB.isLastSession) ? close : na, 'TP 1', shape.xcross, size = size.tiny, text = 'TP 1', textcolor = color.white, location = location.belowbar)
plotshape(na(lastORB) ? na : lastORB.tp2FoundTick and lastORB.entryBullish and isClose and (showHistoricZones or lastORB.isLastSession) ? close : na, 'TP 2', shape.xcross, size = size.tiny, text = 'TP 2', textcolor = color.white, location = location.abovebar)
plotshape(na(lastORB) ? na : lastORB.tp2FoundTick and not lastORB.entryBullish and isClose and (showHistoricZones or lastORB.isLastSession) ? close : na, 'TP 2', shape.xcross, size = size.tiny, text = 'TP 2', textcolor = color.white, location = location.belowbar)
plotshape(na(lastORB) ? na : lastORB.tp3FoundTick and lastORB.entryBullish and isClose and (showHistoricZones or lastORB.isLastSession) ? close : na, 'TP 3', shape.xcross, size = size.tiny, text = 'TP 3', textcolor = color.white, location = location.abovebar)
plotshape(na(lastORB) ? na : lastORB.tp3FoundTick and not lastORB.entryBullish and isClose and (showHistoricZones or lastORB.isLastSession) ? close : na, 'TP 3', shape.xcross, size = size.tiny, text = 'TP 3', textcolor = color.white, location = location.belowbar)
plotshape(na(lastORB) ? na : lastORB.slFoundTick and lastORB.entryBullish and isClose and (showHistoricZones or lastORB.isLastSession) ? close : na, 'SL', shape.xcross, size = size.tiny, text = 'SL', color = color.red, textcolor = color.white, location = location.belowbar)
plotshape(na(lastORB) ? na : lastORB.slFoundTick and not lastORB.entryBullish and isClose and (showHistoricZones or lastORB.isLastSession) ? close : na, 'SL', shape.xcross, size = size.tiny, text = 'SL', color = color.red, textcolor = color.white, location = location.abovebar)
plotshape(na(previousORB) ? na : previousORB.exitTradeFoundTick and previousORB.entryBullish and isClose and (showHistoricZones or previousORB.isLastSession) ? close : na, 'Exit', shape.xcross, size = size.tiny, text = 'Exit', color = color.red, textcolor = color.white, location = location.belowbar, offset = -1)
plotshape(na(previousORB) ? na : previousORB.exitTradeFoundTick and not previousORB.entryBullish and isClose and (showHistoricZones or previousORB.isLastSession) ? close : na, 'Exit', shape.xcross, size = size.tiny, text = 'Exit', color = color.red, textcolor = color.white, location = location.abovebar, offset = -1)
//#endregion Plots
foundEntryTick = false
foundTPTick = false
foundSLTick = false
if not na(lastORB)
if lastORB.foundEntryTick
foundEntryTick := true
foundEntryTick
if lastORB.tp1FoundTick or lastORB.tp2FoundTick or lastORB.tp3FoundTick
foundTPTick := true
foundTPTick
if lastORB.slFoundTick
foundSLTick := true
foundSLTick
alertcondition(foundEntryTick, 'Buy / Sell')
alertcondition(foundTPTick, 'Take Profit')
alertcondition(foundSLTick, 'Stop Loss')
if barstate.islast
if orbList.size() > 0
for i = 0 to showHistoricZones ? orbList.size() - 1 : 0 by 1
curORB = orbList.get(i)
safeDeleteORB(curORB)
renderORB(curORB)
// Dashboard
if barstate.islast and orbDisplayEnabled
var table ORBDisplay = orbDisplayEnabled ? table.new(getPosition(orbLocation), 4, 5, bgcolor = orbColor, frame_width = 2, frame_color = color.black, border_width = 1, border_color = color.black) : na
ORB lastORBD = na
float foundEntryPrice = na
bool isEntryBullish = false
if orbList.size() > 0
lastORBD := orbList.get(0)
foundEntryPrice := lastORBD.entryPrice
isEntryBullish := lastORBD.entryBullish
isEntryBullish
// Header
table.merge_cells(ORBDisplay, 0, 0, 3, 0)
table.cell(ORBDisplay, 0, 0, 'ORB Dashboard', text_color = color.white, bgcolor = orbColor)
// Bullish / Bearish
table.merge_cells(ORBDisplay, 0, 1, 0, 2)
table.cell(ORBDisplay, 0, 1, na(foundEntryPrice) ? 'No Signal' : isEntryBullish ? 'Bullish' : 'Bearish', text_color = color.white, bgcolor = na(foundEntryPrice) ? orbColor : isEntryBullish ? color.green : color.red)
// Entry Price
table.cell(ORBDisplay, 1, 1, isEntryBullish ? 'Buy Price' : 'Sell Price', text_color = color.white, bgcolor = na(foundEntryPrice) ? orbColor : isEntryBullish ? #4caf50 : color.red)
table.cell(ORBDisplay, 1, 2, na(foundEntryPrice) ? 'No Signal' : str.tostring(foundEntryPrice, format.mintick), text_color = color.white, bgcolor = na(foundEntryPrice) ? orbColor : isEntryBullish ? color.green : color.red)
// Current Profit %
table.merge_cells(ORBDisplay, 2, 1, 3, 1)
table.merge_cells(ORBDisplay, 2, 2, 3, 2)
curProfit = close - foundEntryPrice
if not isEntryBullish
curProfit := curProfit * -1
curProfit
curProfitPercent = curProfit / foundEntryPrice * 100.0
table.cell(ORBDisplay, 2, 1, 'Current Profit %', text_color = color.white, bgcolor = na(foundEntryPrice) ? orbColor : curProfit > 0 ? color.green : color.red)
profitPercentText = ''
//profitPercentText += str.tostring(curProfit, format.mintick) + " | "
profitPercentText := profitPercentText + str.tostring(curProfitPercent, '#.##') + '%'
if na(curProfitPercent)
profitPercentText := 'No Signal'
profitPercentText
table.cell(ORBDisplay, 2, 2, profitPercentText, text_color = color.white, bgcolor = na(foundEntryPrice) ? orbColor : curProfit > 0 ? color.green : color.red)
// TP & SL Levels
if not na(foundEntryPrice) and tpMethod == 'ATR'
table.cell(ORBDisplay, 0, 3, 'TP 1', text_color = color.white)
table.cell(ORBDisplay, 1, 3, 'TP 2', text_color = color.white)
table.cell(ORBDisplay, 2, 3, 'TP 3', text_color = color.white)
table.cell(ORBDisplay, 3, 3, 'SL', text_color = color.white)
float tp1Price = lastORBD.entryPrice + lastORBD.entryATR * atrTP1Mult * atrTotalMult * (lastORBD.entryBullish ? 1 : -1)
float tp2Price = lastORBD.entryPrice + lastORBD.entryATR * atrTP2Mult * atrTotalMult * (lastORBD.entryBullish ? 1 : -1)
float tp3Price = lastORBD.entryPrice + lastORBD.entryATR * atrTP3Mult * atrTotalMult * (lastORBD.entryBullish ? 1 : -1)
table.cell(ORBDisplay, 0, 4, str.tostring(tp1Price, format.mintick), text_color = color.white)
table.cell(ORBDisplay, 1, 4, str.tostring(tp2Price, format.mintick), text_color = color.white)
table.cell(ORBDisplay, 2, 4, str.tostring(tp3Price, format.mintick), text_color = color.white)
table.cell(ORBDisplay, 3, 4, str.tostring(lastORBD.slPrice, format.mintick), text_color = color.white)
else if not na(foundEntryPrice)
table.merge_cells(ORBDisplay, 0, 3, 3, 3)
table.merge_cells(ORBDisplay, 0, 4, 3, 4)
table.cell(ORBDisplay, 0, 3, 'SL', text_color = color.white)
table.cell(ORBDisplay, 0, 4, str.tostring(lastORBD.slPrice, format.mintick), text_color = color.white)
// Backtesting Dashboard
if barstate.islast and backtestDisplayEnabled
var table backtestDisplay = backtestDisplayEnabled ? table.new(getPosition(backtestingLocation), 2, 10, bgcolor = orbColor, frame_width = 2, frame_color = color.black, border_width = 1, border_color = color.black) : na
float totalORBProfitPercent = 0
int successfulTrades = 0
int unsuccessfulTrades = 0
if orbList.size() > 0
for i = 0 to orbList.size() - 1 by 1
curORB = orbList.get(i)
if not na(curORB.entryIndex)
isSuccess = false
float totalProfitTaken = 0.0
if not na(curORB.tp1Price)
isSuccess := true
totalORBProfitPercent := totalORBProfitPercent + diffPercent(curORB.tp1Price, curORB.entryPrice) * backtestTP1Exit
totalProfitTaken := totalProfitTaken + backtestTP1Exit
totalProfitTaken
if not na(curORB.tp2Price)
isSuccess := true
totalORBProfitPercent := totalORBProfitPercent + diffPercent(curORB.tp2Price, curORB.entryPrice) * backtestTP2Exit
totalProfitTaken := totalProfitTaken + backtestTP2Exit
totalProfitTaken
if not na(curORB.tp3Price)
isSuccess := true
totalORBProfitPercent := totalORBProfitPercent + diffPercent(curORB.tp3Price, curORB.entryPrice) * backtestTP3Exit
totalProfitTaken := totalProfitTaken + backtestTP3Exit
totalProfitTaken
if not na(curORB.slIndex)
if curORB.slIndex != -1
totalORBProfitPercent := totalORBProfitPercent - diffPercent(curORB.slPrice, curORB.entryPrice) * (1.0 - totalProfitTaken)
if totalProfitTaken == 0.0
unsuccessfulTrades := unsuccessfulTrades + 1
unsuccessfulTrades
if isSuccess
successfulTrades := successfulTrades + 1
successfulTrades
// Header
table.merge_cells(backtestDisplay, 0, 0, 1, 0)
table.cell(backtestDisplay, 0, 0, 'ORB Backtesting', text_color = color.white, bgcolor = orbColor)
// Total ORBs
table.cell(backtestDisplay, 0, 1, 'Total Days', text_color = color.white, bgcolor = orbColor)
table.cell(backtestDisplay, 1, 1, str.tostring(orbList.size()), text_color = color.white, bgcolor = orbColor)
// Wins
table.cell(backtestDisplay, 0, 2, 'Wins', text_color = color.white, bgcolor = orbColor)
table.cell(backtestDisplay, 1, 2, str.tostring(successfulTrades), text_color = color.white, bgcolor = orbColor)
// Losses
table.cell(backtestDisplay, 0, 3, 'Losses', text_color = color.white, bgcolor = orbColor)
table.cell(backtestDisplay, 1, 3, str.tostring(unsuccessfulTrades), text_color = color.white, bgcolor = orbColor)
// Winrate
table.cell(backtestDisplay, 0, 4, 'Winrate', text_color = color.white, bgcolor = orbColor)
table.cell(backtestDisplay, 1, 4, str.tostring(100.0 * (successfulTrades / (successfulTrades + unsuccessfulTrades)), '#.##') + '%', text_color = color.white, bgcolor = orbColor)
// Average Profit %
table.cell(backtestDisplay, 0, 5, 'Average Profit', text_color = color.white, bgcolor = orbColor)
table.cell(backtestDisplay, 1, 5, str.tostring(totalORBProfitPercent / (successfulTrades + unsuccessfulTrades), '#.##') + '%', text_color = color.white, bgcolor = orbColor)
// Total Profit %
table.cell(backtestDisplay, 0, 6, 'Total Profit', text_color = color.white, bgcolor = orbColor)
table.cell(backtestDisplay, 1, 6, str.tostring(totalORBProfitPercent, '#.##') + '%', text_color = color.white, bgcolor = orbColor)
Show all 482 lines