Fix + improve efficient frontier (#1190)

This commit is contained in:
jmaslek
2022-01-15 11:02:59 -05:00
committed by GitHub
parent 7412d2b61a
commit a3255b96a0
3 changed files with 50 additions and 43 deletions

View File

@@ -1,11 +1,11 @@
"""Optimization View"""
__docformat__ = "numpy"
import copy
import math
from typing import List
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
import numpy as np
import pandas as pd
@@ -342,13 +342,20 @@ def display_ef(
ef, rets, stds = optimizer_model.generate_random_portfolios(
stocks, period, n_portfolios
)
# The ef needs to be deep-copied to avoid error in plotting sharpe
ef2 = copy.deepcopy(ef)
sharpes = rets / stds
ax.scatter(stds, rets, marker=".", c=sharpes, cmap="viridis_r")
for ticker, ret, std in zip(
ef.tickers, ef.expected_returns, np.sqrt(np.diag(ef.cov_matrix))
):
ax.annotate(ticker, (std * 1.01, ret))
plotting.plot_efficient_frontier(ef, ax=ax, show_assets=True)
# Find the tangency portfolio
rfrate = get_rf()
ef.max_sharpe(risk_free_rate=rfrate)
ret_sharpe, std_sharpe, _ = ef.portfolio_performance(
ef2.max_sharpe(risk_free_rate=rfrate)
ret_sharpe, std_sharpe, _ = ef2.portfolio_performance(
verbose=True, risk_free_rate=rfrate
)
ax.scatter(std_sharpe, ret_sharpe, marker="*", s=100, c="r", label="Max Sharpe")

View File

@@ -374,7 +374,7 @@ class PortfolioOptimization(BaseController):
parser.add_argument(
"-p",
"--period",
default="3mo",
default="1y",
dest="period",
help="period to get yfinance data from",
choices=self.period_choices,
@@ -430,7 +430,7 @@ class PortfolioOptimization(BaseController):
parser.add_argument(
"-p",
"--period",
default="3mo",
default="1y",
dest="period",
help="period to get yfinance data from",
choices=self.period_choices,
@@ -476,7 +476,7 @@ class PortfolioOptimization(BaseController):
parser.add_argument(
"-p",
"--period",
default="3mo",
default="1y",
dest="period",
help="period to get yfinance data from",
choices=self.period_choices,
@@ -547,7 +547,7 @@ class PortfolioOptimization(BaseController):
parser.add_argument(
"-p",
"--period",
default="3mo",
default="1y",
dest="period",
help="period to get yfinance data from",
choices=self.period_choices,
@@ -621,7 +621,7 @@ class PortfolioOptimization(BaseController):
parser.add_argument(
"-p",
"--period",
default="3mo",
default="1y",
dest="period",
help="period to get yfinance data from",
choices=self.period_choices,
@@ -695,7 +695,7 @@ class PortfolioOptimization(BaseController):
parser.add_argument(
"-p",
"--period",
default="3mo",
default="1y",
dest="period",
help="period to get yfinance data from",
choices=self.period_choices,

68
requirements.txt vendored
View File

@@ -2,13 +2,13 @@ aiohttp==3.7.4.post0; python_version >= "3.6"
alabaster==0.7.12; python_full_version >= "3.6.8" and python_full_version < "4.0.0" and python_version >= "3.6"
alpha-vantage==2.3.1
ansiwrap==0.8.4; python_version >= "3.6"
anyio==3.4.0; python_full_version >= "3.6.2" and python_version >= "3.6"
anyio==3.5.0; python_full_version >= "3.6.2" and python_version >= "3.7"
appdirs==1.4.4; python_full_version >= "3.6.2" and python_version >= "3.6"
appnope==0.1.2; platform_system == "Darwin" and python_version >= "3.7" and sys_platform == "darwin"
argon2-cffi-bindings==21.2.0; python_version >= "3.6"
argon2-cffi==21.3.0; python_version >= "3.6"
argon2-cffi-bindings==21.2.0; python_version >= "3.7"
argon2-cffi==21.3.0; python_version >= "3.7"
async-timeout==3.0.1; python_full_version >= "3.5.3" and python_version >= "3.6"
attrs==21.4.0; python_full_version >= "3.6.1" and python_version >= "3.6"
attrs==21.4.0; python_full_version >= "3.7.0" and python_version >= "3.6"
babel==2.9.1; python_full_version >= "3.6.8" and python_full_version < "4.0.0" and python_version >= "3.6" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6")
backcall==0.2.0; python_version >= "3.7"
backports.zoneinfo==0.2.1; python_version < "3.9" and python_version >= "3.6" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6")
@@ -19,7 +19,7 @@ bleach==4.1.0; python_version >= "3.7"
bs4==0.0.1
bt==0.2.9; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0")
certifi==2021.10.8; python_full_version >= "3.7.1" and python_version >= "3.6" and python_full_version < "4.0.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0") and (python_version >= "3.8" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.8" and python_version < "4.0" and python_full_version >= "3.6.0") and (python_version >= "3" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3")
cffi==1.15.0; implementation_name == "pypy" and python_version >= "3.7" and python_full_version >= "3.6.1"
cffi==1.15.0; implementation_name == "pypy" and python_version >= "3.7" and python_full_version >= "3.7.0"
chardet==4.0.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
charset-normalizer==2.0.10; python_full_version >= "3.7.1" and python_version >= "3.6" and python_full_version < "4.0.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0") and (python_version >= "3.8" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.8" and python_version < "4.0" and python_full_version >= "3.6.0") and (python_version >= "3" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3")
click==8.0.3; python_full_version >= "3.6.2" and python_version >= "3.6"
@@ -42,7 +42,7 @@ detecta==0.0.5; python_version >= "3.6"
dnspython==2.1.0; python_version >= "3.6"
docutils==0.16; python_full_version >= "3.6.8" and python_full_version < "4.0.0" and python_version >= "3.6"
ecos==2.0.10; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.6"
entrypoints==0.3; python_full_version >= "3.6.1" and python_version >= "3.7"
entrypoints==0.3; python_full_version >= "3.7.0" and python_version >= "3.7"
et-xmlfile==1.1.0; python_version >= "3.6"
fear-greed-index==0.1.3; python_full_version >= "3.6.8" and python_full_version < "4.0.0"
ffn==0.3.6; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
@@ -56,17 +56,17 @@ frozendict==2.1.3; python_version >= "3.6"
fundamentalanalysis==0.2.12
future==0.18.2; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
gitdb==4.0.9; python_version >= "3.7"
gitpython==3.1.25; python_version >= "3.7"
gitpython==3.1.26; python_version >= "3.7"
grpcio==1.43.0; python_full_version >= "3.7.1" and python_full_version < "4.0.0" and python_version >= "3.6"
hijri-converter==2.2.2; python_version >= "3.6"
holidays==0.11.3.1; python_version >= "3.6"
idna==3.3; python_full_version >= "3.7.1" and python_version >= "3.6" and python_full_version < "4.0.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0") and (python_version >= "3.8" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.8" and python_version < "4.0" and python_full_version >= "3.6.0") and (python_version >= "3" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3")
idna==3.3; python_full_version >= "3.7.1" and python_version >= "3.7" and python_full_version < "4.0.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0") and (python_version >= "3.8" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.8" and python_version < "4.0" and python_full_version >= "3.6.0") and (python_version >= "3" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3")
imagesize==1.3.0; python_full_version >= "3.6.8" and python_full_version < "4.0.0" and python_version >= "3.6"
inflection==0.5.1; python_version >= "3.6"
investpy==1.0.7; python_version >= "3"
ipykernel==6.6.1; python_version >= "3.7"
ipykernel==6.7.0; python_version >= "3.7"
ipympl==0.8.5
ipython-genutils==0.2.0; python_full_version >= "3.6.1" and python_version >= "3.6"
ipython-genutils==0.2.0; python_full_version >= "3.7.0" and python_version >= "3.7"
ipython==7.31.0; python_version >= "3.7"
ipywidgets==7.6.5
iso8601==0.1.16
@@ -75,15 +75,15 @@ jinja2==3.0.3; python_full_version >= "3.6.8" and python_full_version < "4.0.0"
joblib==1.1.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7"
json5==0.9.6; python_version >= "3.6"
jsonschema==3.2.0
jupyter-client==7.1.0; python_full_version >= "3.6.1" and python_version >= "3.7"
jupyter-client==7.1.1; python_full_version >= "3.7.0" and python_version >= "3.7"
jupyter-console==6.4.0; python_version >= "3.6"
jupyter-core==4.9.1; python_full_version >= "3.6.1" and python_version >= "3.7"
jupyter-server==1.13.1; python_version >= "3.6"
jupyter-core==4.9.1; python_full_version >= "3.7.0" and python_version >= "3.7"
jupyter-server==1.13.3; python_version >= "3.7"
jupyter==1.0.0
jupyterlab-pygments==0.1.2; python_version >= "3.7"
jupyterlab-server==2.10.3; python_version >= "3.6"
jupyterlab-widgets==1.0.2; python_version >= "3.6"
jupyterlab==3.2.6; python_version >= "3.6"
jupyterlab==3.2.8; python_version >= "3.6"
kiwisolver==1.3.2; python_full_version >= "3.6.8" and python_full_version < "4.0.0" and python_version >= "3.7"
korean-lunar-calendar==0.2.1; python_version >= "3.6"
lxml==4.7.1; python_full_version >= "3.6.8" and python_version >= "3.5" and python_full_version < "4.0.0" and (python_version >= "3" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3") and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6")
@@ -98,12 +98,12 @@ multidict==5.2.0; python_version >= "3.6"
multitasking==0.0.10
mypy-extensions==0.4.3; python_full_version >= "3.6.2" and python_version >= "3.6"
mypy==0.930; python_version >= "3.6"
nbclassic==0.3.4; python_version >= "3.6"
nbclient==0.5.9; python_full_version >= "3.6.1" and python_version >= "3.7"
nbclassic==0.3.5; python_version >= "3.6"
nbclient==0.5.10; python_full_version >= "3.7.0" and python_version >= "3.7"
nbconvert==6.4.0; python_version >= "3.7"
nbformat==5.1.3; python_full_version >= "3.6.1" and python_version >= "3.7"
nest-asyncio==1.5.4; python_full_version >= "3.6.1" and python_version >= "3.7"
notebook==6.4.6; python_version >= "3.6"
nbformat==5.1.3; python_full_version >= "3.7.0" and python_version >= "3.7"
nest-asyncio==1.5.4; python_full_version >= "3.7.0" and python_version >= "3.7"
notebook==6.4.7; python_version >= "3.6"
numpy==1.21.2; python_version >= "3.7" and python_version < "3.11"
oandapyv20==0.6.3
oauthlib==3.1.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
@@ -126,15 +126,15 @@ plotly==5.5.0; python_version >= "3.6"
pmdarima==1.8.4; python_version >= "3.6"
praw==7.5.0; python_version >= "3.6" and python_version < "4.0"
prawcore==2.3.0; python_version >= "3.6" and python_version < "4.0"
prometheus-client==0.12.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
prometheus-client==0.12.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
prompt-toolkit==3.0.24; python_full_version >= "3.6.2"
protobuf==3.19.1; python_full_version >= "3.7.1" and python_full_version < "4.0.0" and python_version >= "3.5"
protobuf==3.19.3; python_full_version >= "3.7.1" and python_full_version < "4.0.0" and python_version >= "3.5"
psaw==0.0.12; python_version >= "3"
ptyprocess==0.7.0; os_name != "nt" and python_version >= "3.7" and sys_platform != "win32"
py==1.11.0; implementation_name == "pypy" and python_version >= "3.7" and python_full_version >= "3.6.1"
py==1.11.0; implementation_name == "pypy" and python_version >= "3.7" and python_full_version >= "3.7.0"
pyally==1.1.2
pycoingecko==2.2.0
pycparser==2.21; implementation_name == "pypy" and python_version >= "3.7" and python_full_version >= "3.6.1"
pycparser==2.21; implementation_name == "pypy" and python_version >= "3.7" and python_full_version >= "3.7.0"
pyex==0.5.0
pygments==2.11.2; python_version >= "3.5"
pymeeus==0.5.11; python_version >= "3.6"
@@ -145,7 +145,7 @@ pyotp==2.6.0; python_version >= "3"
pyparsing==3.0.6; python_full_version >= "3.6.8" and python_full_version < "4.0.0" and python_version >= "3.7"
pyportfolioopt==1.5.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0"
pyprind==2.11.3; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
pyrsistent==0.18.0; python_version >= "3.6"
pyrsistent==0.18.1; python_version >= "3.7"
python-binance==1.0.15
python-coinmarketcap==0.2
python-dateutil==2.8.2; python_full_version >= "3.7.1" and python_version >= "3.7" and python_full_version < "4.0.0" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.5")
@@ -153,10 +153,10 @@ python-dotenv==0.19.2; python_version >= "3.5"
pytrends==4.7.3
pytz-deprecation-shim==0.1.0.post0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6"
pytz==2021.3; python_full_version >= "3.7.1" and python_version >= "3.6" and python_full_version < "4.0.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6")
pywin32==303; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.7" and python_full_version >= "3.6.1"
pywinpty==1.1.6; os_name == "nt" and python_version >= "3.6"
pywin32==303; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.7" and python_full_version >= "3.7.0"
pywinpty==1.1.6; os_name == "nt" and python_version >= "3.7"
pyyaml==6.0; python_version >= "3.6"
pyzmq==22.3.0; python_full_version >= "3.6.1" and python_version >= "3.7"
pyzmq==22.3.0; python_full_version >= "3.7.0" and python_version >= "3.7"
qdldl==0.1.5.post0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.6"
qtconsole==5.2.2; python_version >= "3.6"
qtpy==2.0.0; python_version >= "3.6"
@@ -171,15 +171,15 @@ robin-stocks==2.1.0; python_version >= "3"
scikit-learn==1.0.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7"
scipy==1.7.3; python_version >= "3.7" and python_version < "3.11" and python_full_version >= "3.6.1" and python_full_version < "4.0.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0") and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7")
screeninfo==0.6.7
scs==3.0.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.6"
scs==3.1.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.6"
seaborn==0.11.2; python_version >= "3.6"
selenium==3.141.0
send2trash==1.8.0; python_version >= "3.6"
send2trash==1.8.0; python_version >= "3.7"
sentiment-investor==2.1.0; python_version >= "3.8" and python_version < "4.0"
setuptools-scm==6.3.2; python_full_version >= "3.6.8" and python_full_version < "4.0.0" and python_version >= "3.7"
six==1.16.0; python_full_version >= "3.7.1" and python_version >= "3.7" and python_full_version < "4.0.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6") and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0") and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7")
smmap==5.0.0; python_version >= "3.7"
sniffio==1.2.0; python_full_version >= "3.6.2" and python_version >= "3.6"
sniffio==1.2.0; python_full_version >= "3.6.2" and python_version >= "3.7"
snowballstemmer==2.2.0; python_full_version >= "3.6.8" and python_full_version < "4.0.0" and python_version >= "3.6"
socketio-client-nexus==0.7.6
soupsieve==2.3.1; python_version >= "3.6" and python_full_version > "3.0.0"
@@ -196,16 +196,16 @@ statsmodels==0.12.2; python_version >= "3.6"
tabulate==0.8.9
temporal-cache==0.1.4
tenacity==8.0.1; python_version >= "3.6"
terminado==0.12.1; python_version >= "3.6"
terminado==0.12.1; python_version >= "3.7"
testpath==0.5.0; python_version >= "3.7"
textwrap3==0.9.2; python_version >= "3.6"
thepassiveinvestor==1.0.10
threadpoolctl==3.0.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7"
tomli==1.2.3; python_full_version >= "3.6.2" and python_version >= "3.7"
tornado==6.1; python_full_version >= "3.6.1" and python_version >= "3.7"
tornado==6.1; python_full_version >= "3.7.0" and python_version >= "3.7"
tqdm==4.62.3; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6"
tradingview-ta==3.2.10; python_version >= "3.6"
traitlets==5.1.1; python_full_version >= "3.6.1" and python_version >= "3.7"
traitlets==5.1.1; python_full_version >= "3.7.0" and python_version >= "3.7"
typing-extensions==4.0.1; python_version >= "3.6"
tzdata==2021.5; platform_system == "Windows" and python_version >= "3.6" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6")
tzlocal==4.1; python_version >= "3.6"
@@ -224,5 +224,5 @@ websockets==9.1; python_full_version >= "3.6.1" and python_version >= "3.6"
widgetsnbextension==3.5.2
wrapt==1.13.3; python_full_version >= "3.7.1" and python_full_version < "4.0.0"
yarl==1.7.2; python_version >= "3.6"
yfinance==0.1.68
yfinance==0.1.69
zope.interface==5.4.0; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.5"