Simulating returns using copula and SPD distribution

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Simulating returns using copula and SPD distribution

GARCH
Hi,

I am fitting some SPD distributions to past returns and some Copula to
simulate the dependance.
I am struggling with the simulation part, as the returns I simulate a
clearly out of line after some time.

I have attached some sample code in order to clarify the point.

I first calibrate the SPD distribution on the past returns:

#Calibrating the SPD distributioon the residuals of an ARMA+GARCH

*spec.u1 = ugarchspec(mean.model=list(armaOrder=c(1,1)),
distribution="std")*

*fit.u1 = ugarchfit(spec.u1, return.u1)*

*z.u1= residuals(fit.u1, standardize=TRUE)*

*gpd.u1 = spdfit(z.u1, upper=1. - tailFraction, lower=tailFraction)*


#Calibrating the SPD distributioon the residuals of an ARMA+GARCH

*spec.u2 = ugarchspec(mean.model=list(armaOrder=c(1,1)),
distribution="std")*

*fit.u2 = ugarchfit(spec.u2, return.u1)*

*z.u2= residuals(fit.u2, standardize=TRUE)*

*gpd.u2 = spdfit(z.u2, upper=1. - tailFraction, lower=tailFraction)*


Then, once we have all this set, we need to calibrate the Copula of our
choice


#Calibrate the Copula

#We extract the residuals from the xts into a vector

*res.u1 = as.vector(z.u1[,1])*

*res.u2 = as.vector(z.u2[,1])*

#We transform the margin to uniform

*U.u1 = pspd(res.u1, gpd.u1)*

*U.u2 = pspd(res.u2, gpd.u2)*



#We create the matrix to help us calibrate the Copula

*test <-list()*

*test[[1]] = U.u1*

*test[[2]] = U.u2*

*test_matrix = do.call(rbind, test)*



*set.seed(123)*



#We define the Copula we want to use

*tcopula<-tCopula(param=0.5, dim=2, dispstr = "ex", df =6)*

#We fit the Copula with maximum Likelihood

*fit.mpl <- fitCopula(tcopula, t(test_matrix), method="ml")*



#We get back the parameters

#Rho

*rho.fit = fit.mpl@copula@parameters[1]*

#Degrees of Freedom

*df.fit = fit.mpl@copula@parameters[2]*



#Create fitted t-copula object

*t.cop.fit = tCopula(param=rho.fit, dim=2, df=df.fit)*



*margins = c("t", "t")*

*paramMargins = list(list(df=df.fit),list(df=df.fit))*



#Create fitted custom distribution object

*myBvd.tcop.fit = mvdc(copula=t.cop.fit, margins = margins, paramMargins=
paramMargins)*



If all is well, I should be able to run some simulations and simulate my
returns from this set up:


#Generate random numbers from the Copula

*u = rMvdc(nsim, myBvd.tcop.fit)*

*u.1 = u[,1]*

#Generate the simulated returns

*sim.u1 = ugarchsim(fit.u1, n.sim=nsim, startMethod="sample", m.sim=1,*

*                    custom.dist=list(name="sample",distfit=matrix(u.1,
ncol=1)))*

#Get back the simulated returns

*sim.u1.returns = sim.u1@simulation$seriesSim*



The problem lies in the order of magnitude the simulated returns. I can get
some occurrence of +26% for example, which is clearly wrong.


Could someone point me on the wrong part?

I have also a remaining question:

In the univariate case, we can simulate the random number with *rspd(n =
days, gpd.u1)*, and they will be in accordance with the gpd distribtuion
calibrated.

In the multivariate case, can I consider this step to be taken care of by
the random number of the Copula since it has been calibrated on the margins
transformed to Uniform by the gpd distribution function?


Thanks

        [[alternative HTML version deleted]]

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Simulating returns using copula and SPD distribution

alexios
You've missed a step. Think about it:
1. You take z.
2. Fit an spd.
3. Transform it to U using pspd.
4. Fit a copula on U.
5. Sample from copula to generate u.
6. Need to translate u back to z (step 1) using the quantile function
(qspd) and the estimated parameters from step 2.

i.e. you've missed step 6.


-Alexios

On 28/05/2014 16:53, Guillaume PEALAT wrote:

