openbb-charting 2.1.3__tar.gz → 2.2.0__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.3 → openbb_charting-2.2.0}/PKG-INFO +5 -4
- openbb_charting-2.2.0/openbb_charting/__init__.py +25 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/charting.py +86 -49
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/charts/generic_charts.py +39 -26
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/charts/helpers.py +19 -11
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/charts/price_historical.py +22 -17
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/charts/price_performance.py +13 -11
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/charts/relative_rotation.py +18 -10
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/backend.py +71 -54
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/config/openbb_styles.py +5 -4
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/openbb_figure.py +80 -51
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/base.py +18 -7
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/data_classes.py +23 -17
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/ta_class.py +7 -5
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/ta_helpers.py +8 -5
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/to_chart.py +12 -10
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/query_params.py +3 -2
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/pyproject.toml +4 -3
- openbb_charting-2.1.3/openbb_charting/__init__.py +0 -14
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/README.md +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/charts/__init__.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/__init__.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/assets/Terminal_icon.png +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/assets/plotly-2.32.0.min.js +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/chart_style.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/config/__init__.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/dummy_backend.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly.html +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/__init__.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/plugins/__init__.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/plugins/custom_indicators_plugin.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/plugins/momentum_plugin.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/plugins/overlap_plugin.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/plugins/trend_indicators_plugin.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/plugins/volatility_plugin.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/plotly_ta/plugins/volume_plugin.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/core/table.html +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/styles/__init__.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/styles/colors.py +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/styles/default/dark.pltstyle.json +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/styles/default/light.pltstyle.json +0 -0
- {openbb_charting-2.1.3 → openbb_charting-2.2.0}/openbb_charting/styles/default/tables.pltstyle.json +0 -0
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: openbb-charting
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Charting extension for OpenBB
|
|
5
5
|
License: AGPL-3.0-only
|
|
6
6
|
Author: OpenBB Team
|
|
7
7
|
Author-email: hello@openbb.co
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.9,<3.13
|
|
9
9
|
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.9
|
|
13
12
|
Classifier: Programming Language :: Python :: 3.10
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Requires-Dist: nbformat (>=5.9.2,<6.0.0)
|
|
16
|
-
Requires-Dist:
|
|
16
|
+
Requires-Dist: numpy (>=1,<2)
|
|
17
|
+
Requires-Dist: openbb-core (>=1.3.0,<2.0.0)
|
|
17
18
|
Requires-Dist: pandas-ta (>=0.3.14b,<0.4.0)
|
|
18
19
|
Requires-Dist: plotly (>=5.17.0,<6.0.0)
|
|
19
20
|
Requires-Dist: pywry (>=0.6.1,<0.7.0)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""OpenBB OBBject extension for charting."""
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
4
|
+
|
|
5
|
+
from openbb_core.app.model.extension import Extension
|
|
6
|
+
|
|
7
|
+
warnings.filterwarnings(
|
|
8
|
+
"ignore",
|
|
9
|
+
category=UserWarning,
|
|
10
|
+
module="openbb_core.app.model.extension",
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_charting_module():
|
|
15
|
+
"""Get the Charting module."""
|
|
16
|
+
# pylint: disable=import-outside-toplevel
|
|
17
|
+
import importlib
|
|
18
|
+
|
|
19
|
+
_Charting = importlib.import_module("openbb_charting.charting").Charting
|
|
20
|
+
return _Charting
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
ext = Extension(name="charting", description="Create custom charts from OBBject data.")
|
|
24
|
+
|
|
25
|
+
Charting = ext.obbject_accessor(get_charting_module())
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# pylint: disable=too-many-arguments,unused-argument
|
|
4
4
|
|
|
5
5
|
from typing import (
|
|
6
|
+
TYPE_CHECKING,
|
|
6
7
|
Any,
|
|
7
8
|
Callable,
|
|
8
9
|
ClassVar,
|
|
@@ -16,23 +17,23 @@ from typing import (
|
|
|
16
17
|
)
|
|
17
18
|
from warnings import warn
|
|
18
19
|
|
|
19
|
-
import numpy as np
|
|
20
|
-
import pandas as pd
|
|
21
20
|
from importlib_metadata import entry_points
|
|
22
21
|
from openbb_core.app.model.charts.chart import Chart
|
|
23
22
|
from openbb_core.app.model.obbject import OBBject
|
|
24
|
-
from openbb_core.app.utils import basemodel_to_df, convert_to_basemodel
|
|
25
23
|
from openbb_core.provider.abstract.data import Data
|
|
26
|
-
from plotly.graph_objs import Figure
|
|
27
24
|
|
|
28
|
-
from openbb_charting.charts.generic_charts import bar_chart, line_chart
|
|
29
25
|
from openbb_charting.charts.helpers import (
|
|
30
26
|
get_charting_functions,
|
|
31
27
|
get_charting_functions_list,
|
|
32
28
|
)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
from
|
|
29
|
+
|
|
30
|
+
if TYPE_CHECKING:
|
|
31
|
+
from numpy import ndarray # noqa
|
|
32
|
+
from pandas import DataFrame, Series # noqa
|
|
33
|
+
from plotly.graph_objs import Figure # noqa
|
|
34
|
+
from openbb_charting.core.openbb_figure import OpenBBFigure # noqa
|
|
35
|
+
from openbb_charting.query_params import ChartParams # noqa
|
|
36
|
+
from openbb_charting.core.backend import Backend # noqa
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
class Charting:
|
|
@@ -64,18 +65,24 @@ class Charting:
|
|
|
64
65
|
entry_point.load()
|
|
65
66
|
for entry_point in entry_points(group="openbb_charting_extension")
|
|
66
67
|
]
|
|
68
|
+
_format = "plotly" # the charts computed by this extension will be in plotly format
|
|
67
69
|
|
|
68
70
|
def __init__(self, obbject):
|
|
69
71
|
"""Initialize Charting extension."""
|
|
70
72
|
# pylint: disable=import-outside-toplevel
|
|
71
|
-
|
|
73
|
+
import importlib # noqa
|
|
74
|
+
|
|
75
|
+
charting_settings_module = importlib.import_module(
|
|
76
|
+
"openbb_core.app.model.charts.charting_settings", "ChartingSettings"
|
|
77
|
+
)
|
|
78
|
+
ChartingSettings = charting_settings_module.ChartingSettings
|
|
72
79
|
|
|
73
80
|
self._obbject: OBBject = obbject
|
|
74
81
|
self._charting_settings = ChartingSettings(
|
|
75
82
|
user_settings=self._obbject._user_settings, # type: ignore
|
|
76
83
|
system_settings=self._obbject._system_settings, # type: ignore
|
|
77
84
|
)
|
|
78
|
-
self._backend
|
|
85
|
+
self._backend = self._handle_backend()
|
|
79
86
|
self._functions: Dict[str, Callable] = self._get_functions()
|
|
80
87
|
|
|
81
88
|
@classmethod
|
|
@@ -84,6 +91,9 @@ class Charting:
|
|
|
84
91
|
|
|
85
92
|
Without assigning to a variable, it will print the the information to the console.
|
|
86
93
|
"""
|
|
94
|
+
# pylint: disable=import-outside-toplevel
|
|
95
|
+
from openbb_charting.query_params import IndicatorsParams
|
|
96
|
+
|
|
87
97
|
return IndicatorsParams()
|
|
88
98
|
|
|
89
99
|
@classmethod
|
|
@@ -103,8 +113,11 @@ class Charting:
|
|
|
103
113
|
|
|
104
114
|
return functions
|
|
105
115
|
|
|
106
|
-
def _handle_backend(self) -> Backend:
|
|
116
|
+
def _handle_backend(self) -> "Backend":
|
|
107
117
|
"""Create and start the backend."""
|
|
118
|
+
# pylint: disable=import-outside-toplevel
|
|
119
|
+
from openbb_charting.core.backend import create_backend, get_backend
|
|
120
|
+
|
|
108
121
|
create_backend(self._charting_settings)
|
|
109
122
|
backend = get_backend()
|
|
110
123
|
backend.start(debug=self._charting_settings.debug_mode)
|
|
@@ -121,11 +134,15 @@ class Charting:
|
|
|
121
134
|
)
|
|
122
135
|
return self._functions[adjusted_route]
|
|
123
136
|
|
|
124
|
-
def get_params(self) -> ChartParams:
|
|
137
|
+
def get_params(self) -> Union["ChartParams", None]:
|
|
125
138
|
"""Return the ChartQueryParams class for the function the OBBject was created from.
|
|
126
139
|
|
|
127
140
|
Without assigning to a variable, it will print the docstring to the console.
|
|
141
|
+
If the class is not defined, the help for the function will be returned.
|
|
128
142
|
"""
|
|
143
|
+
# pylint: disable=import-outside-toplevel
|
|
144
|
+
from openbb_charting.query_params import ChartParams
|
|
145
|
+
|
|
129
146
|
if self._obbject._route is None: # pylint: disable=protected-access
|
|
130
147
|
raise ValueError("OBBject was initialized with no function route.")
|
|
131
148
|
charting_function = (
|
|
@@ -133,23 +150,32 @@ class Charting:
|
|
|
133
150
|
).replace("/", "_")[1:]
|
|
134
151
|
if hasattr(ChartParams, charting_function):
|
|
135
152
|
return getattr(ChartParams, charting_function)()
|
|
136
|
-
|
|
137
|
-
|
|
153
|
+
|
|
154
|
+
return help( # type: ignore
|
|
155
|
+
self._get_chart_function( # pylint: disable=protected-access
|
|
156
|
+
self._obbject.extra[ # pylint: disable=protected-access
|
|
157
|
+
"metadata"
|
|
158
|
+
].route
|
|
159
|
+
)
|
|
138
160
|
)
|
|
139
161
|
|
|
140
162
|
def _prepare_data_as_df(
|
|
141
|
-
self, data: Optional[Union[
|
|
142
|
-
) -> Tuple[
|
|
163
|
+
self, data: Optional[Union["DataFrame", "Series"]]
|
|
164
|
+
) -> Tuple["DataFrame", bool]:
|
|
143
165
|
"""Convert supplied data to a DataFrame."""
|
|
166
|
+
# pylint: disable=import-outside-toplevel
|
|
167
|
+
from openbb_core.app.utils import basemodel_to_df, convert_to_basemodel
|
|
168
|
+
from pandas import DataFrame, Series
|
|
169
|
+
|
|
144
170
|
has_data = (
|
|
145
|
-
isinstance(data, (Data,
|
|
171
|
+
isinstance(data, (Data, DataFrame, Series)) and not data.empty # type: ignore
|
|
146
172
|
) or (bool(data))
|
|
147
173
|
index = (
|
|
148
174
|
data.index.name
|
|
149
|
-
if has_data and isinstance(data, (
|
|
175
|
+
if has_data and isinstance(data, (DataFrame, Series))
|
|
150
176
|
else None
|
|
151
177
|
)
|
|
152
|
-
data_as_df:
|
|
178
|
+
data_as_df: DataFrame = (
|
|
153
179
|
basemodel_to_df(convert_to_basemodel(data), index=index)
|
|
154
180
|
if has_data
|
|
155
181
|
else self._obbject.to_dataframe(index=index)
|
|
@@ -166,11 +192,11 @@ class Charting:
|
|
|
166
192
|
data: Union[
|
|
167
193
|
list,
|
|
168
194
|
dict,
|
|
169
|
-
|
|
170
|
-
List[
|
|
171
|
-
|
|
172
|
-
List[
|
|
173
|
-
|
|
195
|
+
"DataFrame",
|
|
196
|
+
List["DataFrame"],
|
|
197
|
+
"Series",
|
|
198
|
+
List["Series"],
|
|
199
|
+
"ndarray",
|
|
174
200
|
Data,
|
|
175
201
|
],
|
|
176
202
|
index: Optional[str] = None,
|
|
@@ -189,12 +215,12 @@ class Charting:
|
|
|
189
215
|
same_axis: bool = False,
|
|
190
216
|
render: bool = True,
|
|
191
217
|
**kwargs,
|
|
192
|
-
) -> Union[OpenBBFigure, Figure, None]:
|
|
218
|
+
) -> Union["OpenBBFigure", "Figure", None]:
|
|
193
219
|
"""Create a line chart from external data and render a chart or return the OpenBBFigure.
|
|
194
220
|
|
|
195
221
|
Parameters
|
|
196
222
|
----------
|
|
197
|
-
data : Union[Data,
|
|
223
|
+
data : Union[Data, DataFrame, Series]
|
|
198
224
|
Data to be plotted (OHLCV data).
|
|
199
225
|
index : Optional[str], optional
|
|
200
226
|
Index column, by default None
|
|
@@ -232,6 +258,9 @@ class Charting:
|
|
|
232
258
|
**kwargs: Dict[str, Any]
|
|
233
259
|
Extra parameters to be passed to `figure.show()`
|
|
234
260
|
"""
|
|
261
|
+
# pylint: disable=import-outside-toplevel
|
|
262
|
+
from openbb_charting.charts.generic_charts import line_chart
|
|
263
|
+
|
|
235
264
|
fig = line_chart(
|
|
236
265
|
data=data,
|
|
237
266
|
index=index,
|
|
@@ -261,11 +290,11 @@ class Charting:
|
|
|
261
290
|
data: Union[
|
|
262
291
|
list,
|
|
263
292
|
dict,
|
|
264
|
-
|
|
265
|
-
List[
|
|
266
|
-
|
|
267
|
-
List[
|
|
268
|
-
|
|
293
|
+
"DataFrame",
|
|
294
|
+
List["DataFrame"],
|
|
295
|
+
"Series",
|
|
296
|
+
List["Series"],
|
|
297
|
+
"ndarray",
|
|
269
298
|
Data,
|
|
270
299
|
],
|
|
271
300
|
x: str,
|
|
@@ -283,12 +312,12 @@ class Charting:
|
|
|
283
312
|
bar_kwargs: Optional[Dict[str, Any]] = None,
|
|
284
313
|
render: bool = True,
|
|
285
314
|
**kwargs,
|
|
286
|
-
) -> Union[OpenBBFigure, Figure, None]:
|
|
315
|
+
) -> Union["OpenBBFigure", "Figure", None]:
|
|
287
316
|
"""Create a bar chart on a single x-axis with one or more values for the y-axis.
|
|
288
317
|
|
|
289
318
|
Parameters
|
|
290
319
|
----------
|
|
291
|
-
data : Union[list, dict,
|
|
320
|
+
data : Union[list, dict, DataFrame, List[DataFrame], Series, List[Series], ndarray, Data]
|
|
292
321
|
Data to plot.
|
|
293
322
|
x : str
|
|
294
323
|
The x-axis column name.
|
|
@@ -315,6 +344,9 @@ class Charting:
|
|
|
315
344
|
OpenBBFigure
|
|
316
345
|
The OpenBBFigure object.
|
|
317
346
|
"""
|
|
347
|
+
# pylint: disable=import-outside-toplevel
|
|
348
|
+
from openbb_charting.charts.generic_charts import bar_chart
|
|
349
|
+
|
|
318
350
|
fig = bar_chart(
|
|
319
351
|
data=data,
|
|
320
352
|
x=x,
|
|
@@ -355,7 +387,7 @@ class Charting:
|
|
|
355
387
|
fig, content = charting_function(**kwargs)
|
|
356
388
|
fig = self._set_chart_style(fig)
|
|
357
389
|
content = fig.show(external=True, **kwargs).to_plotly_json()
|
|
358
|
-
self._obbject.chart = Chart(fig=fig, content=content)
|
|
390
|
+
self._obbject.chart = Chart(fig=fig, content=content, format=self._format)
|
|
359
391
|
if render:
|
|
360
392
|
fig.show(**kwargs)
|
|
361
393
|
except Exception: # pylint: disable=W0718
|
|
@@ -363,7 +395,9 @@ class Charting:
|
|
|
363
395
|
fig = self.create_line_chart(data=self._obbject.results, render=False, **kwargs) # type: ignore
|
|
364
396
|
fig = self._set_chart_style(fig)
|
|
365
397
|
content = fig.show(external=True, **kwargs).to_plotly_json() # type: ignore
|
|
366
|
-
self._obbject.chart = Chart(
|
|
398
|
+
self._obbject.chart = Chart(
|
|
399
|
+
fig=fig, content=content, format=self._format
|
|
400
|
+
)
|
|
367
401
|
if render:
|
|
368
402
|
return fig.show(**kwargs) # type: ignore
|
|
369
403
|
except Exception as e:
|
|
@@ -378,11 +412,11 @@ class Charting:
|
|
|
378
412
|
Union[
|
|
379
413
|
list,
|
|
380
414
|
dict,
|
|
381
|
-
|
|
382
|
-
List[
|
|
383
|
-
|
|
384
|
-
List[
|
|
385
|
-
|
|
415
|
+
"DataFrame",
|
|
416
|
+
List["DataFrame"],
|
|
417
|
+
"Series",
|
|
418
|
+
List["Series"],
|
|
419
|
+
"ndarray",
|
|
386
420
|
Data,
|
|
387
421
|
]
|
|
388
422
|
] = None,
|
|
@@ -404,7 +438,7 @@ class Charting:
|
|
|
404
438
|
|
|
405
439
|
Parameters
|
|
406
440
|
----------
|
|
407
|
-
data : Union[Data,
|
|
441
|
+
data : Union[Data, DataFrame, Series]
|
|
408
442
|
Data to be plotted.
|
|
409
443
|
indicators : Dict[str, Dict[str, Any]], optional
|
|
410
444
|
Indicators to be plotted, by default None
|
|
@@ -474,7 +508,9 @@ class Charting:
|
|
|
474
508
|
fig = self.create_line_chart(data=data_as_df, render=False, **kwargs)
|
|
475
509
|
fig = self._set_chart_style(fig)
|
|
476
510
|
content = fig.show(external=True, **kwargs).to_plotly_json() # type: ignore
|
|
477
|
-
self._obbject.chart = Chart(
|
|
511
|
+
self._obbject.chart = Chart(
|
|
512
|
+
fig=fig, content=content, format=self._format
|
|
513
|
+
)
|
|
478
514
|
if render:
|
|
479
515
|
return fig.show(**kwargs) # type: ignore
|
|
480
516
|
except Exception as e: # pylint: disable=W0718
|
|
@@ -482,7 +518,7 @@ class Charting:
|
|
|
482
518
|
"Failed to automatically create a generic chart with the data provided."
|
|
483
519
|
) from e
|
|
484
520
|
|
|
485
|
-
def _set_chart_style(self, figure: Figure):
|
|
521
|
+
def _set_chart_style(self, figure: "Figure"):
|
|
486
522
|
"""Set the user preference for light or dark mode."""
|
|
487
523
|
style = self._charting_settings.chart_style
|
|
488
524
|
font_color = "black" if style == "light" else "white"
|
|
@@ -512,21 +548,24 @@ class Charting:
|
|
|
512
548
|
|
|
513
549
|
def table(
|
|
514
550
|
self,
|
|
515
|
-
data: Optional[Union[
|
|
551
|
+
data: Optional[Union["DataFrame", "Series"]] = None,
|
|
516
552
|
title: str = "",
|
|
517
553
|
):
|
|
518
554
|
"""Display an interactive table.
|
|
519
555
|
|
|
520
556
|
Parameters
|
|
521
557
|
----------
|
|
522
|
-
data : Optional[Union[
|
|
558
|
+
data : Optional[Union[DataFrame, Series]], optional
|
|
523
559
|
Data to be plotted, by default None.
|
|
524
560
|
If no data is provided the OBBject results will be used.
|
|
525
561
|
title : str, optional
|
|
526
562
|
Title of the table, by default "".
|
|
527
563
|
"""
|
|
564
|
+
# pylint: disable=import-outside-toplevel
|
|
565
|
+
from pandas import RangeIndex
|
|
566
|
+
|
|
528
567
|
data_as_df, _ = self._prepare_data_as_df(data)
|
|
529
|
-
if isinstance(data_as_df.index,
|
|
568
|
+
if isinstance(data_as_df.index, RangeIndex):
|
|
530
569
|
data_as_df.reset_index(inplace=True, drop=True)
|
|
531
570
|
else:
|
|
532
571
|
data_as_df.reset_index(inplace=True)
|
|
@@ -542,9 +581,7 @@ class Charting:
|
|
|
542
581
|
warn(f"Failed to show figure with backend. {e}")
|
|
543
582
|
|
|
544
583
|
else:
|
|
545
|
-
from plotly import
|
|
546
|
-
optional_imports,
|
|
547
|
-
)
|
|
584
|
+
from plotly import optional_imports
|
|
548
585
|
|
|
549
586
|
ipython_display = optional_imports.get_module("IPython.display")
|
|
550
587
|
if ipython_display:
|
|
@@ -2,13 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
# pylint: disable=too-many-arguments,unused-argument,too-many-locals, too-many-branches, too-many-lines, too-many-statements, use-dict-literal, broad-exception-caught, too-many-nested-blocks
|
|
4
4
|
|
|
5
|
-
from typing import Any, Dict, List, Literal, Optional, Union
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Union
|
|
6
6
|
|
|
7
|
-
import numpy as np
|
|
8
|
-
import pandas as pd
|
|
9
7
|
from openbb_core.app.utils import basemodel_to_df, convert_to_basemodel
|
|
10
8
|
from openbb_core.provider.abstract.data import Data
|
|
11
|
-
from plotly.graph_objs import Figure
|
|
12
9
|
|
|
13
10
|
from openbb_charting.charts.helpers import (
|
|
14
11
|
calculate_returns,
|
|
@@ -16,19 +13,24 @@ from openbb_charting.charts.helpers import (
|
|
|
16
13
|
z_score_standardization,
|
|
17
14
|
)
|
|
18
15
|
from openbb_charting.core.chart_style import ChartStyle
|
|
19
|
-
from openbb_charting.core.openbb_figure import OpenBBFigure
|
|
20
16
|
from openbb_charting.styles.colors import LARGE_CYCLER
|
|
21
17
|
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from numpy import ndarray # noqa
|
|
20
|
+
from pandas import DataFrame, Series # noqa
|
|
21
|
+
from plotly.graph_objs import Figure # noqa
|
|
22
|
+
from openbb_charting.core.openbb_figure import OpenBBFigure # noqa
|
|
23
|
+
|
|
22
24
|
|
|
23
25
|
def line_chart( # noqa: PLR0912
|
|
24
26
|
data: Union[
|
|
25
27
|
list,
|
|
26
28
|
dict,
|
|
27
|
-
|
|
28
|
-
List[
|
|
29
|
-
|
|
30
|
-
List[
|
|
31
|
-
|
|
29
|
+
"DataFrame",
|
|
30
|
+
List["DataFrame"],
|
|
31
|
+
"Series",
|
|
32
|
+
List["Series"],
|
|
33
|
+
"ndarray",
|
|
32
34
|
Data,
|
|
33
35
|
],
|
|
34
36
|
index: Optional[str] = None,
|
|
@@ -46,31 +48,35 @@ def line_chart( # noqa: PLR0912
|
|
|
46
48
|
returns: bool = False,
|
|
47
49
|
same_axis: bool = False,
|
|
48
50
|
**kwargs,
|
|
49
|
-
) -> Union[OpenBBFigure, Figure]:
|
|
51
|
+
) -> Union["OpenBBFigure", "Figure"]:
|
|
50
52
|
"""Create a line chart."""
|
|
53
|
+
# pylint: disable=import-outside-toplevel
|
|
54
|
+
from pandas import DataFrame, Series, to_datetime # noqa
|
|
55
|
+
from openbb_charting.core.openbb_figure import OpenBBFigure # noqa
|
|
56
|
+
|
|
51
57
|
if data is None:
|
|
52
58
|
raise ValueError("Error: Data is a required field.")
|
|
53
59
|
|
|
54
60
|
auto_layout = False
|
|
55
61
|
index = (
|
|
56
62
|
data.index.name
|
|
57
|
-
if isinstance(data, (
|
|
63
|
+
if isinstance(data, (DataFrame, Series))
|
|
58
64
|
else index if index is not None else x if x is not None else "date"
|
|
59
65
|
)
|
|
60
|
-
df:
|
|
61
|
-
|
|
62
|
-
)
|
|
66
|
+
df: DataFrame = (basemodel_to_df(convert_to_basemodel(data), index=index)).dropna(
|
|
67
|
+
how="all", axis=1
|
|
68
|
+
)
|
|
63
69
|
|
|
64
70
|
if df.index.name is None:
|
|
65
71
|
if "date" in df.columns:
|
|
66
|
-
df.date = df.date.apply(
|
|
72
|
+
df.date = df.date.apply(to_datetime)
|
|
67
73
|
df.set_index("date", inplace=True)
|
|
68
74
|
else:
|
|
69
75
|
found_index = False
|
|
70
76
|
for col in df.columns:
|
|
71
77
|
if df[col].dtype == "object":
|
|
72
78
|
try:
|
|
73
|
-
df[col] = df[col].apply(
|
|
79
|
+
df[col] = df[col].apply(to_datetime)
|
|
74
80
|
index = df[col].name # type: ignore
|
|
75
81
|
df.set_index(col, inplace=True)
|
|
76
82
|
df.index.name = "date"
|
|
@@ -326,11 +332,11 @@ def bar_chart( # noqa: PLR0912
|
|
|
326
332
|
data: Union[
|
|
327
333
|
list,
|
|
328
334
|
dict,
|
|
329
|
-
|
|
330
|
-
List[
|
|
331
|
-
|
|
332
|
-
List[
|
|
333
|
-
|
|
335
|
+
"DataFrame",
|
|
336
|
+
List["DataFrame"],
|
|
337
|
+
"Series",
|
|
338
|
+
List["Series"],
|
|
339
|
+
"ndarray",
|
|
334
340
|
Data,
|
|
335
341
|
],
|
|
336
342
|
x: str,
|
|
@@ -345,13 +351,13 @@ def bar_chart( # noqa: PLR0912
|
|
|
345
351
|
bar_kwargs: Optional[Dict[str, Any]] = None,
|
|
346
352
|
layout_kwargs: Optional[Dict[str, Any]] = None,
|
|
347
353
|
**kwargs,
|
|
348
|
-
) -> Union[OpenBBFigure, Figure]:
|
|
354
|
+
) -> Union["OpenBBFigure", "Figure"]:
|
|
349
355
|
"""Create a vertical bar chart on a single x-axis with one or more values for the y-axis.
|
|
350
356
|
|
|
351
357
|
Parameters
|
|
352
358
|
----------
|
|
353
359
|
data : Union[
|
|
354
|
-
list, dict,
|
|
360
|
+
list, dict, "DataFrame", List["DataFrame"], "Series", List["Series"], "ndarray", Data
|
|
355
361
|
]
|
|
356
362
|
Data to plot.
|
|
357
363
|
x : str
|
|
@@ -380,6 +386,9 @@ def bar_chart( # noqa: PLR0912
|
|
|
380
386
|
OpenBBFigure
|
|
381
387
|
The OpenBBFigure object.
|
|
382
388
|
"""
|
|
389
|
+
# pylint: disable=import-outside-toplevel
|
|
390
|
+
from openbb_charting.core.openbb_figure import OpenBBFigure
|
|
391
|
+
|
|
383
392
|
try:
|
|
384
393
|
figure = OpenBBFigure()
|
|
385
394
|
except Exception as _:
|
|
@@ -492,7 +501,7 @@ def bar_increasing_decreasing( # pylint: disable=W0102
|
|
|
492
501
|
orientation: Literal["h", "v"] = "h",
|
|
493
502
|
barmode: Literal["group", "stack", "relative", "overlay"] = "relative",
|
|
494
503
|
layout_kwargs: Optional[Dict[str, Any]] = None,
|
|
495
|
-
) -> Union[OpenBBFigure, Figure]:
|
|
504
|
+
) -> Union["OpenBBFigure", "Figure"]:
|
|
496
505
|
"""Create a bar chart with increasing and decreasing values represented by two colors.
|
|
497
506
|
|
|
498
507
|
Parameters
|
|
@@ -521,6 +530,10 @@ def bar_increasing_decreasing( # pylint: disable=W0102
|
|
|
521
530
|
OpenBBFigure
|
|
522
531
|
The OpenBBFigure object.
|
|
523
532
|
"""
|
|
533
|
+
# pylint: disable=import-outside-toplevel
|
|
534
|
+
from openbb_charting.core.openbb_figure import OpenBBFigure # noqa
|
|
535
|
+
from pandas import Series # noqa
|
|
536
|
+
|
|
524
537
|
try:
|
|
525
538
|
figure = OpenBBFigure()
|
|
526
539
|
except Exception as _:
|
|
@@ -538,7 +551,7 @@ def bar_increasing_decreasing( # pylint: disable=W0102
|
|
|
538
551
|
# figure.update_layout(ChartStyle().plotly_template.get("layout", {}))
|
|
539
552
|
|
|
540
553
|
try:
|
|
541
|
-
data =
|
|
554
|
+
data = Series(data=values, index=keys)
|
|
542
555
|
increasing_data = data[data > 0] # type: ignore
|
|
543
556
|
decreasing_data = data[data < 0] # type: ignore
|
|
544
557
|
except Exception as e:
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
"""Helper functions for charting."""
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
from typing import Callable, Dict, List, Type
|
|
3
|
+
from typing import TYPE_CHECKING, Callable, Dict, List, Type
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
from
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from pandas import DataFrame, Series
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
def get_charting_functions(view: Type) -> Dict[str, Callable]:
|
|
11
10
|
"""Discover charting functions."""
|
|
11
|
+
# pylint: disable=import-outside-toplevel
|
|
12
|
+
from inspect import getmembers, getsource, isfunction
|
|
13
|
+
|
|
12
14
|
implemented_functions: Dict[str, Callable] = {}
|
|
13
15
|
|
|
14
16
|
for name, obj in getmembers(view, isfunction):
|
|
@@ -27,22 +29,25 @@ def get_charting_functions_list(view: Type) -> List[str]:
|
|
|
27
29
|
return list(get_charting_functions(view).keys())
|
|
28
30
|
|
|
29
31
|
|
|
30
|
-
def z_score_standardization(data:
|
|
32
|
+
def z_score_standardization(data: "Series") -> "Series":
|
|
31
33
|
"""Z-Score Standardization Method."""
|
|
32
34
|
return (data - data.mean()) / data.std()
|
|
33
35
|
|
|
34
36
|
|
|
35
|
-
def calculate_returns(data:
|
|
37
|
+
def calculate_returns(data: "Series") -> "Series":
|
|
36
38
|
"""Calculate the returns of a column."""
|
|
37
39
|
return ((1 + data.pct_change().dropna()).cumprod() - 1) * 100
|
|
38
40
|
|
|
39
41
|
|
|
40
42
|
def should_share_axis(
|
|
41
|
-
df:
|
|
43
|
+
df: "DataFrame", col1: str, col2: str, threshold: float = 0.15
|
|
42
44
|
) -> bool:
|
|
43
45
|
"""Determine whether two columns should share an axis."""
|
|
46
|
+
# pylint: disable=import-outside-toplevel
|
|
47
|
+
from pandas import Series
|
|
48
|
+
|
|
44
49
|
try:
|
|
45
|
-
if isinstance(df,
|
|
50
|
+
if isinstance(df, Series):
|
|
46
51
|
df = df.to_frame()
|
|
47
52
|
range1 = df[col1].max() - df[col1].min()
|
|
48
53
|
range2 = df[col2].max() - df[col2].min()
|
|
@@ -56,19 +61,22 @@ def should_share_axis(
|
|
|
56
61
|
return False
|
|
57
62
|
|
|
58
63
|
|
|
59
|
-
def heikin_ashi(data:
|
|
64
|
+
def heikin_ashi(data: "DataFrame") -> "DataFrame":
|
|
60
65
|
"""Return OHLC data as Heikin Ashi Candles.
|
|
61
66
|
|
|
62
67
|
Parameters
|
|
63
68
|
----------
|
|
64
|
-
data:
|
|
69
|
+
data: DataFrame
|
|
65
70
|
DataFrame containing OHLC data.
|
|
66
71
|
|
|
67
72
|
Returns
|
|
68
73
|
-------
|
|
69
|
-
|
|
74
|
+
DataFrame
|
|
70
75
|
DataFrame copy with Heikin Ashi candle calculations.
|
|
71
76
|
"""
|
|
77
|
+
# pylint: disable=import-outside-toplevel
|
|
78
|
+
from pandas_ta import candles
|
|
79
|
+
|
|
72
80
|
df = data.copy()
|
|
73
81
|
|
|
74
82
|
check_columns = ["open", "high", "low", "close"]
|
|
@@ -1,29 +1,34 @@
|
|
|
1
1
|
"""Price historical charting utility."""
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
from
|
|
7
|
-
|
|
8
|
-
from openbb_charting.charts.helpers import (
|
|
9
|
-
calculate_returns,
|
|
10
|
-
heikin_ashi,
|
|
11
|
-
should_share_axis,
|
|
12
|
-
z_score_standardization,
|
|
13
|
-
)
|
|
14
|
-
from openbb_charting.core.chart_style import ChartStyle
|
|
15
|
-
from openbb_charting.core.openbb_figure import OpenBBFigure
|
|
16
|
-
from openbb_charting.core.plotly_ta.ta_class import PlotlyTA
|
|
3
|
+
# pylint: disable=too-many-branches, too-many-locals, unused-argument
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Dict, Tuple
|
|
7
|
+
|
|
17
8
|
from openbb_charting.styles.colors import LARGE_CYCLER
|
|
18
9
|
|
|
19
|
-
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from openbb_charting.core.openbb_figure import OpenBBFigure
|
|
20
12
|
|
|
21
13
|
|
|
22
14
|
def price_historical( # noqa: PLR0912
|
|
23
15
|
**kwargs,
|
|
24
|
-
) -> Tuple[OpenBBFigure, Dict[str, Any]]:
|
|
16
|
+
) -> Tuple["OpenBBFigure", Dict[str, Any]]:
|
|
25
17
|
"""Equity Price Historical Chart."""
|
|
26
|
-
|
|
18
|
+
# pylint: disable=import-outside-toplevel
|
|
19
|
+
from pandas import DataFrame # noqa
|
|
20
|
+
from openbb_core.app.utils import basemodel_to_df # noqa
|
|
21
|
+
from openbb_charting.core.openbb_figure import OpenBBFigure # noqa
|
|
22
|
+
from openbb_charting.core.plotly_ta.ta_class import PlotlyTA # noqa
|
|
23
|
+
from openbb_charting.core.chart_style import ChartStyle # noqa
|
|
24
|
+
from openbb_charting.charts.helpers import ( # noqa
|
|
25
|
+
calculate_returns,
|
|
26
|
+
heikin_ashi,
|
|
27
|
+
should_share_axis,
|
|
28
|
+
z_score_standardization,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
if "data" in kwargs and isinstance(kwargs["data"], DataFrame):
|
|
27
32
|
data = kwargs["data"]
|
|
28
33
|
elif "data" in kwargs and isinstance(kwargs["data"], list):
|
|
29
34
|
data = basemodel_to_df(kwargs["data"], index=kwargs.get("index", "date")) # type: ignore
|