Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import argparse
import datetime # For datetime objects
import os.path # To manage paths
import sys # To find out the script name (in argv[0])
import math
# Import the backtrader platform
import backtrader as bt
from backtrader.utils import flushfile # win32 quick stdout flushing
import pandas as pd
import numpy as np
class SimpleMLPPredictor(bt.Indicator):
lines = ('predict',)
params = (('period', 10),)
def __init__(self):
self.addminperiod(self.params.period)
def next(self):
self.lines.predict[0] = get_prediction(np.random.choice([0,1]))
# Create Custom position sizer
class FixedReverser(bt.Sizer):
params = (('stake', 1),)
def _getsizing(self, comminfo, cash, data, isbuy):
position = self.broker.getposition(data)
size = self.p.stake * (1 + (position.size != 0))
return size
#################################################
class LongShortStrategyESDaily(bt.Strategy):
params = dict(
smaperiod=10,
trade=False,
#stake=1,
exectype=bt.Order.Market,
stopafter=0,
valid=None,
cancel=0,
donotsell=False,
)
def log(self, txt, dt=None):
''' Logging function fot this strategy'''
dt = dt or self.datas[0].datetime.datetime(0)
print('%s, %s' % (dt.isoformat(), txt))
def __init__(self):
# Keep a reference to the "close" line in the data[0] dataseries
self.dataclose = self.datas[0].close
self.dataopen = self.datas[0].open
# To control operation entries
self.orderid = list()
self.order = None
self.counttostop = 0
self.datastatus = 0
# Create SMA on 2nd data
self.predict = SimpleMLPPredictor()
print('--------------------------------------------------')
print('Strategy Created')
print('--------------------------------------------------')
def notify_data(self, data, status, *args, **kwargs):
print('*' * 5, datetime.datetime.now(), 'DATA NOTIF:', data._getstatusname(status), *args)
if status == data.LIVE:
self.counttostop = self.p.stopafter
self.datastatus = 1
def notify_store(self, msg, *args, **kwargs):
print('*' * 5, datetime.datetime.now(), 'STORE NOTIF:', msg)
def notify_order(self, order):
if order.status in [order.Completed, order.Cancelled, order.Rejected]:
self.order = None
print('-' * 50, datetime.datetime.now(), 'ORDER BEGIN')
print(order)
print('-' * 50, datetime.datetime.now(), 'ORDER END')
def notify_trade(self, trade):
print('-' * 50, datetime.datetime.now(), 'TRADE BEGIN')
print(trade)
print('-' * 50, datetime.datetime.now(), 'TRADE END')
def prenext(self):
self.next(frompre=True)
def next(self, frompre=False):
txt = list()
txt.append('%04d' % len(self))
dtfmt = '%Y-%m-%dT%H:%M:%S.%f'
txt.append('%s' % self.data.datetime.datetime(0).strftime(dtfmt))
txt.append('{}'.format(self.data.open[0]))
txt.append('{}'.format(self.data.high[0]))
txt.append('{}'.format(self.data.low[0]))
txt.append('{}'.format(self.data.close[0]))
txt.append('{}'.format(self.data.volume[0]))
txt.append('{}'.format(self.position.size))
txt.append('{}'.format(self.predict[0]))
print(', '.join(txt))
if self.counttostop: # stop after x live lines
self.counttostop -= 1
if not self.counttostop:
self.env.runstop()
return
if not self.p.trade:
return
if self.datastatus and not self.position and len(self.orderid) < 1:
if self.predict[0] == 1:
# BUY, BUY, BUY!!! (with all possible default parameters)
self.log('GO LONG, %.2f' % self.data.close[0])
# Keep track of the created order to avoid a 2nd order
self.order = self.buy()
elif self.predict[0] == 0:
# SELL, SELL, SELL!!! (with all possible default parameters)
self.log('GO SHORT, %.2f' % self.data.close[0])
# Keep track of the created order to avoid a 2nd order
self.order = self.sell()
self.orderid.append(self.order)
elif self.datastatus and self.position.size > 0:
if self.predict[0] == 1:
pass
# BUY, BUY, BUY!!! (with all possible default parameters)
#self.log('GO LONG, %.2f' % self.dataclose[0])
# Keep track of the created order to avoid a 2nd order
#self.order = self.buy()
elif self.predict[0] == 0:
# SELL, SELL, SELL!!! (with all possible default parameters)
self.log('REVERSE LONG TO SHORT, %.2f' % self.data.close[0])
# Keep track of the created order to avoid a 2nd order
self.order = self.sell()
self.orderid.append(self.order)
elif self.datastatus and self.position.size < 0:
if self.predict[0] == 1:
# BUY, BUY, BUY!!! (with all possible default parameters)
self.log('REVERSE SHORT TO LONG, %.2f' % self.data.close[0])
# Keep track of the created order to avoid a 2nd order
self.order = self.buy()
elif self.predict[0] == 0:
pass
# SELL, SELL, SELL!!! (with all possible default parameters)
#self.log('GO SHORT, %.2f' % self.dataclose[0])
# Keep track of the created order to avoid a 2nd order
#self.order = self.sell()
elif self.order is not None and self.p.cancel:
if self.datastatus > self.p.cancel:
self.cancel(self.order)
if self.datastatus:
self.datastatus += 1
def start(self):
if self.data0.contractdetails is not None:
print('Timezone from ContractDetails: {}'.format(
self.data0.contractdetails.m_timeZoneId))
header = ['Datetime', 'Open', 'High', 'Low', 'Close', 'Volume',
'OpenPositionSize', 'Forecast']
print(', '.join(header))
self.done = False
def runstrategy():
# Create a cerebro
cerebro = bt.Cerebro()
storekwargs = dict(
host='127.0.0.1', port=4003,
clientId=103,
timeoffset=not None,
reconnect=3,
timeout=3.0,
notifyall=None,
_debug=None
)
ibstore = bt.stores.IBStore(**storekwargs)
broker = ibstore.getbroker()
cerebro.setbroker(broker)
timeframe = bt.TimeFrame.Days
datatf = datatf1 = bt.TimeFrame.Ticks
datacomp = datacomp1 = 1
IBDataFactory = ibstore.getdata
datakwargs = dict(
timeframe=datatf,
compression=datacomp,
historical=None,
#fromdate=None,
fromdate=datetime.datetime(2016, 12, 1),
#todate=datetime.datetime(2016, 12, 3),
rtbar=None,
qcheck=0.5,
what=None,
backfill_start=not None,
backfill=not None,
latethrough=None,
tz=None
)
data0 = IBDataFactory(dataname='ES-201703-GLOBEX', **datakwargs)
rekwargs = dict(
timeframe=timeframe,
compression=datacomp,
bar2edge=not None,
adjbartime=not None,
rightedge=not None,
takelate=not None,
)
cerebro.resampledata(dataname=data0, **rekwargs)
cerebro.addstrategy(LongShortStrategyESDaily,
smaperiod=10,
trade=True,
exectype=bt.bt.Order.Market,
#stake=1,
stopafter=None,
valid=None,
cancel=0,
donotsell=None
)
cerebro.addsizer(FixedReverser)
# Live data ... avoid long data accumulation by switching to "exactbars"
cerebro.run()
#if args.plot and args.exactbars < 1: # plot if possible
cerebro.plot()
if __name__ == '__main__':
runstrategy()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.