[LanZhu] - Bursa Index/Sector Trend With Portfolio
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Lanzhu0506

// This indicator has included some codes from other author's indicator as below
// Portfolio Tracker [Anan] from Mohamed3nan

//@version=5

indicator('[LanZhu] - Bursa Index/Sector Trend With Portfolio')

import Lanzhu0506/Bursa_Sector/13 as bursa

///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
///                         Input & Setting                         ///
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

// =====================
// ===Trend Indicator=== 
// =====================

trendIndicatorGroup = '===Index & Sector Trend==='

sym = input.string(title = "Index Type", defval = "Sector", options=['Main Index', 'Sector'], group = trendIndicatorGroup)
trendRes = input.timeframe(title = 'Trend Timeframe', defval = 'D', group = trendIndicatorGroup)
mainIndexUpColor = input.color(title = "Main Index Uptrend Color", defval = color.new(color.blue, 50), inline='main', group = trendIndicatorGroup)
mainIndexDownColor = input.color(title = "Main Index Downtrend Color", defval = color.new(color.red, 50), inline='main', group = trendIndicatorGroup)
sectorUpColor = input.color(title = "Sector Uptrend Color", defval = color.new(color.lime, 50), inline='sector', group = trendIndicatorGroup)
sectorDownColor = input.color(title = "Sector Downtrend Color", defval = color.new(color.purple, 50), inline='sector', group = trendIndicatorGroup)

// ===============
// ===Portfolio=== 
// ===============

portfolioWatchlistGroup = '===Portfolio==='

use1 = input.bool(true, '', inline='1', group=portfolioWatchlistGroup)
sym1 = input.symbol('FBMKLCI', '', inline='1', group=portfolioWatchlistGroup)
price1 = input.float(1, 'Price', inline='1', group=portfolioWatchlistGroup)
qty1 = input.int(1, 'QTY', inline='1', group=portfolioWatchlistGroup)

use2 = input.bool(false, '', inline='2', group=portfolioWatchlistGroup)
sym2 = input.symbol('', '', inline='2', group=portfolioWatchlistGroup)
price2 = input.float(0, 'Price', inline='2', group=portfolioWatchlistGroup)
qty2 = input.int(0, 'QTY', inline='2', group=portfolioWatchlistGroup)

use3 = input.bool(false, '', inline='3', group=portfolioWatchlistGroup)
sym3 = input.symbol('', '', inline='3', group=portfolioWatchlistGroup)
price3 = input.float(0, 'Price', inline='3', group=portfolioWatchlistGroup)
qty3 = input.int(0, 'QTY', inline='3', group=portfolioWatchlistGroup)

use4 = input.bool(false, '', inline='4', group=portfolioWatchlistGroup)
sym4 = input.symbol('', '', inline='4', group=portfolioWatchlistGroup)
price4 = input.float(0, 'Price', inline='4', group=portfolioWatchlistGroup)
qty4 = input.int(0, 'QTY', inline='4', group=portfolioWatchlistGroup)

use5 = input.bool(false, '', inline='5', group=portfolioWatchlistGroup)
sym5 = input.symbol('', '', inline='5', group=portfolioWatchlistGroup)
price5 = input.float(0, 'Price', inline='5', group=portfolioWatchlistGroup)
qty5 = input.int(0, 'QTY', inline='5', group=portfolioWatchlistGroup)


tableYpos = input.string('middle', '↕', inline='01', group=portfolioWatchlistGroup, options=['top', 'middle', 'bottom'])
tableXpos = input.string('right', '↔', inline='01', group=portfolioWatchlistGroup, options=['left', 'center', 'right'], tooltip='Position on the chart.')
tableRowHeight = input.int(0, '|', inline='02', group=portfolioWatchlistGroup, minval=0, maxval=100)
tableColWidth = input.int(0, '—', inline='02', group=portfolioWatchlistGroup, minval=0, maxval=100, tooltip='0-100. Use 0 to auto-size height and width.')
textSize_ = input.string('Small', 'Table Text Size', options=['Auto', 'Tiny', 'Small', 'Normal', 'Large', 'Huge'], group=portfolioWatchlistGroup)
textSize = textSize_ == 'Auto' ? size.auto : textSize_ == 'Tiny' ? size.tiny : textSize_ == 'Small' ? size.small : textSize_ == 'Normal' ? size.normal : textSize_ == 'Large' ? size.large : size.huge
row_col = input.color(color.blue, 'Headers', inline='03', group=portfolioWatchlistGroup)
col_col = input.color(color.blue, ' ', inline='03', group=portfolioWatchlistGroup)
poscol = input.color(color.green, 'Profit/Loss', inline='04', group=portfolioWatchlistGroup)
neutralcolor = input.color(color.gray, '', inline='04', group=portfolioWatchlistGroup)
negcol = input.color(color.red, '', inline='04', group=portfolioWatchlistGroup)


