Strategy Myth-Busting #13 - MultiEMA+BXTrender - [SP/MYN]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © spdoinkal / myncrypto

//@version=5

strategy('Strategy Myth-Busting #13 - MultiEMA+BXTrender - [SP/MYN]', max_bars_back=5000, overlay=true, pyramiding=0, initial_capital=1000, currency='USD', default_qty_type=strategy.percent_of_equity, default_qty_value=10.0, commission_value=0.075, use_bar_magnifier = false)
// Secret EMA Cloud by teddycleps
// B-X Trender 
// Keep all default
// Distance between EMA's need to be spaced, otherwise in a ranged market
// 15 min candles
// Stop Loss on previous swing high/low
// No take profit. Exit on new red/green circle

//Long
//EMA Green (21) on top, White (89)in middle and red (200) on bottom and there is distance between EMA's need to be spaced, otherwise in a ranged market
// Price action must pull back into 89 EMA (White line) either close or touching it.
// Once pullback occurs wait for BX Trender to issue a new green circle and BX Trend line must be green and above 0
// Price action must also pull up back above the (Green Line) EMA 21


//Short
//EMA Red (200) on top, White (89) in middle and Green (21) on bottom and there is distance between EMA's need to be spaced, otherwise in a ranged market
// Price action must pull back into 89 EMA (White line) either close or touching it.
// Once pullback occurs wait for BX Trender to issue a new red circle and BX Trend line must be red and below 0
// Price action must also pull up back below the (green Line) EMA 21

// 21/89/200 EMA Cloud
//░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░


var string EMAGroupName = 'EMA Cloud'


i_fastEMALength = input.int(21, title = 'Fast EMA length', step = 1, group = EMAGroupName)
i_midEMALength = input.int(89, title = 'Mid EMA length', step = 1, group = EMAGroupName)
i_slowEMALength = input.int(200, title ='Slow EMA length', step = 10, group = EMAGroupName)

fEMA = ta.ema(close, i_fastEMALength)
mEMA = ta.ema(close, i_midEMALength)
sEMA = ta.ema(close, i_slowEMALength)

plotFEMA = plot(fEMA, 'FAST EMA', color=color.new(color.green, 0), linewidth = 2, style=plot.style_line)
plotMEMA = plot(mEMA, 'MID EMA', color=color.new(color.white, 0), linewidth = 2, style=plot.style_line)
plotSEMA = plot(sEMA, 'SLOW EMA', color=color.new(color.red, 0), linewidth = 2, style=plot.style_line)

fill(plotFEMA, plotSEMA, color=fEMA > sEMA ? color.new(color.green, 80) : color.new(color.red, 70), title='EMA Background Fill')


// B-Xtrender @Puppytherapy
//░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

var string BXTenderGroupName = 'B-XTENDER INPUTS'

short_l1 = input(5, title='Short - L1', group = BXTenderGroupName)
short_l2 = input(20, title='Short - L2', group = BXTenderGroupName)
short_l3 = input(15, title='Short - L3', group = BXTenderGroupName)

long_l1 = input(20, title='Long - L1', group = BXTenderGroupName)
long_l2 = input(15, title='Long - L2', group = BXTenderGroupName)

shortTermXtrender = ta.rsi(ta.ema(close, short_l1) - ta.ema(close, short_l2), short_l3) - 50
longTermXtrender = ta.rsi(ta.ema(close, long_l1), long_l2) - 50

// shortXtrenderCol = shortTermXtrender > 0 ? shortTermXtrender > shortTermXtrender[1] ? color.lime : #228B22 : shortTermXtrender > shortTermXtrender[1] ? color.red : #8B0000
// plot(shortTermXtrender, color=shortXtrenderCol, style=plot.style_columns, linewidth=1, title='B-Xtrender Osc. - Histogram', transp=50)

