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

作者: リン・ハーンリディア, 作成日:2023-08-10 13:44:30, 更新日:2023-09-12 15:51:24

img

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

前回の記事では,注文到着間隔を研究することによって,パラメータを動的に調整し,見積もりの質を評価する方法を示した.この記事では,深度データに焦点を当て,中間価格 (フェア価格またはマイクロ価格としても知られる) を研究する.

深度データ

バイナンスでは,Best_bid_price (最高購入価格),best_bid_quantity (最高入札価格の量),best_ask_price (最低販売価格),best_ask_quantity (最高入札価格の量),およびトランザクション_タイムに関する歴史的なデータダウンロードを提供しています.このデータには,第2位またはより深いオーダーブックレベルが含まれていません. 本記事の分析は,8月7日のYGG市場に基づいています.この市場では900万点以上のデータポイントで有意な変動を経験しました.

まず,当日の市場状況を見てみましょう.大きな変動があり,オーダーブック量は市場の変動とともに大きく変化しました.特にスプレッドは,市場変動の程度を示しました.これは最高のオードとオード価格の違いです.当日のYGG市場の統計では,スプレッドは20%の時間で1つのティックよりも大きいものでした.この時代,さまざまな取引ボットがオーダーブックで競争しているため,そのような状況はますます稀になってきています.

[1] において

from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

[2] において

books = pd.read_csv('YGGUSDT-bookTicker-2023-08-07.csv')

[3] において

tick_size = 0.0001

[4] において

books['date'] = pd.to_datetime(books['transaction_time'], unit='ms')
books.index = books['date']

[5] において

books['spread'] = round(books['best_ask_price'] - books['best_bid_price'],4)

[6] において

books['best_bid_price'][::10].plot(figsize=(10,5),grid=True);

アウト[6]:

img

[7]:

books['best_bid_qty'][::10].rolling(10000).mean().plot(figsize=(10,5),grid=True);
books['best_ask_qty'][::10].rolling(10000).mean().plot(figsize=(10,5),grid=True);

アウト[7]:

img

[8] で:

(books['spread'][::10]/tick_size).rolling(10000).mean().plot(figsize=(10,5),grid=True);

アウト[8]:

img

[9]:

books['spread'].value_counts()[books['spread'].value_counts()>500]/books['spread'].value_counts().sum()

アウト[9]:

img

不均衡 の 引用

不均衡の報定は,ほとんどの場合,買いと売りの注文の間の注文簿の量の大きな違いから観察される.この差は,購入注文量の減少がしばしば減少につながる前に言及された理由に類似して,短期市場動向に強い予測効果を持っています. 注文簿の片側が他の部分よりも大幅に小さい場合,アクティブの買いと売りの注文の量が類似していると仮定すると,より小さな側が消費される可能性が高く,それによって価格の変化を誘発します. 不均衡の報定は,文字Iで表現されます.

img

Q_b は待機中の購入注文の金額 (best_bid_qty) と Q_a は待機中の売却注文の金額 (best_ask_qty) を表す.

中間価格を定義する

img

下のグラフは,次の1間隔における中間価格の変化率と不均衡Iとの関係を示しています.予想通り,価格がIが増加するにつれて上昇する可能性が高くなり,1に近づくほど価格変化が加速します.高周波取引では,中間価格の導入は将来の価格変化をより良く予測するためであり,つまり将来の価格差が小さいほど,中間価格がより良く定義されます.明らかに,待機中の注文の不均衡は,戦略の予測のために追加の情報を提供し,これを念頭に置いて,重量化された中間価格を定義します:

img

[10] で:

books['I'] = books['best_bid_qty'] / (books['best_bid_qty'] + books['best_ask_qty'])

[11] で:

books['mid_price'] = (books['best_ask_price'] + books['best_bid_price'])/2

[12] で:

bins = np.linspace(0, 1, 51)
books['I_bins'] = pd.cut(books['I'], bins, labels=bins[1:])
books['price_change'] = (books['mid_price'].pct_change()/tick_size).shift(-1)
avg_change = books.groupby('I_bins')['price_change'].mean()
plt.figure(figsize=(8,5))
plt.plot(avg_change)
plt.xlabel('I Value Range')
plt.ylabel('Average Mid Price Change Rate');
plt.grid(True)

アウト[12]:

img

[13]では:

