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