EPS & Sales
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Fred6724

//@version=5
indicator("EPS & Sales", overlay=true, max_labels_count = 500)

// === USER INPUTS ====
i_ArrowOnGraph = input(true,  title='Displays Arrows', inline="1", group="Arrows")
i_salesOnGraph = input(false, title='Sales', inline="1", group="Arrows")
i_arrowSize    = input.string(size.small, title='Arrow Size', options=[size.tiny,size.small,size.normal, size.large], inline="2", group="Arrows")
i_arrowColor   = input(color.rgb(0,0,0,0), title='Arrow Colors', inline="3", group="Arrows")
i_posArrowColor= input(color.rgb(13,7,201,0), title='%Pos' ,group="Arrows", inline="3")
i_negArrowColor= input(color.red, title='%Neg' ,group="Arrows", inline="3")
i_tableSize    = input.string(size.normal, title='Table Size', options=[size.tiny,size.small,size.normal, size.large] ,group="Table" ,inline="5")
i_posTable     = input.string(defval=position.bottom_left, title='Table Position', options=[position.top_left,position.top_center,position.top_right, position.middle_left, position.middle_center, position.middle_right, position.bottom_left, position.bottom_center, position.bottom_right] ,group="Table" ,inline="6", tooltip = "Available in Weekly Table Only.")
i_tableStyle   = input.string("Weekly", title = "Type of Table", options = ["Weekly", "Daily"], group="Table", inline="0")
i_frameWidth   = input.int(1, title='Frame Width', group="Table", options= [0,1,2,3,4,5], inline="0.25")
i_frameColor   = input(color.rgb(0, 0, 0), title='| Color' , group="Table", inline="0.25")
i_tableBorder  = input(false, title='Table Border', group="Table", inline="0.5")
i_borderColor  = input(color.rgb(0, 0, 0), title='| Color' ,group="Table", inline="0.5")
i_moreData     = input(false, title='Less Quarters' ,group="Table", inline="1", tooltip = "Available in Weekly Table Only.")
i_alwaysDispP  = input(false, title='Always display %Var', group="Table", inline="1", tooltip = "Available in Weekly Table Only.")
i_QoQ          = input(false, title='QoQ Datas' ,group="Table" ,inline="2", tooltip = "Available in Weekly Table Only.")
i_compare      = input(false, title='Show VS' ,group="Table" ,inline="2", tooltip = "Available in Weekly Table Only.")
i_surprises    = input(false, title='% Surprise' ,group="Table", inline="3", tooltip = "Available in Weekly Table Only.")
i_posSurp      = input(color.rgb(56,142,60,0), title='%Pos' ,group="Table", inline="3")
i_negSurp      = input(color.red, title='%Neg' ,group="Table", inline="3")
i_grossMargin  = input(false, title='Gross Margin' ,group="Table" ,inline="4")
i_ROE          = input(false, title='Return On Equity' ,group="Table" ,inline="4")
i_resultBackgroundColorOdd  = input(color.white, title='Odd Rows' ,group="Table", inline="7")
i_resultBackgroundColorEven = input(color.rgb(192,192,192,0), title='Even Rows' ,group="Table", inline="7")
i_RowAndColumnTextColor  = input(color.black, title='Sideways Row & Column Text ' ,group="Table")
i_posColor = input(color.rgb(13,7,201,0), title='% Positive' ,group="Table", inline="8")
i_negColor = input(color.red, title='% Negative' ,group="Table", inline="8")
// Not input
datasize = 10
blankUnderUp = i_moreData == false ? 3 : 6 // Because there is a blank between the top of the table and the second line but Tradingview doesn't display it.


// Declare tables
// Weekly Table
var table epsTable   = table.new(i_posTable, 15, 15, frame_color = i_frameColor, frame_width = i_frameWidth, border_width=i_tableBorder ? 1:0, border_color=i_borderColor)
// Daily Table
var table epsTableDa = table.new(position.bottom_center,17, 4, frame_color = i_frameColor, frame_width = i_frameWidth, border_width=i_tableBorder ? 1:0, border_color=i_borderColor)

// === FUNCTIONS AND CALCULATIONS ===.
// Current earnings per share
// Modified line to get (actual) and (standard) earnings with 'request.earnings'. HUGE key point here to have closer results to IBD - MarketSmith
EPS            = request.earnings(syminfo.tickerid, earnings.actual, ignore_invalid_symbol=true, lookahead = barmerge.lookahead_on)
EPS_Standard   = request.earnings(syminfo.tickerid, earnings.standardized, ignore_invalid_symbol=true, lookahead = barmerge.lookahead_on)
EPS_Estimate   = request.earnings(syminfo.tickerid, earnings.estimate, ignore_invalid_symbol=true, lookahead = barmerge.lookahead_on) // To reduce the probability of not detecting a change if EPS are the same quarters over quarters
SALES          = request.financial(syminfo.tickerid, "TOTAL_REVENUE", "FQ")
SALES_Estimate = request.financial(syminfo.tickerid, "SALES_ESTIMATES", "FQ")
SALES_GROWTH   = request.financial(syminfo.tickerid, "REVENUE_ONE_YEAR_GROWTH", "FQ")
grossMargin = i_grossMargin ? request.financial(syminfo.tickerid, "GROSS_MARGIN", "FQ"):na
ROE = request.financial(syminfo.tickerid, "RETURN_ON_EQUITY", "FQ")
//Date
rev = request.financial(syminfo.tickerid,'TOTAL_REVENUE','FQ',barmerge.gaps_on, ignore_invalid_symbol=true)


// GET EPS NUMBERS FROM TRADINGVIEW
barSince = ta.barssince(EPS != EPS[1] or EPS_Standard != EPS_Standard[1] or EPS_Estimate != EPS_Estimate[1]) // To reduce the probability of not detecting a change if EPS are the same quarters over quarters
EPSTime  = barSince == 0 
// If the number of (bars since the value of EPS, is different, from previous EPS) equals 0, we are in an EPS event. (You can do it)
// (Better method, using the time since the last public EPS/Sales (Before we were using default 3M that was causing errors in case of non-regular period publishing))
// Now we are using sometimes Actual EPS, somtimes Standard EPS, based on my observations with MarketSmith numbers.
// Actual EPS
// Use if() function to get number before the first earning event - If return na we get the first EPS value except if the line before us already done it
firstEPS = ta.valuewhen(bar_index==0, EPS, 0)
actualEPS   = ta.valuewhen(EPSTime, EPS, 0)
if(na(actualEPS))
    actualEPS  := firstEPS
actualEPS1  = ta.valuewhen(EPSTime, EPS, 1) // With "1" to search the previous EPS value, etc
if(na(actualEPS1) and actualEPS  != firstEPS)
    actualEPS1 := firstEPS
actualEPS2  = ta.valuewhen(EPSTime, EPS, 2)
if(na(actualEPS2) and actualEPS1 != firstEPS)
    actualEPS2 := firstEPS
actualEPS3  = ta.valuewhen(EPSTime, EPS, 3)
if(na(actualEPS3) and actualEPS2 != firstEPS)
    actualEPS3 := firstEPS
actualEPS4  = ta.valuewhen(EPSTime, EPS, 4)
if(na(actualEPS4) and actualEPS3 != firstEPS)
    actualEPS4 := firstEPS
actualEPS5  = ta.valuewhen(EPSTime, EPS, 5)
if(na(actualEPS5) and actualEPS4 != firstEPS)
    actualEPS5 := firstEPS
actualEPS6  = ta.valuewhen(EPSTime, EPS, 6)
if(na(actualEPS6) and actualEPS5 != firstEPS)
    actualEPS6 := firstEPS
actualEPS7  = ta.valuewhen(EPSTime, EPS, 7)
if(na(actualEPS7) and actualEPS6 != firstEPS)
    actualEPS7 := firstEPS
actualEPS8  = ta.valuewhen(EPSTime, EPS, 8)
if(na(actualEPS8) and actualEPS7 != firstEPS)
    actualEPS8 := firstEPS
actualEPS9  = ta.valuewhen(EPSTime, EPS, 9)
if(na(actualEPS9) and actualEPS8 != firstEPS)
    actualEPS9 := firstEPS
actualEPS10 = ta.valuewhen(EPSTime, EPS, 10)
if(na(actualEPS10) and actualEPS9 != firstEPS)
    actualEPS10 := firstEPS
actualEPS11 = ta.valuewhen(EPSTime, EPS, 11)
if(na(actualEPS11) and actualEPS10 != firstEPS)
    actualEPS11 := firstEPS
