來(lái)源:https://pypi.org/project/pyportfolioopt/
PyPortfolioOpt是一個(gè)實(shí)現(xiàn)投資組合優(yōu)化方法的庫(kù),其中包括經(jīng)典的均值方差優(yōu)化技術(shù)和Black-Litterman資產(chǎn)配置模型落包,以及該領(lǐng)域的最新進(jìn)展部蛇,例如收縮率shrinkage和層次風(fēng)險(xiǎn)平價(jià)模型Hierarchical Risk Parity,以及一些新穎的實(shí)驗(yàn)功能咐蝇,例如指數(shù)加權(quán)協(xié)方差矩陣涯鲁。
它既廣泛又易于擴(kuò)展,對(duì)于臨時(shí)投資者和認(rèn)真的從業(yè)者都可能有用有序。無(wú)論您是發(fā)現(xiàn)了一些被低估的精選期權(quán)的基礎(chǔ)知識(shí)型投資者抹腿,還是擁有一籃子策略的算法交易者,PyPortfolioOpt都可以幫助您以風(fēng)險(xiǎn)有效的方式構(gòu)建自己的Alpha組合旭寿。
安裝
pip安裝
pip install PyPortfolioOpt
源碼安裝
git clone https://github.com/robertmartin8/PyPortfolioOpt
python setup.py install
例子
這是一個(gè)關(guān)于現(xiàn)實(shí)中的股票數(shù)據(jù)的示例警绩,通過(guò)最大化夏普比率(衡量風(fēng)險(xiǎn)調(diào)整后回報(bào))構(gòu)建多頭投資組合。
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樣本協(xié)方差
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)
輸出結(jié)果:
{'GOOG': 0.01269,
'AAPL': 0.09202,
'FB': 0.19856,
'BABA': 0.09642,
'AMZN': 0.07158,
'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.06129,
'MA': 0.24562,
'PFE': 0.18413,
'JPM': 0.0,
'SBUX': 0.03769}
Expected annual return: 33.0%
Annual volatility: 21.7%
Sharpe Ratio: 1.43
這里最大夏普對(duì)應(yīng)的點(diǎn)實(shí)際上就是無(wú)風(fēng)險(xiǎn)收益點(diǎn)與有效前沿的切線的切點(diǎn)位置:
同時(shí)盅称,我們也可以將上面的權(quán)重配比兌換為實(shí)際的購(gòu)買金額:
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.lp_portfolio()
print("Discrete allocation:", allocation)
print("Funds remaining: ${:.2f}".format(leftover))
11 out of 20 tickers were removed
Discrete allocation: {'GOOG': 0, 'AAPL': 5, 'FB': 11, 'BABA': 5, 'AMZN': 1,
'BBY': 7, 'MA': 14, 'PFE': 50, 'SBUX': 5}
Funds remaining: $8.42
*免責(zé)聲明:關(guān)于該項(xiàng)目的任何內(nèi)容均不構(gòu)成投資建議肩祥,作者對(duì)您的后續(xù)投資決定不承擔(dān)任何責(zé)任。