Skip to content

Commit

Permalink
+ Разоблачение стратегий +300% +600% +790% )))
Browse files Browse the repository at this point in the history
  • Loading branch information
WISEPLAT committed Aug 11, 2022
1 parent 3b52df1 commit 9c2c0eb
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 11 deletions.
42 changes: 42 additions & 0 deletions Strategy2_44.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ def __init__(self):

self.orders_bar_executed = defaultdict(list)

self.my_logs = []

print(self.p.lots)


Expand All @@ -36,6 +38,20 @@ def log(self, txt, dt=None):
self.datas[0].datetime[0]) if dt is None else dt # Заданная дата или дата последнего бара первого тикера ТС
print(f'{dt.strftime("%d.%m.%Y %H:%M")}, {txt}') # Выводим дату и время с заданным текстом на консоль

def log_csv(self, ticker=None, signal=None, signal_price=None, order=None, order_price=None,
size=None, status=None, cost=None, comm=None, amount=None, pnl=None, dt=None):
"""Собираем логи для csv файла"""

tradedate = bt.num2date(self.datas[0].datetime[0]) if dt is None else dt # Заданная дата или дата последнего бара первого тикера ТС
depo = f"{self.cerebro.broker.get_cash():.2f}"
amount = f"{(self.cerebro.broker.get_value()):.2f}" # - (self.cerebro.broker.get_cash()):.2f}"
strategy_name = self.p.name
info = ""
if order == "BUY" and float(cost) < 0: info = "Warning"

self.my_logs.append([tradedate, ticker, signal, signal_price, order, order_price, size, status,
cost, comm, pnl, amount, depo, strategy_name, info])

