デリバティブ偏愛家の日記

マーケットメイク戦略の基本をモンテカルロシミュレーションする

どうも。最近、APIを使ったマーケットメイクを考えているのですが、そもそもバイサイド的な発想の方がメインだったので、基本的なところを確認したいと思い、簡単なシミュレーションをしてみました。使用したPythonのコードも末尾に載せています。

マーケットメイクとは

主に取引所において、Bid/Askにそれぞれ常にオーダーを出し続ける戦略です。通常、投資家が成行で買い注文すると、Ask側の価格で約定し、即その場で売るとBid側価格で約定するので、Bid/Askのスプレッド分はコストとなりますが、マーケットメイカー(以下、MM)は、逆にBid/Askのスプレッドが収益となります。

反面、MMは買いポジションを持たされた後に相場が下落する場合等に損失となる可能性があるので、ポジション管理や、そもそもどの水準にオーダーを出すのか(Mid)、スプレッドをどう設定するのか等を考える必要があります。

雑な分類ですが、市場の流動性と別の似た市場(ヘッジ市場)の有無を鑑みて、以下の4種類の市場があると考えられます。

1.流動性:高 / ヘッジ市場:有

株価指数連動ETF等がこれに該当するかな、と思います。ヘッジ市場は先物を想定していますが、スプレッドは先物とETFでそんなに差があるか微妙ですね…

2.流動性:高 / ヘッジ市場:無

東証一部の個別株や最近だとBTCのような仮想通貨が近いかと。別にかなり似た動きする上に流動性が高い市場が存在しないので、抱えたポジションのリスクをヘッジする方法が無い状態です。ただ、流動性は高いのでポジションが解消される可能性は高いので在庫管理はまだ楽。

3.流動性:低 / ヘッジ市場:有

マイナーなETFや、主要市場以外に上場している微妙な先物等の市場です。収益額こそ微妙ですが、きちんとヘッジ市場が存在するので、ひたすらフルヘッジをしていれば薄利が出せます。勿論既にHFTの主戦場になっていますが…

4.流動性:低 / ヘッジ市場:無

新興市場株やマイナーなアルトコインの市場です。一番マーケットメイクが難しいところでしょう。

今回は2の「流動性:高 / ヘッジ市場:無」をメインに分析していこうと思います。

前提条件

いつになく長いです。面倒な方は飛ばしても良いですが、結局ここの前提を踏まえた理解をしないと大変なことになる可能性があります。

基本的には自分が市場で唯一のMMで、対象資産の価格をウィーナー過程で動かしつつ、ある確率分布に従って発注される投資家からの成行注文を受けながら、全くヘッジはせずにマリー(買い注文と売り注文の相殺)だけをして、最終的な損益がどうなるかを分析していきます。

市場

自分がMMで、それ以外にオーダーを出している参加者はいない、つまり店頭FXと同じ状態。投資家は成行でランダムに注文してくる。

対象資産

初期時点で価格100、ボラティリティは年率6%(これは後で動かします)のUSDJPYっぽい何か。

価格変動

唯一のMMなら自分で価格動かせるじゃん、という話ですが、あくまで価格はウィーナー過程に従うとします。というのも、流石に唯一のMMという仮定はあまりに非現実的ですが、他に参加者がいても後述する提示スプレッドと約定確率に関しては特に変化が無いので、「唯一のMM」というよりは「他はいるけど考えない」が正しいです。

時間設定

1秒刻みで1,000回価格が変動(全体で約16分)。この1秒単位で下の約定判定も行う。

約定確率

こういった分析をする場合の出来高の確率分布が、本来どうあるべきなのか分からなかったのでオリジナル。一旦0を中心とした正規分布をプロットした後、0未満はマイナス数量の約定はあり得ないので全て0(約定無し)の扱いに。あまりに頻繁に約定するのはMMとしては理想的だけれど現実的ではないので、平均はマイナスにずらすことで出来高0の発生確率を高めてみました。

上図は平均-1、標準偏差2の場合の出来高の確率分布。約78%の確率で約定せず、約22%で何枚か約定する、という感じ。約定は1枚単位で、小数部分は無いです。

これは重要なポイントですが、今回のシミュレーションではスプレッドと約定確率には一切相関が無い状態になっています。両者の相関に関しては、こういった仮想の資産でシミュレーションするのではなく、実際の約定データ等から分析していく分野になると思うので外しました。

売買サイド判定