t3(src, len) =>
    xe1_1 = ta.ema(src, len)
    xe2_1 = ta.ema(xe1_1, len)
    xe3_1 = ta.ema(xe2_1, len)
    xe4_1 = ta.ema(xe3_1, len)
    xe5_1 = ta.ema(xe4_1, len)
    xe6_1 = ta.ema(xe5_1, len)
    b_1 = 0.7
    c1_1 = -b_1 * b_1 * b_1
    c2_1 = 3 * b_1 * b_1 + 3 * b_1 * b_1 * b_1
    c3_1 = -6 * b_1 * b_1 - 3 * b_1 - 3 * b_1 * b_1 * b_1
    c4_1 = 1 + 3 * b_1 + b_1 * b_1 * b_1 + 3 * b_1 * b_1
    nT3Average_1 = c1_1 * xe6_1 + c2_1 * xe5_1 + c3_1 * xe4_1 + c4_1 * xe3_1
    nT3Average_1

maShortTermXtrender = t3(shortTermXtrender, 5)

// colShortTermXtrender = maShortTermXtrender > maShortTermXtrender[1] ? color.lime : color.red
// plot(maShortTermXtrender, color=color.new(#000000, 0), style=plot.style_line, linewidth=3, title='B-Xtrender Shadow')
// plot(maShortTermXtrender, color=colShortTermXtrender, style=plot.style_line, linewidth=3, title='B-Xtrender Color ')

BXTenderLongEntryCondition = maShortTermXtrender > maShortTermXtrender[1] and maShortTermXtrender[1] < maShortTermXtrender[2] 
BXTenderShortEntryCondition = maShortTermXtrender < maShortTermXtrender[1] and maShortTermXtrender[1] > maShortTermXtrender[2]

plotshape(BXTenderLongEntryCondition ? maShortTermXtrender : na, location=location.belowbar, style=shape.circle, color=color.new(color.lime, 10), size=size.tiny)
plotshape(BXTenderShortEntryCondition ? maShortTermXtrender : na, location=location.abovebar, style=shape.circle, color=color.new(color.red, 10), size=size.tiny)



/////////////////////////////////////
//* Put your strategy rules below *//
/////////////////////////////////////


uptrend = fEMA > mEMA and mEMA > sEMA  
dntrend = fEMA < mEMA and mEMA < sEMA  

// Checks for suitable distance between EMAS
var string EMADistanceGroupName = 'Minimum Gap Distance Between EMAs'
i_minDistanceBetweenEMAs = input(78,title="Minimum distance between 21, 89 and 200 EMAs", group = EMADistanceGroupName)
bool EMAUptrendWithDistance = (fEMA > (mEMA + i_minDistanceBetweenEMAs)) and (mEMA > (sEMA + i_minDistanceBetweenEMAs)) 
bool EMADowntrendWithDistance = (fEMA < (mEMA - i_minDistanceBetweenEMAs)) and (mEMA < (sEMA - i_minDistanceBetweenEMAs)) 
fill(plotFEMA, plotSEMA, color = EMAUptrendWithDistance or EMADowntrendWithDistance  ? color.new(color.gray, 70) : na)


// var string pullBackGroupName = 'EMA Pullback Settings'
// i_marginAboveOrBelowMidEMA = input(100,title="Margin of proximity to middle EMA for pullback detection", group=pullBackGroupName)
// i_lookbackForEMAPullback = input(8, title="Lookback for EMA Pullback", group=pullBackGroupName)
// longMidEMAWithMargin = mEMA + i_marginAboveOrBelowMidEMA
// shortMidEMAWithMargin = mEMA - i_marginAboveOrBelowMidEMA
// longEMAPullBack = close < longMidEMAWithMargin
// shortEMAPullBack= close > shortMidEMAWithMargin 
// longPB = ta.barssince(longEMAPullBack) <= i_lookbackForEMAPullback
// shortPB = ta.barssince(shortEMAPullBack) <= i_lookbackForEMAPullback


