🌊

ジャンプがあるときの指値最適化

2023/12/23に公開

この記事は仮想通貨botter Advent Calendar 2023の24日目の記事です。

はじめに

market making botを作る際にAvellaneda and Stoikov(以下AS)の結果を使ってみようと思ったことがあるbotterの人は多いのではないでしょうか。そして、実際使ってみて儲からないな、となった方も多いのではないでしょうか。私もその一人です。この記事では、「ASがなぜうまくいかないのか」「ジャンプがあるときのASの拡張」について紹介します。参考文献はAlgorithmic and High-Frequency Tradingです。

ASの復習

ASの結果を復習しておきます。tを時刻、sを価格(例えば仲値とか)、在庫をqとすると、基準価格と最適指値幅は

\begin{align} r(s, t)&=s-q \gamma \sigma^2(T-t) \\ \delta^a(t)+\delta^b(t)&=\gamma \sigma^2(T-t)+\frac{2}{\gamma} \ln \left(1+\frac{\gamma}{k}\right) \end{align}

で表されます。ここで、\delta^a(t), \delta^b(t)はそれぞれask, bidの最適指値幅、\gammaはリスク回避度、\sigmaはボラティリティ、T-tは残存時間、kは"成行注文の強さ"を表すパラメータです。
基準価格r(s,t)から、上下に\delta^a(t), \delta^b(t)だけ離れたところに指値を出す、という戦略になります。

気持ちとしては、

  • 買いポジションが多いほど在庫リスクを解消したいので基準価格を下げるべき(逆もしかり)
  • 残存期間が大きいほど価格変動リスクを取れるので指値幅を広げるべき
  • ボラティリティが大きいほど取れる幅が大きいので指値幅を広げるべき
  • "成行注文の強さ"が大きいほど指値幅を広げるべき

というような感じでしょうか。

\sigma, kはマーケットのデータから推定すべきパラメータで、一方で\gammaTは自分で設定するパラメータです。なので、実際に運用する場合には\sigma, kを逐次推定し、最適指値幅を更新していく、という実装になります。

ASは何をしているのか

さて、ASモデルの結果はわかりましたが、そもそもASが解こうとしている問題はなんでしょうか。

時刻tに仲値から\delta^{a,b}(t)だけ離して指値を出すという戦略をとったときに、将来時点Tで現金+資産の評価額(mark to market: MtM)の確率分布が得られます。分布が得られると効用関数が求められるので、効用を最大化するような\delta^{a,b}(t)を求める、という問題です。[1]
ここで、効用とは、どれくらい嬉しいかを定量的に扱おうというもので、簡単なものだとMtMの期待値などが考えやすいかと思います。ただし、例えばMtMの期待値が高くても、その分散が大きいと実際には嬉しくないかもしれません。そのあたりを考慮した効用関数を考える必要があります。ASではCRRA型と呼ばれる効用関数を採用しています。

ここで、ASモデルで仮定していることを整理してみましょう。

  • 価格(仲値)の変動がブラウン運動に従う[2]
  • 仲値から深さ\deltaに飛んでくる成行注文の頻度は、売り、買いともにAe^{-\delta k}である。ここで、Aはパラメータ
  • 成行注文のサイズは一定である。
  • 仲値の変動と成行注文の到着は独立である。

が主な仮定かと思います。[3]

ASモデルでは、このような仮定のもとで、最もいい(最も効用が大きくなる)指値幅を求めています。逆に言うと、ASモデルの仮定が一つでも満たされていないと、ASモデルで得られる指値幅は最適ではなくなる可能性がある、ということです。

実際、仮想通貨市場ではこれらの仮定は全然満たされていないと考えられます。[4]
例えば、成行注文がベストより深いところに飛ぶ状況というのは複数の板が約定しているので、「仲値の変動と成行注文の到着は独立」というのはかなり無理があると思います。成行で食われた板のところに一瞬で板が出し直される、という状況であればある程度成り立つかもしれませんが。[5]
また、仲値がブラウン運動というのも実際のデータを確認すると当てはまっていないように見えます。

BTC/USDT:USDT mid price

(ちょっとテクニカルな話)
ASモデルのいいところは、最適指値幅を解析的に求めることができるという点です。最適指値の導出には動的計画法を用いてHJB方程式を得た上で、HJB方程式を解くというステップを踏みます。[6]こうして得られたHJB方程式は非線形微分差分方程式になるので、通常は解析解を持ちません。そこで、実際に戦略を実行しようとすると、マーケットのパラメータが変わるごとにHJB方程式を計算機で解かなければなりません。
ASモデルでは漸近展開を用いることで近似解を解析的に得ました。これにより、HJB方程式を毎回解く必要がなくなりました。また、解析解が得られたことにより、戦略の性質をより理解しやすくなりました。

ASの拡張

ASモデルの仮定が満たされていないのであれば、ASモデルを拡張することで、より仮定が現実に即したモデルを作ろう、という研究がいくつかあります。仮定が完璧に現実に即していれば、それは本当の最適指値です。
ここでは、そのような拡張のうち、ジャンプがあるときのASの拡張を紹介します。

さて、ASモデルの問題設定では仲値S_tはブラウン運動に従う、つまり、

dS_t=\sigma dW_t

を仮定していました。ここで、W_tは標準ブラウン運動、\sigmaはボラティリティです。
しかし、上の図であったように仲値はブラウン運動というよりむしろジャンプを含んだ過程に従うと考えられます。そこで、仲値の過程を

dS_t=\sigma dW_t + \epsilon^+ dM^+_t - \epsilon^- dM^-_t

