summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormontezdesousa <79287829+montezdesousa@users.noreply.github.com>2022-12-02 23:56:41 +0000
committerGitHub <noreply@github.com>2022-12-02 23:56:41 +0000
commitfaca7ab67d1ce5d0ae0e5c862332bcfc37f72ea9 (patch)
tree4e149ff740f7d78a81aa929b976f310d1159716e
parentf47d15088fbe76533f2d29857b58f93fcd34c9d4 (diff)
Portfolio optimization bug fixes (#3675)
* remove hcp * add prams dict to statics * little controller bug * fix view bug * avoid crash if one stock * check params on setup * create parameter class * check and convert parameters using class * change params name to avoid confusion * create a parameter statics dict * change some funcs names * remove unused imports * remove default dict * optional type * add multi choices * cast only int and float * fix completer * fix bugs with parameter validation * fix bugs with parameter validation * add excel formatting * sdk needs mapping as well, controller takes care of this in terminal * small formating * add some safe guard try except * controller bugs * oops * change export path of parameters to portfolio folder * add more commands to scripts * catch optimization exception * log errors * black and exceptions * add flag to test * black * flake8 * forgot this * pylint * change defaults * fix ef default * fix bl * sync sdk defaults * sync last defaults * fix plot heat and add more choices to controller autocomplete * patch weights * fix wrong bool parsing Co-authored-by: James Maslek <jmaslek11@gmail.com>
-rw-r--r--openbb_terminal/miscellaneous/portfolio_examples/optimization/OpenBB_Parameters_Template_v1.0.0.xlsxbin18022 -> 33733 bytes
-rw-r--r--openbb_terminal/miscellaneous/scripts/portfolio/test_po_show_plot_rpf.openbb1
-rw-r--r--openbb_terminal/miscellaneous/scripts/portfolio/test_portfolio_boolean_args.openbb5
-rw-r--r--openbb_terminal/miscellaneous/scripts/portfolio/test_portfolio_po.openbb22
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/optimizer_helper.py48
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/optimizer_model.py745
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/optimizer_view.py390
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/parameters/Parameter.py85
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/parameters/params_controller.py17
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/parameters/params_helpers.py124
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/parameters/params_view.py20
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/po_controller.py44
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/po_engine.py29
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/po_model.py171
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/po_view.py37
-rw-r--r--openbb_terminal/portfolio/portfolio_optimization/statics.py334
16 files changed, 1373 insertions, 699 deletions
diff --git a/openbb_terminal/miscellaneous/portfolio_examples/optimization/OpenBB_Parameters_Template_v1.0.0.xlsx b/openbb_terminal/miscellaneous/portfolio_examples/optimization/OpenBB_Parameters_Template_v1.0.0.xlsx
index 3b8a5afb170..56ffb4d5e05 100644
--- a/openbb_terminal/miscellaneous/portfolio_examples/optimization/OpenBB_Parameters_Template_v1.0.0.xlsx
+++ b/openbb_terminal/miscellaneous/portfolio_examples/optimization/OpenBB_Parameters_Template_v1.0.0.xlsx
Binary files differ
diff --git a/openbb_terminal/miscellaneous/scripts/portfolio/test_po_show_plot_rpf.openbb b/openbb_terminal/miscellaneous/scripts/portfolio/test_po_show_plot_rpf.openbb
index 7146022d153..4277466898d 100644
--- a/openbb_terminal/miscellaneous/scripts/portfolio/test_po_show_plot_rpf.openbb
+++ b/openbb_terminal/miscellaneous/scripts/portfolio/test_po_show_plot_rpf.openbb
@@ -52,3 +52,4 @@ plot -pf name_0 -ct sector -he
maxsharpe
rpf -pf a,b,c
rpf -pf name_0,maxsharpe_1
+exit
diff --git a/openbb_terminal/miscellaneous/scripts/portfolio/test_portfolio_boolean_args.openbb b/openbb_terminal/miscellaneous/scripts/portfolio/test_portfolio_boolean_args.openbb
index dec916dbccc..97abd141325 100644
--- a/openbb_terminal/miscellaneous/scripts/portfolio/test_portfolio_boolean_args.openbb
+++ b/openbb_terminal/miscellaneous/scripts/portfolio/test_portfolio_boolean_args.openbb
@@ -2,8 +2,9 @@ portfolio
load --file Public_Equity_Orderbook.xlsx
po
params
-file --file OpenBB_Parameters_Template_v1.0.0.xlsx
+load OpenBB_Parameters_Template_v1.0.0.xlsx
set ef
arg tangency False
arg log_returns True
-exit \ No newline at end of file
+clear
+exit
diff --git a/openbb_terminal/miscellaneous/scripts/portfolio/test_portfolio_po.openbb b/openbb_terminal/miscellaneous/scripts/portfolio/test_portfolio_po.openbb
index 979549dab13..57a3e5d812d 100644
--- a/openbb_terminal/miscellaneous/scripts/portfolio/test_portfolio_po.openbb
+++ b/openbb_terminal/miscellaneous/scripts/portfolio/test_portfolio_po.openbb
@@ -1,13 +1,14 @@
portfolio
po
load 60_40_Portfolio.xlsx
+file --file example.ini
maxsharpe -s 2022-10-20
minrisk -r 0.05
-maxutil -a 0.1
+maxutil -a 0.1 -ra 2 -tk 0.4 -tr 8
maxret -e 2022-11-20
maxdiv -mn 0.1
maxdecorr -lr
-ef -t
+ef -t -se 69 -n 10
equal -th 0.1
riskparity -p 1y
relriskparity -de 0.9
@@ -21,4 +22,21 @@ plot -pf MAXSHARPE_0 -dd
plot -pf MAXSHARPE_0 -rc
plot -pf MAXSHARPE_0 -he
rpf NAME_6
+..
+load --file market.csv
+po
+equal
+maxsharpe -s 1995-05-07
+minrisk -r 0.08
+maxutil -a 0.1 -ra 2 -tk 0.4 -tr 8
+maxret -e 2022-11-20
+maxdiv -mn 0.1
+maxdecorr -lr -p max
+ef -t -se 420 -n 0
+equal -th 0.1
+riskparity -p 1y
+relriskparity -de 0.9
+hrp -cd pearson
+herc -at 0.1
+nco -rm EDaR -lr
exit
diff --git a/openbb_terminal/portfolio/portfolio_optimization/optimizer_helper.py b/openbb_terminal/portfolio/portfolio_optimization/optimizer_helper.py
index c97832ce3fb..9284da4bf35 100644
--- a/openbb_terminal/portfolio/portfolio_optimization/optimizer_helper.py
+++ b/openbb_terminal/portfolio/portfolio_optimization/optimizer_helper.py
@@ -2,9 +2,14 @@
__docformat__ = "numpy"
import argparse
+from typing import Any
import pandas as pd
-from openbb_terminal.portfolio.portfolio_optimization import statics
+from openbb_terminal.portfolio.portfolio_optimization.statics import (
+ RISK_CHOICES,
+ OPTIMIZATION_PARAMETERS,
+ TERMINAL_TEMPLATE_MAP,
+)
from openbb_terminal.rich_config import console
# These are all the possible yfinance properties
@@ -146,8 +151,45 @@ def validate_risk_measure(risk_measure: str, warning: bool = True) -> str:
str
Validated risk measure
"""
- if risk_measure.lower() in statics.RISK_CHOICES:
- return statics.RISK_CHOICES[risk_measure.lower()]
+ if risk_measure.lower() in RISK_CHOICES:
+ return RISK_CHOICES[risk_measure.lower()]
if warning:
console.print("[yellow]Risk measure not found. Using 'MV'.[/yellow]")
return "MV"
+
+
+def get_kwarg(key: str, kwargs: dict, default: Any = None) -> Any:
+ """Get a key from kwargs
+
+ If key is in kwargs, returns it.
+ Otherwise, if default provided, returns it.
+ Otherwise, if key is in OPTIMIZATION_PARAMETERS, returns it.
+
+ Parameters
+ ----------
+ key : str
+ The key to be searched
+ kwargs : dict
+ The kwargs to be searched
+ default : Any
+ The default value to be returned if the key is not found
+
+ Returns
+ -------
+ Any
+ The value of the key if it exists, else None
+ """
+
+ if key in kwargs:
+ return kwargs[key]
+
+ if default:
+ return default
+
+ # TODO: Remove this line when mapping between template and terminal is not needed
+ template_key = TERMINAL_TEMPLATE_MAP.get(key, key)
+
+ PARAMETER = OPTIMIZATION_PARAMETERS.get(template_key)
+ if PARAMETER is None:
+ return default
+ return PARAMETER.default
diff --git a/openbb_terminal/portfolio/portfolio_optimization/optimizer_model.py b/openbb_terminal/portfolio/portfolio_optimization/optimizer_model.py
index f4a1ec0675d..2a61e251633 100644
--- a/openbb_terminal/portfolio/portfolio_optimization/optimizer_model.py
+++ b/openbb_terminal/portfolio/portfolio_optimization/optimizer_model.py
@@ -21,7 +21,11 @@ from scipy.interpolate import interp1d
from openbb_terminal.decorators import log_start_end
from openbb_terminal.portfolio.portfolio_optimization import (
yahoo_finance_model,
- optimizer_helper,
+)
+from openbb_terminal.portfolio.portfolio_optimization.optimizer_helper import (
+ get_kwarg,
+ validate_risk_measure,
+ valid_property_infos,
)
from openbb_terminal.rich_config import console
@@ -199,15 +203,15 @@ def get_equal_weights(
Dictionary of weights where keys are the tickers, dataframe of stock returns
"""
- interval = kwargs.get("interval", "3y")
- start_date = kwargs.get("start_date", "")
- end_date = kwargs.get("end_date", "")
- log_returns = kwargs.get("log_returns", False)
- freq = kwargs.get("freq", "D")
- maxnan = kwargs.get("maxnan", 0.05)
- threshold = kwargs.get("threshold", 0.0)
- method = kwargs.get("method", "time")
- value = kwargs.get("value", 1.0)
+ interval = get_kwarg("interval", kwargs)
+ start_date = get_kwarg("start_date", kwargs)
+ end_date = get_kwarg("end_date", kwargs)
+ log_returns = get_kwarg("log_returns", kwargs)
+ freq = get_kwarg("freq", kwargs)
+ maxnan = get_kwarg("maxnan", kwargs)
+ threshold = get_kwarg("threshold", kwargs)
+ method = get_kwarg("method", kwargs)
+ value = get_kwarg("value", kwargs)
stock_prices = yahoo_finance_model.process_stocks(
symbols, interval, start_date, end_date
@@ -271,17 +275,17 @@ def get_property_weights(
Dictionary of portfolio weights or allocations
"""
- interval = kwargs.get("interval", "3y")
- start_date = kwargs.get("start_date", "")
- end_date = kwargs.get("end_date", "")
- log_returns = kwargs.get("log_returns", False)
- freq = kwargs.get("freq", "D")
- maxnan = kwargs.get("maxnan", 0.05)
- threshold = kwargs.get("threshold", 0.0)
- method = kwargs.get("method", "time")
- value = kwargs.get("value", 1.0)
+ interval = get_kwarg("interval", kwargs)
+ start_date = get_kwarg("start_date", kwargs)
+ end_date = get_kwarg("end_date", kwargs)
+ log_returns = get_kwarg("log_returns", kwargs)
+ freq = get_kwarg("freq", kwargs)
+ maxnan = get_kwarg("maxnan", kwargs)
+ threshold = get_kwarg("threshold", kwargs)
+ method = get_kwarg("method", kwargs)
+ value = get_kwarg("value", kwargs)
- s_property = kwargs.get("s_property", "marketCap")
+ s_property = get_kwarg("s_property", kwargs, default="marketCap")
stock_prices = yahoo_finance_model.process_stocks(
symbols, interval, start_date, end_date
@@ -427,29 +431,29 @@ def get_mean_risk_portfolio(
DataFrame of stock returns.
"""
- interval = kwargs.get("interval", "3y")
- start_date = kwargs.get("start_date", "")
- end_date = kwargs.get("end_date", "")
- log_returns = kwargs.get("log_returns", False)
- freq = kwargs.get("freq", "D")
- maxnan = kwargs.get("maxnan", 0.05)
- threshold = kwargs.get("threshold", 0.0)
- method = kwargs.get("method", "time")
- value = kwargs.get("value", 1.0)
- value_short = kwargs.get("value_short", 0.0)
-
- risk_measure = kwargs.get("risk_measure", "MV")
- objective = kwargs.get("objective", "Sharpe")
- risk_free_rate = kwargs.get("risk_free_rate", 0.0)
- risk_aversion = kwargs.get("risk_aversion", 1.0)
- alpha = kwargs.get("alpha", 0.05)
- target_return = kwargs.get("target_return", -1.0)
- target_risk = kwargs.get("target_risk", -1.0)
- mean = kwargs.get("mean", "hist")
- covariance = kwargs.get("covariance", "hist")
- d_ewma = kwargs.get("d_ewma", 0.94)
-
- risk_measure = optimizer_helper.validate_risk_measure(risk_measure)
+ interval = get_kwarg("interval", kwargs)
+ start_date = get_kwarg("start_date", kwargs)
+ end_date = get_kwarg("end_date", kwargs)
+ log_returns = get_kwarg("log_returns", kwargs)
+ freq = get_kwarg("freq", kwargs)
+ maxnan = get_kwarg("maxnan", kwargs)
+ threshold = get_kwarg("threshold", kwargs)
+ method = get_kwarg("method", kwargs)
+ value = get_kwarg("value", kwargs)
+ value_short = get_kwarg("value_short", kwargs)
+
+ risk_measure = get_kwarg("risk_measure", kwargs)
+ objective = get_kwarg("objective", kwargs)
+ risk_free_rate = get_kwarg("risk_free_rate", kwargs)
+ risk_aversion = get_kwarg("risk_aversion", kwargs)
+ alpha = get_kwarg("alpha", kwargs)
+ target_return = get_kwarg("target_return", kwargs)
+ target_risk = get_kwarg("target_risk", kwargs)
+ mean = get_kwarg("mean", kwargs)
+ covariance = get_kwarg("covariance", kwargs)
+ d_ewma = get_kwarg("d_ewma", kwargs)
+
+ risk_measure = validate_risk_measure(risk_measure)
stock_prices = yahoo_finance_model.process_stocks(
symbols, interval, start_date, end_date
@@ -468,48 +472,64 @@ def get_mean_risk_portfolio(
)
return {}, pd.DataFrame()
- risk_free_rate = risk_free_rate / time_factor[freq.upper()]
-
- # Building the portfolio object
- port = rp.Portfolio(returns=stock_returns, alpha=alpha)
+ if stock_returns.shape[1] < 2:
+ console.print(
+ f"[red]Given the parameters could only get data for '{stock_returns.columns[0]}'.[/red]\n"
+ "[red]Optimization needs at least two assets.[/red]\n",
+ )
+ return {}, pd.DataFrame()
- # Estimate input parameters:
- port.assets_stats(method_mu=mean, method_cov=covariance, d=d_ewma)
+ first_day = stock_returns.index[0].strftime("%Y-%m-%d")
+ console.print(
+ f"[yellow]First day of data respecting parameters: {first_day}[/yellow]\n"
+ )
- # Budget constraints
- port.upperlng = value
- if value_short > 0:
- port.sht = True
- port.uppersht = value_short
- port.budget = value - value_short
- else:
- port.budget = value
+ risk_free_rate = risk_free_rate / time_factor[freq.upper()]
- # Estimate optimal portfolio:
- model = "Classic"
- hist = True
+ try:
+ # Building the portfolio object
+ port = rp.Portfolio(returns=stock_returns, alpha=alpha)
- if target_return > -1:
- port.lowerret = float(target_return) / time_factor[freq.upper()]
+ # Estimate input parameters:
+ port.assets_stats(method_mu=mean, method_cov=covariance, d=d_ewma)
- if target_risk > -1:
- if risk_measure not in ["ADD", "MDD", "CDaR", "EDaR", "UCI"]:
- setattr(
- port,
- upper_risk[risk_measure],
- float(target_risk) / time_factor[freq.upper()] ** 0.5,
- )
+ # Budget constraints
+ port.upperlng = value
+ if value_short > 0:
+ port.sht = True
+ port.uppersht = value_short
+ port.budget = value - value_short
else:
- setattr(port, upper_risk[risk_measure], float(target_risk))
+ port.budget = value
- weights = port.optimization(
- model=model,
- rm=risk_measure,
- obj=objective,
- rf=risk_free_rate,
- l=risk_aversion,
- hist=hist,
- )
+ # Estimate optimal portfolio:
+ model = "Classic"
+ hist = True
+
+ if target_return > -1:
+ port.lowerret = float(target_return) / time_factor[freq.upper()]
+
+ if target_risk > -1:
+ if risk_measure not in ["ADD", "MDD", "CDaR", "EDaR", "UCI"]:
+ setattr(
+ port,
+ upper_risk[risk_measure],
+ float(target_risk) / time_factor[freq.upper()] ** 0.5,
+ )
+ else:
+ setattr(port, upper_risk[risk_measure], float(target_risk))
+
+ weights = port.optimization(
+ model=model,
+ rm=risk_measure,
+ obj=objective,
+ rf=risk_free_rate,
+ l=risk_aversion,
+ hist=hist,
+ )
+
+ except Exception as _:
+ weights = None
if weights is not None:
weights = weights.round(5)
@@ -1032,19 +1052,19 @@ def get_max_diversification_portfolio(
DataFrame of stock returns.
"""
- interval = kwargs.get("interval", "3y")
- start_date = kwargs.get("start_date", "")
- end_date = kwargs.get("end_date", "")
- log_returns = kwargs.get("log_returns", False)
- freq = kwargs.get("freq", "D")
- maxnan = kwargs.get("maxnan", 0.05)
- threshold = kwargs.get("threshold", 0.0)
- method = kwargs.get("method", "time")
- value = kwargs.get("value", 1.0)
- value_short = kwargs.get("value_short", 0.0)
+ interval = get_kwarg("interval", kwargs)
+ start_date = get_kwarg("start_date", kwargs)
+ end_date = get_kwarg("end_date", kwargs)
+ log_returns = get_kwarg("log_returns", kwargs)
+ freq = get_kwarg("freq", kwargs)
+ maxnan = get_kwarg("maxnan", kwargs)
+ threshold = get_kwarg("threshold", kwargs)
+ method = get_kwarg("method", kwargs)
+ value = get_kwarg("value", kwargs)
+ value_short = get_kwarg("value_short", kwargs)
- covariance = kwargs.get("covariance", "hist")
- d_ewma = kwargs.get("d_ewma", 0.94)
+ covariance = get_kwarg("covariance", kwargs)
+ d_ewma = get_kwarg("d_ewma", kwargs)
stock_prices = yahoo_finance_model.process_stocks(
symbols, interval, start_date, end_date
@@ -1058,24 +1078,29 @@ def get_max_diversification_portfolio(
method=method,
)
- # Building the portfolio object
- port = rp.Portfolio(returns=stock_returns)
+ try:
+ # Building the portfolio object
+ port = rp.Portfolio(returns=stock_returns)
- # Estimate input parameters:
- port.assets_stats(method_mu="hist", method_cov=covariance, d=d_ewma)
- port.mu = stock_returns.std().to_frame().T
+ # Estimate input parameters:
+ port.assets_stats(method_mu="hist", method_cov=covariance, d=d_ewma)
+ port.mu = stock_returns.std().to_frame().T
- # Budget constraints
- port.upperlng = value
- if value_short > 0:
- port.sht = True
- port.uppersht = value_short
- port.budget = value - value_short
- else:
- port.budget = value
+ # Budget constraints
+ port.upperlng = value
+ if value_short > 0:
+ port.sht = True
+ port.uppersht = value_short
+ port.budget = value - value_short
+ else:
+ port.budget = value
- # Estimate optimal portfolio:
- weights = port.optimization(model="Classic", rm="MV", obj="Sharpe", rf=0, hist=True)
+ # Estimate optimal portfolio:
+ weights = port.optimization(
+ model="Classic", rm="MV", obj="Sharpe", rf=0, hist=True
+ )
+ except Exception as _:
+ weights = None
if weights is not None:
weights = weights.round(5)
@@ -1151,19 +1176,19 @@ def get_max_decorrelation_portfolio(
DataFrame of stock returns.
"""
- interval = kwargs.get("interval", "3y")
- start_date = kwargs.get("start_date", "")
- end_date = kwargs.get("end_date", "")
- log_returns = kwargs.get("log_returns", False)
- freq = kwargs.get("freq", "D")
- maxnan = kwargs.get("maxnan", 0.05)
- threshold = kwargs.get("threshold", 0.0)
- method = kwargs.get("method", "time")
- value = kwargs.get("value", 1.0)
- value_short = kwargs.get("value_short", 0.0)
+ interval = get_kwarg("interval", kwargs)
+ start_date = get_kwarg("start_date", kwargs)
+ end_date = get_kwarg("end_date", kwargs)
+ log_returns = get_kwarg("log_returns", kwargs)
+ freq = get_kwarg("freq", kwargs)
+ maxnan = get_kwarg("maxnan", kwargs)
+ threshold = get_kwarg("threshold", kwargs)
+ method = get_kwarg("method", kwargs)
+ value = get_kwarg("value", kwargs)
+ value_short = get_kwarg("value_short", kwargs)
- covariance = kwargs.get("covariance", "hist")
- d_ewma = kwargs.get("d_ewma", 0.94)
+ covariance = get_kwarg("covariance", kwargs)
+ d_ewma = get_kwarg("d_ewma", kwargs)
stock_prices = yahoo_finance_model.process_stocks(
symbols, interval, start_date, end_date
@@ -1177,26 +1202,30 @@ def get_max_decorrelation_portfolio(
method=method,
)
- # Building the portfolio object
- port = rp.Portfolio(returns=stock_returns)
+ try:
- # Estimate input parameters:
- port.assets_stats(method_mu="hist", method_cov=covariance, d=d_ewma)
- port.cov = rp.cov2corr(port.cov)
+ # Building the portfolio object
+ port = rp.Portfolio(returns=stock_returns)
- # Budget constraints
- port.upperlng = value
- if value_short > 0:
- port.sht = True
- port.uppersht = value_short
- port.budget = value - value_short
- else:
- port.budget = value
+ # Estimate input parameters:
+ port.assets_stats(method_mu="hist", method_cov=covariance, d=d_ewma)
+ port.cov = rp.cov2corr(port.cov)
- # Estimate optimal portfolio:
- weights = port.optimization(
- model="Classic", rm="MV", obj="MinRisk", rf=0, hist=True
- )
+ # Budget constraints
+ port.upperlng = value
+ if value_short > 0:
+ port.sht = True
+ port.uppersht = value_short
+ port.budget = value - value_short
+ else:
+ port.budget = value
+
+ # Estimate optimal portfolio:
+ weights = port.optimization(
+ model="Classic", rm="MV", obj="MinRisk", rf=0, hist=True
+ )
+ except Exception as _:
+ weights = None
if weights is not None:
weights = weights.round(5)
@@ -1284,26 +1313,26 @@ def get_black_litterman_portfolio(
DataFrame of stock returns.
"""
- interval = kwargs.get("interval", "3y")
- start_date = kwargs.get("start_date", "")
- end_date = kwargs.get("end_date", "")
- log_returns = kwargs.get("log_returns", False)
- freq = kwargs.get("freq", "D")
- maxnan = kwargs.get("maxnan", 0.05)
- threshold = kwargs.get("threshold", 0.0)
- method = kwargs.get("method", "time")
- value = kwargs.get("value", 1.0)
- value_short = kwargs.get("value_short", 0.0)
-
- benchmark = kwargs.get("benchmark", None)
- p_views = kwargs.get("p_views", None)
- q_views = kwargs.get("q_views", None)
- objective = kwargs.get("objective", "Sharpe")
- risk_free_rate = kwargs.get("risk_free_rate", 0)
- risk_aversion = kwargs.get("risk_aversion", 1)
- delta = kwargs.get("delta", None)
- equilibrium = kwargs.get("equilibrium", True)
- optimize = kwargs.get("optimize", True)
+ interval = get_kwarg("interval", kwargs)
+ start_date = get_kwarg("start_date", kwargs)
+ end_date = get_kwarg("end_date", kwargs)
+ log_returns = get_kwarg("log_returns", kwargs)
+ freq = get_kwarg("freq", kwargs)
+ maxnan = get_kwarg("maxnan", kwargs)
+ threshold = get_kwarg("threshold", kwargs)
+ method = get_kwarg("method", kwargs)
+ value = get_kwarg("value", kwargs)
+ value_short = get_kwarg("value_short", kwargs)
+
+ benchmark = get_kwarg("benchmark", kwargs)
+ p_views = get_kwarg("p_views", kwargs)
+ q_views = get_kwarg("q_views", kwargs)
+ objective = get_kwarg("objective", kwargs)
+ risk_free_rate = get_kwarg("risk_free_rate", kwargs)
+ risk_aversion = get_kwarg("risk_aversion", kwargs)
+ delta = get_kwarg("delta", kwargs)
+ equilibrium = get_kwarg("equilibrium", kwargs)
+ optimize = get_kwarg("optimize", kwargs)
stock_prices = yahoo_finance_model.process_stocks(
symbols, interval, start_date, end_date
@@ -1349,32 +1378,35 @@ def get_black_litterman_portfolio(
weights = pd.DataFrame(weights)
if optimize:
- # Building the portfolio object
- port = rp.Portfolio(returns=stock_returns)
-
- # Estimate input parameters:
- port.assets_stats(method_mu="hist", method_cov="hist")
- port.mu_bl = pd.DataFrame(mu).T
- port.cov_bl = pd.DataFrame(cov)
-
- # Budget constraints
- port.upperlng = value
- if value_short > 0:
- port.sht = True
- port.uppersht = value_short
- port.budget = value - value_short
- else:
- port.budget = value
-
- # Estimate optimal portfolio:
- weights = port.optimization(
- model="BL",
- rm="MV",
- obj=objective,
- rf=risk_free_rate,
- l=risk_aversion,
- hist=True,
- )
+ try:
+ # Building the portfolio object
+ port = rp.Portfolio(returns=stock_returns)
+
+ # Estimate input parameters:
+ port.assets_stats(method_mu="hist", method_cov="hist")
+ port.mu_bl = pd.DataFrame(mu).T
+ port.cov_bl = pd.DataFrame(cov)
+
+ # Budget constraints
+ port.upperlng = value
+ if value_short > 0:
+ port.sht = True
+ port.uppersht = value_short
+ port.budget = value - value_short
+ else:
+ port.budget = value
+
+ # Estimate optimal portfolio:
+ weights = port.optimization(
+ model="BL",
+ rm="MV",
+ obj=objective,
+ rf=risk_free_rate,
+ l=risk_aversion,
+ hist=True,
+ )
+ except Exception as _:
+ weights = None
if weights is not None:
weights = weights.round(5)
@@ -1478,25 +1510,25 @@ def get_ef(
frontier, mu, cov, stock_returns, weights, X1, Y1, port
"""
- interval = kwargs.get("interval", "3y")
- start_date = kwargs.get("start_date", "")
- end_date = kwargs.get("end_date", "")
- log_returns = kwargs.get("log_returns", False)
- freq = kwargs.get("freq", "D")
- maxnan = kwargs.get("maxnan", 0.05)
- threshold = kwargs.get("threshold", 0.05)
- method = kwargs.get("method", "time")
- value = kwargs.get("value", 1.0)
- value_short = kwargs.get("value_short", 0.0)
-
- risk_measure = kwargs.get("risk_measure", "MV")
- risk_free_rate = kwargs.get("risk_free_rate", 0.0)
- alpha = kwargs.get("alpha", 0.05)
- n_portfolios = kwargs.get("n_portfolios", 100)
- seed = kwargs.get("seed", 123)
+ interval = get_kwarg("interval", kwargs)
+ start_date = get_kwarg("start_date", kwargs)
+ end_date = get_kwarg("end_date", k