//Check for pullback / pushup into middle EMA calcs
var string pullBackGroupName = 'EMA Pullback Settings'
PBperc = input.float(0.5, title = "% Diff for EMA Pullback", step = 0.1, group=pullBackGroupName)
PBlength = input.int(8, title = "Lookback for EMA Pullback", group=pullBackGroupName)

// Look for a pullback to the middle EMA (LONGS)
longPercentDiff = ((low - mEMA) / low) * 100
longPBcheck = longPercentDiff <= PBperc
longPB = ta.barssince(longPBcheck) <= PBlength

// Look for a pushup to the middle EMA (SHORTS)
shortPercentDiff = ((mEMA - high) / mEMA) * 100
shortPBcheck = shortPercentDiff <= PBperc
shortPB = ta.barssince(shortPBcheck) <= PBlength

plotshape(longPB and not longPB[1], "", shape.labelup,   location.belowbar, color= color.green, textcolor = color.white, text = "(2) Bull Pullback")
plotshape(shortPB and not shortPB[1], "", shape.labeldown,   location.abovebar, color= color.red, textcolor = color.white, text = "(2) Bear Pullback")


longCondition = uptrend  and EMAUptrendWithDistance and longPB and BXTenderLongEntryCondition and longTermXtrender > 0 and ta.rising(longTermXtrender, 1) and close > fEMA
shortCondition = dntrend and EMADowntrendWithDistance and shortPB and BXTenderShortEntryCondition and longTermXtrender < 0 and ta.falling(longTermXtrender, 1) and close < fEMA

closeLong = BXTenderShortEntryCondition
closeShort = BXTenderLongEntryCondition


useClose = input.bool(true, title = "Use Close Signal", group='Trade Direction')

//define as 0 if do not want to use
closeLongCondition = useClose ? closeLong : 0
closeShortCondition = useClose ? closeShort :  0


// ADX
//░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

adxEnabled = input.bool(defval = false , title = "Average Directional Index (ADX)", tooltip = "", group ="ADX" ) 
adxlen = input(14, title = "ADX Smoothing", group="ADX")
adxdilen = input(14, title = "DI Length", group="ADX")
adxabove = input(26, title = "ADX Threshold", group="ADX")

adxdirmov(len) =>
	adxup = ta.change(high)
	adxdown = -ta.change(low)
	adxplusDM = na(adxup) ? na : (adxup > adxdown and adxup > 0 ? adxup : 0)
	adxminusDM = na(adxdown) ? na : (adxdown > adxup and adxdown > 0 ? adxdown : 0)
	adxtruerange = ta.rma(ta.tr, len)
	adxplus = fixnan(100 * ta.rma(adxplusDM, len) / adxtruerange)
	adxminus = fixnan(100 * ta.rma(adxminusDM, len) / adxtruerange)
	[adxplus, adxminus]
adx(adxdilen, adxlen) =>
	[adxplus, adxminus] = adxdirmov(adxdilen)
	adxsum = adxplus + adxminus
	adx = 100 * ta.rma(math.abs(adxplus - adxminus) / (adxsum == 0 ? 1 : adxsum), adxlen)

adxsig = adxEnabled ? adx(adxdilen, adxlen) : na
isADX = adxEnabled ? (adxsig > adxabove) : true



//Backtesting Time Period (Input.time not working as expected as of 03/30/2021.  Giving odd start/end dates
//░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
useStartPeriodTime = input.bool(true, 'Start', group='Date Range', inline='Start Period')
startPeriodTime = input.time(timestamp('1 Jan 2019'), '', group='Date Range', inline='Start Period')
useEndPeriodTime = input.bool(true, 'End', group='Date Range', inline='End Period')
endPeriodTime = input.time(timestamp('31 Dec 2030'), '', group='Date Range', inline='End Period')

start = useStartPeriodTime ? startPeriodTime >= time : false
end = useEndPeriodTime ? endPeriodTime <= time : false
calcPeriod = not start and not end