> Hi,
>
> I am fitting some SPD distributions to past returns and some Copula to
> simulate the dependance.
> I am struggling with the simulation part, as the returns I simulate a
> clearly out of line after some time.
>
> I have attached some sample code in order to clarify the point.
>
> I first calibrate the SPD distribution on the past returns:
>
> #Calibrating the SPD distributioon the residuals of an ARMA+GARCH
>
> *spec.u1 = ugarchspec(mean.model=list(armaOrder=c(1,1)),
> distribution="std")*
>
> *fit.u1 = ugarchfit(spec.u1, return.u1)*
>
> *z.u1= residuals(fit.u1, standardize=TRUE)*
>
> *gpd.u1 = spdfit(z.u1, upper=1. - tailFraction, lower=tailFraction)*
>
>
> #Calibrating the SPD distributioon the residuals of an ARMA+GARCH
>
> *spec.u2 = ugarchspec(mean.model=list(armaOrder=c(1,1)),
> distribution="std")*
>
> *fit.u2 = ugarchfit(spec.u2, return.u1)*
>
> *z.u2= residuals(fit.u2, standardize=TRUE)*
>
> *gpd.u2 = spdfit(z.u2, upper=1. - tailFraction, lower=tailFraction)*
>
>
> Then, once we have all this set, we need to calibrate the Copula of our
> choice
>
>
> #Calibrate the Copula
>
> #We extract the residuals from the xts into a vector
>
> *res.u1 = as.vector(z.u1[,1])*
>
> *res.u2 = as.vector(z.u2[,1])*
>
> #We transform the margin to uniform
>
> *U.u1 = pspd(res.u1, gpd.u1)*
>
> *U.u2 = pspd(res.u2, gpd.u2)*
>
>
>
> #We create the matrix to help us calibrate the Copula
>
> *test <-list()*
>
> *test[[1]] = U.u1*
>
> *test[[2]] = U.u2*
>
> *test_matrix = do.call(rbind, test)*
>
>
>
> *set.seed(123)*
>
>
>
> #We define the Copula we want to use
>
> *tcopula<-tCopula(param=0.5, dim=2, dispstr = "ex", df =6)*
>
> #We fit the Copula with maximum Likelihood
>
> *fit.mpl <- fitCopula(tcopula, t(test_matrix), method="ml")*
>
>
>
> #We get back the parameters
>
> #Rho
>
> *rho.fit = fit.mpl@copula@parameters[1]*
>
> #Degrees of Freedom
>
> *df.fit = fit.mpl@copula@parameters[2]*
>
>
>
> #Create fitted t-copula object
>
> *t.cop.fit = tCopula(param=rho.fit, dim=2, df=df.fit)*
>
>
>
> *margins = c("t", "t")*
>
> *paramMargins = list(list(df=df.fit),list(df=df.fit))*
>
>
>
> #Create fitted custom distribution object
>
> *myBvd.tcop.fit = mvdc(copula=t.cop.fit, margins = margins, paramMargins=
> paramMargins)*
>
>
>
> If all is well, I should be able to run some simulations and simulate my
> returns from this set up:
>
>
> #Generate random numbers from the Copula
>
> *u = rMvdc(nsim, myBvd.tcop.fit)*
>
> *u.1 = u[,1]*
>
> #Generate the simulated returns
>
> *sim.u1 = ugarchsim(fit.u1, n.sim=nsim, startMethod="sample", m.sim=1,*
>
> *                    custom.dist=list(name="sample",distfit=matrix(u.1,
> ncol=1)))*
>
> #Get back the simulated returns
>
> *sim.u1.returns = sim.u1@simulation$seriesSim*
>
>
>
> The problem lies in the order of magnitude the simulated returns. I can get
> some occurrence of +26% for example, which is clearly wrong.
>
>
> Could someone point me on the wrong part?
>
> I have also a remaining question:
>
> In the univariate case, we can simulate the random number with *rspd(n =
> days, gpd.u1)*, and they will be in accordance with the gpd distribtuion
> calibrated.
>
> In the multivariate case, can I consider this step to be taken care of by
> the random number of the Copula since it has been calibrated on the margins
> transformed to Uniform by the gpd distribution function?
>
>
> Thanks
>
> [[alternative HTML version deleted]]
>
> _______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> -- Subscriber-posting only. If you want to post, subscribe first.
> -- Also note that this is not the r-help list where general R questions should go.
>
>

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Simulating returns using copula and SPD distribution

