# Robert Bushre
# Date: 4/19/24
# Ver: 1
#
#Scripts are not guaranteed as to accuracy.
#
# Benjamin Graham's updated Intrinsic Value formula
# V = {EPS x (8.5 + 2g) x 4.4} / Y
#
# where:
#
# V: Intrinsic Value of the company,
# EPS: the company's last 12-month earnings per share,
# 8.5: the appropriate P-E ratio for a no-growth company as proposed by Graham,
# g: the company's long-term (five years) earnings growth estimate,
# 4.4: the average yield of high-grade corporate bonds,
# Y: the current yield on 20 year AAA corporate bonds.
#
# From what I have read the above formula is not considered a perdiction of
# a stocks future value. But as an indication of the Stocks fair value for
# the given nominal PE of 8.5, and twice the Historical Growth adjusted for current
# interest rates. I have choosen to change the 8.5 to using the stocks current PE.
# This seems to give a good indication if the stock current price is valued close
# to current interest rate given its Historical growth.
#
# I'm not a financial expert so take this with a grain salt, just one person idea.
#
# Note if TOS does not have a "By the Numbers" section under the Analize Tab, this
#Script can not get the past earnings.
#
#HINT: Benjamin Graham's updated Intrinsic Value formula \n V = {EPS x (8.5 + 2g) x 4.4} / Y \n \n where:\n \n <li> V: Intrinsic Value of the company,<li> EPS: the company's last 12-month earnings per share,<li> 8.5: the appropriate P-E ratio for a no-growth company as proposed by Graham,<li> g: the company's long-term (five years) earnings growth estimate,<li> 4.4: the average yield of high-grade corporate bonds,<li> Y: the current yield on 20 year AAA corporate bonds.\n \n From what I have read the above formula is not considered a perdiction of a stocks future value. But as an indication of the Stocks fair value for the given nominal PE of 8.5, and twice the Historical Growth adjusted for current interest rates. I have choosen to change the 8.5 to using the stocks current PE. This seems to give a good indication if the stock current price is valued close to current interest rate given its Historical growth. \n Scripts are not guaranteed as to accuracy.
#
#
#Hint label_color: Choose the color type that best fits your Light or Dark Scheme, the defaulr number 6 is a Lt Green in the Dark Scheme and Blue in the light Scheme \n <li> num = Dark - light <li> 0 = Magenta - Plum\n <li> 1 = Cyan - Dk Green <li> 2 = Pink - Lt Pink <li> 3 = Lr Gray - Lt Blue\n <li> 4 = Orange - Dk Orange <li> 5 = Lt Red - Red <li> 6 = Lt Green - Blue <li> 7 = Gray - Black\n <li> 8 = Lime - Violet <li> 9 = white - Dr Green
#
input label_color = { "0","1","2","3","4","5",default "6","7","8","9"};
#
# TNX symbol is for 10 year T-note
# TYX symbol is for 30 year T-Bond
# Since the TNX and TYX are no longer provided I added the "/10Y" and "/30Y" Futures.
#
# as of 7/23/24 there is new TNX as TNX:CGI and TYX as TYX:CGI, these also work now
# so I have added them.
#
input riskFreeRateOfReturnSymbol = {default "/10Y", "/30Y", "TYX:CGI","TNX:CGI"}; #Hint riskFreeRateOfReturnSymbol: This the symbol used to get the current interest Rate, the /10Y is used by default.
#
def RFV = if riskFreeRateOfReturnSymbol == riskFreeRateOfReturnSymbol."TYX:CGI" or riskFreeRateOfReturnSymbol == riskFreeRateOfReturnSymbol."TNX:CGI" then close(riskFreeRateOfReturnSymbol)/10 else close(riskFreeRateOfReturnSymbol);
#
input aaa_bond_Rate = 4.99; #Hint aaa_bond_rate: This is the AAA 20 year Bond Rate and can be retrived from the AAA:FRED value.
#
input Growth_multiplier = 2; #Hint Growth_Multiplier: This is a number used to Multiply the Growth by, the Ben Graham formula uses 2 by default.
#
def m = Growth_multiplier; # just to make the formula below smaller
#
Declare Once_per_bar;
#
def IsDaily = GetAggregationPeriod() == AggregationPeriod.DAY ;
def yearstart = getyear() * 10000 + 101;
def tradedays = countTradingDays(yearstart, GetYYYYMMDD());
#
def HGCB = RFV + 1.2; #Adjust for closer match to High Grade Corp. Bond rate.
#
#current Earnings
def AE = if IsNaN(GetActualEarnings()) then 0 else GetActualEarnings();
def EPS = Sum(AE, 252);
#
# Current Price to Earnings
def PE = close / EPS;
#
#
# GetActualEarnings Growth for last Recorded Year and Fifth Year ago, if N/A then go one year right of five and one year left of Last.
#
def Last_year_EPSTTM = if IsNan(Getvalue(EarningsPerShareTTM(),tradedays,1265)) then Getvalue(EarningsPerShareTTM(),tradedays+252,1265) else Getvalue(EarningsPerShareTTM(),tradedays,1265) ;
#
def five_year_ago_EPSTTM = if IsNan(Getvalue(EarningsPerShareTTM(),tradedays+1008,1265)) then Getvalue(EarningsPerShareTTM(),tradedays+756,1265) else Getvalue(EarningsPerShareTTM(),tradedays+1008,1265) ;
#
# Calculate the Growth value
def Growth = Round((Last_year_EPSTTM - five_year_ago_EPSTTM)/Last_year_EPSTTM,2);
#
#
# Benjamin Graham's updated Intrinsic Value formula
# V = {EPS x (PE + 2g) x HGCB} / AAA
#
def V = Round((EPS * (PE + m*Growth) * HGCB) / aaa_bond_Rate,2);
#
# Negative EPS signal
def Neps = if IsNaN(EPS) then 1 else if EPS < 0 then 1 else 0;
#
# Close percent below or above Formula Value
Def diffPct = Round((Close / v) - 1);
#
# Label for on chart
#
Addlabel(V > 0 ,"Ben Graham Value = "+AsPrice(V)+", diff "+AsPercent(diffPct),getcolor(label_color));
Addlabel(IsNaN(Growth) or EPS == 0 ,"Ben Graham Value -"+ if IsNaN(Growth) and EPS == 0 then " No Growth calculation and No Current earnings value" else if IsNan(Growth) then " No Growth calculation" else if EPS == 0 then "No Current earnings value" else "" ,getcolor(label_color));
AddLabel(V < 0,"Ben Graham Value is negative value"+ if Neps then " for EPS" else "" ,getcolor(label_color));
Addlabel(IsNan(Close(riskFreeRateOfReturnSymbol)),"Ben Graham Value "+riskFreeRateOfReturnSymbol+" is not Seen",getcolor(label_color));
#
#
#
#END Script