openbb-charting 2.1.0__tar.gz → 2.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/PKG-INFO +2 -4
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/__init__.py +3 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/charting_router.py +175 -23
- openbb_charting-2.1.1/openbb_charting/core/assets/plotly-2.32.0.min.js +8 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/backend.py +1 -12
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/openbb_figure.py +4 -2
- openbb_charting-2.1.1/openbb_charting/core/plotly.html +3621 -0
- openbb_charting-2.1.1/openbb_charting/core/table.html +166 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/query_params.py +17 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/utils/helpers.py +19 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/utils/relative_rotation.py +4 -7
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/pyproject.toml +2 -4
- openbb_charting-2.1.0/openbb_charting/core/assets/plotly-2.24.2.min.js +0 -8
- openbb_charting-2.1.0/openbb_charting/core/plotly.html +0 -5285
- openbb_charting-2.1.0/openbb_charting/core/table.html +0 -326
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/README.md +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/builder.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/__init__.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/assets/Terminal_icon.png +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/chart_style.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/config/__init__.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/config/openbb_styles.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/dummy_backend.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/__init__.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/base.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/data_classes.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/plugins/__init__.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/plugins/custom_indicators_plugin.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/plugins/momentum_plugin.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/plugins/overlap_plugin.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/plugins/trend_indicators_plugin.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/plugins/volatility_plugin.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/plugins/volume_plugin.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/ta_class.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/plotly_ta/ta_helpers.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/core/to_chart.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/styles/__init__.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/styles/colors.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/styles/default/dark.pltstyle.json +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/styles/default/light.pltstyle.json +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/styles/default/tables.pltstyle.json +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/utils/__init__.py +0 -0
- {openbb_charting-2.1.0 → openbb_charting-2.1.1}/openbb_charting/utils/generic_charts.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: openbb-charting
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.1
|
|
4
4
|
Summary: Charting extension for OpenBB
|
|
5
5
|
License: AGPL-3.0-only
|
|
6
6
|
Author: OpenBB Team
|
|
@@ -13,14 +13,12 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.10
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
15
|
Requires-Dist: nbformat (>=5.9.2,<6.0.0)
|
|
16
|
-
Requires-Dist: openbb-core (>=1.2.
|
|
16
|
+
Requires-Dist: openbb-core (>=1.2.3,<2.0.0)
|
|
17
17
|
Requires-Dist: pandas-ta (>=0.3.14b,<0.4.0)
|
|
18
18
|
Requires-Dist: plotly (>=5.17.0,<6.0.0)
|
|
19
19
|
Requires-Dist: pywry (>=0.6.1,<0.7.0)
|
|
20
|
-
Requires-Dist: reportlab (>=4.0.4,<5.0.0)
|
|
21
20
|
Requires-Dist: scipy (>=1.10.0,<2.0.0)
|
|
22
21
|
Requires-Dist: statsmodels (>=0.14.0,<0.15.0)
|
|
23
|
-
Requires-Dist: svglib (>=1.5.1,<2.0.0)
|
|
24
22
|
Description-Content-Type: text/markdown
|
|
25
23
|
|
|
26
24
|
# OpenBB Charting extension
|
|
@@ -459,6 +459,9 @@ class Charting:
|
|
|
459
459
|
)
|
|
460
460
|
kwargs["provider"] = self._obbject.provider # pylint: disable=protected-access
|
|
461
461
|
kwargs["extra"] = self._obbject.extra # pylint: disable=protected-access
|
|
462
|
+
kwargs["extra_params"] = kwargs["extra"]["metadata"].arguments.get(
|
|
463
|
+
"extra_params"
|
|
464
|
+
)
|
|
462
465
|
if "kwargs" in kwargs:
|
|
463
466
|
_kwargs = kwargs.pop("kwargs")
|
|
464
467
|
kwargs.update(_kwargs.get("chart_params", {}))
|
|
@@ -8,6 +8,7 @@ from warnings import warn
|
|
|
8
8
|
import pandas as pd
|
|
9
9
|
from openbb_core.app.model.charts.chart import ChartFormat
|
|
10
10
|
from openbb_core.app.utils import basemodel_to_df
|
|
11
|
+
from openbb_core.provider.abstract.data import Data
|
|
11
12
|
from plotly.graph_objs import Figure
|
|
12
13
|
|
|
13
14
|
from openbb_charting.core.chart_style import ChartStyle
|
|
@@ -19,6 +20,7 @@ from openbb_charting.utils import relative_rotation
|
|
|
19
20
|
from openbb_charting.utils.generic_charts import bar_chart
|
|
20
21
|
from openbb_charting.utils.helpers import (
|
|
21
22
|
calculate_returns,
|
|
23
|
+
duration_sorter,
|
|
22
24
|
heikin_ashi,
|
|
23
25
|
should_share_axis,
|
|
24
26
|
z_score_standardization,
|
|
@@ -31,7 +33,6 @@ def equity_price_performance(
|
|
|
31
33
|
**kwargs,
|
|
32
34
|
) -> Tuple[Union[OpenBBFigure, Figure], Dict[str, Any]]: # noqa: PLR0912
|
|
33
35
|
"""Equity Price Performance Chart."""
|
|
34
|
-
|
|
35
36
|
if "data" in kwargs and isinstance(kwargs["data"], pd.DataFrame):
|
|
36
37
|
data = kwargs["data"]
|
|
37
38
|
elif "data" in kwargs and isinstance(kwargs["data"], list):
|
|
@@ -83,7 +84,7 @@ def equity_price_performance(
|
|
|
83
84
|
limit = kwargs.pop("limit", 10)
|
|
84
85
|
chart_df = chart_df.head(limit) # type: ignore
|
|
85
86
|
|
|
86
|
-
layout_kwargs: Dict[str, Any] = kwargs
|
|
87
|
+
layout_kwargs: Dict[str, Any] = kwargs.get("layout_kwargs", {})
|
|
87
88
|
|
|
88
89
|
title = (
|
|
89
90
|
f"{kwargs.pop('title')}" if "title" in kwargs else "Equity Price Performance"
|
|
@@ -140,7 +141,6 @@ def etf_price_performance(
|
|
|
140
141
|
|
|
141
142
|
def etf_holdings(**kwargs) -> Tuple[Union[OpenBBFigure, Figure], Dict[str, Any]]:
|
|
142
143
|
"""Equity Compare Groups Chart."""
|
|
143
|
-
|
|
144
144
|
if "data" in kwargs and isinstance(kwargs["data"], pd.DataFrame):
|
|
145
145
|
data = kwargs["data"]
|
|
146
146
|
elif "data" in kwargs and isinstance(kwargs["data"], list):
|
|
@@ -198,7 +198,6 @@ def equity_price_historical( # noqa: PLR0912
|
|
|
198
198
|
**kwargs,
|
|
199
199
|
) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
200
200
|
"""Equity Price Historical Chart."""
|
|
201
|
-
|
|
202
201
|
if "data" in kwargs and isinstance(kwargs["data"], pd.DataFrame):
|
|
203
202
|
data = kwargs["data"]
|
|
204
203
|
elif "data" in kwargs and isinstance(kwargs["data"], list):
|
|
@@ -406,7 +405,7 @@ def equity_price_historical( # noqa: PLR0912
|
|
|
406
405
|
name=data[col].name,
|
|
407
406
|
mode="lines",
|
|
408
407
|
hovertemplate=hovertemplate,
|
|
409
|
-
line=dict(width=
|
|
408
|
+
line=dict(width=2, color=LARGE_CYCLER[i % len(LARGE_CYCLER)]),
|
|
410
409
|
yaxis=yaxis,
|
|
411
410
|
)
|
|
412
411
|
|
|
@@ -512,7 +511,6 @@ def crypto_price_historical(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
|
512
511
|
|
|
513
512
|
def _ta_ma(**kwargs):
|
|
514
513
|
"""Plot moving average helper."""
|
|
515
|
-
|
|
516
514
|
index = (
|
|
517
515
|
kwargs.get("index")
|
|
518
516
|
if "index" in kwargs and kwargs.get("index") is not None
|
|
@@ -587,8 +585,6 @@ def _ta_ma(**kwargs):
|
|
|
587
585
|
ma_df = ma_df.dropna()
|
|
588
586
|
data = data.iloc[-len(ma_df) :]
|
|
589
587
|
|
|
590
|
-
color = 0
|
|
591
|
-
|
|
592
588
|
if (
|
|
593
589
|
"candles" in kwargs
|
|
594
590
|
and kwargs.get("candles") is True
|
|
@@ -600,7 +596,7 @@ def _ta_ma(**kwargs):
|
|
|
600
596
|
else:
|
|
601
597
|
ma_df[f"{target}".title()] = data[target]
|
|
602
598
|
|
|
603
|
-
for col in ma_df.columns:
|
|
599
|
+
for i, col in enumerate(ma_df.columns):
|
|
604
600
|
name = col.replace("_", " ")
|
|
605
601
|
fig.add_scatter(
|
|
606
602
|
x=ma_df.index,
|
|
@@ -608,10 +604,9 @@ def _ta_ma(**kwargs):
|
|
|
608
604
|
name=name,
|
|
609
605
|
mode="lines",
|
|
610
606
|
hovertemplate=f"{name}: %{{y}}<extra></extra>",
|
|
611
|
-
line=dict(width=1, color=LARGE_CYCLER[
|
|
607
|
+
line=dict(width=1, color=LARGE_CYCLER[i]),
|
|
612
608
|
showlegend=True,
|
|
613
609
|
)
|
|
614
|
-
color += 1
|
|
615
610
|
|
|
616
611
|
fig.update_layout(
|
|
617
612
|
title=dict(text=title, x=0.5, font=dict(size=16)),
|
|
@@ -685,7 +680,6 @@ def technical_zlma(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
|
685
680
|
|
|
686
681
|
def technical_aroon(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
687
682
|
"""Technical Aroon Chart."""
|
|
688
|
-
|
|
689
683
|
if "data" in kwargs and isinstance(kwargs["data"], pd.DataFrame):
|
|
690
684
|
data = kwargs["data"]
|
|
691
685
|
else:
|
|
@@ -726,7 +720,6 @@ def technical_aroon(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
|
726
720
|
|
|
727
721
|
def technical_macd(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
728
722
|
"""Plot moving average convergence divergence chart."""
|
|
729
|
-
|
|
730
723
|
if "data" in kwargs and isinstance(kwargs["data"], pd.DataFrame):
|
|
731
724
|
data = kwargs["data"]
|
|
732
725
|
else:
|
|
@@ -765,7 +758,6 @@ def technical_macd(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
|
765
758
|
|
|
766
759
|
def technical_adx(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
767
760
|
"""Average directional movement index chart."""
|
|
768
|
-
|
|
769
761
|
if "data" in kwargs and isinstance(kwargs["data"], pd.DataFrame):
|
|
770
762
|
data = kwargs["data"]
|
|
771
763
|
else:
|
|
@@ -801,7 +793,6 @@ def technical_adx(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
|
801
793
|
|
|
802
794
|
def technical_rsi(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
803
795
|
"""Relative strength index chart."""
|
|
804
|
-
|
|
805
796
|
if "data" in kwargs and isinstance(kwargs["data"], pd.DataFrame):
|
|
806
797
|
data = kwargs["data"]
|
|
807
798
|
else:
|
|
@@ -875,7 +866,6 @@ def technical_cones(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
|
875
866
|
"orange",
|
|
876
867
|
"blue",
|
|
877
868
|
]
|
|
878
|
-
color = 0
|
|
879
869
|
|
|
880
870
|
fig = OpenBBFigure()
|
|
881
871
|
|
|
@@ -883,7 +873,7 @@ def technical_cones(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
|
883
873
|
|
|
884
874
|
text_color = "black" if ChartStyle().plt_style == "light" else "white"
|
|
885
875
|
|
|
886
|
-
for col in df_ta.columns:
|
|
876
|
+
for i, col in enumerate(df_ta.columns):
|
|
887
877
|
fig.add_scatter(
|
|
888
878
|
x=df_ta.index,
|
|
889
879
|
y=df_ta[col],
|
|
@@ -891,11 +881,10 @@ def technical_cones(**kwargs) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
|
891
881
|
mode="lines+markers",
|
|
892
882
|
hovertemplate=f"{col}: %{{y}}<extra></extra>",
|
|
893
883
|
marker=dict(
|
|
894
|
-
color=colors[
|
|
884
|
+
color=colors[i],
|
|
895
885
|
size=11,
|
|
896
886
|
),
|
|
897
887
|
)
|
|
898
|
-
color += 1
|
|
899
888
|
|
|
900
889
|
fig.set_title(title)
|
|
901
890
|
|
|
@@ -1064,7 +1053,7 @@ def economy_fred_series( # noqa: PLR0912
|
|
|
1064
1053
|
if normalize:
|
|
1065
1054
|
y1title = None
|
|
1066
1055
|
title = f"{title} - Normalized" if title else "Normalized"
|
|
1067
|
-
bar_mode = kwargs
|
|
1056
|
+
bar_mode = kwargs.get("barmode", "group")
|
|
1068
1057
|
fig = bar_chart(
|
|
1069
1058
|
df_ta.reset_index(),
|
|
1070
1059
|
"date",
|
|
@@ -1119,7 +1108,7 @@ def economy_fred_series( # noqa: PLR0912
|
|
|
1119
1108
|
name=df_ta[col].name,
|
|
1120
1109
|
mode="lines",
|
|
1121
1110
|
hovertemplate=f"{df_ta[col].name}: %{{y}}<extra></extra>",
|
|
1122
|
-
line=dict(width=
|
|
1111
|
+
line=dict(width=2, color=LARGE_CYCLER[i % len(LARGE_CYCLER)]),
|
|
1123
1112
|
yaxis="y1" if kwargs.get("same_axis") is True else yaxes,
|
|
1124
1113
|
)
|
|
1125
1114
|
|
|
@@ -1228,7 +1217,6 @@ def technical_relative_rotation(
|
|
|
1228
1217
|
**kwargs: Any,
|
|
1229
1218
|
) -> Tuple["OpenBBFigure", Dict[str, Any]]:
|
|
1230
1219
|
"""Relative Rotation Chart."""
|
|
1231
|
-
|
|
1232
1220
|
ratios_df = basemodel_to_df(kwargs["obbject_item"].rs_ratios, index="date") # type: ignore
|
|
1233
1221
|
momentum_df = basemodel_to_df(kwargs["obbject_item"].rs_momentum, index="date") # type: ignore
|
|
1234
1222
|
benchmark_symbol = kwargs["obbject_item"].benchmark # type: ignore
|
|
@@ -1253,7 +1241,7 @@ def technical_relative_rotation(
|
|
|
1253
1241
|
ratios_df, momentum_df, benchmark_symbol, study, date # type: ignore
|
|
1254
1242
|
)
|
|
1255
1243
|
|
|
1256
|
-
figure = OpenBBFigure(fig)
|
|
1244
|
+
figure = OpenBBFigure(fig) # pylint: disable=E0606
|
|
1257
1245
|
font_color = "black" if ChartStyle().plt_style == "light" else "white"
|
|
1258
1246
|
figure.update_layout(
|
|
1259
1247
|
paper_bgcolor="rgba(0,0,0,0)",
|
|
@@ -1292,3 +1280,167 @@ def technical_relative_rotation(
|
|
|
1292
1280
|
content = figure.to_plotly_json()
|
|
1293
1281
|
|
|
1294
1282
|
return figure, content
|
|
1283
|
+
|
|
1284
|
+
|
|
1285
|
+
def fixedincome_government_yield_curve( # noqa: PLR0912
|
|
1286
|
+
**kwargs,
|
|
1287
|
+
) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
1288
|
+
"""Government Yield Curve Chart."""
|
|
1289
|
+
data = kwargs.get("data", None)
|
|
1290
|
+
df: pd.DataFrame = pd.DataFrame()
|
|
1291
|
+
if data:
|
|
1292
|
+
if isinstance(data, pd.DataFrame) and not data.empty: # noqa: SIM108
|
|
1293
|
+
df = data
|
|
1294
|
+
elif isinstance(data, (list, Data)):
|
|
1295
|
+
df = basemodel_to_df(data, index=None) # type: ignore
|
|
1296
|
+
else:
|
|
1297
|
+
pass
|
|
1298
|
+
else:
|
|
1299
|
+
df = pd.DataFrame([d.model_dump() for d in kwargs["obbject_item"]]) # type: ignore
|
|
1300
|
+
|
|
1301
|
+
if df.empty:
|
|
1302
|
+
raise ValueError("Error: No data to plot.")
|
|
1303
|
+
|
|
1304
|
+
if "maturity" not in df.columns:
|
|
1305
|
+
raise ValueError("Error: Maturity column not found in the data.")
|
|
1306
|
+
|
|
1307
|
+
if "rate" not in df.columns:
|
|
1308
|
+
raise ValueError("Error: Rate column not found in the data.")
|
|
1309
|
+
|
|
1310
|
+
if "date" not in df.columns:
|
|
1311
|
+
raise ValueError("Error: Date column not found in the data.")
|
|
1312
|
+
|
|
1313
|
+
provider = kwargs.get("provider")
|
|
1314
|
+
df["date"] = df["date"].astype(str)
|
|
1315
|
+
maturities = duration_sorter(df["maturity"].unique().tolist())
|
|
1316
|
+
|
|
1317
|
+
# Use the supplied colors, if any.
|
|
1318
|
+
colors = kwargs.get("colors", [])
|
|
1319
|
+
if not colors:
|
|
1320
|
+
colors = LARGE_CYCLER
|
|
1321
|
+
color_count = 0
|
|
1322
|
+
|
|
1323
|
+
figure = OpenBBFigure().create_subplots(shared_xaxes=True)
|
|
1324
|
+
figure.update_layout(ChartStyle().plotly_template.get("layout", {}))
|
|
1325
|
+
|
|
1326
|
+
def create_fig(figure, df, dates, color_count, country: Optional[str] = None):
|
|
1327
|
+
"""Create a scatter for each date in the data."""
|
|
1328
|
+
for date in dates:
|
|
1329
|
+
color = colors[color_count % len(colors)]
|
|
1330
|
+
plot_df = df[df["date"] == date].copy()
|
|
1331
|
+
plot_df["rate"] = plot_df["rate"].apply(lambda x: x * 100)
|
|
1332
|
+
plot_df = (
|
|
1333
|
+
plot_df.drop(columns=["date"])
|
|
1334
|
+
.set_index("maturity")
|
|
1335
|
+
.filter(items=maturities, axis=0)
|
|
1336
|
+
.reset_index()
|
|
1337
|
+
.rename(columns={"maturity": "Maturity", "rate": "Yield"})
|
|
1338
|
+
)
|
|
1339
|
+
plot_df["Maturity"] = [
|
|
1340
|
+
(
|
|
1341
|
+
d.split("_")[1] + " " + d.split("_")[0].title()
|
|
1342
|
+
if d != "long_term"
|
|
1343
|
+
else "Long Term"
|
|
1344
|
+
)
|
|
1345
|
+
for d in plot_df["Maturity"]
|
|
1346
|
+
]
|
|
1347
|
+
figure.add_scatter(
|
|
1348
|
+
x=plot_df["Maturity"],
|
|
1349
|
+
y=plot_df["Yield"],
|
|
1350
|
+
# fill=fill,
|
|
1351
|
+
mode="lines+markers",
|
|
1352
|
+
name=f"{country} - {date}" if country else date,
|
|
1353
|
+
line=dict(width=3, color=color),
|
|
1354
|
+
marker=dict(size=10, color=color),
|
|
1355
|
+
hovertemplate=(
|
|
1356
|
+
"Maturity: %{x}<br>Yield: %{y}%<extra></extra>"
|
|
1357
|
+
if len(dates) == 1
|
|
1358
|
+
else "%{fullData.name}<br>Maturity: %{x}<br>Yield: %{y}%<extra></extra>"
|
|
1359
|
+
),
|
|
1360
|
+
)
|
|
1361
|
+
color_count += 1
|
|
1362
|
+
return figure, color_count
|
|
1363
|
+
|
|
1364
|
+
dates = df.date.unique().tolist()
|
|
1365
|
+
figure, color_count = create_fig(figure, df, dates, color_count)
|
|
1366
|
+
extra_params = kwargs.get("extra_params")
|
|
1367
|
+
extra_params = (
|
|
1368
|
+
extra_params if isinstance(extra_params, dict) else extra_params.__dict__
|
|
1369
|
+
)
|
|
1370
|
+
# Set the title for the chart
|
|
1371
|
+
country: str = ""
|
|
1372
|
+
if provider in ("federal_reserve", "fmp"):
|
|
1373
|
+
country = "United States"
|
|
1374
|
+
elif provider == "ecb":
|
|
1375
|
+
curve_type = extra_params.get("yield_curve_type", "").replace("_", " ").title()
|
|
1376
|
+
grade = extra_params.get("rating", "").replace("_", " ")
|
|
1377
|
+
grade = grade.upper() if grade == "aaa" else "All Ratings"
|
|
1378
|
+
country = f"Euro Area ({grade}) {curve_type}"
|
|
1379
|
+
elif provider == "fred":
|
|
1380
|
+
curve_type = extra_params.get("yield_curve_type", "")
|
|
1381
|
+
curve_type = (
|
|
1382
|
+
"Real Rates"
|
|
1383
|
+
if curve_type == "real"
|
|
1384
|
+
else curve_type.replace("_", " ").title()
|
|
1385
|
+
)
|
|
1386
|
+
country = f"United States {curve_type}"
|
|
1387
|
+
elif provider == "econdb":
|
|
1388
|
+
country = extra_params.get("country", "")
|
|
1389
|
+
country = country.replace("_", " ").title() if country else "United States"
|
|
1390
|
+
country = country + " " if country else ""
|
|
1391
|
+
title = kwargs.get("title", "")
|
|
1392
|
+
if not title:
|
|
1393
|
+
title = f"{country}Yield Curve"
|
|
1394
|
+
if len(dates) == 1:
|
|
1395
|
+
title = f"{country} Yield Curve - {dates[0]}"
|
|
1396
|
+
|
|
1397
|
+
# Update the layout of the figure.
|
|
1398
|
+
figure.update_layout(
|
|
1399
|
+
title=dict(text=title, x=0.5, font=dict(size=20)),
|
|
1400
|
+
plot_bgcolor="rgba(255,255,255,0)",
|
|
1401
|
+
xaxis=dict(
|
|
1402
|
+
title="Maturity",
|
|
1403
|
+
ticklen=0,
|
|
1404
|
+
showgrid=False,
|
|
1405
|
+
type="category",
|
|
1406
|
+
categoryorder="array",
|
|
1407
|
+
categoryarray=(
|
|
1408
|
+
[
|
|
1409
|
+
(
|
|
1410
|
+
d.split("_")[1] + " " + d.split("_")[0].title()
|
|
1411
|
+
if d != "long_term"
|
|
1412
|
+
else "Long Term"
|
|
1413
|
+
)
|
|
1414
|
+
for d in maturities
|
|
1415
|
+
]
|
|
1416
|
+
),
|
|
1417
|
+
),
|
|
1418
|
+
yaxis=dict(
|
|
1419
|
+
title="Yield (%)",
|
|
1420
|
+
ticklen=0,
|
|
1421
|
+
showgrid=True,
|
|
1422
|
+
gridcolor="rgba(128,128,128,0.3)",
|
|
1423
|
+
),
|
|
1424
|
+
legend=dict(
|
|
1425
|
+
orientation="v",
|
|
1426
|
+
yanchor="top",
|
|
1427
|
+
xanchor="right",
|
|
1428
|
+
y=0.95,
|
|
1429
|
+
x=0,
|
|
1430
|
+
xref="paper",
|
|
1431
|
+
font=dict(size=12),
|
|
1432
|
+
bgcolor="rgba(0,0,0,0)",
|
|
1433
|
+
),
|
|
1434
|
+
margin=dict(
|
|
1435
|
+
b=25,
|
|
1436
|
+
t=10,
|
|
1437
|
+
),
|
|
1438
|
+
)
|
|
1439
|
+
|
|
1440
|
+
layout_kwargs = kwargs.get("layout_kwargs", {})
|
|
1441
|
+
if layout_kwargs:
|
|
1442
|
+
figure.update_layout(layout_kwargs)
|
|
1443
|
+
|
|
1444
|
+
content = figure.show(external=True)
|
|
1445
|
+
|
|
1446
|
+
return figure, content
|