1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
"""Views for the ETF Extension."""
from typing import Any, Dict, Tuple, Union
import pandas as pd
from openbb_charting.charts.generic_charts import bar_chart
from openbb_charting.charts.price_historical import price_historical
from openbb_charting.charts.price_performance import price_performance
from openbb_charting.core.openbb_figure import OpenBBFigure
from openbb_core.app.utils import basemodel_to_df
from plotly.graph_objs import Figure
class EtfViews:
"""Etf Views."""
@staticmethod
def etf_historical( # noqa: PLR0912
**kwargs,
) -> Tuple[OpenBBFigure, Dict[str, Any]]:
"""Etf Price Historical Chart."""
return price_historical(**kwargs)
@staticmethod
def etf_price_performance( # noqa: PLR0912
**kwargs,
) -> Tuple[OpenBBFigure, Dict[str, Any]]:
"""Etf Price Performance Chart."""
return price_performance(**kwargs)
@staticmethod
def etf_holdings(**kwargs) -> Tuple[Union[OpenBBFigure, Figure], Dict[str, Any]]:
"""Equity Compare Groups Chart."""
if "data" in kwargs and isinstance(kwargs["data"], pd.DataFrame):
data = kwargs["data"]
elif "data" in kwargs and isinstance(kwargs["data"], list):
data = basemodel_to_df(kwargs["data"], index=None) # type: ignore
else:
data = basemodel_to_df(kwargs["obbject_item"], index=None) # type: ignore
if "weight" not in data.columns:
raise ValueError("No 'weight' column found in the data.")
orientation = kwargs.get("orientation", "h")
limit = kwargs.get("limit", 20)
symbol = kwargs["standard_params"].get("symbol") # type: ignore
title = kwargs.get("title", f"Top {limit} {symbol} Holdings")
layout_kwargs = kwargs.get("layout_kwargs", {})
data = data.sort_values("weight", ascending=False)
limit = min(limit, len(data)) # type: ignore
target = data.head(limit)[["symbol", "weight"]].set_index("symbol")
target = target.multiply(100)
axis_title = "Weight (%)"
fig = bar_chart(
target.reset_index(),
"symbol",
["weight"],
title=title, # type: ignore
xtitle=axis_title if orientation == "h" else None,
ytitle=axis_title if orientation == "v" else None,
orientation=orientation, # type: ignore
)
fig.update_layout(
hovermode="x" if orientation == "v" else "y",
margin=dict(r=0, l=50) if orientation == "h" else None,
)
fig.update_traces(
hovertemplate=(
"%{y:.3f}%<extra></extra>"
if orientation == "v"
else "%{x:.3f}%<extra></extra>"
)
)
if layout_kwargs:
fig.update_layout(**layout_kwargs) # type: ignore
content = fig.show(external=True).to_plotly_json() # type: ignore
return fig, content
|