@yuichirominato 2018.07.02更新 66views

D-Waveで金融ポートフォリオ最適化問題のウェブアプリを作ってみた

D-Wave QUBO イジング 量子アニーリング 金融

はじめに

量子コンピュータもだいぶ世間に浸透してきて、気軽にアプリケーションを作れるようになってきました(値段すごい高いけど)。今回は以前D-Waveマシンで実装した金融ポートフォリオ最適化問題に関してウェブのインターフェイスと統合して、動かせる量子コンピュータアプリを作って見ました。

ポートフォリオ最適化問題

過去のデータから資産運用に関して、ある銘柄のリターン(報酬)の期待値と、銘柄同士連動していることを想定しての相関係数からリスクを割り出し、一定のリスクを盛り込んだポートフォリオの銘柄の組合せ方法を量子コンピュータで計算をします。

実際に解いて見た記事は下記から

「D-Waveで金融ポートフォリオ最適化問題を解く」
https://blog.mdrft.com/post/1176

今回はインターフェイスを使って、保有銘柄数とリスクの見込みを変更してD-WaveにAPI経由で投げるなど実際に使えるものを作って見ます。

その他のアプリ

自動車関連は交通最適化に関してアプリを作ったことがあります。そちらはこちらを参考にしてください。GoogleMap APIを繋いで混雑状況を解消するアルゴリズムをVW社の論文を参考に作りました。

「D-waveの量子コンピュータとGoogle Maps APIで実際に使える交通最適化ウェブアプリ(羽田空港から新国立競技場の道路混雑緩和)を作ってみた」
https://blog.mdrft.com/post/183

参考資料

こちらを参考にしました。

Solving the Optimal Trading
Trajectory Problem
Using a Quantum Annealer

https://1qbit.com/wp-content/uploads/2016/05/1QBit-Research-Paper-%E2%80%93-Solving-the-Optimal-Trading-Trajectory-Problem-Using-a-Quantum-Annealer.pdf

今回はQUBOというものを使ってハミルトニアンと呼ばれるエネルギー関数を作って計算をします。

今回使用したD-Waveマシンとは?

カナダのベンチャー企業で、量子アニーリングと言われる量子効果を活用したアルゴリズムをハードウェア実装したマシンです。

企業情報:
本社所在地:カナダブリティッシュコロンビア州バーナビー
設立:1999年
事業内容:量子コンピュータのハードウェアとソフトウェアを商用製品として提供
従業員数:160名(Ph.D 55名)

引用元:https://www.dwavesys.com/resources/media-resources

引用元:https://www.dwavesys.com/resources/media-resources

詳細はカナダのホームページを参照してくださいませ。
https://www.dwavesys.com/

日本語サイトもあります
http://dwavejapan.com/

今回構築する手順

今回は保有銘柄数とリスクの程度を指定するポートフォリオ最適化問題を解きます。金融モデルの最適化問題の中でももっとも優しいものなので入門にちょうどいいと思います。

ハミルトニアンと呼ばれる一般式は、こちらです。最初の項がリターン、2項目がリスク(こちらはリスクをどれくらい見込むかは自分で決めます)。最終項は保有銘柄数Kの制約条件です。H=ー∑μixi+γ∑δijxixj+B(∑xi−K)2H=ー∑μixi+γ∑δijxixj+B(∑xi−K)2

今回は、6銘柄17量子ビットを使って、リスクと銘柄数を指定するアプリにして見ます。最初に前処理でインターフェイスを作り、そのあとAPIを通じてカナダのマシンをクラウド経由で操作し、答えを取り出します。サーバーサイドのスクリプトも必要で、バイナリ値の操作なども必要なので、サーバーサイドスクリプトなども工夫が必要です。

例題

6銘柄を考えます。なんと都合のいいことに、ポートフォリオ最適化問題はリターンやリスクの計算を全て過去のデータから前処理で行ってしまうので、イジングマシン特有のめんどい作業がほぼいりません。

データ類は今回はダミーで実装します。用意する(論理)量子ビットは6。

xi={x0,x1,x2,x3,x4,x5}xi={x0,x1,x2,x3,x4,x5}

期待値のリターンを銘柄ごとにそろえます。今回はダミーデータを使います。
μi={0.026,0.031,0.007,0.022,0.010,0.055}μi={0.026,0.031,0.007,0.022,0.010,0.055}

続いて銘柄間の相関を表す分散共分散を用意します。
δijδijに相当します。今回これもダミーデータを使います。x0x1x2x3x4x5x00x10.00150×20.00120.00170×30.00180.00220.00400×40.00220.00050.00320.00120×50.00120.00190.00240.00760.00210x0x1x2x3x4x5x000.00150.00120.00180.00220.0012×100.00170.00220.00050.0019×200.00400.00320.0024×300.00120.0076×400.0021×50

