1. Introduction

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.

2. Closing Price Analysis

2.1 Full Period (April 2018 - March 2026)

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.

2.2 Pre-Covid (April 2018 - March 2020)

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.

2.3 During Covid (March 2020 - March 2022)

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.

2.4 Post-Covid (April 2022 - March 2026)

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.

3. Daily Returns Analysis

3.1 Full Period (April 2018 - March 2026)

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.

3.2 Pre-Covid (April 2018 - March 2020)

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.

3.3 During Covid (March 2020 - March 2022)

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.

3.4 Post-Covid (April 2022 - March 2026)

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.

4. Conclusion

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

  1. Volatility peaked during Covid. The standard deviation of daily returns was highest during the Covid period for both HDFC Bank and Nifty Bank, roughly 30-50% higher than the Pre-Covid and Post-Covid levels, confirming that the pandemic sharply increased day-to-day price uncertainty in the banking sector.
  2. Volatility settled Post-Covid. Return volatility fell to its lowest level Post-Covid, suggesting the sector stabilized as pandemic-related uncertainty faded and markets normalized.
  3. Fat tails in every period. Kurtosis of daily returns was well above the normal-distribution benchmark of 3 in every sub-period (especially extreme Pre-Covid, partly driven by the sharp late-March 2020 crash sitting just inside that window). Large single-day moves are more common than a normal distribution would predict, a well-documented stylised fact in financial markets.
  4. Upward price trend. Closing prices trended upward across the full period for both series (Pre-Covid to Post-Covid mean price roughly 50% higher), despite the sharp interruption during 2020-2022, reflecting overall sectoral growth over the eight-year window.
  5. Stock tracks the index. HDFC Bank’s return behaviour closely tracks Nifty Bank’s throughout, which is expected given HDFC Bank’s large weight within the Nifty Bank index. This is evidence that the stock and index were an appropriate pair to compare.

Appendix: Code to reproduce the analysis

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”)