// Standard EPS
standardEPS   = ta.valuewhen(EPSTime, EPS_Standard, 0) 
standardEPS1  = ta.valuewhen(EPSTime, EPS_Standard, 1) 
standardEPS2  = ta.valuewhen(EPSTime, EPS_Standard, 2)
standardEPS3  = ta.valuewhen(EPSTime, EPS_Standard, 3)
standardEPS4  = ta.valuewhen(EPSTime, EPS_Standard, 4)
standardEPS5  = ta.valuewhen(EPSTime, EPS_Standard, 5)
standardEPS6  = ta.valuewhen(EPSTime, EPS_Standard, 6)
standardEPS7  = ta.valuewhen(EPSTime, EPS_Standard, 7)
standardEPS8  = ta.valuewhen(EPSTime, EPS_Standard, 8)
standardEPS9  = ta.valuewhen(EPSTime, EPS_Standard, 9)
standardEPS10 = ta.valuewhen(EPSTime, EPS_Standard, 10)
standardEPS11 = ta.valuewhen(EPSTime, EPS_Standard, 11)
// Estimate EPS
estimateEPS   = ta.valuewhen(EPSTime, EPS_Estimate, 0) 
estimateEPS1  = ta.valuewhen(EPSTime, EPS_Estimate, 1) 
estimateEPS2  = ta.valuewhen(EPSTime, EPS_Estimate, 2)
estimateEPS3  = ta.valuewhen(EPSTime, EPS_Estimate, 3)
estimateEPS4  = ta.valuewhen(EPSTime, EPS_Estimate, 4)
estimateEPS5  = ta.valuewhen(EPSTime, EPS_Estimate, 5)
estimateEPS6  = ta.valuewhen(EPSTime, EPS_Estimate, 6)
estimateEPS7  = ta.valuewhen(EPSTime, EPS_Estimate, 7)
// EPS Surprise
EpsSurprise0 = (actualEPS -estimateEPS )/math.abs(estimateEPS )*100
EpsSurprise1 = (actualEPS1-estimateEPS1)/math.abs(estimateEPS1)*100
EpsSurprise2 = (actualEPS2-estimateEPS2)/math.abs(estimateEPS2)*100
EpsSurprise3 = (actualEPS3-estimateEPS3)/math.abs(estimateEPS3)*100
EpsSurprise4 = (actualEPS4-estimateEPS4)/math.abs(estimateEPS4)*100
EpsSurprise5 = (actualEPS5-estimateEPS5)/math.abs(estimateEPS5)*100
EpsSurprise6 = (actualEPS6-estimateEPS6)/math.abs(estimateEPS6)*100
EpsSurprise7 = (actualEPS7-estimateEPS7)/math.abs(estimateEPS7)*100

// Same with Sales 
// Use if() function to get number before the first earning event - If return na we get the first sales value except if the line before us already done it
firstSale = ta.valuewhen(bar_index==0, SALES, 0)
sales   = ta.valuewhen(EPSTime, SALES, 0)
if(na(sales))
    sales  := firstSale
sales1  = ta.valuewhen(EPSTime, SALES, 1)
if(na(sales1) and sales  != firstSale)
    sales1 := firstSale
sales2  = ta.valuewhen(EPSTime, SALES, 2)
if(na(sales2) and sales1 != firstSale)
    sales2 := firstSale
sales3  = ta.valuewhen(EPSTime, SALES, 3)
if(na(sales3) and sales2 != firstSale)
    sales3 := firstSale
sales4  = ta.valuewhen(EPSTime, SALES, 4)
if(na(sales4) and sales3 != firstSale)
    sales4 := firstSale
sales5  = ta.valuewhen(EPSTime, SALES, 5)
if(na(sales5) and sales4 != firstSale)
    sales5 := firstSale
sales6  = ta.valuewhen(EPSTime, SALES, 6)
if(na(sales6) and sales5 != firstSale)
    sales6 := firstSale
sales7  = ta.valuewhen(EPSTime, SALES, 7)
if(na(sales7) and sales6 != firstSale)
    sales7 := firstSale
sales8  = ta.valuewhen(EPSTime, SALES, 8)
if(na(sales8) and sales7 != firstSale)
    sales8 := firstSale
sales9  = ta.valuewhen(EPSTime, SALES, 9)
if(na(sales9) and sales8 != firstSale)
    sales9 := firstSale
sales10 = ta.valuewhen(EPSTime, SALES, 10)
if(na(sales10) and sales9 != firstSale)
    sales10 := firstSale
sales11 = ta.valuewhen(EPSTime, SALES, 11)
if(na(sales11) and sales10 != firstSale)
    sales11 := firstSale

// Sales One Year Growth to get more Historical Data
// We use if() condition to get one more line
firstSaleGrowth = ta.valuewhen(bar_index==0, SALES_GROWTH, 0)
salesChange0   = ta.valuewhen(EPSTime, SALES_GROWTH, 0)
if(na(salesChange0))
    salesChange0  := firstSaleGrowth
salesChange1  = ta.valuewhen(EPSTime, SALES_GROWTH, 1)
if(na(salesChange1) and salesChange0  != firstSaleGrowth)
    salesChange1 := firstSaleGrowth
salesChange2  = ta.valuewhen(EPSTime, SALES_GROWTH, 2)
if(na(salesChange2) and salesChange1 != firstSaleGrowth)
    salesChange2 := firstSaleGrowth
salesChange3  = ta.valuewhen(EPSTime, SALES_GROWTH, 3)
if(na(salesChange3) and salesChange2 != firstSaleGrowth)
    salesChange3 := firstSaleGrowth
salesChange4  = ta.valuewhen(EPSTime, SALES_GROWTH, 4)
if(na(salesChange4) and salesChange3 != firstSaleGrowth)
    salesChange4 := firstSaleGrowth
salesChange5  = ta.valuewhen(EPSTime, SALES_GROWTH, 5)
if(na(salesChange5) and salesChange4 != firstSaleGrowth)
    salesChange5 := firstSaleGrowth
salesChange6  = ta.valuewhen(EPSTime, SALES_GROWTH, 6)
if(na(salesChange6) and salesChange5 != firstSaleGrowth)
    salesChange6 := firstSaleGrowth
salesChange7  = ta.valuewhen(EPSTime, SALES_GROWTH, 7)
if(na(salesChange7) and salesChange6 != firstSaleGrowth)
    salesChange7 := firstSaleGrowth

// Sometimes the sales number is actualised but not the sales variation..
if(salesChange0 == salesChange1 and not (na(sales4) or sales4 == 0))
    salesChange0 := (sales - sales4)/math.abs(sales4)*100

// Case where earning are very close, should check if the % variation is good (VRRM Mar-22 - Dec-21) -> 70 90 and not 90 90
if(salesChange1 == salesChange0 and sales1 == sales)
    salesChange1 := (sales1 - sales5)/math.abs(sales5)*100
if(salesChange2 == salesChange1 and sales2 == sales1)
    salesChange2 := (sales2 - sales6)/math.abs(sales6)*100
if(salesChange3 == salesChange2 and sales3 == sales2)
    salesChange3 := (sales3 - sales7)/math.abs(sales7)*100
if(salesChange4 == salesChange3 and sales4 == sales3)
    salesChange4 := (sales4 - sales8)/math.abs(sales8)*100
if(salesChange5 == salesChange4 and sales5 == sales4)
    salesChange5 := (sales5 - sales9)/math.abs(sales9)*100
if(salesChange6 == salesChange5 and sales6 == sales5)
    salesChange6 := (sales6 - sales10)/math.abs(sales10)*100
if(salesChange7 == salesChange6 and sales7 == sales6)
    salesChange7 := (sales7 - sales11)/math.abs(sales11)*100

// Sales Estimaate
salesEstimate   = ta.valuewhen(EPSTime, SALES_Estimate, 0)
salesEstimate1  = ta.valuewhen(EPSTime, SALES_Estimate, 1)
salesEstimate2  = ta.valuewhen(EPSTime, SALES_Estimate, 2)
salesEstimate3  = ta.valuewhen(EPSTime, SALES_Estimate, 3)
salesEstimate4  = ta.valuewhen(EPSTime, SALES_Estimate, 4)
salesEstimate5  = ta.valuewhen(EPSTime, SALES_Estimate, 5)
salesEstimate6  = ta.valuewhen(EPSTime, SALES_Estimate, 6)
salesEstimate7  = ta.valuewhen(EPSTime, SALES_Estimate, 7)

// Detect same sales for TradingView bug correction (Same sales than previous display)
bool sameSales  = SALES==sales1 and SALES_GROWTH==salesChange1
bool recentEarn = ta.barssince(EPSTime)<=6

// Function to define previous quarters gross margin & roe (Less precise than EPS and Sales Data)
f_grossMargin(i) =>
    request.security(syminfo.tickerid, '3M', grossMargin[i])
f_roe(i) =>
    request.security(syminfo.tickerid, '3M', ROE[i])

// Same with Gross Margin
// Use if() function to get number before the first earning event - If return na we get the first sales value except if the line before us already done it
firstGrossMargin = ta.valuewhen(bar_index==0, grossMargin, 0)
GM0   = ta.valuewhen(EPSTime, grossMargin, 0)
if(na(GM0))
    GM0  := firstGrossMargin
GM1  = ta.valuewhen(EPSTime, grossMargin, 1)
if(na(GM1) and GM0  != firstGrossMargin)
    GM1 := firstGrossMargin
GM2  = ta.valuewhen(EPSTime, grossMargin, 2)
if(na(GM2) and GM1 != firstGrossMargin)
    GM2 := firstGrossMargin
GM3  = ta.valuewhen(EPSTime, grossMargin, 3)
if(na(GM3) and GM2 != firstGrossMargin)
    GM3 := firstGrossMargin
GM4  = ta.valuewhen(EPSTime, grossMargin, 4)
if(na(GM4) and GM3 != firstGrossMargin)
    GM4 := firstGrossMargin
GM5  = ta.valuewhen(EPSTime, grossMargin, 5)
if(na(GM5) and GM4 != firstGrossMargin)
    GM5 := firstGrossMargin
GM6  = ta.valuewhen(EPSTime, grossMargin, 6)
if(na(GM6) and GM5 != firstGrossMargin)
    GM6 := firstGrossMargin
GM7  = ta.valuewhen(EPSTime, grossMargin, 7)
if(na(GM7) and GM6 != firstGrossMargin)
    GM7 := firstGrossMargin

