Indicator : Financial Table
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © morzor61



// Section 
// 1. Income Statement      tb01
// 2. Balance Sheet         tb02
// 3. Cash Flow             tb03
// 4. Valuation             tb04

// 1) Get Financial Data
// 2) Decare array
// 3) Store the array if conditions are met. 
// 4) Generate table 


//@version=4
study("Indicator : Financial Table", format=format.volume)

period          =   input("FQ", "Report Type", options=["FQ", "FY"])
plotdata        =   input("EPS", "Data to Plot", options=["Revenue", "Net Profit", "EPS"])
int datasize    =   input(8, "Data size", minval=2)+1
opt_textsize    =   input(size.small,                   "Text Size",                options=[ size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group="table")
is_opt_pos         =   input(position.middle_left,      "Table \nPosition\n #1",    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")
bs_opt_pos         =   input(position.middle_center,    "Table \nPosition\n #2",    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")
cf_opt_pos         =   input(position.middle_right,     "Table \nPosition\n #3",    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")



// Function to detect the report data 
// var ticker      = "ESD_FACTSET:" + syminfo.prefix + ";" + syminfo.ticker + ";EARNINGS"
// report_date = security(earning_ticker, "D", time, gaps = true, lookahead=true) //earning report date

// Function to Get Financial Data
get_Fin_data(_finID, _period)    => 
    financial(
         symbol         = syminfo.tickerid, 
         financial_id   = _finID, 
         period         = _period,
         gaps           = barmerge.gaps_on)

eps             = get_Fin_data("EARNINGS_PER_SHARE", period)
revenue         = get_Fin_data("TOTAL_REVENUE", period)
np              = get_Fin_data("NET_INCOME", period) 


datatoplot = plotdata == "EPS" ? eps : plotdata == "Revenue" ? revenue : np 


//  ■ Income Statement 
var date    = array.new_int(datasize) // Date
var is01    = array.new_float(datasize) // Revenue
var is02    = array.new_float(datasize) // Net Profit
var is03    = array.new_float(datasize) // EPS

if not na(datatoplot) 
    label.new(bar_index, datatoplot, text=tostring(
          plotdata == "EPS" ? datatoplot : 
          plotdata == "Revenue" ? datatoplot/100000 : datatoplot/100000,
          plotdata == "EPS" ? "#,##0.000" : 
          plotdata == "Revenue" ? "#,##0"+" M" :
          "#,##0"+" M"))
    array.push(is03, eps)
    array.shift(is03)
    array.push(date, time)
    array.shift(date)
    array.push(is01, revenue)
    array.shift(is01)
    array.push(is02, np)
    array.shift(is02)
    
// ■ Balance Sheet 

// asset
//    1. current 
curasst = get_Fin_data("TOTAL_CURRENT_ASSETS", period) // bs01

//        - cash
//        - receivable
//        - inventory
//    2. non current 
ttasst = get_Fin_data("TOTAL_ASSETS", period) // bs02
// liability 
//    1. current 
curlbt = get_Fin_data("TOTAL_CURRENT_LIABILITIES", period) // bs03
//      - debt short  
//      - accounts payable
//      - total
//    2. non-current
noncurlbt = get_Fin_data("TOTAL_NON_CURRENT_LIABILITIES", period) // bs04

//        - debt lobg
//        - total non

// shd equity
shdeqt = get_Fin_data("SHRHLDRS_EQUITY", period) // bs05
//        
//        
var bs01 = array.new_float(datasize) // Current Asset
var bs02 = array.new_float(datasize) // Non-current Asset
var bs03 = array.new_float(datasize) // Current Liabilities
var bs04 = array.new_float(datasize) // Non-current Liabilites
var bs05 = array.new_float(datasize) // Share Holder's Equity


if not na(datatoplot)
    array.push(bs01, curasst)
    array.push(bs02, ttasst)
    array.push(bs03, curlbt)
    array.push(bs04, noncurlbt)
    array.push(bs05, shdeqt)
    array.shift(bs01)
    array.shift(bs02)
    array.shift(bs03)
    array.shift(bs04)
    array.shift(bs05)

var tbbs = table.new(bs_opt_pos, 7, datasize, frame_color=color.black,frame_width=1, border_width=1, border_color=color.black)
if barstate.islast 
    table.cell(tbbs, 0,0, "", text_size = opt_textsize)
    table.cell(tbbs, 1,0, "Date", text_size = opt_textsize)
    table.cell(tbbs, 2,0, "Current \nAsset", text_size = opt_textsize)
    table.cell(tbbs, 3,0, "Total \nAsset", text_size = opt_textsize)
    table.cell(tbbs, 4,0, "Current \nLiabilities", text_size = opt_textsize)
    table.cell(tbbs, 5,0, "Non-current \nLiabilities", text_size = opt_textsize)
    table.cell(tbbs, 6,0, "Shd \n Eqity", text_size = opt_textsize)
    
for i = 1 to datasize-1
    if barstate.islast 
        table.cell(tbbs, 0, i, tostring(i), text_size = opt_textsize)
        table.cell(tbbs, 1, i, str.format("{0, date, Y-MMM}", array.get(date, i)), text_size = opt_textsize)
        table.cell(tbbs, 2, i, tostring(array.get(bs01, i)/1000000, "#,##0"+"M"), text_size = opt_textsize,     bgcolor = array.get(bs01 ,i) <= array.get(bs01 , i-1) ? #FF6961 : #39FF14)
        table.cell(tbbs, 3, i, tostring(array.get(bs02, i)/1000000, "#,##0"+"M"), text_size = opt_textsize,     bgcolor = array.get(bs02 ,i) <= array.get(bs02 , i-1) ? #FF6961 : #39FF14)
        table.cell(tbbs, 4, i, tostring(array.get(bs03, i)/1000000, "#,##0"+"M"), text_size = opt_textsize,     bgcolor = array.get(bs03 ,i) <= array.get(bs03 , i-1) ? #FF6961 : #39FF14)
        table.cell(tbbs, 5, i, tostring(array.get(bs04, i)/1000000, "#,##0"+"M"), text_size = opt_textsize,     bgcolor = array.get(bs04 ,i) <= array.get(bs04 , i-1) ? #FF6961 : #39FF14)
        table.cell(tbbs, 6, i, tostring(array.get(bs05, i)/1000000, "#,##0"+"M"), text_size = opt_textsize,     bgcolor = array.get(bs05 ,i) <= array.get(bs05 , i-1) ? #FF6961 : #39FF14)

plot(datatoplot , style=plot.style_circles, linewidth=5, join=true)


var tbis = table.new(is_opt_pos, 5, datasize, frame_color=color.black,frame_width=1, border_width=1, border_color=color.black)

if barstate.islast 
    table.cell(tbis, 0,0, "", text_size = opt_textsize)
    table.cell(tbis, 1,0, "Date", text_size = opt_textsize)
    table.cell(tbis, 2,0, "Revenue", text_size = opt_textsize)
    table.cell(tbis, 3,0, "Net Profit", text_size = opt_textsize)
    table.cell(tbis, 4,0, "EPS", text_size = opt_textsize)

for i = 1 to datasize-1
    if barstate.islast
        table.cell(tbis, 0, i, tostring(i), text_size = opt_textsize)
        table.cell(tbis, 1, i, str.format("{0, date, Y-MMM}", array.get(date, i)),    text_size = opt_textsize)
        table.cell(tbis, 2, i, tostring(array.get(is01, i)/1000000, "#,##0"+"M"),       text_size = opt_textsize,   bgcolor = array.get(is01 ,i) <= array.get(is01 , i-1) ? #FF6961 : #39FF14)
        table.cell(tbis, 3, i, tostring(array.get(is02, i)/1000000, "#,##0"+"M"),       text_size = opt_textsize,   bgcolor = array.get(is02 ,i) <= array.get(is02 , i-1) ? #FF6961 : #39FF14)
        table.cell(tbis, 4, i, tostring(array.get(is03, i), "#,##0.000"),               text_size = opt_textsize,   bgcolor = array.get(is03 ,i) <= array.get(is03 , i-1) ? #FF6961 : #39FF14)

// Cash Flow
//  1. Operation (cfo)
cfo     = get_Fin_data("CASH_F_OPERATING_ACTIVITIES", period)
//  2. Investment (cfi)
cfi     = get_Fin_data("CASH_F_INVESTING_ACTIVITIES", period)
//  3. Financial (cff)
cff     = get_Fin_data("CASH_F_FINANCING_ACTIVITIES", period)
//  4. Capital Expenditure (capex)
capex   = get_Fin_data("CAPITAL_EXPENDITURES", period)
//  5. Free Cash Flow (fcf) 
fcf     = get_Fin_data("FREE_CASH_FLOW", period)

var cf01    =   array.new_float(datasize) // cfo
var cf02    =   array.new_float(datasize) // cfi
var cf03    =   array.new_float(datasize)  // cff
var cf04    =   array.new_float(datasize) // capex
var cf05    =   array.new_float(datasize) // fcf

if not na(datatoplot) 
    array.push(cf01, cfo)
    array.push(cf02, cfi)
    array.push(cf03, cff)
    array.push(cf04, capex)
    array.push(cf05, fcf)
    array.shift(cf01)
    array.shift(cf02)
    array.shift(cf03)
    array.shift(cf04)
    array.shift(cf05)

var tbcf = table.new(cf_opt_pos, 7, datasize, frame_color=color.black,frame_width=1, border_width=1, border_color=color.black)
if barstate.islast 
    table.cell(tbcf, 0,0, "",                       text_size = opt_textsize)
    table.cell(tbcf, 1,0, "Date",                   text_size = opt_textsize)
    table.cell(tbcf, 2,0, "CF \nOperation",         text_size = opt_textsize)
    table.cell(tbcf, 3,0, "CF \nInvestment",        text_size = opt_textsize)
    table.cell(tbcf, 4,0, "CF \nFinancing",         text_size = opt_textsize)
    table.cell(tbcf, 5,0, "Capital \nExpenditure",  text_size = opt_textsize)
    table.cell(tbcf, 6,0, "Free \nCash Flow",       text_size = opt_textsize)
    
for i = 1 to datasize-1
    if barstate.islast 
        table.cell(tbcf, 0, i, tostring(i), text_size = opt_textsize)
        table.cell(tbcf, 1, i, str.format("{0, date, Y-MMM}", array.get(date, i)), text_size = opt_textsize)
        table.cell(tbcf, 2, i, tostring(array.get(cf01, i)/1000000, "#,##0"+"M"), text_size = opt_textsize,             bgcolor = array.get(cf01,i) <= array.get(cf01, i-1) ? #FF6961 : #39FF14)
        table.cell(tbcf, 3, i, tostring(array.get(cf02, i)/1000000, "#,##0"+"M"), text_size = opt_textsize,             bgcolor = array.get(cf02,i) <= array.get(cf02, i-1) ? #FF6961 : #39FF14)
        table.cell(tbcf, 4, i, tostring(array.get(cf03, i)/1000000, "#,##0"+"M"), text_size = opt_textsize,             bgcolor = array.get(cf03,i) <= array.get(cf03, i-1) ? #FF6961 : #39FF14)
        table.cell(tbcf, 5, i, tostring(array.get(cf04, i)/1000000, "#,##0"+"M"), text_size = opt_textsize,             bgcolor = array.get(cf04,i) <= array.get(cf04, i-1) ? #FF6961 : #39FF14)
        table.cell(tbcf, 6, i, tostring(array.get(cf05, i)/1000000, "#,##0"+"M"), text_size = opt_textsize,             bgcolor = array.get(cf05,i) <= array.get(cf05, i-1) ? #FF6961 : #39FF14)
        
