1. ホーム
  2. スクリプト・コラム
  3. パイソン

pyfinanceパッケージによるPython株式所得分析

2022-02-01 08:35:42

pyfinanceの紹介

datasets.py : 金融データのダウンロード(リクエストベースのデータクローラー、エクストラネットの制限によりダウンロードできなくなったデータもあります)。

general.py : アクティブシェア計算、リターン分布近似、トラッキングエラー最適化などの一般的な金融計算を行います。

ols.py: 回帰分析、pandasのローリングウィンドウ回帰をサポートします。

options.py: オプションデリバティブの計算と戦略分析。

returns.py: CAPMフレームワークによる金融時系列の統計分析。FactSet Research SystemsやZephyrなどのソフトウェアの機能を模倣し、スピードと柔軟性を向上させた設計になっています。

utils.py: インフラストラクチャ。

この記事では、株式投資分析におけるpyfinanceを紹介するreturnsモジュールを中心に、datasets、options、olsなどのモジュールについて紹介します。

リターンズモジュールの応用例

pyfinanceは比較的簡単にインストールでき、cmd(またはanacondaプロンプト)で "pip install pyfinance" と入力するだけです。 returnsは主にpandasと同等のTSeriesクラス(dataframeは未サポート)をベースとしています。 pandasのSeriesクラスを拡張してより高機能化し、証券投資分析におけるCAMP(資本資産価格モデル)フレームワークに基づいたパフォーマンス評価指標の算出をサポートするものと同義となります。returnsモジュールを参照する場合は、"from pyfinance import TSeries"を直接使用すればOKです。

データインタフェースとしてtushareを使用し、yieldデータをTSeriesに変換するデータフェッチ関数を定義し、TSeriesクラスの関数を直接使用します。

import pandas as pd  
import numpy as np
from pyfinance import TSeries
import tushare as ts
def get_data(code,start='2011-01-01',end=''):
    df=ts.get_k_data(code,start,end)
    df.index=pd.to_datetime(df.date)
    ret=df.close/df.close.shift(1)-1
    # return TSeries sequence
    return TSeries(ret.dropna())

# Get the Ping An of China data
tss=get_data('601318')
#tss.head()


歩留まり計算

pyfinanceのリターンは、年率リターン(anlzd_ret)、累積リターン(cuml_ret)、定期リターン(rollup)等を提供しています。ここでは、Ping An Bank株を例にして、イールドメトリクスを計算してみます。

#annualized return
anl_ret=tss.anlzd_ret()
#Cumulative return
cum_ret=tss.cuml_ret()
#Calculate the periodic rate of return
q_ret=tss.rollup('Q')
a_ret=tss.rollup('A')

print(f'Annualized return: {anl_ret*100:.2f}%')
print(f'Cumulative return: {cum_ret*100:.2f}%')
#print(f'Quarterly return: {q_ret.tail().round(4)}')
#print(f'Calendar year return: {a_ret.round(4)}')


出力結果です。

累積収益率:205.79パーセント

年率換算のリターン 12.24%

#Visualize quarterly (annual) returns
from pyecharts import Bar
attr=q_ret.index.strftime('%Y%m')
v1=(q_ret*100).round(2).values
bar=Bar('Ping An of China quarterly return %') bar.add('',attr,v1,)
bar


from pyecharts import Bar
attr=a_ret.index.strftime('%Y')
v1=(a_ret*100).round(2).values
bar=Bar('Ping An of China calendar year return %')
bar.add('',attr,v1,is_label_show=True,
       is_splitline_show=False)
bar


CAPMモデル関連指標

CAPMモデルのα、β、回帰決定係数R2、t統計量、残差項を基に計算します。実際にはols回帰が主に使われているので、これらの動的なアルファ値やベータ値を得るには、さらにolsモジュールのローリング回帰関数(PandasRollingOLS)に頼りますが、その応用は次のツイートで説明します。

#Based on the CSI 300 index
#To ensure the length of both is the same, the index of Ping An of China is used as the benchmark
benchmark=get_data('hs300')
benchmark=benchmark.loc[tss.index]

alpha,beta,rsq=tss.alpha(benchmark),tss.beta(benchmark),tss.rsq(benchmark)
tstat_a,tstat_b=tss.tstat_alpha(benchmark),ttss.tstat_beta(benchmark)
print(f'alpha:{alpha:.4f},tstat: {tstat_a:.2f}')
print(f'beta :{beta:.4f}, t-statistic: {tstat_b:.2f}')
print(f'regression coefficient of determination R2: {tss.rsq(benchmark):.3f}')


