Skip to content

Instantly share code, notes, and snippets.

@alexchinco
Created August 28, 2015 15:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexchinco/e07ded72159c6f3d312f to your computer and use it in GitHub Desktop.
Save alexchinco/e07ded72159c6f3d312f to your computer and use it in GitHub Desktop.
Solution to multiscale noisy-rational-expectations model.
## Prep workspace
options(width=120, digits=6, digits.secs=6)
rm(list=ls())
library(foreign)
library(grid)
library(plyr)
library(ggplot2)
library(tikzDevice)
print(options('tikzLatexPackages'))
options(tikzLatexPackages =
c("\\usepackage{tikz}\n",
"\\usepackage[active,tightpage,psfixbb]{preview}\n",
"\\PreviewEnvironment{pgfpicture}\n",
"\\setlength\\PreviewBorder{0pt}\n",
"\\usepackage{amsmath}\n",
"\\usepackage{pxfonts}\n",
"\\usepackage{bm}\n",
"\\usepackage{xfrac}\n"
)
)
setTikzDefaults(overwrite = FALSE)
print(options('tikzLatexPackages'))
library(reshape)
library(vars)
library(scales)
library(zoo)
library(splines)
library(MASS)
library(wmtsa)
library(foreach)
library(doMC)
registerDoMC(8)
## Define directories
scl.str.DAT_DIR <- "~/Dropbox/research/fast_trading_priced_noise/data/"
scl.str.FIG_DIR <- "~/Dropbox/research/fast_trading_priced_noise/figures/"
## Define global parameters
set.seed(123456)
scl.int.ITER <- 10^4
scl.int.T <- 10^4
vec.flt.SIG_E <- sort(runif(10^5, 0, 1.5))
## vec.flt.SIG_E <- seq(0, 1.50, by = 0.00001)[-1]
scl.flt.MU_V <- 1
scl.flt.SIG_V <- 1
scl.flt.SIG_Z <- 1
## Define equlibrium functions
fun.PSI <- function(SIG_E, SIG_V) {
OUT <- SIG_E^2/(SIG_E^2 + SIG_V^2)
return(OUT)
}
fun.OMG <- function(SIG_Z, GAM_V, PSI, SIG_V) {
OUT <- (SIG_Z^2/GAM_V^2)/(PSI * SIG_V^2 + SIG_Z^2/GAM_V^2)
return(OUT)
}
fun.BET_V <- function(LAM_A, GAM_V, PSI, OMG) {
OUT <- 1/(2 * LAM_A) * (1 - LAM_A * GAM_V * (1 - PSI) * OMG)
return(OUT)
}
fun.BET_S <- function(GAM_V, OMG) {
OUT <- - GAM_V/2 * (1 - OMG)
return(OUT)
}
fun.GAM_V <- function(LAM_A, BET_V, BET_S) {
OUT <- 1/(2 * LAM_A) * (1 - LAM_A * (BET_V + BET_S))
return(OUT)
}
fun.LAM_A <- function(BET_V, BET_S, GAM_V, SIG_V, SIG_E, SIG_Z) {
NUMER <- (BET_V + BET_S + GAM_V) * SIG_V^2
DENOM <- (BET_V + BET_S + GAM_V)^2 * SIG_V^2 + BET_V^2 * SIG_E^2 + (1 + BET_S^2/GAM_V^2) * SIG_Z^2
OUT <- NUMER/DENOM
return(OUT)
}
fun.BET_0 <- function(LAM_A, LAM_0, GAM_0, GAM_V, PSI, OMG, MU_V) {
OUT <- - 1/(2 * LAM_A) * (LAM_0 + LAM_A * (GAM_0 + GAM_V * PSI * OMG * MU_V))
return(OUT)
}
fun.GAM_0 <- function(LAM_A, LAM_0, BET_0) {
OUT <- - 1/(2 * LAM_A) * (LAM_0 + LAM_A * BET_0)
return(OUT)
}
fun.LAM_0 <- function(LAM_A, BET_V, BET_S, GAM_V, MU_V, BET_0, GAM_0) {
OUT <- (1 - LAM_A * (BET_V + BET_S + GAM_V)) * MU_V - LAM_A * (BET_0 + GAM_0)
return(OUT)
}
## Define error functions
fun.ERR_SLOPE <- function(ARGS, VAL) {
BET_V <- ARGS[1]
BET_S <- ARGS[2]
GAM_V <- ARGS[3]
LAM_A <- ARGS[4]
SIG_V <- VAL[1]
SIG_E <- VAL[2]
SIG_Z <- VAL[3]
PSI <- fun.PSI(SIG_E, SIG_V)
OMG <- fun.OMG(SIG_Z, GAM_V, PSI, SIG_V)
BET_V_HAT <- fun.BET_V(LAM_A, GAM_V, PSI, OMG)
BET_S_HAT <- fun.BET_S(GAM_V, OMG)
GAM_V_HAT <- fun.GAM_V(LAM_A, BET_V, BET_S)
LAM_A_HAT <- fun.LAM_A(BET_V, BET_S, GAM_V, SIG_V, SIG_E, SIG_Z)
ERROR <- sum(c((BET_V_HAT - BET_V)^2,
(BET_S_HAT - BET_S)^2,
(GAM_V_HAT - GAM_V)^2,
(LAM_A_HAT - LAM_A)^2
)
)
return(ERROR)
}
fun.ERR_LEVEL <- function(ARGS, VAL) {
BET_0 <- ARGS[1]
GAM_0 <- ARGS[2]
SIG_V <- VAL[1]
MU_V <- LAM_0 <- VAL[2]
SIG_E <- VAL[3]
SIG_Z <- VAL[4]
BET_V <- VAL[5]
BET_S <- VAL[6]
GAM_V <- VAL[7]
LAM_A <- VAL[8]
PSI <- fun.PSI(SIG_E, SIG_V)
OMG <- fun.OMG(SIG_Z, GAM_V, PSI, SIG_V)
BET_0_HAT <- fun.BET_0(LAM_A, LAM_0, GAM_0, GAM_V, PSI, OMG, MU_V)
GAM_0_HAT <- fun.GAM_0(LAM_A, LAM_0, BET_0)
LAM_0_HAT <- fun.LAM_0(LAM_A, BET_V, BET_S, GAM_V, MU_V, BET_0, GAM_0)
ERROR <- sum(c((BET_0_HAT - BET_0)^2,
(GAM_0_HAT - GAM_0)^2,
(LAM_0_HAT - LAM_0)^2
)
)
return(ERROR)
}
## Estimate equilibrium parameters
if (TRUE == FALSE) {
scl.int.SIG_E_LEN <- length(vec.flt.SIG_E)
mat.flt.SLOPE <- foreach(e=1:scl.int.SIG_E_LEN, .combine = "rbind", .inorder = FALSE) %dopar% {
if (e %in% c(1,round(seq(0,scl.int.SIG_E_LEN, length.out = 11)))) {
print(round(e/scl.int.SIG_E_LEN * 100))
}
vec.flt.VAL <- c(scl.flt.SIG_V,
vec.flt.SIG_E[e],
scl.flt.SIG_Z
)
vec.flt.PAR <- c(1, -1, 1, 1)
obj.opt.OUT <- optim(par = vec.flt.PAR,
fn = fun.ERR_SLOPE,
method = "BFGS",
VAL = vec.flt.VAL
)
vec.flt.OUT <- c(vec.flt.SIG_E[e], obj.opt.OUT$par, obj.opt.OUT$value, obj.opt.OUT$convergence)
return(as.numeric(vec.flt.OUT))
}
mat.df.SLOPE <- as.data.frame(mat.flt.SLOPE)
names(mat.df.SLOPE) <- c("sigE", "betV", "betS", "gamV", "lamA", "err", "fit")
mat.df.SLOPE <- mat.df.SLOPE[(mat.df.SLOPE$fit == 0.00) & (mat.df.SLOPE$err < 0.01) & (mat.df.SLOPE$betS < 0.00), c("sigE", "betV", "betS", "gamV", "lamA")]
scl.int.SIG_E_LEN <- dim(mat.df.SLOPE)[1]
mat.flt.LEVEL <- foreach(e=1:scl.int.SIG_E_LEN, .combine = "rbind", .inorder = FALSE) %dopar% {
if (e %in% c(1,round(seq(0,scl.int.SIG_E_LEN, length.out = 11)))) {
print(round(e/scl.int.SIG_E_LEN * 100))
}
scl.flt.SIG_E <- mat.df.SLOPE[e, 1]
scl.flt.BET_V <- mat.df.SLOPE[e, 2]
scl.flt.BET_S <- mat.df.SLOPE[e, 3]
scl.flt.GAM_V <- mat.df.SLOPE[e, 4]
scl.flt.LAM_A <- mat.df.SLOPE[e, 5]
vec.flt.VAL <- c(scl.flt.SIG_V,
scl.flt.MU_V,
scl.flt.SIG_E,
scl.flt.SIG_Z,
scl.flt.BET_V,
scl.flt.BET_S,
scl.flt.GAM_V,
scl.flt.LAM_A
)
vec.flt.PAR <- c(-1, -1)
obj.opt.OUT <- optim(par = vec.flt.PAR,
fn = fun.ERR_LEVEL,
method = "BFGS",
VAL = vec.flt.VAL
)
vec.flt.OUT <- c(scl.flt.SIG_E, obj.opt.OUT$par, obj.opt.OUT$value, obj.opt.OUT$convergence)
return(as.numeric(vec.flt.OUT))
}
mat.df.LEVEL <- as.data.frame(mat.flt.LEVEL)
names(mat.df.LEVEL) <- c("sigE", "bet0", "gam0", "err", "fit")
mat.df.LEVEL <- mat.df.LEVEL[(mat.df.LEVEL$fit == 0.00) & (mat.df.LEVEL$err < 0.01), c("sigE", "bet0", "gam0")]
mat.df.LEVEL$lam0 <- scl.flt.MU_V
mat.df.PARAM <- merge(mat.df.SLOPE, mat.df.LEVEL, by = "sigE")
save(mat.df.PARAM, file = paste(scl.str.DAT_DIR, "data--equilibrium-parameters--26aug2015.Rdata"))
}
load(file = paste(scl.str.DAT_DIR, "data--equilibrium-parameters--26aug2015.Rdata"))
## Plot equilibrium parameters
if (TRUE == FALSE) {
mat.df.PLOT <- mat.df.PARAM[, c("sigE", "betV", "betS", "gamV", "lamA")]
names(mat.df.PLOT) <- c("sigE",
"$\\beta_{\\tilde{v}}$",
"$\\beta_{s}$",
"$\\gamma_{v}$",
"$\\lambda_a$"
)
mat.df.PLOT$sigE <- mat.df.PLOT$sigE/scl.flt.SIG_V
mat.df.PLOT <- melt(mat.df.PLOT, c("sigE"))
theme_set(theme_bw())
scl.str.RAW_FILE <- "plot--equilibrium-parameters--26aug2015"
scl.str.TEX_FILE <- paste(scl.str.RAW_FILE,'.tex',sep='')
scl.str.PDF_FILE <- paste(scl.str.RAW_FILE,'.pdf',sep='')
scl.str.AUX_FILE <- paste(scl.str.RAW_FILE,'.aux',sep='')
scl.str.LOG_FILE <- paste(scl.str.RAW_FILE,'.log',sep='')
tikz(file = scl.str.TEX_FILE, height = 2.25, width = 7, standAlone=TRUE)
obj.gg2.PLOT <- ggplot()
obj.gg2.PLOT <- obj.gg2.PLOT + scale_colour_brewer(palette="Set1")
obj.gg2.PLOT <- obj.gg2.PLOT + geom_smooth(data = mat.df.PLOT,
aes(x = sigE,
y = value
),
method = "lm",
formula = y ~ ns(x, 25),
se = FALSE,
size = 1.75
)
## obj.gg2.PLOT <- obj.gg2.PLOT + geom_point(data = mat.df.PLOT,
## aes(x = sigE,
## y = value
## ),
## size = 0.50,
## alpha = 0.50
## )
obj.gg2.PLOT <- obj.gg2.PLOT + xlab("$\\sigma_{\\epsilon}/\\sigma_v$")
obj.gg2.PLOT <- obj.gg2.PLOT + ylab("")
obj.gg2.PLOT <- obj.gg2.PLOT + scale_x_continuous(limits = c(0, 1.5), breaks = c(0.00, 0.50, 1.00, 1.50))
obj.gg2.PLOT <- obj.gg2.PLOT + facet_wrap(~ variable, nrow = 1, scales = "free_y")
obj.gg2.PLOT <- obj.gg2.PLOT + theme(plot.margin = unit(c(1,0.15,0.15,-1), "lines"),
axis.text = element_text(size = 8),
axis.title = element_text(size = 10),
plot.title = element_text(vjust = 1.75),
panel.grid.minor = element_blank(),
legend.position = "none"
)
obj.gg2.PLOT <- obj.gg2.PLOT + ggtitle("Equilibrium Parameters")
print(obj.gg2.PLOT)
dev.off()
system(paste('lualatex', file.path(scl.str.TEX_FILE)), ignore.stdout = TRUE)
system(paste('rm ', scl.str.TEX_FILE, sep = ''))
system(paste('mv ', scl.str.PDF_FILE, ' ', scl.str.FIG_DIR, sep = ''))
system(paste('rm ', scl.str.AUX_FILE, sep = ''))
system(paste('rm ', scl.str.LOG_FILE, sep = ''))
}
## Simulate trader profits
if (TRUE == FALSE) {
vec.flt.BREAKS <- seq(0, 1.5, by = 0.01)
scl.int.BKT_LEN <- length(vec.flt.BREAKS) - 1
mat.df.SMOOTH <- mat.df.PARAM
mat.df.SMOOTH$bkt <- NA
for (b in 1:scl.int.BKT_LEN) {
vec.int.ROWS <- which((mat.df.SMOOTH$sigE >= vec.flt.BREAKS[b]) & (mat.df.SMOOTH$sigE < vec.flt.BREAKS[b+1]))
if (length(vec.int.ROWS) > 0) {
mat.df.SMOOTH[vec.int.ROWS, ]$bkt <- b
}
}
mat.df.SMOOTH <- ddply(mat.df.SMOOTH,
c("bkt"),
function(X)c(mean(X$sigE, na.rm = TRUE),
mean(X$bet0, na.rm = TRUE),
mean(X$betV, na.rm = TRUE),
mean(X$betS, na.rm = TRUE),
mean(X$gam0, na.rm = TRUE),
mean(X$gamV, na.rm = TRUE),
mean(X$lam0, na.rm = TRUE),
mean(X$lamA, na.rm = TRUE)
)
)
names(mat.df.SMOOTH) <- c("bkt", "sigE", "bet0", "betV", "betS", "gam0", "gamV", "lam0", "lamA")
scl.int.BKT_LEN <- length(unique(mat.df.SMOOTH$bkt))
mat.flt.OUTTER <- foreach(e=1:scl.int.BKT_LEN, .combine = "rbind", .inorder = FALSE) %dopar% {
## if (e %in% c(1,round(seq(0,scl.int.BKT_LEN, length.out = 11)))) {
## print(round(e/scl.int.BKT_LEN * 100))
## }
print(e)
scl.flt.SIG_E <- mat.df.SMOOTH[e, 2]
scl.flt.BET_0 <- mat.df.SMOOTH[e, 3]
scl.flt.BET_V <- mat.df.SMOOTH[e, 4]
scl.flt.BET_S <- mat.df.SMOOTH[e, 5]
scl.flt.GAM_0 <- mat.df.SMOOTH[e, 6]
scl.flt.GAM_V <- mat.df.SMOOTH[e, 7]
scl.flt.LAM_0 <- mat.df.SMOOTH[e, 8]
scl.flt.LAM_A <- mat.df.SMOOTH[e, 9]
mat.flt.INNER <- foreach(i=1:scl.int.ITER, .combine = "rbind") %do% {
scl.flt.V <- rnorm(1, 0, scl.flt.SIG_V)
vec.flt.EPS <- rnorm(scl.int.T, 0, scl.flt.SIG_E)
vec.flt.S <- rnorm(scl.int.T, scl.flt.V, scl.flt.SIG_Z/scl.flt.GAM_V)
vec.flt.V_TIL <- scl.flt.V + vec.flt.EPS
vec.flt.X <- scl.flt.BET_0 + scl.flt.BET_V * vec.flt.V_TIL + scl.flt.BET_S * vec.flt.S
scl.flt.Y <- scl.flt.GAM_0 + scl.flt.GAM_V * scl.flt.V
vec.flt.Z <- rnorm(scl.int.T, 0, scl.flt.SIG_Z)
vec.flt.A <- vec.flt.X + scl.flt.Y + vec.flt.Z
vec.flt.P <- scl.flt.LAM_0 + scl.flt.LAM_A * vec.flt.A
vec.flt.INNER <- c(mean((vec.flt.V_TIL - vec.flt.P) * vec.flt.X),
mean((scl.flt.V - vec.flt.P) * scl.flt.Y),
mean((scl.flt.V - vec.flt.P) * vec.flt.Z),
mean(-(scl.flt.V - vec.flt.P) * vec.flt.A)
)
return(vec.flt.INNER)
}
vec.flt.OUTTER <- c(scl.flt.SIG_E,
mean(mat.flt.INNER[, 1]),
mean(mat.flt.INNER[, 2]),
mean(mat.flt.INNER[, 3]),
mean(mat.flt.INNER[, 4])
)
return(vec.flt.OUTTER)
}
mat.df.PROFITS <- as.data.frame(mat.flt.OUTTER)
names(mat.df.PROFITS) <- c("sigE", "shortRun", "longRun", "noise", "marketMaker")
save(mat.df.PROFITS, file = paste(scl.str.DAT_DIR, "data--trader-profits--26aug2015.Rdata", sep = ""))
}
load(file = paste(scl.str.DAT_DIR, "data--trader-profits--26aug2015.Rdata", sep = ""))
## Plot trader profits
if (TRUE == TRUE) {
mat.df.PLOT <- mat.df.PROFITS
names(mat.df.PLOT) <- c("sigE",
"Short-Run Trader",
"Long-Run Trader",
"Noise Trader",
"Market Maker"
)
mat.df.PLOT$sigE <- mat.df.PLOT$sigE/scl.flt.SIG_V
mat.df.PLOT <- melt(mat.df.PLOT, c("sigE"))
theme_set(theme_bw())
scl.str.RAW_FILE <- "plot--expected-profits--26aug2015"
scl.str.TEX_FILE <- paste(scl.str.RAW_FILE,'.tex',sep='')
scl.str.PDF_FILE <- paste(scl.str.RAW_FILE,'.pdf',sep='')
scl.str.AUX_FILE <- paste(scl.str.RAW_FILE,'.aux',sep='')
scl.str.LOG_FILE <- paste(scl.str.RAW_FILE,'.log',sep='')
tikz(file = scl.str.TEX_FILE, height = 2.25, width = 7, standAlone=TRUE)
obj.gg2.PLOT <- ggplot()
obj.gg2.PLOT <- obj.gg2.PLOT + scale_colour_brewer(palette="Set1")
obj.gg2.PLOT <- obj.gg2.PLOT + geom_smooth(data = mat.df.PLOT,
aes(x = sigE,
y = value
),
method = "lm",
formula = y ~ ns(x, 6),
se = FALSE,
size = 1.75
)
## obj.gg2.PLOT <- obj.gg2.PLOT + geom_point(data = mat.df.PLOT,
## aes(x = sigE,
## y = value
## ),
## size = 0.50,
## alpha = 0.50
## )
obj.gg2.PLOT <- obj.gg2.PLOT + xlab("$\\sigma_{\\epsilon}/\\sigma_v$")
obj.gg2.PLOT <- obj.gg2.PLOT + ylab("")
obj.gg2.PLOT <- obj.gg2.PLOT + scale_x_continuous(limits = c(0, 1.5), breaks = c(0.00, 0.50, 1.00, 1.50))
obj.gg2.PLOT <- obj.gg2.PLOT + facet_wrap(~ variable, nrow = 1, scales = "free_y")
obj.gg2.PLOT <- obj.gg2.PLOT + theme(plot.margin = unit(c(1,0.15,0.15,-1), "lines"),
axis.text = element_text(size = 8),
axis.title = element_text(size = 10),
plot.title = element_text(vjust = 1.75),
panel.grid.minor = element_blank(),
legend.position = "none"
)
obj.gg2.PLOT <- obj.gg2.PLOT + ggtitle("Expected Profits")
print(obj.gg2.PLOT)
dev.off()
system(paste('lualatex', file.path(scl.str.TEX_FILE)), ignore.stdout = TRUE)
system(paste('rm ', scl.str.TEX_FILE, sep = ''))
system(paste('mv ', scl.str.PDF_FILE, ' ', scl.str.FIG_DIR, sep = ''))
system(paste('rm ', scl.str.AUX_FILE, sep = ''))
system(paste('rm ', scl.str.LOG_FILE, sep = ''))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment