Refactoring/Enhancements/Fixes
Breaking Changes:
- Removed the `api` parameter; callbacks no longer need to be in a specific class.
- Topbar callbacks now take a chart as an argument (see updated callback examples)
- Removed the `topbar` parameter from chart declaration. The Topbar will be automatically created upon declaration of a topbar widget.
- Removed the `searchbox` parameter from charts. It will be created upon subscribing to it in `chart.events`.
- Removed `dynamic_loading`.
- Removed ‘volume_enabled’ parameter. Volume will be enabled if the volumn column is present in the dataframe.
- Widgets’ `func` parameter is now declared last.
- Switchers take a tuple of options rather than a variable number of arguments.
- `add_hotkey` renamed to `hotkey`
- Horizontal lines now take a `func` argument rather than `interactive`. This event will emit the Line object that was moved.
- Removed the `name` parameter from `line.set`. Line object names are now declared upon creation.
Enhancements:
- Added the `button` widget to the Topbar.
- Added the color picker to the drawing context menu.
- Charts now have a `candle_data` method, which returns the current data displayed on the chart as a DataFrame.
- Fixed callbacks are now located in the `chart.events` object:
- search (e.g `chart.events.search += on_search`)
- new_bar
- range_change
- Added volume to the legend
- Drawings can now be accessed through `chart.toolbox.drawings`
- added the `style` and `name` parameters to `create_line`
Bug Fixes:
- Fixed a bug causing new charts not to load after `exit` was called.
- Refactored rayline placement to ensure they do not move the visible range.
- Fixed a bug causing the visible range to shift when trendlines are moved past the final candlestick.
- Fixed a bug preventing trendlines and raylines on irregular timeframes.
- Fixed a bug causing the legend to prevent mouse input into the chart.
This commit is contained in:
@ -1,74 +1,92 @@
|
||||
# Callbacks
|
||||
# Events
|
||||
|
||||
The `Chart` object allows for asynchronous and synchronous callbacks to be passed back to python, allowing for more sophisticated chart layouts including searching, timeframe selectors text boxes, and hotkeys using the `add_hotkey` method.
|
||||
|
||||
`QtChart`and `WxChart` can also use callbacks.
|
||||
|
||||
A variety of the parameters below should be passed to the Chart upon decaration.
|
||||
* `api`: The class object that the fixed callbacks will always be emitted to.
|
||||
* `topbar`: Adds a [TopBar](#topbar) to the `Chart` or `SubChart` and allows use of the `create_switcher` method.
|
||||
* `searchbox`: Adds a search box onto the `Chart` or `SubChart` that is activated by typing.
|
||||
Events allow asynchronous and synchronous callbacks to be passed back into python.
|
||||
|
||||
___
|
||||
## How to use Callbacks
|
||||
## `chart.events`
|
||||
|
||||
Fixed Callbacks are emitted to the class given as the `api` parameter shown above.
|
||||
`events.search` `->` `chart` | `string`: Fires upon searching. Searchbox will be automatically created.
|
||||
|
||||
`events.new_bar` `->` `chart`: Fires when a new candlestick is added to the chart.
|
||||
|
||||
`events.range_change` `->` `chart` | `bars_before` | `bars_after`: Fires when the range (visibleLogicalRange) changes.
|
||||
|
||||
Chart events can be subscribed to using: `chart.events.<name> += <callable>`
|
||||
___
|
||||
|
||||
## How to use Events
|
||||
|
||||
Take a look at this minimal example:
|
||||
|
||||
```python
|
||||
class API:
|
||||
def __init__(self):
|
||||
self.chart = None
|
||||
from lightweight_charts import Chart
|
||||
|
||||
|
||||
def on_search(chart, string):
|
||||
print(f'Search Text: "{string}" | Chart/SubChart ID: "{chart.id}"')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
chart = Chart()
|
||||
chart.events.search += on_search
|
||||
chart.show(block=True)
|
||||
|
||||
def on_search(self, string):
|
||||
print(f'Search Text: "{string}" | Chart/SubChart ID: "{self.chart.id}"')
|
||||
```
|
||||
Upon searching in a pane, the expected output would be akin to:
|
||||
```
|
||||
Search Text: "AAPL" | Chart/SubChart ID: "window.blyjagcr"
|
||||
```
|
||||
The ID shown above will change depending upon which pane was used to search, due to the instance of `self.chart` dynamically updating to the latest pane which triggered the callback.
|
||||
`self.chart` will update upon each callback, allowing for access to the specific pane in question.
|
||||
The ID shown above will change depending upon which pane was used to search, allowing for access to the object in question.
|
||||
|
||||
```{important}
|
||||
* When using `show` rather than `show_async`, block should be set to `True` (`chart.show(block=True)`).
|
||||
* `API` class methods can be either coroutines or normal methods.
|
||||
* Non fixed callbacks (switchers, hotkeys) can be methods, coroutines, or regular functions.
|
||||
* Event callables can be either coroutines, methods, or functions.
|
||||
```
|
||||
|
||||
There are certain callbacks which are always emitted to a specifically named method of API:
|
||||
* Search callbacks: `on_search`
|
||||
* Interactive Horizontal Line callbacks: `on_horizontal_line_move`
|
||||
|
||||
___
|
||||
|
||||
## `TopBar`
|
||||
The `TopBar` class represents the top bar shown on the chart when using callbacks:
|
||||
The `TopBar` class represents the top bar shown on the chart:
|
||||
|
||||

|
||||
|
||||
This class is accessed from the `topbar` attribute of the chart object (`chart.topbar.<method>`), after setting the topbar parameter to `True` upon declaration of the chart.
|
||||
This object is accessed from the `topbar` attribute of the chart object (`chart.topbar.<method>`).
|
||||
|
||||
Switchers and text boxes can be created within the top bar, and their instances can be accessed through the `topbar` dictionary. For example:
|
||||
Switchers, text boxes and buttons can be added to the top bar, and their instances can be accessed through the `topbar` dictionary. For example:
|
||||
|
||||
```python
|
||||
chart = Chart(api=api, topbar=True)
|
||||
|
||||
chart.topbar.textbox('symbol', 'AAPL') # Declares a textbox displaying 'AAPL'.
|
||||
print(chart.topbar['symbol'].value) # Prints the value within ('AAPL')
|
||||
|
||||
chart.topbar['symbol'].set('MSFT') # Sets the 'symbol' textbox to 'MSFT'
|
||||
print(chart.topbar['symbol'].value) # Prints the value again ('MSFT')
|
||||
```
|
||||
|
||||
Events can also be emitted from the topbar. For example:
|
||||
|
||||
```python
|
||||
from lightweight_charts import Chart
|
||||
|
||||
def on_button_press(chart):
|
||||
new_button_value = 'On' if chart.topbar['my_button'].value == 'Off' else 'Off'
|
||||
chart.topbar['my_button'].set(new_button_value)
|
||||
print(f'Turned something {new_button_value.lower()}.')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
chart = Chart()
|
||||
chart.topbar.button('my_button', 'Off', func=on_button_press)
|
||||
chart.show(block=True)
|
||||
|
||||
```
|
||||
|
||||
___
|
||||
|
||||
### `switcher`
|
||||
`name: str` | `method: function` | `*options: str` | `default: str`
|
||||
`name: str` | `options: tuple` | `default: str` | `func: callable`
|
||||
|
||||
* `name`: the name of the switcher which can be used to access it from the `topbar` dictionary.
|
||||
* `method`: The function from the `api` class given to the constructor that will receive the callback.
|
||||
* `options`: The strings to be displayed within the switcher. This may be a variety of timeframes, security types, or whatever needs to be updated directly from the chart.
|
||||
* `options`: The options for each switcher item.
|
||||
* `default`: The initial switcher option set.
|
||||
___
|
||||
|
||||
@ -79,6 +97,15 @@ ___
|
||||
* `initial_text`: The text to show within the text box.
|
||||
___
|
||||
|
||||
### `button`
|
||||
`name: str` | `button_text: str` | `separator: bool` | `func: callable`
|
||||
|
||||
* `name`: the name of the text box to access it from the `topbar` dictionary.
|
||||
* `button_text`: Text to show within the button.
|
||||
* `separator`: places a separator line to the right of the button.
|
||||
* `func`: The event handler which will be executed upon a button click.
|
||||
___
|
||||
|
||||
## Callbacks Example:
|
||||
|
||||
```python
|
||||
@ -93,40 +120,37 @@ def get_bar_data(symbol, timeframe):
|
||||
return pd.read_csv(f'../examples/6_callbacks/bar_data/{symbol}_{timeframe}.csv')
|
||||
|
||||
|
||||
class API:
|
||||
def __init__(self):
|
||||
self.chart = None # Changes after each callback.
|
||||
def on_search(chart, searched_string):
|
||||
new_data = get_bar_data(searched_string, chart.topbar['timeframe'].value)
|
||||
if new_data.empty:
|
||||
return
|
||||
chart.topbar['symbol'].set(searched_string)
|
||||
chart.set(new_data)
|
||||
|
||||
def on_search(self, searched_string): # Called when the user searches.
|
||||
new_data = get_bar_data(searched_string, self.chart.topbar['timeframe'].value)
|
||||
if new_data.empty:
|
||||
return
|
||||
self.chart.topbar['symbol'].set(searched_string)
|
||||
self.chart.set(new_data)
|
||||
|
||||
def on_timeframe_selection(chart):
|
||||
new_data = get_bar_data(chart.topbar['symbol'].value, chart.topbar['timeframe'].value)
|
||||
if new_data.empty:
|
||||
return
|
||||
chart.set(new_data, True)
|
||||
|
||||
def on_timeframe_selection(self): # Called when the user changes the timeframe.
|
||||
new_data = get_bar_data(self.chart.topbar['symbol'].value, self.chart.topbar['timeframe'].value)
|
||||
if new_data.empty:
|
||||
return
|
||||
self.chart.set(new_data, True)
|
||||
|
||||
def on_horizontal_line_move(self, line_id, price):
|
||||
print(f'Horizontal line moved to: {price}')
|
||||
|
||||
def on_horizontal_line_move(chart, line):
|
||||
print(f'Horizontal line moved to: {line.price}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
api = API()
|
||||
|
||||
chart = Chart(api=api, topbar=True, searchbox=True, toolbox=True)
|
||||
chart = Chart(toolbox=True)
|
||||
chart.legend(True)
|
||||
|
||||
chart.topbar.textbox('symbol', 'TSLA')
|
||||
chart.topbar.switcher('timeframe', api.on_timeframe_selection, '1min', '5min', '30min', default='5min')
|
||||
chart.topbar.switcher('timeframe', ('1min', '5min', '30min'), default='5min',
|
||||
func=on_timeframe_selection)
|
||||
|
||||
df = get_bar_data('TSLA', '5min')
|
||||
chart.set(df)
|
||||
|
||||
chart.horizontal_line(200, interactive=True)
|
||||
chart.horizontal_line(200, func=on_horizontal_line_move)
|
||||
|
||||
chart.show(block=True)
|
||||
```
|
||||
|
||||
@ -5,8 +5,7 @@ This page contains a reference to all chart objects that can be used within the
|
||||
___
|
||||
|
||||
## Chart
|
||||
`volume_enabled: bool` | `width: int` | `height: int` | `x: int` | `y: int` | `on_top: bool` | `maximize: bool` | `debug: bool` |
|
||||
`api: object` | `topbar: bool` | `searchbox: bool` | `toolbox: bool`
|
||||
`width: int` | `height: int` | `x: int` | `y: int` | `on_top: bool` | `maximize: bool` | `debug: bool` | `toolbox: bool`
|
||||
|
||||
The main object used for the normal functionality of lightweight-charts-python, built on the pywebview library.
|
||||
|
||||
@ -61,11 +60,13 @@ This method should be called after the chart window has loaded.
|
||||
___
|
||||
|
||||
## QtChart
|
||||
`widget: QWidget` | `volume_enabled: bool`
|
||||
`widget: QWidget`
|
||||
|
||||
The `QtChart` object allows the use of charts within a `QMainWindow` object, and has similar functionality to the `Chart` and `ChartAsync` objects for manipulating data, configuring and styling.
|
||||
The `QtChart` object allows the use of charts within a `QMainWindow` object, and has similar functionality to the `Chart` object for manipulating data, configuring and styling.
|
||||
|
||||
Callbacks can be recieved through the Qt event loop.
|
||||
Either the `PyQt5` or `PySide6` libraries will work with this chart.
|
||||
|
||||
Callbacks can be received through the Qt event loop.
|
||||
___
|
||||
|
||||
### `get_webview`
|
||||
@ -107,11 +108,11 @@ app.exec_()
|
||||
___
|
||||
|
||||
## WxChart
|
||||
`parent: wx.Panel` | `volume_enabled: bool`
|
||||
`parent: wx.Panel`
|
||||
|
||||
The WxChart object allows the use of charts within a `wx.Frame` object, and has similar functionality to the `Chart` and `ChartAsync` objects for manipulating data, configuring and styling.
|
||||
The WxChart object allows the use of charts within a `wx.Frame` object, and has similar functionality to the `Chart` object for manipulating data, configuring and styling.
|
||||
|
||||
Callbacks can be recieved through the Wx event loop.
|
||||
Callbacks can be received through the Wx event loop.
|
||||
___
|
||||
|
||||
### `get_webview`
|
||||
@ -157,7 +158,6 @@ if __name__ == '__main__':
|
||||
___
|
||||
|
||||
## StreamlitChart
|
||||
`parent: wx.Panel` | `volume_enabled: bool`
|
||||
|
||||
The `StreamlitChart` object allows the use of charts within a Streamlit app, and has similar functionality to the `Chart` object for manipulating data, configuring and styling.
|
||||
|
||||
|
||||
@ -43,32 +43,30 @@ If `cumulative_volume` is used, the volume data given will be added onto the lat
|
||||
___
|
||||
|
||||
## `create_line` (Line)
|
||||
`color: str` | `width: int` | `price_line: bool` | `price_label: bool` | `-> Line`
|
||||
`name: str` | `color: str` | `style: LINE_STYLE`| `width: int` | `price_line: bool` | `price_label: bool` | `-> Line`
|
||||
|
||||
Creates and returns a `Line` object, representing a `LineSeries` object in Lightweight Charts and can be used to create indicators. As well as the methods described below, the `Line` object also has access to:
|
||||
[`title`](#title), [`marker`](#marker), [`horizontal_line`](#horizontal-line) [`hide_data`](#hide-data), [`show_data`](#show-data) and[`price_line`](#price-line).
|
||||
|
||||
Its instance should only be accessed from this method.
|
||||
|
||||
|
||||
### `set`
|
||||
`data: pd.DataFrame` `name: str`
|
||||
`data: pd.DataFrame`
|
||||
|
||||
Sets the data for the line.
|
||||
|
||||
When not using the `name` parameter, the columns should be named: `time | value` (Not case sensitive).
|
||||
When a name has not been set upon declaration, the columns should be named: `time | value` (Not case sensitive).
|
||||
|
||||
Otherwise, the method will use the column named after the string given in `name`. This name will also be used within the legend of the chart. For example:
|
||||
```python
|
||||
line = chart.create_line()
|
||||
line = chart.create_line('SMA 50')
|
||||
|
||||
# DataFrame with columns: date | SMA 50
|
||||
df = pd.read_csv('sma50.csv')
|
||||
|
||||
line.set(df, name='SMA 50')
|
||||
line.set(df)
|
||||
```
|
||||
|
||||
|
||||
### `update`
|
||||
`series: pd.Series`
|
||||
|
||||
@ -76,7 +74,6 @@ Updates the data for the line.
|
||||
|
||||
This should be given as a Series object, with labels akin to the `line.set()` function.
|
||||
|
||||
|
||||
### `delete`
|
||||
Irreversibly deletes the line.
|
||||
|
||||
@ -263,8 +260,8 @@ ___
|
||||
Shows the hidden candles on the chart.
|
||||
___
|
||||
|
||||
## `add_hotkey`
|
||||
`modifier: 'ctrl'/'shift'/'alt'/'meta'` | `key: str/int/tuple` | `method: object`
|
||||
## `hotkey`
|
||||
`modifier: 'ctrl'/'shift'/'alt'/'meta'` | `key: str/int/tuple` | `func: callable`
|
||||
|
||||
Adds a global hotkey to the chart window, which will execute the method or function given.
|
||||
|
||||
@ -273,26 +270,29 @@ When using a number in `key`, it should be given as an integer. If multiple key
|
||||
```python
|
||||
def place_buy_order(key):
|
||||
print(f'Buy {key} shares.')
|
||||
|
||||
|
||||
|
||||
|
||||
def place_sell_order(key):
|
||||
print(f'Sell all shares, because I pressed {key}.')
|
||||
|
||||
|
||||
chart.add_hotkey('shift', (1, 2, 3), place_buy_order)
|
||||
chart.add_hotkey('shift', 'X', place_sell_order)
|
||||
if __name__ == '__main__':
|
||||
chart = Chart()
|
||||
chart.hotkey('shift', (1, 2, 3), place_buy_order)
|
||||
chart.hotkey('shift', 'X', place_sell_order)
|
||||
chart.show(block=True)
|
||||
```
|
||||
|
||||
___
|
||||
|
||||
## `create_table`
|
||||
`width: int/float` | `height: int/float` | `headings: tuple[str]` | `widths: tuple[float]` | `alignments: tuple[str]` | `position: 'left'/'right'/'top'/'bottom'` | `draggable: bool` | `method: object`
|
||||
`width: int/float` | `height: int/float` | `headings: tuple[str]` | `widths: tuple[float]` | `alignments: tuple[str]` | `position: 'left'/'right'/'top'/'bottom'` | `draggable: bool` | `func: callable` | `-> Table`
|
||||
|
||||
Creates and returns a [`Table`](https://lightweight-charts-python.readthedocs.io/en/latest/tables.html) object.
|
||||
___
|
||||
|
||||
## `create_subchart` (SubChart)
|
||||
`volume_enabled: bool` | `position: 'left'/'right'/'top'/'bottom'`, `width: float` | `height: float` | `sync: bool/str` | `-> SubChart`
|
||||
`position: 'left'/'right'/'top'/'bottom'`, `width: float` | `height: float` | `sync: bool/str` | `scale_candles_only: bool`|`toolbox: bool` | `-> SubChart`
|
||||
|
||||
Creates and returns a `SubChart` object, placing it adjacent to the previous `Chart` or `SubChart`. This allows for the use of multiple chart panels within the same `Chart` window. Its instance should only be accessed by using this method.
|
||||
|
||||
@ -335,7 +335,6 @@ if __name__ == '__main__':
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Synced Line Chart Example:
|
||||
|
||||
```python
|
||||
@ -346,17 +345,16 @@ if __name__ == '__main__':
|
||||
chart = Chart(inner_width=1, inner_height=0.8)
|
||||
chart.time_scale(visible=False)
|
||||
|
||||
chart2 = chart.create_subchart(width=1, height=0.2, sync=True, volume_enabled=False)
|
||||
chart2 = chart.create_subchart(width=1, height=0.2, sync=True)
|
||||
line = chart2.create_line()
|
||||
|
||||
df = pd.read_csv('ohlcv.csv')
|
||||
df2 = pd.read_csv('rsi.csv')
|
||||
|
||||
chart.set(df)
|
||||
line = chart2.create_line()
|
||||
line.set(df2)
|
||||
|
||||
chart.show(block=True)
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
project = 'lightweight-charts-python'
|
||||
copyright = '2023, louisnw'
|
||||
author = 'louisnw'
|
||||
release = '1.0.15'
|
||||
release = '1.0.16'
|
||||
|
||||
extensions = ["myst_parser"]
|
||||
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
# Table
|
||||
`width: int/float` | `height: int/float` | `headings: tuple[str]` | `widths: tuple[float]` | `alignments: tuple[str]` | `position: 'left'/'right'/'top'/'bottom'` | `draggable: bool` | `method: object`
|
||||
`width: int/float` | `height: int/float` | `headings: tuple[str]` | `widths: tuple[float]` | `alignments: tuple[str]` | `position: 'left'/'right'/'top'/'bottom'` | `draggable: bool` | `func: callable`
|
||||
|
||||
Tables are panes that can be used to gain further functionality from charts. They are intended to be used for watchlists, order management, or position management. It should be accessed from the `create_table` common method.
|
||||
|
||||
The `Table` and `Row` objects inherit from dictionaries, and can be manipulated as such.
|
||||
|
||||
|
||||
The `Table` and `Row` objects act as dictionaries, and can be manipulated as such.
|
||||
|
||||
`width`/`height`: Either given as a percentage (a `float` between 0 and 1) or as an integer representing pixel size.
|
||||
|
||||
@ -15,7 +13,7 @@ The `Table` and `Row` objects inherit from dictionaries, and can be manipulated
|
||||
|
||||
`draggable`: If `True`, then the window can be dragged to any position within the window.
|
||||
|
||||
`method`: If given this will be called when a row is clicked.
|
||||
`func`: If given this will be called when a row is clicked, returning the `Row` object in question.
|
||||
___
|
||||
|
||||
## `new_row` (Row)
|
||||
@ -25,11 +23,22 @@ Creates a new row within the table, and returns a `Row` object.
|
||||
|
||||
if `id` is passed it should be unique to all other rows. Otherwise, the `id` will be randomly generated.
|
||||
|
||||
Rows can be passed a string (header) item or a tuple to set multiple headings:
|
||||
|
||||
```python
|
||||
row['Symbol'] = 'AAPL'
|
||||
row['Symbol', 'Action'] = 'AAPL', 'BUY'
|
||||
```
|
||||
|
||||
### `background_color`
|
||||
`column: str` | `color: str`
|
||||
|
||||
Sets the background color of the Row cell at the given column.
|
||||
Sets the background color of the row cell.
|
||||
|
||||
### `text_color`
|
||||
`column: str` | `color: str`
|
||||
|
||||
Sets the foreground color of the row cell.
|
||||
|
||||
### `delete`
|
||||
Deletes the row.
|
||||
@ -77,10 +86,7 @@ ___
|
||||
import pandas as pd
|
||||
from lightweight_charts import Chart
|
||||
|
||||
def on_row_click(row_id):
|
||||
row = table.get(row_id)
|
||||
print(row)
|
||||
|
||||
def on_row_click(row):
|
||||
row['PL'] = round(row['PL']+1, 2)
|
||||
row.background_color('PL', 'green' if row['PL'] > 0 else 'red')
|
||||
|
||||
@ -97,7 +103,7 @@ if __name__ == '__main__':
|
||||
headings=('Ticker', 'Quantity', 'Status', '%', 'PL'),
|
||||
widths=(0.2, 0.1, 0.2, 0.2, 0.3),
|
||||
alignments=('center', 'center', 'right', 'right', 'right'),
|
||||
position='left', method=on_row_click)
|
||||
position='left', func=on_row_click)
|
||||
|
||||
table.format('PL', f'£ {table.VALUE}')
|
||||
table.format('%', f'{table.VALUE} %')
|
||||
|
||||
@ -3,15 +3,15 @@ The Toolbox allows for trendlines, ray lines and horizontal lines to be drawn an
|
||||
|
||||
It can be used within any Chart object, and is enabled by setting the `toolbox` parameter to `True` upon Chart declaration.
|
||||
|
||||
The Toolbox should only be accessed from the `toolbox` attribute of the chart object. (`chart.toolbox.<method>`)
|
||||
|
||||
The following hotkeys can also be used when the Toolbox is enabled:
|
||||
* Alt+T: Trendline
|
||||
* Alt+H: Horizontal Line
|
||||
* Alt+R: Ray Line
|
||||
* Meta+Z or Ctrl+Z: Undo
|
||||
|
||||
Drawings can also be deleted by right-clicking on them, which brings up a context menu.
|
||||
|
||||
Right-clicking on a drawing will open a context menu, allowing for color selection and deletion.
|
||||
|
||||
___
|
||||
|
||||
## `save_drawings_under`
|
||||
@ -58,33 +58,29 @@ def get_bar_data(symbol, timeframe):
|
||||
return pd.read_csv(f'bar_data/{symbol}_{timeframe}.csv')
|
||||
|
||||
|
||||
class API:
|
||||
def __init__(self):
|
||||
self.chart: Chart = None
|
||||
def on_search(chart, searched_string):
|
||||
new_data = get_bar_data(searched_string, chart.topbar['timeframe'].value)
|
||||
if new_data.empty:
|
||||
return
|
||||
chart.topbar['symbol'].set(searched_string)
|
||||
chart.set(new_data)
|
||||
chart.toolbox.load_drawings(searched_string) # Loads the drawings saved under the symbol.
|
||||
|
||||
|
||||
def on_timeframe_selection(chart):
|
||||
new_data = get_bar_data(chart.topbar['symbol'].value, chart.topbar['timeframe'].value)
|
||||
if new_data.empty:
|
||||
return
|
||||
chart.set(new_data, render_drawings=True) # The symbol has not changed, so we want to re-render the drawings.
|
||||
|
||||
def on_search(self, searched_string):
|
||||
new_data = get_bar_data(searched_string, self.chart.topbar['timeframe'].value)
|
||||
if new_data.empty:
|
||||
return
|
||||
self.chart.topbar['symbol'].set(searched_string)
|
||||
self.chart.set(new_data)
|
||||
self.chart.toolbox.load_drawings(searched_string) # Loads the drawings saved under the symbol.
|
||||
|
||||
def on_timeframe_selection(self):
|
||||
new_data = get_bar_data(self.chart.topbar['symbol'].value, self.chart.topbar['timeframe'].value)
|
||||
if new_data.empty:
|
||||
return
|
||||
self.chart.set(new_data, render_drawings=True) # The symbol has not changed, so we want to re-render the drawings.
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
api = API()
|
||||
|
||||
chart = Chart(api=api, topbar=True, searchbox=True, toolbox=True)
|
||||
chart = Chart(toolbox=True)
|
||||
chart.legend(True)
|
||||
|
||||
chart.events.search += on_search
|
||||
chart.topbar.textbox('symbol', 'TSLA')
|
||||
chart.topbar.switcher('timeframe', api.on_timeframe_selection, '1min', '5min', '30min', default='5min')
|
||||
chart.topbar.switcher('timeframe', ('1min', '5min', '30min'), default='5min', func=on_timeframe_selection)
|
||||
|
||||
df = get_bar_data('TSLA', '5min')
|
||||
|
||||
@ -94,9 +90,9 @@ if __name__ == '__main__':
|
||||
chart.toolbox.load_drawings(chart.topbar['symbol'].value) # Loads the drawings under the default symbol.
|
||||
|
||||
chart.toolbox.save_drawings_under(chart.topbar['symbol']) # Saves drawings based on the symbol.
|
||||
|
||||
|
||||
chart.show(block=True)
|
||||
|
||||
chart.toolbox.export_drawings('drawings.json') # Exports the drawings to the JSON file.
|
||||
chart.toolbox.export_drawings('drawings.json') # Exports the drawings to the JSON file upon close.
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user