Skip to content

how to plot horizontal line in a streaming intraday chart #552

@pannet1

Description

@pannet1

the streaming part and the buy button clicking all works great. however when clicking the console says
`Error adding horizontal line: must plot this primitive in prior time-range

import finplot as fplt
import numpy as np
import pandas as pd
import time
from PyQt6.QtWidgets import (
    QApplication,
    QVBoxLayout,
    QPushButton,
    QGridLayout,
    QGraphicsView,
    QComboBox,
)
from PyQt6.QtCore import QThread
import random


# Mock broker API (replace with your actual API calls)
def place_buy_order():
    order_id = f"BUY-{random.randint(1000, 9999)}"
    print(f"Placing buy order: {order_id}")
    time.sleep(0.1)
    print(f"Buy order {order_id} placed.")


class BrokerThread(QThread):
    def __init__(self, order_function):
        super().__init__()
        self.order_function = order_function

    def run(self):
        self.order_function()


def gen_dumb_price(symbol="DUMB"):
    random.seed(hash(symbol))
    v = np.random.normal(size=(1000, 4))
    df = pd.DataFrame(v, columns="low open close high".split())
    df = df.rolling(10).mean()
    ma = df["low"].rolling(20).mean().diff()
    for col in df.columns:
        df[col] *= ma * 100
    df.values.sort(axis=1)
    df = (df.T + np.sin(df.index / 87) * 3 + np.cos(df.index / 201) * 5).T + 20
    flip = df["open"].shift(-1) <= df["open"]
    df.loc[flip, "open"], df.loc[flip, "close"] = df["close"].copy(), df["open"].copy()
    df["volume"] = df["high"] - df["low"]
    # epoch time
    df.index = np.linspace(1608332400 - 60 * 1000, 1608332400, 1000)
    return df["open close high low volume".split()].dropna()


def update_chart(ax, df, current_index):
    if current_index >= len(df):
        return current_index
    df_subset = df.iloc[: current_index + 1]
    fplt.candlestick_ochl(df_subset, ax=ax)
    fplt.refresh()
    return current_index + 1


current_symbol = "DUMB"
df = gen_dumb_price(current_symbol)
ax = fplt.create_plot("Live Candlestick Chart", init_zoom_periods=100, maximize=False)

current_index = 1
update_interval = 0.5
last_update_time = time.time()
horizontal_line = None


def update_loop():
    global current_index, last_update_time
    now = time.time()
    if now - last_update_time >= update_interval:
        current_index = update_chart(ax, df, current_index)
        last_update_time = now


app = QApplication([])
win = QGraphicsView()
win.setWindowTitle("Trading Chart with Buy Button and Symbol Selection")
layout = QGridLayout()
win.setLayout(layout)
win.resize(800, 600)

controls_layout = QVBoxLayout()
buy_button = QPushButton("Buy")
controls_layout.addWidget(buy_button)

symbol_dropdown = QComboBox()
symbol_dropdown.addItems(["DUMB", "AAPL", "GOOG", "MSFT", "TSLA"])
controls_layout.addWidget(symbol_dropdown)

layout.addLayout(controls_layout, 0, 1, 1, 1)

win.axs = [ax]
layout.addWidget(ax.vb.win, 0, 0, 1, 1)

active_threads = []


def on_buy_click():
    global horizontal_line
    broker_thread = BrokerThread(place_buy_order)
    active_threads.append(broker_thread)
    broker_thread.finished.connect(lambda: active_threads.remove(broker_thread))
    broker_thread.start()

    # Add horizontal line
    if current_index > 2 and len(df) > 1:  # Ensure enough data
        y_value = df["high"].iloc[current_index - 2]
        now = time.time()  # Use Unix timestamp
        latest_time = df.index[-1]  # df.index is already unix timestamp.

        try:
            if horizontal_line is None:
                horizontal_line = fplt.add_line(
                    (now, y_value),
                    (latest_time, y_value),
                    color="#0000FF",
                    style="-",
                    width=1,
                    interactive=False,
                )
            else:
                horizontal_line.setPos((now, y_value), (latest_time, y_value))
            fplt.refresh()

        except Exception as e:
            print(f"Error adding horizontal line: {e}")


def on_symbol_change(symbol):
    global df, current_index, current_symbol, horizontal_line
    current_symbol = symbol
    df = gen_dumb_price(symbol)
    current_index = 1
    ax.reset()
    if horizontal_line is not None:
        ax.remove_line(horizontal_line)
        horizontal_line = None
    update_chart(ax, df, current_index)


buy_button.clicked.connect(on_buy_click)
symbol_dropdown.currentTextChanged.connect(on_symbol_change)

fplt.show(qt_exec=False)
win.show()
fplt.timer_callback(update_loop, 0.1)
app.exec()

```

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions