ジャンプがあるときの指値最適化
この記事は仮想通貨botter Advent Calendar 2023の24日目の記事です。
はじめに
market making botを作る際にAvellaneda and Stoikov(以下AS)の結果を使ってみようと思ったことがあるbotterの人は多いのではないでしょうか。そして、実際使ってみて儲からないな、となった方も多いのではないでしょうか。私もその一人です。この記事では、「ASがなぜうまくいかないのか」「ジャンプがあるときのASの拡張」について紹介します。参考文献はAlgorithmic and High-Frequency Tradingです。
ASの復習
ASの結果を復習しておきます。
で表されます。ここで、
基準価格
気持ちとしては、
- 買いポジションが多いほど在庫リスクを解消したいので基準価格を下げるべき(逆もしかり)
- 残存期間が大きいほど価格変動リスクを取れるので指値幅を広げるべき
- ボラティリティが大きいほど取れる幅が大きいので指値幅を広げるべき
- "成行注文の強さ"が大きいほど指値幅を広げるべき
というような感じでしょうか。
ASは何をしているのか
さて、ASモデルの結果はわかりましたが、そもそもASが解こうとしている問題はなんでしょうか。
時刻
ここで、効用とは、どれくらい嬉しいかを定量的に扱おうというもので、簡単なものだとMtMの期待値などが考えやすいかと思います。ただし、例えばMtMの期待値が高くても、その分散が大きいと実際には嬉しくないかもしれません。そのあたりを考慮した効用関数を考える必要があります。ASではCRRA型と呼ばれる効用関数を採用しています。
ここで、ASモデルで仮定していることを整理してみましょう。
- 価格(仲値)の変動がブラウン運動に従う[2]
- 仲値から深さ
に飛んでくる成行注文の頻度は、売り、買いともに\delta である。ここで、Ae^{-\delta k} はパラメータA - 成行注文のサイズは一定である。
- 仲値の変動と成行注文の到着は独立である。
が主な仮定かと思います。[3]
ASモデルでは、このような仮定のもとで、最もいい(最も効用が大きくなる)指値幅を求めています。逆に言うと、ASモデルの仮定が一つでも満たされていないと、ASモデルで得られる指値幅は最適ではなくなる可能性がある、ということです。
実際、仮想通貨市場ではこれらの仮定は全然満たされていないと考えられます。[4]
例えば、成行注文がベストより深いところに飛ぶ状況というのは複数の板が約定しているので、「仲値の変動と成行注文の到着は独立」というのはかなり無理があると思います。成行で食われた板のところに一瞬で板が出し直される、という状況であればある程度成り立つかもしれませんが。[5]
また、仲値がブラウン運動というのも実際のデータを確認すると当てはまっていないように見えます。
(ちょっとテクニカルな話)
ASモデルのいいところは、最適指値幅を解析的に求めることができるという点です。最適指値の導出には動的計画法を用いてHJB方程式を得た上で、HJB方程式を解くというステップを踏みます。[6]こうして得られたHJB方程式は非線形微分差分方程式になるので、通常は解析解を持ちません。そこで、実際に戦略を実行しようとすると、マーケットのパラメータが変わるごとにHJB方程式を計算機で解かなければなりません。
ASモデルでは漸近展開を用いることで近似解を解析的に得ました。これにより、HJB方程式を毎回解く必要がなくなりました。また、解析解が得られたことにより、戦略の性質をより理解しやすくなりました。
ASの拡張
ASモデルの仮定が満たされていないのであれば、ASモデルを拡張することで、より仮定が現実に即したモデルを作ろう、という研究がいくつかあります。仮定が完璧に現実に即していれば、それは本当の最適指値です。
ここでは、そのような拡張のうち、ジャンプがあるときのASの拡張を紹介します。
さて、ASモデルの問題設定では仲値
を仮定していました。ここで、
しかし、上の図であったように仲値はブラウン運動というよりむしろジャンプを含んだ過程に従うと考えられます。そこで、仲値の過程を
と仮定してやります。ここで、
気持ちとしては、先程は考慮されたいなかった成行注文による仲値の変動をモデルに組み込んでやろう、というものです。こうすることで、MtMの期待値の評価にジャンプが組み込まれる分、最適指値に補正が入ります。
詳細な計算はAlgorithmic and High-Frequency Tradingを参照してください。
結論だけ言うと、
となります。[8]
ここで、ここで
としたとき、
で表されます。
結構いかつい式が出てきますが、導出等はASモデルとだいたい一緒です。
また、在庫リスクへのジャンプの影響分も考える必要があります。それが右辺第三項目です。ただ、これは
import numpy as np
from scipy.linalg import expm
import matplotlib.pyplot as plt
n = 7
z = np.ones(n, dtype=float)
A = np.zeros((n, n), dtype=float)
q = np.linspace(3, -3, n)
k = 100.
lambda_p = 1.
lambda_m = 1.
sigma = 0.01
gamma = 0.04
T = 30.
t = np.linspace(0, T, 100)
omega = np.zeros((len(t), n))
def plot_delta(eta_p, eta_m, alpha=1.):
for i in range(n):
for j in range(n):
if i == j:
A[i, j] = q[i] * k * (eta_p * lambda_p - eta_m * lambda_m) - 0.5 * sigma ** 2 * gamma * k * q[i] ** 2
if i == j - 1:
A[i, j] = lambda_p * np.exp(-1 -k * eta_p)
if i == j + 1:
A[i, j] = lambda_m * np.exp(-1 -k * eta_m)
for i, t_ in enumerate(t):
omega[i] = expm(A * (T - t_)) @ z
for q_i, q_ in enumerate(q):
if q_i == 0:
continue
plt.plot(t, 1/k + eta_p - 1/k * np.log(omega[:, q_i-1]) + 1/k * np.log(omega[:, q_i]), label=f"(q={q_}, {eta_p=}, {eta_m=})", alpha=alpha)
plt.xlabel("t")
plt.ylabel("depth")
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, fontsize=12)
plot_delta(0.005, 0.005, 1.)
plot_delta(0., 0., 0.3)
plt.title("buy depth")
結果は下の図のようになります。
薄い線のほうが
実際、ジャンプの大きさの期待値分だけシフトしたものとほとんど一致しているように見えます。
パラメータによってはもう少し効果がはっきり現れるかもしれません。
結果としては、ジャンプの大きさの期待値が分かれば、ジャンプがない場合の指値から期待値分だけ深く出すのが良さそうです。
まとめ
この記事ではASモデルの結果とジャンプがある場合の最適指値を考察しました。
ASモデルやその拡張は、仮定がかなり厳しいために、そのままでは実際には使えるケースは非常に少ないと思います。ただし、こういったモデルからヒントを得ることはできると思います。今回でいうと、ジャンプの影響を取り込むにはジャンプの大きさ分だけ指値を深く出すのが良さそうという考察が得られました。もちろん、ジャンプの大きさの期待値をどう推定するか等の問題は残りますが、この考察部分だけを取り出して戦略に組み込むことができるかもしれないし、また、経験的にうまくいっている戦略の解釈にも応用できるかもしれません。
-
Ho and Stollあたりから考えられている問題です。 ↩︎
-
デリバティブでは幾何ブラウン運動等を仮定することが多いですが、ASモデルのように高頻度取引で利用する確率制御モデルの場合、価格が負になる確率は無視できるので、ブラウン運動でモデル化することが多いです。 ↩︎
-
他にもあるかもしれません。取引にかかるfeeなど。ちなみにfee rateが一定の場合にはASモデルに組み込むことができるはずです。 ↩︎
-
他の市場では仮定がある程度満たされているかもしれません。関連の文献を見ていると債券市場であったり、相対の取引モデル等では有効なのかもしれません。 ↩︎
-
仲値の変動は1.ベストに置かれた指値注文のサイズ以上の成行注文の到着と2.スプレッド内への指値注文の到着、3.ベストに置かれた指値注文のキャンセル、によって決まるので1-3を確率過程としてモデル化する、とすればより正確になるのではないかと思います。ブラウン運動を仮定する、そういうのを全部ひっくるめてしまっているので無理が生じている部分があるはずです。そういう文献もあった気がします。 ↩︎
-
ASモデルで考えているような問題を解く、という話であれば、もちろん他の解き方もあります。モンテカルロしたり、最大値原理を用いたり。 ↩︎
-
期待値が定義されるiidであれば何でもOKです。 ↩︎
-
実は明示していませんでしたが、効用関数の形がASモデルとは違うので、ちょっと形が変わっています。
が小さいときに\gamma とできるので、Algorithmic and High-Frequency Tradingの(10.27a, b)の式はASモデルで(1/\gamma)\ln(1+\gamma/k)\sim 1/k を小さいとしたときに対応していると思ってもらえばわかりやすいかも。10.3に詳しいことが書いてあります。また、簡単のために\gamma としています。 ↩︎\alpha=0 -
間違っていたらすみません。 ↩︎
Discussion