def next(self):
"""
Приход нового бара тикера
Expand All @@ -46,9 +62,20 @@ def next(self):
return # то еще не пришли все новые бары. Ждем дальше, выходим
#print(self.p.name)
for data in self.datas: # Пробегаемся по всем запрошенным тикерам

ticker = data._dataname

if self.p.symbols == '' or data._dataname in self.p.symbols: # Если торгуем все тикеры или данный тикер
self.log(f'{data._dataname} - {bt.TimeFrame.Names[data.p.timeframe]} {data.p.compression} - Open={data.open[0]:.2f}, High={data.high[0]:.2f}, Low={data.low[0]:.2f}, Close={data.close[0]:.2f}, Volume={data.volume[0]:.0f}',
bt.num2date(data.datetime[0]))

_close = data.close[0] # текущий close
_low = data.low[0] # текущий low
_high = data.high[0] # текущий high
_open = data.open[0]
_oc2 = (_open + _close) / 2
_volume = data.volume # ссылка на Объемы # print(volume[0])

print("close: ", data.close[0])

self.dataclose = data.close
Expand Down Expand Up @@ -76,6 +103,8 @@ def next(self):
# BUY, BUY, BUY!!! (with default parameters)
self.log('BUY CREATE, %.2f' % self.dataclose[0])

self.log_csv(ticker=ticker, signal='BUY', signal_price=_close) #, size=size)

# Keep track of the created order to avoid a 2nd order
self.order = self.buy(data=data) #, size=size)

Expand All @@ -88,6 +117,8 @@ def next(self):
# SELL, SELL, SELL!!! (with all possible default parameters)
self.log('SELL CREATE, %.2f' % self.dataclose[0])

self.log_csv(ticker=ticker, signal='SELL', signal_price=_close) #, size=size)

# Keep track of the created order to avoid a 2nd order
self.order = self.sell(data=data)
except:
Expand All @@ -101,6 +132,10 @@ def notify_trade(self, trade):
(trade.pnl, trade.pnlcomm))

def notify_order(self, order):

ticker = order.data._name
size = order.size

if order.status in [order.Submitted, order.Accepted]:
# Buy/Sell order submitted/accepted to/by broker - Nothing to do
return
Expand All @@ -110,8 +145,15 @@ def notify_order(self, order):
if order.status in [order.Completed]:
if order.isbuy():
self.log('BUY EXECUTED, %.2f' % order.executed.price)
self.log_csv(ticker=ticker, order='BUY', order_price=order.executed.price, size=size,
status=order.getstatusname(order.status), cost=f"{order.executed.value:.2f}",
comm=f"{order.executed.comm:.2f}")
elif order.issell():
self.log('SELL EXECUTED, %.2f' % order.executed.price)
self.log_csv(ticker=ticker, order='SELL', order_price=order.executed.price, size=size,
status=order.getstatusname(order.status),
cost=f"{order.executed.value + order.executed.pnl:.2f}",
comm=f"{order.executed.comm:.2f}", pnl=f"{order.executed.pnl:.2f}")

self.bar_executed = len(self)
self.orders_bar_executed[order.data._name] = len(self)
Expand Down
32 changes: 29 additions & 3 deletions StrategySMA2_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ def __init__(self):
self.price_buy = defaultdict(list)
self.size_buy = defaultdict(list)

self.my_logs = []

for i in range(len(self.datas)):
ticker = list(self.dnames.keys())[i] # key name is ticker name
self.sma_all1[ticker] = bt.indicators.SMA(self.datas[i], period=8)
Expand All @@ -54,6 +56,20 @@ def log(self, txt, dt=None):
self.datas[0].datetime[0]) if dt is None else dt # Заданная дата или дата последнего бара первого тикера ТС
print(f'{dt.strftime("%d.%m.%Y %H:%M")}, {txt}') # Выводим дату и время с заданным текстом на консоль

def log_csv(self, ticker=None, signal=None, signal_price=None, order=None, order_price=None,
size=None, status=None, cost=None, comm=None, amount=None, pnl=None, dt=None):
"""Собираем логи для csv файла"""

tradedate = bt.num2date(self.datas[0].datetime[0]) if dt is None else dt # Заданная дата или дата последнего бара первого тикера ТС
depo = f"{self.cerebro.broker.get_cash():.2f}"
amount = f"{(self.cerebro.broker.get_value()):.2f}" # - (self.cerebro.broker.get_cash()):.2f}"
strategy_name = self.p.name
info = ""
if order == "BUY" and float(cost) < 0: info = "Warning"

self.my_logs.append([tradedate, ticker, signal, signal_price, order, order_price, size, status,
cost, comm, pnl, amount, depo, strategy_name, info])

def next(self):
"""
Приход нового бара тикера
Expand Down Expand Up @@ -111,7 +127,6 @@ def next(self):
if not self.orders[ticker]:
if self.sma_all1[ticker] > self.sma_all2[ticker]:
#print(self.bbands[ticker].lines.top, self.bbands[ticker].lines.mid, self.bbands[ticker].lines.bot)
self.log(f"BUY CREATE [{ticker}] {self.data.close[0]:.2f}")

lot = self.p.lots[ticker]
percent = 3 # сколько % от депозита использовать на сделку
Expand All @@ -120,6 +135,8 @@ def next(self):

size = functions.calc_size(depo=depo, lot=lot, percent=percent, ticker_price=ticker_price)

self.log(f"BUY CREATE [{ticker}] {self.data.close[0]:.2f}")
self.log_csv(ticker=ticker, signal='BUY', signal_price=_close, size=size)
self.buy(data=data, exectype=bt.Order.Market, size=size)
self.orders[ticker] = True

