L2 Financial Markets Microstructure
Compare your national country local exchange index with US or London.
Install the necessary packages
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
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(zoo)
Let’s compare the S&P 500 and Singapore Exchange Index.
#Download historical data for S&P 500 and Singapore Exchange Index
getSymbols("^GSPC", src = "yahoo") # S&P 500
## [1] "GSPC"
getSymbols("^STI", src = "yahoo") # Straits Times Index (SGX)
## Warning: ^STI contains missing values. Some functions will not work if objects
## contain missing values in the middle of the series. Consider using na.omit(),
## na.approx(), na.fill(), etc to remove or replace them.
## [1] "STI"
The data from 1 January 2010 to 1 January 2023 will be trimmed and cleaned.
# Fill in NA with an approximation data
STI <- na.approx(STI)
# Fill in NA with an approximation data
STI <- na.approx(STI)
# Trim data for the comparison period
start_date <- "2010-01-01"
end_date <- "2023-01-01"
GSPC <- subset(GSPC, index(GSPC) >= start_date & index(GSPC) <= end_date)
STI <- subset(STI, index(STI) >= start_date & index(STI) <= end_date)
# Check if the data is well trimmed
print(GSPC[rownames(GSPC) >= "2010-01-01" & rownames(GSPC) <= "2010-01-02", ])
## GSPC.Open GSPC.High GSPC.Low GSPC.Close GSPC.Volume GSPC.Adjusted
print(STI[rownames(STI) >= "2010-01-01" & rownames(STI) <= "2010-01-02", ])
## STI.Open STI.High STI.Low STI.Close STI.Volume STI.Adjusted
# Merge the datasets
aligned_data <- merge(GSPC, STI)
# Remove missing values
cleaned_data <- na.omit(aligned_data)
After data is cleanned and trimmed, we can now compare the statistics between the S&P 500 and Singapore Exchange Index
# Calculate statistics for S&P 500
nasdaq_stats <- c(mean(GSPC[, 4], na.rm = TRUE),
median(GSPC[, 4], na.rm = TRUE),
sd(GSPC[, 4], na.rm = TRUE))
# Calculate statistics for Singapore Exchange (SGX)
sgx_stats <- c(mean(STI[, 4], na.rm = TRUE),
median(STI[, 4], na.rm = TRUE),
sd(STI[, 4], na.rm = TRUE))
# Calculate Coefficient of Variation for S&P 500 and SGX
cv_nasdaq <- nasdaq_stats[3] / nasdaq_stats[1] * 100
cv_sgx <- sgx_stats[3] / sgx_stats[1] * 100
# Add Coefficient of Variation to statistics
nasdaq_stats <- c(nasdaq_stats, cv_nasdaq)
sgx_stats <- c(sgx_stats, cv_sgx)
# Combine statistics into a single data frame
stats_comparison <- rbind(nasdaq_stats, sgx_stats)
# Name the columns
colnames(stats_comparison) <- c("Mean", "Median", "Standard Deviation", "Coefficient of Variation")
# Name the rows
rownames(stats_comparison) <- c("S&P 500", "Singapore Exchange (SGX)")
# Print the rounded result
print(round(stats_comparison, 2))
## Mean Median Standard Deviation
## S&P 500 2401.49 2125.03 988.94
## Singapore Exchange (SGX) 3093.40 3139.98 236.20
## Coefficient of Variation
## S&P 500 41.18
## Singapore Exchange (SGX) 7.64
As the S&P 500 has a coefficient of variation that is almost 4 times that of the SGX, we can conclude that the S&P 500 is more volatile and riskier than the SGX. A higher coefficient of variation reflects greater uncertainty in the S&P 500’s performance, meaning that its returns are more likely to deviate from its average value. Investors in the S&P 500 can expect larger deviations from the mean, either in the form of large gains or significant losses. SGX’s lower coefficient of variation implies greater stability and predictability in its returns. It is less volatile, making it a safer choice for investors who prioritize consistent performance and are risk-averse. Investors should assess their risk tolerance when choosing between these indices. If an investor prefers higher potential returns and is comfortable with more volatility, the S&P 500 might be more appealing. Conversely, if an investor prefers stability and lower volatility, the SGX might be a better option.
Let us compare the cumulative returns between the S&P 500 and SGX from 2010 to 2023.
# Check the first few rows to verify data
head(GSPC)
## GSPC.Open GSPC.High GSPC.Low GSPC.Close GSPC.Volume GSPC.Adjusted
## 2010-01-04 1116.56 1133.87 1116.56 1132.99 3991400000 1132.99
## 2010-01-05 1132.66 1136.63 1129.66 1136.52 2491020000 1136.52
## 2010-01-06 1135.71 1139.19 1133.95 1137.14 4972660000 1137.14
## 2010-01-07 1136.27 1142.46 1131.32 1141.69 5270680000 1141.69
## 2010-01-08 1140.52 1145.39 1136.22 1144.98 4389590000 1144.98
## 2010-01-11 1145.96 1149.74 1142.02 1146.98 4255780000 1146.98
head(STI)
## STI.Open STI.High STI.Low STI.Close STI.Volume STI.Adjusted
## 2010-01-04 2897.62 2897.62 2886.43 2894.55 0 2894.55
## 2010-01-05 2894.55 2923.91 2894.55 2920.28 0 2920.28
## 2010-01-06 2920.28 2937.98 2919.74 2930.49 0 2930.49
## 2010-01-07 2930.49 2945.06 2901.24 2913.25 0 2913.25
## 2010-01-08 2913.25 2932.72 2909.41 2922.76 0 2922.76
## 2010-01-11 2922.76 2947.08 2922.76 2933.53 0 2933.53
First, we calculate the daily returns of S&P500 and SGX.
# Calculate daily returns for both indices
GSPC_returns <- dailyReturn(GSPC)
STI_returns <- dailyReturn(STI)
Next, we calculate the cumulative returns of S&P500 and SGX.
# Calculate cumulative returns
GSPC_cumulative_returns <- cumsum(GSPC_returns)
STI_cumulative_returns <- cumsum(STI_returns)
Finally, we can compare them with a line graph.
plot(index(GSPC_cumulative_returns), GSPC_cumulative_returns, type = "l", col = "blue",
xlab = "Date", ylab = "Cumulative Returns", main = "Cumulative Returns: S&P 500 vs SGX (2010-2023)")
lines(index(STI_cumulative_returns), STI_cumulative_returns, col = "red")
legend("topleft", legend = c("S&P 500", "SGX"), col = c("blue", "red"), lty = 1)
From 2010 to 2020, the cumulative returns of the S&P 500 has experienced significant growth. However, the cumulative returns of the SGX have remained largely flat, showing little movement over the past decade. As such, we can conclude that investing in the S&P 500 generates a higher return compared to the SGX.
From our findings, we believe that the strong gowth in the S&P 500 was driven by strong economic recovery post-2008 financial crisis and the rise of technology companies like Apple, Amazon, and Microsoft. On the other hand, SGX’s performance was constrained by its sector composition, which is dominated by financials, real estate, and commodities, sectors that generally did not experience the same explosive growth as the U.S. tech sector. Therefore, while the SGX provides stability and lower volatility, it lacked the growth drivers that propelled the S&P 500 to higher returns. As such, the S&P 500 clearly outperformed the SGX, offering higher capital appreciation and overall returns for investors willing to accept its inherent volatility.
L4 Efficiency of market and information
Check if on 26 October 2017 coca cola shares were hit by the adverse information realize on the market. (assume 26 is the information release date)
library(quantmod)
library(ggplot2)
# Download historical data for KO from 2017-10-01 to 2017-11-01
getSymbols("KO", from = "2017-10-01", to = "2017-11-01")
## [1] "KO"
# Set the event date
event_date <- "2017-10-26"
# Calculate the log returns of KO Adjusted prices
KO_returns <- diff(log(KO$KO.Adjusted))
# Create the event dummy variable (1 for event date, 0 otherwise)
event_dummy <- ifelse(index(KO_returns) == event_date, 1, 0)
# Run the event study regression model (excluding the first element for lag)
event_study <- lm(KO_returns[-1] ~ event_dummy[-1])
# Display the summary of the event study model
summary(event_study)
##
## Call:
## lm(formula = KO_returns[-1] ~ event_dummy[-1])
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.0056736 -0.0036879 -0.0008877 0.0029816 0.0089743
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.001105 0.001060 1.042 0.310
## event_dummy[-1] 0.002796 0.004857 0.576 0.572
##
## Residual standard error: 0.00474 on 19 degrees of freedom
## Multiple R-squared: 0.01714, Adjusted R-squared: -0.03459
## F-statistic: 0.3314 on 1 and 19 DF, p-value: 0.5716
# Set the event date (October 26, 2017)
event_date <- "2017-10-26"
# Calculate the log returns of KO Adjusted prices
KO_returns <- diff(log(KO$KO.Adjusted))
# Define the event window (-2 to +2 days around the event)
event_window <- c(-2, 2)
# Get the numeric position of the event date in the returns vector
poz <- match(as.Date(event_date), index(KO_returns))
# Define the start and end of the event window
w_beg <- poz + event_window[1]
w_end <- poz + event_window[2]
# Define the event dummy for the event window (1 for event window, 0 otherwise)
event_dummy <- rep(0, length(KO_returns)) # Initialize the dummy variable
event_dummy[w_beg:w_end] <- 1 # Set the event window to 1
# Calculate Cumulative Abnormal Returns (CAR) over the event window
CAR <- cumsum(KO_returns[-1] * event_dummy[-1])[(w_beg - 1):(w_end - 1)]
# Test for significance (t-statistic and p-value)
t_stat <- CAR[length(CAR)] / sd(CAR) / sqrt(length(CAR))
p_value <- 2 * pt(-abs(t_stat), df = length(CAR) - 1)
# Print the results
cat("Cumulative Abnormal Return:", CAR[length(CAR)], "\n")
## Cumulative Abnormal Return: -0.009980684
cat("t-statistic:", t_stat, "\n")
## t-statistic: -1.436425
cat("p-value:", p_value, "\n")
## p-value: 0.2242329
The Cumulative Abnormal Return over the event window is negative at -0.998%.This indicates that Coca-Cola’s stock price underperformed relative to its expected return during this period. The negative CAR suggests that the market may have reacted negatively to adverse information.
On the other hand, a p-value greater than 0.05 means we fail to reject the null hypothesis that the adverse information on October 26, 2017 had no impact on Coca-Cola’s stock price. Hence, there is insufficient evidence to suggest that the event on October 26 2017 caused an abnormal movement in Coca-Cola’s stock price.
L9 Portfolio - CAMP
State the difference between CAPM and Markovitz
In Markowitz’s theory, risk is defined as the standard deviation of portfolio returns. It looks at both systematic and unsystematic risks. CAPM focuses only on systematic risk, which is measured by beta. CAPM assumes that investors hold well-diversified portfolios where unsystematic risk is negligible.
Markowitz is primarily used for portfolio construction. It helps investors allocate assets in such a way that the portfolio has the best possible return for a given level of risk. In contrast, CAPM is primarily used to determine the expected return of an asset based on its systematic risk relative to the market. It is also used to determine whether a particular investment offers an appropriate return for its risk
Markowitz focuses on finding the efficient frontier and minimizing standard deviation of portfolio. It involves calculating the covariance between return of assets in the portfolio. On the other hand, the key equation for CAPM is E(Ri) = Rf + βi ( E(Rm) - Rf ).