// Trade Direction 
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tradeDirection = input.string('Long and Short', title = 'Trade Direction', options=['Long and Short', 'Long Only', 'Short Only'], group='Trade Direction')

// Percent as Points
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
per(pcnt) =>
    strategy.position_size != 0 ? math.round(pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na)

// Take profit 1
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp1 = input.float(title = 'Take Profit 1 - Target %', defval=0.5, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 1')
q1 = input.int(title = '% Of Position', defval=25, minval=0, group='Take Profit', inline='Take Profit 1')

// Take profit 2
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp2 = input.float(title = 'Take Profit 2 - Target %', defval=1.5, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 2')
q2 = input.int(title = '% Of Position', defval=50, minval=0, group='Take Profit', inline='Take Profit 2')

// Take profit 3
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp3 = input.float(title = 'Take Profit 3 - Target %', defval=2.5, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 3')
q3 = input.int(title = '% Of Position', defval=25, minval=0, group='Take Profit', inline='Take Profit 3')

// Take profit 4
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp4 = input.float(title = 'Take Profit 4 - Target %', defval=7.5, minval=0.0, step=0.5, group='Take Profit')

/// Stop Loss
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
stoplossPercent = input.float(title = 'Stop Loss (%)', defval=3.0, minval=0.01, step = 0.5, group='Stop Loss') * 0.01
slLongClose = close < strategy.position_avg_price * (1 - stoplossPercent)
slShortClose = close > strategy.position_avg_price * (1 + stoplossPercent)

/// Leverage
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
leverage = input.float(1, 'Leverage', step=.5, group='Leverage')
contracts = math.min(math.max(.000001, strategy.equity / close * leverage), 1000000000)


/// Trade State Management
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

isInLongPosition = strategy.position_size > 0
isInShortPosition = strategy.position_size < 0

/// ProfitView Alert Syntax String Generation
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

alertSyntaxPrefix = input.string(defval='CRYPTANEX_99FTX_Strategy-Name-Here', title = 'Alert Syntax Prefix', group='ProfitView Alert Syntax')
alertSyntaxBase = alertSyntaxPrefix + '\n#' + str.tostring(open) + ',' + str.tostring(high) + ',' + str.tostring(low) + ',' + str.tostring(close) + ',' + str.tostring(volume) + ','


/// Trade Execution
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

longConditionCalc = (longCondition and isADX)
shortConditionCalc = (shortCondition and isADX)

// plotshape(shortConditionCalc, title='Short', style=shape.labeldown, location=location.abovebar, size=size.tiny, text='Short', textcolor=color.new(color.white, 0), color=color.new(color.red, 0))
// plotshape(longConditionCalc, title='Long', style=shape.labelup, location=location.belowbar, size=size.tiny, text='Long', textcolor=color.new(color.white, 0), color=color.new(color.green, 0))

if calcPeriod
    if longConditionCalc and tradeDirection != 'Short Only' and isInLongPosition == false
        strategy.entry('Long', strategy.long, qty=contracts)

        alert(message=alertSyntaxBase + 'side:long', freq=alert.freq_once_per_bar_close)

    if shortConditionCalc and tradeDirection != 'Long Only' and isInShortPosition == false
        strategy.entry('Short', strategy.short, qty=contracts)

        alert(message=alertSyntaxBase + 'side:short', freq=alert.freq_once_per_bar_close)
    
    //Inspired from Multiple %% profit exits example by adolgo https://www.tradingview.com/script/kHhCik9f-Multiple-profit-exits-example/
    strategy.exit('TP1', qty_percent=q1, profit=per(tp1))
    strategy.exit('TP2', qty_percent=q2, profit=per(tp2))
    strategy.exit('TP3', qty_percent=q3, profit=per(tp3))
    strategy.exit('TP4', profit=per(tp4))

    strategy.close('Long', qty_percent=100, comment='SL Long', when=slLongClose)
    strategy.close('Short', qty_percent=100, comment='SL Short', when=slShortClose)

    strategy.close_all(when=closeLongCondition or closeShortCondition, comment='Close Postion')

/// Dashboard
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
// Inspired by https://www.tradingview.com/script/uWqKX6A2/ - Thanks VertMT

showDashboard = input.bool(group="Dashboard", title = "Show Dashboard", defval=true)

f_fillCell(_table, _column, _row, _title, _value, _bgcolor, _txtcolor) =>
    _cellText = _title + "\n" + _value
    table.cell(_table, _column, _row, _cellText, bgcolor=_bgcolor, text_color=_txtcolor, text_size=size.auto)

// Draw dashboard table
if showDashboard
    var bgcolor = color.new(color.black,0)
    
    // Keep track of Wins/Losses streaks
    newWin  = (strategy.wintrades  > strategy.wintrades[1]) and (strategy.losstrades == strategy.losstrades[1]) and (strategy.eventrades == strategy.eventrades[1])
    newLoss = (strategy.wintrades == strategy.wintrades[1]) and (strategy.losstrades  > strategy.losstrades[1]) and (strategy.eventrades == strategy.eventrades[1])

    varip int winRow     = 0
    varip int lossRow    = 0
    varip int maxWinRow  = 0
    varip int maxLossRow = 0

    if newWin
        lossRow := 0
        winRow := winRow + 1
    if winRow > maxWinRow
        maxWinRow := winRow
        
    if newLoss
        winRow := 0
        lossRow := lossRow + 1
    if lossRow > maxLossRow
        maxLossRow := lossRow


    // Prepare stats table
    var table dashTable = table.new(position.bottom_right, 1, 15, border_width=1)
    
   
    if barstate.islastconfirmedhistory
        // Update table
        dollarReturn = strategy.netprofit
        f_fillCell(dashTable, 0, 0, "Start:", str.format("{0,date,long}", strategy.closedtrades.entry_time(0)) , bgcolor, color.white) // + str.format(" {0,time,HH:mm}", strategy.closedtrades.entry_time(0)) 
        f_fillCell(dashTable, 0, 1, "End:", str.format("{0,date,long}", strategy.opentrades.entry_time(0)) , bgcolor, color.white) // + str.format(" {0,time,HH:mm}", strategy.opentrades.entry_time(0))
        _profit = (strategy.netprofit / strategy.initial_capital) * 100
        f_fillCell(dashTable, 0, 2, "Net Profit:", str.tostring(_profit, '##.##') + "%", _profit > 0 ? color.green : color.red, color.white)
        _numOfDaysInStrategy = (strategy.opentrades.entry_time(0) - strategy.closedtrades.entry_time(0)) / (1000 * 3600 * 24)
        f_fillCell(dashTable, 0, 3, "Percent Per Day", str.tostring(_profit / _numOfDaysInStrategy, '#########################.#####')+"%", _profit > 0 ? color.green : color.red, color.white)
        _winRate = ( strategy.wintrades / strategy.closedtrades ) * 100
        f_fillCell(dashTable, 0, 4, "Percent Profitable:", str.tostring(_winRate, '##.##') + "%", _winRate < 50 ? color.red : _winRate < 75 ? #999900 : color.green, color.white)
        f_fillCell(dashTable, 0, 5, "Profit Factor:", str.tostring(strategy.grossprofit / strategy.grossloss,  '##.###'), strategy.grossprofit > strategy.grossloss ? color.green : color.red, color.white)
        f_fillCell(dashTable, 0, 6, "Total Trades:", str.tostring(strategy.closedtrades), bgcolor, color.white)
        f_fillCell(dashTable, 0, 8, "Max Wins In A Row:", str.tostring(maxWinRow, '######') , bgcolor, color.white)
        f_fillCell(dashTable, 0, 9, "Max Losses In A Row:", str.tostring(maxLossRow, '######') , bgcolor, color.white)

