Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
pannet1 opened this issue Feb 24, 2025 · 0 comments
Open

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

pannet1 opened this issue Feb 24, 2025 · 0 comments

Comments

@pannet1
Copy link

pannet1 commented Feb 24, 2025

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()

```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant