-
Notifications
You must be signed in to change notification settings - Fork 12
/
efficient_frontier_portfolio_optimizer.py
79 lines (73 loc) · 2.81 KB
/
efficient_frontier_portfolio_optimizer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pandas_datareader import data as web
from datetime import datetime
from pypfopt import risk_models
from pypfopt import EfficientFrontier
from pypfopt import expected_returns
from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices
from pypfopt import plotting
#Importing my own file to use the functions:
import basic_portfolio_functions as bpf
#The Efficient Frontier Method to optimize
def optimizePortEfficient(port, weights, start, plot = False, short = False, printBasicStats=True, how = 'Sharpe'):
#Getting Data
df = bpf.getData(port, start)
#Plotting the portfolio
if plot:
bpf.plotPort(df, port)
if printBasicStats:
bpf.basicStats(df, weights, start)
#Optimization for Sharpe using Efficient Frontier
if short:
bounds = (-1,1)
else:
bounds = (0,1)
mu = df.pct_change().mean() * 252
S = risk_models.sample_cov(df)
#Method and constraints for optimization
if how == 'Sharpe':
# Maximized on Sharpe Ratio
ef = EfficientFrontier(mu, S, weight_bounds=bounds) #Here the weight bounds are being used to allow short positions as well
weights = ef.max_sharpe()
cleaned_weights = dict(ef.clean_weights())
print("Weights of an optimal portfolio maximised on Sharpe Ratio:")
print(cleaned_weights)
ef.portfolio_performance(verbose = True)
bpf.getDiscreteAllocations(df, weights)
plotting.plot_weights(weights)
return weights
elif how == "Vol":
# Minimized on Volatility
efi = EfficientFrontier(mu, S, weight_bounds=bounds)
w = dict(efi.min_volatility())
print("Weights of an optimal portfolio minimized on Volatilty (Risk):")
print(w)
efi.portfolio_performance(verbose = True)
bpf.getDiscreteAllocations(df, w)
plotting.plot_weights(w)
return w
elif how == "targetRisk":
#Optimized for a given target risk
efi = EfficientFrontier(mu, S, weight_bounds=bounds)
efi.efficient_risk(0.25)
w = dict(efi.clean_weights())
if w ==None:
print("No portfolio possible at the given risk level")
else:
print("Weights of an optimal portfolio for given risk:")
print(w)
efi.portfolio_performance(verbose = True)
bpf.getDiscreteAllocations(df, w)
plotting.plot_weights(w)
return w
# an Example FAANG portfolio with equal weights
# portfolio = ['FB', "AAPL", "AMZN", 'NFLX', 'GOOG']
# weights = np.array([0.2,0.2,0.2,0.2,0.2])
# start = '2013-01-01'
# price = 10000000
# w = optimizePortEfficient(portfolio, weights, start)
# w = list(w.values())
# bpf.VaR(portfolio, weights, price)
# bpf.VaR(portfolio, w, price)