#L1 Intro
library(quantmod)
library(xts)
library(zoo)
library(dplyr)
start_date <- as.Date("2023-05-01")
end_date <- as.Date("2023-09-30")
table_data <- data.frame(
Category = character(),
Beginning_of_Term = character(),
End_of_Term = character(),
Value_Beg = character(),
Value_End = character(),
stringsAsFactors = FALSE
)
add_row <- function(category, value_beg, value_end = "") {
if (!is.null(value_beg) && !is.na(value_beg) && value_beg != "") {
value_beg_formatted <- format(value_beg, scientific = FALSE, trim = TRUE)
value_end_formatted <- format(value_end, scientific = FALSE, trim = TRUE)
new_row <- data.frame(
Category = category,
Beginning_of_Term = format(start_date, "%d %B %Y"),
End_of_Term = format(end_date, "%d %B %Y"),
Value_Beg = value_beg_formatted,
Value_End = value_end_formatted,
stringsAsFactors = FALSE
)
table_data <<- rbind(table_data, new_row) # Update the global table_data
} else {
cat("Warning: Data for", category, "is missing or incomplete.\n")
}
}
get_symbol_data <- function(symbol, src, from, to) {
tryCatch({
data <- getSymbols(symbol, src = src, from = from, to = to, auto.assign = FALSE, warnings = FALSE)
if (is.null(data) || nrow(data) == 0) {
warning(paste("No data returned for symbol:", symbol))
return(NULL)
}
return(data)
}, error = function(e) {
warning(paste("Error fetching data for symbol:", symbol, "-", e$message))
return(NULL)
})
}
update_data <- function() { ### Fetch S&P 500 and Nasdaq data
sp500_data <- get_symbol_data("^GSPC", "yahoo", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: ^GSPC - could not
## find function "getSymbols"
nasdaq_data <- get_symbol_data("^IXIC", "yahoo", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: ^IXIC - could not
## find function "getSymbols"
if (!is.null(sp500_data)) {
sp500_open <- round(as.numeric(first(Op(sp500_data))), 2)
sp500_close <- round(as.numeric(last(Cl(sp500_data))), 2)
add_row("S&P 500 Index Level", sp500_open, sp500_close)
}
if (!is.null(nasdaq_data)) {
nasdaq_open <- round(as.numeric(first(Op(nasdaq_data))), 2)
nasdaq_close <- round(as.numeric(last(Cl(nasdaq_data))), 2)
add_row("Nasdaq Composite Index Level", nasdaq_open, nasdaq_close)
}
prime_rate <- get_symbol_data("DPRIME", "FRED", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: DPRIME - could
## not find function "getSymbols"
fed_funds_rate <- get_symbol_data("FEDFUNDS", "FRED", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: FEDFUNDS - could
## not find function "getSymbols"
commercial_paper_rate <- get_symbol_data("DCPN3M", "FRED", start_date, end_date) # 3-Month Nonfinancial Commercial Paper Rate
## Warning in value[[3L]](cond): Error fetching data for symbol: DCPN3M - could
## not find function "getSymbols"
cd_rate <- get_symbol_data("TB3MS", "FRED", start_date, end_date) # 3-Month Treasury Bill Secondary Market Rate
## Warning in value[[3L]](cond): Error fetching data for symbol: TB3MS - could not
## find function "getSymbols"
tbill_13wk <- get_symbol_data("DTB3", "FRED", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: DTB3 - could not
## find function "getSymbols"
tbill_26wk <- get_symbol_data("DTB6", "FRED", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: DTB6 - could not
## find function "getSymbols"
if (!is.null(prime_rate)) {
add_row("Prime Rate", round(as.numeric(first(prime_rate)), 2), round(as.numeric(last(prime_rate)), 2))
}
if (!is.null(fed_funds_rate)) {
add_row("Federal Funds Rate", round(as.numeric(first(fed_funds_rate)), 2), round(as.numeric(last(fed_funds_rate)), 2))
}
if (!is.null(commercial_paper_rate)) {
add_row("Commercial Paper Rate (90 days)", round(as.numeric(first(commercial_paper_rate)), 2), round(as.numeric(last(commercial_paper_rate)), 2))
}
if (!is.null(cd_rate)) {
add_row("Certificate of Deposit Rate (3-month)", round(as.numeric(first(cd_rate)), 2), round(as.numeric(last(cd_rate)), 2))
}
if (!is.null(tbill_13wk)) {
add_row("Treasury Bill Rate (13 weeks)", round(as.numeric(first(tbill_13wk)), 2), round(as.numeric(last(tbill_13wk)), 2))
}
if (!is.null(tbill_26wk)) {
add_row("Treasury Bill Rate (26 weeks)", round(as.numeric(first(tbill_26wk)), 2), round(as.numeric(last(tbill_26wk)), 2))
}
treasury_long_term_yield <- get_symbol_data("GS10", "FRED", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: GS10 - could not
## find function "getSymbols"
corporate_bond_yield <- get_symbol_data("BAA", "FRED", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: BAA - could not
## find function "getSymbols"
high_yield_bond_yield <- get_symbol_data("BAMLH0A0HYM2EY", "FRED", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: BAMLH0A0HYM2EY -
## could not find function "getSymbols"
if (!is.null(treasury_long_term_yield)) {
add_row("Treasury Long-term Bond Yield", round(as.numeric(first(treasury_long_term_yield)), 2), round(as.numeric(last(treasury_long_term_yield)), 2))
}
if (!is.null(corporate_bond_yield)) {
add_row("Corporate (Master) Bond Yield", round(as.numeric(first(corporate_bond_yield)), 2), round(as.numeric(last(corporate_bond_yield)), 2))
}
if (!is.null(high_yield_bond_yield)) {
add_row("High-yield Corporate Bond Yield", round(as.numeric(first(high_yield_bond_yield)), 2), round(as.numeric(last(high_yield_bond_yield)), 2))
}
gbp_usd <- get_symbol_data("GBPUSD=X", "yahoo", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: GBPUSD=X - could
## not find function "getSymbols"
jpy_usd <- get_symbol_data("JPYUSD=X", "yahoo", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: JPYUSD=X - could
## not find function "getSymbols"
mxn_usd <- get_symbol_data("MXNUSD=X", "yahoo", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: MXNUSD=X - could
## not find function "getSymbols"
if (!is.null(gbp_usd)) {
gbp_beg <- round(as.numeric(first(Cl(gbp_usd))), 4)
gbp_end <- round(as.numeric(last(Cl(gbp_usd))), 4)
add_row("Exchange Rate of the British Pound (in $)", gbp_beg, gbp_end)
}
if (!is.null(jpy_usd)) {
jpy_beg <- round(as.numeric(first(Cl(jpy_usd))), 6)
jpy_end <- round(as.numeric(last(Cl(jpy_usd))), 6)
add_row("Exchange Rate of the Japanese Yen (in $)", jpy_beg, jpy_end)
}
if (!is.null(mxn_usd)) {
mxn_beg <- round(as.numeric(first(Cl(mxn_usd))), 6)
mxn_end <- round(as.numeric(last(Cl(mxn_usd))), 6)
add_row("Exchange Rate of the Mexican Peso (in $)", mxn_beg, mxn_end)
}
treasury_futures <- get_symbol_data("ZB=F", "yahoo", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: ZB=F - could not
## find function "getSymbols"
if (!is.null(treasury_futures)) {
treasury_beg <- round(as.numeric(first(Cl(treasury_futures))), 2)
treasury_end <- round(as.numeric(last(Cl(treasury_futures))), 2)
add_row("Treasury Bond Futures", treasury_beg, treasury_end)
}
sp500_futures <- get_symbol_data("ES=F", "yahoo", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: ES=F - could not
## find function "getSymbols"
if (!is.null(sp500_futures)) {
sp500_fut_beg <- round(as.numeric(first(Cl(sp500_futures))), 2)
sp500_fut_end <- round(as.numeric(last(Cl(sp500_futures))), 2)
add_row("S&P 500 Index Futures", sp500_fut_beg, sp500_fut_end)
}
bp_futures <- get_symbol_data("6B=F", "yahoo", start_date, end_date)
## Warning in value[[3L]](cond): Error fetching data for symbol: 6B=F - could not
## find function "getSymbols"
if (!is.null(bp_futures)) {
bp_fut_beg <- round(as.numeric(first(Cl(bp_futures))), 4)
bp_fut_end <- round(as.numeric(last(Cl(bp_futures))), 4)
add_row("British Pound Futures", bp_fut_beg, bp_fut_end)
}
call_option_firm <- "AAPL"
call_option_expiration <- "2024-12-20"
call_option_strike <- 150 # Example strike price
call_option_premium <- 10 # Example premium
firm_data <- get_symbol_data(call_option_firm, "yahoo", Sys.Date() - 10, Sys.Date() - 1)
## Warning in value[[3L]](cond): Error fetching data for symbol: AAPL - could not
## find function "getSymbols"
if (!is.null(firm_data)) {
current_price <- round(as.numeric(last(Cl(firm_data))), 2)
} else {
current_price <- "N/A"
}
add_row(paste("Call Option on", call_option_firm, "- Stock Price"), current_price)
add_row(paste("Call Option on", call_option_firm, "- Option Premium"), call_option_premium)
add_row(paste("Call Option on", call_option_firm, "- Strike Price"), call_option_strike)
add_row(paste("Call Option on", call_option_firm, "- Expiration"), call_option_expiration)
put_option_firm <- "INTC"
put_option_expiration <- "2024-12-20"
put_option_strike <- 50
put_option_premium <- 0.0005
firm_data <- get_symbol_data(put_option_firm, "yahoo", Sys.Date() - 10, Sys.Date() - 1)
## Warning in value[[3L]](cond): Error fetching data for symbol: INTC - could not
## find function "getSymbols"
if (!is.null(firm_data)) {
current_price <- round(as.numeric(last(Cl(firm_data))), 2)
} else {
current_price <- "N/A"
}
add_row(paste("Put Option on", put_option_firm, "- Stock Price"), current_price)
add_row(paste("Put Option on", put_option_firm, "- Option Premium"), put_option_premium)
add_row(paste("Put Option on", put_option_firm, "- Strike Price"), put_option_strike)
add_row(paste("Put Option on", put_option_firm, "- Expiration"), put_option_expiration)
currency_call = "Euro (EURUSD)"
currency_call_expiration = "2024-12-20"
currency_call_strike = 1.20
currency_call_premium = 0.05
eurusd_data <- get_symbol_data("EURUSD=X", "yahoo", Sys.Date() - 10, Sys.Date() - 1)
## Warning in value[[3L]](cond): Error fetching data for symbol: EURUSD=X - could
## not find function "getSymbols"
if (!is.null(eurusd_data)) {
eurusd_price <- round(as.numeric(last(Cl(eurusd_data))), 4)
} else {
eurusd_price <- "N/A"
}
add_row(paste("Call Option on", currency_call, "- Currency Value"), eurusd_price)
add_row(paste("Call Option on", currency_call, "- Option Premium"), currency_call_premium)
add_row(paste("Call Option on", currency_call, "- Strike Price"), currency_call_strike)
add_row(paste("Call Option on", currency_call, "- Expiration"), currency_call_expiration)
currency_put = "Japanese Yen (JPYUSD)"
currency_put_expiration = "2024-12-20"
currency_put_strike = 0.0090
currency_put_premium = 0.0005
jpyusd_data <- get_symbol_data("JPYUSD=X", "yahoo", Sys.Date() - 10, Sys.Date() - 1)
## Warning in value[[3L]](cond): Error fetching data for symbol: JPYUSD=X - could
## not find function "getSymbols"
if (!is.null(jpyusd_data)) {
jpyusd_price <- round(as.numeric(last(Cl(jpyusd_data))), 6)
} else {
jpyusd_price <- "N/A"
}
add_row(paste("Put Option on", currency_put, "- Currency Value"), jpyusd_price)
add_row(paste("Put Option on", currency_put, "- Option Premium"), currency_put_premium)
add_row(paste("Put Option on", currency_put, "- Strike Price"), currency_put_strike)
add_row(paste("Put Option on", currency_put, "- Expiration"), currency_put_expiration)
print(table_data, right = FALSE)
## Category Beginning_of_Term
## 1 Call Option on AAPL - Stock Price 01 May 2023
## 2 Call Option on AAPL - Option Premium 01 May 2023
## 3 Call Option on AAPL - Strike Price 01 May 2023
## 4 Call Option on AAPL - Expiration 01 May 2023
## 5 Put Option on INTC - Stock Price 01 May 2023
## 6 Put Option on INTC - Option Premium 01 May 2023
## 7 Put Option on INTC - Strike Price 01 May 2023
## 8 Put Option on INTC - Expiration 01 May 2023
## 9 Call Option on Euro (EURUSD) - Currency Value 01 May 2023
## 10 Call Option on Euro (EURUSD) - Option Premium 01 May 2023
## 11 Call Option on Euro (EURUSD) - Strike Price 01 May 2023
## 12 Call Option on Euro (EURUSD) - Expiration 01 May 2023
## 13 Put Option on Japanese Yen (JPYUSD) - Currency Value 01 May 2023
## 14 Put Option on Japanese Yen (JPYUSD) - Option Premium 01 May 2023
## 15 Put Option on Japanese Yen (JPYUSD) - Strike Price 01 May 2023
## 16 Put Option on Japanese Yen (JPYUSD) - Expiration 01 May 2023
## End_of_Term Value_Beg Value_End
## 1 30 September 2023 N/A
## 2 30 September 2023 10
## 3 30 September 2023 150
## 4 30 September 2023 2024-12-20
## 5 30 September 2023 N/A
## 6 30 September 2023 0.0005
## 7 30 September 2023 50
## 8 30 September 2023 2024-12-20
## 9 30 September 2023 N/A
## 10 30 September 2023 0.05
## 11 30 September 2023 1.2
## 12 30 September 2023 2024-12-20
## 13 30 September 2023 N/A
## 14 30 September 2023 0.0005
## 15 30 September 2023 0.009
## 16 30 September 2023 2024-12-20
#L.5 Financial statements and fundamental analysis
library(readxl)
library(edgar)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following object is masked _by_ '.GlobalEnv':
##
## add_row
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr)
library(finreportr)
options(HTTPUserAgent = "igordros@icloud.com")
Financial_Report_Microsoft <- read_excel(“Financial_Report.xlsx”)
Financial_Report <- read_excel(“Financial_Report.xlsx”)
View(Financial_Report)
BankofAmerica <- GetBalanceSheet('BAC', 2018)
This Bank has the most of its funds because of firstly: interest bearing deposits, then non-interest bearing deposits, then interest bearing deposits (foreign), and lastly non-interest bearing deposits (foreign)
Bank mainly invests in federal funds and securities. From Consolidated balance sheet from edgar sec (261,131 million of $ worth of sold securities)
I believe that the bank already sells securities as we can see in ‘Notes to financial statements’ under ‘securities’ they offer various securities. And there are securities for sale so Bank of America does not want to enter the securities market, because it is already in it.
Bank of America offers various types of insurances. You can find them in the Financial statement as well.
Bank of America has a significant part of its assets in loans and leases which very often have variable rates. Bank earns on any interest rate rise. On the other side, bank has interest bearing deposits but they mostly have fixed rates. Therefore, I believe that Bank of America has a positive gap between rate-sensitive assets and liabilities.
All of the data are taken from official edgar sec page from 10-k Annual Financial statements.
total_assets <- 2354507000000 # 2,354,507 million USD
total_interest_income <- 66769000000 # 66,769 million USD
interest_income_percentage <- (total_interest_income / total_assets) * 100
Total Assets from ‘Consolidated Balance sheet’ Total interest income from ‘Consolidated Statement of Income’ Percentage = (66,769,000,000 / 2,354,507,000,000) * 100% = interest_income_percentage
total_interest_expense <- 19337000000 # 19,337 million USD
interest_expense_percentage <- (total_interest_expense / total_assets) * 100
Total interest expense from ‘Consolidated Statement of Income’ Percentage = (19,337,000,000 / 2,354,507,000,000) * 100% = interest_expense_percentage
net_interest_income <- 47432000000 # 47,432 million USD
average_earning_assets <- (2354507000000 + 2281234000000) / 2 # Average of Total Assets for 2017 and 2018
net_interest_margin <- (net_interest_income / average_earning_assets) * 100
Net interest income from ‘Consolidated Statement of Income’ Average earning assets = (2,354,507,000,000 + 2,281,234,000,000) / 2 Net interest margin = (47,432,000,000 / 2,317,870,500,000) * 100% = net_interest_margin
total_non_interest_income <- 43815000000 # 43,815 million USD
non_interest_income_percentage <- (total_non_interest_income / total_assets) * 100
total_non_interest_expense <- 53381000000 # 53,381 million USD
non_interest_expense_percentage <- (total_non_interest_expense / total_assets) * 100
Total non-interest income from ‘Consolidated Statement of Income’ Total non-interest expense from ‘Consolidated Statement of Income’ Percentage of income = (43,815,000,000 / 2,354,507,000,000) * 100% = non_interest_income_percentage Percentage of expense = (53,381,000,000 / 2,354,507,000,000) * 100% = non_interest_expense_percentage
Provision for credit losses = 3,282 million USD Total Assets = 2,354,507 million USD Percentage = (3,282,000,000 / 2,354,507,000,000) * 100% = 0.14%
Net income from ‘Consolidated Statement of Income’ = 28,147 million USD Total Assets from ‘Consolidated Balance Sheet’ = 2,354,507 million USD Percentage = (28,147,000,000 / 2,354,507,000,000) * 100% = 1.2%
Interest income – positive impact, because bank would earn more on loans and investments.
Provision for credit losses – as the market condition worsens, bank’s risk on loans and credit losses increases, so the bank needs to increase its provision for losses on the loans which would decrease the demand for those services.
The S&P 500 mutual fund is a moderate risk investment due to its diversification across 500 large companies.
Return for year 2023 = 26.29% Average return from the last 3 years = (26.29 - 18.11 + 28.71) / 3 = 12.3%
S&P 500 is heavily influenced by fluctuations of stocks of companies included in S&P 500. It is highly dependent on stock market conditions.
Vanguard charges $25 for each brokerage account and 0.25% to 1% of transaction value depending on the amount.
The expense ratio is 0.04 = 4%. You can see this on the Vanguard website.
Securities firms offer a wide range of financial services including trading, investment banking, asset management, wealth management, etc. cat(“These companies serve individuals and companies by being an intermediary between buyer and seller on the financial market.
In their Financial statement in Part 1, Item 1A, Risk Factors, JP Morgan stated: Regulatory risks, including the impact that applicable laws, rules, and regulations in the highly-regulated and supervised financial services industry, as well as changes to or in the application, interpretation or enforcement of those laws, rules and regulations, can have on JPMorgan Chase’s business and operations.
JP Morgan’s performance in 2024 has been extremely successful due to many factors such as: rising interest rates which increase their margin on loans; high activity in financial markets; good revenues from branches like wealth management or investment banking and strong economic growth.
#L.10 WACC
WACC (weighted average cost of capital) - can be measured at market values and accounting values. You cannot mix them up. They are completely different in a way for counting, so if you mix them up you will get incorrect result that may be misleading. At market values you need both equity and debt of company and the cost of equity and the cost of debt. This measure tells the investors the rate of return they might expect with how much risk they would bare on their investment.
Example:
library(quantmod)
## Loading required package: xts
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
##
## ######################### Warning from 'xts' package ##########################
## # #
## # The dplyr lag() function breaks how base R's lag() function is supposed to #
## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #
## # source() into this session won't work correctly. #
## # #
## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #
## # dplyr from breaking base R's lag() function. #
## # #
## # Code in packages is not affected. It's protected by R's namespace mechanism #
## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #
## # #
## ###############################################################################
##
## Attaching package: 'xts'
## The following objects are masked from 'package:dplyr':
##
## first, last
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
options(HTTPUserAgent = "igordros@icloud.com")
getSymbols("MSFT")
## [1] "MSFT"
outstanding_shares <- 30000000 # Number of outstanding shares
market_cap <- last(MSFT$MSFT.Adjusted) * outstanding_shares
cost_of_debt <- 0.03 # 3%
tax_rate <- 0.25 # 25%
beta <- 1.1 # Beta of Microsoft's stock
risk_free_rate <- 0.02 # 2% risk-free rate
market_risk_premium <- 0.06 # 6% market risk premium
market_value_of_debt <- 100e9 # $100 billion
cost_of_equity <- risk_free_rate + beta * market_risk_premium
total_market_value <- market_cap + market_value_of_debt
weight_of_debt <- market_value_of_debt / total_market_value
weight_of_equity <- market_cap / total_market_value
wacc <- (weight_of_debt * cost_of_debt * (1 - tax_rate)) + (weight_of_equity * cost_of_equity)
cat("WACC for Microsoft:", wacc * 100, "%\n")
## WACC for Microsoft: 2.967816 %