///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
///                 Calculation & Plotting & Alert                 ///
//////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////

// =====================
// ===Trend Indicator=== 
// =====================

string sector = bursa.getSector()
float currentClose = 0
float pastClose = 0

transportCurrentClose = request.security('MYX:TRANSPORTATION', trendRes, close)
transportPastClose = request.security('MYX:TRANSPORTATION', trendRes, close[1])

reitCurrentClose = request.security('MYX:REIT', trendRes, close)
reitPastClose = request.security('MYX:REIT', trendRes, close[1])  

utilityCurrentClose = request.security('MYX:UTILITIES', trendRes, close)
utilityPastClose = request.security('MYX:UTILITIES', trendRes, close[1])  

telcoCurrentClose = request.security('MYX:TELECOMMUNICATIONS', trendRes, close)
telcoPastClose = request.security('MYX:TELECOMMUNICATIONS', trendRes, close[1])  

healthCurrentClose = request.security('MYX:HEALTH', trendRes, close)
healthPastClose = request.security('MYX:HEALTH', trendRes, close[1])  

plantationCurrentClose = request.security('MYX:PLANTATION', trendRes, close)
plantationPastClose = request.security('MYX:PLANTATION', trendRes, close[1])  

propertyCurrentClose = request.security('MYX:PROPERTIES', trendRes, close)
propertyPastClose = request.security('MYX:PROPERTIES', trendRes, close[1])  

financeCurrentClose = request.security('MYX:FINANCE', trendRes, close)
financePastClose = request.security('MYX:FINANCE', trendRes, close[1])  

technologyCurrentClose = request.security('MYX:TECHNOLOGY', trendRes, close)
technologyPastClose = request.security('MYX:TECHNOLOGY', trendRes, close[1])  

industryCurrentClose = request.security('MYX:IND-PROD', trendRes, close)
industryPastClose = request.security('MYX:IND-PROD', trendRes, close[1])  

consumerCurrentClose = request.security('MYX:CONSUMER', trendRes, close)
consumerPastClose = request.security('MYX:CONSUMER', trendRes, close[1])

constructionCurrentClose = request.security('MYX:CONSTRUCTN', trendRes, close)
constructionPastClose = request.security('MYX:CONSTRUCTN', trendRes, close[1])  

energyCurrentClose = request.security('MYX:ENERGY', trendRes, close)
energyPastClose = request.security('MYX:ENERGY', trendRes, close[1])

klciCurrentClose = request.security('FBMKLCI', trendRes, close)
klciPastClose = request.security('FBMKLCI', trendRes, close[1])


if sector == 'MYX:TRANSPORTATION'
    currentClose := transportCurrentClose
    pastClose := transportPastClose
else if sector == 'MYX:REIT'
    currentClose := reitCurrentClose
    pastClose := reitPastClose
else if sector == 'MYX:UTILITIES'
    currentClose := utilityCurrentClose
    pastClose := utilityPastClose
else if sector == 'MYX:TELECOMMUNICATIONS'
    currentClose := telcoCurrentClose
    pastClose := telcoPastClose
else if sector == 'MYX:HEALTH'
    currentClose := healthCurrentClose
    pastClose := healthPastClose
else if sector == 'MYX:PLANTATION'
    currentClose := plantationCurrentClose
    pastClose := plantationPastClose
else if sector == 'MYX:PROPERTIES'
    currentClose := propertyCurrentClose
    pastClose := propertyPastClose
else if sector == 'MYX:FINANCE'
    currentClose := financeCurrentClose
    pastClose := financePastClose
else if sector == 'MYX:TECHNOLOGY'
    currentClose := technologyCurrentClose
    pastClose := technologyPastClose
else if sector == 'MYX:IND-PROD'
    currentClose := industryCurrentClose
    pastClose := industryPastClose
else if sector == 'MYX:CONSUMER'
    currentClose := consumerCurrentClose
    pastClose := consumerPastClose
