library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(zoo)
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(scales)
library(plotly)
## Loading required package: ggplot2
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
library(ggplot2)
library(gganimate)
library(gifski)
library(av)
df <- read.csv("Heidelberg Cement Bangladesh Stock Price History.csv", stringsAsFactors = FALSE)
head(df$Date)
## [1] "3/27/2025" "3/25/2025" "3/24/2025" "3/23/2025" "3/20/2025" "3/19/2025"
str(df$Date)
## chr [1:3578] "3/27/2025" "3/25/2025" "3/24/2025" "3/23/2025" "3/20/2025" ...
The dataset contains 3,578 rows and 7 columns, tracking daily stock price movements.
Variables:
1.Date – Trading date
2.Price – Closing stock price
3.Open – Opening stock price
4.High – Highest stock price of the day
5.Low – Lowest stock price of the day
6.Vol. – Trading volume
7.Change % – Daily percentage change
df$Date <- as.Date(df$Date, format = "%m/%d/%Y")
colnames(df)[colnames(df) == "Change.."] <- "ChangePerc"
df$ChangePerc <- gsub("%", "", df$ChangePerc)
df$ChangePerc <- as.numeric(df$ChangePerc) / 100
summary(df$ChangePerc)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -0.1646000 -0.0085000 -0.0005500 0.0002196 0.0067000 0.2260000
df$Vol. <- gsub("K", "", df$Vol.)
df$Vol. <- gsub(",", "", df$Vol.)
df$Vol. <- as.numeric(df$Vol.) * 1000
## Warning: NAs introduced by coercion
sum(is.na(df$Vol.))
## [1] 2
df <- df[!is.na(df$Vol.), ]
df <- na.omit(df)
# 1. Summary of Stock Prices
summary(df$Price)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 125.3 234.4 300.9 332.2 427.1 675.1
# 2. Stock Price Volatility
range(df$Price)
## [1] 125.3 675.1
sd(df$Price)
## [1] 130.8648
# 3. Daily Percentage Change
summary(df$ChangePerc)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -0.1646000 -0.0085000 -0.0006000 0.0001802 0.0066250 0.2260000
# 4. Trading Volume Analysis
summary(df$Vol.)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0 6948 18130 54814 52413 974650
# 5. Correlation Between Stock Prices & Volume
cor(df$Price, df$Vol., use = "complete.obs")
## [1] 0.1666656
# 6. Rolling 30-day Moving Average for Trends
df$MovingAvg <- rollmean(df$Price, k = 30, fill = NA, align = "right")
ggplot(df, aes(x = Date, y = Price)) +
geom_line(color = "blue", alpha = 0.7, size = 1.5) +
geom_smooth(method = "lm", color = "red") +
scale_x_date(date_labels = "%Y", date_breaks = "2 years") +
theme_minimal() +
ggtitle("Stock Price Trend of Heidelberg Cement Bangladesh")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `geom_smooth()` using formula = 'y ~ x'
This plot shows the trend of Heidelberg Cement Bangladesh’s stock price over time. The blue line represents the daily closing prices, while the red regression line shows the overall trend of stock price movement over the period. The x-axis is labeled with years, and the transparency of the blue line (alpha = 0.7) helps reduce clutter and make the plot clearer.
ggplotly()
## `geom_smooth()` using formula = 'y ~ x'
p_anim <- ggplot(df, aes(x = Date, y = Price)) +
geom_line(color = "blue") +
transition_reveal(Date) +
ggtitle("Stock Price Movement Over Time")
animate(p_anim, fps = 10, duration = 10)
# Save the animation
anim_save("Stock_Price_Animation.gif", animation = p_anim)