Path: blob/master/ invest-robot-contest_tinkoff-invest-volume-analysis-robot-master/visualizers/finplot_graph.py
5927 views
import threading1from datetime import timedelta23import finplot as fplt4import numpy as np5import pandas as pd67from utils.strategy_util import ticks_to_cluster8910class FinplotGraph(threading.Thread):11def __init__(self, signal_cluster_period):12super().__init__()1314self.signal_cluster_period = signal_cluster_period15self.plots = {}16self.ax = None1718def run(self):19self.ax = fplt.create_plot("Tinkoff Invest profile touch strategy", maximize=False)20self.ax.setLabel("right", "Цена")21self.ax.setLabel("bottom", "Дата / время")22fplt.show()2324def render(25self,26df: pd.DataFrame,27valid_entry_points,28invalid_entry_points,29clusters=None30):31candles = ticks_to_cluster(df, period=self.signal_cluster_period)3233# риски в свечах с максимальными объемами34max_volumes = candles[["time", "max_volume_price"]]3536# не подтвержденные точки входа с разделением на лонг и шорт37# округление времени точек входа для сопоставления с графиком38round_invalid_times = [pd.to_datetime(time).ceil(self.signal_cluster_period) for time in invalid_entry_points]39candles["invalid_buy_entry_point"] = np.where(40candles["time"].isin(round_invalid_times) & (candles.shift()["direction"] == 1), candles["low"] - (41candles["low"] * 0.007 / 100), np.nan42)43candles["invalid_sell_entry_point"] = np.where(44candles["time"].isin(round_invalid_times) & (candles.shift()["direction"] == 2), candles["high"] + (45candles["high"] * 0.007 / 100), np.nan46)4748# подтвержденные точки входа с разделением на лонг и шорт49# округление времени точек входа для сопоставления с графиком50round_valid_times = [pd.to_datetime(time).ceil(self.signal_cluster_period) for time in valid_entry_points]51candles["valid_buy_entry_point"] = np.where(52candles["time"].isin(round_valid_times) & (candles.shift()["direction"] == 1), candles["low"] - (53candles["low"] * 0.007 / 100), np.nan54)55candles["valid_sell_entry_point"] = np.where(56candles["time"].isin(round_valid_times) & (candles.shift()["direction"] == 2), candles["high"] + (57candles["high"] * 0.007 / 100), np.nan58)5960if not self.plots:61# первое построение графика62self.plots["candles"] = (fplt.candlestick_ochl(candles))6364self.plots["max_volume_price"] = (65fplt.plot(max_volumes["time"],66max_volumes["max_volume_price"],67style="d",68color="#808080",69ax=self.ax)70)7172self.plots["invalid_buy_entry_point"] = (73fplt.plot(candles["time"],74candles["invalid_buy_entry_point"],75style="^",76color="#000",77ax=self.ax,78legend="Не подходящая ТВ в лонг")79)80self.plots["invalid_sell_entry_point"] = (81fplt.plot(candles["time"],82candles["invalid_sell_entry_point"],83style="v",84color="#000",85ax=self.ax,86legend="Не подходящая ТВ в шорт")87)8889self.plots["valid_buy_entry_point"] = (90fplt.plot(candles["time"],91candles["valid_buy_entry_point"],92style="^",93color="#4a5",94ax=self.ax,95legend="Подходящая ТВ в лонг")96)97self.plots["valid_sell_entry_point"] = (98fplt.plot(candles["time"],99candles["valid_sell_entry_point"],100style="v",101color="#4a5",102ax=self.ax,103legend="Подходящая ТВ в шорт")104)105else:106# обновление данных графика после первого построения107# https://github.com/highfestiva/finplot/issues/131#issuecomment-786245998108self.plots["candles"].update_data(candles, gfx=False)109self.plots["max_volume_price"].update_data(max_volumes["max_volume_price"], gfx=False)110self.plots["invalid_buy_entry_point"].update_data(candles["invalid_buy_entry_point"], gfx=False)111self.plots["invalid_sell_entry_point"].update_data(candles["invalid_sell_entry_point"], gfx=False)112self.plots["valid_buy_entry_point"].update_data(candles["valid_buy_entry_point"], gfx=False)113self.plots["valid_sell_entry_point"].update_data(candles["valid_sell_entry_point"], gfx=False)114115for key, plot in self.plots.items():116plot.update_gfx()117118if clusters is not None:119for index, cluster in clusters.iterrows():120cluster_time = cluster["time"]121cluster_price = cluster["max_volume_price"]122# todo прибавляю 55мин по той причине, что целый час еще не сформировался на графике123# крайней датой может быть 15:59:59.230333+00:00124end_time = cluster_time + timedelta(minutes=55)125fplt.add_line((cluster_time, cluster_price),126(end_time, cluster_price),127color="#80878787",128ax=self.ax)129130fplt.autoviewrestore()131132133