GARCH
Alexios,

Thanks.
I thought about that but if I translate u back to z using the following
function:
u.1.sim = qspd(u.1, gpd.spx)

I get zillions of NA.

> head(u.1)
[1] -1.19669066  1.86539169  0.41492263  0.07366442 -0.80536637  1.09567877
> head(u.1.sim)
[1]         NA         NA -0.1510786 -1.5404552         NA         NA

So there is still something wrong but I can not pinpoint it.

Thanks



2014-05-28 18:18 GMT+01:00 alexios ghalanos <[hidden email]>:

> You've missed a step. Think about it:
> 1. You take z.
> 2. Fit an spd.
> 3. Transform it to U using pspd.
> 4. Fit a copula on U.
> 5. Sample from copula to generate u.
> 6. Need to translate u back to z (step 1) using the quantile function
> (qspd) and the estimated parameters from step 2.
>
> i.e. you've missed step 6.
>
>
> -Alexios
>
> On 28/05/2014 16:53, Guillaume PEALAT wrote:
> > Hi,
> >
> > I am fitting some SPD distributions to past returns and some Copula to
> > simulate the dependance.
> > I am struggling with the simulation part, as the returns I simulate a
> > clearly out of line after some time.
> >
> > I have attached some sample code in order to clarify the point.
> >
> > I first calibrate the SPD distribution on the past returns:
> >
> > #Calibrating the SPD distributioon the residuals of an ARMA+GARCH
> >
> > *spec.u1 = ugarchspec(mean.model=list(armaOrder=c(1,1)),
> > distribution="std")*
> >
> > *fit.u1 = ugarchfit(spec.u1, return.u1)*
> >
> > *z.u1= residuals(fit.u1, standardize=TRUE)*
> >
> > *gpd.u1 = spdfit(z.u1, upper=1. - tailFraction, lower=tailFraction)*
> >
> >
> > #Calibrating the SPD distributioon the residuals of an ARMA+GARCH
> >
> > *spec.u2 = ugarchspec(mean.model=list(armaOrder=c(1,1)),
> > distribution="std")*
> >
> > *fit.u2 = ugarchfit(spec.u2, return.u1)*
> >
> > *z.u2= residuals(fit.u2, standardize=TRUE)*
> >
> > *gpd.u2 = spdfit(z.u2, upper=1. - tailFraction, lower=tailFraction)*
> >
> >
> > Then, once we have all this set, we need to calibrate the Copula of our
> > choice
> >
> >
> > #Calibrate the Copula
> >
> > #We extract the residuals from the xts into a vector
> >
> > *res.u1 = as.vector(z.u1[,1])*
> >
> > *res.u2 = as.vector(z.u2[,1])*
> >
> > #We transform the margin to uniform
> >
> > *U.u1 = pspd(res.u1, gpd.u1)*
> >
> > *U.u2 = pspd(res.u2, gpd.u2)*
> >
> >
> >
> > #We create the matrix to help us calibrate the Copula
> >
> > *test <-list()*
> >
> > *test[[1]] = U.u1*
> >
> > *test[[2]] = U.u2*
> >
> > *test_matrix = do.call(rbind, test)*
> >
> >
> >
> > *set.seed(123)*
> >
> >
> >
> > #We define the Copula we want to use
> >
> > *tcopula<-tCopula(param=0.5, dim=2, dispstr = "ex", df =6)*
> >
> > #We fit the Copula with maximum Likelihood
> >
> > *fit.mpl <- fitCopula(tcopula, t(test_matrix), method="ml")*
> >
> >
> >
> > #We get back the parameters
> >
> > #Rho
> >
> > *rho.fit = fit.mpl@copula@parameters[1]*
> >
> > #Degrees of Freedom
> >
> > *df.fit = fit.mpl@copula@parameters[2]*
> >
> >
> >
> > #Create fitted t-copula object
> >
> > *t.cop.fit = tCopula(param=rho.fit, dim=2, df=df.fit)*
> >
> >
> >
> > *margins = c("t", "t")*
> >
> > *paramMargins = list(list(df=df.fit),list(df=df.fit))*
> >
> >
> >
> > #Create fitted custom distribution object
> >
> > *myBvd.tcop.fit = mvdc(copula=t.cop.fit, margins = margins, paramMargins=
> > paramMargins)*
> >
> >
> >
> > If all is well, I should be able to run some simulations and simulate my
> > returns from this set up:
> >
> >
> > #Generate random numbers from the Copula
> >
> > *u = rMvdc(nsim, myBvd.tcop.fit)*
> >
> > *u.1 = u[,1]*
> >
> > #Generate the simulated returns
> >
> > *sim.u1 = ugarchsim(fit.u1, n.sim=nsim, startMethod="sample", m.sim=1,*
> >
> > *                    custom.dist=list(name="sample",distfit=matrix(u.1,
> > ncol=1)))*
> >
> > #Get back the simulated returns
> >
> > *sim.u1.returns = sim.u1@simulation$seriesSim*
> >
> >
> >
> > The problem lies in the order of magnitude the simulated returns. I can
> get
> > some occurrence of +26% for example, which is clearly wrong.
> >
> >
> > Could someone point me on the wrong part?
> >
> > I have also a remaining question:
> >
> > In the univariate case, we can simulate the random number with *rspd(n =
> > days, gpd.u1)*, and they will be in accordance with the gpd distribtuion
> > calibrated.
> >
> > In the multivariate case, can I consider this step to be taken care of by
> > the random number of the Copula since it has been calibrated on the
> margins
> > transformed to Uniform by the gpd distribution function?
> >
> >
> > Thanks
> >
> >       [[alternative HTML version deleted]]
> >
> > _______________________________________________
> > [hidden email] mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> > -- Subscriber-posting only. If you want to post, subscribe first.
> > -- Also note that this is not the r-help list where general R questions
> should go.
> >
> >
>
>

        [[alternative HTML version deleted]]

