1#!/usr/bin/env python 2# -*- coding: utf-8; py-indent-offset:4 -*- 3############################################################################### 4# 5# Copyright (C) 2015, 2016 Daniel Rodriguez 6# 7# This program is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19# 20############################################################################### 21from __future__ import (absolute_import, division, print_function,) 22# unicode_literals) 23 24import argparse 25import datetime 26 27import backtrader as bt 28import backtrader.feeds as btfeeds 29 30 31class St(bt.Strategy): 32 def __init__(self): 33 self.curdate = datetime.date.min 34 self.elapsed = 0 35 self.order = None 36 37 def notify_order(self, order): 38 curdtstr = self.data.datetime.datetime().strftime('%a %Y-%m-%d %H:%M:%S') 39 if order.status in [order.Completed]: 40 dtstr = bt.num2date(order.executed.dt).strftime('%a %Y-%m-%d %H:%M:%S') 41 if order.isbuy(): 42 print('%s: BUY EXECUTED, on:' % curdtstr, dtstr) 43 self.order = None 44 else: # Sell 45 print('%s: SELL EXECUTED, on:' % curdtstr, dtstr) 46 47 def next(self): 48 curdate = self.data.datetime.date() 49 if curdate > self.curdate: 50 self.elapsed += 1 51 self.curdate = curdate 52 53 dtstr = self.data.datetime.datetime().strftime('%a %Y-%m-%d %H:%M:%S') 54 if self.position and self.elapsed == 2: 55 print('%s: SELL CREATED' % dtstr) 56 self.close(exectype=bt.Order.Close) 57 self.elapsed = 0 58 elif self.order is None and self.elapsed == 2: # no pending order 59 print('%s: BUY CREATED' % dtstr) 60 self.order = self.buy(exectype=bt.Order.Close) 61 self.elapsed = 0 62 63 64def runstrat(): 65 args = parse_args() 66 67 cerebro = bt.Cerebro() 68 cerebro.adddata(getdata(args)) 69 cerebro.addstrategy(St) 70 if args.eosbar: 71 cerebro.broker.seteosbar(True) 72 73 cerebro.run() 74 75 76def getdata(args): 77 78 dataformat = dict( 79 bt=btfeeds.BacktraderCSVData, 80 visualchart=btfeeds.VChartCSVData, 81 sierrachart=btfeeds.SierraChartCSVData, 82 yahoo=btfeeds.YahooFinanceCSVData, 83 yahoo_unreversed=btfeeds.YahooFinanceCSVData 84 ) 85 86 dfkwargs = dict() 87 if args.csvformat == 'yahoo_unreversed': 88 dfkwargs['reverse'] = True 89 90 if args.fromdate: 91 fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d') 92 dfkwargs['fromdate'] = fromdate 93 94 if args.todate: 95 fromdate = datetime.datetime.strptime(args.todate, '%Y-%m-%d') 96 dfkwargs['todate'] = todate 97 98 if args.tend is not None: 99 # internally only the "time" part is used 100 dfkwargs['sessionend'] = datetime.datetime.strptime(args.tend, '%H:%M') 101 102 dfkwargs['dataname'] = args.infile 103 dfcls = dataformat[args.csvformat] 104 105 data = dfcls(**dfkwargs) 106 107 return data 108 109 110def parse_args(): 111 parser = argparse.ArgumentParser( 112 formatter_class=argparse.ArgumentDefaultsHelpFormatter, 113 description='Sample for Close Orders with daily data') 114 115 parser.add_argument('--infile', '-i', required=False, 116 default='../../datas/2006-min-005.txt', 117 help='File to be read in') 118 119 parser.add_argument('--csvformat', '-c', required=False, default='bt', 120 choices=['bt', 'visualchart', 'sierrachart', 121 'yahoo', 'yahoo_unreversed'], 122 help='CSV Format') 123 124 parser.add_argument('--fromdate', '-f', required=False, default=None, 125 help='Starting date in YYYY-MM-DD format') 126 127 parser.add_argument('--todate', '-t', required=False, default=None, 128 help='Ending date in YYYY-MM-DD format') 129 130 parser.add_argument('--eosbar', required=False, action='store_true', 131 help=('Consider a bar with the end of session time to' 132 'be the end of the session')) 133 134 parser.add_argument('--tend', '-te', 135 default=None, required=False, 136 help='End time for the Session Filter (HH:MM)') 137 138 return parser.parse_args() 139 140 141if __name__ == '__main__': 142 runstrat() 143