Fixstars Amplify SDKを使って日経225銘柄でポートフォリオ最適化をやってみた

#はじめに
[量子コンピューティング by NRI Advent Calendar 2021](https://qiita.com/advent-calendar/2021/nri_quantum)、22日になります。今まで業界の動向や数式や図たくさんで難しい話だったかと思います。
この記事では、難しい数式は出さず、やってみたことを書いてみたいと思います。
今回、Fixstars社から提供されているイジングマシン（量子アニーリングマシンを含む）向けライブラリであるFixstars Amplify SDK、Fixstar Amplifyのオンラインデモを大部分参考にさせて頂き、日本の株式でのポートフォリオ最適化をやってました。

#本記事で書くこと
* Fixstars Amplify SDKについて
* 日本株でのポートフォリオ最適化

#Fixstars Amplify SDK について
Fixstars Amplify SDKとは、株式会社フィックスターズが開発、提供しているイジングマシン向けミドルウェアライブラリです。 イジングマシンを用いるアプリケーションとハードウェアの中間層として、 イジングマシンの利便性の向上とアプリケーションソフトウェアの高効率な開発が可能となる様々な機能が提供されています。[公式ドキュメント](https://amplify.fixstars.com/ja/docs/about.html "About Amplify SDK")。

Fixstars Amplify SDKでは、機能提供だけでなく、技術リソースの提供も多数用意されており量子コンピュータの勉強にも大変有益な情報が提供されています。あれやこれや書物をつまみ食いするのではなく１つ決めてしっかり読み込むのもいいかもしれません。（＾ω＾）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262031/ffaa0f49-55f3-ef4f-0438-cfbf6ae3c2e2.png)
(https://amplify.fixstars.com/ja/techresources/ より引用)

オンラインデモも多数用意されており、SDKの使い方の参考になります。サンプルコードを選択すると、Jupyter Notebookが起動し、問題の説明、定式化、実装について詳しく説明されています。一から順にすべてやってみるのはオススメです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262031/048c5111-b577-36be-047d-a5d08b8e205a.png)
(https://amplify.fixstars.com/ja/demo より引用)

その他、詳細情報について知りたい方は[公式ホームページ](https://amplify.fixstars.com/ja/ "公式ホームページ")や[ドキュメント](https://amplify.fixstars.com/ja/docs/index.html "ドキュメント")をご覧ください。

# Fixstars Amplify SDKを用いた、日本株のポートフォリオ最適化
## ポートフォリオ最適化デモについて
Fixstar Amplify SDKのオンラインデモ [ポートフォリオ最適化](https://amplify.fixstars.com/ja/demo?demo_id=13) では、米国株およそ100銘柄の数十日分の値動きを元に期待収益率の最大化とリスクの最小化の例が示されております。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262031/449b969d-11ea-d3d1-18be-5bdb7fb916c7.png)
(https://amplify.fixstars.com/ja/demo?demo_id=13 より引用)

オンラインデモでの数式やコードを順々にやっていき、最後にイジングマシンのソルバーにモデルを放り込むと、ポートフォリオの最適化の答えが返ってきます!!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262031/4b8c8d98-02f8-2a5b-d2d7-4368f9346843.png)
（　＾ω＾）・・・

米国株にあまり馴染みが無いのでピンと来ないですね。。。

( ﾟдﾟ)ハッ！、だったら、日本の株式でやってみようというのがこの記事の目的です。


##実行手順について
用意したデータでポートフォリオ最適化を行うには、オンラインデモ上ではなく、ローカル環境にてSDK実行環境を用意する必要があります。


今回Windows環境での実行でしたので、WSLをインストールして、規定のUbuntuにデフォルトで入っているpython3での環境構築を行いました。


```powershell
wsl --install
```
実行後、再起動およびユーザ名とパスワードの登録を求められるので、適当に設定。

　
必要なパッケージをインストールします。

```bash
sudo apt update
sudo apt upgrade
sudo apt install python3-pip
sudo apt install jupyter-notebook
pip install amplify #自動でnumpyも入る
pip install pandas
pip install matplotlib
```
環境によっては、```/etc/resolv.conf```に誤ったDNSが登録されていたり、```apt```のproxy設定を入れたりする必要があります。

また、WSLはCドライブに置かれてしまい、少々邪魔なのでDドライブに移動させるのもいいかもしれません。

オンラインデモのjupyter notebookをダウンロードして、Windowsで適当なディレクトリに配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262031/8e019888-2e4d-7afa-a085-c234d857a133.png)

WSLではCドライブやDドライブは ```/mnt/```配下にマウントされているので、さきほど置いたnotebookを確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262031/e921d4f2-d36c-bb0d-0ce0-81101a1a3a9a.png)

notebookが置かれているディレクトリでjupyter notebookを起動すれば、ディレクトリ設定をしなくてもjupyter上から確認することができます。

```bash
jupyter notebook
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262031/15144449-aeb7-eaf3-bac0-d5effa2ff07f.png)

あとは、後述するデータ取得とディレクトリ情報の書き換え、Amplify AEトークンをAmplifyのサイトから取得し、トークン情報を書けば、動かすことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262031/46652e90-d62c-bf02-6b59-8738ef60445a.png)



###参考にさせて頂いたサイト
- [WSL のインストール](https://docs.microsoft.com/ja-jp/windows/wsl/install)
- [Proxy環境下で「apt update」ができないときのメモ](https://qiita.com/48saaan/items/47f8d9cd3321c3bcfce6)
- [WSL上のLinuxをCドライブから移動させる](https://www.aise.ics.saitama-u.ac.jp/~gotoh/HowToReplaceWSL.html)
- [Windowsで環境を極力汚さずにPythonを動かす方法 (WSL利用 Windows10, version 1607以降限定)](https://qiita.com/rhene/items/ff11c7850a9a7617c50f)
- [初心者向け Jupyter Notebookでパスワードかトークンを求められたときの対処法](https://qiita.com/XTJP/items/29981dc25d80f7fed871)





## データの準備について
東証一部全部は多いので、日経225の銘柄に絞り、2021/1/1~2021/12/17のデータ（225銘柄、235日）を今回集めてみました。

```
 pip install pandas-datareader
 pip install yahoo_finance_api2
 pip install yfinance
```

さっと調べたところ、大体、この３つが日本株のデータ集めに使われているようでした。（他にも多数ありますが、今回は省略）

ツールのサイトでの注意書きや、Yahooo!ファイナンスヘルプにあるようにスクレイピングは禁止されていたりと、ツールの使用やデータの取り扱いには注意が必要です。

取得したい銘柄のコードをCSVファイルで作成して、```pandas```で読み込んでいます。

```python
import pandas as pd
shares225 = pd.read_csv("./share_code_jp.csv", encoding="ms932", sep=",", header=0)
print(shares225)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262031/71a56db0-c486-5159-cde1-2ed627189c31.png)


下記のどちらかの方法で、証券コードごとに株価情報取得し、証券コードをファイル名としたCSVファイルとして保存します。

```python:yahoo_finance_api2の例
from yahoo_finance_api2 import share
from yahoo_finance_api2.exceptions import YahooFinanceError

for code in shares225["code"]:
    my_share = share.Share(str(code) + ".T")
    symbol_data = None

    try:
        symbol_data = my_share.get_historical(share.PERIOD_TYPE_DAY,60,share.FREQUENCY_TYPE_DAY,1)
        df = pd.DataFrame(symbol_data.values(), index=symbol_data.keys()).T
        df.timestamp = pd.to_datetime(df.timestamp, unit='ms')
        df.index = pd.DatetimeIndex(df.timestamp, name='timestamp').tz_localize('UTC').tz_convert('Asia/Tokyo')
        df.to_csv("<dir>"+ str(code) + ".csv", index=False)
    except YahooFinanceError as e:
        print(e.message)
```
※おそらくですが、```yahoo_finance_api2```では直近２ヶ月分程度しか取れないような気がします。
　


```python:yfinanceの例
import yfinance as yf
from pandas_datareader import data as pdr
import yfinance as yf
yf.pdr_override()

for code in shares225["code"]:
    share_code = str(code) + ".T"
    df = pdr.get_data_yahoo(share_code, start="2021-01-01", end="2021-12-17")
    df.to_csv("<dir>"+ str(code) + ".csv")

```
　


次に、```<dir>``` ディレクトリ配下のデータを読み込むようにコード修正を行います。今回、自分は```data```ディレクトリを作成し、ファイルを保存していますので、そのディレクトリを指定します。


```python
# <dir>以下のデータの読み込み
asset, names = read_csv_data_yahoo(root="<dir>")
num_brand, num_date = asset.shape

# ヒストリカルデータ方式による期待収益率とリスク分散の計算
expected_rate_of_return, variance_rate_of_return = histrical_data_method(asset, D)
```




## マシンの実行について

データを集めた後は、オンラインデモと同じように実行していきます。ポートフォリオを最適化するコードはAmplifyデモをご確認頂ければと思います。
銘柄数、日数どちらもオンラインデモより多く、時間内に返ってくるか気になりましたが、、、
　
結果は、無事返ってきました!!(ﾟ∀ﾟ) （目的関数と制約条件を足し合わせたQUBOモデルの中身を出力した際には、jupyter notebookがout of memoryで表示されなくなるぐらい式は長いです。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262031/4daa7c12-80ad-6e34-b19b-c4b51bc575b5.png)
（　＾ω＾）・・・

