#Getting the data from Yahoo Finance
brka<-getSymbols('BRK-A',src='yahoo',from='2019-01-01',to='2022-02-28',auto.assign=FALSE)
spy<-getSymbols('SPY',src='yahoo',from='2019-01-01',to='2022-02-28',auto.assign=FALSE)
#Subsetting data for training period for the GARCH(1,1) Model
startdate=as.POSIXct('2019-01-01')
enddate=as.POSIXct('2022-01-01')
train_brka=brka[paste(startdate,enddate,sep="::")]
train_spy=spy[paste(startdate,enddate,sep="::")]
chartSeries(brka)

chartSeries(spy)


# Calculating the returns
retb=CalculateReturns(brka$`BRK-A.Adjusted`)
retb=retb[-c(1),]
rets=CalculateReturns(spy$SPY.Adjusted)
rets=rets[-c(1),]
# Calculating the returns
chart_Series(retb)

chart.Histogram(retb,method=c('add.density','add.normal'),colorset = c('blue','red','black'))
legend("topright",legend = c("return","kernel","normal dist"),fill=c('blue','red','black'))

chart_Series(rets)

# Plotting the histogram for the returns
chart.Histogram(rets,method=c('add.density','add.normal'),colorset = c('blue','red','black'))
legend("topright",legend = c("return","kernel","normal dist"),fill=c('blue','red','black'))

#Checking for Normality of the returns
qqnorm(retb,pch=1,frame=FALSE)
qqline(retb,col='steelblue',lwd=2)

qqnorm(rets,pch=1,frame=FALSE)
qqline(rets,col='steelblue',lwd=2)

#Calculating the log returns
logretb=diff(log(brka$`BRK-A.Adjusted`),lag=1)
logrets=diff(log(spy$SPY.Adjusted),lag=1)
chart.Histogram(logretb,method=c('add.density','add.normal'),colorset = c('blue','red','black'))
legend("topright",legend = c("return","kernel","normal dist"),fill=c('blue','red','black'))

chart.Histogram(logrets,method=c('add.density','add.normal'),colorset = c('blue','red','black'))
legend("topright",legend = c("return","kernel","normal dist"),fill=c('blue','red','black'))

