mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 12:40:35 +00:00
Portfolio optimization bugs (#1388)
* Better EF plotting * Better error handling with optimization commands * fix test Co-authored-by: didierlopes.eth <dro.lopes@campus.fct.unl.pt>
This commit is contained in:
@@ -285,9 +285,13 @@ def display_efficient_risk(
|
||||
Optional axes to plot data on
|
||||
"""
|
||||
s_title = f"{d_period[period]} Weights that maximise returns at target volatility: {target_volatility}"
|
||||
ef_opt, ef = optimizer_model.get_efficient_risk_portfolio(
|
||||
stocks, period, target_volatility, market_neutral
|
||||
)
|
||||
try:
|
||||
ef_opt, ef = optimizer_model.get_efficient_risk_portfolio(
|
||||
stocks, period, target_volatility, market_neutral
|
||||
)
|
||||
except ValueError as e:
|
||||
console.print(f"[red]{e}[/red]\n")
|
||||
return
|
||||
weights = {key: value * round(port_value, 5) for key, port_value in ef_opt.items()}
|
||||
|
||||
if not market_neutral and pie:
|
||||
@@ -332,9 +336,15 @@ def display_efficient_return(
|
||||
Optional axes to plot data on
|
||||
"""
|
||||
s_title = f"{d_period[period]} Weights that minimizes volatility at target return: {target_return}"
|
||||
ef_opt, ef = optimizer_model.get_efficient_return_portfolio(
|
||||
stocks, period, target_return, market_neutral
|
||||
)
|
||||
try:
|
||||
ef_opt, ef = optimizer_model.get_efficient_return_portfolio(
|
||||
stocks, period, target_return, market_neutral
|
||||
)
|
||||
except ValueError as e:
|
||||
# This means optimization failed
|
||||
console.print(f"[red]{e}[/red]\n")
|
||||
return
|
||||
|
||||
weights = {key: value * round(port_value, 5) for key, port_value in ef_opt.items()}
|
||||
|
||||
if not market_neutral and pie:
|
||||
@@ -382,7 +392,8 @@ def display_ef(
|
||||
|
||||
sharpes = rets / stds
|
||||
ax.scatter(stds, rets, marker=".", c=sharpes)
|
||||
plotting.plot_efficient_frontier(ef, ax=ax, show_assets=True)
|
||||
plotting.plot_efficient_frontier(ef, ax=ax, show_assets=False)
|
||||
|
||||
for ticker, ret, std in zip(
|
||||
ef.tickers, ef.expected_returns, np.sqrt(np.diag(ef.cov_matrix))
|
||||
):
|
||||
@@ -407,6 +418,9 @@ def display_ef(
|
||||
ax.set_xlim(xmin=min(stds) * 0.8)
|
||||
ax.add_line(line)
|
||||
ax.set_title(f"Efficient Frontier simulating {n_portfolios} portfolios")
|
||||
|
||||
ax.legend(loc="best", scatterpoints=1)
|
||||
|
||||
theme.style_primary_axis(ax)
|
||||
if external_axes is None:
|
||||
theme.visualize_output()
|
||||
|
||||
@@ -247,6 +247,7 @@ class PortfolioOptimization(BaseController):
|
||||
console.print(
|
||||
"Please have at least 2 loaded tickers to calculate weights.\n"
|
||||
)
|
||||
return
|
||||
|
||||
optimizer_view.display_equal_weight(
|
||||
stocks=self.tickers, value=ns_parser.value, pie=ns_parser.pie
|
||||
@@ -282,6 +283,7 @@ class PortfolioOptimization(BaseController):
|
||||
console.print(
|
||||
"Please have at least 2 stocks selected to perform calculations."
|
||||
)
|
||||
return
|
||||
|
||||
optimizer_view.display_property_weighting(
|
||||
self.tickers,
|
||||
@@ -320,6 +322,7 @@ class PortfolioOptimization(BaseController):
|
||||
console.print(
|
||||
"Please have at least 2 stocks selected to perform calculations."
|
||||
)
|
||||
return
|
||||
|
||||
optimizer_view.display_property_weighting(
|
||||
self.tickers,
|
||||
@@ -367,6 +370,7 @@ class PortfolioOptimization(BaseController):
|
||||
console.print(
|
||||
"Please have at least 2 stocks selected to perform calculations."
|
||||
)
|
||||
return
|
||||
|
||||
optimizer_view.display_property_weighting(
|
||||
self.tickers,
|
||||
@@ -423,6 +427,7 @@ class PortfolioOptimization(BaseController):
|
||||
console.print(
|
||||
"Please have at least 2 loaded tickers to calculate weights.\n"
|
||||
)
|
||||
return
|
||||
|
||||
optimizer_view.display_max_sharpe(
|
||||
stocks=self.tickers,
|
||||
@@ -471,6 +476,7 @@ class PortfolioOptimization(BaseController):
|
||||
console.print(
|
||||
"Please have at least 2 loaded tickers to calculate weights.\n"
|
||||
)
|
||||
return
|
||||
|
||||
optimizer_view.display_min_volatility(
|
||||
stocks=self.tickers,
|
||||
@@ -535,6 +541,7 @@ class PortfolioOptimization(BaseController):
|
||||
console.print(
|
||||
"Please have at least 2 loaded tickers to calculate weights.\n"
|
||||
)
|
||||
return
|
||||
|
||||
if ns_parser.pie and ns_parser.market_neutral:
|
||||
console.print(
|
||||
@@ -611,11 +618,13 @@ class PortfolioOptimization(BaseController):
|
||||
console.print(
|
||||
"Please have at least 2 loaded tickers to calculate weights.\n"
|
||||
)
|
||||
return
|
||||
|
||||
if ns_parser.pie and ns_parser.market_neutral:
|
||||
console.print(
|
||||
"Cannot show pie chart for market neutral due to negative weights."
|
||||
)
|
||||
return
|
||||
|
||||
optimizer_view.display_efficient_risk(
|
||||
stocks=self.tickers,
|
||||
@@ -685,11 +694,13 @@ class PortfolioOptimization(BaseController):
|
||||
console.print(
|
||||
"Please have at least 2 loaded tickers to calculate weights.\n"
|
||||
)
|
||||
return
|
||||
|
||||
if ns_parser.pie and ns_parser.market_neutral:
|
||||
console.print(
|
||||
"Cannot show pie chart for market neutral due to negative weights."
|
||||
)
|
||||
return
|
||||
|
||||
optimizer_view.display_efficient_return(
|
||||
stocks=self.tickers,
|
||||
@@ -743,6 +754,7 @@ class PortfolioOptimization(BaseController):
|
||||
console.print(
|
||||
"Please have at least 2 loaded tickers to calculate weights.\n"
|
||||
)
|
||||
return
|
||||
|
||||
optimizer_view.display_ef(
|
||||
stocks=self.tickers,
|
||||
|
||||
@@ -326,6 +326,7 @@ def test_call_func(
|
||||
)
|
||||
|
||||
controller = po_controller.PortfolioOptimization(queue=None)
|
||||
controller.tickers = ["AAPL", "MSFT"]
|
||||
|
||||
getattr(controller, tested_func)(other_args)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user