ValueBands for Acceptable P/E/ and P/B
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © NatsukiKano

//@version=5

// # What's this script?
// - Plot of BookValue and TangibleBookValue
// - Visualization of Price Bands for Acceptable P/E and P/B
// - Adaptation to Currency Change
// - Combine long term financial data and short term financial data
// - 2023/01/23:Set timeframe="W" for stable loading of financial data.

indicator(title="ValueBands for Acceptable P/E/ and P/B",shorttitle="ValueBands",timeframe="W" ,format= format.price, precision=0, overlay=true)

// ====================
// PRE
// ====================

// <import_statements>
// --------------------
Group1 ="Acceptable Ratio"
AcceptablePERatio   = input(15.0    , "Price per Earnings"          , group = Group1)
AcceptablePBRatio   = input(1.5     , "Price per BookValue"         , group = Group1)
AcceptablePTBRatio  = input(1.5     , "Price per TangibleBookValue" , group = Group1)

Group2 ="Line Color"
ColorBookValue          = input(color.new(color.teal ,10)   , "BookValue"                       , group = Group2)
ColorTangibleBookValue  = input(color.new(color.navy,10)    , "TangibleBookValue"               , group = Group2)
ColorAcceptablePE       = input(color.new(color.orange,10)  , "P/E"                             , group = Group2)
ColorAcceptablePB       = input(color.new(color.blue,10)    , "P/B"                             , group = Group2)
ColorAcceptablePTB      = input(color.new(color.navy,10)    , "P/TB"                            , group = Group2)
ColorGeometricMean      = input(color.new(color.silver,10)  , "GeometricMean of P/E and P/B"    , group = Group2)
FillingTransparency     = input(95, "FillingTransparency" , group = Group2)

// <request>
// --------------------
EPS_Y   = request.financial(syminfo.tickerid    , "EARNINGS_PER_SHARE"      , "FY"  , barmerge.gaps_off , false , syminfo.currency)
EPS_TTM = request.financial(syminfo.tickerid    , "EARNINGS_PER_SHARE"      , "TTM" , barmerge.gaps_off , false , syminfo.currency)
BVPS_Y  = request.financial(syminfo.tickerid    , "BOOK_VALUE_PER_SHARE"    , "FY"  , barmerge.gaps_off , false , syminfo.currency)
BVPS_Q  = request.financial(syminfo.tickerid    , "BOOK_VALUE_PER_SHARE"    , "FQ"  , barmerge.gaps_off , false , syminfo.currency)
TBPS_Y  =  request.financial(syminfo.tickerid   , "BOOK_TANGIBLE_PER_SHARE" , "FY"  , barmerge.gaps_off , false , syminfo.currency)
TBPS_Q  =  request.financial(syminfo.tickerid   , "BOOK_TANGIBLE_PER_SHARE" , "FQ"  , barmerge.gaps_off , false , syminfo.currency)

// ====================
// Calc.
// ====================

// Combine long term financial data and short term financial data
// --------------------
EPS     = EPS_TTM ? EPS_TTM : EPS_Y
BVPS    = BVPS_Q ? BVPS_Q : BVPS_Y
TBPS    = TBPS_Q ? TBPS_Q : TBPS_Y

// Acceptable Price
// --------------------
APE     = math.max(0, AcceptablePERatio * EPS)
APB     = math.max(0, AcceptablePBRatio * BVPS)
APTB    = math.max(0, AcceptablePTBRatio * TBPS)

// Geometric mean of Acceptable Prices
// if APE15 & APB1.5 then  GM_APE_APB=GrahamNumber 
// --------------------
GM_APE_APB    = math.sqrt( APE * APB )
GM_APE_APTB   = math.sqrt( APE * APTB )

// ====================
// POST
// ====================

// Draw BookValue and TangibleBookValue
// --------------------
lineTBV     = plot( TBPS    , "TangibleBookValue"   , ColorTangibleBookValue    , linewidth = 2)
lineBV      = plot( BVPS    , "BookValue"           , ColorBookValue            , linewidth = 2)
fill(lineBV     ,lineTBV    ,color.new(ColorTangibleBookValue,FillingTransparency), title="Area:BV-TBV",fillgaps=true)

// Draw Acceptable Price Band
// --------------------
lineATPB    = plot( APTB        , "Acceptable P/TB"                    , ColorAcceptablePTB        , linewidth = 1)
lineAPB     = plot( APB         , "Acceptable P/B"                     , ColorAcceptablePB         , linewidth = 1)
lineAPE     = plot( APE         , "Acceptable P/E"                     , ColorAcceptablePE         , linewidth = 2)
lineGN      = plot( GM_APE_APB  , "GeometricMean(APE&APB)"  , ColorGeometricMean        , linewidth = 1)
lineGNTBV   = plot( GM_APE_APTB , "GeometricMean(APE&APTB)" , ColorGeometricMean        , linewidth = 1)
fill(lineAPB    ,lineAPE    ,color=color.new(APB > APE ? ColorAcceptablePB : ColorAcceptablePE ,FillingTransparency), title="Area:PE-PB",fillgaps=true)