#Defining Model Specification for GARCH(1,1), Ftting the log returns for BRKA and forecasting future volatility
model1=ugarchspec(mean.model = list(armaOrder=c(0,0)),variance.model = list(model="sGARCH",garchOrder=c(1,1)),distribution.model='norm')
logretb=na.omit(logretb)# Clearing the NA Values
model_fit=ugarchfit(data=logretb,spec = model1,out.sample=(length(brka$`BRK-A.Adjusted`)-length(train_brka$`BRK-A.Adjusted`)))
model_fit
##
## *---------------------------------*
## * GARCH Model Fit *
## *---------------------------------*
##
## Conditional Variance Dynamics
## -----------------------------------
## GARCH Model : sGARCH(1,1)
## Mean Model : ARFIMA(0,0,0)
## Distribution : norm
##
## Optimal Parameters
## ------------------------------------
## Estimate Std. Error t value Pr(>|t|)
## mu 0.000636 0.000354 1.7960 0.072498
## omega 0.000007 0.000002 4.4668 0.000008
## alpha1 0.140958 0.018519 7.6116 0.000000
## beta1 0.807407 0.019771 40.8372 0.000000
##
## Robust Standard Errors:
## Estimate Std. Error t value Pr(>|t|)
## mu 0.000636 0.000356 1.7852 0.074233
## omega 0.000007 0.000003 2.7471 0.006013
## alpha1 0.140958 0.017290 8.1525 0.000000
## beta1 0.807407 0.029038 27.8052 0.000000
##
## LogLikelihood : 2329.82
##
## Information Criteria
## ------------------------------------
##
## Akaike -6.1530
## Bayes -6.1285
## Shibata -6.1530
## Hannan-Quinn -6.1435
##
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
## statistic p-value
## Lag[1] 1.878 0.17055
## Lag[2*(p+q)+(p+q)-1][2] 3.672 0.09237
## Lag[4*(p+q)+(p+q)-1][5] 5.446 0.12110
## d.o.f=0
## H0 : No serial correlation
##
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
## statistic p-value
## Lag[1] 0.3418 0.5588
## Lag[2*(p+q)+(p+q)-1][5] 1.0336 0.8520
## Lag[4*(p+q)+(p+q)-1][9] 2.1045 0.8922
## d.o.f=2
##
## Weighted ARCH LM Tests
## ------------------------------------
## Statistic Shape Scale P-Value
## ARCH Lag[3] 0.1455 0.500 2.000 0.7029
## ARCH Lag[5] 1.4475 1.440 1.667 0.6062
## ARCH Lag[7] 1.8175 2.315 1.543 0.7559
##
## Nyblom stability test
## ------------------------------------
## Joint Statistic: 4.7729
## Individual Statistics:
## mu 0.04653
## omega 1.25881
## alpha1 0.20719
## beta1 0.11140
##
## Asymptotic Critical Values (10% 5% 1%)
## Joint Statistic: 1.07 1.24 1.6
## Individual Statistic: 0.35 0.47 0.75
##
## Sign Bias Test
## ------------------------------------
## t-value prob sig
## Sign Bias 1.608 0.1083
## Negative Sign Bias 1.466 0.1430
## Positive Sign Bias 1.008 0.3139
## Joint Effect 3.544 0.3151
##
##
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
## group statistic p-value(g-1)
## 1 20 15.11 0.7155
## 2 30 32.10 0.3157
## 3 40 43.47 0.2867
## 4 50 54.05 0.2875
##
##
## Elapsed time : 0.108212
forecast_brka<-ugarchforecast(model_fit,n.ahead=38)
forecast_brka
##
## *------------------------------------*
## * GARCH Model Forecast *
## *------------------------------------*
## Model: sGARCH
## Horizon: 38
## Roll Steps: 0
## Out of Sample: 38
##
## 0-roll forecast [T0=2021-12-31]:
## Series Sigma
## T+1 0.0006364 0.009317
## T+2 0.0006364 0.009453
## T+3 0.0006364 0.009580
## T+4 0.0006364 0.009699
## T+5 0.0006364 0.009810
## T+6 0.0006364 0.009915
## T+7 0.0006364 0.010013
## T+8 0.0006364 0.010105
## T+9 0.0006364 0.010192
## T+10 0.0006364 0.010273
## T+11 0.0006364 0.010350
## T+12 0.0006364 0.010422
## T+13 0.0006364 0.010490
## T+14 0.0006364 0.010554
## T+15 0.0006364 0.010615
## T+16 0.0006364 0.010672
## T+17 0.0006364 0.010726
## T+18 0.0006364 0.010776
## T+19 0.0006364 0.010824
## T+20 0.0006364 0.010869
## T+21 0.0006364 0.010912
## T+22 0.0006364 0.010953
## T+23 0.0006364 0.010991
## T+24 0.0006364 0.011027
## T+25 0.0006364 0.011061
## T+26 0.0006364 0.011093
## T+27 0.0006364 0.011124
## T+28 0.0006364 0.011152
## T+29 0.0006364 0.011180
## T+30 0.0006364 0.011205
## T+31 0.0006364 0.011230
## T+32 0.0006364 0.011253
## T+33 0.0006364 0.011275
## T+34 0.0006364 0.011296
## T+35 0.0006364 0.011315
## T+36 0.0006364 0.011334
## T+37 0.0006364 0.011351
## T+38 0.0006364 0.011368
variance_rate_brka<-coef(model_fit)[2]/(1-coef(model_fit)[3]-coef(model_fit)[4])
LT_vol_brka=sqrt(coef(model_fit)[2]/(1-coef(model_fit)[3]-coef(model_fit)[4]))
#Defining Model Specification for GARCH(1,1), Ftting the log returns for SPY and forecasting future volatility
model2=ugarchspec(mean.model=list(armaOrder=c(0,0)),variance.model=list(model='sGARCH',garchOrder=c(1,1)),distribution.model = 'norm')
logrets=na.omit(logrets)
model2_fit=ugarchfit(data=logrets,spec=model2,out.sample = (length(spy$SPY.Adjusted)-length(train_spy$SPY.Adjusted)))
model2_fit
##
## *---------------------------------*
## * GARCH Model Fit *
## *---------------------------------*
##
## Conditional Variance Dynamics
## -----------------------------------
## GARCH Model : sGARCH(1,1)
## Mean Model : ARFIMA(0,0,0)
## Distribution : norm
##
## Optimal Parameters
## ------------------------------------
## Estimate Std. Error t value Pr(>|t|)
## mu 0.001272 0.000268 4.7463 0.000002
## omega 0.000007 0.000002 3.8050 0.000142
## alpha1 0.285623 0.042327 6.7480 0.000000
## beta1 0.682136 0.022975 29.6909 0.000000
##
## Robust Standard Errors:
## Estimate Std. Error t value Pr(>|t|)
## mu 0.001272 0.000247 5.1493 0.000000
## omega 0.000007 0.000003 1.9791 0.047800
## alpha1 0.285623 0.056981 5.0126 0.000001
## beta1 0.682136 0.067770 10.0654 0.000000
##
## LogLikelihood : 2461.985
##
## Information Criteria
## ------------------------------------
##
## Akaike -6.5026
## Bayes -6.4781
## Shibata -6.5027
## Hannan-Quinn -6.4932
##
## Weighted Ljung-Box Test on Standardized Residuals
## ------------------------------------
## statistic p-value
## Lag[1] 1.246 0.2643
## Lag[2*(p+q)+(p+q)-1][2] 1.694 0.3190
## Lag[4*(p+q)+(p+q)-1][5] 2.745 0.4555
## d.o.f=0
## H0 : No serial correlation
##
## Weighted Ljung-Box Test on Standardized Squared Residuals
## ------------------------------------
## statistic p-value
## Lag[1] 0.4782 0.4892
## Lag[2*(p+q)+(p+q)-1][5] 1.4406 0.7545
## Lag[4*(p+q)+(p+q)-1][9] 2.4803 0.8406
## d.o.f=2
##
## Weighted ARCH LM Tests
## ------------------------------------
## Statistic Shape Scale P-Value
## ARCH Lag[3] 0.01209 0.500 2.000 0.9124
## ARCH Lag[5] 1.39278 1.440 1.667 0.6209
## ARCH Lag[7] 1.64297 2.315 1.543 0.7923
##
## Nyblom stability test
## ------------------------------------
## Joint Statistic: 1.5416
## Individual Statistics:
## mu 0.07789
## omega 0.32591
## alpha1 0.15593
## beta1 0.13604
##
## Asymptotic Critical Values (10% 5% 1%)
## Joint Statistic: 1.07 1.24 1.6
## Individual Statistic: 0.35 0.47 0.75
##
## Sign Bias Test
## ------------------------------------
## t-value prob sig
## Sign Bias 1.7064 0.08835 *
## Negative Sign Bias 0.4286 0.66832
## Positive Sign Bias 0.5488 0.58328
## Joint Effect 5.4766 0.14004
##
##
## Adjusted Pearson Goodness-of-Fit Test:
## ------------------------------------
## group statistic p-value(g-1)
## 1 20 40.67 0.0026725
## 2 30 61.14 0.0004443
## 3 40 68.44 0.0024629
## 4 50 85.53 0.0009574
##
##
## Elapsed time : 0.09510994
forecast_spy<-ugarchforecast(model2_fit,n.ahead=38)
forecast_spy
##
## *------------------------------------*
## * GARCH Model Forecast *
## *------------------------------------*
## Model: sGARCH
## Horizon: 38
## Roll Steps: 0
## Out of Sample: 38
##
## 0-roll forecast [T0=2021-12-31]:
## Series Sigma
## T+1 0.001272 0.007256
## T+2 0.001272 0.007588
## T+3 0.001272 0.007897
## T+4 0.001272 0.008184
## T+5 0.001272 0.008453
## T+6 0.001272 0.008705
## T+7 0.001272 0.008942
## T+8 0.001272 0.009166
## T+9 0.001272 0.009377
## T+10 0.001272 0.009578
## T+11 0.001272 0.009768
## T+12 0.001272 0.009948
## T+13 0.001272 0.010119
## T+14 0.001272 0.010282
## T+15 0.001272 0.010438
## T+16 0.001272 0.010586
## T+17 0.001272 0.010728
## T+18 0.001272 0.010863
## T+19 0.001272 0.010992
## T+20 0.001272 0.011116
## T+21 0.001272 0.011234
## T+22 0.001272 0.011348
## T+23 0.001272 0.011456
## T+24 0.001272 0.011561
## T+25 0.001272 0.011661
## T+26 0.001272 0.011757
## T+27 0.001272 0.011849
## T+28 0.001272 0.011937
## T+29 0.001272 0.012022
## T+30 0.001272 0.012104
## T+31 0.001272 0.012182
## T+32 0.001272 0.012258
## T+33 0.001272 0.012330
## T+34 0.001272 0.012400
## T+35 0.001272 0.012468
## T+36 0.001272 0.012532
## T+37 0.001272 0.012595
## T+38 0.001272 0.012655
variance_rate_spy<-coef(model_fit)[2]/(1-coef(model_fit)[3]-coef(model_fit)[4])
LT_vol_spy=sqrt(coef(model2_fit)[2]/(1-coef(model2_fit)[3]-coef(model2_fit)[4]))
# VaR Estimation based on returns
retb<-(train_brka$`BRK-A.Adjusted`-lag.xts(train_brka$`BRK-A.Adjusted`))/lag.xts(train_brka$`BRK-A.Adjusted`)
rets<-(train_spy$SPY.Adjusted-lag.xts(train_spy$SPY.Adjusted))/lag.xts(train_spy$SPY.Adjusted)
retb=na.omit(retb)
rets=na.omit(rets)
corr<-cor(retb,rets)
#Daily Positional Losses historically
portfolio_size=1000000
daily_pos_b=retb*portfolio_size
daily_pnl_b=daily_pos_b
daily_pnl_b=na.omit(daily_pnl_b)
VaR_brka=quantile(daily_pnl_b,0.01)
ES_brka<-mean(sort(as.numeric(daily_pnl_b))[1:7])
daily_pos_s=rets*portfolio_size
daily_pnl_s=daily_pos_s
daily_pnl_s=na.omit(daily_pnl_s)
VaR_spy=quantile(daily_pnl_s,0.01)
ES_spy<-mean(sort(as.numeric(daily_pnl_s))[1:7])
daily_pos_port=daily_pos_s+daily_pos_b
daily_pnl_port=na.omit(daily_pos_port)
VaR_port=quantile(daily_pnl_port,0.01)
ES_port=mean(sort(as.numeric(daily_pnl_port))[1:7])
diversification_benefit=VaR_port-VaR_spy-VaR_brka
#Plotting the positional losses
temp1<-sort(as.numeric(daily_pnl_b))
temp2<-sort(as.numeric(daily_pnl_s))
temp3<-sort(as.numeric(daily_pnl_s+daily_pnl_b))
pnl<-data.frame(cbind(temp1,temp2,temp3))
colnames(pnl)<-c('PnL_BRKA','PnL_SPY','PnL_Portfolio')
g<-ggplot(pnl,mapping=aes(x=PnL_BRKA))
g+geom_histogram(color='darkblue',fill='lightblue')+geom_vline(data=pnl,aes(xintercept=quantile(PnL_BRKA,0.01),col='VaR'))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