_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.
Reply | Threaded
Open this post in threaded view
|

Re: Simulating returns using copula and SPD distribution

alexios
I’m sorry but you need to think a little bit about what you are doing here.

How can your ‘u’ be negative or greater than 1 ? Any CDF transformation (p*) should return a set of probabilities [0,1].
Do you wonder why you get “zillions” of NA when you feed q* with anything other than [0,1] bounded numbers?

Retrace your steps and think about what you are doing rather than mechanically following a recipe.

-Alexios

On 28 May 2014, at 18:29, Guillaume PEALAT <[hidden email]> wrote:

> Alexios,
>
> Thanks.
> I thought about that but if I translate u back to z using the following function:
> u.1.sim = qspd(u.1, gpd.spx)
>
> I get zillions of NA.
>
> > head(u.1)
> [1] -1.19669066  1.86539169  0.41492263  0.07366442 -0.80536637  1.09567877
> > head(u.1.sim)
> [1]         NA         NA -0.1510786 -1.5404552         NA         NA
>
> So there is still something wrong but I can not pinpoint it.
>
> Thanks
>
>
>
> 2014-05-28 18:18 GMT+01:00 alexios ghalanos <[hidden email]>:
> You've missed a step. Think about it:
> 1. You take z.
> 2. Fit an spd.
> 3. Transform it to U using pspd.
> 4. Fit a copula on U.
> 5. Sample from copula to generate u.
> 6. Need to translate u back to z (step 1) using the quantile function
> (qspd) and the estimated parameters from step 2.
>
> i.e. you've missed step 6.
>
>
> -Alexios
>
> On 28/05/2014 16:53, Guillaume PEALAT wrote:
> > Hi,
> >
> > I am fitting some SPD distributions to past returns and some Copula to
> > simulate the dependance.
> > I am struggling with the simulation part, as the returns I simulate a
> > clearly out of line after some time.
> >
> > I have attached some sample code in order to clarify the point.
> >
> > I first calibrate the SPD distribution on the past returns:
> >
> > #Calibrating the SPD distributioon the residuals of an ARMA+GARCH
> >
> > *spec.u1 = ugarchspec(mean.model=list(armaOrder=c(1,1)),
> > distribution="std")*
> >
> > *fit.u1 = ugarchfit(spec.u1, return.u1)*
> >
> > *z.u1= residuals(fit.u1, standardize=TRUE)*
> >
> > *gpd.u1 = spdfit(z.u1, upper=1. - tailFraction, lower=tailFraction)*
> >
> >
> > #Calibrating the SPD distributioon the residuals of an ARMA+GARCH
> >
> > *spec.u2 = ugarchspec(mean.model=list(armaOrder=c(1,1)),
> > distribution="std")*
> >
> > *fit.u2 = ugarchfit(spec.u2, return.u1)*
> >
> > *z.u2= residuals(fit.u2, standardize=TRUE)*
> >
> > *gpd.u2 = spdfit(z.u2, upper=1. - tailFraction, lower=tailFraction)*
> >
> >
> > Then, once we have all this set, we need to calibrate the Copula of our
> > choice
> >
> >
> > #Calibrate the Copula
> >
> > #We extract the residuals from the xts into a vector
> >
> > *res.u1 = as.vector(z.u1[,1])*
> >
> > *res.u2 = as.vector(z.u2[,1])*
> >
> > #We transform the margin to uniform
> >
> > *U.u1 = pspd(res.u1, gpd.u1)*
> >
> > *U.u2 = pspd(res.u2, gpd.u2)*
> >
> >
> >
> > #We create the matrix to help us calibrate the Copula
> >
> > *test <-list()*
> >
> > *test[[1]] = U.u1*
> >
> > *test[[2]] = U.u2*
> >
> > *test_matrix = do.call(rbind, test)*
> >
> >
> >
> > *set.seed(123)*
> >
> >
> >
> > #We define the Copula we want to use
> >
> > *tcopula<-tCopula(param=0.5, dim=2, dispstr = "ex", df =6)*
> >
> > #We fit the Copula with maximum Likelihood
> >
> > *fit.mpl <- fitCopula(tcopula, t(test_matrix), method="ml")*
> >
> >
> >
> > #We get back the parameters
> >
> > #Rho
> >
> > *rho.fit = fit.mpl@copula@parameters[1]*
> >
> > #Degrees of Freedom
> >
> > *df.fit = fit.mpl@copula@parameters[2]*
> >
> >
> >
> > #Create fitted t-copula object
> >
> > *t.cop.fit = tCopula(param=rho.fit, dim=2, df=df.fit)*
> >
> >
> >
> > *margins = c("t", "t")*
> >
> > *paramMargins = list(list(df=df.fit),list(df=df.fit))*
> >
> >
> >
> > #Create fitted custom distribution object
> >
> > *myBvd.tcop.fit = mvdc(copula=t.cop.fit, margins = margins, paramMargins=
> > paramMargins)*
> >
> >
> >
> > If all is well, I should be able to run some simulations and simulate my
> > returns from this set up:
> >
> >
> > #Generate random numbers from the Copula
> >
> > *u = rMvdc(nsim, myBvd.tcop.fit)*
> >
> > *u.1 = u[,1]*
> >
> > #Generate the simulated returns
> >
> > *sim.u1 = ugarchsim(fit.u1, n.sim=nsim, startMethod="sample", m.sim=1,*
> >
> > *                    custom.dist=list(name="sample",distfit=matrix(u.1,
> > ncol=1)))*
> >
> > #Get back the simulated returns
> >
> > *sim.u1.returns = sim.u1@simulation$seriesSim*
> >
> >
> >
> > The problem lies in the order of magnitude the simulated returns. I can get
> > some occurrence of +26% for example, which is clearly wrong.
> >
> >
> > Could someone point me on the wrong part?
> >
> > I have also a remaining question:
> >
> > In the univariate case, we can simulate the random number with *rspd(n =
> > days, gpd.u1)*, and they will be in accordance with the gpd distribtuion
> > calibrated.
> >
> > In the multivariate case, can I consider this step to be taken care of by
> > the random number of the Copula since it has been calibrated on the margins
> > transformed to Uniform by the gpd distribution function?
> >
> >
> > Thanks
> >
> >       [[alternative HTML version deleted]]
> >
> > _______________________________________________
> > [hidden email] mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-sig-finance
> > -- Subscriber-posting only. If you want to post, subscribe first.
> > -- Also note that this is not the r-help list where general R questions should go.
> >
> >
>
>

        [[alternative HTML version deleted]]


_______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should go.