Неправильно отображаются маркеры.

Alexxxandr

Новичок
Пользователь
Сен 11, 2022
36
0
6
Маркеры должны отображаться прямо на свечах. Но в процессе построения графика свеча строится реалтайм, когда появляется маркер крупной сделки, свечка сжимается и отображается на графике слева, а маркер справа.
Python:
import matplotlib.pyplot as plt
import mplfinance as mpf
import pandas as pd
import websocket
import threading
import json
from matplotlib.animation import FuncAnimation

# Создаем пустой DataFrame для свечного графика и агрегированных сделок
df_candle = pd.DataFrame(columns=['Open', 'High', 'Low', 'Close', 't', 'T'])
df_trades = pd.DataFrame(columns=['Price', 'Quantity', 'IsBuyerMaker', 'T'])

class SocketConn(websocket.WebSocketApp):
    def __init__(self, url, on_message):
        super().__init__(url=url, on_open=self.on_open)

        self.on_message = on_message
        self.on_error = lambda ws, e: print("Error", e)
        self.on_close = lambda ws: print("Closing")

        self.run_forever()

    def on_open(self, ws):
        print("Websocket was opened")

def on_message_candle(ws, msg):
    global df_candle
    data = json.loads(msg)  # Преобразуем сообщение в словарь Python
    kline = data['k']
    df_candle.loc[pd.to_datetime(kline['t'], unit='ms')] = [kline['o'], kline['h'], kline['l'], kline['c'], kline['t'], kline['T']]
    # print(kline)

def on_message_trade(ws, msg):
    global df_trades
    data = json.loads(msg)  # Преобразуем сообщение в словарь Python
    if float(data['q']) > 5:  # Если объем сделки больше 5
        df_trades.loc[pd.to_datetime(data['T'], unit='ms')] = [data['p'], data['q'], data['m'], data['T']]
        print(f"Large {'buy' if data['m'] else 'sell'} trade: Price {data['p']}, Quantity {data['q']}")

threading.Thread(target=SocketConn, args=("wss://fstream.binance.com/ws/btcusdt@kline_5m", on_message_candle)).start()
threading.Thread(target=SocketConn, args=("wss://fstream.binance.com/ws/btcusdt@aggTrade", on_message_trade)).start()

fig, ax = plt.subplots()

def update_graph(i):
    if not df_candle.empty:
        ax.clear()
        df_tail = df_candle.tail(400).astype(float)
        mpf.plot(df_tail, type='candle', ax=ax)

        if not df_trades.empty:
            for _, row in df_tail.iterrows():
                trades_in_candle = df_trades[(df_trades['T'] >= row['t']) & (df_trades['T'] <= row['T'])]
                for _, trade_row in trades_in_candle.iterrows():
                    color = 'green' if trade_row['IsBuyerMaker'] == True else 'red'
                    size = float(trade_row['Quantity']) * 5  # Увеличиваем размер маркера в 5 раз
                    ax.scatter(row.name, float(trade_row['Price']), color=color, s=size)  # Используем время свечи для размещения маркеров

ani = FuncAnimation(fig, update_graph, interval=100, cache_frame_data=False)
plt.show()
 

Форум IT Специалистов