else if sector == 'MYX:CONSTRUCTN'
    currentClose := constructionCurrentClose
    pastClose := constructionPastClose
else if sector == 'MYX:ENERGY'
    currentClose := energyCurrentClose
    pastClose := energyPastClose

upTrend = currentClose >= pastClose
downTrend = currentClose <= pastClose

klciUpTrend = klciCurrentClose >= klciPastClose
klciDownTrend = klciCurrentClose <= klciPastClose

plotshape(upTrend, 'Up Trend', style=shape.square, location=location.bottom, color=color.new(color.lime, 50), size=size.small)
plotshape(downTrend, 'Down Trend', style=shape.square, location=location.bottom, color=color.new(color.purple, 50), size=size.small)

plotshape(klciUpTrend, 'KLCI Up Trend', style=shape.square, location=location.top, color=color.new(color.blue, 50), size=size.small)
plotshape(klciDownTrend, 'KLCI Down Trend', style=shape.square, location=location.top, color=color.new(color.red, 50), size=size.small)

var table sectorTable = table.new(position.middle_left, 5, 1, border_width=1)

table.cell(sectorTable, 0, 0, text='MYX:FBMKLCI', width=10, bgcolor=color.new(color.gray,50), text_size=size.small, text_color=color.white)
table.cell(sectorTable, 1, 0, text=str.tostring(klciCurrentClose), width=10, bgcolor=color.new(klciUpTrend ? mainIndexUpColor : mainIndexDownColor, 50), text_size=size.small, text_color=color.white)

table.cell(sectorTable, 2, 0, text="", width=2, bgcolor=color.new(color.white, 50))

table.cell(sectorTable, 3, 0, text=sector, width=10, bgcolor=color.new(color.gray,50), text_size=size.small, text_color=color.white)
table.cell(sectorTable, 4, 0, text=str.tostring(currentClose), width=10, bgcolor=color.new(upTrend ? sectorUpColor : sectorDownColor, 50), text_size=size.small, text_color=color.white)


// ===============
// ===Portfolio=== 
// ===============

var table anan = table.new(tableYpos + '_' + tableXpos, 8, 11, border_width=2)
table.cell(anan, 0, 0, "Asset"         , text_color = col_col, bgcolor = color.new(col_col, 80), text_size = textSize, width= tableColWidth, height= tableRowHeight)
table.cell(anan, 1, 0, "Current Price"  , text_color = col_col, bgcolor = color.new(col_col, 80), text_size = textSize, width= tableColWidth, height= tableRowHeight)
table.cell(anan, 2, 0, "Cost Value"    , text_color = col_col, bgcolor = color.new(col_col, 80), text_size = textSize, width= tableColWidth, height= tableRowHeight)
table.cell(anan, 3, 0, "Holdings"      , text_color = col_col, bgcolor = color.new(col_col, 80), text_size = textSize, width= tableColWidth, height= tableRowHeight)
table.cell(anan, 4, 0, "Current Value" , text_color = col_col, bgcolor = color.new(col_col, 80), text_size = textSize, width= tableColWidth, height= tableRowHeight)
table.cell(anan, 5, 0, "Avg. Price"    , text_color = col_col, bgcolor = color.new(col_col, 80), text_size = textSize, width= tableColWidth, height= tableRowHeight)
table.cell(anan, 6, 0, "P/L"   , text_color = col_col, bgcolor = color.new(col_col, 80), text_size = textSize, width= tableColWidth, height= tableRowHeight)
table.cell(anan, 7, 0, "P/L %" , text_color = col_col, bgcolor = color.new(col_col, 80), text_size = textSize, width= tableColWidth, height= tableRowHeight)

getCurPrice(sym) =>
    request.security(sym, '12M', close)

getROC(sym) =>
    request.security(sym, '1D', ta.roc(close, 1))
    
curPrice1 = getCurPrice(sym1)
curPrice2 = getCurPrice(sym2)
curPrice3 = getCurPrice(sym3)
curPrice4 = getCurPrice(sym4)
curPrice5 = getCurPrice(sym5)