Expand All @@ -133,6 +150,7 @@ def next(self):
# условие на продажу take-profit
if self.sma_all1[ticker] < self.sma_all2[ticker]:
self.log(f"SELL CREATE [{ticker}] {self.data.close[0]:.2f}")
self.log_csv(ticker=ticker, signal='SELL', signal_price=_close, size=size)
self.sell(data=data, exectype=bt.Order.Market, size=size)
self.orders[ticker] = False
# if _close>=self.price_buy[ticker]*(1+profit_percent*ratio_profit/100):
Expand All @@ -142,6 +160,7 @@ def next(self):
# условие на продажу stop-loss %
if _close<=self.price_buy[ticker]*(1-stop_loss_percent/100):
self.log(f"SELL STOP LOSS CREATE [{ticker}] {self.data.close[0]:.2f}")
self.log_csv(ticker=ticker, signal='STOP LOSS', signal_price=_close, size=size)
self.sell(data=data, exectype=bt.Order.Market, size=size)
self.orders[ticker] = False
# ==========================================================================================================================
Expand Down Expand Up @@ -201,12 +220,19 @@ def notify_order(self, order):
if order.status in [order.Completed]:
if order.isbuy():
self.log(f"BUY EXECUTED [{order.data._name}], {order.executed.price:.2f} size={size}")
self.log_csv(ticker=ticker, order='BUY', order_price=order.executed.price, size=size,
status=order.getstatusname(order.status), cost=f"{order.executed.value:.2f}",
comm=f"{order.executed.comm:.2f}")
self.price_buy[ticker] = order.executed.price # записываем цену покупки для тикера
self.size_buy[ticker] = size # записываем объем покупки для тикера
self.size_buy[ticker] = size # записываем объем покупки для тикера
elif order.issell():
self.log(f"SELL EXECUTED [{order.data._name}], {order.executed.price:.2f} size={size}")
self.log_csv(ticker=ticker, order='SELL', order_price=order.executed.price, size=size,
status=order.getstatusname(order.status),
cost=f"{order.executed.value + order.executed.pnl:.2f}",
comm=f"{order.executed.comm:.2f}", pnl=f"{order.executed.pnl:.2f}")
self.price_buy.pop(ticker, None) # удаляем цену покупки для тикера
self.size_buy.pop(ticker, None) # удаляем объем покупки для тикера
self.size_buy.pop(ticker, None) # удаляем объем покупки для тикера

self.bar_executed = len(self)

Expand Down
23 changes: 21 additions & 2 deletions functions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import datetime, os
import pandas as pd

def calc_size(depo, lot, percent, ticker_price):
"""
Функция расчета позиции
Expand All @@ -11,9 +14,10 @@ def calc_size(depo, lot, percent, ticker_price):
shares_can_buy = money / cost_lot
size_mod = shares_can_buy * lot # размер не кратный lot
size = round(size_mod / lot) * lot # размер кратный lot
print(money, cost_lot, shares_can_buy, size_mod, size)
# print(money, cost_lot, shares_can_buy, size_mod, size)
return size


def get_info_about_paper(qpProvider, symbols, show_log=False):
"""
Функция получения информацию по бумагам:
Expand All @@ -38,4 +42,19 @@ def get_info_about_paper(qpProvider, symbols, show_log=False):
f_decimal[symbol] = securityInfo['scale'] # сохраняем Кол-во десятичных знаков в глобальной переменной f_decimal
lots[symbol] = securityInfo['lot_size'] # сохраняем Лот в глобальной переменной lot

return syminfo_mintick, f_decimal, lots
return syminfo_mintick, f_decimal, lots


def export_log_to_csv(my_log, export_dir):
"""
Функция экспорта логов в csv файл
"""
time_log = datetime.datetime.now().strftime('%d-%m-%Y_%H-%M-%S')
df = pd.DataFrame(my_log, columns=('TRADEDATE', 'TICKER', 'SIGNAL', 'S.PRICE', 'ORDER', 'O.PRICE',
'SIZE', 'STATUS', 'COST', 'COMM', 'PNL', 'AMOUNT', 'DEPO', 'STRATEGY_NAME', 'INFO'))
if not os.path.exists(export_dir): os.makedirs(export_dir)
df.to_csv(os.path.join(export_dir, time_log+"_logs.csv"), index=False, encoding='utf-8', sep=";", decimal=".")

