R语言对高频交易订单流进行建模分析 4
2017-08-25 20:05
615 查看
一、实验介绍--订单流模型拟合
1.1 实验知识点
指数核 hawkes 过程拟合正反馈强度分析
订单量影响分析
1.2 实验环境
R 3.4.1Rstudio
二、订单流模型拟合
在上节中我们对订单流数据做了一些统计分析 , 对交易的一些特征有了一些粗浅的理解 , 在本节中 我们要做的是利用实际数据来拟合 hawkes 过程 ,看一看真实数据的订单流动力学中有什么特征。首先我们仍是选出交易时间内的数据:
library(tidyverse) library(lubridate) dat <- read.csv(url("http://labfile.oss.aliyuncs.com/courses/883/pigu.csv")) bisect_lower_bound <- function(x) { date <- as.POSIXct(x[1],origin="1970-01-01",tz="America/Chicago") + days(1) hour(date) <- 8 minute(date) <- 30 second(date) <- 0 k <- as.numeric(date) l = -1 r = length(x)+1 while(r-l>1) { mid = round((l+r)/2) if (x[mid] >= k) r=mid else l=mid } r } bisect_higher_bound <- function(x) { date <- as.POSIXct(x[1],origin="1970-01-01",tz="America/Chicago") + days(1) hour(date) <- 15 minute(date) <- 0 second(date) <- 0 k <- as.numeric(date) l = -1 r = length(x)+1 while(r-l>1) { mid = round((l+r)/2) if (x[mid] <= k) l=mid else r=mid } l } start <- bisect_lower_bound(dat$time) end <- bisect_higher_bound(dat$time) trade <- dat[start:end,]
2.1 指数核 hawkes 过程拟合
形象地来看,限价单组建起了买方和卖方的堡垒,而市价单则对对手的堡垒发起冲击。那么作为进攻部队,市价单对买方卖方力量的博弈是非常关键的,在本节中我们就单独看一看市价单的动力学是怎么样的。
我们先把所有的市价单单独提出来:
market_order <- trade[trade$action_type=="T",] head(market_order)
## X action_item action_type ask_price ask_vol bid_price bid_vol ## 959396 959395 trd T 145925 643 145900 364 ## 959397 959396 trd T 145925 640 145900 364 ## 959413 959412 trd T 145925 642 145900 372 ## 959414 959413 trd T 145925 642 145900 366 ## 959415 959414 trd T 145925 642 145900 365 ## 959416 959415 trd T 145925 642 145900 364 ## price time vol ## 959396 145925 1358260200 3 ## 959397 145925 1358260200 3 ## 959413 145900 1358260200 1 ## 959414 145900 1358260200 6 ## 959415 145900 1358260200 1 ## 959416 145900 1358260200 1
然后做一些预处理,把时间相同的订单进行合并,并把所有时间减去初始值
m <- market_order %>% group_by(time) %>% summarise(sum(vol)) time <- m$time - m$time[1] vol <- m$`sum(vol)`
首先我们不考虑订单量的大小,把所有买单卖单视作同质的,用指数核的 hawkes 过程进行拟合,
这里可以直接使用第二节所用的似然函数,然后用 nlminb 函数做优化:
log_likelihood <- function(params , event) { mu = params[1] alpha = params[2] beta = params[3] n = length(event) t_n = event kernel_sum <- numeric(n) for (i in 2:n) { kernel_sum[i] = (kernel_sum[i-1]+alpha) * exp(-beta*(event[i] - event[i-1])) } lambda <- kernel_sum + mu L = sum( log(lambda) ) - mu * t_n - alpha*n/beta + alpha/beta*sum(exp(-beta*(t_n-event))) #print(L) -L }
nlminb(c(1,1,1) , log_likelihood ,event= time)
## $par ## [1] 1.522979 145.265214 368.465284 ## ## $objective ## [1] -80224.79 ## ## $convergence ## [1] 0 ## ## $iterations ## [1] 39 ## ## $evaluations ## function gradient ## 44 131 ## ## $message ## [1] "relative convergence (4)"
拟合得到的 beta 的值非常大,说明前面事件对后面事件的影响衰减得非常快。注意 1/beta 被定义为 Hawkes 过程的记忆时间 , 超过这个时间的后续事件基本不受这个事件的影响 。 这里我们可以看到影响周期小于一毫秒 , 说明频率确实非常快。
2.2 正反馈强度分析
索罗斯在他的“金融炼金术”中提出了一种叫做 reflexity(自反性)的理论 , 这个理论说的是投资者和交易者的认知偏差会改变标的的基本面。例如一支股票持续上涨,会使得投资者对提高对它基本面的认知 ,又反过来推动股价的进一步上升, 从而形成正反馈。但是如何量化地对正反馈进行分析一直是一个问题。在 Hawkes 过程中,根据 lambda 的表达式我们可以把事件发生的强度分为两部分 , 一部分是背景的强度 , 一部分则是由前面事件激发而得到的强度,这部分“衍生”的强度的平均值可以被认为是正反馈的强度。
例如在指数核中,我们可以通过积分计算出正反馈机制的比例是 alpha / beta , 下面我们把一天的时间按照30分钟的间隔分为13段 , 看看每一段的背景强度和 reflexity 分别是多少。
time_cut <- cut(time , breaks = seq(-0.01 , time[length(time)]+0.01 , length.out=14) ) reflexity <- as.data.frame(cbind(time , time_cut)) reflexity_res <- list() for (i in 1:13) { ref_time <- time[reflexity$time_cut==i] ref_time <- ref_time - ref_time[1] ref_res <- nlminb(c(1,1,1) , log_likelihood ,event= ref_time ) reflexity_res[[i]] <- ref_res } ## Warning messages: ## 1: In log(lambda) : \u4ea7\u751f\u4e86NaNs ## 2: In nlminb(c(1, 1, 1), log_likelihood, event = ref_time) : ## NA/NaN function evaluation ## 3: In log(lambda) : \u4ea7\u751f\u4e86NaNs ## 4: In nlminb(c(1, 1, 1), log_likelihood, event = ref_time) : ## NA/NaN function evaluation ## 5: In log(lambda) : \u4ea7\u751f\u4e86NaNs ## 6: In nlminb(c(1, 1, 1), log_likelihood, event = ref_time) : ## NA/NaN function evaluation mu_vec <- c() alpha_vec <- c() beta_vec <- c() for (i in 1:13) { mu_vec <- c(mu_vec , reflexity_res[[i]]$par[1]) alpha_vec <- c(alpha_vec , reflexity_res[[i]]$par[2]) beta_vec <- c(beta_vec , reflexity_res[[i]]$par[3]) } time_vec <- seq(market_order$time[1]-0.01 , market_order$time[nrow(market_order)]+0.01 , length.out=14) time_vec <- as.POSIXct(time_vec,origin="1970-01-01",tz="America/Chicago")
par(mfrow=c(2,1)) plot(time_vec[1:(length(time_vec)-1)],mu_vec , col="blue" , type="b" , xlab="time" , ylab="mu" , main="background intensity in different periods") plot(time_vec[1:(length(time_vec)-1)] , col="red" , type="b",alpha_vec/beta_vec , xlab="time" , ylab="alpha/beta",main = "reflexity in different periods" )
我们把背景强度和 reflexity 分别画出来,可以看到背景强度形成了一个碗状,说明开盘和收盘时的事件的背景强度较大。而 reflexity 则在各个 时间段基本一致,基本围绕 0.4 波动。
2.3 考虑订单数量
前面我们把订单视作同质进行分析 ,但是很明显量大的订单对市场的冲击更大,我们应该 把订单的数量考虑进去。首先我们看一下整个时间段的订单强度:
plot(time , vol , type="l" , ylab="volume" , xlab="time" , main="market order intensity")
然后我们可以开始尝试建模,将量的因素考虑进去:
其中 nj 代表第 j 个事件的数量。
log_likelihood_volume <- function(params , event , vol) { mu = params[1] alpha = params[2] beta = params[3] n = length(event) t_n = event kernel_sum <- numeric(n) for (i in 2:n) { kernel_sum[i] = (kernel_sum[i-1]+alpha*vol[i-1]) * exp(-beta*(event[i] - event[i-1])) } lambda <- kernel_sum + mu L = sum( log(lambda) ) - mu * t_n - alpha/beta*sum(vol) + alpha/beta*sum(vol*exp(-beta*(t_n-event))) #print(L) -L }
nlminb(c(1,1,1) , log_likelihood_volume ,event= time , vol= vol )
## Warning in log(lambda): NaNs produced ## Warning in nlminb(c(1, 1, 1), log_likelihood_volume, event = time, vol = ## vol): NA/NaN function evaluation ## Warning in log(lambda): NaNs produced ## Warning in nlminb(c(1, 1, 1), log_likelihood_volume, event = time, vol = ## vol): NA/NaN function evaluation ## Warning in log(lambda): NaNs produced ## Warning in nlminb(c(1, 1, 1), log_likelihood_volume, event = time, vol = ## vol): NA/NaN function evaluation ## $par ## [1] 1.557608 7.106736 293.679848 ## ## $objective ## [1] -82261.69 ## ## $convergence ## [1] 0 ## ## $iterations ## [1] 44 ## ## $evaluations ## function gradient ## 56 150 ## ## $message ## [1] "relative convergence (4)"
2.4 订单数量的幂指数
前面我们假设订单量的影响是线性的,可真实是这样的吗,我们尝试在订单数量上加入一个幂指数。那么强度的表达式变为
log_likelihood_volume_exponent <- function(params , event , vol) { mu = params[1] alpha = params[2] beta = params[3] k = params[4] n = length(event) t_n = event kernel_sum <- numeric(n) vol <- vol^k for (i in 2:n) { kernel_sum[i] = (kernel_sum[i-1]+alpha*vol[i-1]) * exp(-beta*(event[i] - event[i-1])) } lambda <- kernel_sum + mu L = sum( log(lambda) ) - mu * t_n - alpha/beta*sum(vol) + alpha/beta*sum(vol*exp(-beta*(t_n-event))) -L }
nlminb(c(1,1,1,1) , log_likelihood_volume_exponent ,event= time , vol= vol)
## $par ## [1] 1.5214343 42.1613593 321.6189710 0.5287265 ## ## $objective ## [1] -86579.32 ## ## $convergence ## [1] 0 ## ## $iterations ## [1] 51 ## ## $evaluations ## function gradient ## 67 231 ## ## $message ## [1] "relative convergence (4)"
从参数我们可以看到k的值大约是 0.5 , 说明订单的影响大约是数量的根号,并不是线性增长的。 这是非常有趣的一个现象 , 说明订单量的冲击是边际递减的。
三、 总结
在前面我们对市价单的动力学进行建模 , 我们看到了一些有趣的现象, 例如日内交易背景强度的变化;订单数量影响的幂指数小于1。 这些都可以做进一步地挖掘,可以让我们更加深入地理解市场的动力学。相关文章推荐
- R语言对高频交易订单流进行建模分析 1
- R语言对高频交易订单流进行建模分析 2
- R语言对高频交易订单流进行建模分析 3
- 运用四色建模法进行领域分析
- 运用四色建模法进行领域分析
- [转]高频交易数据的时间序列如何建模
- PBOC/EMV-交易流程详解--POS与卡片的数据交互进行分析
- QPBOC交易流程详解--POS与卡片的数据交互进行分析
- 运用四色建模法进行领域分析
- PBOC/EMV-交易流程详解--POS与卡片的数据交互进行分析
- 2013年东三省数模A题第三问-(对统计性竞赛题进行建模分析)
- 代写CS|留学生|金融编程|代码代做|C++语言|JAVA|R语言|Python|经济统计|数值分析|建模|作业加急|天才写手网
- 对比较复杂的数据结构进行建模分析
- 转载:案例用Excel对会员客户交易数据进行RFM分析
- QPBOC交易流程详解--POS与卡片的数据交互进行分析
- 运用四色建模法进行领域分析
- QPBOC交易流程详解--POS与卡片的数据交互进行分析
- QPBOC交易流程详解--POS与卡片的数据交互进行分析
- 用R语言进行回归分析
- 用R语言进行数据分析