PyPortfolioOpt adalah perpustakaan yang mengimplementasikan metode optimasi portofolio, termasuk teknik optimasi mean-variance klasik dan alokasi Black-Litterman, serta perkembangan terkini di bidang ini seperti penyusutan dan Hierarchical Risk Parity.
Ini ekstensif namun mudah diperluas , dan dapat berguna baik bagi investor biasa, atau profesional yang mencari alat pembuatan prototipe yang mudah. Baik Anda investor berorientasi fundamental yang telah mengidentifikasi beberapa pilihan yang undervalued, atau trader algoritmik yang memiliki serangkaian strategi, PyPortfolioOpt dapat membantu Anda menggabungkan sumber alfa dengan cara yang hemat risiko.
PyPortfolioOpt telah diterbitkan di Jurnal Perangkat Lunak Sumber Terbuka?
PyPortfolioOpt sekarang dikelola oleh Tuan Tran.
Buka dokumentasi di ReadTheDocs untuk melihat proyek secara mendalam, atau lihat buku masak untuk melihat beberapa contoh yang menunjukkan proses lengkap mulai dari mengunduh data hingga membuat portofolio.
Jika Anda ingin bermain dengan PyPortfolioOpt secara interaktif di browser Anda, Anda dapat meluncurkan Binder di sini. Butuh beberapa saat untuk menyiapkannya, tetapi Anda dapat mencoba resep buku masak tanpa harus memenuhi semua persyaratannya.
Catatan: pengguna macOS perlu menginstal Command Line Tools.
Catatan: jika Anda menggunakan windows, Anda harus menginstal C++ terlebih dahulu. (unduh, instruksi pemasangan)
Proyek ini tersedia di PyPI, artinya Anda cukup:
pip install PyPortfolioOpt
(Anda mungkin perlu mengikuti petunjuk instalasi terpisah untuk cvxopt dan cvxpy).
Namun, praktik terbaiknya adalah menggunakan manajer ketergantungan dalam lingkungan virtual. Rekomendasi saya saat ini adalah menyiapkan diri Anda dengan puisi, lalu lari
poetry add PyPortfolioOpt
Jika tidak, klon/unduh proyek dan jalankan di direktori proyek:
python setup.py install
PyPortfolioOpt mendukung Docker. Bangun wadah pertama Anda dengan docker build -f docker/Dockerfile . -t pypfopt
. Anda dapat menggunakan gambar tersebut untuk menjalankan pengujian atau bahkan meluncurkan server Jupyter.
# iPython interpreter:
docker run -it pypfopt poetry run ipython
# Jupyter notebook server:
docker run -it -p 8888:8888 pypfopt poetry run jupyter notebook --allow-root --no-browser --ip 0.0.0.0
# click on http://127.0.0.1:8888/?token=xxx
# Pytest
docker run -t pypfopt poetry run pytest
# Bash
docker run -it pypfopt bash
Untuk informasi lebih lanjut, silakan baca panduan ini.
Jika Anda ingin membuat perubahan besar untuk mengintegrasikannya dengan sistem milik Anda, mungkin masuk akal untuk mengkloning repositori ini dan hanya menggunakan kode sumbernya.
git clone https://github.com/robertmartin8/PyPortfolioOpt
Alternatifnya, Anda dapat mencoba:
pip install -e git+https://github.com/robertmartin8/PyPortfolioOpt.git
Berikut adalah contoh data saham kehidupan nyata, yang menunjukkan betapa mudahnya menemukan portofolio jangka panjang yang memaksimalkan rasio Sharpe (ukuran pengembalian yang disesuaikan dengan risiko).
import pandas as pd
from pypfopt import EfficientFrontier
from pypfopt import risk_models
from pypfopt import expected_returns
# Read in price data
df = pd . read_csv ( "tests/resources/stock_prices.csv" , parse_dates = True , index_col = "date" )
# Calculate expected returns and sample covariance
mu = expected_returns . mean_historical_return ( df )
S = risk_models . sample_cov ( df )
# Optimize for maximal Sharpe ratio
ef = EfficientFrontier ( mu , S )
raw_weights = ef . max_sharpe ()
cleaned_weights = ef . clean_weights ()
ef . save_weights_to_file ( "weights.csv" ) # saves to file
print ( cleaned_weights )
ef . portfolio_performance ( verbose = True )
Ini menghasilkan bobot berikut:
{'GOOG': 0.03835,
'AAPL': 0.0689,
'FB': 0.20603,
'BABA': 0.07315,
'AMZN': 0.04033,
'GE': 0.0,
'AMD': 0.0,
'WMT': 0.0,
'BAC': 0.0,
'GM': 0.0,
'T': 0.0,
'UAA': 0.0,
'SHLD': 0.0,
'XOM': 0.0,
'RRC': 0.0,
'BBY': 0.01324,
'MA': 0.35349,
'PFE': 0.1957,
'JPM': 0.0,
'SBUX': 0.01082}
Expected annual return: 30.5%
Annual volatility: 22.2%
Sharpe Ratio: 1.28
Ini menarik tetapi tidak berguna. Namun, PyPortfolioOpt menyediakan metode yang memungkinkan Anda mengonversi bobot berkelanjutan di atas menjadi alokasi aktual yang dapat Anda beli. Cukup masukkan harga terbaru, dan ukuran portofolio yang diinginkan ($10.000 dalam contoh ini):
from pypfopt . discrete_allocation import DiscreteAllocation , get_latest_prices
latest_prices = get_latest_prices ( df )
da = DiscreteAllocation ( weights , latest_prices , total_portfolio_value = 10000 )
allocation , leftover = da . greedy_portfolio ()
print ( "Discrete allocation:" , allocation )
print ( "Funds remaining: ${:.2f}" . format ( leftover ))
12 out of 20 tickers were removed
Discrete allocation: {'GOOG': 1, 'AAPL': 4, 'FB': 12, 'BABA': 4, 'BBY': 2,
'MA': 20, 'PFE': 54, 'SBUX': 1}
Funds remaining: $ 11.89
Penafian: proyek ini tidak merupakan nasihat investasi, dan penulis tidak bertanggung jawab atas keputusan investasi Anda selanjutnya. Silakan merujuk ke lisensi untuk informasi lebih lanjut.
Makalah Harry Markowitz tahun 1952 adalah karya klasik yang tidak dapat disangkal, yang mengubah optimalisasi portofolio dari sebuah seni menjadi sebuah sains. Pemahaman utamanya adalah bahwa dengan menggabungkan aset-aset dengan tingkat pengembalian dan volatilitas yang berbeda-beda, seseorang dapat memutuskan alokasi optimal secara matematis yang meminimalkan risiko terhadap target pengembalian – kumpulan semua portofolio optimal tersebut disebut sebagai batas efisien (efisiensi frontier) .
Meskipun banyak perkembangan telah dilakukan dalam hal ini, lebih dari setengah abad kemudian, gagasan inti Markowitz masih penting secara fundamental dan digunakan sehari-hari di banyak perusahaan manajemen portofolio. Kelemahan utama dari optimasi mean-variance adalah bahwa perlakuan teoritis memerlukan pengetahuan tentang pengembalian yang diharapkan dan karakteristik risiko (kovarians) aset di masa depan. Tentu saja, jika kita mengetahui tingkat pengembalian yang diharapkan dari sebuah saham akan jauh lebih mudah, namun yang menjadi permasalahan adalah bahwa tingkat pengembalian saham sangat sulit untuk diperkirakan. Sebagai penggantinya, kami dapat memperoleh perkiraan pengembalian yang diharapkan dan kovarians berdasarkan data historis – meskipun kami kehilangan jaminan teoritis yang diberikan oleh Markowitz, semakin dekat perkiraan kami dengan nilai sebenarnya, semakin baik portofolio kami.
Oleh karena itu, proyek ini menyediakan empat rangkaian fungsi utama (walaupun tentu saja keduanya terkait erat)
Sasaran desain utama PyPortfolioOpt adalah modularitas – pengguna harus dapat menukar komponen mereka sambil tetap menggunakan kerangka kerja yang disediakan PyPortfolioOpt.
Di bagian ini, kami merinci beberapa fungsi PyPortfolioOpt yang tersedia. Contoh lainnya ditawarkan di notebook Jupyter di sini. Sumber daya bagus lainnya adalah tes.
Versi yang jauh lebih komprehensif dapat ditemukan di ReadTheDocs, serta kemungkinan ekstensi untuk pengguna tingkat lanjut.
Matriks kovarians tidak hanya mengkodekan volatilitas suatu aset, namun juga korelasinya dengan aset lain. Hal ini penting karena untuk memperoleh manfaat dari diversifikasi (dan dengan demikian meningkatkan pengembalian per unit risiko), aset dalam portofolio harus sebisa mungkin tidak berkorelasi.
sklearn.covariance
.constant_variance
, single_factor
, dan constant_correlation
.sklearn.covariance
(Plot ini dibuat menggunakan plotting.plot_covariance
)
ef = EfficientFrontier ( mu , S , weight_bounds = ( - 1 , 1 ))
efficient_risk
dan efficient_return
, PyPortfolioOpt memberikan opsi untuk membentuk portofolio netral pasar (yaitu jumlah bobot menjadi nol). Hal ini tidak mungkin dilakukan untuk portofolio max Sharpe dan portofolio volatilitas minimum karena dalam kasus tersebut keduanya tidak invarian sehubungan dengan leverage. Netralitas pasar memerlukan bobot negatif: ef = EfficientFrontier ( mu , S , weight_bounds = ( - 1 , 1 ))
ef . efficient_return ( target_return = 0.2 , market_neutral = True )
ef = EfficientFrontier ( mu , S , weight_bounds = ( 0 , 0.1 ))
Salah satu masalah dengan optimasi mean-variance adalah hal ini menyebabkan banyak bobot nol. Meskipun hal ini termasuk dalam sampel yang "optimal", terdapat banyak penelitian yang menunjukkan bahwa karakteristik ini menyebabkan portofolio mean-variance berkinerja buruk di luar sampel. Untuk itu, saya telah memperkenalkan fungsi tujuan yang dapat mengurangi jumlah bobot yang dapat diabaikan untuk salah satu fungsi tujuan. Pada dasarnya, ini menambahkan penalti (diparameterkan dengan gamma
) pada bobot kecil, dengan istilah yang mirip dengan regularisasi L2 dalam pembelajaran mesin. Mungkin perlu mencoba beberapa nilai gamma
untuk mencapai jumlah bobot yang tidak dapat diabaikan. Untuk portofolio uji 20 sekuritas, gamma ~ 1
sudah cukup
ef = EfficientFrontier ( mu , S )
ef . add_objective ( objective_functions . L2_reg , gamma = 1 )
ef . max_sharpe ()
Mulai v0.5.0, kami sekarang mendukung alokasi aset Black-Litterman, yang memungkinkan Anda menggabungkan perkiraan keuntungan sebelumnya (misalnya keuntungan tersirat pasar) dengan pandangan Anda sendiri untuk membentuk perkiraan posterior. Hal ini menghasilkan perkiraan keuntungan yang diharapkan jauh lebih baik daripada hanya menggunakan rata-rata keuntungan historis. Lihat dokumen untuk diskusi teori, serta saran dalam memformat masukan.
S = risk_models . sample_cov ( df )
viewdict = { "AAPL" : 0.20 , "BBY" : - 0.30 , "BAC" : 0 , "SBUX" : - 0.2 , "T" : 0.131321 }
bl = BlackLittermanModel ( S , pi = "equal" , absolute_views = viewdict , omega = "default" )
rets = bl . bl_returns ()
ef = EfficientFrontier ( rets , S )
ef . max_sharpe ()
Fitur-fitur di atas sebagian besar berkaitan dengan penyelesaian masalah optimasi mean-variance melalui pemrograman kuadrat (meskipun hal ini ditangani oleh cvxpy
). Namun, kami juga menawarkan pengoptimal yang berbeda:
Silakan merujuk ke dokumentasi untuk informasi lebih lanjut.
Tes ditulis dalam pytest (menurut saya jauh lebih intuitif daripada unittest
dan variannya), dan saya telah mencoba memastikan cakupan mendekati 100%. Jalankan pengujian dengan menavigasi ke direktori paket dan menjalankan pytest
pada baris perintah.
PyPortfolioOpt menyediakan kumpulan data pengujian pengembalian harian untuk 20 ticker:
[ 'GOOG' , 'AAPL' , 'FB' , 'BABA' , 'AMZN' , 'GE' , 'AMD' , 'WMT' , 'BAC' , 'GM' ,
'T' , 'UAA' , 'SHLD' , 'XOM' , 'RRC' , 'BBY' , 'MA' , 'PFE' , 'JPM' , 'SBUX' ]
Ticker ini telah dipilih secara informal untuk memenuhi beberapa kriteria:
Saat ini, pengujian belum mengeksplorasi semua kasus edge dan kombinasi fungsi tujuan dan parameter. Namun, setiap metode dan parameter telah diuji agar berfungsi sebagaimana mestinya.
Jika Anda menggunakan PyPortfolioOpt untuk karya yang diterbitkan, harap kutip makalah JOSS.
Rangkaian kutipan:
Martin, R. A., (2021). PyPortfolioOpt: portfolio optimization in Python. Journal of Open Source Software, 6(61), 3066, https://doi.org/10.21105/joss.03066
BibTex::
@article { Martin2021 ,
doi = { 10.21105/joss.03066 } ,
url = { https://doi.org/10.21105/joss.03066 } ,
year = { 2021 } ,
publisher = { The Open Journal } ,
volume = { 6 } ,
number = { 61 } ,
pages = { 3066 } ,
author = { Robert Andrew Martin } ,
title = { PyPortfolioOpt: portfolio optimization in Python } ,
journal = { Journal of Open Source Software }
}
Kontribusi dipersilahkan . Lihat Panduan Kontribusi untuk informasi lebih lanjut.
Saya ingin mengucapkan terima kasih kepada semua orang yang telah berkontribusi pada PyPortfolioOpt sejak dirilis pada tahun 2018. Ucapan khusus kepada: