高周波取引戦略について考える (3)

作者: リン・ハーン小草, 作成日:2023-08-07 18:17:28, 更新日:2023-09-18 19:50:53

img

前回の記事では,累積的な取引量モデリングや,価格ショック現象の単純な分析について説明しました. この記事では,トレードオーダーデータを取り巻く分析をさらに進めます. この2日間,YGGは,価格の変動が大きく,取引量が一度BTCを上回ったこともあり,今日,その分析を行いました.

注文時間間隔

一般的に,注文の到着時間がパッサンプロセスと一致すると仮定します.パッサンプロセス◎ ◎ ◎ ◎ ◎ ◎ ◎ ◎ ◎

8月5日のaggTradesをダウンロードすると1931193のトレードが,非常に誇張されている.まずは,支払いの分布を見てください. 100msと500msのあたりにスムーズな局所的なピークが見られます.

パルソン分布の確率質関数 (PMF) は,次の式で与えられる.

img

その中には:

  • k は,我々が興味を持っている事件の数である.
  • λは,単位時間 (または単位空間) 内のイベントの平均発生率である.
  • P ((k; λ) は,平均発生率 λ の条件下において,偶然に起こる k 件の確率を表します.

パッサン過程では,イベント間の時間間隔は指数分布に従います.指数分布の確率密度関数 (PDF) は,次の式で与えられる:

img

組み合わせにより,結果とパパソン分布の予想差が大きいことが判明し,パパソンプロセスは長い間隔時間の頻度を低估し,低い間隔時間の頻度を高估した. (実用的な間隔の分布は修正されたパパソン分布に近い)

from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
trades = pd.read_csv('YGGUSDT-aggTrades-2023-08-05.csv')
trades['date'] = pd.to_datetime(trades['transact_time'], unit='ms')
trades.index = trades['date']
buy_trades = trades[trades['is_buyer_maker']==False].copy()
buy_trades = buy_trades.groupby('transact_time').agg({
    'agg_trade_id': 'last',
    'price': 'last',
    'quantity': 'sum',
    'first_trade_id': 'first',
    'last_trade_id': 'last',
    'is_buyer_maker': 'last',
    'date': 'last',
    'transact_time':'last'
})
buy_trades['interval']=buy_trades['transact_time'] - buy_trades['transact_time'].shift()
buy_trades.index = buy_trades['date']
buy_trades['interval'][buy_trades['interval']<1000].plot.hist(bins=200,figsize=(10, 5));

img

Intervals = np.array(range(0, 1000, 5))
mean_intervals = buy_trades['interval'].mean()
buy_rates = 1000/mean_intervals
probabilities = np.array([np.mean(buy_trades['interval'] > interval)  for interval in Intervals])
probabilities_s = np.array([np.e**(-buy_rates*interval/1000) for interval in Intervals])

plt.figure(figsize=(10, 5))
plt.plot(Intervals, probabilities)
plt.plot(Intervals, probabilities_s)
plt.xlabel('Intervals')
plt.ylabel('Probability')
plt.grid(True)

img

統計的1s内の注文発生回数の分布とパプソン分布を比較すると,同じ差異が非常に顕著である. パプソン分布は,低確率事件の発生頻度を著しく低估している.

  • 不定発生率: パルソンプロセスは,任意の時間段間のイベントの平均発生率を定数と仮定する.この仮定が成立しない場合,データの分布はパルソン分布と偏差する.
  • プロセスの相互作用: パルソンのプロセスのもう一つの基本的な仮定は,イベントが相互に独立していることである.現実世界のイベントが相互に影響を与える場合,それらの分布はパルソンの分布から逸脱する可能性がある.

つまり,現実環境では,注文の発生頻度が不一定で,リアルタイムで更新が必要であり,固定時間内により多くの注文がより多くの注文を誘発するインセンティブ作用がある.これは,戦略が単一のパラメータを固定できないことを意味する.

result_df = buy_trades.resample('0.1S').agg({ 
    'price': 'count',
    'quantity': 'sum'
}).rename(columns={'price': 'order_count', 'quantity': 'quantity_sum'})
count_df = result_df['order_count'].value_counts().sort_index()[result_df['order_count'].value_counts()>20]
(count_df/count_df.sum()).plot(figsize=(10,5),grid=True,label='sample pmf');

from scipy.stats import poisson
prob_values = poisson.pmf(count_df.index, 1000/mean_intervals) 

plt.plot(count_df.index, prob_values,label='poisson pmf');
plt.legend() ;

img

パラメータをリアルタイムで更新する

前述の注文間隔の分析から,固定パラメータが実際の市場市場に適していないと結論づけられ,戦略の市場説明の重要なパラメータはリアルタイム更新が必要である. 最も考えやすい方法はスライドウィンドウの移動平均である. 下の2つの図は,それぞれ1s内の支払頻度と取引量の1000のウィンドウの平均値である. 取引集積現象があることが見られる. つまり,一定の時間間の注文頻度が通常よりも著しく高く,その時の量は同時に大きい. ここで上の一つの平均値を使用して最新の1秒間の予想値を測定し,残余の平均値による絶対誤差の平均値を使用して予測を測定する.

グラフから,注文頻度がパッサン分布からそれほど偏っている理由も理解できる.一方,平均的な注文数秒あたりは8.5回しかありませんが,極端な状況では平均的な注文数秒あたりは大きく偏っています.

この例では,最初の2秒間の平均値で予測された残差差の誤差は最小で,単純な平均値予測結果よりもはるかに優れていることが判明した.

result_df['order_count'][::10].rolling(1000).mean().plot(figsize=(10,5),grid=True);

img

result_df
order_count について 量_総数
2023-08-05 03:30:06.100 1 76.0
2023-08-05 03:30:06.200 0 0.0
2023-08-05 03:30:06.300 0 0.0
2023-08-05 03:30:06.400 1 416.0
2023-08-05 03:30:06.500 0 0.0
2023-08-05 23:59:59.500 3 9238.0
2023-08-05 23:59:59.600 0 0.0
2023-08-05 23:59:59.700 1 3981.0
2023-08-05 23:59:59.800 0 0.0
2023-08-05 23:59:59.900 2 534.0
result_df['quantity_sum'].rolling(1000).mean().plot(figsize=(10,5),grid=True);

img

(result_df['order_count'] - result_df['mean_count'].mean()).abs().mean()
6.985628185332997
result_df['mean_count'] = result_df['order_count'].ewm(alpha=0.11, adjust=False).mean()
(result_df['order_count'] - result_df['mean_count'].shift()).abs().mean()
0.6727616961866929
result_df['mean_quantity'] = result_df['quantity_sum'].ewm(alpha=0.1, adjust=False).mean()
(result_df['quantity_sum'] - result_df['mean_quantity'].shift()).abs().mean()
4180.171479076811

概要

この記事では,注文時間間隔偏差パパ松プロセスの理由を簡潔に説明します.主にパラメータが時間とともに変化するからです. より正確な市場予測のために,戦略は市場の基本パラメータをリアルタイムで予測する必要があります. 残差を使用して予測の良悪を測定することができます. 上記の最も簡単な例は,特定の時間配列分析,波動率集積などの関連研究が非常に多く,さらに改善することができます.


もっと