Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/ invest-robot-contest_trading_bot-master/trading/strategy/str1.py
5935 views
1
from trading.candles.add_indicators import add_ema, add_macd, add_adx
2
import matplotlib.pyplot as plt
3
from trading.candles.get_candles import create_hour_graph, create_15_min_graph
4
import dataframe_image as dfi
5
from pandas_style.strategy_1 import color_macd
6
from math import isnan
7
from trading.get_securities import security_incr_by_figi, security_name_by_figi
8
from trading.place_order import sell_sfb, buy_order
9
import pandas as pd
10
import sqlite3 as sl
11
from main import bot
12
from trading.check_av import check_time, check_money
13
from trading.trade_help import in_lot_figi, quotation_to_float, get_price_figi
14
import time
15
16
'''
17
18
Функция, которая позволяет получить графики бумаг, а также таблицу со значениями индикаторов
19
Полученные данные будут использованы в телеграм-боте для визуализации стратегии
20
21
'''
22
23
24
def statistic_str1(figi, user_id, period=4, hour_graph=True):
25
# Создаём график и добавляем индикаторы
26
27
if hour_graph:
28
df = create_hour_graph(figi, user_id, week=period, save=False)
29
else:
30
df = create_15_min_graph(figi, user_id, days=period, save=False)
31
32
df = add_ema(df=df, window=7)
33
df = add_ema(df=df, window=21)
34
df = add_macd(df)
35
df = add_adx(df=df, window=14)
36
37
# Добавляем индикаторы EMA на график для наглядности
38
df.plot(x='time_graph', y='close')
39
ax = df.plot(x='time_graph', y='close')
40
df.plot(ax=ax, x="time_graph", y="ema_7", color='green')
41
df.plot(ax=ax, x="time_graph", y="ema_21", color='red')
42
43
price_growth = False
44
incr = security_incr_by_figi(figi, user_id)
45
trend_power = ''
46
47
for i in df.index:
48
49
if i > 0 and (df['ema_7'][i - 1] > df['ema_21'][i - 1]) and (df['ema_7'][i] < df['ema_21'][i]) or (
50
i > 0 and (isnan(df['ema_21'][i - 1])) and (df['ema_7'][i] < df['ema_21'][i])):
51
plt.arrow(x=i, y=df['ema_7'][i] + incr * 120, dx=0, dy=-incr * 80, width=0.6, color='red',
52
head_length=incr * 15)
53
elif i > 0 and (df['ema_7'][i - 1] < df['ema_21'][i - 1]) and (df['ema_7'][i] > df['ema_21'][i]) or (
54
i > 0 and (isnan(df['ema_21'][i - 1])) and (df['ema_7'][i] > df['ema_21'][i])):
55
plt.arrow(x=i, y=df['ema_7'][i] - incr * 120, dx=0, dy=incr * 80, width=0.6, color='green',
56
head_length=incr * 15)
57
58
if df['ema_7'].iloc[-1] > df['ema_21'].iloc[-1]:
59
if df['macd'].iloc[-1] > 0:
60
if df['adx'].iloc[-1] > 20:
61
price_growth = True
62
63
if hour_graph:
64
plt.savefig(f"img/str1/graph/hour_{figi}.png")
65
else:
66
plt.savefig(f"img/str1/graph/15_min_{figi}.png")
67
68
plt.clf()
69
70
style_df = df[-10:].drop(['time', 'open', 'low', 'high', 'orders'], axis=1)
71
style_df = style_df.style.apply(color_macd)
72
73
if hour_graph:
74
dfi.export(style_df, f"img/str1/ind/hour_{figi}.png")
75
else:
76
dfi.export(style_df, f"img/str1/ind/15_min_{figi}.png")
77
78
if df['adx'].iloc[-1] < 20:
79
trend_power = 'Слабый тренд'
80
elif df['adx'].iloc[-1] < 40:
81
trend_power = 'Умеренный тренд'
82
elif df['adx'].iloc[-1] < 60:
83
trend_power = 'Сильный тренд'
84
elif df['adx'].iloc[-1] < 80:
85
trend_power = 'Очень сильный тренд'
86
elif df['adx'].iloc[-1] < 100:
87
trend_power = 'Слишком сильный тренд'
88
89
return price_growth, trend_power
90
91
92
'''
93
94
Функция, которая позволяет запускать торговый алгоритм для бумаг, которые имеют фалг True
95
96
'''
97
98
99
async def start_str1():
100
conn = sl.connect("db/BotDB.db")
101
cur = conn.cursor()
102
103
shares = cur.execute(
104
'SELECT user_id, account_id, account_type, figi, buy_price, currency, quantity_lots, macd_border, adx_border, '
105
'take_profit, '
106
'stop_loss FROM str1_config WHERE trade_status = ? and account_access = ? ',
107
("True", "1")).fetchall()
108
109
for line in shares:
110
user_id = line[0]
111
account_id = line[1]
112
account_type = line[2]
113
figi = line[3]
114
buy_price = line[4]
115
currency = line[5]
116
quantity_lots = line[6]
117
macd_border = line[7]
118
adx_border = line[8]
119
take_profit = line[9]
120
stop_loss = line[10]
121
122
if check_time(user_id=user_id, figi=figi)[0] or account_type == "sandbox":
123
124
if check_money(user_id=user_id, price=get_price_figi(figi=figi, user_id=user_id),
125
quantity=quantity_lots * in_lot_figi(figi=figi, user_id=user_id), currency=currency,
126
account_id=account_id, account_type=account_type):
127
await trade_str1(user_id=user_id, account_id=account_id, account_type=account_type, figi=figi,
128
buy_price=buy_price,
129
currency=currency, quantity_lots=quantity_lots, macd_border=macd_border,
130
adx_border=adx_border,
131
take_profit=take_profit, stop_loss=stop_loss)
132
133
134
'''
135
136
Функция, которая анализирует торговые индикаторы и покупает или продаёт бумаги
137
138
'''
139
140
141
async def trade_str1(user_id, account_id, account_type, figi, buy_price, currency, quantity_lots,
142
macd_border,
143
adx_border, take_profit,
144
stop_loss, period=4):
145
# Создаём график и добавляем индикаторы
146
147
df = create_hour_graph(user_id=user_id, figi=figi, week=period, save=False)
148
149
df = add_ema(df=df, window=7)
150
df = add_ema(df=df, window=21)
151
df = add_macd(df)
152
df = add_adx(df=df, window=14)
153
154
macd_count = 0 # консолидируется ли macd
155
156
connection = sl.connect("db/BotDB.db")
157
cursor = connection.cursor()
158
159
for i in df.index:
160
161
if i > len(df.index) - 6:
162
if 1.12 > df["macd"][i - 1] / df["macd"][i] < 0.88:
163
if macd_count < 3:
164
macd_count += 1
165
elif macd_count > 0:
166
macd_count -= 1
167
168
if buy_price == 0.0: # Если не было покупки
169
170
if (df["macd"].iloc[-1] > macd_border) and (df["macd"].iloc[-1] < df["macd"].iloc[-2]) and (
171
df["adx"].iloc[-1] > adx_border) and (df["ema_7"].iloc[-1] > df["ema_21"].iloc[-1]) and (
172
macd_count < 3):
173
order = buy_order(user_id=user_id, figi=figi, price=0.0, quantity_lots=quantity_lots,
174
via="str1_auto", account_id=account_id, account_type=account_type)
175
if order:
176
await bot.send_message(chat_id=user_id,
177
text=f"Покупка акций {security_name_by_figi(figi, user_id)} по цене {quotation_to_float(order.executed_order_price)}")
178
cursor.execute(
179
"UPDATE str1_config SET buy_price=?, currency = ? WHERE user_id = ? AND figi = ? AND "
180
"account_id = ?",
181
(quotation_to_float(order.executed_order_price), currency, user_id, figi, account_id))
182
183
184
else: # Если была покупка
185
if df["ema_7"].iloc[-1] < df["ema_21"].iloc[-1] or macd_count >= 4 or (
186
df["macd"].iloc[-1] / df["macd"].iloc[-1] < 0.955) or (
187
buy_price / df["close"].iloc[-1] < 1 - stop_loss) or (
188
buy_price / df["close"].iloc[-1] > 1 + take_profit):
189
order = sell_sfb(figi=figi, price=0, user_id=user_id, quantity_lots=quantity_lots, via="str1_auto",
190
account_id=account_id, account_type=account_type)
191
if order:
192
await bot.send_message(chat_id=user_id,
193
text=f"Продажа акций {security_name_by_figi(figi, user_id)} по цене {quotation_to_float(order.executed_order_price)}")
194
cursor.execute(
195
"UPDATE str1_config SET buy_price=0.0, currency = ? WHERE user_id = ? AND figi = ? AND account_id "
196
"= ?",
197
(currency, user_id, figi, account_id))
198
199
connection.commit()
200
201
return 0
202
203
204
'''
205
206
Функция, которая позволяет получить использовать алгоритм на исторических данных.
207
Такой способ поможет протестировать стратегию и улучшить её.
208
209
'''
210
211
212
def analyze_ema_adx_macd(figi, user_id, period=4, hour_graph=True, macd_border=0, adx_border=20, take_profit=0.02,
213
stop_loss=0.03):
214
# Создаём график и добавляем индикаторы
215
216
if hour_graph:
217
df = create_hour_graph(figi, user_id=user_id, week=period, save=False)
218
else:
219
df = create_15_min_graph(figi, user_id=user_id, days=period, save=False)
220
221
df = add_ema(df=df, window=7)
222
df = add_ema(df=df, window=21)
223
df = add_macd(df)
224
df = add_adx(df=df, window=14)
225
226
# Добавляем индикаторы EMA на график для наглядности
227
df.plot(x='time_graph', y='close')
228
ax = df.plot(x='time_graph', y='close')
229
df.plot(ax=ax, x="time_graph", y="ema_7", color='green')
230
df.plot(ax=ax, x="time_graph", y="ema_21", color='red')
231
232
buy_flag = False # Была ли уже покупка
233
macd_count = 0 # консолидируется ли macd
234
stop = False
235
buy_price = 0.0
236
incr = security_incr_by_figi(user_id=user_id, figi=figi)
237
total = 0.0
238
stat_df = pd.DataFrame(columns=["date", "time", "sum", "operation"])
239
240
for i in df.index:
241
242
if i > 0 and (df['ema_7'][i - 1] > df['ema_21'][i - 1]) and (df['ema_7'][i] < df['ema_21'][i]) or (
243
i > 0 and (isnan(df['ema_21'][i - 1])) and (df['ema_7'][i] < df['ema_21'][i])):
244
plt.arrow(x=i, y=df['ema_7'][i] + incr * 120, dx=0, dy=-incr * 80, width=0.6, color='red',
245
head_length=incr * 15)
246
elif i > 0 and (df['ema_7'][i - 1] < df['ema_21'][i - 1]) and (df['ema_7'][i] > df['ema_21'][i]) or (
247
i > 0 and (isnan(df['ema_21'][i - 1])) and (df['ema_7'][i] > df['ema_21'][i])):
248
plt.arrow(x=i, y=df['ema_7'][i] - incr * 120, dx=0, dy=incr * 80, width=0.6, color='green',
249
head_length=incr * 15)
250
251
if i > 0:
252
if 1.12 > df["macd"][i - 1] / df["macd"][i] < 0.88:
253
if macd_count < 3:
254
macd_count += 1
255
elif macd_count > 0:
256
macd_count -= 1
257
258
if stop:
259
stop = False
260
261
elif not buy_flag: # Если не было покупки
262
if df["macd"][i] > macd_border:
263
if df["macd"][i - 1] < df["macd"][i]: # Если MACD растёт
264
if macd_count < 3: # Если MACD не стоит на месте
265
if df["adx"][i] > adx_border:
266
if df["ema_7"][i] > df["ema_21"][i]:
267
buy_flag = True
268
plt.axvline(x=i, color="green")
269
buy_price = df["close"][i]
270
insert_df = pd.DataFrame({
271
"date": [df["time_graph"][i]],
272
"time": [df["hour_graph"][i]],
273
"sum": [-(df["low"][i] + df["high"][i]) / 2],
274
"operation": ["Покупка"],
275
}
276
)
277
stat_df = pd.concat([stat_df, insert_df], ignore_index=True)
278
total -= (df["low"][i] + df["high"][i]) / 2 * 1.003
279
280
281
elif buy_flag: # Если была покупка
282
if df["ema_7"][i] < df["ema_21"][i] or macd_count >= 4 or (
283
df["macd"][i] / df["macd"][i - 1] < 0.955) or (buy_price / df["close"][i] < 1 - stop_loss) or (
284
buy_price / df["close"][i] > 1 + take_profit):
285
buy_flag = False
286
plt.axvline(x=i, color="red")
287
stop = True
288
insert_df = pd.DataFrame({
289
"date": [df["time_graph"][i]],
290
"time": [df["hour_graph"][i]],
291
"sum": [(df["low"][i] + df["high"][i]) / 2],
292
"operation": ["Продажа"],
293
}
294
295
)
296
stat_df = pd.concat([stat_df, insert_df], ignore_index=True)
297
total += (df["low"][i] + df["high"][i]) / 2 * 0.997
298
299
insert_df = pd.DataFrame({
300
"date": [0],
301
"time": [0],
302
"sum": [total],
303
"operation": ["Итог"],
304
}
305
306
)
307
stat_df = pd.concat([stat_df, insert_df], ignore_index=True)
308
309
if hour_graph:
310
plt.savefig(f"img/str1/test/graph/hour_{figi}.png")
311
else:
312
plt.savefig(f"img/str1/test/graph/15_min_{figi}.png")
313
314
plt.clf()
315
316
style_df = df[-11:].drop(['time', 'open', 'low', 'high', 'orders'], axis=1)
317
style_df = style_df.style.apply(color_macd)
318
319
if hour_graph:
320
dfi.export(style_df, f"img/str1/test/ind/hour_{figi}.png")
321
dfi.export(stat_df, f"img/str1/test/total/hour_{figi}.png")
322
else:
323
dfi.export(style_df, f"img/str1/test/ind/15_min_{figi}.png")
324
# dfi.export(stat_df, f"img/str1/test/total/15_min_{figi}.png")
325
326
return stat_df
327
328