一旦今回は0~1までの数をランダムで生成し、ある閾値を超えたら投資家の売り注文(MM目線だとロングポジション発生)、未満だった場合は投資家の買い注文(MM目線でショートポジション発生)という簡素な仕組みに。つまり市場の動きと無相関。何と理想的な…ここは今後少し掘り下げたいですね。

ただ、ウィーナー過程のドリフト項を弄った上に売買判定閾値を0.5から変えると、「トレンドが発生して、かつトレンドフォロー系のオーダーがどんどん来る」という悲劇的な展開を再現することが出来ます。上記の出来高判定と合わせることで、ある時点で約定する数量とサイドが決まります。

MM側オーダー水準

ウィーナー過程に従って動く対象資産のMidに対して、上下対称にスプレッドを乗せてBid/Askとします。どちらかに寄せるのはMMの常套手段ですが、今回はスルーします。

MM側オーダー数量

先にポジションリミットを決めておき、ロング、ショートいずれでもそれを超えないようにオーダー数量を決めます。なのでリミットが10枚で、現状4枚ロングの場合、Bid買いオーダーは6枚、Ask売りオーダーは14枚になります。

最終時点まで経過した後は

若干雑ですが、最後の時点で持っていたポジションはその時点の自分の出しているオーダー水準に成行でぶつけて全解消します。具体的には最後の時点(500勝時間単位目)でロング4枚、Mid 120円、スプレッド片側0.005円の場合、119.995円で4枚売るという取引をします。「自分以外にMMにいるじゃねえか」って?まあその通りなんですが最終時点の評価損益を実現に変えたいんですよね。

長くなりました。既に9割くらいの読者の方が脱落されていると思いますが…これらの処理を各種パラメータを少しづつ変えながら10,000回繰り返し、実現損益の平均値と、ボラティリティを集計することで、各種パラメータの影響を分析していきます。

パラメータ整理

上述の前提を踏まえて、パラメータとその初期値を以下に決めました。

  • ドリフト項:0%(年率)
  • スポットボラティリティ:6%(年率)
  • 出来高確率分布平均値:-1
  • 出来高確率分布標準偏差:2
  • スプレッド(片側):0.005円(Bid/Askで1銭に)
  • ポジションリミット:10
  • Buy/Sell閾値:0.5(0.5以上でMM目線の買い→つまり確率は半々)

「USDJPYスプレッド1銭ってどこの外為オ○ラインだよ」というヤジが来そうですが、あまりに薄利だと誤差なんだか何だか分からなくなるので、多少利が乗る水準にしました。パラメータの数に関しては、正直もう少し絞れたかなと思いますが、オプション分析と同じく、一気に色々とパラメータを動かすとカオスになるので、基本的にはこの初期値を基準として一つずつ動かして変化を見ます。

シミュレーション結果

結果を見ていきます。

各時間区分において投資家の成行注文が約定する訳ですが、その確定損益の平均値(最後の成行決済含む)を「平均PL」、その標準偏差を「PL標準偏差」、前者を後者で割った値を「シャープレシオ」とします。

以下のグラフは全て平均PL、標準偏差が左軸、シャープレシオは右軸です。

スポットボラティリティ変化

スポットのボラを4%~20%まで上下させた結果です。PLの平均値はほぼ不動ですが、標準偏差は一貫して上昇するのでシャープレシオは低下傾向。

スプレッド変化

「業界最小水準スプレッド」付近からネット銀行の為替両替手数料くらいまで幅を持たせました。分かり易く収益が改善していきます。

スポットボラティリティとスプレッド変化の関係

上の2つのパラメータの相互の関係を見るため、ひたすらシミュレーションしまくって3次元にしました。

手前がボラティリティ、奥行きがスプレッド、縦軸はシャープレシオです。綺麗な曲面になっており、基本系のボラ6%、スプレッド0.005で数値微分したところ、

  • ボラティリティ:-0.78
  • スプレッド:-0.88

とまあ似たような水準ながらも、スプレッド変化のインパクトの方が僅かに大きいようです(あくまで基本の水準において)。ただ、一応全データで数値微分したものの、元のデータがあくまで乱数生成で計算されたものなので、誤差の影響で「どの水準でもスプレッド変化の影響がボラティリティ変化の影響より大きい」と断言することは出来ませんでした。

出来高確率分布の標準偏差変化

出来高確率分布の標準偏差を上下させました(平均は不変)。当たり前ですが標準偏差が大きくなると約定する確率が増えるので、相殺できる確率が上昇(平均保有時間が縮小)し、標準偏差が低下します。そのおかげでシャープレシオは改善してきますが、ある程度で伸びが鈍化するようです。