// Same with Return On Equity
// Use if() function to get number before the first earning event - If return na we get the first sales value except if the line before us already done it
firstReturnOnEquity = ta.valuewhen(bar_index==0, ROE, 0)
ROE0   = ta.valuewhen(EPSTime, ROE, 0)
if(na(ROE0))
    ROE0  := firstReturnOnEquity
ROE1  = ta.valuewhen(EPSTime, ROE, 1)
if(na(ROE1) and ROE0  != firstReturnOnEquity)
    ROE1 := firstReturnOnEquity
ROE2  = ta.valuewhen(EPSTime, ROE, 2)
if(na(ROE2) and ROE1 != firstReturnOnEquity)
    ROE2 := firstReturnOnEquity
ROE3  = ta.valuewhen(EPSTime, ROE, 3)
if(na(ROE3) and ROE2 != firstReturnOnEquity)
    ROE3 := firstReturnOnEquity
ROE4  = ta.valuewhen(EPSTime, ROE, 4)
if(na(ROE4) and ROE3 != firstReturnOnEquity)
    ROE4 := firstReturnOnEquity
ROE5  = ta.valuewhen(EPSTime, ROE, 5)
if(na(ROE5) and ROE4 != firstReturnOnEquity)
    ROE5 := firstReturnOnEquity
ROE6  = ta.valuewhen(EPSTime, ROE, 6)
if(na(ROE6) and ROE5 != firstReturnOnEquity)
    ROE6 := firstReturnOnEquity
ROE7  = ta.valuewhen(EPSTime, ROE, 7)
if(na(ROE7) and ROE6 != firstReturnOnEquity)
    ROE7 := firstReturnOnEquity


// Calculation using IBD/Marketsmith principle : current quarter EPS vs the same quartar's EPS of previous year. (YoY) 
EpsChange0  = actualEPS  < 0 and actualEPS4  <= 0 ? na: actualEPS4  < 0 and standardEPS4  > 0 ? (EPS-actualEPS4)        /math.abs(actualEPS4) *100:EPS          < 0 and actualEPS4  > 0 ? na:(EPS-actualEPS4)        /math.abs(actualEPS4) *100
EpsChange1  = actualEPS1 < 0 and actualEPS5  <= 0 ? na: actualEPS5  < 0 and standardEPS5  > 0 ? (actualEPS1-actualEPS5) /math.abs(actualEPS5) *100:actualEPS1   < 0 and actualEPS5  > 0 ? na:(actualEPS1-actualEPS5) /math.abs(actualEPS5) *100
EpsChange2  = actualEPS2 < 0 and actualEPS6  <= 0 ? na: actualEPS6  < 0 and standardEPS6  > 0 ? (actualEPS2-actualEPS6) /math.abs(actualEPS6) *100:actualEPS2   < 0 and actualEPS6  > 0 ? na:(actualEPS2-actualEPS6) /math.abs(actualEPS6) *100
EpsChange3  = actualEPS3 < 0 and actualEPS7  <= 0 ? na: actualEPS7  < 0 and standardEPS7  > 0 ? (actualEPS3-actualEPS7) /math.abs(actualEPS7) *100:actualEPS3   < 0 and actualEPS7  > 0 ? na:(actualEPS3-actualEPS7) /math.abs(actualEPS7) *100
EpsChange4  = actualEPS4 < 0 and actualEPS8  <= 0 ? na: actualEPS8  < 0 and standardEPS8  > 0 ? (actualEPS4-actualEPS8) /math.abs(actualEPS8) *100:actualEPS4   < 0 and actualEPS8  > 0 ? na:(actualEPS4-actualEPS8) /math.abs(actualEPS8) *100
EpsChange5  = actualEPS5 < 0 and actualEPS9  <= 0 ? na: actualEPS9  < 0 and standardEPS9  > 0 ? (actualEPS5-actualEPS9) /math.abs(actualEPS9) *100:actualEPS5   < 0 and actualEPS9  > 0 ? na:(actualEPS5-actualEPS9) /math.abs(actualEPS9) *100
EpsChange6  = actualEPS6 < 0 and actualEPS10 <= 0 ? na: actualEPS10 < 0 and standardEPS10 > 0 ? (actualEPS6-actualEPS10)/math.abs(actualEPS10)*100:actualEPS6 < 0 and actualEPS10 > 0 ? na:(actualEPS6-actualEPS10)/math.abs(actualEPS10)*100
EpsChange7  = actualEPS7 < 0 and actualEPS11 <= 0 ? na: actualEPS11 < 0 and standardEPS11 > 0 ? (actualEPS7-actualEPS11)/math.abs(actualEPS11)*100:actualEPS7 < 0 and actualEPS11 > 0 ? na:(actualEPS7-actualEPS11)/math.abs(actualEPS11)*100
// The case in which atual was - and standard was + was not taken into account, I added a condition to fix a ver low value in this case and have the '#' succesfully display
// because of the choice when fillCell.

// When EPS is negative we take the closer from 0 between standardized and reported
// We also use another variable to recognize when the calculation has been done with negative EPS (To display '#')                                                                                  // added this condition because 0.98 vs -0.16 = #712/713% not 999% APA
EpsChangeHash0 = actualEPS4  >= 0 ? na: actualEPS < 0 and standardEPS4  < 0 ? na:actualEPS4  < 0 and standardEPS4  > 0 ? (EPS-actualEPS4)        /math.abs(actualEPS4) *100:actualEPS4  <= standardEPS4  and standardEPS4 >-0.01 ? (EPS-standardEPS4)        /math.abs(standardEPS4) *100:(EPS-actualEPS4)/math.abs(actualEPS4)*100
EpsChangeHash1 = actualEPS5  >= 0 ? na:actualEPS1 < 0 and standardEPS5  < 0 ? na:actualEPS5  < 0 and standardEPS5  > 0 ? (actualEPS1-actualEPS5) /math.abs(actualEPS5) *100:actualEPS5  <= standardEPS5  and standardEPS5 >-0.01 ? (actualEPS1-standardEPS5) /math.abs(standardEPS5) *100:(actualEPS1-actualEPS5) /math.abs(actualEPS5) *100
EpsChangeHash2 = actualEPS6  >= 0 ? na:actualEPS2 < 0 and standardEPS6  < 0 ? na:actualEPS6  < 0 and standardEPS6  > 0 ? (actualEPS2-actualEPS6) /math.abs(actualEPS6) *100:actualEPS6  <= standardEPS6  and standardEPS6 >-0.01 ? (actualEPS2-standardEPS6) /math.abs(standardEPS6) *100:(actualEPS2-actualEPS6) /math.abs(actualEPS6) *100
EpsChangeHash3 = actualEPS7  >= 0 ? na:actualEPS3 < 0 and standardEPS7  < 0 ? na:actualEPS7  < 0 and standardEPS7  > 0 ? (actualEPS3-actualEPS7) /math.abs(actualEPS7) *100:actualEPS7  <= standardEPS7  and standardEPS7 >-0.01 ? (actualEPS3-standardEPS7) /math.abs(standardEPS7) *100:(actualEPS3-actualEPS7) /math.abs(actualEPS7) *100
EpsChangeHash4 = actualEPS8  >= 0 ? na:actualEPS4 < 0 and standardEPS8  < 0 ? na:actualEPS8  < 0 and standardEPS8  > 0 ? (actualEPS4-actualEPS8) /math.abs(actualEPS8) *100:actualEPS8  <= standardEPS8  and standardEPS8 >-0.01 ? (actualEPS4-standardEPS8) /math.abs(standardEPS8) *100:(actualEPS4-actualEPS8) /math.abs(actualEPS8) *100
EpsChangeHash5 = actualEPS9  >= 0 ? na:actualEPS5 < 0 and standardEPS9  < 0 ? na:actualEPS9  < 0 and standardEPS9  > 0 ? (actualEPS5-actualEPS9) /math.abs(actualEPS9) *100:actualEPS9  <= standardEPS9  and standardEPS9 >-0.01 ? (actualEPS5-standardEPS9) /math.abs(standardEPS9) *100:(actualEPS5-actualEPS9) /math.abs(actualEPS9) *100
EpsChangeHash6 = actualEPS10 >= 0 ? na:actualEPS6 < 0 and standardEPS10 < 0 ? na:actualEPS10 < 0 and standardEPS10 > 0 ? (actualEPS6-actualEPS10)/math.abs(actualEPS10)*100:actualEPS10 <= standardEPS10 and standardEPS10>-0.01 ? (actualEPS6-standardEPS10)/math.abs(standardEPS10)*100:(actualEPS6-actualEPS10)/math.abs(actualEPS10)*100
EpsChangeHash7 = actualEPS11 >= 0 ? na:actualEPS7 < 0 and standardEPS11 < 0 ? na:actualEPS11 < 0 and standardEPS11 > 0 ? (actualEPS7-actualEPS11)/math.abs(actualEPS11)*100:actualEPS11 <= standardEPS11 and standardEPS11>-0.01 ? (actualEPS7-standardEPS11)/math.abs(standardEPS11)*100:(actualEPS7-actualEPS11)/math.abs(actualEPS11)*100


// Due to comments I add a possibility to display the % variation even if the company is not profitable
if(i_alwaysDispP)
    EpsChange0  := (actualEPS-actualEPS4  )/math.abs(actualEPS4) *100
    EpsChange1  := (actualEPS1-actualEPS5 )/math.abs(actualEPS5) *100
    EpsChange2  := (actualEPS2-actualEPS6 )/math.abs(actualEPS6) *100
    EpsChange3  := (actualEPS3-actualEPS7 )/math.abs(actualEPS7) *100
    EpsChange4  := (actualEPS4-actualEPS8 )/math.abs(actualEPS8) *100
    EpsChange5  := (actualEPS5-actualEPS9 )/math.abs(actualEPS9) *100
    EpsChange6  := (actualEPS6-actualEPS10)/math.abs(actualEPS10)*100
    EpsChange7  := (actualEPS7-actualEPS11)/math.abs(actualEPS11)*100
    
