Skip to content

Commit

Permalink
Merge pull request #4079 from OpenBB-finance/hotfix/fix4054
Browse files Browse the repository at this point in the history
Fix load a benchmark that isn't in the list of limited choices + yf.Ticker().info bugs
  • Loading branch information
jmaslek authored Feb 6, 2023
2 parents 108d7cd + 30651d2 commit da69e6d
Show file tree
Hide file tree
Showing 7 changed files with 343 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ portfolio
load --example
show
bench QQQ
bench FAKE_BENCH
bench TSLA
alloc assets -t -l 4
alloc sectors -t -l 4
alloc countries -t -l 4
alloc regions -t -l 4
bench SPY
alloc assets -t -l 4
alloc sectors -t -l 4
alloc countries -t -l 4
Expand Down
73 changes: 42 additions & 31 deletions openbb_terminal/portfolio/allocation_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,16 @@ def get_assets_allocation(
pd.DataFrame
DataFrame with the portfolio's asset allocations
"""
benchmark_assets_allocation = pd.DataFrame(benchmark_info["holdings"])
benchmark_assets_allocation.rename(
columns={"symbol": "Symbol", "holdingPercent": "Benchmark"}, inplace=True
)
benchmark_assets_allocation.drop(columns=["holdingName"], inplace=True)
if "holdings" in benchmark_info:
benchmark_assets_allocation = pd.DataFrame(benchmark_info["holdings"])
benchmark_assets_allocation.rename(
columns={"symbol": "Symbol", "holdingPercent": "Benchmark"}, inplace=True
)
benchmark_assets_allocation.drop(columns=["holdingName"], inplace=True)
else:
benchmark_assets_allocation = pd.DataFrame(
columns=["Symbol", "Benchmark", "Sector", "Country"]
)

portfolio_assets_allocation = (
portfolio_trades[portfolio_trades["Type"] != "CASH"]
Expand Down Expand Up @@ -109,34 +114,37 @@ def get_sectors_allocation(
Returns
-------
pd.DataFrame
DataFrame with regional allocations.
DataFrame with benchmark allocations.
pd.DataFrame
DataFrame with country allocations
DataFrame with portfolio allocations
"""

benchmark_sectors_allocation = (
pd.DataFrame.from_dict(
data={
sector_name: allocation
for sector in benchmark_info["sectorWeightings"]
for sector_name, allocation in sector.items()
},
orient="index",
if "sectorWeightings" in benchmark_info:
benchmark_sectors_allocation = (
pd.DataFrame.from_dict(
data={
sector_name: allocation
for sector in benchmark_info["sectorWeightings"]
for sector_name, allocation in sector.items()
},
orient="index",
)
.squeeze()
.sort_values(ascending=False)
)
.squeeze()
.sort_values(ascending=False)
)

# Prettify sector allocations of benchmark to align with Portfolio Excel
prettified = [
sector.replace("_", " ").title()
for sector in benchmark_sectors_allocation.index
]
# Prettify sector allocations of benchmark to align with Portfolio Excel
prettified = [
sector.replace("_", " ").title()
for sector in benchmark_sectors_allocation.index
]

benchmark_sectors_allocation.index = prettified
benchmark_sectors_allocation = pd.DataFrame(benchmark_sectors_allocation)
benchmark_sectors_allocation.reset_index(inplace=True)
benchmark_sectors_allocation.columns = ["Sector", "Benchmark"]
benchmark_sectors_allocation.index = prettified
benchmark_sectors_allocation = pd.DataFrame(benchmark_sectors_allocation)
benchmark_sectors_allocation.reset_index(inplace=True)
benchmark_sectors_allocation.columns = ["Sector", "Benchmark"]
else:
benchmark_sectors_allocation = pd.DataFrame(columns=["Sector", "Benchmark"])

# Define portfolio sector allocation
# Aggregate sector value for stocks and crypto
Expand Down Expand Up @@ -243,9 +251,9 @@ def get_countries_allocation(
Returns
-------
pd.DataFrame
DataFrame with regional allocations.
DataFrame with benchmark allocations.
pd.DataFrame
DataFrame with country allocations
DataFrame with portfolio allocations
"""

benchmark_allocation = get_symbol_allocation(
Expand Down Expand Up @@ -305,7 +313,7 @@ def get_symbol_allocation(
Returns
-------
pd.DataFrame
Dictionary with country allocations
Dictionary with category allocations
"""

if category == "Region":
Expand All @@ -332,7 +340,10 @@ def get_symbol_allocation(
# Collect data from Fidelity about the portfolio composition of the benchmark
URL = f"https://screener.fidelity.com/ftgw/etf/goto/snapshot/portfolioComposition.jhtml?symbols={symbol}"
html = request(URL).content
df_list = pd.read_html(html)
try:
df_list = pd.read_html(html)
except ValueError:
return pd.DataFrame(columns=[category, col_name])

# Find the ones that contain regions and countries
for index, item in enumerate(df_list):
Expand Down
7 changes: 6 additions & 1 deletion openbb_terminal/portfolio/attribution_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import yfinance as yf

from openbb_terminal.decorators import log_start_end
from openbb_terminal.rich_config import console

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -68,7 +69,11 @@ def get_spy_sector_contributions(

# Load in info
sp500_tickers_data = get_daily_sector_prices(start_date, end_date)
weight_data = yf.Ticker(sectors_ticker).info["sectorWeightings"]
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()

# reformat Data
weights: Dict[str, dict] = {"SPY": {}}
Expand Down
Loading

0 comments on commit da69e6d

Please sign in to comment.