また、そもそも出来高確率分布を色々弄った結果、最終的に各時間区分において平均何枚の注文が来るのか計算したものが以下です。

基本形で使っている標準偏差2だと平均して0.26枚程度は約定しているようですが、3.5まで上昇すると0.78枚程、つまりそこそこな確率で1枚は約定していることになり、相殺される確率がかなり高くなっていることから、シャープレシオの伸びの鈍化の原因となっているようです。

ポジションリミット変化

ポジションリミットを1~100まである程度間隔を空けて計算しました。どうやらシャープレシオ的には5枚辺りが最善のようですが、これは約定確率に依存するので、出来高確率分布の標準偏差を以下で調整していきます。

上図は出来高確率分布の標準偏差を2.5に上げた場合です。一応5枚辺りが最適解になっていますが、若干山が右に寄った印象。

さらに3.5まで上げました。最適解が10枚付近まで上昇しています。

標準偏差毎に並べたグラフです(リミット50枚以降はほぼ差が無いので割愛)。標準偏差が上がるとシャープレシオの頂点も右に寄っていきます。

さて、次に最終合計損益の平均値をプロットしました。今まではあくまでシャープレシオが最大となるポジションリミットの話であって、最終合計損益ベースの話ではリミットは20枚程まで増やすのが最適となるようです。

Buy/Sell閾値変化

売買判定の閾値を上げていった結果です。最大でAskが叩かれる(MMが売りとなる)確率は75%。売りを持たされてもスポットが上昇する確率は50%なので、あくまで平均PLはほぼ不変。逆に標準偏差は上昇していくのでシャープレシオは低下していきます。

トレンドの発生(ドリフト項の変化)

次にトレンドを発生させました。年率3000%上昇するトレンドって凄まじ過ぎるだろ、と思いますが、シミュレーションする15分程度に換算すると8銭程度の上昇です。普段はそれが継続しないから大変なことにはなりません。

注文偏り同様、PLに変化は無いものの標準偏差が大きくなるので、シャープレシオは低下。

注文偏りがある場合にトレンド発生(ドリフト項の変化)

少し現実的になってきました。今度は先程の売買判定に使うBuy/Sell閾値を0.75にした上で、同様に上昇トレンドも加えます。MM目線で売りポジションを持つ確率が高くなる上に上昇トレンドする悲劇的な局面で、如実にPLが悪化します。

上と同じシナリオで、ポジションリミットを50まで拡大しました。自明ですが売りポジションを大量に抱える可能性が高まるので、シャープレシオのマイナス化が早くなります。

逆にリミットを5まで縮小したケース。注文偏り+トレンド相場でも多少は耐えているようです。

上記リミット3種類を%やシャープレシオではなく合計損益額で比較したもの。ロットが大きいタイミングでの負けが影響して、リミット50における損益分岐点は実際にはかなり左寄りになっています。

パラメータ比較と総括

一応パラメータの比較として、基本形からシャープレシオを2に上げるために必要な各パラメータの変化を調べました(初期時点のシャープレシオ=1.689)。

  • スポットボラティリティ:6%→5%
  • スプレッド:0.005→0.0061
  • 出来高確率分布標準偏差:2→3(平均約定枚数ベースで0.258枚→0.582枚)

相対的に、出来高確率分布標準偏差でシャープレシオを改善させるのが難しい印象ですね(平均約定枚数ベースで約2倍近く増える必要があるので)。

今回のシミュレーションでは前述のようにスプレッドと出来高が独立していましたが、現実の市場ではスプレッドを広げると約定確率は下がるので、上記のようにスプレッドを拡大するだけで簡単にシャープレシオが改善することはありません。

実際にMM戦略を考えていく場合には、これらの基本的な分析を踏まえて、出来高の確率分布から約定確率を計算し、証拠金やリスク許容度といった様々な要素からポジションリミットを決定する必要があります(単純にシャープレシオだけでは決められない)。また、今回は常にポジションに応じてオーダー数量を決めていましたが、相場のトレンドや直近の注文偏りに応じて数量を調整する必要がありますし、スプレッドの広さはボラティリティに比例させたり、ポジションの偏りに連動したり、他の板に乗っている注文を参照したり、またはMidをずらす等色々検討すべきことがあります。この辺りはMM戦略を考える醍醐味ですね…とは言えその領域まで行くと、実際の市場のデータが必要となり、ここでやったような簡単なモンテカルロシミュレーションでは対応できないので、今回はこの辺りが限界かな、という感じがしました。

Pythonコード

何だか無駄の多いコードですが…

Tagged on: ,

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です