// EPS QoQ (To prevent me from harassment in the comments :-) ... )
EpsChangeQoQ0 = (actualEPS -actualEPS1)/math.abs(actualEPS1)*100
EpsChangeQoQ1 = (actualEPS1-actualEPS2)/math.abs(actualEPS2)*100
EpsChangeQoQ2 = (actualEPS2-actualEPS3)/math.abs(actualEPS3)*100
EpsChangeQoQ3 = (actualEPS3-actualEPS4)/math.abs(actualEPS4)*100
EpsChangeQoQ4 = (actualEPS4-actualEPS5)/math.abs(actualEPS5)*100
EpsChangeQoQ5 = (actualEPS5-actualEPS6)/math.abs(actualEPS6)*100
EpsChangeQoQ6 = (actualEPS6-actualEPS7)/math.abs(actualEPS7)*100
EpsChangeQoQ7 = (actualEPS7-actualEPS8)/math.abs(actualEPS8)*100

// Sales Surprise
SalesSurprise0 = (sales  - salesEstimate )/math.abs(salesEstimate )*100
SalesSurprise1 = (sales1 - salesEstimate1)/math.abs(salesEstimate1)*100
SalesSurprise2 = (sales2 - salesEstimate2)/math.abs(salesEstimate2)*100
SalesSurprise3 = (sales3 - salesEstimate3)/math.abs(salesEstimate3)*100
SalesSurprise4 = (sales4 - salesEstimate4)/math.abs(salesEstimate4)*100
SalesSurprise5 = (sales5 - salesEstimate5)/math.abs(salesEstimate5)*100
SalesSurprise6 = (sales6 - salesEstimate6)/math.abs(salesEstimate6)*100
SalesSurprise7 = (sales7 - salesEstimate7)/math.abs(salesEstimate7)*100

// Sales QoQ
salesChangeQoQ0 = (sales  -sales1) /math.abs(sales1) *100
salesChangeQoQ1 = (sales1 -sales2) /math.abs(sales2) *100
salesChangeQoQ2 = (sales2 -sales3) /math.abs(sales3) *100
salesChangeQoQ3 = (sales3 -sales4) /math.abs(sales4) *100
salesChangeQoQ4 = (sales4 -sales5) /math.abs(sales5) *100
salesChangeQoQ5 = (sales5 -sales6) /math.abs(sales6) *100
salesChangeQoQ6 = (sales6 -sales7) /math.abs(sales7) *100
salesChangeQoQ7 = (sales7 -sales8) /math.abs(sales8) *100


//Adapting Format of Sales 98 000 000 to 98,0 M 
Sales0M  = (sales /1000000)
Sales1M  = (sales1/1000000)
Sales2M  = (sales2/1000000)
Sales3M  = (sales3/1000000)
Sales4M  = (sales4/1000000)
Sales5M  = (sales5/1000000)
Sales6M  = (sales6/1000000)
Sales7M  = (sales7/1000000)
Sales8M  = (sales8/1000000)
Sales9M  = (sales9/1000000)
Sales10M = (sales10/1000000)
Sales11M = (sales11/1000000)

// If sales > 1000M we want it to be display in $Bil
if(sales >= 10000000000)
    Sales0M  := (sales /1000000000)
    Sales1M  := (sales1/1000000000)
    Sales2M  := (sales2/1000000000)
    Sales3M  := (sales3/1000000000)
    Sales4M  := (sales4/1000000000)
    Sales5M  := (sales5/1000000000)
    Sales6M  := (sales6/1000000000)
    Sales7M  := (sales7/1000000000)
    Sales8M  := (sales8/1000000000)
    Sales9M  := (sales9/1000000000)
    Sales10M := (sales10/1000000000)
    Sales11M := (sales11/1000000000)


// === TABLE FUNCTIONS === (Used for cells completion)
// Each function changes the display format in the cells
f_fillCell(_table, _column, _row, _value) =>
    _c_color = i_posColor
    _transp = 0
    _cellText = str.tostring(_value, '0.00')
    if(_cellText == 'NaN')
        _cellText := 'N/A'
    myColor = _row == 10 or _row == 8 or _row == 6 or _row == 4 ? i_resultBackgroundColorOdd:i_resultBackgroundColorEven
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(myColor, 0), text_color=i_RowAndColumnTextColor,text_size=i_tableSize)

// To have one digit after coma for sales    
f_fillCell2(_table, _column, _row, _value) =>
    _c_color = i_posColor
    _transp = 0
    _cellText = str.tostring(_value, '0.0')
    if(_cellText == 'NaN')
        _cellText := 'N/A'
    myColor = _row == 10 or _row == 8 or _row == 6 or _row == 4 ? i_resultBackgroundColorOdd:i_resultBackgroundColorEven
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(myColor, 0), text_color=i_RowAndColumnTextColor,text_size=i_tableSize)

// For Sales comparison    
f_fillCell2SALES(_table, _column, _row, _value, _value1) =>
    _c_color = i_posColor
    _transp = 0
    _cellText1 = str.tostring(_value, '0.0')
    _cellText2 = str.tostring(_value1,'0.0')
    if(_cellText1 == 'NaN')
        _cellText1 := 'N/A'
    if(_cellText2 == 'NaN')
        _cellText2 := 'N/A'
    _cellText  =  _cellText1 + ' vs ' + _cellText2
    myColor = _row == 10 or _row == 8 or _row == 6 or _row == 4 ? i_resultBackgroundColorOdd:i_resultBackgroundColorEven
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(myColor, 0), text_color=i_RowAndColumnTextColor,text_size=i_tableSize)

// EPS comparison (Only used to compare EPS for calculation with a 'if' further)
f_fillCellEPS(_table, _column, _row, _value, _value1) =>
    _c_color = i_posColor
    _transp = 0
    _cellText1 = str.tostring(_value, '0.00')
    _cellText2 = str.tostring(_value1,'0.00')
    if(_cellText1 == 'NaN')
        _cellText1 := 'N/A'
    if(_cellText2 == 'NaN')
        _cellText2 := 'N/A'
    _cellText  =  _cellText1 + ' vs ' + _cellText2
    myColor = _row == 10 or _row == 8 or _row == 6 or _row == 4 ? i_resultBackgroundColorOdd:i_resultBackgroundColorEven
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(myColor, 0), text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    
f_fillCellComp(_table, _column, _row, _value) =>
    _c_color = _value >= 0 ? i_posColor : i_negColor
    _transp = 0
    // Recent modification made that I need to put the IBD/MarketSmith limitaton of +999% here
    _cellText = _value > 999 ? '+999%': _value < -999 ? '-999%' :_value > 0 ? '+' + str.tostring(_value, '0') + '%':str.tostring(_value, '0') + '%'
    if(_cellText == 'NaN%')
        _cellText := 'N/A'
    if(_cellText == '+0%')
        _cellText := '0%'
    if(_value == EpsChangeHash0)
        _cellText := _value > 999 ? '#+999%': _value < -999 ? '#-999%' : _value > 0 ? '#' +  '+' + str.tostring(_value, '0') + '%':'#' + str.tostring(_value, '0') + '%'
    if(_value == EpsChangeHash1)
        _cellText := _value > 999 ? '#+999%': _value < -999 ? '#-999%' : _value > 0 ? '#' +  '+' + str.tostring(_value, '0') + '%':'#' + str.tostring(_value, '0') + '%'
    if(_value == EpsChangeHash2)
        _cellText := _value > 999 ? '#+999%': _value < -999 ? '#-999%' : _value > 0 ? '#' +  '+' + str.tostring(_value, '0') + '%':'#' + str.tostring(_value, '0') + '%'
    if(_value == EpsChangeHash3)
        _cellText := _value > 999 ? '#+999%': _value < -999 ? '#-999%' : _value > 0 ? '#' +  '+' + str.tostring(_value, '0') + '%':'#' + str.tostring(_value, '0') + '%'
    if(_value == EpsChangeHash4)
        _cellText := _value > 999 ? '#+999%': _value < -999 ? '#-999%' : _value > 0 ? '#' +  '+' + str.tostring(_value, '0') + '%':'#' + str.tostring(_value, '0') + '%'
    if(_value == EpsChangeHash5)
        _cellText := _value > 999 ? '#+999%': _value < -999 ? '#-999%' : _value > 0 ? '#' +  '+' + str.tostring(_value, '0') + '%':'#' + str.tostring(_value, '0') + '%'
    if(_value == EpsChangeHash6)
        _cellText := _value > 999 ? '#+999%': _value < -999 ? '#-999%' : _value > 0 ? '#' +  '+' + str.tostring(_value, '0') + '%':'#' + str.tostring(_value, '0') + '%'
    if(_value == EpsChangeHash7)
        _cellText := _value > 999 ? '#+999%': _value < -999 ? '#-999%' : _value > 0 ? '#' +  '+' + str.tostring(_value, '0') + '%':'#' + str.tostring(_value, '0') + '%'
    // Color for even or odd row
    myColor = _row == 10 or _row == 8 or _row == 6 or _row == 4 ? i_resultBackgroundColorOdd:i_resultBackgroundColorEven
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(myColor, 0), text_color=_cellText=='0%' or _cellText=='N/A'?i_RowAndColumnTextColor:_c_color,text_size=i_tableSize)