renderTable(cell, use, sym, qty, price) =>
    curPrice = switch cell
        1 => curPrice1
        2 => curPrice2
        3 => curPrice3
        4 => curPrice4
        5 => curPrice5
    roc = getROC(sym)
    if use
        table.cell(anan, 0, cell, sym,                                                              text_color=row_col, bgcolor =color.new(row_col, 80) , text_size =textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 1, cell, str.tostring(curPrice)+" ("+str.tostring(roc,"#.##") + "%)",               text_color = roc>0 ? poscol : roc<0 ? negcol : neutralcolor                                                , bgcolor = color.new(roc>0 ? poscol : roc<0 ? negcol : neutralcolor , 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 2, cell, str.tostring(price*qty),                                               text_color =(curPrice*qty)>(price*qty) ? poscol : (curPrice*qty)<(price*qty) ? negcol : neutralcolor       , bgcolor = color.new((curPrice*qty)>(price*qty) ? poscol : (curPrice*qty)<(price*qty) ? negcol : neutralcolor , 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 3, cell, str.tostring(qty),                                                     text_color=poscol                                                                                          , bgcolor = color.new(poscol , 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 4, cell, str.tostring(curPrice*qty),                                            text_color =(curPrice*qty)>(price*qty) ? poscol : (curPrice*qty)<(price*qty) ? negcol : neutralcolor       , bgcolor = color.new((curPrice*qty)>(price*qty) ? poscol : (curPrice*qty)<(price*qty) ? negcol : neutralcolor , 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 5, cell, str.tostring(price),                                                   text_color =curPrice>price ? poscol : curPrice<price ? negcol : neutralcolor                               , bgcolor = color.new(curPrice>price ? poscol : curPrice<price ? negcol : neutralcolor , 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 6, cell, str.tostring((curPrice*qty)-(price*qty)),                              text_color =(curPrice*qty)-(price*qty)>0 ? poscol : ((curPrice*qty)-(price*qty))<0 ? negcol : neutralcolor , bgcolor = color.new((curPrice*qty)-(price*qty)>0 ? poscol : ((curPrice*qty)-(price*qty))<0 ? negcol : neutralcolor , 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 7, cell, str.tostring(((curPrice*qty)-(price*qty))/(price*qty)*100,"#.##")+ "%",text_color =(curPrice*qty)-(price*qty)>0 ? poscol : ((curPrice*qty)-(price*qty))<0 ? negcol : neutralcolor , bgcolor = color.new((curPrice*qty)-(price*qty)>0 ? poscol : ((curPrice*qty)-(price*qty))<0 ? negcol : neutralcolor , 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)

renderTable(1 , use1,  sym1,  qty1,  price1)
renderTable(2 , use2,  sym2,  qty2,  price2)
renderTable(3 , use3,  sym3,  qty3,  price3)
renderTable(4 , use4,  sym4,  qty4,  price4)
renderTable(5 , use5,  sym5,  qty5,  price5)

float totalCost = 0
float totalCurrentValue = 0

if use1
    totalCost := totalCost + (price1 * qty1)
    totalCurrentValue := totalCurrentValue + (curPrice1*qty1)

if use2
    totalCost := totalCost + (price2 * qty2)
    totalCurrentValue :=  totalCurrentValue + (curPrice2*qty2)

if use3
    totalCost := totalCost + (price3 * qty3)
    totalCurrentValue := totalCurrentValue + (curPrice3*qty3)

if use4
    totalCost := totalCost + (price4 * qty4)
    totalCurrentValue := totalCurrentValue + (curPrice4*qty4)

if use5
    totalCost := totalCost + (price5* qty5)
    totalCurrentValue := totalCurrentValue + (curPrice5*qty5)

table.cell(anan, 0, 6, "Total", text_color = color.new(color.orange, 0), bgcolor=color.new(color.orange, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 1, 6, "", text_color = color.new(color.orange, 0), bgcolor=color.new(color.orange, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 2, 6, str.tostring(totalCost), text_color = color.new(color.orange, 0), bgcolor=color.new(color.orange, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 3, 6, "", text_color = color.new(color.orange, 0), bgcolor=color.new(color.orange, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 4, 6, str.tostring(totalCurrentValue), text_color = color.new(color.orange, 0), bgcolor=color.new(color.orange, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 5, 6, "", text_color = color.new(color.orange, 0), bgcolor=color.new(color.orange, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 6, 6, str.tostring(totalCurrentValue - totalCost), text_color = color.new(color.orange, 0), bgcolor=color.new(color.orange, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 7, 6, str.tostring(((totalCurrentValue - totalCost) / totalCost) * 100, "#.##")+ "%", text_color = color.new(color.orange, 0), bgcolor=color.new(color.orange, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)