と仮定してやります。ここで、M^+_t, M^-_tは強度\lambda^+, \lambda^-のポアソン過程であり、それぞれ買い/売りの成行注文の個数に相当します。ジャンプの大きさは確率的であるとします。\epsilon^+, \epsilon^-はそれぞれジャンプの大きさで、独立同一分布であり、その期待値は\eta^\pm=\mathbb{E}[\epsilon^\pm]とします。[7]
気持ちとしては、先程は考慮されたいなかった成行注文による仲値の変動をモデルに組み込んでやろう、というものです。こうすることで、MtMの期待値の評価にジャンプが組み込まれる分、最適指値に補正が入ります。
詳細な計算はAlgorithmic and High-Frequency Tradingを参照してください。
結論だけ言うと、

\begin{align*} \delta^a = \frac{1}{k} + \eta^+ - \frac{1}{k}\ln\frac{\omega(t, q-1)}{\omega(t, q)} \\ \delta^b = \frac{1}{k} + \eta^- - \frac{1}{k}\ln\frac{\omega(t, q+1)}{\omega(t, q)} \end{align*}

となります。[8]

ここで、ここで\bar{q},\underline{q}はそれぞれqの上限、下限とし\omega(t, q)

\begin{align*} \boldsymbol{\omega}(t)&=(\omega(t, \bar{q}), \omega(t, \bar{q}-1), \ldots, \omega(t, \underline{q}))^{\top}, \\ \boldsymbol{z} &= (1, 1, \ldots, 1)^{\top}, \\ \end{align*}

としたとき、

\begin{align} \boldsymbol{\omega}(t)&=e^{\mathbf{A}(T-t)} \mathbf{z}, \\ A_{i, q}&=\begin{cases} q k\left(\eta^{+} \lambda^{+}-\eta^{-} \lambda^{-}\right)-\frac{1}{2}\sigma^2\gamma k q^2, & i=q, \\ \lambda^{+}e^{-1-k\eta^+}, & i=q-1, \\ \lambda^{-}e^{-1-k\eta^-}, & i=q+1, \\ 0, & \text { otherwise } \end{cases} \end{align}

で表されます。

結構いかつい式が出てきますが、導出等はASモデルとだいたい一緒です。
\delta^{a,b}の右辺第二項目が、ジャンプの大きさによる補正項になっています。ジャンプの大きさの期待値分離すのがよい、ということになります。
また、在庫リスクへのジャンプの影響分も考える必要があります。それが右辺第三項目です。ただ、これはA_{i,i}\eta^{\pm}が入り込む形になっており、少し複雑です。今回は数値計算によって\eta^{\pm}の影響を確認したいと思います。

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")

[9]

結果は下の図のようになります。

薄い線のほうが\eta^{\pm}=0としたときで、これはASモデルの結果と対応します。濃い線のほうがジャンプの影響を織り込んだものになりますが、"在庫リスクへのジャンプの影響分"はほとんどなさそうです。
実際、ジャンプの大きさの期待値分だけシフトしたものとほとんど一致しているように見えます。
パラメータによってはもう少し効果がはっきり現れるかもしれません。

結果としては、ジャンプの大きさの期待値が分かれば、ジャンプがない場合の指値から期待値分だけ深く出すのが良さそうです。

まとめ

この記事ではASモデルの結果とジャンプがある場合の最適指値を考察しました。
ASモデルやその拡張は、仮定がかなり厳しいために、そのままでは実際には使えるケースは非常に少ないと思います。ただし、こういったモデルからヒントを得ることはできると思います。今回でいうと、ジャンプの影響を取り込むにはジャンプの大きさ分だけ指値を深く出すのが良さそうという考察が得られました。もちろん、ジャンプの大きさの期待値をどう推定するか等の問題は残りますが、この考察部分だけを取り出して戦略に組み込むことができるかもしれないし、また、経験的にうまくいっている戦略の解釈にも応用できるかもしれません。

脚注
  1. Ho and Stollあたりから考えられている問題です。 ↩︎

  2. デリバティブでは幾何ブラウン運動等を仮定することが多いですが、ASモデルのように高頻度取引で利用する確率制御モデルの場合、価格が負になる確率は無視できるので、ブラウン運動でモデル化することが多いです。 ↩︎

  3. 他にもあるかもしれません。取引にかかるfeeなど。ちなみにfee rateが一定の場合にはASモデルに組み込むことができるはずです。 ↩︎

  4. 他の市場では仮定がある程度満たされているかもしれません。関連の文献を見ていると債券市場であったり、相対の取引モデル等では有効なのかもしれません。 ↩︎

  5. 仲値の変動は1.ベストに置かれた指値注文のサイズ以上の成行注文の到着と2.スプレッド内への指値注文の到着、3.ベストに置かれた指値注文のキャンセル、によって決まるので1-3を確率過程としてモデル化する、とすればより正確になるのではないかと思います。ブラウン運動を仮定する、そういうのを全部ひっくるめてしまっているので無理が生じている部分があるはずです。そういう文献もあった気がします。 ↩︎

  6. ASモデルで考えているような問題を解く、という話であれば、もちろん他の解き方もあります。モンテカルロしたり、最大値原理を用いたり。 ↩︎

  7. 期待値が定義されるiidであれば何でもOKです。 ↩︎

  8. 実は明示していませんでしたが、効用関数の形がASモデルとは違うので、ちょっと形が変わっています。\gammaが小さいときに(1/\gamma)\ln(1+\gamma/k)\sim 1/kとできるので、Algorithmic and High-Frequency Tradingの(10.27a, b)の式はASモデルで\gammaを小さいとしたときに対応していると思ってもらえばわかりやすいかも。10.3に詳しいことが書いてあります。また、簡単のために\alpha=0としています。 ↩︎

  9. 間違っていたらすみません。 ↩︎

Discussion