g2<-ggplot(pnl,mapping=aes(x=PnL_SPY))
g2+geom_histogram(color='darkblue',fill='lightblue')+geom_vline(data=pnl,aes(xintercept=quantile(PnL_SPY,0.01),col='VaR'))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

g3<-ggplot(pnl,mapping=aes(x=PnL_Portfolio))
g3+geom_histogram(color='darkblue',fill='lightblue')+geom_vline(data=pnl,aes(xintercept=quantile(PnL_Portfolio,0.01),col='VaR'))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

#VaR backtesting:
#Subset the dates to get the data
backtest_start=as.POSIXct('2021-02-28')
backtest_end=as.POSIXct('2022-02-28')
backtest_brka=brka[paste(backtest_start,backtest_end,sep="::")]
backtest_spy=spy[paste(backtest_start,backtest_end,sep="::")]
#Calculating the daily returns for the period
retb_bt<-CalculateReturns(backtest_brka$`BRK-A.Adjusted`)
rets_bt<-CalculateReturns(backtest_spy$SPY.Adjusted)
daily_pos_brka_bt<-rets_bt*portfolio_size
daily_pos_spy_bt<-rets_bt*portfolio_size
daily_pos_brka_bt=na.omit(daily_pos_brka_bt)
daily_pos_spy_bt=na.omit(daily_pos_spy_bt)
#Number of days the loss crosses VaR
count_spy=sum(daily_pos_spy_bt<VaR_spy)
count_spy
## [1] 0
count_brka=sum(daily_pos_brka_bt<VaR_brka)
count_brka
## [1] 0
daily_pos_port_bt=daily_pos_brka_bt+daily_pos_spy_bt
count_port=sum(daily_pos_port_bt<VaR_port)
count_port
## [1] 0
#VaR BASED ON NORMAL DISTRIBUTION
sigb=sd(retb)
sigs=sd(rets)
portsig=(sigb^2/4+sigs^2/4+2*sigs*sigb*corr)^0.5
VaR_b_N=-qnorm(0.99)*sigb*10^6
VaR_s_N=-qnorm(0.99)*sigs*10^6
VaR_p_N=-qnorm(0.99)*portsig*2*10^6
VaR_b_N
## [1] -33150.44
VaR_s_N
## [1] -32121.53
VaR_p_N
## SPY.Adjusted
## BRK-A.Adjusted -94621
#ECONOMIC CAPITAL
RAROC_spy<-as.numeric(rets_bt[paste(as.POSIXct('2022-01-03'))])*10^6/VaR_spy
RAROC_brka<-as.numeric(retb_bt[paste(as.POSIXct('2022-01-03'))])*10^6/VaR_brka
RAROC_port<-(as.numeric(rets_bt[paste(as.POSIXct('2022-01-03'))])+as.numeric(retb_bt[paste(as.POSIXct('2022-01-03'))]))*10^6/VaR_port
RAROC_brka
## 1%
## -0.2096993
RAROC_spy
## 1%
## -0.1318538
RAROC_port
## 1%
## -0.1679277
#export the data for the report
#write.csv(as.data.frame(brka),"brka.csv")
#write.csv(as.data.frame(spy),"spy.csv")