// FOR %SURPRISES
f_fillCellCompSurp(_table, _column, _row, _value) =>
    _c_color = _value >= 0 ? i_posSurp : i_negSurp
    _transp = 0
    // Recent modification made that I need to put the IBD/MarketSmith limitaton of +999% here
    _cellText = _value > 999 ? '+999%': _value < -999 ? '-999%' :_value > 0 ? '+' + str.tostring(_value, '0') + '%':str.tostring(_value, '0') + '%'
    if(_cellText == 'NaN%')
        _cellText := 'N/A'
    if(_cellText == '+0%')
        _cellText := '0%'
    // Color for even or odd row
    myColor = _row == 10 or _row == 8 or _row == 6 or _row == 4 ? i_resultBackgroundColorOdd:i_resultBackgroundColorEven
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(myColor, 0), text_color=_cellText=='0%' or _cellText=='N/A'?i_RowAndColumnTextColor:_c_color,text_size=i_tableSize)


//For QoQ EPS%
f_fillCellComp2(_table, _column, _row, _value) =>
    _c_color = _value >= 0 ? i_posColor : i_negColor
    _transp = 0
    // Recent modification made that I need to put the IBD/MarketSmith limitaton of +999% here
    _cellText = _value > 999 ? '+999%':_value < -999 ? '-999%':_value > 0 ? '+' + str.tostring(_value, '0') + '%':str.tostring(_value, '0') + '%'
    if(_cellText == 'NaN%')
        _cellText := 'N/A'
    // Color for even or odd row
    myColor = _row == 10 or _row == 8 or _row == 6 or _row == 4 ? i_resultBackgroundColorOdd:i_resultBackgroundColorEven
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(myColor, 0), text_color=_cellText=='N/A'? i_RowAndColumnTextColor:_c_color,text_size=i_tableSize)
    
// Function for Date
f_array(arrayId, val) => 
    array.unshift(arrayId, val) // append vale to an array
    array.pop(arrayId)

ftdate(_table, _column, _row, _value) => 
    myColor = _row == 10 or _row == 8 or _row == 6 or _row == 4 ? i_resultBackgroundColorOdd:i_resultBackgroundColorEven
    table.cell(table_id = _table, column = _column, row = _row, text = _value, bgcolor = myColor, text_color = i_RowAndColumnTextColor, text_size = i_tableSize)
// For Date
var date = array.new_int(datasize)
if rev
    f_array(date, time)


// For Daily Table
f_fillCellDa(_table, _column, _row, _value) =>
    _c_color = i_posColor
    _transp = 0
    _cellText = str.tostring(_value, '0.00') + " |"
    if(_cellText == 'NaN')
        _cellText := 'N/A |'
    myColor = _row == 10 or _row == 8 or _row == 6 or _row == 4 ? i_resultBackgroundColorOdd:i_resultBackgroundColorEven
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(myColor, 0), text_color=i_RowAndColumnTextColor,text_size=i_tableSize)

// To have one digit after coma for sales    
f_fillCell2Da(_table, _column, _row, _value) =>
    _c_color = i_posColor
    _transp = 0
    _cellText = str.tostring(_value, '0.0')  + " |"
    if(_cellText == 'NaN |')
        _cellText := 'N/A |'
    myColor = _row == 10 or _row == 8 or _row == 6 or _row == 4 ? i_resultBackgroundColorOdd:i_resultBackgroundColorEven
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(myColor, 0), text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
	
f_fillCellCompDa(_table, _column, _row, _value) =>
    _c_color = _value >= 0 ? i_posColor : i_negColor
    _transp = 0
    // Recent modification made that I need to put the IBD/MarketSmith limitaton of +999% here
    _cellText = _value > 999 ? "+999% |": _value < -999 ? "-999% |" :_value > 0 ? '+' + str.tostring(_value, '0') + "% |":str.tostring(_value, '0') + "% |"
    if(_cellText == "NaN% |")
        _cellText := "N/A |"
    if(_cellText == "+0% |")
        _cellText := "0% |"
    if(_value == EpsChangeHash0)
        _cellText := _value > 999 ? "#+999% |": _value < -999 ? "#-999% |" : _value > 0 ? "#" +  "+" + str.tostring(_value, "0") + "% |":"#" + str.tostring(_value, "0") + "% |"
    if(_value == EpsChangeHash1)
        _cellText := _value > 999 ? "#+999% |": _value < -999 ? "#-999% |" : _value > 0 ? "#" +  "+" + str.tostring(_value, "0") + "% |":"#" + str.tostring(_value, "0") + "% |"
    if(_value == EpsChangeHash2)
        _cellText := _value > 999 ? "#+999% |": _value < -999 ? "#-999% |" : _value > 0 ? "#" +  "+" + str.tostring(_value, "0") + "% |":"#" + str.tostring(_value, "0") + "% |"
    if(_value == EpsChangeHash3)
        _cellText := _value > 999 ? "#+999% |": _value < -999 ? "#-999% |" : _value > 0 ? "#" +  "+" + str.tostring(_value, "0") + "% |":"#" + str.tostring(_value, "0") + "% |"
    if(_value == EpsChangeHash4)
        _cellText := _value > 999 ? "#+999% |": _value < -999 ? "#-999% |" : _value > 0 ? "#" +  "+" + str.tostring(_value, "0") + "% |":"#" + str.tostring(_value, "0") + "% |"
    if(_value == EpsChangeHash5)
        _cellText := _value > 999 ? "#+999% |": _value < -999 ? "#-999% |" : _value > 0 ? "#" +  "+" + str.tostring(_value, "0") + "% |":"#" + str.tostring(_value, "0") + "% |"
    if(_value == EpsChangeHash6)
        _cellText := _value > 999 ? "#+999% |": _value < -999 ? "#-999% |" : _value > 0 ? "#" +  "+" + str.tostring(_value, "0") + "% |":"#" + str.tostring(_value, "0") + "% |"
    if(_value == EpsChangeHash7)
        _cellText := _value > 999 ? "#+999% |": _value < -999 ? "#-999% |" : _value > 0 ? "#" +  "+" + str.tostring(_value, "0") + "% |":"#" + str.tostring(_value, "0") + "% |"
    // Color for even or odd row
    myColor = _row == 10 or _row == 8 or _row == 6 or _row == 4 ? i_resultBackgroundColorOdd:i_resultBackgroundColorEven
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(myColor, 0), text_color=_cellText=="0% |" or _cellText=="N/A |"?i_RowAndColumnTextColor:_c_color,text_size=i_tableSize)



