From 10fd42f785182edfbf6b46a19a4ef66e85985a23 Mon Sep 17 00:00:00 2001 From: David Brazda Date: Wed, 12 Jun 2024 21:28:51 +0200 Subject: [PATCH] xloc support for chart helper --- lightweight_charts/helpers.py | 66 ++++++++++++++++++++++++----------- setup.py | 2 +- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/lightweight_charts/helpers.py b/lightweight_charts/helpers.py index daa82b8..247306a 100644 --- a/lightweight_charts/helpers.py +++ b/lightweight_charts/helpers.py @@ -12,7 +12,7 @@ class Panel: * ohlcv : tuple optional\n (series, entries, exits, other_markers) * histogram : list of tuples, optional.\n - [(series, name, color)] + [(series, name, color, opacity)] * title : str, optional The title of the panel. Default is None. * right : list of tuples, optional @@ -21,6 +21,7 @@ class Panel: * left : list of tuples, optional * middle1 : list of tuples, optional * middle2 : list of tuples, optional + * xloc : str or slice, optional. Vectorbt indexing. Default is None. Examples ------- @@ -28,7 +29,7 @@ class Panel: ``` pane1 = Panel( ohlcv=(), #(series, entries, exits, other_markers) - histogram=[], # [(series, name, "rgba(53, 94, 59, 0.6)")] + histogram=[], # [(series, name, "rgba(53, 94, 59, 0.6)", opacity)] right=[], left=[], #[(series, name, entries, exits, other_markers)] middle1=[], @@ -40,11 +41,12 @@ class Panel: # Synced example pane1 = Panel( ohlcv=(t1data.data["BAC"],), #(series, entries, exits, other_markers) - histogram=[(order_imbalance_allvolume, "oivol")], # [(series, name, "rgba(53, 94, 59, 0.6)")] + histogram=[(order_imbalance_allvolume, "oivol")], # [(series, name, "rgba(53, 94, 59, 0.6)", opacity)] right=[], # [(series, name, entries, exits, other_markers)] left=[(sma, "sma", short_signals, short_exits)], middle1=[], middle2=[], + xloc="2024-02-12 09:30" ) pane2 = Panel( @@ -56,10 +58,10 @@ class Panel: histogram=[(order_imbalance_sma, "oisma")], ) - ch = chart([pane1, pane2], sync=True, title="neco", size="m") + ch = chart([pane1, pane2], sync=True, title="neco", size="m", xloc=slice("2024-02-12 09:30","2024-02-12 16:00")) ``` """ - def __init__(self, ohlcv=None, right=None, left=None, middle1=None, middle2=None, histogram=None, title=None): + def __init__(self, ohlcv=None, right=None, left=None, middle1=None, middle2=None, histogram=None, title=None, xloc=None): self.ohlcv = ohlcv if ohlcv is not None else [] self.right = right if right is not None else [] self.left = left if left is not None else [] @@ -67,11 +69,10 @@ class Panel: self.middle2 = middle2 if middle2 is not None else [] self.histogram = histogram if histogram is not None else [] self.title = title - + self.xloc = xloc - -def chart(panes: list[Panel], sync=False, title='', size="m"): +def chart(panes: list[Panel], sync=False, title='', size="m", xloc=None): """ Function to fast render a chart with multiple panes. This function manipulates graphical output or interfaces with an external framework to display charts with synchronized @@ -92,6 +93,21 @@ def chart(panes: list[Panel], sync=False, title='', size="m"): - 'm' for medium - 'xl' for extra large + * xloc (str): xloc advanced filtering of vbt.xloc accessor. Defaults to None. Applies to all panes. + Might be overriden by pane-specific xloc. + + XLOC Examples: + xloc["2020-01-01 17:30"] + xloc["2020-01-01"] + xloc["2020-01"] + xloc["2020"] + xloc["2020-01-01":"2021-01-01"] + xloc["january":"april"] + xloc["monday":"saturday"] + xloc["09:00":"16:00"] + xloc["16:00":"09:00"] + xloc["monday 09:00":"friday 16:00"] + Returns: None: This function does not return a value. It performs operations to render graphical content. @@ -105,6 +121,7 @@ def chart(panes: list[Panel], sync=False, title='', size="m"): left=[(sma, "sma", short_signals, short_exits)], middle1=[], middle2=[], + xloc=slice("2024-02-12 09:30","2024-02-12 16:00") ) pane2 = Pane( ohlcv=(t1data.data["BAC"],), @@ -114,13 +131,20 @@ def chart(panes: list[Panel], sync=False, title='', size="m"): middle2=[], histogram=[(order_imbalance_sma, "oisma")] ) - ch = chart([pane1, pane2], sync=True, title="Chart", size="l") + ch = chart([pane1, pane2], sync=True, title="Chart", size="l", xloc=slice("2024-02-12 09:30","2024-02-12 16:00")) ``` Notes: ------ """ + + def xloc_me(dfsr, xloc): + if xloc is None: + return dfsr + else: + return dfsr.vbt.xloc[xloc].obj + size_to_dimensions = { 's': (800, 400), 'm': (1000, 600), @@ -136,16 +160,17 @@ def chart(panes: list[Panel], sync=False, title='', size="m"): else: subchartX = chartX.create_subchart(position='right', width=1, height=height_ratio, sync=sync, leftScale=bool(pane.left)) active_chart = subchartX + xloc = pane.xloc if pane.xloc is not None else xloc if pane.ohlcv is not None: series, entries, exits, markers = (pane.ohlcv + (None,) * 4)[:4] - active_chart.set(series) + active_chart.set(xloc_me(series, xloc)) if entries is not None: - active_chart.markers_set(entries, "entries") + active_chart.markers_set(xloc_me(entries, xloc), "entries") if exits is not None: - active_chart.markers_set(exits, "exits") + active_chart.markers_set(xloc_me(exits, xloc), "exits") if markers is not None: - active_chart.markers_set(markers) + active_chart.markers_set(xloc_me(markers, xloc)) for tup in pane.histogram: series, name, color, opacity, _ = (tup + (None, None, None, None, None))[:5] @@ -158,15 +183,15 @@ def chart(panes: list[Panel], sync=False, title='', size="m"): if opacity is not None: kwargs['opacity'] = opacity tmp = active_chart.create_histogram(**kwargs) #green transparent "rgba(53, 94, 59, 0.6)" - tmp.set(series) + tmp.set(xloc_me(series, xloc)) if pane.title is not None: active_chart.topbar.textbox("title",pane.title) main_title_set = True if index==0 else False - #iterate over keys - they are all priceScaleId except of histogram and ohlcv + #iterate over keys - they are all priceScaleId except of these for att_name, att_value_tuple in vars(pane).items(): - if att_name in ["ohlcv","histogram","title"]: + if att_name in ["ohlcv","histogram","title","xloc"]: continue for tup in att_value_tuple: series, name, entries, exits, markers = (tup + (None, None, None, None, None))[:5] @@ -175,6 +200,7 @@ def chart(panes: list[Panel], sync=False, title='', size="m"): #pokud jde o vbt indikator vytahneme vsechny output a predpokladame, ze jde o lines a vykreslime je if is_vbt_indicator(series): + series = series.xloc[xloc] if xloc is not None else series for output in series.output_names: output_series = getattr(series, output) tmp = active_chart.create_line(name=output, priceScaleId=att_name)#, color="blue") @@ -184,14 +210,14 @@ def chart(panes: list[Panel], sync=False, title='', size="m"): name = "no_name" tmp = active_chart.create_line(name=name, priceScaleId=att_name)#, color="blue") - tmp.set(series) + tmp.set(xloc_me(series, xloc)) if entries is not None: - tmp.markers_set(entries, "entries") + tmp.markers_set(xloc_me(entries, xloc), "entries") if exits is not None: - tmp.markers_set(exits, "exits") + tmp.markers_set(xloc_me(exits, xloc), "exits") if markers is not None: - tmp.markers_set(markers) + tmp.markers_set(xloc_me(markers, xloc)) active_chart.legend(True) active_chart.fit() diff --git a/setup.py b/setup.py index e5db9f1..89132a9 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ with open('README.md', 'r', encoding='utf-8') as f: setup( name='lightweight_charts', - version='2.0.18', + version='2.0.19', packages=find_packages(), python_requires='>=3.8', install_requires=[