めんどいので、1つの行列でまとめておきます。x0x1x2x3x4x5x0−0.026×10.0015−0.031×20.00120.0017−0.007×30.00180.00220.0040−0.022×40.00220.00050.00320.0012−0.010×50.00120.00190.00240.00760.0021−0.055x0x1x2x3x4x5x0−0.0260.00150.00120.00180.00220.0012×1−0.0310.00170.00220.00050.0019×2−0.0070.00400.00320.0024×3−0.0220.00120.0076×4−0.0100.0021×5−0.055

今回想定ているD-Waveでの量子ビットの対応は下記の通りです。6量子ビットの完全結合を表現するために17量子ビットほど使用しています。

リターンやリスクのmatrixは自由に変更可能ですが、今回は固定でやります。変えたい人は自由に変えて見てください。

早速データを用意する

まずは上記のmatrixを準備します。mat.js

var mat =[
[-0.026, 0.0015, 0.0012, 0.0018, 0.0022, 0.0012],
[0     , -0.031, 0.0017, 0.0022, 0.0005, 0.0019],
[0     ,      0, -0.007, 0.0040, 0.0032, 0.0024],
[0     ,      0,      0, -0.022, 0.0012, 0.0076],
[0     ,      0,      0,      0, -0.010, 0.0021],
[0     ,      0,      0,      0,      0, -0.055]
]

次にリスクを見込む量をγγとしますが、こちらをとりあえず0.5として、処理をして見ます。
さらに対角項のリターンは10倍、非対角項は100倍してバランスを取って見ます(やっていいのかわかりませんが、D-Waveはこのままでは数値が小さすぎて入れられないので)。mat2.js

var G = 1;
var N = mat.length;

for(var i=0;i<N;i++){
 for(var j=i+1;j<N;j++){
  mat[i][j] = Number((G*100*mat[i][j]).toFixed(4))
 }
 mat[i][i] = Number((10*mat[i][i]).toFixed(4));
}
0:(6) [-0.26, 0.15, 0.12, 0.18, 0.22, 0.12]
1:(6) [0, -0.31, 0.17, 0.22, 0.05, 0.19]
2:(6) [0, 0, -0.07, 0.4, 0.32, 0.24]
3:(6) [0, 0, 0, -0.22, 0.12, 0.76]
4:(6) [0, 0, 0, 0, -0.1, 0.21]
5:(6) [0, 0, 0, 0, 0, -0.55]

こんな感じでQUBOmatrixが得られました。続いて制約条件です。求め方は下記の記事を参考にしてください。

「D-Waveで金融ポートフォリオ最適化問題を解く」
https://blog.mdrft.com/post/1176

求めるQUBOはK2+(1−2K)x0+(1−2K)x1+(1−2K)x2+(1−2K)x3+(1−2K)x4+(1−2K)x5+2x0x1+2x0x2+2x0x3+2x0x4+2x0x5+2x1x2+2x1x3+2x1x4+2x1x5+2x2x3+2x2x4+2x2x5+2x3x4+2x3x5+2x4x5K2+(1−2K)x0+(1−2K)x1+(1−2K)x2+(1−2K)x3+(1−2K)x4+(1−2K)x5+2x0x1+2x0x2+2x0x3+2x0x4+2x0x5+2x1x2+2x1x3+2x1x4+2x1x5+2x2x3+2x2x4+2x2x5+2x3x4+2x3x5+2x4x5

QUBOmatrixにして、x0x1x2x3x4x5x0(1−2K)Bx12B(1−2K)Bx22B2B(1−2K)Bx32B2B2B(1−2K)Bx42B2B2B2B(1−2K)Bx52B2B2B2B2B(1−2K)Bx0x1x2x3x4x5x0(1−2K)B2B2B2B2B2Bx1(1−2K)B2B2B2B2Bx2(1−2K)B2B2B2Bx3(1−2K)B2B2Bx4(1−2K)B2Bx5(1−2K)B

こちらは、Bの値を少し大きめにとって先ほどのmatrixに代入します。こちらもBはあとで前処理で変更できるように変数にして見ます。mat3.js

var B = 0.5

var cc = [
[-5,  2,  2,  2,  2,  2],
[ 0, -5,  2,  2,  2,  2],
[ 0,  0, -5,  2,  2,  2],
[ 0,  0,  0, -5,  2,  2],
[ 0,  0,  0,  0, -5,  2],
[ 0,  0,  0,  0,  0, -5]
];

