| Title: | Stochastic Correlation Modelling via Circular Diffusion |
|---|---|
| Description: | Performs simulation and inference of diffusion processes on circle. Stochastic correlation models based on circular diffusion models are provided. For details see Majumdar, S. and Laha, A.K. (2024) "Diffusion on the circle and a stochastic correlation model" <doi:10.48550/arXiv.2412.06343>. |
| Authors: | Sourav Majumdar [aut, cre]
|
| Maintainer: | Sourav Majumdar <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.0.1 |
| Built: | 2026-05-16 07:18:35 UTC |
| Source: | https://github.com/cran/stochcorr |
stoch.bootstrap returns the Bootstrap confidence interval for estimated parameters from circdiff.
circ.bootstrap(est, theta, boot_iter=500, p=0.05, seed = NULL)circ.bootstrap(est, theta, boot_iter=500, p=0.05, seed = NULL)
est |
object of class |
theta |
data of the discretely observed diffusion |
boot_iter |
number of bootstrap iteration (Default is 500) |
p |
1-p% confidence interval (Default is 0.05) |
seed |
(optional) seed value |
This function returns a (1-p)% confidence interval for estimated parameters from circdiff
using parametric bootstrap. See section 4 of Majumdar and Laha (2024) https://doi.org/10.48550/arXiv.2412.06343.
Returns a matrix of the bootstrap (1-p)% confidence interval for the parameters. The first row is the lower bound and the second row is the upper bound.
library(stochcorr) data(wind) if(requireNamespace("ggplot2")){ library(ggplot2) ggplot2::ggplot(wind, aes(x = Date, y = Dir)) + geom_line() + labs(title = "Sotavento Wind Farm", x = "Date", y = "Wind Direction") + scale_x_datetime(date_labels = "%d-%b", date_breaks = "2 day") + theme_test() + theme( text = element_text(size = 15), axis.text.x = element_text(angle = 90, hjust = 1) ) } a<-circdiff(wind$Dir,10/1440,"vmp") a b<-circdiff(wind$Dir,10/1440,"cbm") b estimates_vmp<-circ.bootstrap(a,wind$Dir, seed = 100) estimates_vmp estimates_cbm<-circ.bootstrap(b,wind$Dir, seed = 100) estimates_cbmlibrary(stochcorr) data(wind) if(requireNamespace("ggplot2")){ library(ggplot2) ggplot2::ggplot(wind, aes(x = Date, y = Dir)) + geom_line() + labs(title = "Sotavento Wind Farm", x = "Date", y = "Wind Direction") + scale_x_datetime(date_labels = "%d-%b", date_breaks = "2 day") + theme_test() + theme( text = element_text(size = 15), axis.text.x = element_text(angle = 90, hjust = 1) ) } a<-circdiff(wind$Dir,10/1440,"vmp") a b<-circdiff(wind$Dir,10/1440,"cbm") b estimates_vmp<-circ.bootstrap(a,wind$Dir, seed = 100) estimates_vmp estimates_cbm<-circ.bootstrap(b,wind$Dir, seed = 100) estimates_cbm
circdiff returns the estimates of parameters of a discretely observed von-Mises process or Circular Brownian motion
circdiff(theta, dt, corr_process, iter=2000, lambda=0, lambda_1=0, lambda_2=0)circdiff(theta, dt, corr_process, iter=2000, lambda=0, lambda_1=0, lambda_2=0)
theta |
data of the discretely observed diffusion |
dt |
time step |
corr_process |
|
iter |
number of iterations (Default is 2000) |
lambda |
regularization parameter for |
lambda_1 |
regularization parameter for |
lambda_2 |
regularization parameter for |
Let be a discretely observed circular diffusion
at time step . The circular diffusion could either be von-Mises process,
or the circular brownian motion,
under periodic boundary condition. The function returns the MLE of for von-Mises process or
for circular brownian motion.
We provide an option to perform penalised MLE using an iterative optimization procedure as following,
we maximise for von Mises process, where is the number of observations,
For Circular Brownian motion we maximise,
See section 3 of Majumdar and Laha (2024) https://doi.org/10.48550/arXiv.2412.06343.
A list containing the estimates of the model
if corr_process=vmp then it returns
dt time step
lambda_vm the drift parameter of the von Mises process
sigma_vm the volatility parameter of the von Mises process
mu_vm the mean direction of the von Mises process
lambda_1, lambda_2 value of the regularization parameters used for estimation
else if corr_process=cbm then it returns
dt time step
sigma_cbm the volatility parameter of the circular Brownian motion
lambda value of the regularization parameter used for estimation
library(stochcorr) data(wind) if(requireNamespace("ggplot2")){ library(ggplot2) ggplot2::ggplot(wind, aes(x = Date, y = Dir)) + geom_line() + labs(title = "Sotavento Wind Farm", x = "Date", y = "Wind Direction") + scale_x_datetime(date_labels = "%d-%b", date_breaks = "2 day") + theme_test() + theme( text = element_text(size = 15), axis.text.x = element_text(angle = 90, hjust = 1) ) } a<-circdiff(wind$Dir,10/1440,"vmp") a b<-circdiff(wind$Dir,10/1440,"cbm") blibrary(stochcorr) data(wind) if(requireNamespace("ggplot2")){ library(ggplot2) ggplot2::ggplot(wind, aes(x = Date, y = Dir)) + geom_line() + labs(title = "Sotavento Wind Farm", x = "Date", y = "Wind Direction") + scale_x_datetime(date_labels = "%d-%b", date_breaks = "2 day") + theme_test() + theme( text = element_text(size = 15), axis.text.x = element_text(angle = 90, hjust = 1) ) } a<-circdiff(wind$Dir,10/1440,"vmp") a b<-circdiff(wind$Dir,10/1440,"cbm") b
dcbm evaluates the transition density for Circular Brownian Motion
dcbm(theta, t, theta_0, sigma)dcbm(theta, t, theta_0, sigma)
theta |
vector of data |
t |
time step |
theta_0 |
initial value |
sigma |
sigma |
See section 2 of Majumdar and Laha (2024) https://doi.org/10.48550/arXiv.2412.06343.
dcbm gives the transition density function of the circular Brownian motion
dvmp evaluates the transition density for von Mises process
dvmp(theta, t, theta_0, lambda, sigma, mu)dvmp(theta, t, theta_0, lambda, sigma, mu)
theta |
vector of data |
t |
time step |
theta_0 |
initial value |
lambda |
lambda |
sigma |
sigma |
mu |
mu |
See section 2 of Majumdar and Laha (2024) https://doi.org/10.48550/arXiv.2412.06343.
dvmp gives the transition density function of the von Mises process
End of the day closing price for USD/GBP and FTSE250 in the year 2020.
data("ftse2020")data("ftse2020")
A data frame with 224 rows and 3 columns:
USD/GBPEOD USD/GBP rate
FTSE250EOD FTSE250
DateDate
Yahoo Finance
End of the day closing price for USD/JPY and Nikkei in the year 2020.
data("nikkei2020")data("nikkei2020")
A data frame with 213 rows and 3 columns:
USD/JPYEOD USD/JPY rate
NikkeiEOD Nikkei
DateDate
Yahoo Finance
End of the day closing price for USD/INR and NIFTY in the year 2020.
data("nse2020")data("nse2020")
A data frame with 250 rows and 3 columns:
USD/INREOD USD/INR rate
NiftyEOD Nifty
DateDate
Yahoo Finance
rtraj.cbm returns a simulated path of a circular Brownian motion for given parameters
rtraj.cbm(n, theta_0, dt, sigma, burnin=1000)rtraj.cbm(n, theta_0, dt, sigma, burnin=1000)
n |
number of steps in the simulated path |
theta_0 |
initial point |
dt |
Time step |
sigma |
volatility parameter |
burnin |
number of initial samples to be rejected (Default is 1000) |
Let evolve according to a circular Brownian motion given by,
We simulate by simulating from its transition density.
A vector of length n of the simulated path from circular Brownian motion
rtraj.vmp returns a simulated path of a von Mises process for given parameters
rtraj.vmp(n, theta_0, dt, mu, lambda, sigma)rtraj.vmp(n, theta_0, dt, mu, lambda, sigma)
n |
number of steps in the simulated path |
theta_0 |
initial point |
dt |
Time step |
mu |
mean parameter |
lambda |
drift parameter |
sigma |
volatility parameter |
Let evolve according to a von Mises process given by,
We simulate by the Euler-Maruyama discretization of the above SDE.
A vector of length n of the simulated path from von Mises process
End of the day closing price for EUR/USD and S&P500 in the year 2020.
data("s&p2020")data("s&p2020")
A data frame with 224 rows and 3 columns:
EUR/USDEOD EUR/USD rate
S&P500EOD S&P500
DateDate
Yahoo Finance
stoch.bootstrap returns the Bootstrap confidence interval for estimated rho from stochcorr.
stoch.bootstrap(est, S_1, S_2, boot_iter=500, p=0.05, seed = NULL)stoch.bootstrap(est, S_1, S_2, boot_iter=500, p=0.05, seed = NULL)
est |
object of class |
S_1 |
historical price of the first asset |
S_2 |
historical price of the second asset |
boot_iter |
number of bootstrap iteration (Default is 500) |
p |
1-p% confidence interval (Default is 0.05) |
seed |
(optional) seed value |
This function returns a p% confidence interval for estimated rho from stochcorr
using parametric bootstrap. See section 4 of Majumdar and Laha (2024) https://doi.org/10.48550/arXiv.2412.06343.
Returns a matrix for the bootstrap (1-p)% confidence interval for rho. The first row of the matrix is the lower bound and the second row is the upper bound.
library(stochcorr) data("nse2020") ## using von Mises process as the correlation process a <- stochcorr(nse2020$`USD/INR`, nse2020$Nifty, 1 / 250, corr_process = "vmp") b <- stoch.bootstrap(a, nse2020$`USD/INR`, nse2020$Nifty, seed = 100) rho_data <- as.data.frame(cbind(a$rho, nse2020$Date)) rho_data[, 2] <- as.Date(rho_data[, 2], origin = "1970-01-01") colnames(rho_data) <- c("Correlation", "Time") if(requireNamespace("ggplot2")){ library(ggplot2) ggplot2::ggplot(rho_data, aes(x = Time, y = Correlation)) + theme_test() + theme( text = element_text(size = 15), axis.text.x = element_text(angle = 90, hjust = 1) ) + geom_line() + geom_ribbon(aes(ymin = b[1, ], ymax = b[2, ]), fill = "blue", alpha = 0.15) + scale_y_continuous(breaks = round(seq(-1, 1, by = 0.05), 1)) + scale_x_date(breaks = "1 month", date_labels = "%B %Y") } ## using Circular Brownian Motions as the correlation process a <- stochcorr(nse2020$`USD/INR`, nse2020$Nifty, 1 / 250, corr_process = "cbm") b <- stoch.bootstrap(a, nse2020$`USD/INR`, nse2020$Nifty, seed = 100) rho_data <- as.data.frame(cbind(a$rho, nse2020$Date)) rho_data[, 2] <- as.Date(rho_data[, 2], origin = "1970-01-01") colnames(rho_data) <- c("Correlation", "Time") if(requireNamespace("ggplot2")){ library(ggplot2) ggplot2::ggplot(rho_data, aes(x = Time, y = Correlation)) + theme_test() + theme( text = element_text(size = 15), axis.text.x = element_text(angle = 90, hjust = 1) ) + geom_line() + geom_ribbon(aes(ymin = b[1, ], ymax = b[2, ]), fill = "blue", alpha = 0.15) + scale_y_continuous(breaks = round(seq(-1, 1, by = 0.05), 1)) + scale_x_date(breaks = "1 month", date_labels = "%B %Y")}library(stochcorr) data("nse2020") ## using von Mises process as the correlation process a <- stochcorr(nse2020$`USD/INR`, nse2020$Nifty, 1 / 250, corr_process = "vmp") b <- stoch.bootstrap(a, nse2020$`USD/INR`, nse2020$Nifty, seed = 100) rho_data <- as.data.frame(cbind(a$rho, nse2020$Date)) rho_data[, 2] <- as.Date(rho_data[, 2], origin = "1970-01-01") colnames(rho_data) <- c("Correlation", "Time") if(requireNamespace("ggplot2")){ library(ggplot2) ggplot2::ggplot(rho_data, aes(x = Time, y = Correlation)) + theme_test() + theme( text = element_text(size = 15), axis.text.x = element_text(angle = 90, hjust = 1) ) + geom_line() + geom_ribbon(aes(ymin = b[1, ], ymax = b[2, ]), fill = "blue", alpha = 0.15) + scale_y_continuous(breaks = round(seq(-1, 1, by = 0.05), 1)) + scale_x_date(breaks = "1 month", date_labels = "%B %Y") } ## using Circular Brownian Motions as the correlation process a <- stochcorr(nse2020$`USD/INR`, nse2020$Nifty, 1 / 250, corr_process = "cbm") b <- stoch.bootstrap(a, nse2020$`USD/INR`, nse2020$Nifty, seed = 100) rho_data <- as.data.frame(cbind(a$rho, nse2020$Date)) rho_data[, 2] <- as.Date(rho_data[, 2], origin = "1970-01-01") colnames(rho_data) <- c("Correlation", "Time") if(requireNamespace("ggplot2")){ library(ggplot2) ggplot2::ggplot(rho_data, aes(x = Time, y = Correlation)) + theme_test() + theme( text = element_text(size = 15), axis.text.x = element_text(angle = 90, hjust = 1) ) + geom_line() + geom_ribbon(aes(ymin = b[1, ], ymax = b[2, ]), fill = "blue", alpha = 0.15) + scale_y_continuous(breaks = round(seq(-1, 1, by = 0.05), 1)) + scale_x_date(breaks = "1 month", date_labels = "%B %Y")}
stochcorr returns the estimates of the instantaneous correlation and other
model parameters.
stochcorr(S_1, S_2, dt, corr_process, iter=2000, lambda=4, lambda_1=10, lambda_2=0)stochcorr(S_1, S_2, dt, corr_process, iter=2000, lambda=4, lambda_1=10, lambda_2=0)
S_1 |
Historical price of the first asset |
S_2 |
Historical price of the second asset |
dt |
Time step |
corr_process |
specify the correlation process, |
iter |
Number of iteration (Default is 2000) |
lambda |
regularization parameter for circular Brownian motion (Default is 4) |
lambda_1 |
(Default is 10) |
lambda_2 |
0 (Default) |
Let and be two discretely observed geometric Brownian motions
observed at a time step of dt.
where , with being specified by the von Mises Process
() or
the Circular Brownian Motion,
with periodic boundary conditions. Here are mutually independent Brownian Motions.
We estimate the model by maximising penalized MLE, using an iterative optimization procedure. In case of the von Mises process as the correlation process we maximise,
For Circular Brownian motion as the correlation process we maximise,
See section 4 of Majumdar and Laha (2024) https://doi.org/10.48550/arXiv.2412.06343.
A list containing the estimates of the model including the asset price parameters, instantaneous correlations and estimates of the correlation process
rho Estimated instantaneous correlations
mu_1 Drift of the first asset
mu_2 Drift of the second asset
sigma_1 Volatility of the first asset
sigma_2 Volatility of the second asset
if corr_process=vmp then it additionally returns
lambda_vm the drift parameter of the von Mises process
sigma_vm the volatility parameter of the von Mises process
mu_vm the mean direction of the von Mises process
lambda_1, lambda_2 value of the regularization parameters used for estimation
else if corr_process=cbm then it returns
sigma_cbm the volatility parameter of the circular Brownian motion
lambda value of the regularization parameter used for estimation
data("nse2020") ## using von Mises process as the correlation process a <- stochcorr(nse2020$`USD/INR`, nse2020$Nifty, 1 / 250, corr_process = "vmp") ## using Circular Brownian Motions as the correlation process a <- stochcorr(nse2020$`USD/INR`, nse2020$Nifty, 1 / 250, corr_process = "cbm")data("nse2020") ## using von Mises process as the correlation process a <- stochcorr(nse2020$`USD/INR`, nse2020$Nifty, 1 / 250, corr_process = "vmp") ## using Circular Brownian Motions as the correlation process a <- stochcorr(nse2020$`USD/INR`, nse2020$Nifty, 1 / 250, corr_process = "cbm")
stochcorr.sim returns the paths of stock price under a stochastic correlation model
stochcorr.sim(m=500, n, dt, S1_0, S2_0, mu1, sigma1, mu2, sigma2, mu, lambda, sigma, corr_process)stochcorr.sim(m=500, n, dt, S1_0, S2_0, mu1, sigma1, mu2, sigma2, mu, lambda, sigma, corr_process)
m |
number of paths (Default is 500) |
n |
number of steps in each simulated path |
dt |
time step |
S1_0 |
initial price of the first asset |
S2_0 |
initial price of the second asset |
mu1 |
drift of the first asset |
sigma1 |
volatility of the first asset |
mu2 |
drift of the second asset |
sigma2 |
volatility of the second asset |
mu |
mean direction of the correlation process (if |
lambda |
drift of the correlation process (if |
sigma |
volatility of the correlation process (if |
corr_process |
specify the correlation process, |
This function returns the simulated paths of two stock prices following a stochastic correlation model. See stochcorr()
details of the stochastic correlation model
Returns a list with prices of two assets S1 and S2 under the stochastic correlation model
library(stochcorr) # Generate 500 paths of two geometric Brownian motions, S1 and S2, of length 100 each # following the von Mises process with mu=pi/2, lambda=1 and sigma =1 a<-stochcorr.sim(m=500,100,0.01,100,100,0.05,0.05,0.06,0.1,pi/2,1,1,"vmp") t<-seq(0,100*0.01-0.01,0.01) # Plot the first realization of S1 and S2 plot(t,a$S1[1,], ylim=c(min(a$S1[1,],a$S2[1,]),max(a$S1[1,],a$S2[1,])),type="l") lines(t,a$S2[1,], col="red",type="l") legend(0.01,max(a$S1[1,],a$S2[1,]), legend = c("S1","S2"), col = c("black", "red"), lty=1)library(stochcorr) # Generate 500 paths of two geometric Brownian motions, S1 and S2, of length 100 each # following the von Mises process with mu=pi/2, lambda=1 and sigma =1 a<-stochcorr.sim(m=500,100,0.01,100,100,0.05,0.05,0.06,0.1,pi/2,1,1,"vmp") t<-seq(0,100*0.01-0.01,0.01) # Plot the first realization of S1 and S2 plot(t,a$S1[1,], ylim=c(min(a$S1[1,],a$S2[1,]),max(a$S1[1,],a$S2[1,])),type="l") lines(t,a$S2[1,], col="red",type="l") legend(0.01,max(a$S1[1,],a$S2[1,]), legend = c("S1","S2"), col = c("black", "red"), lty=1)
Wind direction data from Sotavento Wind farm from 1 November 2024 to 30 November 2024 at a 10 minute frequency.
data("wind")data("wind")
A data frame with 4320 rows and 2 columns:
DirWind Direction data
DateDate
https://www.sotaventogalicia.com/en/technical-area/real-time-data/historical/