量子コンピュータ
金融
量子アニーリング
アービトラージ

【為替】量子アニーリングで為替アービトラージ計算の実装


はじめに

HFTなどの高頻度取引は小さな利ざやを高速で取引し、裁定取引を探して決済をします。楽しそうな映画や本があります。

ミリ秒単位の高頻度株取引の世界に殴り込んだ2人のいとこの奮闘を描く「ザ・ハミングバード・プロジェクト」

https://gigazine.net/news/20190121-the-hummingbird-project-trailer/

フラッシュ・ボーイズ 10億分の1秒の男たち

https://www.bousaid.com/entry/2018/01/19/080709

今回は為替取引での裁定取引の利益を算出するアルゴリズムをD-Waveのようなイジングモデルで行ってみます。基本的には為替取引はネットワークグラフ問題なので、そこで利益の出るループを探すという最適化を行なっていきます。

実際の計算時間はHFTで活用できるレベルには到底及びませんが、参考になるので将来的な活用や他分野での活用に役立ててみてください。


参考

参考はカナダの1qbitの論文をもとにします。

Finding optimal arbitrage opportunities using a quantum annealer

http://1qbit.com/wp-content/uploads/2016/10/1QBit-White-Paper-%E2%80%93-Finding-Optimal-Arbitrage-Opportunities-Using-a-Quantum-Annealer.pdf


為替の裁定取引とは?

裁定取引(さいていとりひき、英: Arbitrage)とは、金利差や価格差を利用して売買し利鞘(りざや)を稼ぐ取引のこと。サヤ取り(鞘取り)ともいう。

https://ja.wikipedia.org/wiki/%E8%A3%81%E5%AE%9A%E5%8F%96%E5%BC%95

ということで、為替計算をしているうちに自然と価格差が生まれる場所があれば、その価格差を利用して利益が取れるような取引です。いち早く他人よりもその価格差を発見できれば、常に利益がとれるということでそのような価格差を見つけましょう。

通常の計算ではループを見つけるたびに逐一処理をしますが、量子コンピュータでは逐一処理がもともとアルゴリズムとしてついてますので、マルコフネットワークという無向グラフを解くことでこの裁定機会を発見することを目指します。


モデル

モデルは下記を使います。円は各通貨。線は通貨同士の取引金額を表します。この中で利益の出るループを見つけるのが目的です。

1.jpg


解法

解法には二種類ありますが、今回は片方を使ってみます。解き方はノードを中心に考える方法とエッジを中心に考える方法とがあります。ノードは点、エッジは線の条件です。

57b5db4f0112944783ae5f6f1f52d070.png

http://1qbit.com/wp-content/uploads/2016/10/1QBit-White-Paper-%E2%80%93-Finding-Optimal-Arbitrage-Opportunities-Using-a-Quantum-Annealer.pdf

条件式はすみませんが、論文から借ります。エッジベースで考えてみます。コスト関数が1つと制約条件式が2つあります。

一番上は利益を最大にするコスト関数。係数にはlogがついてます。

二番目はループを作る条件。

三番目は同じノードを二回通ってはいけないという条件です。


小さなモデルで確認してみる

まずは3ノードの小さなモデルでループができるか確認してみると、

2.jpg

制約条件は二種類。まずはループを作る。Aについてはq1+q5=q0+q4のようにしていきます。これをBとCについても。次にループを作るには、Aに入る数が0か1にします。BとC同様で、式は、

E1 = (q1+q5-q0-q4)^2 + (q0+q2-q1-q3)^2 + (q4+q3-q2-q5)^2

E2 = (q1+q5)*(q1+q5-1)+(q0+q2)*(q0+q2-1)+(q3+q4)*(q3+q4-1)

やってみたところ、

from blueqat import opt

from blueqat.opt import Opt

result = Opt().add("(q1+q5-q0-q4)^2 + (q0+q2-q1-q3)^2 + (q4+q3-q2-q5)^2").add("(q1+q5)*(q1+q5-1)+(q0+q2)*(q0+q2-1)+(q3+q4)*(q3+q4-1)").run(shots=100)

opt.counter(result)

#=>
Counter({'011010': 11,
'100101': 20,
'001100': 16,
'110000': 13,
'000011': 18,
'000000': 22})

このようにループがきちんとできました。すごい。。。

あとはコスト関数を載せる

コスト関数を載せるとこの選択肢の中でもっともループのコストの高いものを選ぶようになります。今回は部分的にコストを最初のモデルから載せてみます。

import numpy as np

from blueqat import opt
from blueqat.opt import Opt

result = Opt().add("(q1+q5-q0-q4)^2 + (q0+q2-q1-q3)^2 + (q4+q3-q2-q5)^2").add("(q1+q5)*(q1+q5-1)+(q0+q2)*(q0+q2-1)+(q3+q4)*(q3+q4-1)").add(-0.05*np.diag([0.00961,104.05,0.14864,6.72585,0.06463,15.47])).run(shots=100)

opt.counter(result)

#=>
Counter({'110000': 58, '011010': 42})

ここで、11000もしくは011010を選ぶループが選ばれました。あとはエネルギーを調べることでループの最大値がわかります。

このようにループを拡大することで利益を算出することができます。logを取るはずでしたが、今回はシミュレータだったのでそのままできました。

ぜひ興味ある人は全体をやってみてください。