利用不同的排隊論模型得到limit order book的平均隊列長度QL和平均等待時間DLC特咆,與收益率進行相關性分析个从。
模型假設
使用買一價和賣一價的平均值作為 reference price,用一段時間間隔下reference price 的變化率作為收益率坎穿。利用use.total_amount和use.net_amount可以得到買方和賣方的成交單量沟优,分別作為隊列的離開與到達岔擂。
使用數據
文件/data/intern/3_weeks.pq,每0.25s一個數據點惩嘉。后面主要用到中頻和高頻兩種取樣方法罢洲。
中頻:每10s的volume求和作為一個點。對于每個點文黎,使用其前30分鐘的數據作為隊列計算惹苗,與后15min的收益率進行相關性檢驗。
高頻:每1s的volume求和作為一個點耸峭。對每個點桩蓉,使用其前60s的數據作為隊列計算,與后15s的收益率進行相關性檢驗劳闹。
模型總結
M/M/1模型
假定到達與離開都服從poisson分布,參數記為\lambda, \mu本涕,則有緩沖效用\rho=\frac{\lambda}{\mu}
QL=\frac{\rho}{1-\rho} , DLC=\frac{\rho}{\mu-\lambda}
M/M/1/N
在上模型基礎上限定最大隊長N
DLC=\rho*\frac{1-(N+1)\rho^N+N\rho^{N+1}}{(1-\rho)(1-\rho^{N+1})}
M/G/1模型
假定離開是獨立同分布业汰,其他同M/M/1
QL=\frac{\lambda^2 \overline {X^2}}{2(1-\rho)} , DLC=\frac{\lambda \overline {X^2}}{2(1-\rho)}
G/G/1模型
到達與離開都是獨立同分布,沒有直接的計算公式偏友,需要先算出隊列的概率密度函數再計算蔬胯。具體到本limit order book的問題,概率分布的公式如下:
\pi_i(n)=\pi_i(0)\prod_{j=1}^n \rho_i(j-1)
\pi_i(0)=(1+\sum_{n=1}^\infty \prod_{j=1}^n\rho_i(j-1))^{-1}
則一般情況下可得:
DLY_i=1-\pi_i(0)
QL_i=\sum_{k=1}^\infty k\pi_i(1+k)
運算代碼
M/M/1模型
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import math
from scipy.stats import pearsonr
data = pd.read_parquet('/data/intern/3_weeks.pq')
Pref=(data['ask1']+data['bid1'])/2
data["Pref"]=Pref
use=data.loc[:,['net_amount','total_amount','Pref']]
use['decrease_amount']=(use.total_amount+use.net_amount)/2#買方成交單量 離開
use['increase_amount']=(use.total_amount-use.net_amount)/2#賣方成交單量 到達
use=use.resample('10s').sum()#以10s的數據計算
lambda_=use.increase_amount.rolling('30T').mean()
mu_=use.decrease_amount.rolling('30T').mean()
rate=np.ones(len(use))
for i in range(len(use)):
if i < 60:
rate[i]=(use.Pref[i]-use.Pref[0])/use.Pref[0]
else:
rate[i]=(use.Pref[i-60]+use.Pref[i])/use.Pref[i-60]
use["rate"]=rate
#清除死亡率小于出生率的點
lambda0=[]
mu0=[]
rate0=[]
for i in range(len(mu_)):
if mu_[i]>lambda_[i]:
lambda0.append(lambda_[i])
mu0.append(mu_[i])
rate0.append(rate[i])
rho=np.array(lambda0)/np.array(mu0)
lambda_=np.array(lambda0)
mu_=np.array(mu0)
rate=np.array(rate0)
#平均等待時間W,平均隊長N
W=rho/(mu_-lambda_)
N=lambda_*W
N_use=N[180:-60]
rate_use=rate[240:]
pearsonr(N_use,rate_use)
M/G/1模型
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import math
from scipy.stats import pearsonr
data = pd.read_parquet('/data/intern/3_weeks.pq')
Pref=(data['ask1']+data['bid1'])/2
data["Pref"]=Pref
use=data.loc[:,['net_amount','total_amount','Pref']]
use['decrease_amount']=(use.total_amount+use.net_amount)/2#買方成交單量 離開
use['increase_amount']=(use.total_amount-use.net_amount)/2#賣方成交單量 到達
use=use.resample('10s').sum()#以10s的數據計算
lambda_=use.increase_amount.rolling('30T').mean()
mu_=use.decrease_amount.rolling('30T').mean()
rate=np.ones(len(use))
#計算10分鐘平均收益率
for i in range(len(use)):
if i < 90:
rate[i]=(use.Pref[i]-use.Pref[0])/use.Pref[0]
else:
rate[i]=(use.Pref[i-90]+use.Pref[i])/use.Pref[i-90]
use["rate"]=rate
key=use.decrease_amount*use.decrease_amount
key=key.rolling('30T').mean()
#清除死亡率小于出生率的點
lambda0=[]
mu0=[]
rate0=[]
for i in range(len(mu_)):
if mu_[i]>lambda_[i]:
lambda0.append(lambda_[i])
mu0.append(mu_[i])
rate0.append(rate[i])
rho=np.array(lambda0)/np.array(mu0)
lambda_=np.array(lambda0)
mu_=np.array(mu0)
rate=np.array(rate0)
#平均等待時間W,平均隊長N
W=(lambda_*key)/(2*(1-rho))
N=lambda_*W
N_use=N[180:-60]
rate_use=rate[240:]
pearsonr(N_use,rate_use)
G/G/1模型
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import pearsonr
data = pd.read_parquet('/data/intern/3_weeks_1s.pq')
use=data.loc[:,['net_amount','total_amount']]
use['decrease_amount']=(use.total_amount+use.net_amount)/2#買方成交單量 離開
use['increase_amount']=(use.total_amount-use.net_amount)/2#賣方成交單量 到達
use=use.resample('10s').sum()
use=use[:500]#確定隊列長度
Pref=(data['ask1']+data['bid1'])/2
use["Pref"]=Pref
#計算隊列
use['total_size']=np.add.accumulate(use.increase_amount)-np.add.accumulate(use.decrease_amount)
#用clip函數處理極值
use.decrease_amount=np.clip(use.decrease_amount.values,0.001,100000)
use.increase_amount=np.clip(use.increase_amount.values,0.001,100000)
use.total_size=use.total_size/4000#size減小倍位他,這樣size的概率密度函數有意義氛濒,不然都是0或1
use.total_size=use.total_size.astype(int)#模型需要用整數計算
t=180#30min*6數據點個數
#frho函數产场,用于確定第i個點的rho(n)的值,
def frho(i,n):
queue=use[i-t:i]
sincrease=0.00001
sdecrease=0.00001
for j in range(len(queue)-1):
if queue.total_size[j] == n:
sincrease+=queue.increase_amount[j]
sdecrease+=queue.decrease_amount[j+1]
return sincrease/sdecrease
use['num']=range(len(use))
times=40#無窮次求和,設置一個大數,觀察知rho_times=0舞竿,則設為t足夠
def fpi(i,n):
a_use1=[]
onlyusethere=[]
for j in range(times):
x=frho(i,j+1)
onlyusethere.append(x)
a_use1=np.add.accumulate(onlyusethere)
t_use=np.multiply.accumulate(a_use1)
pi_0=1/(1+t_use.sum())
if n==0:
return pi_0
else:
return pi_0*t_use[n-1]
QL=[]
for i in range(len(use))[t:len(use)]:
sum=0
for j in range(times):
sum+=j*fpi(i,j)
QL.append(sum)
print(len(QL))
QL
#將QL寫入外部文件京景,便于并行時調用
output = open('1.pk', 'wb')
pickle.dump(QL, output)
output.close()
rate=np.ones(len(use))
#計算10分鐘平均收益率
for i in range(len(use)):
if i < 90:
rate[i]=(use.Pref[i]-use.Pref[0])/use.Pref[0]
else:
rate[i]=(use.Pref[i-90]+use.Pref[i])/use.Pref[i-90]
use["rate"]=rate
N_use=QL[:-60]
rate_use=use.rate[240:]
pearsonr(N_use,rate_use)
結果分析
M/M/1
高頻:
pearson相關系數:-8.09*10^{-5}
中頻:
pearson相關系數:0.0104
M/M/1/N
N 取50時
高頻:
pearson相關系數:-0.04734
中頻:
pearson相關系數:-0.0378
N 取10時
高頻:
pearson相關系數:-0.0059
中頻:
pearson相關系數:0.04312
M/G/1
高頻:
pearson相關系數:8.66*10^{-4}
中頻:
pearson相關系數:0.0015
G/G/1
考慮到中頻的相關性明顯高于高頻情況,只列出中頻的結果骗奖,并用過去5min收益率确徙、10min收益率、15min收益率作為信號执桌,同未來15min收益率計算相關性進行對比鄙皇。
計算1.5h的數據(540個數據點)
pearson相關系數:0.44798
前5min收益率與后15min收益率相關性:-0.3894
前10min收益率與后15min收益率相關性:-0.4175
前15min收益率與后15min收益率相關性:-0.5029
計算12小時的數據(4000個數據點)
pearson相關系數:0.08827
前5min收益率與后15min收益率相關性:-0.4396
前10min收益率與后15min收益率相關性:-0.4275
前15min收益率與后15min收益率相關性:-0.4147
計算24小時的數據(8000個數據點)
pearson相關系數:0.05169
前5min收益率與后15min收益率相關性:-0.4582
前10min收益率與后15min收益率相關性:-0.4570
前15min收益率與后15min收益率相關性:-0.4515
數據量變大時,前5min,10min,15min收益率和后15min收益率的相關性系數基本不變仰挣,維持較高的值伴逸,而GG1模型得出的相關系數持續(xù)減小