05.1.12
Quantstats
qs.utils.download_returns("GOOG", period="2y") で Google の 2 年分の日次リターンを取り、qs.stats.sharpe で数値を 1 つ、qs.plots.snapshot で図を 1 枚、qs.reports.html(..., "VTI") で全米株式 ETF の VTI をベンチマークにしたレポートを出します。後半では yfinance で MSFT・AAPL・AMZN・GOOG・TSLA の株価を取り、pct_change() の変化率に比重 0.3 / 0.3 / 0.2 / 0.1 / 0.1 を np.dot で掛けてポートフォリオのリターン系列を作り、同じ qs.reports.html に渡します。読み終えると、「1 本のリターン系列を用意すればあとは QuantStats に任せる」という流れで任意の銘柄やポートフォリオの成績表が作れます。直感 #
ある銘柄やポートフォリオが「良かったか」を判断するには、リターンの大きさだけでなく、途中でどれだけ下落したか(最大ドローダウン)、揺れに対してどれだけ報われたか(シャープレシオ)、市場平均に勝っていたかを見る必要があります。これらを自分で計算して図にするのは数十行の作業ですが、QuantStats は「日ごとに何 % 増えたか」の 1 本の Series を渡すだけで全部を計算し、ベンチマークと並べた HTML を出力します。ポートフォリオも、各銘柄の日次変化率を比重で加重平均すれば 1 本の Series になるので、個別銘柄とまったく同じ手順でレポートが作れます。
| |
VTI と特定の銘柄の比較レポート #
GOOG の 2 年分のリターンを取り、シャープレシオ、スナップショット図、VTI との比較レポートの 3 つを順に出します。
| |

複数銘柄のパフォーマンス比較レポート #
MSFT・AAPL・AMZN・GOOG・TSLA を 0.3 / 0.3 / 0.2 / 0.1 / 0.1 の比重で保有したポートフォリオのリターンを、VTI と比較します。QuantStats に渡せるのは「日ごとの変化率」の系列なので、株価から pandas.DataFrame.pct_change で変化率を求め、比重で加重平均して 1 本の Series にします。
| |
| Adj Close | Close | ... | Open | Volume | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| AAPL | AMZN | GOOG | MSFT | TSLA | AAPL | AMZN | GOOG | MSFT | TSLA | ... | AAPL | AMZN | GOOG | MSFT | TSLA | AAPL | AMZN | GOOG | MSFT | TSLA | |
| Date | |||||||||||||||||||||
| 2020-12-31 | 131.333542 | 162.846497 | 87.594002 | 219.139343 | 235.223328 | 132.690002 | 162.846497 | 87.594002 | 222.419998 | 235.223328 | ... | 134.080002 | 163.750000 | 86.771004 | 221.699997 | 233.330002 | 99116600 | 59144000 | 20238000 | 20942100 | 148949700 |
| 2021-01-04 | 128.087051 | 159.331497 | 86.412003 | 214.479111 | 243.256668 | 129.410004 | 159.331497 | 86.412003 | 217.690002 | 243.256668 | ... | 133.520004 | 163.500000 | 87.876999 | 222.529999 | 239.820007 | 143301900 | 88228000 | 38038000 | 37130100 | 145914600 |
| 2021-01-05 | 129.670715 | 160.925507 | 87.045998 | 214.685989 | 245.036667 | 131.009995 | 160.925507 | 87.045998 | 217.899994 | 245.036667 | ... | 128.889999 | 158.300507 | 86.250000 | 217.259995 | 241.220001 | 97664900 | 53110000 | 22906000 | 23823000 | 96735600 |
| 2021-01-06 | 125.305786 | 156.919006 | 86.764503 | 209.119339 | 251.993332 | 126.599998 | 156.919006 | 86.764503 | 212.250000 | 251.993332 | ... | 127.720001 | 157.324005 | 85.131500 | 212.169998 | 252.830002 | 155088000 | 87896000 | 52042000 | 35930700 | 134100000 |
| 2021-01-07 | 129.581635 | 158.108002 | 89.362503 | 215.070267 | 272.013336 | 130.919998 | 158.108002 | 89.362503 | 218.289993 | 272.013336 | ... | 128.360001 | 157.850006 | 87.002998 | 214.039993 | 259.209991 | 109578200 | 70290000 | 45300000 | 27694500 | 154496700 |
5 rows × 30 columns
| |
| AAPL | AMZN | GOOG | MSFT | TSLA | |
|---|---|---|---|---|---|
| Date | |||||
| 2021-01-04 | -0.024719 | -0.021585 | -0.013494 | -0.021266 | 0.034152 |
| 2021-01-05 | 0.012364 | 0.010004 | 0.007337 | 0.000965 | 0.007317 |
| 2021-01-06 | -0.033662 | -0.024897 | -0.003234 | -0.025929 | 0.028390 |
| 2021-01-07 | 0.034123 | 0.007577 | 0.029943 | 0.028457 | 0.079447 |
| 2021-01-08 | 0.008631 | 0.006496 | 0.011168 | 0.006093 | 0.078403 |
5 rows × 5 columns
| |
[-0.01530147 0.00900607 -0.01796814 0.02928912 0.0152212 -0.02670266
0.00147395 0.01133958 -0.01243583 -0.00920841]
| |
Date
2021-01-04 -0.015301
2021-01-05 0.009006
2021-01-06 -0.017968
2021-01-07 0.029289
2021-01-08 0.015221
2021-01-11 -0.026703
2021-01-12 0.001474
2021-01-13 0.011340
2021-01-14 -0.012436
2021-01-15 -0.009208
dtype: float64
| |
使いどころと落とし穴 #
np.dot の加重平均は stock_dict のキーの順番と returns_df の列の順番が一致していることが前提で、yf.download は銘柄をアルファベット順に並べ替えることがあるので、returns_df[list(stock_dict.keys())] で列順を明示してから掛けるのが安全です。固定比重の加重平均は「毎日リバランスする」計算になるため、買い持ちの成績を正確に出したいときは株数を固定して評価額を追う必要があります。download_returns と yf.download はどちらも Yahoo Finance に依存しており、仕様変更で Adj Close 列が無くなることがあるので、エラーが出たら auto_adjust の既定値や列名を確認してください。
まとめ #
QuantStats の入力は「日次リターンの Series」1 本です。個別銘柄なら qs.utils.download_returns("GOOG", period="2y") で直接取れ、ポートフォリオなら yf.download の Adj Close を pct_change() して比重で np.dot すれば同じ形になります。あとは qs.stats.sharpe で数値、qs.plots.snapshot で図、qs.reports.html(returns, "VTI", download_filename=...) でベンチマーク比較の HTML が出るので、リターン系列を用意する部分だけに集中すれば任意の銘柄・配分の成績表が作れます。