-
-
Save jaikumarm/b9b8124d880d683104971e25a4ab72c2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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