（　＾ω＾）b ｸﾞｯ！


（　＾ω＾） （銘柄名を出すのはやめておこう）



ポートフォリオで採用された各銘柄の約一年の値動きをグラフにするとこのような感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2262031/a7409f5e-6500-d8d9-fb5d-b2e32fe63466.png)

```python:pandas-datareaderの株価取得例および株価のグラフ化の例
import pandas_datareader.data as web
import matplotlib.pyplot as plt
SYMBOLS = ["2914.T", "5214.T", "9434.T", "9020.T", "2802.T", "5232.T", "5201.T", "3382.T", "4689.T"]
df = web.DataReader(SYMBOLS, data_source='yahoo', start='2021-01-01')
df["Close"].plot(figsize=(20,10))
```

（　＾ω＾）・・・

（　＾ω＾）（多分、銘柄間の相関低くく、利益を上げられる組み合わせなのだろう・・・若干関連している銘柄があるな・・・）

#最後に
デモと同じようにポートフォリオ最適化を日本の株式で試みてみました。気になる箇所にはコードを追加し、内部データや処理の理解を深めることができました。
次は、別の問題を見つけて、目的関数から自分で設計して、Amplify SDKで試してみたいです。

今回、日本株のポートフォリオの最適化を行いましたが、開発目的での利用のみであり、実際の投資には使用しておりません。皆様もライセンスや許可には十分注意して参考にしてください。m(__)m


https://amplify.fixstars.com/ja/termsofuse
https://pypi.org/project/yfinance/
https://support.yahoo-net.jp/PccFinance/s/article/H000011276