summaryrefslogtreecommitdiffstats
path: root/openbb_platform/extensions/etf/openbb_etf/etf_views.py
blob: 71e2c9e3c23f18c7fe8fd76ad32af754d02c53d3 (plain)
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