# запись имени последнего лог файла
with open(os.path.join(export_dir, 'last_log_filename.txt'), "w") as the_file:
the_file.write(time_log+"_logs.csv")
10 changes: 8 additions & 2 deletions main2_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from backtrader import Cerebro, TimeFrame
from BackTraderQuik.QKStore import QKStore # Хранилище QUIK
from QuikPy import QuikPy # Работа с QUIK из Python через LUA скрипты QuikSharp
import StrategySMA2_4 as ts # Торговые системы
import StrategySMA2_4_fix as ts # Торговые системы

import functions

Expand All @@ -15,6 +15,7 @@
symbols = ('TQBR.GAZP', ) # Кортеж тикеров
symbols = ('TQBR.GAZP', 'TQBR.AFKS',) # Кортеж тикеров
symbols = ('TQBR.AFKS', 'TQBR.SBER', 'TQBR.GAZP', 'TQBR.GMKN', 'TQBR.LKOH', ) # Кортеж тикеров
symbols = ('TQBR.GAZP',) # Кортеж тикеров


qpProvider = QuikPy() # Вызываем конструктор QuikPy с подключением к локальному компьютеру с QUIK
Expand All @@ -33,10 +34,15 @@
# cerebro.addstrategy(ts.TestStrategy01, name="Two Tickers", symbols=('TQBR.GAZP', 'TQBR.LKOH',)) # Добавляем торговую систему по двум тикерам
cerebro.addstrategy(ts.TestStrategy04, name="All Tickers", lots=lots) # Добавляем торговую систему по всем тикерам

cerebro.run() # Запуск торговой системы
strategy_runs = cerebro.run() # Запуск торговой системы
# cerebro.plot() # Рисуем график. Требуется matplotlib версии 3.2.2 (pip install matplotlib==3.2.2)

print('Стоимость портфеля: %.2f' % cerebro.broker.getvalue())
print('Свободные средства: %.2f' % cerebro.broker.get_cash())

my_log = strategy_runs[0].my_logs
functions.export_log_to_csv(my_log=my_log, export_dir="logs")

qpProvider.CloseConnectionAndThread() # Закрытие соединения с Quik

cerebro.plot(style='candle') # Рисуем график. Требуется matplotlib версии 3.2.2 (pip install matplotlib==3.2.2)
12 changes: 8 additions & 4 deletions main2_44.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import Strategy2_44 as ts # Торговые системы
from QuikPy import QuikPy # Работа с QUIK из Python через LUA скрипты QuikSharp

import functions

if __name__ == '__main__': # Точка входа при запуске этого скрипта
qpProvider = QuikPy() # Вызываем конструктор QuikPy с подключением к локальному компьютеру с QUIK
cerebro = Cerebro() # Инициируем "движок" BackTrader
Expand Down Expand Up @@ -44,12 +46,14 @@
#cerebro.addstrategy(ts.TestStrategy01, name="Two Tickers", symbols=('TQBR.GAZP', 'TQBR.LKOH',)) # Добавляем торговую систему по двум тикерам
cerebro.addstrategy(ts.TestStrategy01, name="All Tickers", lots=all_lots) # Добавляем торговую систему по всем тикерам

cerebro.run() # Запуск торговой системы
strategy_runs = cerebro.run() # Запуск торговой системы

print('Стоимость портфеля: %.2f' % cerebro.broker.getvalue())
print('Свободные средства: %.2f' % cerebro.broker.get_cash())

cerebro.plot(style='candle') # Рисуем график. Требуется matplotlib версии 3.2.2 (pip install matplotlib==3.2.2)
my_log = strategy_runs[0].my_logs
functions.export_log_to_csv(my_log=my_log, export_dir="logs")

# Выход
qpProvider.CloseConnectionAndThread() # Перед выходом закрываем соединение и поток QuikPy из любого экземпляра
qpProvider.CloseConnectionAndThread() # Закрытие соединения с Quik

cerebro.plot(style='candle') # Рисуем график. Требуется matplotlib версии 3.2.2 (pip install matplotlib==3.2.2)

0 comments on commit 9c2c0eb

Please sign in to comment.