This assignment applies descriptive analytics to a stock and its corresponding sectoral index. The stock selected is HDFC Bank (HDBK), and the sectoral index selected is Nifty Bank, since HDFC Bank is a constituent of the banking sector index. Daily closing price data was collected for the period 1 April 2018 to 31 March 2026.
To study how the Covid-19 pandemic affected price behaviour and volatility, the full period was further divided into three sub-periods:
| Sub-period | Dates |
|---|---|
| Pre-Covid | 1 April 2018 - 24 March 2020 |
| During Covid | 25 March 2020 - 31 March 2022 |
| Post-Covid | 1 April 2022 - 31 March 2026 |
For each period, descriptive statistics and visualizations were generated first on the closing price series, and then on the daily log returns series, using R.
Daily log returns were computed as the difference in the natural log of consecutive closing prices:
\[Return_t = \ln(Price_t) - \ln(Price_{t-1})\]
Log returns are the standard convention in financial analytics because they are additive over time and better approximate a stationary series compared to raw prices.
Note: The R code is shown for each step and can be expanded using the “Code” buttons. Console outputs and plots are from the original R session.
R commands used
summary(data$HDFC_Price); sd(data$HDFC_Price); var(data$HDFC_Price)
skewness(data$HDFC_Price); kurtosis(data$HDFC_Price)
# repeat for data$NiftyBank_Price
R console output (descriptive statistics)
> summary(data$HDFC_Price)
Min. 1st Qu. Median Mean 3rd Qu. Max.
382.90 598.83 741.22 722.45 819.99 1012.90
> sd(data$HDFC_Price)
[1] 147.286
> var(data$HDFC_Price)
[1] 21693.18
> skewness(data$HDFC_Price)
[1] -0.0376
> kurtosis(data$HDFC_Price)
[1] 2.1747
> summary(data$NiftyBank_Price)
Min. 1st Qu. Median Mean 3rd Qu. Max.
16917.65 29552.65 37374.90 38678.41 47839.06 61550.80
> sd(data$NiftyBank_Price)
[1] 11031.302
> var(data$NiftyBank_Price)
[1] 121689628.64
> skewness(data$NiftyBank_Price)
[1] 0.2056
> kurtosis(data$NiftyBank_Price)
[1] 1.9884
Plots
Interpretation
Over this period, HDFC Bank’s closing price averaged Rs. 722.45, ranging from Rs. 382.90 to Rs. 1012.90, with a standard deviation of Rs. 147.29. The skewness of -0.038 indicates a roughly symmetric distribution, and a kurtosis of 2.175 suggests a flatter-than-normal distribution of prices. Nifty Bank moved similarly, averaging 38678.4 with a standard deviation of 11031.3, indicating that the sectoral index and the stock broadly tracked the same trend over this window.
R commands used
summary(precovid$HDFC_Price); sd(precovid$HDFC_Price); var(precovid$HDFC_Price)
skewness(precovid$HDFC_Price); kurtosis(precovid$HDFC_Price)
# repeat for precovid$NiftyBank_Price
R console output (descriptive statistics)
> summary(precovid$HDFC_Price)
Min. 1st Qu. Median Mean 3rd Qu. Max.
382.90 514.10 544.64 553.34 602.66 649.58
> sd(precovid$HDFC_Price)
[1] 51.323
> var(precovid$HDFC_Price)
[1] 2634.09
> skewness(precovid$HDFC_Price)
[1] 0.0433
> kurtosis(precovid$HDFC_Price)
[1] 2.1636
> summary(precovid$NiftyBank_Price)
Min. 1st Qu. Median Mean 3rd Qu. Max.
16917.65 26573.40 27801.45 28190.98 30333.10 32443.85
> sd(precovid$NiftyBank_Price)
[1] 2378.227
> var(precovid$NiftyBank_Price)
[1] 5655962.39
> skewness(precovid$NiftyBank_Price)
[1] -0.4434
> kurtosis(precovid$NiftyBank_Price)
[1] 4.1692
Plots
Interpretation
Over this period, HDFC Bank’s closing price averaged Rs. 553.34, ranging from Rs. 382.90 to Rs. 649.58, with a standard deviation of Rs. 51.32. The skewness of 0.043 indicates a roughly symmetric distribution, and a kurtosis of 2.164 suggests a flatter-than-normal distribution of prices. Nifty Bank moved similarly, averaging 28191.0 with a standard deviation of 2378.2, indicating that the sectoral index and the stock broadly tracked the same trend over this window.
R commands used
summary(duringcovid$HDFC_Price); sd(duringcovid$HDFC_Price); var(duringcovid$HDFC_Price)
skewness(duringcovid$HDFC_Price); kurtosis(duringcovid$HDFC_Price)
# repeat for duringcovid$NiftyBank_Price
R console output (descriptive statistics)
> summary(duringcovid$HDFC_Price)
Min. 1st Qu. Median Mean 3rd Qu. Max.
405.92 561.90 719.50 675.37 756.77 842.25
> sd(duringcovid$HDFC_Price)
[1] 112.496
> var(duringcovid$HDFC_Price)
[1] 12655.31
> skewness(duringcovid$HDFC_Price)
[1] -0.8193
> kurtosis(duringcovid$HDFC_Price)
[1] 2.3111
> summary(duringcovid$NiftyBank_Price)
Min. 1st Qu. Median Mean 3rd Qu. Max.
17249.30 23075.28 33769.12 30863.47 36050.90 41238.30
> sd(duringcovid$NiftyBank_Price)
[1] 6747.433
> var(duringcovid$NiftyBank_Price)
[1] 45527852.39
> skewness(duringcovid$NiftyBank_Price)
[1] -0.5613
> kurtosis(duringcovid$NiftyBank_Price)
[1] 1.7915
Plots
Interpretation
Over this period, HDFC Bank’s closing price averaged Rs. 675.37, ranging from Rs. 405.92 to Rs. 842.25, with a standard deviation of Rs. 112.50. The skewness of -0.819 indicates a left-skewed (long tail toward lower prices) distribution, and a kurtosis of 2.311 suggests a flatter-than-normal distribution of prices. Nifty Bank moved similarly, averaging 30863.5 with a standard deviation of 6747.4, indicating that the sectoral index and the stock broadly tracked the same trend over this window.
R commands used
summary(postcovid$HDFC_Price); sd(postcovid$HDFC_Price); var(postcovid$HDFC_Price)
skewness(postcovid$HDFC_Price); kurtosis(postcovid$HDFC_Price)
# repeat for postcovid$NiftyBank_Price
R console output (descriptive statistics)
> summary(postcovid$HDFC_Price)
Min. 1st Qu. Median Mean 3rd Qu. Max.
639.06 757.19 819.41 829.73 894.43 1012.90
> sd(postcovid$HDFC_Price)
[1] 94.525
> var(postcovid$HDFC_Price)
[1] 8935.05
> skewness(postcovid$HDFC_Price)
[1] 0.2831
> kurtosis(postcovid$HDFC_Price)
[1] 2.2165
> summary(postcovid$NiftyBank_Price)
Min. 1st Qu. Median Mean 3rd Qu. Max.
32617.10 42985.20 47840.15 47812.07 53167.10 61550.80
> sd(postcovid$NiftyBank_Price)
[1] 6990.805
> var(postcovid$NiftyBank_Price)
[1] 48871349.42
> skewness(postcovid$NiftyBank_Price)
[1] -0.0585
> kurtosis(postcovid$NiftyBank_Price)
[1] 2.2022
Plots
Interpretation
Over this period, HDFC Bank’s closing price averaged Rs. 829.73, ranging from Rs. 639.06 to Rs. 1012.90, with a standard deviation of Rs. 94.53. The skewness of 0.283 indicates a roughly symmetric distribution, and a kurtosis of 2.216 suggests a flatter-than-normal distribution of prices. Nifty Bank moved similarly, averaging 47812.1 with a standard deviation of 6990.8, indicating that the sectoral index and the stock broadly tracked the same trend over this window.
R commands used
summary(data$HDFC_Return); sd(data$HDFC_Return); var(data$HDFC_Return)
skewness(data$HDFC_Return); kurtosis(data$HDFC_Return)
# repeat for data$NiftyBank_Return
R console output (descriptive statistics)
> summary(data$HDFC_Return)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.134700 -0.007100 0.000400 0.000200 0.007400 0.109700
> sd(data$HDFC_Return)
[1] 0.0153000
> var(data$HDFC_Return)
[1] 0.000200
> skewness(data$HDFC_Return)
[1] -0.3638
> kurtosis(data$HDFC_Return)
[1] 12.9176
> summary(data$NiftyBank_Return)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.183100 -0.005800 0.000800 0.000400 0.007000 0.100000
> sd(data$NiftyBank_Return)
[1] 0.0145000
> var(data$NiftyBank_Return)
[1] 0.000200
> skewness(data$NiftyBank_Return)
[1] -1.2682
> kurtosis(data$NiftyBank_Return)
[1] 22.6664
Plots
Interpretation
Daily log returns for HDFC Bank averaged close to zero (mean = 0.00020), which is expected for return series, with a standard deviation of 0.01530 indicating the typical size of daily price swings. The kurtosis of 12.92 is well above the normal-distribution benchmark of 3, confirming the presence of fat tails — i.e., extreme single-day moves occurred more often than a normal distribution would predict. The skewness of -0.364 shows returns were left-skewed, meaning sharp down-moves were somewhat more extreme than up-moves. Nifty Bank returns show a similar pattern (SD = 0.01450, kurtosis = 22.67), reinforcing that volatility in the stock closely mirrors volatility in its sectoral index.
R commands used
summary(precovid$HDFC_Return); sd(precovid$HDFC_Return); var(precovid$HDFC_Return)
skewness(precovid$HDFC_Return); kurtosis(precovid$HDFC_Return)
# repeat for precovid$NiftyBank_Return
R console output (descriptive statistics)
> summary(precovid$HDFC_Return)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.134700 -0.006400 0.000200 -0.000500 0.006700 0.085700
> sd(precovid$HDFC_Return)
[1] 0.0149000
> var(precovid$HDFC_Return)
[1] 0.000200
> skewness(precovid$HDFC_Return)
[1] -2.2348
> kurtosis(precovid$HDFC_Return)
[1] 25.6533
> summary(precovid$NiftyBank_Return)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.183100 -0.006900 0.000200 -0.000700 0.007200 0.079800
> sd(precovid$NiftyBank_Return)
[1] 0.0161000
> var(precovid$NiftyBank_Return)
[1] 0.000300
> skewness(precovid$NiftyBank_Return)
[1] -3.6309
> kurtosis(precovid$NiftyBank_Return)
[1] 42.1842
Plots
Interpretation
Daily log returns for HDFC Bank averaged close to zero (mean = -0.00050), which is expected for return series, with a standard deviation of 0.01490 indicating the typical size of daily price swings. The kurtosis of 25.65 is well above the normal-distribution benchmark of 3, confirming the presence of fat tails — i.e., extreme single-day moves occurred more often than a normal distribution would predict. The skewness of -2.235 shows returns were left-skewed, meaning sharp down-moves were somewhat more extreme than up-moves. Nifty Bank returns show a similar pattern (SD = 0.01610, kurtosis = 42.18), reinforcing that volatility in the stock closely mirrors volatility in its sectoral index.
R commands used
summary(duringcovid$HDFC_Return); sd(duringcovid$HDFC_Return); var(duringcovid$HDFC_Return)
skewness(duringcovid$HDFC_Return); kurtosis(duringcovid$HDFC_Return)
# repeat for duringcovid$NiftyBank_Return
R console output (descriptive statistics)
> summary(duringcovid$HDFC_Return)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.083900 -0.009600 0.000900 0.001300 0.011600 0.109700
> sd(duringcovid$HDFC_Return)
[1] 0.0196000
> var(duringcovid$HDFC_Return)
[1] 0.000400
> skewness(duringcovid$HDFC_Return)
[1] 0.3558
> kurtosis(duringcovid$HDFC_Return)
[1] 6.8127
> summary(duringcovid$NiftyBank_Return)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.086800 -0.007800 0.001500 0.001500 0.011900 0.100000
> sd(duringcovid$NiftyBank_Return)
[1] 0.0194000
> var(duringcovid$NiftyBank_Return)
[1] 0.000400
> skewness(duringcovid$NiftyBank_Return)
[1] 0.0610
> kurtosis(duringcovid$NiftyBank_Return)
[1] 6.6171
Plots
Interpretation
Daily log returns for HDFC Bank averaged close to zero (mean = 0.00130), which is expected for return series, with a standard deviation of 0.01960 indicating the typical size of daily price swings. The kurtosis of 6.81 is well above the normal-distribution benchmark of 3, confirming the presence of fat tails — i.e., extreme single-day moves occurred more often than a normal distribution would predict. The skewness of 0.356 shows returns were right-skewed, meaning sharp up-moves were somewhat more extreme than down-moves. Nifty Bank returns show a similar pattern (SD = 0.01940, kurtosis = 6.62), reinforcing that volatility in the stock closely mirrors volatility in its sectoral index.
R commands used
summary(postcovid$HDFC_Return); sd(postcovid$HDFC_Return); var(postcovid$HDFC_Return)
skewness(postcovid$HDFC_Return); kurtosis(postcovid$HDFC_Return)
# repeat for postcovid$NiftyBank_Return
R console output (descriptive statistics)
> summary(postcovid$HDFC_Return)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.088100 -0.006500 0.000400 -0.000000 0.006600 0.095400
> sd(postcovid$HDFC_Return)
[1] 0.0128000
> var(postcovid$HDFC_Return)
[1] 0.000200
> skewness(postcovid$HDFC_Return)
[1] -0.2942
> kurtosis(postcovid$HDFC_Return)
[1] 10.0503
> summary(postcovid$NiftyBank_Return)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.082800 -0.004600 0.000800 0.000300 0.005400 0.044300
> sd(postcovid$NiftyBank_Return)
[1] 0.0100000
> var(postcovid$NiftyBank_Return)
[1] 0.000100
> skewness(postcovid$NiftyBank_Return)
[1] -0.7014
> kurtosis(postcovid$NiftyBank_Return)
[1] 9.5381
Plots
Interpretation
Daily log returns for HDFC Bank averaged close to zero (mean = -0.00000), which is expected for return series, with a standard deviation of 0.01280 indicating the typical size of daily price swings. The kurtosis of 10.05 is well above the normal-distribution benchmark of 3, confirming the presence of fat tails — i.e., extreme single-day moves occurred more often than a normal distribution would predict. The skewness of -0.294 shows returns were left-skewed, meaning sharp down-moves were somewhat more extreme than up-moves. Nifty Bank returns show a similar pattern (SD = 0.01000, kurtosis = 9.54), reinforcing that volatility in the stock closely mirrors volatility in its sectoral index.
The table below summarizes daily-return volatility and distribution shape for HDFC Bank and Nifty Bank across the three sub-periods, drawn directly from Section 3.
| Period | HDFC SD | HDFC Skew | HDFC Kurtosis | Nifty Bank SD | Nifty Bank Skew | Nifty Bank Kurtosis |
|---|---|---|---|---|---|---|
| Pre-Covid | 0.0149 | -2.235 | 25.65 | 0.0161 | -3.631 | 42.18 |
| During Covid | 0.0196 | 0.356 | 6.81 | 0.0194 | 0.061 | 6.62 |
| Post-Covid | 0.0128 | -0.294 | 10.05 | 0.0100 | -0.701 | 9.54 |
Key takeaways
The sections above use the saved console output and plots. To re-run
the analysis on your own data, use the template below (change the file
name and column names to match your dataset) and set
eval = TRUE.
library(moments) # skewness(), kurtosis()
library(dplyr)
data <- read.csv("hdfc_nifty_bank.csv") # columns: Date, HDFC_Price, NiftyBank_Price
data$Date <- as.Date(data$Date)
# Daily log returns: ln(P_t) - ln(P_t-1)
data$HDFC_Return <- c(NA, diff(log(data$HDFC_Price)))
data$NiftyBank_Return <- c(NA, diff(log(data$NiftyBank_Price)))
data <- na.omit(data)
# Sub-periods
precovid <- subset(data, Date >= as.Date("2018-04-01") & Date <= as.Date("2020-03-24"))
duringcovid <- subset(data, Date >= as.Date("2020-03-25") & Date <= as.Date("2022-03-31"))
postcovid <- subset(data, Date >= as.Date("2022-04-01") & Date <= as.Date("2026-03-31"))
# Example: descriptive statistics for one series
summary(data$HDFC_Price); sd(data$HDFC_Price); var(data$HDFC_Price)
skewness(data$HDFC_Price); kurtosis(data$HDFC_Price)
install.packages(“rmarkdown”)