Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/ invest-robot-contest_tinkoff-invest-volume-analysis-robot-master/visualizers/finplot_graph.py
5927 views
1
import threading
2
from datetime import timedelta
3
4
import finplot as fplt
5
import numpy as np
6
import pandas as pd
7
8
from utils.strategy_util import ticks_to_cluster
9
10
11
class FinplotGraph(threading.Thread):
12
def __init__(self, signal_cluster_period):
13
super().__init__()
14
15
self.signal_cluster_period = signal_cluster_period
16
self.plots = {}
17
self.ax = None
18
19
def run(self):
20
self.ax = fplt.create_plot("Tinkoff Invest profile touch strategy", maximize=False)
21
self.ax.setLabel("right", "Цена")
22
self.ax.setLabel("bottom", "Дата / время")
23
fplt.show()
24
25
def render(
26
self,
27
df: pd.DataFrame,
28
valid_entry_points,
29
invalid_entry_points,
30
clusters=None
31
):
32
candles = ticks_to_cluster(df, period=self.signal_cluster_period)
33
34
# риски в свечах с максимальными объемами
35
max_volumes = candles[["time", "max_volume_price"]]
36
37
# не подтвержденные точки входа с разделением на лонг и шорт
38
# округление времени точек входа для сопоставления с графиком
39
round_invalid_times = [pd.to_datetime(time).ceil(self.signal_cluster_period) for time in invalid_entry_points]
40
candles["invalid_buy_entry_point"] = np.where(
41
candles["time"].isin(round_invalid_times) & (candles.shift()["direction"] == 1), candles["low"] - (
42
candles["low"] * 0.007 / 100), np.nan
43
)
44
candles["invalid_sell_entry_point"] = np.where(
45
candles["time"].isin(round_invalid_times) & (candles.shift()["direction"] == 2), candles["high"] + (
46
candles["high"] * 0.007 / 100), np.nan
47
)
48
49
# подтвержденные точки входа с разделением на лонг и шорт
50
# округление времени точек входа для сопоставления с графиком
51
round_valid_times = [pd.to_datetime(time).ceil(self.signal_cluster_period) for time in valid_entry_points]
52
candles["valid_buy_entry_point"] = np.where(
53
candles["time"].isin(round_valid_times) & (candles.shift()["direction"] == 1), candles["low"] - (
54
candles["low"] * 0.007 / 100), np.nan
55
)
56
candles["valid_sell_entry_point"] = np.where(
57
candles["time"].isin(round_valid_times) & (candles.shift()["direction"] == 2), candles["high"] + (
58
candles["high"] * 0.007 / 100), np.nan
59
)
60
61
if not self.plots:
62
# первое построение графика
63
self.plots["candles"] = (fplt.candlestick_ochl(candles))
64
65
self.plots["max_volume_price"] = (
66
fplt.plot(max_volumes["time"],
67
max_volumes["max_volume_price"],
68
style="d",
69
color="#808080",
70
ax=self.ax)
71
)
72
73
self.plots["invalid_buy_entry_point"] = (
74
fplt.plot(candles["time"],
75
candles["invalid_buy_entry_point"],
76
style="^",
77
color="#000",
78
ax=self.ax,
79
legend="Не подходящая ТВ в лонг")
80
)
81
self.plots["invalid_sell_entry_point"] = (
82
fplt.plot(candles["time"],
83
candles["invalid_sell_entry_point"],
84
style="v",
85
color="#000",
86
ax=self.ax,
87
legend="Не подходящая ТВ в шорт")
88
)
89
90
self.plots["valid_buy_entry_point"] = (
91
fplt.plot(candles["time"],
92
candles["valid_buy_entry_point"],
93
style="^",
94
color="#4a5",
95
ax=self.ax,
96
legend="Подходящая ТВ в лонг")
97
)
98
self.plots["valid_sell_entry_point"] = (
99
fplt.plot(candles["time"],
100
candles["valid_sell_entry_point"],
101
style="v",
102
color="#4a5",
103
ax=self.ax,
104
legend="Подходящая ТВ в шорт")
105
)
106
else:
107
# обновление данных графика после первого построения
108
# https://github.com/highfestiva/finplot/issues/131#issuecomment-786245998
109
self.plots["candles"].update_data(candles, gfx=False)
110
self.plots["max_volume_price"].update_data(max_volumes["max_volume_price"], gfx=False)
111
self.plots["invalid_buy_entry_point"].update_data(candles["invalid_buy_entry_point"], gfx=False)
112
self.plots["invalid_sell_entry_point"].update_data(candles["invalid_sell_entry_point"], gfx=False)
113
self.plots["valid_buy_entry_point"].update_data(candles["valid_buy_entry_point"], gfx=False)
114
self.plots["valid_sell_entry_point"].update_data(candles["valid_sell_entry_point"], gfx=False)
115
116
for key, plot in self.plots.items():
117
plot.update_gfx()
118
119
if clusters is not None:
120
for index, cluster in clusters.iterrows():
121
cluster_time = cluster["time"]
122
cluster_price = cluster["max_volume_price"]
123
# todo прибавляю 55мин по той причине, что целый час еще не сформировался на графике
124
# крайней датой может быть 15:59:59.230333+00:00
125
end_time = cluster_time + timedelta(minutes=55)
126
fplt.add_line((cluster_time, cluster_price),
127
(end_time, cluster_price),
128
color="#80878787",
129
ax=self.ax)
130
131
fplt.autoviewrestore()
132
133