remove mixed portfolio changes

This commit is contained in:
Diogo Sousa
2023-02-01 11:47:59 +00:00
parent d265a126a5
commit 4dd80e2b54
4 changed files with 38 additions and 87 deletions

View File

@@ -9,7 +9,6 @@ from typing import Dict
import yfinance as yf
import pandas as pd
from openbb_terminal.decorators import log_start_end
from openbb_terminal.rich_config import console
logger = logging.getLogger(__name__)
@@ -69,11 +68,7 @@ def get_spy_sector_contributions(
# Load in info
sp500_tickers_data = get_daily_sector_prices(start_date, end_date)
try:
weight_data = yf.Ticker(sectors_ticker).info["sectorWeightings"]
except Exception as _: # noqa
console.print("[red]Could not get info for S&P 500.")
return pd.DataFrame()
weight_data = yf.Ticker(sectors_ticker).info["sectorWeightings"]
# reformat Data
weights: Dict[str, dict] = {"SPY": {}}

View File

@@ -82,7 +82,6 @@ class PortfolioController(BaseController):
CHOICES_MENUS = [
"bro",
"po",
"pa",
]
VALID_DISTRIBUTIONS = ["laplace", "student_t", "logistic", "normal"]
AGGREGATION_METRICS = ["assets", "sectors", "countries", "regions"]
@@ -121,15 +120,6 @@ class PortfolioController(BaseController):
for file_type in self.file_types
for filepath in self.DEFAULT_HOLDINGS_PATH.rglob(f"*.{file_type}")
}
self.DATA_HOLDINGS_FILES.update(
{
filepath.name: filepath
for file_type in self.file_types
for filepath in (
MISCELLANEOUS_DIRECTORY / "portfolio_examples" / "holdings"
).rglob(f"*.{file_type}")
}
)
self.portfolio_df = pd.DataFrame(
columns=[
@@ -160,10 +150,6 @@ class PortfolioController(BaseController):
self.update_choices()
choices: dict = self.choices_default
self.choices = choices
self.choices["bench"] = {
"--benchmark": {c: None for c in statics.BENCHMARK_CHOICES},
"-b": "--benchmark",
}
self.completer = NestedCompleter.from_nested_dict(choices)
def update_choices(self):
@@ -228,7 +214,7 @@ class PortfolioController(BaseController):
> bro brokers holdings, \t\t supports: robinhood, ally, degiro, coinbase
> po portfolio optimization, \t optimize your portfolio weights efficiently[/menu]
[cmds]
load load data into the portfolio
load load transactions into the portfolio (use load --example for an example)
show show existing transactions
bench define the benchmark
[/cmds]
@@ -318,7 +304,6 @@ class PortfolioController(BaseController):
"--file",
type=str,
dest="file",
required="-h" not in other_args,
help="The file to be loaded",
choices={c: {} for c in self.DATA_HOLDINGS_FILES},
metavar="FILE",
@@ -338,12 +323,28 @@ class PortfolioController(BaseController):
dest="risk_free_rate",
help="Set the risk free rate.",
)
parser.add_argument(
"-e",
"--example",
help="Run an example holdings file to understand how the portfolio menu can be used.",
dest="example",
action="store_true",
default=False,
)
if other_args and "-" not in other_args[0][0]:
other_args.insert(0, "-f")
ns_parser = self.parse_known_args_and_warn(parser, other_args)
if ns_parser and ns_parser.file:
if ns_parser.file in self.DATA_HOLDINGS_FILES:
if ns_parser and ns_parser.file or ns_parser and ns_parser.example:
if ns_parser.example:
file_location = (
MISCELLANEOUS_DIRECTORY / "portfolio" / "holdings_example.xlsx"
)
console.print(
"[green]Loading an example, please type `about` "
"to learn how to create your own Portfolio Excel sheet.[/green]\n"
)
elif ns_parser.file in self.DATA_HOLDINGS_FILES:
file_location = self.DATA_HOLDINGS_FILES[ns_parser.file]
else:
file_location = ns_parser.file # type: ignore
@@ -356,6 +357,8 @@ class PortfolioController(BaseController):
if ns_parser.name:
self.portfolio_name = ns_parser.name
elif ns_parser.example:
self.portfolio_name = "OpenBB Example Portfolio"
else:
self.portfolio_name = ns_parser.file
console.print(
@@ -415,6 +418,7 @@ class PortfolioController(BaseController):
dest="benchmark",
required="-h" not in other_args,
help="Set the benchmark for the portfolio. By default, this is SPDR S&P 500 ETF Trust (SPY).",
choices={c: {} for c in statics.BENCHMARK_CHOICES},
metavar="BENCHMARK",
)
parser.add_argument(
@@ -435,13 +439,9 @@ class PortfolioController(BaseController):
"[red]Please first load transactions file using 'load'[/red]"
)
else:
if self.portfolio.set_benchmark(
ns_parser.benchmark, ns_parser.full_shares
):
self.benchmark_name = statics.BENCHMARK_CHOICES.get(
ns_parser.benchmark, ns_parser.benchmark
)
self.original_benchmark_ticker = ns_parser.benchmark
self.benchmark_name = statics.BENCHMARK_CHOICES.get(ns_parser.benchmark)
self.original_benchmark_ticker = ns_parser.benchmark
self.portfolio.set_benchmark(ns_parser.benchmark, ns_parser.full_shares)
@log_start_end(log=logger)
def call_alloc(self, other_args: List[str]):
@@ -580,13 +580,9 @@ class PortfolioController(BaseController):
bench_result = attribution_model.get_spy_sector_contributions(
start_date, end_date
)
if bench_result.empty:
return
portfolio_result = attribution_model.get_portfolio_sector_contributions(
start_date, self.portfolio.portfolio_trades
)
if portfolio_result.empty:
return
# relative results - the proportions of return attribution
if ns_parser.type == "relative":

View File

@@ -21,8 +21,7 @@ from openbb_terminal.portfolio.allocation_model import get_allocation
from openbb_terminal.terminal_helper import suppress_stdout
# pylint: disable=E1136,W0201,R0902,C0302
# pylint: disable=unsupported-assignment-operation,redefined-outer-name
# pylint: too-many-public-methods, consider-using-f-string,disable=raise-missing-from
# pylint: disable=unsupported-assignment-operation,redefined-outer-name,too-many-public-methods, consider-using-f-string
logger = logging.getLogger(__name__)
@@ -496,7 +495,7 @@ class PortfolioEngine:
] = info_list
@log_start_end(log=logger)
def set_benchmark(self, symbol: str = "SPY", full_shares: bool = False) -> bool:
def set_benchmark(self, symbol: str = "SPY", full_shares: bool = False):
"""Load benchmark into portfolio.
Parameters
@@ -506,15 +505,12 @@ class PortfolioEngine:
full_shares: bool
Whether to mimic the portfolio trades exactly (partial shares) or round down the
quantity to the nearest number
Returns
-------
bool
True if successful, False otherwise
"""
p_bar = tqdm(range(4), desc=" Loading benchmark")
self.benchmark_ticker = symbol
self.benchmark_historical_prices = yf.download(
symbol,
start=self.inception_date - datetime.timedelta(days=1),
@@ -523,15 +519,6 @@ class PortfolioEngine:
ignore_tz=True,
)["Adj Close"]
if self.benchmark_historical_prices.empty:
console.print(
f"\n[red]Could not download benchmark data for {symbol}."
" Choose another symbol.\n[/red]"
)
return False
self.benchmark_ticker = symbol
p_bar.n += 1
p_bar.refresh()
@@ -551,6 +538,11 @@ class PortfolioEngine:
p_bar.refresh()
self.benchmark_returns = self.benchmark_historical_prices.pct_change().dropna()
self.benchmark_info = yf.Ticker(symbol).info
p_bar.n += 1
p_bar.refresh()
(
self.portfolio_returns,
self.benchmark_returns,
@@ -559,20 +551,6 @@ class PortfolioEngine:
p_bar.n += 1
p_bar.refresh()
try:
self.benchmark_info = yf.Ticker(symbol).info
except Exception as _: # noqa
console.print(
f"[red]\n\nCould not get info for {symbol}."
" This affects 'alloc' command.[/red]\n"
)
return False
p_bar.n += 1
p_bar.refresh()
return True
@log_start_end(log=logger)
def __mimic_trades_for_benchmark(self, full_shares: bool = False):
"""Mimic trades from the transactions based on chosen benchmark assuming partial shares
@@ -928,12 +906,6 @@ class PortfolioEngine:
Flag to force recalculate allocation if already exists
"""
if not self.benchmark_info:
return
if self.portfolio_trades.empty:
return
if category == "Asset":
if (
self.benchmark_assets_allocation.empty

View File

@@ -58,8 +58,8 @@ def generate_portfolio(
transactions = PortfolioEngine.read_transactions(transactions_file_path)
portfolio_engine = PortfolioEngine(transactions)
portfolio_engine.generate_portfolio_data()
portfolio_engine.set_risk_free_rate(risk_free_rate)
portfolio_engine.set_benchmark(symbol=benchmark_symbol, full_shares=full_shares)
portfolio_engine.set_risk_free_rate(risk_free_rate)
return portfolio_engine
@@ -92,7 +92,7 @@ def get_transactions(portfolio_engine: PortfolioEngine) -> pd.DataFrame:
@log_start_end(log=logger)
def set_benchmark(
portfolio_engine: PortfolioEngine, symbol: str, full_shares: bool = False
) -> bool:
):
"""Load benchmark into portfolio
Parameters
@@ -106,11 +106,6 @@ def set_benchmark(
Whether to mimic the portfolio trades exactly (partial shares) or round down the
quantity to the nearest number
Returns
-------
bool
True if successful, False otherwise
Examples
--------
>>> from openbb_terminal.sdk import openbb
@@ -118,7 +113,7 @@ def set_benchmark(
>>> output = openbb.portfolio.bench(p, symbol="SPY")
"""
return portfolio_engine.set_benchmark(symbol=symbol, full_shares=full_shares)
portfolio_engine.set_benchmark(symbol=symbol, full_shares=full_shares)
@log_start_end(log=logger)
@@ -435,13 +430,6 @@ def join_allocation(
pd.DataFrame
DataFrame with portfolio and benchmark allocations
"""
if portfolio.empty:
portfolio = pd.DataFrame(columns=[column, "Portfolio"])
if benchmark.empty:
benchmark = pd.DataFrame(columns=[column, "Benchmark"])
combined = pd.merge(portfolio, benchmark, on=column, how="left")
combined["Difference"] = combined["Portfolio"] - combined["Benchmark"]
combined = combined.replace(np.nan, "-")