alpha:0.0004, t-statistic:1.55。
ベータ値:1.0634、t統計量:60.09
回帰決定係数 R2: 0.606

リスク指標

リスク指標としては、主に標準偏差と最大リトレースメントがあります。標準偏差を計算する場合、pyfinanceのインストールパッケージがあるパスを開くか、Anacondaのインストールの場合、以下のパスに開いて、デフォルトのパラメータを変更する必要があることに注意してください。

c:\Anaconda3Libsite-packagespyfinance, open the returns source file, find anlzd_stdev and semi_stdev functions, and change the freq default None to 250 (the number of trading days in a year).

#annualized standard deviation
a_std=tss.anlzd_stdev()
#downstream standard deviation
s_std=tss.semi_stdev()
#max retracement
md=tss.max_drawdown()
print(f'Annualized standard deviation: {a_std*100:.2f}%')
print(f'downward bias standard deviation: {s_std*100:.2f}%')
print(f'Maximum retracement deviation: {md*100:.2f}%')

年率換算した標準偏差 31.37%
バイアス標準偏差を下げる。0.43%
最大リトレースメント偏差:-45.76%。

低スキューの標準偏差は、主にリターン分布の非対称性に対応するためのものです。リターン関数の分布が左スキューの場合、正規分布を用いるとリスクが過小評価されるため、推定にフルサンプルの標準偏差を用いた従来のシャープ比分母はあまり適切ではなく、リスクフリー投資リターンとの偏差を用いるべきとされています。

ベンチマーク比較指標

ベンチマーク比較指標は、中国平安社の個別銘柄を比較分析するためのベンチマークとして、CSI300指数などを指定するために必要です。

bat=tss.batting_avg(benchmark)
uc=tss.up_capture(benchmark)
dc=tss.down_capture(benchmark)
tc=uc/dc
pct_neg=tss.pct_negative()
pct_pos=tss.pct_positive()
print(f'Percentage of time above benchmark return: {bat*100:.2f}%')
print(f'Ratio of upward periods to benchmark returns: {uc*100:.2f}%')
print(f'Downside to benchmark return ratio: {dc*100:.2f}%')
print(f'Upside to Downside Ratio: {tc*100:.2f}%')
print(f'Individual stock downside (negative earnings) time ratio: {pct_neg*100:.2f}%')
print(f'Time share of individual stocks on the upside (positive returns): {pct_pos*100:.2f}%')

ベンチマークより高いリターンを得た時間の割合。47.83%
ベンチマークリターンに対する上昇期間の比率 111.70%
対ベンチマーク騰落率ダウンサイド期間:105.32%。
アップサイド期間とダウンサイド期間の比率。106.06%
個別銘柄のダウンサイド(マイナスリターン)期間比率:48.94%。
個別銘柄のアップサイド(プラスリターン)タイムシェア。50.00%

また、インフォメーション・レシオとトレイナー・インデックスは、特にファンド商品やポートフォリオのパフォーマンスを定量的に評価する際によく使われるベンチマーク比較評価指標である。

情報比率は、マーコウィッツの平均分散モデルに基づき、超過リスクによる超過リターンを測定し、アクティブリスク1単位あたりの超過リターンを表す。 ir = α ∕ ω(αはポートフォリオの超過リターン、ωはアクティブリスク)、分子αは真の期待リターンと価格モデルで計算したリターンの差、分子は残差項の標準偏差である残差リスクとする。

単位リスクあたりの超過リターンを示すトレイナー・レシオは、TR=(Rp-Rf)/βpで計算され、TRはトレイナー・パフォーマンス指数、Rpはポートフォリオの平均リターン、Rfは平均リスクフリーレート、βpはポートフォリオのシステマティックリスクです。

ir=tss.info_ratio(benchmark)
tr=tss.treynor_ratio(benchmark)
print(f'info ratio: {ir:.3f}')
print(f'Treynor index: {tr:.3f}')

情報量比率:0.433
トレイナー指数 0.096

リスク調整後リターン指標

