mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 13:01:38 +00:00
remove mixed portfolio changes
This commit is contained in:
@@ -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": {}}
|
||||
|
||||
@@ -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":
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, "-")
|
||||
|
||||
Reference in New Issue
Block a user