Polygon:
- Added async methods to polygon. - The `requests` library is no longer required, with `urllib` being used instead. - Added the `get_bar_data` function, which returns a dataframe of aggregate data from polygon. - Opened up the `subscribe` and `unsubscribe` functions Enhancements: - Tables will now scroll when the rows exceed table height. Bugs: - Fixed a bug preventing async functions being used with horizontal line event. - Fixed a bug causing the legend to show duplicate lines if the line was created after the legend. - Fixed a bug causing the line hide icon to persist within the legend after deletion (#75) - Fixed a bug causing the search box to be unfocused when the chart is loaded.
This commit is contained in:
74
docs/source/examples/events.md
Normal file
74
docs/source/examples/events.md
Normal file
@ -0,0 +1,74 @@
|
||||
# Events
|
||||
|
||||
## Hotkey Example
|
||||
|
||||
```python
|
||||
from lightweight_charts import Chart
|
||||
|
||||
def place_buy_order(key):
|
||||
print(f'Buy {key} shares.')
|
||||
|
||||
|
||||
def place_sell_order(key):
|
||||
print(f'Sell all shares, because I pressed {key}.')
|
||||
|
||||
|
||||
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)
|
||||
```
|
||||
___
|
||||
|
||||
|
||||
## Topbar Example
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from lightweight_charts import Chart
|
||||
|
||||
|
||||
def get_bar_data(symbol, timeframe):
|
||||
if symbol not in ('AAPL', 'GOOGL', 'TSLA'):
|
||||
print(f'No data for "{symbol}"')
|
||||
return pd.DataFrame()
|
||||
return pd.read_csv(f'bar_data/{symbol}_{timeframe}.csv')
|
||||
|
||||
|
||||
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_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_horizontal_line_move(chart, line):
|
||||
print(f'Horizontal line moved to: {line.price}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
chart = Chart(toolbox=True)
|
||||
chart.legend(True)
|
||||
|
||||
chart.events.search += on_search
|
||||
|
||||
chart.topbar.textbox('symbol', 'TSLA')
|
||||
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, func=on_horizontal_line_move)
|
||||
|
||||
chart.show(block=True)
|
||||
```
|
||||
98
docs/source/examples/gui_examples.md
Normal file
98
docs/source/examples/gui_examples.md
Normal file
@ -0,0 +1,98 @@
|
||||
# Alternative GUI's
|
||||
|
||||
|
||||
## PyQt5 / PySide6
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
|
||||
|
||||
from lightweight_charts.widgets import QtChart
|
||||
|
||||
app = QApplication([])
|
||||
window = QMainWindow()
|
||||
layout = QVBoxLayout()
|
||||
widget = QWidget()
|
||||
widget.setLayout(layout)
|
||||
|
||||
window.resize(800, 500)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
chart = QtChart(widget)
|
||||
|
||||
df = pd.read_csv('ohlcv.csv')
|
||||
chart.set(df)
|
||||
|
||||
layout.addWidget(chart.get_webview())
|
||||
|
||||
window.setCentralWidget(widget)
|
||||
window.show()
|
||||
|
||||
app.exec_()
|
||||
```
|
||||
___
|
||||
|
||||
|
||||
|
||||
## WxPython
|
||||
|
||||
```python
|
||||
import wx
|
||||
import pandas as pd
|
||||
|
||||
from lightweight_charts.widgets import WxChart
|
||||
|
||||
|
||||
class MyFrame(wx.Frame):
|
||||
def __init__(self):
|
||||
super().__init__(None)
|
||||
self.SetSize(1000, 500)
|
||||
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
panel.SetSizer(sizer)
|
||||
|
||||
chart = WxChart(panel)
|
||||
|
||||
df = pd.read_csv('ohlcv.csv')
|
||||
chart.set(df)
|
||||
|
||||
sizer.Add(chart.get_webview(), 1, wx.EXPAND | wx.ALL)
|
||||
sizer.Layout()
|
||||
self.Show()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = wx.App()
|
||||
frame = MyFrame()
|
||||
app.MainLoop()
|
||||
```
|
||||
___
|
||||
## Jupyter
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from lightweight_charts import JupyterChart
|
||||
|
||||
chart = JupyterChart()
|
||||
|
||||
df = pd.read_csv('ohlcv.csv')
|
||||
chart.set(df)
|
||||
|
||||
chart.load()
|
||||
```
|
||||
___
|
||||
|
||||
## Streamlit
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from lightweight_charts.widgets import StreamlitChart
|
||||
|
||||
chart = StreamlitChart(width=900, height=600)
|
||||
|
||||
df = pd.read_csv('ohlcv.csv')
|
||||
chart.set(df)
|
||||
|
||||
chart.load()
|
||||
```
|
||||
50
docs/source/examples/subchart.md
Normal file
50
docs/source/examples/subchart.md
Normal file
@ -0,0 +1,50 @@
|
||||
# Subcharts
|
||||
|
||||
## Grid of 4
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from lightweight_charts import Chart
|
||||
|
||||
if __name__ == '__main__':
|
||||
chart = Chart(inner_width=0.5, inner_height=0.5)
|
||||
chart2 = chart.create_subchart(position='right', width=0.5, height=0.5)
|
||||
chart3 = chart.create_subchart(position='left', width=0.5, height=0.5)
|
||||
chart4 = chart.create_subchart(position='right', width=0.5, height=0.5)
|
||||
|
||||
chart.watermark('1')
|
||||
chart2.watermark('2')
|
||||
chart3.watermark('3')
|
||||
chart4.watermark('4')
|
||||
|
||||
df = pd.read_csv('ohlcv.csv')
|
||||
chart.set(df)
|
||||
chart2.set(df)
|
||||
chart3.set(df)
|
||||
chart4.set(df)
|
||||
|
||||
chart.show(block=True)
|
||||
|
||||
```
|
||||
___
|
||||
## Synced Line Chart
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from lightweight_charts import Chart
|
||||
|
||||
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)
|
||||
line = chart2.create_line()
|
||||
|
||||
df = pd.read_csv('ohlcv.csv')
|
||||
df2 = pd.read_csv('rsi.csv')
|
||||
|
||||
chart.set(df)
|
||||
line.set(df2)
|
||||
|
||||
chart.show(block=True)
|
||||
```
|
||||
38
docs/source/examples/table.md
Normal file
38
docs/source/examples/table.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Table
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from lightweight_charts import Chart
|
||||
|
||||
def on_row_click(row):
|
||||
row['PL'] = round(row['PL']+1, 2)
|
||||
row.background_color('PL', 'green' if row['PL'] > 0 else 'red')
|
||||
|
||||
table.footer[1] = row['Ticker']
|
||||
|
||||
if __name__ == '__main__':
|
||||
chart = Chart(width=1000, inner_width=0.7, inner_height=1)
|
||||
subchart = chart.create_subchart(width=0.3, height=0.5)
|
||||
df = pd.read_csv('ohlcv.csv')
|
||||
chart.set(df)
|
||||
subchart.set(df)
|
||||
|
||||
table = chart.create_table(width=0.3, height=0.2,
|
||||
headings=('Ticker', 'Quantity', 'Status', '%', 'PL'),
|
||||
widths=(0.2, 0.1, 0.2, 0.2, 0.3),
|
||||
alignments=('center', 'center', 'right', 'right', 'right'),
|
||||
position='left', func=on_row_click)
|
||||
|
||||
table.format('PL', f'£ {table.VALUE}')
|
||||
table.format('%', f'{table.VALUE} %')
|
||||
|
||||
table.new_row('SPY', 3, 'Submitted', 0, 0)
|
||||
table.new_row('AMD', 1, 'Filled', 25.5, 105.24)
|
||||
table.new_row('NVDA', 2, 'Filled', -0.5, -8.24)
|
||||
|
||||
table.footer(2)
|
||||
table.footer[0] = 'Selected:'
|
||||
|
||||
chart.show(block=True)
|
||||
|
||||
```
|
||||
73
docs/source/examples/toolbox.md
Normal file
73
docs/source/examples/toolbox.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Toolbox with persistent drawings
|
||||
|
||||
To get started, create a file called `drawings.json`, which should contain:
|
||||
```
|
||||
{}
|
||||
```
|
||||
___
|
||||
|
||||
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from lightweight_charts import Chart
|
||||
|
||||
|
||||
def get_bar_data(symbol, timeframe):
|
||||
if symbol not in ('AAPL', 'GOOGL', 'TSLA'):
|
||||
print(f'No data for "{symbol}"')
|
||||
return pd.DataFrame()
|
||||
return pd.read_csv(f'bar_data/{symbol}_{timeframe}.csv')
|
||||
|
||||
|
||||
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)
|
||||
|
||||
# Load the drawings saved under the symbol.
|
||||
chart.toolbox.load_drawings(searched_string)
|
||||
|
||||
|
||||
def on_timeframe_selection(chart):
|
||||
new_data = get_bar_data(chart.topbar['symbol'].value, chart.topbar['timeframe'].value)
|
||||
if new_data.empty:
|
||||
return
|
||||
# The symbol has not changed, so we want to re-render the drawings.
|
||||
chart.set(new_data, render_drawings=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
chart = Chart(toolbox=True)
|
||||
chart.legend(True)
|
||||
|
||||
chart.events.search += on_search
|
||||
chart.topbar.textbox('symbol', 'TSLA')
|
||||
chart.topbar.switcher(
|
||||
'timeframe',
|
||||
('1min', '5min', '30min'),
|
||||
default='5min',
|
||||
func=on_timeframe_selection
|
||||
)
|
||||
|
||||
df = get_bar_data('TSLA', '5min')
|
||||
|
||||
chart.set(df)
|
||||
|
||||
# Imports the drawings saved in the JSON file.
|
||||
chart.toolbox.import_drawings('drawings.json')
|
||||
|
||||
# Loads the drawings under the default symbol.
|
||||
chart.toolbox.load_drawings(chart.topbar['symbol'].value)
|
||||
|
||||
# Saves drawings based on the symbol.
|
||||
chart.toolbox.save_drawings_under(chart.topbar['symbol'])
|
||||
|
||||
chart.show(block=True)
|
||||
|
||||
# Exports the drawings to the JSON file upon close.
|
||||
chart.toolbox.export_drawings('drawings.json')
|
||||
|
||||
```
|
||||
48
docs/source/examples/yfinance.md
Normal file
48
docs/source/examples/yfinance.md
Normal file
@ -0,0 +1,48 @@
|
||||
# YFinance
|
||||
|
||||
```python
|
||||
import datetime as dt
|
||||
import yfinance as yf
|
||||
from lightweight_charts import Chart
|
||||
|
||||
|
||||
def get_bar_data(symbol, timeframe):
|
||||
if timeframe in ('1m', '5m', '30m'):
|
||||
days = 7 if timeframe == '1m' else 60
|
||||
start_date = dt.datetime.now()-dt.timedelta(days=days)
|
||||
else:
|
||||
start_date = None
|
||||
|
||||
chart.spinner(True)
|
||||
data = yf.download(symbol, start_date, interval=timeframe)
|
||||
chart.spinner(False)
|
||||
|
||||
if data.empty:
|
||||
return False
|
||||
chart.set(data)
|
||||
return True
|
||||
|
||||
|
||||
def on_search(chart, searched_string):
|
||||
if get_bar_data(searched_string, chart.topbar['timeframe'].value):
|
||||
chart.topbar['symbol'].set(searched_string)
|
||||
|
||||
|
||||
def on_timeframe_selection(chart):
|
||||
get_bar_data(chart.topbar['symbol'].value, chart.topbar['timeframe'].value)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
chart = Chart(toolbox=True, debug=True)
|
||||
chart.legend(True)
|
||||
chart.events.search += on_search
|
||||
chart.topbar.textbox('symbol', 'n/a')
|
||||
chart.topbar.switcher(
|
||||
'timeframe',
|
||||
('1m', '5m', '30m', '1d', '1wk'),
|
||||
default='5m',
|
||||
func=on_timeframe_selection
|
||||
)
|
||||
|
||||
chart.show(block=True)
|
||||
```
|
||||
Reference in New Issue
Block a user