The data set consists of weekly stock data from 2018 to 2025 march for Tesla Inc., sourced from Investing.com. Each row represents a week’s trading summary, and key variables include Date (the week-ending date), Price or Close or High or low (the adjusted closing price for that week), and Return (the percentage change in price from the previous week). I have derived variables used for technical analysis include moving averages such as SMA_50, SMA_200, and EMA_50, which help identify long-term and short-term trends. The data set also includes Bollinger Bands components—up, dn, and mavg—used to assess market volatility, as well as MACD indicators (MACD, Signal, Histogram) to measure momentum. These variables together provide a comprehensive view of Tesla’s stock behavior over time, enabling both performance evaluation and trend forecasting.
Liberary function for the coding.
I have loaded all the required library function usisng the following function.
library(TTR)
library(ggplot2)
library(plotly)
library(tidyverse)
library(gapminder)
library(gganimate)
library(dplyr)
library(readr)
library(lubridate)
library(tidyr)
library(quantmod)
library(PerformanceAnalytics)
After that, I Loaded the data sets to do the required calculation. Here, I have assure the name of each column and also fix the data that has been uploaded in the csv file usig gsub function.
tesla_data <- read.delim("~/R/Tesla.csv")
View(tesla_data)
colnames(tesla_data) <- c("Date", "Price","Open", "High","low")
tesla_data$Date <- as.Date(tesla_data$Date, format="%m/%d/%Y")
tesla_data$Price <- as.numeric(gsub(",", "", tesla_data$Price))
tesla_data$Open <- as.numeric(gsub(",", "", tesla_data$Open))
tesla_data$High <- as.numeric(gsub(",", "", tesla_data$High))
tesla_data$low <- as.numeric(gsub(",", "", tesla_data$low))
After I uploaded the data, using the sum and summery function I have check the data status and Weekly Return calculation of Tesla for last eight years has been conducted using mutate function.
str(tesla_data)
## 'data.frame': 378 obs. of 5 variables:
## $ Date : Date, format: "2018-01-07" "2018-01-14" ...
## $ Price: num 22.4 23.3 22.9 22.9 20.7 ...
## $ Open : num 21.1 22.5 23.3 22.7 22.5 ...
## $ High : num 23 23.5 24 24 23.2 ...
## $ low : num 21 22.3 22.4 22.6 19.6 ...
sum(is.na(tesla_data))
## [1] 0
summary(tesla_data)
## Date Price Open High
## Min. :2018-01-07 Min. : 12.34 Min. : 12.37 Min. : 13.00
## 1st Qu.:2019-10-28 1st Qu.: 23.52 1st Qu.: 23.71 1st Qu.: 24.36
## Median :2021-08-18 Median :191.19 Median :188.93 Median :199.51
## Mean :2021-08-18 Mean :164.55 Mean :164.17 Mean :174.30
## 3rd Qu.:2023-06-09 3rd Qu.:248.91 3rd Qu.:247.88 3rd Qu.:258.20
## Max. :2025-03-30 Max. :436.23 Max. :441.09 Max. :488.54
## low
## Min. : 11.80
## 1st Qu.: 22.35
## Median :177.67
## Mean :154.70
## 3rd Qu.:234.82
## Max. :417.64
tesla_data <- tesla_data %>%
arrange(Date) %>%
mutate(Return = (Price - lag(Price)) / lag(Price))
tesla_data$Return[is.na(tesla_data$Return)] <- 0
This code includes several functions for cleaning, summarizing, and visualizing Tesla’s weekly stock data. The gsub function removes commas from the Price column to ensure numeric formatting, while as.numeric converts the cleaned data from character to numeric format. The summary function is then applied to the Price, Open, High, and Low columns to produce basic descriptive statistics like minimum, maximum, mean, and median values. For visualization, the plot_ly function generates an interactive candlestick chart with the Open, High, Low, and Price columns, allowing users to investigate Tesla’s stock movement over time. The layout function modifies the chart by adding titles to the axes and the chart itself. Finally, ggplotly is used to make the plot interactive, allowing it to be easily embedded in R Markdown documents or Shiny applications.
tesla_data$Price <- as.numeric(gsub(",", "", tesla_data$Price))
summary(tesla_data$Price)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 12.34 23.52 191.19 164.55 248.91 436.23
summary(tesla_data$Open)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 12.37 23.71 188.93 164.17 247.88 441.09
summary(tesla_data$High)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 13.00 24.36 199.51 174.30 258.20 488.54
summary(tesla_data$Low)
## Length Class Mode
## 0 NULL NULL
CH <- fig <- tesla_data %>%
plot_ly(x = ~Date, type = "candlestick",
open = ~Open, high = ~High, low = ~low, close = ~Price) %>%
layout(title = "Tesla Candlestick Chart 2018 to 2025",
xaxis = list(title = "Date"),
yaxis = list(title = "Price"))
plotly_chart <- ggplotly(CH)
plotly_chart
I have used ggplot2 to create a line chart of Tesla’s stock price over the last eight years, and plotly to make it interactive. The plot is initialized with Date on the x-axis and Price on the y-axis by the ggplot function. While geom_smooth adds a red linear regression line without a confidence interval (se = FALSE) to emphasize the overall trend, geom_line depicts the stock price trend as a smooth blue line. The theme_minimal gives the plot a tidy appearance, and the labs function adds axis labels and clear titles. Lastly, ggplotly turns the static ggplot chart into an interactive plot, allowing for tooltip display, zooming, and hovering. .
gg <- ggplot(tesla_data, aes(x = Date, y = Price)) +
geom_line(color = "blue", size = 1, alpha = 0.9) +
geom_smooth(method = "lm", color = "red", se = FALSE) +
labs(title = "Tesla Stock Price Over 8 Years", x = "Date", y = "Closing Price ($)") +
theme_minimal()
plotly_chart <- ggplotly(gg)
plotly_chart
The Figure above shows the trend of tesla price from 2018 to 2025. We can see from the visuals that the price till 2020 was smooth and low but once it starts recovering form the Covid, the price has increasing dramatically. T rend also shows that the price is in increasing trend for Tesla.
This visuals shows how the price has been since 2018 to 2025 throught the animated bubble.
gg_anim <- ggplot(tesla_data, aes(x = Date, y = Price)) +
geom_line(color = "blue", size = 1, alpha = 0.8) +
geom_point(aes(color = High), size = 3) +
labs(title = "Tesla Stock Price Movement: {frame_time}", x = "Date", y = "Closing Price ($)") +
transition_time(Date) +
ease_aes("linear")
animate(gg_anim, nframes = 100, fps = 10)
gganimate::anim_save("tesla_stock_animation.gif", gg_anim)
gg_anim
7. Regression
Using the regression formula i have calculate the Beta value.The beta value for the tesla for last 8 years is 0.51, which means its not very risky stok and if market goes up by 10%, the stock will go up by 5%.
reg_model <- lm(Price ~ Open + High + low, data = tesla_data)
summary(reg_model)
##
## Call:
## lm(formula = Price ~ Open + High + low, data = tesla_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -40.178 -1.826 -0.209 2.609 25.408
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.51313 0.61581 0.833 0.405
## Open -0.63841 0.04100 -15.570 <2e-16 ***
## High 0.91857 0.03923 23.415 <2e-16 ***
## low 0.70291 0.04259 16.505 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 6.875 on 374 degrees of freedom
## Multiple R-squared: 0.9965, Adjusted R-squared: 0.9965
## F-statistic: 3.537e+04 on 3 and 374 DF, p-value: < 2.2e-16
In this code, a scatter plot is created to visualize the relationship between Tesla’s stock returns and prices. Using ggplot, the plot maps Return on the x-axis and Price on the y-axis. geom_point adds semi-transparent blue dots to represent individual data points. Two trend lines are added using geom_smooth: the first is a red linear regression line without a confidence interval, and the second is a firebrick-colored line with a green shaded confidence band (se = TRUE, fill = “green”, alpha = 0.3). coord_cartesian ensures the plot stays within the actual range of the data, and theme_minimal keeps the design clean and simple. Finally, ggplotly makes the plot interactive, allowing dynamic data exploration.
ga <- ggplot(tesla_data, aes(x = Return, y = Price)) +
geom_point(color = "blue", size = 2, alpha = 0.6) +
geom_smooth(method = "lm", color = "red", linetype = "solid", se = FALSE) +
labs(title = "Scatter Plot of Price vs Return with Trend Line", x = "Return (%)", y = "Price") + geom_smooth(method = "lm", color = "firebrick", se = TRUE, fill = "green", alpha = 0.3) +
coord_cartesian(xlim = c(min(tesla_data$Return), max(tesla_data$Return)),
ylim = c(min(tesla_data$Price), max(tesla_data$Price))) +
theme_minimal()
plotly_chart <- ggplotly(ga)
plotly_chart
I have used histogram to depict the return distribution of Tesla and find out that the return distribution for Tesla looks more or less a normal distribution.
tesla_data$Return <- na.omit(tesla_data$Return)
chart.Histogram(tesla_data$Return, main = "Tesla Stock Return Distribution", methods = c("add.normal"))
I have used function like SMA and EMA to depict the moving average for Tesla inc. Differemt colours and function like geom_line and other are used to get the clear figure of it.
tesla_data$SMA_50 <- SMA(tesla_data$Price, n = 50)
tesla_data$SMA_200 <- SMA(tesla_data$Price, n = 200)
tesla_data$EMA_50 <- EMA(tesla_data$Price, n = 50)
Raut <- ggplot(tesla_data, aes(x = Date)) +
geom_line(aes(y = Price, color = "Price"), size = 1) +
geom_line(aes(y = SMA_50, color = "50-day SMA"), size = 1, linetype = "dashed") +
geom_line(aes(y = SMA_200, color = "200-day SMA"), size = 1, linetype = "dashed") +
geom_line(aes(y = EMA_50, color = "50-day EMA"), size = 1) +
labs(title = "Tesla Stock Price with 50-day and 200-day SMA, and EMA",
x = "Date", y = "Price ($)") +
scale_color_manual(values = c("Price" = "black",
"50-day SMA" = "blue",
"200-day SMA" = "red",
"50-day EMA" = "green")) +
theme_minimal() +
theme(legend.title = element_blank())
plotly_chart <- ggplotly(Raut)
plotly_chart
The graph above has shows all the combination of price and some relative moving average for Tesla. From the figure we can say that the trend are in increasing rate and we can see positive market trend.
Relative Strength Index (RSI) has been defined as the momentum oscillator that measures the speed and change of price movements. It is commonly used in technical analysis to identify overbought or oversold conditions in a market. I have used RSI to see the Tesla status and depict a grpah.
tesla_data$RSI <- RSI(tesla_data$Price, n = 14)
gg_rsi <- ggplot(tesla_data, aes(x = Date, y = RSI)) +
geom_line(color = "purple", size = 1) +
geom_hline(yintercept = c(30, 70), linetype = "dashed", color = "red") +
labs(title = "Tesla Stock RSI Indicator", x = "Date", y = "RSI") +
theme_minimal()
plotly_chart <- ggplotly(gg_rsi)
plotly_chart
RSI above 70 generally indicates that the asset is overbought, meaning the price has risen too quickly and could be due for a pullback or correction which incur in 2020 and 2024 in case of Tesla. Similarly, RSI below 30 typically suggests that the asset is oversold, meaning the price has fallen too quickly and could be due for a bounce or reversal and it occurs in 2023. Other then that, the price of Tessa’s values is between 30 and 70 indicate a neutral condition, where the price is neither overbought nor oversold.
I have done an monte carlo simulation for Tesla which define as computational technique used to understand the impact of uncertainty and variability in models and processes. I have generated 20 possible paths which can occur for Tesla. Following formula has been used: simulated_prices[t] <- simulated_prices[t - 1] * exp((mean_return - 0.5 * volatility^2) * dt + volatility * sqrt(dt) * random_shock)
This Monte Carlo simulation is a versatile and robust tool for understanding and quantifying risk, enabling more informed decision-making in scenarios involving uncertainty about the stock of Tesla.
mean_return <- mean(tesla_data$Return)
volatility <- sd(tesla_data$Return)
num_simulations <- 20
num_days <- 252
initial_price <- tail(tesla_data$Price, 1)
tesla_data$Return <- (tesla_data$Price - lag(tesla_data$Price)) / lag(tesla_data$Price)
mean_return <- mean(tesla_data$Return, na.rm = TRUE)
volatility <- sd(tesla_data$Return, na.rm = TRUE)
dt <- 1 / 252
simulated_paths <- data.frame(Date = rep(seq(from = Sys.Date(), by = "day", length.out = num_days), num_simulations),
Path = rep(1:num_simulations, each = num_days),
Price = NA)
set.seed(123)
for (i in 1:num_simulations) {
simulated_prices <- numeric(num_days)
simulated_prices[1] <- initial_price
for (t in 2:num_days) {
random_shock <- rnorm(1, mean = 0, sd = 1)
simulated_prices[t] <- simulated_prices[t - 1] * exp((mean_return - 0.5 * volatility^2) * dt + volatility * sqrt(dt) * random_shock)
}
simulated_paths$Price[simulated_paths$Path == i] <- simulated_prices
}
MC <- ggplot(simulated_paths, aes(x = Date, y = Price, group = Path, color = as.factor(Path))) +
geom_line() +
labs(title = "Monte Carlo Simulation: 20 Paths of Tesla Stock Price",
x = "Date", y = "Stock Price ($)", color = "Simulation Path") +
theme_minimal() +
theme(legend.position = "none") +
scale_color_viridis_d()
plotly_chart <- ggplotly(MC)
plotly_chart
I have used bollinger to see the price status of Tesla in last 8 years. Sometime the price has gone with upper band and sometimes with the lower band. These trends for instance shows that weather the stock is overbought or oversold. These can cause the uncertaining of bolling and breaing of the stock.
bollinger <- BBands(tesla_data$Price, n = 20, sd = 2)
tesla_data <- cbind(tesla_data, bollinger)
gg_bb <- ggplot(tesla_data, aes(x = Date, y = Price)) +
geom_line(color = "black", size = 1, aes(color = "Price")) + # Line for stock price
geom_line(aes(y = up, color = "Upper Band"), linetype = "dashed", size = 1) + # Upper Bollinger Band
geom_line(aes(y = dn, color = "Lower Band"), linetype = "dashed", size = 1) + # Lower Bollinger Band
geom_line(aes(y = mavg, color = "Moving Average"), linetype = "dashed", size = 1) + # Moving Average
labs(title = "Tesla Stock Bollinger Bands", x = "Date", y = "Price ($)") +
scale_color_manual(values = c("Price" = "black", "Upper Band" = "blue", "Lower Band" = "red", "Moving Average" = "green")) +
theme_minimal() +
theme(legend.title = element_blank())
gg_bb
## 6.2 Risk-Return Profile
sharpe_ratio <- mean(tesla_data$Return, na.rm = TRUE) /
sd(tesla_data$Return, na.rm = TRUE)
cat("\nSharpe Ratio:", round(sharpe_ratio, 3))
##
## Sharpe Ratio: 0.119
This value indicates that for every unit of risk, your investment or portfolio is only generating 0.118 units of excess return over the risk-free rate
This code groups Tesla stock data by Date, calculates the average return for each date, and then plots it as a bar chart using ggplot2. The bars (in steel blue) show how the average return varies over time. The x-axis shows the date by year, and the y-axis shows the average return.
tesla_data %>%
group_by(Date) %>%
summarize(Avg_Return = mean(Return, na.rm = TRUE)) %>%
ggplot(aes(x = Date, y = Avg_Return)) +
geom_col(fill = "steelblue") +
labs(title = "Seasonality: Average Returns by Week of Year",
y = "Average Return",
x = "Week Number") + scale_x_date(date_breaks = "1 year", date_labels = "%Y")+
theme_minimal()