Path: blob/master/ invest-robot-contest_trading_bot-master/trading/strategy/str1.py
5935 views
from trading.candles.add_indicators import add_ema, add_macd, add_adx1import matplotlib.pyplot as plt2from trading.candles.get_candles import create_hour_graph, create_15_min_graph3import dataframe_image as dfi4from pandas_style.strategy_1 import color_macd5from math import isnan6from trading.get_securities import security_incr_by_figi, security_name_by_figi7from trading.place_order import sell_sfb, buy_order8import pandas as pd9import sqlite3 as sl10from main import bot11from trading.check_av import check_time, check_money12from trading.trade_help import in_lot_figi, quotation_to_float, get_price_figi13import time1415'''1617Функция, которая позволяет получить графики бумаг, а также таблицу со значениями индикаторов18Полученные данные будут использованы в телеграм-боте для визуализации стратегии1920'''212223def statistic_str1(figi, user_id, period=4, hour_graph=True):24# Создаём график и добавляем индикаторы2526if hour_graph:27df = create_hour_graph(figi, user_id, week=period, save=False)28else:29df = create_15_min_graph(figi, user_id, days=period, save=False)3031df = add_ema(df=df, window=7)32df = add_ema(df=df, window=21)33df = add_macd(df)34df = add_adx(df=df, window=14)3536# Добавляем индикаторы EMA на график для наглядности37df.plot(x='time_graph', y='close')38ax = df.plot(x='time_graph', y='close')39df.plot(ax=ax, x="time_graph", y="ema_7", color='green')40df.plot(ax=ax, x="time_graph", y="ema_21", color='red')4142price_growth = False43incr = security_incr_by_figi(figi, user_id)44trend_power = ''4546for i in df.index:4748if i > 0 and (df['ema_7'][i - 1] > df['ema_21'][i - 1]) and (df['ema_7'][i] < df['ema_21'][i]) or (49i > 0 and (isnan(df['ema_21'][i - 1])) and (df['ema_7'][i] < df['ema_21'][i])):50plt.arrow(x=i, y=df['ema_7'][i] + incr * 120, dx=0, dy=-incr * 80, width=0.6, color='red',51head_length=incr * 15)52elif i > 0 and (df['ema_7'][i - 1] < df['ema_21'][i - 1]) and (df['ema_7'][i] > df['ema_21'][i]) or (53i > 0 and (isnan(df['ema_21'][i - 1])) and (df['ema_7'][i] > df['ema_21'][i])):54plt.arrow(x=i, y=df['ema_7'][i] - incr * 120, dx=0, dy=incr * 80, width=0.6, color='green',55head_length=incr * 15)5657if df['ema_7'].iloc[-1] > df['ema_21'].iloc[-1]:58if df['macd'].iloc[-1] > 0:59if df['adx'].iloc[-1] > 20:60price_growth = True6162if hour_graph:63plt.savefig(f"img/str1/graph/hour_{figi}.png")64else:65plt.savefig(f"img/str1/graph/15_min_{figi}.png")6667plt.clf()6869style_df = df[-10:].drop(['time', 'open', 'low', 'high', 'orders'], axis=1)70style_df = style_df.style.apply(color_macd)7172if hour_graph:73dfi.export(style_df, f"img/str1/ind/hour_{figi}.png")74else:75dfi.export(style_df, f"img/str1/ind/15_min_{figi}.png")7677if df['adx'].iloc[-1] < 20:78trend_power = 'Слабый тренд'79elif df['adx'].iloc[-1] < 40:80trend_power = 'Умеренный тренд'81elif df['adx'].iloc[-1] < 60:82trend_power = 'Сильный тренд'83elif df['adx'].iloc[-1] < 80:84trend_power = 'Очень сильный тренд'85elif df['adx'].iloc[-1] < 100:86trend_power = 'Слишком сильный тренд'8788return price_growth, trend_power899091'''9293Функция, которая позволяет запускать торговый алгоритм для бумаг, которые имеют фалг True9495'''969798async def start_str1():99conn = sl.connect("db/BotDB.db")100cur = conn.cursor()101102shares = cur.execute(103'SELECT user_id, account_id, account_type, figi, buy_price, currency, quantity_lots, macd_border, adx_border, '104'take_profit, '105'stop_loss FROM str1_config WHERE trade_status = ? and account_access = ? ',106("True", "1")).fetchall()107108for line in shares:109user_id = line[0]110account_id = line[1]111account_type = line[2]112figi = line[3]113buy_price = line[4]114currency = line[5]115quantity_lots = line[6]116macd_border = line[7]117adx_border = line[8]118take_profit = line[9]119stop_loss = line[10]120121if check_time(user_id=user_id, figi=figi)[0] or account_type == "sandbox":122123if check_money(user_id=user_id, price=get_price_figi(figi=figi, user_id=user_id),124quantity=quantity_lots * in_lot_figi(figi=figi, user_id=user_id), currency=currency,125account_id=account_id, account_type=account_type):126await trade_str1(user_id=user_id, account_id=account_id, account_type=account_type, figi=figi,127buy_price=buy_price,128currency=currency, quantity_lots=quantity_lots, macd_border=macd_border,129adx_border=adx_border,130take_profit=take_profit, stop_loss=stop_loss)131132133'''134135Функция, которая анализирует торговые индикаторы и покупает или продаёт бумаги136137'''138139140async def trade_str1(user_id, account_id, account_type, figi, buy_price, currency, quantity_lots,141macd_border,142adx_border, take_profit,143stop_loss, period=4):144# Создаём график и добавляем индикаторы145146df = create_hour_graph(user_id=user_id, figi=figi, week=period, save=False)147148df = add_ema(df=df, window=7)149df = add_ema(df=df, window=21)150df = add_macd(df)151df = add_adx(df=df, window=14)152153macd_count = 0 # консолидируется ли macd154155connection = sl.connect("db/BotDB.db")156cursor = connection.cursor()157158for i in df.index:159160if i > len(df.index) - 6:161if 1.12 > df["macd"][i - 1] / df["macd"][i] < 0.88:162if macd_count < 3:163macd_count += 1164elif macd_count > 0:165macd_count -= 1166167if buy_price == 0.0: # Если не было покупки168169if (df["macd"].iloc[-1] > macd_border) and (df["macd"].iloc[-1] < df["macd"].iloc[-2]) and (170df["adx"].iloc[-1] > adx_border) and (df["ema_7"].iloc[-1] > df["ema_21"].iloc[-1]) and (171macd_count < 3):172order = buy_order(user_id=user_id, figi=figi, price=0.0, quantity_lots=quantity_lots,173via="str1_auto", account_id=account_id, account_type=account_type)174if order:175await bot.send_message(chat_id=user_id,176text=f"Покупка акций {security_name_by_figi(figi, user_id)} по цене {quotation_to_float(order.executed_order_price)}")177cursor.execute(178"UPDATE str1_config SET buy_price=?, currency = ? WHERE user_id = ? AND figi = ? AND "179"account_id = ?",180(quotation_to_float(order.executed_order_price), currency, user_id, figi, account_id))181182183else: # Если была покупка184if df["ema_7"].iloc[-1] < df["ema_21"].iloc[-1] or macd_count >= 4 or (185df["macd"].iloc[-1] / df["macd"].iloc[-1] < 0.955) or (186buy_price / df["close"].iloc[-1] < 1 - stop_loss) or (187buy_price / df["close"].iloc[-1] > 1 + take_profit):188order = sell_sfb(figi=figi, price=0, user_id=user_id, quantity_lots=quantity_lots, via="str1_auto",189account_id=account_id, account_type=account_type)190if order:191await bot.send_message(chat_id=user_id,192text=f"Продажа акций {security_name_by_figi(figi, user_id)} по цене {quotation_to_float(order.executed_order_price)}")193cursor.execute(194"UPDATE str1_config SET buy_price=0.0, currency = ? WHERE user_id = ? AND figi = ? AND account_id "195"= ?",196(currency, user_id, figi, account_id))197198connection.commit()199200return 0201202203'''204205Функция, которая позволяет получить использовать алгоритм на исторических данных.206Такой способ поможет протестировать стратегию и улучшить её.207208'''209210211def analyze_ema_adx_macd(figi, user_id, period=4, hour_graph=True, macd_border=0, adx_border=20, take_profit=0.02,212stop_loss=0.03):213# Создаём график и добавляем индикаторы214215if hour_graph:216df = create_hour_graph(figi, user_id=user_id, week=period, save=False)217else:218df = create_15_min_graph(figi, user_id=user_id, days=period, save=False)219220df = add_ema(df=df, window=7)221df = add_ema(df=df, window=21)222df = add_macd(df)223df = add_adx(df=df, window=14)224225# Добавляем индикаторы EMA на график для наглядности226df.plot(x='time_graph', y='close')227ax = df.plot(x='time_graph', y='close')228df.plot(ax=ax, x="time_graph", y="ema_7", color='green')229df.plot(ax=ax, x="time_graph", y="ema_21", color='red')230231buy_flag = False # Была ли уже покупка232macd_count = 0 # консолидируется ли macd233stop = False234buy_price = 0.0235incr = security_incr_by_figi(user_id=user_id, figi=figi)236total = 0.0237stat_df = pd.DataFrame(columns=["date", "time", "sum", "operation"])238239for i in df.index:240241if i > 0 and (df['ema_7'][i - 1] > df['ema_21'][i - 1]) and (df['ema_7'][i] < df['ema_21'][i]) or (242i > 0 and (isnan(df['ema_21'][i - 1])) and (df['ema_7'][i] < df['ema_21'][i])):243plt.arrow(x=i, y=df['ema_7'][i] + incr * 120, dx=0, dy=-incr * 80, width=0.6, color='red',244head_length=incr * 15)245elif i > 0 and (df['ema_7'][i - 1] < df['ema_21'][i - 1]) and (df['ema_7'][i] > df['ema_21'][i]) or (246i > 0 and (isnan(df['ema_21'][i - 1])) and (df['ema_7'][i] > df['ema_21'][i])):247plt.arrow(x=i, y=df['ema_7'][i] - incr * 120, dx=0, dy=incr * 80, width=0.6, color='green',248head_length=incr * 15)249250if i > 0:251if 1.12 > df["macd"][i - 1] / df["macd"][i] < 0.88:252if macd_count < 3:253macd_count += 1254elif macd_count > 0:255macd_count -= 1256257if stop:258stop = False259260elif not buy_flag: # Если не было покупки261if df["macd"][i] > macd_border:262if df["macd"][i - 1] < df["macd"][i]: # Если MACD растёт263if macd_count < 3: # Если MACD не стоит на месте264if df["adx"][i] > adx_border:265if df["ema_7"][i] > df["ema_21"][i]:266buy_flag = True267plt.axvline(x=i, color="green")268buy_price = df["close"][i]269insert_df = pd.DataFrame({270"date": [df["time_graph"][i]],271"time": [df["hour_graph"][i]],272"sum": [-(df["low"][i] + df["high"][i]) / 2],273"operation": ["Покупка"],274}275)276stat_df = pd.concat([stat_df, insert_df], ignore_index=True)277total -= (df["low"][i] + df["high"][i]) / 2 * 1.003278279280elif buy_flag: # Если была покупка281if df["ema_7"][i] < df["ema_21"][i] or macd_count >= 4 or (282df["macd"][i] / df["macd"][i - 1] < 0.955) or (buy_price / df["close"][i] < 1 - stop_loss) or (283buy_price / df["close"][i] > 1 + take_profit):284buy_flag = False285plt.axvline(x=i, color="red")286stop = True287insert_df = pd.DataFrame({288"date": [df["time_graph"][i]],289"time": [df["hour_graph"][i]],290"sum": [(df["low"][i] + df["high"][i]) / 2],291"operation": ["Продажа"],292}293294)295stat_df = pd.concat([stat_df, insert_df], ignore_index=True)296total += (df["low"][i] + df["high"][i]) / 2 * 0.997297298insert_df = pd.DataFrame({299"date": [0],300"time": [0],301"sum": [total],302"operation": ["Итог"],303}304305)306stat_df = pd.concat([stat_df, insert_df], ignore_index=True)307308if hour_graph:309plt.savefig(f"img/str1/test/graph/hour_{figi}.png")310else:311plt.savefig(f"img/str1/test/graph/15_min_{figi}.png")312313plt.clf()314315style_df = df[-11:].drop(['time', 'open', 'low', 'high', 'orders'], axis=1)316style_df = style_df.style.apply(color_macd)317318if hour_graph:319dfi.export(style_df, f"img/str1/test/ind/hour_{figi}.png")320dfi.export(stat_df, f"img/str1/test/total/hour_{figi}.png")321else:322dfi.export(style_df, f"img/str1/test/ind/15_min_{figi}.png")323# dfi.export(stat_df, f"img/str1/test/total/15_min_{figi}.png")324325return stat_df326327328