for(var i=0;i<N;i++){
 for(var j=i+1;j<N;j++){
  mat[i][j] += B*cc[i][j];
 }
}
0:(6) [-0.26, 1.15, 1.12, 1.18, 1.22, 1.12]
1:(6) [0, -0.31, 1.17, 1.22, 1.05, 1.19]
2:(6) [0, 0, -0.07, 1.4, 1.32, 1.24]
3:(6) [0, 0, 0, -0.22, 1.12, 1.76]
4:(6) [0, 0, 0, 0, -0.1, 1.21]
5:(6) [0, 0, 0, 0, 0, -0.55]

よさそうです。処理は係数を経由して進めていますので、あとで変更が可能です。

インターフェイスでは銘柄数を指定するバーとリスクを見込むバーを用意し、計算を投げるボタンをつけます。また、リターンやリスクのmatrixとそれに対応する銘柄がわかるようにしました。

次にmatrixを反映して見ます。

スライダーが変更されると自動反映されるようにテーブルにclassもしくはidを割り当て、change.js

$('#range_risk').on('change',function(event){
 $('#risk').html($('#range_risk').val());
 G = $('#range_risk').val()/5;

 var mat = new Array(N);
 for(var i=0;i<N;i++){
  mat[i] = mat_init[i].concat();
 }

 for(var i=0;i<N;i++){
  for(var j=i+1;j<N;j++){
   mat[i][j] = Number((G*100*mat[i][j]).toFixed(4))
  }
  mat[i][i] = Number((10*mat[i][i]).toFixed(4));
 }

 for(var i=0;i<N;i++){
  for(var j=i+1;j<N;j++){
   mat[i][j] += Number((B*cc[i][j]).toFixed(4));
  }
 }

 for(var i=0;i<N;i++){
  for(var j=i;j<N;j++){
   $('#sub .'+i+'_'+j).html(mat[i][j].toFixed(3));
  }
 }

});

例えばリスクの折り込みの数値によってQUBOが変化します。

また、最終的に銘柄が選択されると色がつくようになります。

今回読み込んだライブラリはjqueryとaws-sdk、そしてデザインを司るbootstrapです。

サーバーサイド処理について

今回もサーバーサイドはサーバーレスを使用しています。
この処理のためにサーバーを立ち上げるのが大変なので、nodejsやpythonのlambdaで実行しています。

https://aws.amazon.com/jp/serverless/

バイナリ値の処理や各種tokenなどの処理が必要です。D-Wave社のAPIの仕様書にのっとって実行していますが、残念ながら現在ではAPI仕様書などはD-Wave契約者以外はみることができませんでした。

QUBOをD-Waveに送り結果を取得する

なんとなくなれてなくて戻ってきた結果の調子がよくわからないので、図示して見ました。戻ってきた配列から特定の量子ビットだけ抜き出して表示します。また、なんとなく計算時間も入れた方がかっこいい気がしたので入れて見ました。実機での計算時間が表示されます。

やってみました。まだ何もしてない状態から、、、


再計算を押すと計算が送られ戻ります。


無事3銘柄選ばれました!次に銘柄数を変更して見ます。4に。

どうやらどうしてもDEFは選ばれるみたい、、、無事4銘柄で計算できました。パラメータ調整などは必要ですが、一旦銘柄数を変更して、都度D-Waveにリクエストとレスポンスを処理するアプリが無事できました。

おつかれさまでした。

あわせて読みたい

SERVICE

汎用量子コンピュータ向けアプリケーション開発SDK

詳しく見る Githubで入手する(無料)

汎用量子コンピュータ向け高速シミュレータ

詳しく見る

量子コンピュータ向けクラウドサービス(準備中)

詳しく見る

イジングマシン向けアプリケーション開発SDK

詳しく見る Githubで入手する(無料)

COMMUNITY

量子コンピュータのことを学びたい、仕事としたいなどの情報交換の場を設け、コミュニティの形成を進めています。オフラインの勉強会と、オンラインのチャットコミュニティの2種類あります。オフラインのConnpassは1400名、オンラインのSlackは880名を超える参加があります。どちらも無料ですのでお気軽にご参加ください。

CONNPASS SLACK

CONTACT

弊社あての連絡はinfo@mdrft.comより用件を明記の上、メールで連絡を頂けますと幸いです。

ブログトップへ Wikiへ移動

量子コンピュータ一般

量子ゲートアルゴリズム

量子アニーリング一般

量子アニーリングアルゴリズム

BlueqatSDKの使い方