リスク調整後リターン指標としては、シャープレシオ、ソルティーノレシオ、カルマルレシオがよく使われるが、いずれもリスク調整後リターン比率なので、分子はリターン指標、分母はリスク指標となる。

  • シャープレシオ。リスク調整後リターン。= [E(Rp)-Rf]/σp で計算。E(Rp):ポートフォリオの期待ペイオフ、Rf:リスクフリーレート、σp:ポートフォリオの標準偏差。リスクの総量が1単位になるごとに、ポートフォリオがどれだけの超過利潤を生むかを計算する。
  • ソルティーノ比(Sortino Ratio):シャープ比と同じ考え、コアは分母にあるダウンサイドボラティリティ(ダウンサイドリスク)の概念を適用し、標準偏差を計算するときに、平均を使用していませんが、設定した最小許容リターン(r_min)、戻り値のシリーズは、この最小リターンを超えるリターンの距離は0に従って計算されます、これ以下 この収量以下のリターンの2乗距離が標準偏差が半減となるように累積されています。これに対応して、ソルティーノレシオの分子も、ストラテジーリターンのうち、最小リターンを超える部分を使用する。シャープ比と比較して、ソルティーノ比は(左)テールの予想損失の分析をより重視し、シャープ比は全サンプルについて分析する。
  • カルマー比(Calmar Ratio) :リターンと最大リトレースメントの関係を表し、年率リターンと過去の最大リトレースメントの比率として計算されます。カルマー比の値が大きいほど、ポートフォリオのパフォーマンスは良好です。
sr=tss.sharpe_ratio()
sor=tss.sortino_ratio(freq=250)
cr=tss.calmar_ratio()
print(f'Sharpe ratio: {sr:.2f}')
print(f'Sortino ratio: {sor:.2f}')
print(f'Karma ratio: {cr:.2f}')

シャープレシオ:0.33
ソルティーノレシオ:28.35
カルマ率:0.27

統合性能評価指標の分析例

以下は、上記の一般的に使用される指標を合成し、比較分析のために複数の個別銘柄にアクセスできるようにしたものです。

def performance(code,start='2011-01-01',end=''):
    tss=get_data(code,start,end)
    benchmark=get_data('hs300',start,end).loc[tss.index]
    dd={}
    #Returns
    #annualized rate of return
    dd['annualized_yield']=tss.anlzd_ret()
    #Cumulative yield
    dd['cumulative_ret']=tss.cuml_ret()
    #alpha and beta
    dd['alpha']=tss.alpha(benchmark)
    dd['beta']=tss.beta(benchmark)
    #risk metrics
    #annualized standard deviation
    dd['annualized standard deviation']=tss.anlzd_stdev()
    #Downside standard deviation
    dd['downside standard deviation']=tss.semi_stdev()
    #Maximum retracement
    dd['max_drawdown']=tss.max_drawdown()
    #Information ratio and Traynor index
    dd['info_ratio']=tss.info_ratio(benchmark)
    dd['Treynor index']=tss.treynor_ratio(benchmark)
    #Risk-adjusted return
    dd['Sharpe ratio']=tss.sharpe_ratio()
    dd['sortino_ratio']=tss.sortino_ratio(freq=250)
    dd['calmar ratio']=tss.calmar_ratio()
    df=pd.DataFrame(dd.values(),index=dd.keys()).round(4)
    return df


複数銘柄のデータを取得し(ポートフォリオも構築)、比較することで性能評価指標を把握する。

#Get data for multiple stocks

df=pd.DataFrame(index=performance('601318').index)
stocks={'Ping An of China':'601318','Guizhou Maotai':'600519',\
        'Haitian Flavor':'603288','Gree Electric':'000651',\
        'Vanke A':'00002','BYD':'002594',\
        'Yunnan Baiyao':'000538','Shuanghui Development':'000895',\
        'Haier Zhijia':'600690','Tsingtao Beer':'600600'}
for name,code in stocks.items():
    try:
        df[name]=performance(code).values
    except:
        continue

d


まとめ

pyfinanceは、主にポートフォリオ投資管理およびパフォーマンス評価指標のために設計されたpythonパッケージで、CFAやFRMを受験する読者にとってかなり有用なものです。実際、pyfinanceのreturnsモジュールは、pandasのSeriesクラスを拡張し、ポートフォリオのリターン分析とパフォーマンス評価をサポートしています。この記事では、pyfinanceの"glue"言語について紹介します。この記事では、pyfinanceのreturnsモジュールの使い方に焦点を当て、他のモジュールについては以降のツイートで取り上げる予定です。

技術的な話

転載、ブックマーク、応援よろしくお願いします。

Pythonのpyfinanceパッケージを使って証券収益分析を行うという記事は以上です。Pythonのpyfinanceパッケージの詳細については、過去の記事を検索するか、以下の記事を引き続き閲覧してください。