# packages
library(tidyquant)
library(tidyverse)
library(broom)
library(knitr)
library(dplyr)
library(kableExtra)
library(car)
library(onewaytests)
library(ggpubr)
library(tibble)
library(e1071)
library(qqplotr)
library(stargazer)
library(stats)
library(Deriv)
library(here)
# load data
stock_data<-c("HUM","AMZN", "MT") %>%
tq_get(get = "stock.prices", from = "2000-01-01") %>%
select(symbol, date, adjusted)
# output the first 6 rows of your data frame:
head(stock_data, n = 6 )%>%
kable(caption = "The first 6 rows of stock data")
| symbol | date | adjusted |
|---|---|---|
| HUM | 2000-01-03 | 6.805113 |
| HUM | 2000-01-04 | 6.861352 |
| HUM | 2000-01-05 | 7.030074 |
| HUM | 2000-01-06 | 7.311279 |
| HUM | 2000-01-07 | 7.873686 |
| HUM | 2000-01-10 | 7.536240 |
ggplot(stock_data, aes(x = date, y = adjusted, color = symbol)) +
geom_line(alpha = 0.8, lwd = 0.5) +
facet_wrap(~ symbol, scales = "free_y") +
labs(title = "Time Series Price Trend of Each Stock",
y = "Adjusted Price (US$)", x = "Dates") +
theme(legend.position = "bottom", plot.title = element_text(hjust = 0.5))
Time Series Price Trend of Each Stock
AMZN
The line graph for AMZN (Stock 2) shows a strong rise over time. This emphasizes how its value in the market has grown steadily and consistently. Even though prices go up and down, they all join to make a good direction. A big jump in costs shows something important happening in the market. Clearly marked axes, with time on the bottom and Amazon prices shown in dollars at top help to make it much easier understanding what’s being showed. This visualization, called “AMZN Prices Over Time” shows how AMZN’s value has changed over the years.
HMU
Changing Over Time A line chart for HUM (Stock 1) shows prices going up steadily during the watched time. Even though things change now and then, showing quick ups and downs in the market, overall it shows steady growth. Important is a big increase in costs, showing strong effects on the market. Properly marked lines show time on the x-axis (in years), giving a complete look at how HUM has done through history. On the y-axis, HUM prices are shown in US dollars. This big picture shows how HUM’s worth changes over time. It includes both long-term improvements and short moments of market action.
MT
Evolution Over Time series plot of MT (Stock 3) over time shows how prices change during the observed period. Background changes suggest possible market change and complicated actions. A clear increase in prices shows a big change in the market. Labels that show time on the top and MT prices on the side (in adjusted dollars) help us see better how well MT has done. It makes it easier to understand its past performance too. This picture, called “MT Prices Over Time” perfectly shows how MT’s worth has changed over time.
Calculate the daily percentage returns of each asset using the following formula:
\[r_t = 100*\ln\Big(\frac{P_t}{P_{t-1}}\Big)\]
Where \(P_t\) is the asset price at time \(t\). Then plot the returns for each asset over time.
stock_data<-stock_data%>%
group_by(symbol)%>%
mutate("Returns" = 100*log(adjusted/lag(adjusted)))
# Plotting the daily returns of the 3 stocks
ggplot(stock_data, aes(x = date, y = Returns, color=symbol))+
geom_line(alpha=0.6, lwd=0.5)+
facet_wrap(factor(symbol, levels=c("HUM", "AMZN", "MT"))~.)+
ylim(-20,20)+
labs(title = "Price Returns of Each Stock Overtime",
y = "Price Returns (%)", x = "Dates")+
theme(legend.position="bottom", plot.title = element_text(hjust = 0.5))
Price Returns of Each Stock Overtime
Create a histogram for each of the returns series
stock_data%>%
group_by(symbol)%>%
summarise(n = n())
## # A tibble: 3 × 2
## symbol n
## <chr> <int>
## 1 AMZN 6065
## 2 HUM 6065
## 3 MT 6065
samplesize <- sum(stock_data$symbol=='HUM')
samplesize
## [1] 6065
sturgerule <- 1+ 3.322*log(samplesize)
ggplot(stock_data, aes(x=Returns, fill=symbol, color=symbol))+
geom_histogram(aes(y=..density..), bins=35 , alpha=0.8)+
facet_wrap(factor(symbol, levels=c("HUM", "AMZN", "MT"))~.) +
facet_wrap(factor(symbol, levels=c("HUM", "AMZN", "MT"))~.) +
xlim(-10,10)+
labs(title = "Histogram Price Returns of Each Stock",
y = "Frequency", x = "Price Returns")+
geom_density(col ="black", lwd=0.3, linetype=5, alpha=0) +
theme(legend.position="bottom", plot.title = element_text(hjust = 0.5))
Histogram of Returns of Each Stock
To comprehensively understand the distribution of returns for each stock, histograms were generated, providing insights into the frequency of different return levels. Employing Sturges’ rule for bin calculation, the number of bins was determined as 1+3.22.log(sample size), ensuring an optimal representation of the distribution characteristics. Sturges’ rule strikes a balance between granularity and interpretability. By considering the logarithm of the sample size, it adjusts the bin count to be suitable for datasets of varying sizes. This adaptability ensures that the resulting histograms effectively capture the distribution characteristics without introducing unnecessary noise.
AMZN
The histogram for AMZN Returns shows a positive skew, focusing on steady good returns over time. Sometimes, big jumps in stock prices happen. These are times when the market is really busy or something huge impacts how Amazon’s shares do.
HUM
The histogram for HUM Returns shows a spread with the highest part around zero. This means it’s like a typical normal distribution. This means that stock prices often change a bit over time. Big ups and downs on the histogram show times when the market is sometimes more unstable.
MT
The histogram for MT Returns showcases a distribution with a more even spread, indicating varying levels of volatility over time. Peaks and troughs in the histogram capture the dynamics of MT’s performance, reflecting fluctuating market conditions.
Formula Hint
The choice of Sturges’ rule for bin calculation ensures an appropriate representation of the data’s characteristics without oversmoothing or undersmoothing. This method takes into account the sample size, providing a data-driven approach to bin determination.
library(ggplot2)
library(dplyr)
# The dataset is provided in the gapminder library
library(gapminder)
data <- gapminder %>% filter(year=="2007") %>% dplyr::select(-year)
# Most basic bubble plot
data %>%
arrange(desc(pop)) %>%
mutate(country = factor(country, country)) %>%
ggplot(aes(x=gdpPercap, y=lifeExp, size = pop)) +
geom_point(alpha=0.5) +
scale_size(range = c(.1, 24), name="Population (M)")
# Create data
library(GGally)
data <- data.frame( var1 = 1:100 + rnorm(100,sd=20), v2 = 1:100 + rnorm(100,sd=27), v3 = rep(1, 100) + rnorm(100, sd = 1))
data$v4 = data$var1 ** 2
data$v5 = -(data$var1 ** 2)
# Check correlations (as scatterplots), distribution and print corrleation coefficient
ggpairs(data, title="correlogram with ggpairs()")
# From the help page:
data(flea)
ggpairs(flea, columns = 2:4, ggplot2::aes(colour=species))
library(GGally)
# Create data
data <- data.frame( var1 = 1:100 + rnorm(100,sd=20), v2 = 1:100 + rnorm(100,sd=27), v3 = rep(1, 100) + rnorm(100, sd = 1))
data$v4 = data$var1 ** 2
data$v5 = -(data$var1 ** 2)
# Check correlation between variables
#cor(data)
# Nice visualization of correlations
ggcorr(data, method = c("everything", "pearson"))
# Create a table for the mean, median, variance,
#Standard deviation, skewness and kurtosis of the returns
stock_data%>%
group_by(symbol)%>%
select(Returns)%>%
drop_na()%>%
summarise(
"Mean"=sprintf("%.3f", mean(Returns)),
"Median" =sprintf("%.3f",median(Returns)),
"Variance" =sprintf("%.3f", var(Returns)),
"Standard Deviation" =sprintf("%.3f", sd(Returns)),
"Skewness" =sprintf("%.3f", skewness(Returns)),
"Kurtosis" =sprintf("%.3f", kurtosis(Returns)),
"n"=sprintf("%.3f",n()))%>%
mutate(symbol=fct_relevel(symbol, "HUM", "AMZN", "MT")) %>%
arrange(symbol) %>%
kable(caption ="Statistical Table for the Returns of Each Stock",
label = "stock1", align=rep('c', 8)) %>%
kable_styling(latex_options = c("hold_position", "striped",
"scale_down"), position="center", stripe_color="blue!8")%>%
kableExtra::row_spec(0, bold = TRUE)
| symbol | Mean | Median | Variance | Standard Deviation | Skewness | Kurtosis | n |
|---|---|---|---|---|---|---|---|
| HUM | 0.066 | 0.058 | 5.912 | 2.431 | -0.851 | 14.045 | 6064.000 |
| AMZN | 0.060 | 0.049 | 9.687 | 3.112 | 0.424 | 12.715 | 6064.000 |
| MT | -0.003 | 0.000 | 12.139 | 3.484 | 0.124 | 10.154 | 6064.000 |
The summary table of returns for each stock—HUM, AMZN, and MT—provides comprehensive insights into various statistical measures, revealing distinct characteristics of their return distributions.
Mean and Median
The average return shows how each stock usually does. HUM has the highest average gain at 0.070, showing a good normal return. AMZN closely watches with a little lower average of 0.058, showing good performance most of the time. On the other hand, MT has a small negative mean of -0.003 which suggests that it usually gives out more than usual in return. Noticing that middle numbers are often smaller than averages suggests there might be a skewed pattern. This means it’s important to study returns more closely and understand their shape better.
Variance and Standard Deviation
The change and standard of deviation give us ways to measure how much the returns vary. MT is special because it has the biggest difference (12.183) and normal change size (3.490). This shows that its profits can be more high or low compared to HUM and AMZN’s results. Even though HUM and AMZN have less variation, they still show big changes. This shows that these stocks are risky by nature.
Skewness
Skewness checks how uneven the return distributions are. HUM and MT both show a lower skewness, which means their distributions have an extended left side. This means that bad returns happen more often than good ones. Instead, AMZN shows a good positive skew. This means it has longer right tails and more frequent high returns compared to other stocks or investments. Knowing about skewness is very important to see how and often extreme profits happen.
Kurtosis
All three stocks have high kurtosis value, which means the distributions are more extreme compared to normal distribution. HUM has the biggest kurtosis at 14.122. This means the distribution has more extreme or big values. Understanding kurtosis is crucial for measuring how likely extreme events or unusual outcomes are in return patterns.
Sample Size (n)
The uniform sample size of 6037 for each stock signifies a substantial dataset for analysis. This large sample size enhances the reliability of the statistical measures, providing a robust foundation for drawing meaningful conclusions.
Conclusions
HUM shows a skewed pattern with bigger kurtosis and more extreme values in its gains. AMZN showing a positive distribution with some amount of extreme returns. MT, with a skewed distribution that’s negative, the highest variance and standard deviation shows more variation. This can lead to potential risk too.
Part 1
Step 1: Formulate Hypotheses
Null Hypothesis \[(H_0):\mu=0\] The expected return is not significantly different from zero)
Alternative Hypothesis \[(H_1):\mu \neq 0\] The expected return is significantly different from zero)
Step 2: Choose Significance Level
Significance level \(\alpha = 0.01\)
Step 3: Select Test Statistic
statistical t test was used. The formula is give as
\[t = \frac{\bar{X}-\mu_0}{S{\sqrt n}}\] where \(\bar{X}\) is the sample mean \(\mu_0\) is the hypothesized population mean (in this case, 0), S is the sample standard deviation, and n is the sample size.
Step 4: Calculate Critical Value(s) or P-value
With a significance level of 0.01 and degrees of freedom\(n - 1\) , find the critical values or P-value.
Step 5: Make a Decision
If the calculated test statistic falls in the rejection region (beyond the critical values), we reject the null hypothesis. Otherwise, we fail to reject the null hypothesis.
Part 2
t_test_HUM <- t.test(stock_data$Returns[stock_data$symbol == "HUM"],
alternative = "two.sided", mu = 0)
print(t_test_HUM)
##
## One Sample t-test
##
## data: stock_data$Returns[stock_data$symbol == "HUM"]
## t = 2.1108, df = 6063, p-value = 0.03483
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 0.004697825 0.127115673
## sample estimates:
## mean of x
## 0.06590675
if (t_test_HUM$p.value < 0.01) {
cat("For HUM: Reject the null hypothesis.
Expected return is significantly different from zero.\n")
} else {
cat("For HUM: Fail to reject the null hypothesis.
Expected return is not significantly different from zero.\n")
}
## For HUM: Fail to reject the null hypothesis.
## Expected return is not significantly different from zero.
t_test_AMZN <- t.test(stock_data$Returns[stock_data$symbol == "AMZN"],
alternative = "two.sided", mu = 0)
print(t_test_AMZN)
##
## One Sample t-test
##
## data: stock_data$Returns[stock_data$symbol == "AMZN"]
## t = 1.512, df = 6063, p-value = 0.1306
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -0.01791965 0.13878144
## sample estimates:
## mean of x
## 0.06043089
if (t_test_AMZN$p.value < 0.01) {
cat("For AMZN: Reject the null hypothesis.
Expected return is significantly different from zero.\n")
} else {
cat("For AMZN: Fail to reject the null hypothesis.
Expected return is not significantly different from zero.\n")
}
## For AMZN: Fail to reject the null hypothesis.
## Expected return is not significantly different from zero.
t_test_MT <- t.test(stock_data$Returns[stock_data$symbol == "MT"],
alternative = "two.sided", mu = 0)
print(t_test_MT)
##
## One Sample t-test
##
## data: stock_data$Returns[stock_data$symbol == "MT"]
## t = -0.061068, df = 6063, p-value = 0.9513
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -0.09044347 0.08497883
## sample estimates:
## mean of x
## -0.002732321
if (t_test_MT$p.value < 0.01) {
cat("For MT: Reject the null hypothesis.
Expected return is significantly different from zero.\n")
} else {
cat("For MT: Fail to reject the null hypothesis.
Expected return is not significantly different from zero.\n")
}
## For MT: Fail to reject the null hypothesis.
## Expected return is not significantly different from zero.
Part 3
Ask Chat-GPT to explain the general steps and details involved in conducting a hypothesis test for the average returns of a sample. Emphasize the importance of the five steps and the equation for the test statistic. Also, inquire about the interpretation of the results and how one would decide whether to reject the null hypothesis.
Chat-GPT is likely to provide a general explanation of the steps involved in a one-sample t-test, including formulating hypotheses, choosing the significance level, calculating the test statistic, determining critical values or p-values, and making a decision based on the results. The response might also include an interpretation of the p-value and guidance on decision-making.
While the answer is specific to the dataset and involves practical implementation in R, Chat-GPT’s response would be more general and focused on the theoretical aspects of hypothesis testing. There might be differences in the level of detail and specificity. The answer is tailored to the data, while Chat-GPT’s response would be applicable to a broad understanding of hypothesis testing.
Step 1: Formulate Hypotheses
Null Hypothesis \(H_0 = \mu_1 = \mu_2 = \mu_3\) (The mean returns are equal for all stocks)
Alternative Hypothesis At least one pair of means is different
Step 2: Choose Significance Level \(\alpha = 0.01\)
Step 3: Select Test Statistic
Since we are comparing means of three independent groups, we would typically use Analysis of Variance (ANOVA). If ANOVA indicates significant differences, we proceed to post hoc tests for pairwise comparisons.
Step 4: Calculate Critical Value(s) or P-value
Perform ANOVA to get the p-value. If the p-value is less than 0.01, we can proceed with post hoc tests.
Step 5: Make a Decision
If ANOVA is significant, conduct post hoc tests to identify which pairs of means are significantly different.
# Assuming stock_data contains the necessary data
anova_result <- aov(Returns ~ symbol, data = stock_data)
print(summary(anova_result))
## Df Sum Sq Mean Sq F value Pr(>F)
## symbol 2 18 8.824 0.954 0.385
## Residuals 18189 168175 9.246
## 3 observations deleted due to missingness
# Post hoc tests (assuming equal variances)
posthoc <- TukeyHSD(anova_result)
print(posthoc)
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = Returns ~ symbol, data = stock_data)
##
## $symbol
## diff lwr upr p adj
## HUM-AMZN 0.005475855 -0.1239584 0.13491014 0.9945936
## MT-AMZN -0.063163216 -0.1925975 0.06627107 0.4870882
## MT-HUM -0.068639070 -0.1980734 0.06079522 0.4278345
Interpretation
The analysis of variance (ANOVA) results for comparing the average returns of the three stocks (HUM, AMZN, MT) yields an F-value of 0.999 with a corresponding p-value of 0.368. Given that the p-value is greater than the chosen significance level of 0.01, we fail to reject the null hypothesis of equal means among the stocks. This suggests that, at a 1% level of significance, there is insufficient evidence to conclude that the average returns of HUM, AMZN, and MT are statistically different.
To further explore potential differences between individual pairs of means, a Tukey post hoc test was conducted. The results indicate that none of the pairwise mean differences are statistically significant after adjusting for multiple comparisons. Specifically, the confidence intervals for the pairwise differences (HUM-AMZN, MT-AMZN, MT-HUM) all include zero, and the p-values are greater than the adjusted significance level.
Therefore, we do not find significant evidence to support the notion that the average returns of any two stocks among HUM, AMZN, and MT are different from each other at the 1% level of significance. This aligns with the ANOVA results and reinforces the conclusion of overall equality in mean returns for the three stocks.
Prompt for Chat-GPT
Ask Chat-GPT to explain the general steps and details involved in conducting an ANOVA test followed by post hoc tests for pairwise comparisons. Inquire about the importance of equal variances assumption and how to interpret the results.
Expected Answer
Chat-GPT would likely provide a general explanation of ANOVA, the need for post hoc tests, and the importance of checking for equal variances. The response might include guidance on interpreting ANOVA results and conducting post hoc tests.
Comparison to Your Answer
The answer is specific to your dataset and involves practical implementation in R. Chat-GPT’s response would be more general and focused on the theoretical aspects of ANOVA and post hoc tests. There might be differences in the level of detail and specificity. The answer is tailored to your data, while Chat-GPT’s response would be applicable to a broad understanding of statistical testing principles.
stocksReturns<-stock_data%>%
drop_na()%>%
select(date, symbol, Returns)%>%
pivot_wider(date, names_from = symbol, values_from = Returns)
glimpse(stock_data$Returns)
## num [1:18195] NA 0.823 2.429 3.922 7.411 ...
cor(stocksReturns%>%select(-date))%>%
kable(caption="Correlation Matrix", label = "stocks4",digit=3 , align=rep('c', 4))%>%
kable_styling(latex_options = c("hold_position", "striped"),
position="center", stripe_color="purple!8")%>%
kableExtra::row_spec(0, bold = TRUE)
| HUM | AMZN | MT | |
|---|---|---|---|
| HUM | 1.000 | 0.163 | 0.217 |
| AMZN | 0.163 | 1.000 | 0.243 |
| MT | 0.217 | 0.243 | 1.000 |
HUM and AMZN (0.165)
The correlation between HUM and AMZN is positive but relatively weak (0.165). This suggests a slight tendency for the two stocks to move in the same direction, but the relationship is not very strong.
HUM and MT (0.218)
The correlation between HUM and MT is positive and slightly stronger (0.218) compared to HUM and AMZN. This indicates a somewhat stronger tendency for the two stocks to move together.
AMZN and MT (0.243)
The correlation between AMZN and MT is positive and stronger (0.243) compared to HUM and AMZN but weaker than HUM and MT. This suggests a moderate tendency for AMZN and MT to move in the same direction.
Step 1: Formulate Hypotheses Null Hypothesis \(H_0\):The correlation coefficients between stock returns are not significantly different from zero, indicating independence.
lternative Hypothesis \(H_1\) : At least one correlation coefficient is significantly different from zero, indicating dependence.
Step 2: Choose Significance Level
Significance level\(\alpha = 0.05\)
Step 3: Select Test Statistic
We will use Fisher’s transformation to convert the correlation coefficients to z-scores, making them approximately normally distributed.
Step 4: Calculate Critical Value(s) or P-value
Under the null hypothesis, the test statistic follows a standard normal distribution. We will compare the absolute value of the test statistic with the critical value from the standard normal distribution or calculate a two-tailed p-value.
Step 5: Make a Decision
If the absolute value of the test statistic is greater than the critical value, or if the p-value is less than the significance level, we reject the null hypothesis. Otherwise, we fail to reject the null hypothesis.
# Create a matrix with the given correlation coefficients
correlation_matrix <- matrix(c(1.000, 0.165, 0.218,
0.165, 1.000, 0.243,
0.218, 0.243, 1.000),
nrow = 3,
byrow = TRUE)
# Convert the matrix to a data frame for better visualization
correlation_df <- as.data.frame(correlation_matrix)
# Set row and column names
rownames(correlation_df) <- colnames(correlation_df) <- c("HUM", "AMZN", "MT")
# Display the correlation matrix
print(correlation_df)
## HUM AMZN MT
## HUM 1.000 0.165 0.218
## AMZN 0.165 1.000 0.243
## MT 0.218 0.243 1.000
# Extract correlation coefficients from the correlation matrix
cor_values <- as.vector(correlation_matrix)
# Fisher's transformation function
fisher_transform <- function(r) {
0.5 * log((1 + r) / (1 - r))
}
# Apply Fisher's transformation
z_scores <- sapply(cor_values, fisher_transform)
# Perform a two-tailed test for each correlation
p_values <- 2 * (1 - pnorm(abs(z_scores)))
# Compare each p-value with the significance level
alpha <- 0.05
reject_null <- p_values < alpha
# Check if any correlation is statistically significant
if (any(reject_null)) {
cat("At least one correlation is statistically significant.
There is evidence of dependence between stock returns.\n")
} else {
cat("No correlations are statistically significant.
No significant evidence of dependence between stock returns.\n")
}
## At least one correlation is statistically significant.
## There is evidence of dependence between stock returns.
Assumption of independence
The hypothesis test performed on the correlation coefficients indicates that at least one correlation among the stock returns is statistically significant. The evidence suggests that the assumption of independence of stock returns may not be realistic.
Rationale
In this case, the result indicates that at least one correlation is statistically significant (p-value < 0.05), leading to the rejection of the null hypothesis. Therefore, there is evidence of dependence between stock returns. This finding is crucial for understanding the potential relationships and dependencies among the stocks in the dataset, impacting portfolio management and risk assessment strategies.
# Define the expected returns for HUM,AMZN and MT
E_r <- c(0.0699459, 0.0580204, -0.0034106)
# Define the variances for HUM,AMZN and MT
Var_r <- c(5.887240, 9.710527,12.181820)
# Define the covariance matrix between HUM,AMZN and MT
Cov_r <- matrix(c(5.887243, 1.244174,1.847846,
1.244174, 9.710527,2.640371,
1.847846, 2.640371, 12.181816), nrow = 3, ncol = 3)
# Create a sequence of possible weights for w1
weights <- seq(0, 1, by = 0.01)
# Initialize variables to store optimal values
max_happiness <- -Inf
optimal_weights <- numeric(3)
# Loop through all possible weight combinations
for (w1 in weights) {
for (w2 in weights) {
w3 <- 1 - w1 - w2 # Ensure that w1 + w2 + w3 = 1
# Calculate portfolio statistics
portfolio_var <- w1^2 * Var_r[1] + w2^2 * Var_r[2] + w3^2 * Var_r[3] +
2 * w1 * w2 * Cov_r[1, 2] + 2 * w1 * w3 * Cov_r[1, 3] +
2 * w2 * w3 * Cov_r[2, 3]
portfolio_return <- w1 * E_r[1] + w2 * E_r[2] + w3 * E_r[3]
happiness <- portfolio_return - portfolio_var
# Check if this combination maximizes happiness
if (happiness > max_happiness) {
max_happiness <- happiness
optimal_weights <- c(w1, w2, w3)
}
}
}
# Print the optimal portfolio weights and expected return
cat("Optimal Portfolio Weights:")
## Optimal Portfolio Weights:
cat("HUM weight:", optimal_weights[1], "\n")
## HUM weight: 0.55
cat("AMZN weight:", optimal_weights[2], "\n")
## AMZN weight: 0.28
cat("MT weight:", optimal_weights[3], "\n")
## MT weight: 0.17
cat("Expected Return of Optimal Portfolio:", portfolio_return, "\n")
## Expected Return of Optimal Portfolio: 0.1313769
# Extract the relevant columns for stocks 1 and 2
returns_data <- stocksReturns[, c("HUM", "AMZN", "MT")]
# Calculate the covariance matrix
covariance_matrix <- cov(returns_data, use = "pairwise.complete.obs")
# Display the covariance matrix
print(covariance_matrix)
## HUM AMZN MT
## HUM 5.911791 1.236293 1.837761
## AMZN 1.236293 9.686651 2.629658
## MT 1.837761 2.629658 12.139455