COMPANY

PAGE TOP

BLOG

PythonができることをRapidMinerで実現してみようーー最適ポートフォリオの探索

皆さん、こんにちは、
周と申します。

前回のブログでは、ポートフォリオの収益率とリスクの計算方法についての紹介、
また可視化によって異なる重みでの日次収益率を比較しました。

ではどのような組み合わせが一番いいでしょうか?
収益を最大化するものでしょうか?それともリスクを最小化するものでしょうか?

私たちは重みを決める時、収益とリスクの二つの要素を総合的に評価する必要があります。

マーコウィッツ理論?

ノーベル経済学賞を受賞したアメリカの経済学者ハリー・マーコウィッツ氏が提案した(Markowitz)ポートフォリオ理論は、組み合わせの選択と資産配置に広く使われています。

この理論には収益の指標として期待収益率,
リスクの指標として収益率の分散を用いることから平均分散モデルと効率的なフロンティアにより、
最適な投資ポートフォリオを見つけます。
モデルに関する説明はこちらを参照してください。

シャープ・レシオ?

収益-ボラティリティの結果により、両者の間にバランスのよいポイントを見つけたいですね。シャープ・レシオはより良い意思決定する場合によく利用されています。

リスク(標準偏差)1単位当たりの超過リターン(リスクゼロでも得られるリターンを上回った超過収益)を測るもので、この数値が高いほどリスクを取ったことによって得られた超過リターンが高いこと(効率よく収益が得られたこと)を意味します。        
                        引用:SMBC日興証券

今回のブログはRapidMinerを用い、どのように実現するかと、
結果に対する考察について述べていきたいと思います。

まずはモンテカルロ方法でシミュレーションを行い、
要するにランダムに重みセットを生成し、
この組み合わせの収益率とボラティリティを計算します。
更にこのプロセスを数回(ここでは4999回にします)繰り返し、
各組み合わせの収益とボラティリティの散布図で表します。

データセット

前回のプロセスからできたポートフォリオ日次収益率共分散マトリックス
既定重み付けのポートフォリオデータセットを引き続き使います。

オペレーター

  • Execute Python 2個

  • Multiply

  • Filter Examples
      

    Execute Python 作成

    二つのExecute Pythonオペレーターを作ります。

  • Markowitz&SR
    以下ではマーコウィッツモデルのシミュレーションを行い、シャープ・レシオ(Sharpe Ratio)を算出するExecute Pythonのスクリプトになります。

import pandas as pd
import numpy as np

def rm_main(data,data1):
    # input : data == stock_r , data1 == cov_mat_annual
    # set times
    data = data.set_index("date")
    data1 = data1.set_index("Attributes")
    times = 4999
    # set empty-sets to store weight, return, vol for everytime
    random_p = np.empty((times, 7))
    # set random seeds
    np.random.seed(233)

    # random loop 4999 times for portfolio
    for i in range(times):
        # random 5 weight
        random5 = np.random.random(5)
        random_weights = random5/np.sum(random5)

        # average return annul data => stock_r
        return_mean = data.mul(random_weights, axis=1).sum(axis=1).mean()
        return_annul = (return_mean + 1)** 252 - 1

        # risk (volitality) annul cov_mat_annual=>data1
        vol_random = np.sqrt(np.dot(random_weights.T, np.dot(data1, random_weights)))

        # store weight, return, volitality in random_p
        random_p[i][:5] = random_weights
        random_p[i][5] = return_annul
        random_p[i][6] = vol_random

    # portfolio_random => data2
    codelist = data.columns.to_list()
    data2 = pd.DataFrame(random_p)
    data2.columns = [i + "weight" for i in codelist] + ["returns", "volatility"]

    # set risk free = 0
    risk_free = 0

    # calculate sharpe_ration
    data2["sharpe_ration"] = (data2.returns - risk_free)/data2.volatility

    return data, data2
  • return_minvol&maxSR
    可視化するために、全てを一つのデータセットにまとめましょう。
import pandas as pd
import numpy as np

def rm_main(data,data1,data2):
    """
    input:
      data:portfolio_return
      data1:min_vol
      data2:max_SR
    output:
      data:update portfolio_return
    """
    datar = data.iloc[:,:5]
    # get weight from each parton
    data1 = np.array(data1.iloc[:,:5])
    data2 = np.array(data2.iloc[:,:5])
    data["por_return_min_vol"] = datar.mul(data1, axis=1).sum(axis=1)
    data["por_return_max_sr"] = datar.mul(data2, axis=1).sum(axis=1)
    return data

プロセス

全体のプロセスは以下のようになります。
ここで注意すべきことは、データセットとExecute Pythonオペレーター(左側・右側のポート)に繋がる順番は、
スクリプトの引数や出力と一致していなければならないことです。

いよいよ実行してみましょう~

結果

  • マーコウィッツ理論から
    以下の図はシミュレーションによって全ての収益とボラティリティの状況を表しています。
    縦軸は収益率、横軸はボラティリティです。投資の本質はこの両者の間に意思決定することになるでしょう。
    一般的な場合は既定のボラティリティで期待収益を最大化し、または既定の収益でボラティリティを最小化します。

この図の緑の曲線は、効率的フロンティアと呼ばれ、

同じリターンではリスクが最小に、同じリスクではリターンが最大になるような組み合わせを結んだ線同じリターンではリスクが最小に、同じリスクではリターンが最大になるような組み合わせを結んだ線である。

この線には最も有利と考えられる選択肢の集合が集まっています。

では、私たちはどの点を選択すればいいでしょうか?
例えば、最小分散投資の場合では、オレンジの点が最小のボラティリティで、最も収益が高い組み合わせになります。

  • シャープ・レシオから
    RapidMinerのPlot欄、Colorに(sharpe_ration)シャープ・レシオを入れると、以下の図になります。
    色は赤いほど、シャープ・レシオが高く、これらの点が散布図の上側に集まっていますね。

シャープ・レシオが高い順でソートすると、ポートフォリオの収益やボラティリティなどが以下の表からすぐに確認できます。(上図の赤い点です)

最後に全ての組み合わせを一つの図にまとめると、

RapidMinerではPlot欄のValue columnsから簡単に選択することができます。
ぜひ活用してみてくださいね。

今回のブログは以上になります。
ここまで見てくれてありがとうございました。
また、ご意見・質問等ありましたら下記の連絡先までご連絡ください。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

もしRapidMinerに興味があるなら、是非今度のハンズオンに参加してみましょう!

https://ksk-anl.smktg.jp/public/application/add/43

1日で機械学習の基礎が学べる!無償ハンズオンセミナー随時開催中
https://www.ksk-anl.com/event/

RapidMinerをもっと知りたい方はこちら
https://www.rapidminer.jp/

早速使ってみたい!RapidMinerの体験版の無償DL
https://www.rapidminer.jp/download/

導入を検討中!わかりやすい詳細なQ&A
https://www.rapidminer.jp/faq/

$$ \begin{aligned} \newcommand\argmin{\mathop{\rm arg~min}\limits} \boldsymbol{\beta}_{\text{ridge}} & = \argmin_{\boldsymbol{\beta} \in \mathcal{R^p}} \biggl[ ||\boldsymbol{y}-\boldsymbol{X\beta}||^2 + \lambda ||\boldsymbol{\beta}||^2 \biggr] \\ & = (\boldsymbol{X}^T\boldsymbol{X} + \lambda\boldsymbol{I_{p+1}})^{-1}\boldsymbol{X}^T\boldsymbol{y} \end{aligned} $$
PAGE TOP