lightweight-charts-python

repository·main·Indexed 24 days ago

https://github.com/louisnw01/lightweight-charts-python

A Pythonic interface for TradingView's Lightweight Charts that enables the creation of interactive financial charts. It supports real-time data updates from bars or ticks, line indicators (e.g., SMA), and drawing tools. The library includes integration widgets for PyQt6, PyQt5, PySide6, WxPython, Jupyter Notebooks, and Streamlit, as well as a topbar interface for custom UI widgets and hotkey callback registration.

Tokens
18.5K
Snippets
37
Records
93
Agent score
84%

What's inside lightweight-charts-python

  1. Handle row clicks and update table cells dynamically

    main

    When creating a table with the func parameter in create_table, you can provide a callback function that receives a row object. This row object allows you to:

    • Update values: Modify cell values by treating the row like a dictionary (e.g., row['ColumnName'] = new_value).
    • Change styling: Use row.background_color(column_name, color) to change the background color of a specific cell based on its value.

    You can also use the callback to update other parts of the table, such as the table.footer.

  2. Access Polygon.io market data via PolygonAPI

    main

    The PolygonAPI class is integrated into all chart types via the chart.polygon attribute. You can use it to fetch and display stock, option, index, forex, or crypto data directly on your chart.

    Common Parameters for all methods:

    • timeframe: The interval (e.g., '1min', '5min', 'H', '2D', '5W').
    • start_date: Start date in YYYY-MM-DD format.
    • end_date: End date in YYYY-MM-DD format (defaults to 'now').
    • limit: Maximum number of base aggregates to query.
    • live: Set to True to use a websocket connection for real-time updates.

    Important Requirements:

    • If live=True, you must install the websockets library.
    • When using live data with the standard show method, you must set block=True (i.e., chart.show(block=True)) to allow data to congregate on the chart. Alternatively, use show_async.

    Note: Methods return a boolean indicating if the request was successful.

    from lightweight_charts import Chart
    
    if __name__ == '__main__':
        chart = Chart()
        chart.polygon.api_key('<API-KEY>')
        chart.polygon.stock(
            symbol='AAPL',
            timeframe='5min',
            start_date='2023-06-09'
        )
        chart.show(block=True)
  3. Run background tasks with asyncio and show_async()

    main

    To run custom logic (like a clock or a live data feed) while the GUI loop is active and listening for events, you should use chart.show_async() within an asyncio event loop.

    Use asyncio.gather() to run the chart's display loop and your background task concurrently. Always check chart.is_alive within your background loops to ensure they exit gracefully when the chart is closed.

    import asyncio
    from datetime import datetime
    from lightweight_charts import Chart
    
    async def update_clock(chart):
        while chart.is_alive:
            # Sleep until the next second
            await asyncio.sleep(1-(datetime.now().microsecond/1_000_000))
            chart.topbar['clock'].set(datetime.now().strftime('%H:%M:%S'))
    
    async def main():
        chart = Chart()
        chart.topbar.textbox('clock')
        # Run the chart and the clock task concurrently
        await asyncio.gather(chart.show_async(), update_clock(chart))
    
    if __name__ == '__main__':
        asyncio.run(main())
  4. Access and manage TopBar widgets

    main

    The TopBar class provides a UI area at the top of the chart. You access it via the chart.topbar attribute.

    To interact with widgets (switchers, textboxes, or buttons), you first declare them using a method on chart.topbar, assigning them a unique name. You can then retrieve and manipulate these widgets using the chart.topbar dictionary with that name.

    Common widget parameters:

    • name: The unique identifier used to access the widget from the topbar dictionary.
    • align: The alignment of the widget ('left' or 'right').
  5. Create a simple static chart

    main

    You can create a basic chart by instantiating the Chart class and passing a pandas DataFrame to the set() method.

    Important: Because the library uses multiprocessing, you must encapsulate your Chart instantiation within an if __name__ == '__main__': block to prevent errors.

    To display the chart and prevent the script from exiting immediately, use chart.show(block=True).

    import pandas as pd
    from lightweight_charts import Chart
    
    if __name__ == '__main__':
        chart = Chart()
        
        # Load data (expects columns like date, open, high, low, close, volume)
        df = pd.read_csv('ohlcv.csv')
        chart.set(df)
        
        chart.show(block=True)
  6. Implement persistent drawings with the Toolbox

    main

    The toolbox feature in lightweight-charts-python allows users to create drawings on a chart and persist them using JSON files. To implement persistence, you can manage drawings based on a specific symbol and timeframe, loading them when the symbol changes and exporting them when the chart session ends.

    Workflow for Persistence:

    1. Initialize: Create an empty drawings.json file (containing {}) to act as your storage.
    2. Setup: Initialize the chart with Chart(toolbox=True).
    3. Import/Load: Use chart.toolbox.import_drawings('filename.json') to load the storage file, then chart.toolbox.load_drawings(symbol) to load drawings specific to the current symbol.
    4. Update Data: When changing timeframes without changing the symbol, use chart.set(new_data, keep_drawings=True) to ensure existing drawings remain visible on the new data.
    5. Save/Export: Use chart.toolbox.save_drawings_under(symbol_object) to save current drawings to the internal storage, and chart.toolbox.export_drawings('filename.json') to write the stored drawings to a file (typically called when the chart is closed).
  7. Handle Topbar events and UI interactions

    main

    The Chart object provides a topbar interface to add interactive elements like textboxes and switchers. You can respond to user interactions through event registration and callback functions.

    Topbar Components

    • chart.topbar.textbox(name, default_value): Creates a text input field. You can access its current value via chart.topbar[name].value and update it using .set(new_value).
    • chart.topbar.switcher(name, options, default, func): Creates a selection menu. The func parameter accepts a callback that is triggered when the selection changes.

    Event Registration

    • Search Event: Use chart.events.search += callback_function to listen for search queries initiated in the topbar.
    • Component Callbacks: Many UI elements and drawing tools (like horizontal_line) accept a func argument to handle interaction events directly.
    import pandas as pd
    from lightweight_charts import Chart
    
    def on_search(chart, searched_string):
        # Access topbar values and update them
        current_timeframe = chart.topbar['timeframe'].value
        chart.topbar['symbol'].set(searched_string)
        # chart.set(new_data) to update the chart
    
    def on_timeframe_selection(chart):
        # Triggered by switcher
        symbol = chart.topbar['symbol'].value
        timeframe = chart.topbar['timeframe'].value
        # chart.set(new_data, True) to update the chart
    
    def on_horizontal_line_move(chart, line):
        print(f'Horizontal line moved to: {line.price}')
    
    if __name__ == '__main__':
        chart = Chart(toolbox=True)
        
        # Register search event
        chart.events.search += on_search
    
        # Configure Topbar
        chart.topbar.textbox('symbol', 'TSLA')
        chart.topbar.switcher('timeframe', ('1min', '5min', '30min'), default='5min', 
                              func=on_timeframe_selection)
    
        # Add interactive drawing tool with callback
        chart.horizontal_line(200, func=on_horizontal_line_move)
    
        chart.show(block=True)