books['weighted_mid_price'] = books['mid_price'] + books['spread']*books['I']/2
bins = np.linspace(-1, 1, 51)
books['I_bins'] = pd.cut(books['I'], bins, labels=bins[1:])
books['weighted_price_change'] = (books['weighted_mid_price'].pct_change()/tick_size).shift(-1)
avg_change = books.groupby('I_bins')['weighted_price_change'].mean()
plt.figure(figsize=(8,5))
plt.plot(avg_change)
plt.xlabel('I Value Range')
plt.ylabel('Weighted Average Mid Price Change Rate');
plt.grid(True)

アウト[13]:

img

調整された重みの中間価格:

グラフから,重度の中間価格がIの異なる値と比較して小さい変動を示し,それがより適していることを示していることが観察できる.しかし,特に0.2と0.8の周りに,いくつかの偏差が残っている.これは,私がまだ追加の情報を提供していることを示唆している.重度の中間価格が暗示している価格訂正期とIとの間の完全に線形関係という仮定は,現実と一致していない.グラフから,偏差速が0と1に近づくと増加することを見ることができます.非線形関係を示します.

I の定義が改められています.

Iの定義が修正された:

img

この時点で:

img

観察すると,重度の中間価格は平均中間価格への訂正であり,訂正期間がスプレッドに掛けられる.訂正期間がIの関数であり,重度の中間価格はI/2の単純な関係を仮定する.この場合,調整されたI分布 (-1,1) の利点は明らかになり,Iが起源の周りに対称性があり,関数に適した関係を見つけることが便利になる.グラフを調べると,この関数は,両方の辺の急成長と起源の対称性に準拠しているので,Iの乗数を満たすべきであることがわかります.さらに,起源の周りの値は線形に近いことが観察できます.さらに,Iが0であるとき,関数は0であり,Iが1であるとき,結果は0.5です.したがって,この関数の式は推測されています:

img

N は正偶数で,実際のテストの後,N が 8 になる方が良い.これまでのところ,この論文では,修正された重みの中間値を示しています.

img

この時点で,中間価格変動の予測は,もはやIと大きく関係していない.この結果は単純な重量化された中間価格よりもわずかに優れているが,実際の取引シナリオではまだ適用できない.これは提案されたアプローチに過ぎない.S Stoikovによる2017年の記事では,マイクロ価格マルコフ連鎖アプローチを用いて導入され,関連するコードが提供されています.研究者はこのアプローチをさらに調査することができます.

[14] では:

books['I'] = (books['best_bid_qty'] - books['best_ask_qty']) / (books['best_bid_qty'] + books['best_ask_qty'])

[15] について

books['weighted_mid_price'] = books['mid_price'] + books['spread']*books['I']/2
bins = np.linspace(-1, 1, 51)
books['I_bins'] = pd.cut(books['I'], bins, labels=bins[1:])
books['weighted_price_change'] = (books['weighted_mid_price'].pct_change()/tick_size).shift(-1)
avg_change = books.groupby('I_bins')['weighted_price_change'].mean()
plt.figure(figsize=(8,5))
plt.plot(avg_change)
plt.xlabel('I Value Range')
plt.ylabel('Weighted Average Mid Price Change Rate');
plt.grid(True)

アウト[15]:

img

[16]:

books['adjust_mid_price'] = books['mid_price'] + books['spread']*books['I']*(books['I']**8+1)/4
bins = np.linspace(-1, 1, 51)
books['I_bins'] = pd.cut(books['I'], bins, labels=bins[1:])
books['adjust_mid_price'] = (books['adjust_mid_price'].pct_change()/tick_size).shift(-1)
avg_change = books.groupby('I_bins')['adjust_mid_price'].mean()
plt.figure(figsize=(8,5))
plt.plot(avg_change)
plt.xlabel('I Value Range')
plt.ylabel('Weighted Average Mid Price Change Rate');
plt.grid(True)

アウト[16]:

img

概要

中間価格は,短期間の将来の価格の予測として機能するため,高周波戦略にとって極めて重要です.したがって,中間価格が可能な限り正確であることが重要です.前述した中間価格アプローチは,オーダーブックデータに基づいており,分析にはオーダーブックの上位レベルのみが利用されます.ライブ取引では,戦略は,実際の取引価格に対して中間価格予測を検証するために,取引データを含むすべての利用可能なデータを利用することを目指すべきです.ストイコフはツイッターで,実際の中間価格が実行されるオファーとオファー価格の確率の重量平均であるべきであることを言及したことを覚えています.この問題は以前の記事で探討されています.長さの制約のために,これらのトピックについての詳細は次の記事で議論されます.


もっと