// Function used to master the fill of cells - Weekly Table
condRepeatSameValueAtLastLine = actualEPS==actualEPS1 and standardEPS==standardEPS1 and EPS_Estimate==EPS_Estimate[1] // here I use 'and' instead of 'or' because we want to avoid the display bug of TradingView when the 2 last lines repeat themselves
if barstate.islast and i_tableStyle == "Weekly"
    table.set_frame_color( epsTableDa, color.rgb(0,0,0,100))
    table.set_border_color(epsTableDa, color.rgb(0,0,0,100))
    // EPS DISPLAY
    if(i_QoQ == false)
        if(i_compare == true)
            f_fillCellEPS(epsTable, 1, 10, condRepeatSameValueAtLastLine ? na:EPS,condRepeatSameValueAtLastLine ? na:actualEPS4)
            f_fillCellEPS(epsTable, 1, 9, actualEPS1, actualEPS5)
            f_fillCellEPS(epsTable, 1, 8, actualEPS2, actualEPS6)
            f_fillCellEPS(epsTable, 1, 7, actualEPS3, actualEPS7)
            f_fillCellEPS(epsTable, 1, 6, actualEPS4, actualEPS8)
            if(i_moreData == false)
                f_fillCellEPS(epsTable, 1, 5, actualEPS5, actualEPS9)
                f_fillCellEPS(epsTable, 1, 4, actualEPS6, actualEPS10)
                f_fillCellEPS(epsTable, 1, 3, actualEPS7, actualEPS11)
    if(i_QoQ == true)
        if(i_compare == true)
            f_fillCellEPS(epsTable, 1, 10, condRepeatSameValueAtLastLine ? na:EPS,condRepeatSameValueAtLastLine ? na:actualEPS1)
            f_fillCellEPS(epsTable, 1, 9, actualEPS1, actualEPS2)
            f_fillCellEPS(epsTable, 1, 8, actualEPS2, actualEPS3)
            f_fillCellEPS(epsTable, 1, 7, actualEPS3, actualEPS4)
            f_fillCellEPS(epsTable, 1, 6, actualEPS4, actualEPS5)
            if(i_moreData == false)
                f_fillCellEPS(epsTable, 1, 5, actualEPS5, actualEPS6)
                f_fillCellEPS(epsTable, 1, 4, actualEPS6, actualEPS7)
                f_fillCellEPS(epsTable, 1, 3, actualEPS7, actualEPS8)
    if(i_compare == false)
        f_fillCell(epsTable, 1, 10, condRepeatSameValueAtLastLine ? na:EPS)
        f_fillCell(epsTable, 1, 9, actualEPS1)
        f_fillCell(epsTable, 1, 8, actualEPS2)
        f_fillCell(epsTable, 1, 7, actualEPS3)
        f_fillCell(epsTable, 1, 6, actualEPS4)
        if(i_moreData == false)
            f_fillCell(epsTable, 1, 5, actualEPS5)
            f_fillCell(epsTable, 1, 4, actualEPS6)
            f_fillCell(epsTable, 1, 3, actualEPS7)
    // % CHANGE EPS
    if(i_QoQ == false)
        if(i_moreData == false)
            f_fillCellComp(epsTable, 2, 3, i_alwaysDispP ? EpsChange7:EpsChangeHash7 > EpsChange7 ? EpsChangeHash7:EpsChange7)
            f_fillCellComp(epsTable, 2, 4, i_alwaysDispP ? EpsChange6:EpsChangeHash6 > EpsChange6 ? EpsChangeHash6:EpsChange6)
            f_fillCellComp(epsTable, 2, 5, i_alwaysDispP ? EpsChange5:EpsChangeHash5 > EpsChange5 ? EpsChangeHash5:EpsChange5)
        f_fillCellComp(epsTable, 2, 6, i_alwaysDispP ? EpsChange4:EpsChangeHash4 > EpsChange4 ? EpsChangeHash4:EpsChange4)
        f_fillCellComp(epsTable, 2, 7, i_alwaysDispP ? EpsChange3:EpsChangeHash3 > EpsChange3 ? EpsChangeHash3:EpsChange3)
        f_fillCellComp(epsTable, 2, 8, i_alwaysDispP ? EpsChange2:EpsChangeHash2 > EpsChange2 ? EpsChangeHash2:EpsChange2)
        f_fillCellComp(epsTable, 2, 9, i_alwaysDispP ? EpsChange1:EpsChangeHash1 > EpsChange1 ? EpsChangeHash1:EpsChange1)
        f_fillCellComp(epsTable, 2, 10, condRepeatSameValueAtLastLine ? na:i_alwaysDispP ? EpsChange0:EpsChangeHash0 > EpsChange0 ? EpsChangeHash0:EpsChange0)
    // % CHANGE EPS QoQ
    if(i_QoQ == true)
        if(i_moreData == false)
            f_fillCellComp2(epsTable, 2, 3, EpsChangeQoQ7)
            f_fillCellComp2(epsTable, 2, 4, EpsChangeQoQ6)
            f_fillCellComp2(epsTable, 2, 5, EpsChangeQoQ5)
        f_fillCellComp2(epsTable, 2, 6, EpsChangeQoQ4)
        f_fillCellComp2(epsTable, 2, 7, EpsChangeQoQ3)
        f_fillCellComp2(epsTable, 2, 8, EpsChangeQoQ2)
        f_fillCellComp2(epsTable, 2, 9, EpsChangeQoQ1)
        f_fillCellComp2(epsTable, 2, 10, EpsChangeQoQ0)
    // %SURPRISE EPS
    if(i_surprises)
        if(i_moreData == false)
            f_fillCellCompSurp(epsTable, 3, 3,  EpsSurprise7)
            f_fillCellCompSurp(epsTable, 3, 4,  EpsSurprise6)
            f_fillCellCompSurp(epsTable, 3, 5,  EpsSurprise5)
        f_fillCellCompSurp(epsTable, 3, 6,  EpsSurprise4)
        f_fillCellCompSurp(epsTable, 3, 7,  EpsSurprise3)
        f_fillCellCompSurp(epsTable, 3, 8,  EpsSurprise2)
        f_fillCellCompSurp(epsTable, 3, 9,  EpsSurprise1)
        f_fillCellCompSurp(epsTable, 3, 10, EpsSurprise0)

    
    
    //SALES DISPLAY
    if(i_QoQ == false)
        if(i_compare == true)
            f_fillCell2SALES(epsTable, 4, 10, condRepeatSameValueAtLastLine ? na:recentEarn and sameSales ? na:Sales0M,condRepeatSameValueAtLastLine ? na:Sales4M)
            f_fillCell2SALES(epsTable, 4, 9, Sales1M, Sales5M)
            f_fillCell2SALES(epsTable, 4, 8, Sales2M, Sales6M)
            f_fillCell2SALES(epsTable, 4, 7, Sales3M, Sales7M)
            f_fillCell2SALES(epsTable, 4, 6, Sales4M, Sales8M)
            if(i_moreData == false)
                f_fillCell2SALES(epsTable, 4, 5, Sales5M, Sales9M )
                f_fillCell2SALES(epsTable, 4, 4, Sales6M, Sales10M)
                f_fillCell2SALES(epsTable, 4, 3, Sales7M, Sales11M)
    if(i_QoQ == true)
        if(i_compare == true)
            f_fillCell2SALES(epsTable, 4, 10, condRepeatSameValueAtLastLine ? na:recentEarn and sameSales ? na:Sales0M,condRepeatSameValueAtLastLine ? na:Sales1M)
            f_fillCell2SALES(epsTable, 4, 9, Sales1M, Sales2M)
            f_fillCell2SALES(epsTable, 4, 8, Sales2M, Sales3M)
            f_fillCell2SALES(epsTable, 4, 7, Sales3M, Sales4M)
            f_fillCell2SALES(epsTable, 4, 6, Sales4M, Sales5M)
            if(i_moreData == false)
                f_fillCell2SALES(epsTable, 4, 5, Sales5M, Sales6M)
                f_fillCell2SALES(epsTable, 4, 4, Sales6M, Sales7M)
                f_fillCell2SALES(epsTable, 4, 3, Sales7M, Sales8M)
    // SALES Normal
    if(i_compare == false)
        f_fillCell2(epsTable, 4, 10, condRepeatSameValueAtLastLine ? na:recentEarn and sameSales ? na:Sales0M)
        f_fillCell2(epsTable, 4, 9, Sales1M)
        f_fillCell2(epsTable, 4, 8, Sales2M)
        f_fillCell2(epsTable, 4, 7, Sales3M)
        f_fillCell2(epsTable, 4, 6, Sales4M)
        if(i_moreData == false)
            f_fillCell2(epsTable, 4, 5, Sales5M)
            f_fillCell2(epsTable, 4, 4, Sales6M)
            f_fillCell2(epsTable, 4, 3, Sales7M) 
    // % CHANGE SALES YOY
    if(i_QoQ == false)
        if(i_moreData == false)
            f_fillCellComp(epsTable, 5, 3, salesChange7)
            f_fillCellComp(epsTable, 5, 4, salesChange6)
            f_fillCellComp(epsTable, 5, 5, salesChange5)
        f_fillCellComp(epsTable, 5, 6, salesChange4)
        f_fillCellComp(epsTable, 5, 7, salesChange3)
        f_fillCellComp(epsTable, 5, 8, salesChange2)
        f_fillCellComp(epsTable, 5, 9, salesChange1)
        f_fillCellComp(epsTable, 5, 10, condRepeatSameValueAtLastLine ? na:recentEarn and sameSales ? na:salesChange0)
    if(i_QoQ == true)
        if(i_moreData == false)
            f_fillCellComp(epsTable, 5, 3, salesChangeQoQ7)
            f_fillCellComp(epsTable, 5, 4, salesChangeQoQ6)
            f_fillCellComp(epsTable, 5, 5, salesChangeQoQ5)
        f_fillCellComp(epsTable, 5, 6, salesChangeQoQ4)
        f_fillCellComp(epsTable, 5, 7, salesChangeQoQ3)
        f_fillCellComp(epsTable, 5, 8, salesChangeQoQ2)
        f_fillCellComp(epsTable, 5, 9, salesChangeQoQ1)
        f_fillCellComp(epsTable, 5, 10, condRepeatSameValueAtLastLine ? na:recentEarn and sameSales ? na:salesChangeQoQ0)
    // %SURPRISE SALES
    if(i_surprises)
        if(i_moreData == false)
            f_fillCellCompSurp(epsTable, 6, 3,  SalesSurprise7)
            f_fillCellCompSurp(epsTable, 6, 4,  SalesSurprise6)
            f_fillCellCompSurp(epsTable, 6, 5,  SalesSurprise5)
        f_fillCellCompSurp(epsTable, 6, 6,  SalesSurprise4)
        f_fillCellCompSurp(epsTable, 6, 7,  SalesSurprise3)
        f_fillCellCompSurp(epsTable, 6, 8,  SalesSurprise2)
        f_fillCellCompSurp(epsTable, 6, 9,  SalesSurprise1)
        f_fillCellCompSurp(epsTable, 6, 10, SalesSurprise0)
    // GROSS MARGIN 
    if(i_grossMargin == true)
        if(i_moreData == false)
            f_fillCellComp(epsTable, 7, 3, GM7)
            f_fillCellComp(epsTable, 7, 4, GM6)
            f_fillCellComp(epsTable, 7, 5, GM5)
        f_fillCellComp(epsTable, 7, 6, GM4)
        f_fillCellComp(epsTable, 7, 7, GM3)
        f_fillCellComp(epsTable, 7, 8, GM2)
        f_fillCellComp(epsTable, 7, 9, GM1)
        f_fillCellComp(epsTable, 7, 10, GM0)
    // ROE
    if(i_ROE == true)
        if(i_moreData == false)
            f_fillCellComp(epsTable, 8, 3, ROE7)
            f_fillCellComp(epsTable, 8, 4, ROE6)
            f_fillCellComp(epsTable, 8, 5, ROE5)
        f_fillCellComp(epsTable, 8, 6, ROE4)
        f_fillCellComp(epsTable, 8, 7, ROE3)
        f_fillCellComp(epsTable, 8, 8, ROE2)
        f_fillCellComp(epsTable, 8, 9, ROE1)
        f_fillCellComp(epsTable, 8, 10, ROE0) 
    
    // For Date MMM-yy
    for i = 0 to datasize-blankUnderUp
        if barstate.islast
            ftdate(epsTable, 0, (datasize-i), str.format('{0, date, MMM-yy}', array.get(date, i)))

    
    //Headings of Weekly Table
    txt6 = i_QoQ ? "%Chg QoQ ":"      %Chg " 
    txt8 = "Quarterly "
    txt9 = "     EPS($)  "
    
    txt10 = "  Sales($Mil) "
    if(sales >= 10000000000)
        txt10 := "  Sales($Bil) "
    txt11 = i_QoQ ? "%Chg QoQ":"     %Chg  " 
    txt12 = "   GM   "
    txt13 = "  ROE  "
    txt14 = "%Surp "

    // Side Column
    table.cell(epsTable,2,0,  text=txt6,  bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    if(i_QoQ == true)
        table.cell(epsTable,2,0, text=txt6, bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    table.cell(epsTable,0,0, text=txt8, bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    table.cell(epsTable,1,0, text=txt9, bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    
    
    //SALES HEADING 
    table.cell(epsTable,4,0, text=txt10, bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    table.cell(epsTable,5,0, text=txt11, bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    
    //GROSS MARGIN   (table, line, row, txt..)
    if(i_grossMargin == true)
        table.cell(epsTable,7,0, text=txt12, bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    // ROE
    if(i_ROE == true)
        table.cell(epsTable,8,0, text=txt13, bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    // //Surprise
    if(i_surprises)
        table.cell(epsTable,3,0, text=txt14, bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
        table.cell(epsTable,6,0, text=txt14, bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)


// Layout Weekly Table
// Date
if(not i_moreData)
    for i = 3 to 5
        for x = 0 to 2
            table.cell_set_text_halign(epsTable, x,  i, text_halign = text.align_right)
        for x = 4 to 5
            table.cell_set_text_halign(epsTable, x,  i, text_halign = text.align_right)
for i = 6 to 10
    for x = 0 to 2
        table.cell_set_text_halign(epsTable, x,  i, text_halign = text.align_right)
    for x = 4 to 5
        table.cell_set_text_halign(epsTable, x,  i, text_halign = text.align_right)
// Align surprises
if(i_surprises)
    if(not i_moreData)
        for i = 3 to 5
            table.cell_set_text_halign(epsTable, 3,  i, text_halign = text.align_right)
            table.cell_set_text_halign(epsTable, 6,  i, text_halign = text.align_right)
    for i = 6 to 10
        table.cell_set_text_halign(epsTable, 3,  i, text_halign = text.align_right)
        table.cell_set_text_halign(epsTable, 6,  i, text_halign = text.align_right)
// Align GM
if(i_grossMargin)
    if(not i_moreData)
        for i = 3 to 5
            table.cell_set_text_halign(epsTable, 7,  i, text_halign = text.align_right)
    for i = 6 to 10
        table.cell_set_text_halign(epsTable, 7,  i, text_halign = text.align_right)
// Align ROE
if(i_ROE)
    if(not i_moreData)
        for i = 3 to 5
            table.cell_set_text_halign(epsTable, 8,  i, text_halign = text.align_right)
    for i = 6 to 10
        table.cell_set_text_halign(epsTable, 8,  i, text_halign = text.align_right)


if barstate.islast and i_tableStyle == "Daily"
    table.set_frame_color( epsTable, color.rgb(0,0,0,100))
    table.set_border_color(epsTable, color.rgb(0,0,0,100))
    // DISPLAY of the Daily Table **************************************************************************************
    // Date
    if(not i_tableBorder)
        ftdate(epsTableDa, 12, 0, "         Qtr Ended " + str.format('{0, date,MMMMMMMMM dd, yyyy}', array.get(date, 0)) + "         │")
        ftdate(epsTableDa, 8,  0, "         Qtr Ended " + str.format('{0, date,MMMMMMMMM dd, yyyy}', array.get(date, 1)) + "         │")
        ftdate(epsTableDa, 4,  0, "         Qtr Ended " + str.format('{0, date,MMMMMMMMM dd, yyyy}', array.get(date, 2)) + "         │")
        ftdate(epsTableDa, 0,  0, "         Qtr Ended " + str.format('{0, date,MMMMMMMMM dd, yyyy}', array.get(date, 3)) + "         │")
    else
        ftdate(epsTableDa, 12, 0, "         Qtr Ended " + str.format('{0, date,MMMMMMMMM dd, yyyy}', array.get(date, 0)) + "          ")
        ftdate(epsTableDa, 8,  0, "         Qtr Ended " + str.format('{0, date,MMMMMMMMM dd, yyyy}', array.get(date, 1)) + "          ")
        ftdate(epsTableDa, 4,  0, "         Qtr Ended " + str.format('{0, date,MMMMMMMMM dd, yyyy}', array.get(date, 2)) + "          ")
        ftdate(epsTableDa, 0,  0, "         Qtr Ended " + str.format('{0, date,MMMMMMMMM dd, yyyy}', array.get(date, 3)) + "          ")
    table.cell(epsTableDa, 16, 0, text="EPS Due    ", bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor ,text_size=i_tableSize)
    // EPS 1 
    f_fillCell(epsTableDa, 12, 1, condRepeatSameValueAtLastLine ? na:EPS)
    f_fillCell(epsTableDa, 8, 1, actualEPS1)
    f_fillCell(epsTableDa, 4, 1, actualEPS2)
    f_fillCell(epsTableDa, 0, 1, actualEPS3)
    // vs
    table.cell(epsTableDa, 13,1, text="           vs      ", bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    table.cell(epsTableDa, 9 ,1, text="           vs      ", bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    table.cell(epsTableDa, 5 ,1, text="           vs      ", bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    table.cell(epsTableDa, 1 ,1, text="           vs      ", bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    // EPS2
    f_fillCell(epsTableDa, 14, 1, condRepeatSameValueAtLastLine ? na:actualEPS4)
    f_fillCell(epsTableDa, 10, 1, actualEPS5)
    f_fillCell(epsTableDa, 6,  1, actualEPS6)
    f_fillCell(epsTableDa, 2,  1, actualEPS7)
    // EPS%
    if(not i_tableBorder)
        f_fillCellCompDa(epsTableDa, 15, 1, condRepeatSameValueAtLastLine ? na:i_alwaysDispP ? EpsChange0:EpsChangeHash0 > EpsChange0 ? EpsChangeHash0:EpsChange0)
        f_fillCellCompDa(epsTableDa, 11, 1, i_alwaysDispP ? EpsChange1:EpsChangeHash1 > EpsChange1 ? EpsChangeHash1:EpsChange1)
        f_fillCellCompDa(epsTableDa, 7,  1, i_alwaysDispP ? EpsChange2:EpsChangeHash2 > EpsChange2 ? EpsChangeHash2:EpsChange2)
        f_fillCellCompDa(epsTableDa, 3,  1, i_alwaysDispP ? EpsChange3:EpsChangeHash3 > EpsChange3 ? EpsChangeHash3:EpsChange3)
    else
        f_fillCellComp(epsTableDa, 15, 1, condRepeatSameValueAtLastLine ? na:i_alwaysDispP ? EpsChange0:EpsChangeHash0 > EpsChange0 ? EpsChangeHash0:EpsChange0)
        f_fillCellComp(epsTableDa, 11, 1, i_alwaysDispP ? EpsChange1:EpsChangeHash1 > EpsChange1 ? EpsChangeHash1:EpsChange1)
        f_fillCellComp(epsTableDa, 7,  1, i_alwaysDispP ? EpsChange2:EpsChangeHash2 > EpsChange2 ? EpsChangeHash2:EpsChange2)
        f_fillCellComp(epsTableDa, 3,  1, i_alwaysDispP ? EpsChange3:EpsChangeHash3 > EpsChange3 ? EpsChangeHash3:EpsChange3)
    // Sales 1
    f_fillCell2(epsTableDa, 12, 2, condRepeatSameValueAtLastLine ? na:(EPSTime or EPSTime[1]) and sameSales ? na:Sales0M)
    f_fillCell2(epsTableDa, 8,  2, Sales1M)
    f_fillCell2(epsTableDa, 4,  2, Sales2M)
    f_fillCell2(epsTableDa, 0,  2, Sales3M)
    // vs
    table.cell(epsTableDa, 13, 2, text="           vs      ", bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    table.cell(epsTableDa, 9 , 2, text="           vs      ", bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    table.cell(epsTableDa, 5 , 2, text="           vs      ", bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    table.cell(epsTableDa, 1 , 2, text="           vs      ", bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    // Sales 2
    f_fillCell2(epsTableDa, 14, 2, condRepeatSameValueAtLastLine ? na:Sales4M)
    f_fillCell2(epsTableDa, 10, 2, Sales5M)
    f_fillCell2(epsTableDa, 6,  2,  Sales6M)
    f_fillCell2(epsTableDa, 2,  2,  Sales7M)
    // Sales%
    if (not i_tableBorder)
        f_fillCellCompDa(epsTableDa, 15, 2, condRepeatSameValueAtLastLine ? na:(EPSTime or EPSTime[1]) and sameSales ? na:salesChange0)
        f_fillCellCompDa(epsTableDa, 11, 2, salesChange1)
        f_fillCellCompDa(epsTableDa, 7,  2, salesChange2)
        f_fillCellCompDa(epsTableDa, 3,  2, salesChange3)
    else
        f_fillCellComp(epsTableDa, 15, 2, condRepeatSameValueAtLastLine ? na:(EPSTime or EPSTime[1]) and sameSales ? na:salesChange0)
        f_fillCellComp(epsTableDa, 11, 2, salesChange1)
        f_fillCellComp(epsTableDa, 7,  2, salesChange2)
        f_fillCellComp(epsTableDa, 3,  2, salesChange3)
    // ROE
    if (i_ROE == true)
        if(not i_tableBorder)
            f_fillCellCompDa(epsTableDa, 15, 3, ROE0) 
            f_fillCellCompDa(epsTableDa, 11, 3, ROE1)
            f_fillCellCompDa(epsTableDa, 7,  3, ROE2)
            f_fillCellCompDa(epsTableDa, 3,  3, ROE3)
        else
            f_fillCellComp(epsTableDa, 15, 3, ROE0) 
            f_fillCellComp(epsTableDa, 11, 3, ROE1)
            f_fillCellComp(epsTableDa, 7,  3, ROE2)
            f_fillCellComp(epsTableDa, 3,  3, ROE3)
    if (i_grossMargin)
        if(not i_tableBorder)
            f_fillCellCompDa(epsTableDa, 15, 3, GM0)
            f_fillCellCompDa(epsTableDa, 11, 3, GM1)
            f_fillCellCompDa(epsTableDa, 7,  3, GM2)
            f_fillCellCompDa(epsTableDa, 3,  3, GM3)
        else
            f_fillCellComp(epsTableDa, 15, 3, GM0)
            f_fillCellComp(epsTableDa, 11, 3, GM1)
            f_fillCellComp(epsTableDa, 7,  3, GM2)
            f_fillCellComp(epsTableDa, 3,  3, GM3)


    // Heandings For Daily Table
    txt20 = "Sales ($Mil)"
    if(sales >= 10000000000)
        txt20 := "Sales ($Bil)"

    txt21 = ""
    if(i_ROE)
        txt21 := "Return on Equity"
    if(i_grossMargin)
        txt21 := "Gross Margin"
    
    // Data for Daily Table
    table.cell(epsTableDa,16,1, text="Earnings ($)           ", bgcolor=color.white, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    table.cell(epsTableDa,16,2, text=txt20, bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    table.cell(epsTableDa,16,3, text=txt21, bgcolor=i_resultBackgroundColorOdd, text_color=i_RowAndColumnTextColor,text_size=i_tableSize)
    // Change BG Colors of all the table
    for i = 0 to 16
        for x = 0 to 3
            table.cell_set_bgcolor(epsTableDa, i,  x, i_resultBackgroundColorOdd)
    // Text Align
    // EPS and Sales at the left
    table.cell_set_text_halign(epsTableDa, 0,  1, text_halign = text.align_left)
    table.cell_set_text_halign(epsTableDa, 0,  2, text_halign = text.align_left)
    table.cell_set_text_halign(epsTableDa, 4,  1, text_halign = text.align_left)
    table.cell_set_text_halign(epsTableDa, 4,  2, text_halign = text.align_left)
    table.cell_set_text_halign(epsTableDa, 8,  1, text_halign = text.align_left)
    table.cell_set_text_halign(epsTableDa, 8,  2, text_halign = text.align_left)
    table.cell_set_text_halign(epsTableDa, 12, 1, text_halign = text.align_left)
    table.cell_set_text_halign(epsTableDa, 12, 2, text_halign = text.align_left)
    // % figures
    table.cell_set_text_halign(epsTableDa, 3,   1, text_halign = text.align_right)
    table.cell_set_text_halign(epsTableDa, 3,   2, text_halign = text.align_right)
    table.cell_set_text_halign(epsTableDa, 3,   3, text_halign = text.align_right)
    table.cell_set_text_halign(epsTableDa, 7,   1, text_halign = text.align_right)
    table.cell_set_text_halign(epsTableDa, 7,   2, text_halign = text.align_right)
    table.cell_set_text_halign(epsTableDa, 7,   3, text_halign = text.align_right)
    table.cell_set_text_halign(epsTableDa, 11,  1, text_halign = text.align_right)
    table.cell_set_text_halign(epsTableDa, 11,  2, text_halign = text.align_right)
    table.cell_set_text_halign(epsTableDa, 11,  3, text_halign = text.align_right)
    table.cell_set_text_halign(epsTableDa, 15,  1, text_halign = text.align_right)
    table.cell_set_text_halign(epsTableDa, 15,  2, text_halign = text.align_right)
    table.cell_set_text_halign(epsTableDa, 15,  3, text_halign = text.align_right)
    // Earnings info
    table.cell_set_text_halign(epsTableDa, 16,  1, text_halign = text.align_left)
    table.cell_set_text_halign(epsTableDa, 16,  2, text_halign = text.align_left)
    table.cell_set_text_halign(epsTableDa, 16,  3, text_halign = text.align_left)
    // Merge Cell
    table.merge_cells(epsTableDa, 0,  0,  3, 0)
    table.merge_cells(epsTableDa, 4,  0,  7, 0)
    table.merge_cells(epsTableDa, 8,  0, 11, 0)
    table.merge_cells(epsTableDa, 12, 0, 15, 0)



// Diplay Arrow on the graph with % variation EPS
selectEPS = ta.valuewhen(EPSTime, EpsChangeHash0, 0) > ta.valuewhen(EPSTime, EpsChange0, 0) // Time for Sales annoucement
EPSvalue   = selectEPS ? ta.valuewhen(EPSTime, EpsChangeHash0, 0):ta.valuewhen(EPSTime, EpsChange0, 0)
salesValue = ta.valuewhen(EPSTime, salesChange0, 0) // Select the value of % sales change for the date of the arrow
//plotshape(EPSTime, style=shape.triangleup, color=color.new(color.silver, 0), location=location.bottom, size=size.tiny, text="", textcolor = color.white)
textLayout1 = i_salesOnGraph ? 'EPS & Sales':'EPS'
textLayout2 = EPSvalue > 999 ? '\n+999%':EPSvalue > 0 ? '\n+' + str.tostring(EPSvalue, '0') + '%':'\n' + str.tostring(EPSvalue, '0') + '%'
if(textLayout2 == '\nNaN%')
    textLayout2 := '\nN/A'
if(textLayout2 == '\n+0%')
    textLayout2 := '\n0%'
textLayout4 = (EPSTime or EPSTime[1]) and sameSales and barstate.islast ? 'NaN%':salesChange0 > 999 ? '+999%':salesChange0 > 0 ? '+' + str.tostring(salesChange0, '0') + '%':str.tostring(salesChange0, '0') + '%' // For Sales
if(textLayout4 == 'NaN%')
    textLayout4 := 'N/A'
if(textLayout4 == '+0%')
    textLayout4 := '0%'
// Here we check if we have to plot sales or not, depending on the result we display appropriate variables
if(EPSTime and i_ArrowOnGraph)
    label1 = label.new(bar_index, bar_index, xloc=xloc.bar_index, yloc=yloc.belowbar, text=textLayout1, style=label.style_triangleup, color=color.new(color.aqua,100), textcolor=i_arrowColor, size=i_arrowSize)
    if(not i_salesOnGraph)
        label2 = label.new(bar_index, low, xloc=xloc.bar_index, yloc=yloc.belowbar, text=textLayout2, style=label.style_triangleup, color=i_arrowColor,              textcolor=textLayout2=='\nN/A' or textLayout2=='\n0%' ? i_arrowColor:EPSvalue > -1 ? i_posArrowColor:i_negArrowColor, size=i_arrowSize)
    if(i_salesOnGraph)
        label2 = label.new(bar_index, low, xloc=xloc.bar_index, yloc=yloc.belowbar, text=textLayout2+' | '+textLayout4, style=label.style_triangleup, color=i_arrowColor,              textcolor=textLayout2=='\nN/A' or textLayout2=='\n0%' ? i_arrowColor:EPSvalue > -1 ? i_posArrowColor:i_negArrowColor, size=i_arrowSize)

// Test for better arrow display but now the space between arrows and text isn't fix...
// offsetArrow = ta.lowest(low*0.85, 4) // Get the Lowest low of the 4 previous bars for correct diplay even in case of earning gap up
// if(EPSTime and i_ArrowOnGraph)
//     label1    = label.new(bar_index, offsetArrow, xloc=xloc.bar_index, yloc=yloc.price, text="", style=label.style_triangleup, color=i_arrowColor, textcolor=i_arrowColor, size=i_arrowSize)
//     label1Eps = label.new(bar_index, offsetArrow*0.85, xloc=xloc.bar_index, yloc=yloc.price, text=textLayout1, style=label.style_triangleup, color=color.new(color.aqua,100), textcolor=i_arrowColor, size=i_arrowSize)
//     if(not i_salesOnGraph)
//         label2 = label.new(bar_index, offsetArrow*0.81, xloc=xloc.bar_index, yloc=yloc.price, text=textLayout2, style=label.style_triangleup, color=color.new(color.aqua,100),              textcolor=textLayout2=='\nN/A' or textLayout2=='\n0%' ? i_arrowColor:EPSvalue > -1 ? i_posArrowColor:i_negArrowColor, size=i_arrowSize)
//     if(i_salesOnGraph)
//         label2 = label.new(bar_index, offsetArrow*0.81, xloc=xloc.bar_index, yloc=yloc.price, text=textLayout2+' | '+textLayout4, style=label.style_triangleup, color=color.new(color.aqua,100),              textcolor=textLayout2=='\nN/A' or textLayout2=='\n0%' ? i_arrowColor:EPSvalue > -1 ? i_posArrowColor:i_negArrowColor, size=i_arrowSize)