Install the necessary packages
library(quantmod)
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)
# 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 correlation and statistics between the S&P 500 and Singapore Exchange Index
# Calculate correlation
correlation <- cor(cleaned_data[, 1], cleaned_data[, 7]) # Adjust column index if needed
# Print the correlation coefficient
print(round(correlation, 2))
## STI.Open
## GSPC.Open 0.17
# Compare the statistics
nasdaq_stats <- c(mean(GSPC[, 4], na.rm = TRUE), median(GSPC[, 4], na.rm = TRUE), sd(GSPC[, 4], na.rm = TRUE)) # Adjust column for Close prices
lond_stats <- c(mean(STI[, 4], na.rm = TRUE), median(STI[, 4], na.rm = TRUE), sd(STI[, 4], na.rm = TRUE)) # Adjust column for Close prices
# Combine statistics into a single data frame
stats_comparison <- rbind(nasdaq_stats, lond_stats)
colnames(stats_comparison) <- c("Mean", "Median", "Standard Deviation")
rownames(stats_comparison) <- c("S&P 500", "Singapore Exchange (STI)")
print(round(stats_comparison, 2))
## Mean Median Standard Deviation
## S&P 500 2401.49 2125.03 988.94
## Singapore Exchange (STI) 3093.40 3139.98 236.20
Let us compare the Value at Risk for the S&P 500 and Singapore Exchange Index.
# Calculate daily returns
GSPC_returns <- dailyReturn(Cl(GSPC))
STI_returns <- dailyReturn(Cl(STI))
# Remove any NA values in returns
GSPC_returns <- na.omit(GSPC_returns)
STI_returns <- na.omit(STI_returns)
# Calculate Value at Risk (VaR)
# Using 95% confidence level
VaR_GSPC <- quantile(GSPC_returns, probs = 0.05) # 5th percentile
VaR_STI <- quantile(STI_returns, probs = 0.05) # 5th percentile
# Print VaR results
cat("Value at Risk (VaR) at 95% confidence level:\n")
## Value at Risk (VaR) at 95% confidence level:
cat("S&P 500 VaR:", round(VaR_GSPC * 100, 2), "%\n")
## S&P 500 VaR: -1.72 %
cat("Singapore Exchange (STI) VaR:", round(VaR_STI * 100, 2), "%\n")
## Singapore Exchange (STI) VaR: -1.3 %
Let us compare the volatility for the S&P 500 and Singapore Exchange Index
# Calculate the standard deviation (volatility) of returns for each index
volatility_GSPC <- sd(GSPC_returns) # Daily volatility for S&P 500
volatility_STI <- sd(STI_returns) # Daily volatility for SGX
# Annualize the volatility
annualized_volatility_GSPC <- volatility_GSPC * sqrt(365)
annualized_volatility_STI <- volatility_STI * sqrt(365)
# Print the volatility comparison
cat("Daily Volatility for S&P 500 (GSPC):", round(volatility_GSPC, 4), "\n")
## Daily Volatility for S&P 500 (GSPC): 0.0112
cat("Daily Volatility for SGX (STI):", round(volatility_STI, 4), "\n")
## Daily Volatility for SGX (STI): 0.0084
cat("Annualized Volatility for S&P 500 (GSPC):", round(annualized_volatility_GSPC, 4), "\n")
## Annualized Volatility for S&P 500 (GSPC): 0.2143
cat("Annualized Volatility for SGX (STI):", round(annualized_volatility_STI, 4), "\n")
## Annualized Volatility for SGX (STI): 0.1613
Let us compare the Sharpe ratio of the S&P 500 and Singapore Exchange Index.
First, we calculate the mean and standard deviation of the S&P 500 and Singapore Exchange Index.
# Calculate the mean return for both indices
mean_GSPC <- mean(GSPC_returns)
mean_STI <- mean(STI_returns)
# Calculate the standard deviation (volatility) of returns for both indices
volatility_GSPC <- sd(GSPC_returns) # Daily volatility for S&P 500
volatility_STI <- sd(STI_returns) # Daily volatility for SGX
We will annualise the mean and standard deviation
# Annualize the mean return (assuming 365 trading days in a year)
annualized_mean_GSPC <- mean_GSPC * 365
annualized_mean_STI <- mean_STI * 365
# Annualize the volatility (assuming 365 trading days in a year)
annualized_volatility_GSPC <- volatility_GSPC * sqrt(365)
annualized_volatility_STI <- volatility_STI * sqrt(365)
Finally, we can calculate the Sharpe ratio for the S&P 500 and Singapore Exchange index
# Calculate the Sharpe Ratio for both indices (assuming 0% risk-free rate)
sharpe_ratio_GSPC <- (annualized_mean_GSPC - 0) / annualized_volatility_GSPC
sharpe_ratio_STI <- (annualized_mean_STI - 0) / annualized_volatility_STI
# Print the Sharpe Ratio comparison
cat("Sharpe Ratio for S&P 500 (GSPC):", round(sharpe_ratio_GSPC, 4), "\n")
## Sharpe Ratio for S&P 500 (GSPC): 0.743
cat("Sharpe Ratio for SGX (STI):", round(sharpe_ratio_STI, 4), "\n")
## Sharpe Ratio for SGX (STI): 0.1614
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 Cumulative Returns
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)
As shown on the graph, the S&P 500 has drastically higher cumulative returns over the years from 2010 to 2023 as compared to the SGX.