|
| 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 | +############################################################################### |
| 21 | +from __future__ import (absolute_import, division, print_function, |
| 22 | + unicode_literals) |
| 23 | + |
| 24 | +import argparse |
| 25 | +import datetime |
| 26 | + |
| 27 | +import backtrader as bt |
| 28 | + |
| 29 | + |
| 30 | +class TALibStrategy(bt.Strategy): |
| 31 | + params = (('ind', 'sma'), ('doji', True),) |
| 32 | + |
| 33 | + INDS = ['sma', 'ema', 'stoc', 'rsi', 'macd', 'bollinger', 'aroon', |
| 34 | + 'ultimate', 'trix', 'kama', 'adxr', 'dema', 'ppo', 'tema', |
| 35 | + 'roc', 'williamsr'] |
| 36 | + |
| 37 | + def __init__(self): |
| 38 | + if self.p.doji: |
| 39 | + bt.talib.CDLDOJI(self.data.open, self.data.high, |
| 40 | + self.data.low, self.data.close) |
| 41 | + |
| 42 | + if self.p.ind == 'sma': |
| 43 | + bt.talib.SMA(self.data.close, timeperiod=25, plotname='TA_SMA') |
| 44 | + bt.indicators.SMA(self.data, period=25) |
| 45 | + elif self.p.ind == 'ema': |
| 46 | + bt.talib.EMA(timeperiod=25, plotname='TA_SMA') |
| 47 | + bt.indicators.EMA(period=25) |
| 48 | + elif self.p.ind == 'stoc': |
| 49 | + bt.talib.STOCH(self.data.high, self.data.low, self.data.close, |
| 50 | + fastk_period=14, slowk_period=3, slowd_period=3, |
| 51 | + plotname='TA_STOCH') |
| 52 | + |
| 53 | + bt.indicators.Stochastic(self.data) |
| 54 | + |
| 55 | + elif self.p.ind == 'macd': |
| 56 | + bt.talib.MACD(self.data, plotname='TA_MACD') |
| 57 | + bt.indicators.MACD(self.data) |
| 58 | + bt.indicators.MACDHisto(self.data) |
| 59 | + elif self.p.ind == 'bollinger': |
| 60 | + bt.talib.BBANDS(self.data, timeperiod=25, |
| 61 | + plotname='TA_BBANDS') |
| 62 | + bt.indicators.BollingerBands(self.data, period=25) |
| 63 | + |
| 64 | + elif self.p.ind == 'rsi': |
| 65 | + bt.talib.RSI(self.data, plotname='TA_RSI') |
| 66 | + bt.indicators.RSI(self.data) |
| 67 | + |
| 68 | + elif self.p.ind == 'aroon': |
| 69 | + bt.talib.AROON(self.data.high, self.data.low, plotname='TA_AROON') |
| 70 | + bt.indicators.AroonIndicator(self.data) |
| 71 | + |
| 72 | + elif self.p.ind == 'ultimate': |
| 73 | + bt.talib.ULTOSC(self.data.high, self.data.low, self.data.close, |
| 74 | + plotname='TA_ULTOSC') |
| 75 | + bt.indicators.UltimateOscillator(self.data) |
| 76 | + |
| 77 | + elif self.p.ind == 'trix': |
| 78 | + bt.talib.TRIX(self.data, timeperiod=25, plotname='TA_TRIX') |
| 79 | + bt.indicators.Trix(self.data, period=25) |
| 80 | + |
| 81 | + elif self.p.ind == 'adxr': |
| 82 | + bt.talib.ADXR(self.data.high, self.data.low, self.data.close, |
| 83 | + plotname='TA_ADXR') |
| 84 | + bt.indicators.ADXR(self.data) |
| 85 | + |
| 86 | + elif self.p.ind == 'kama': |
| 87 | + bt.talib.KAMA(self.data, timeperiod=25, plotname='TA_KAMA') |
| 88 | + bt.indicators.KAMA(self.data, period=25) |
| 89 | + |
| 90 | + elif self.p.ind == 'dema': |
| 91 | + bt.talib.DEMA(self.data, timeperiod=25, plotname='TA_DEMA') |
| 92 | + bt.indicators.DEMA(self.data, period=25) |
| 93 | + |
| 94 | + elif self.p.ind == 'ppo': |
| 95 | + bt.talib.PPO(self.data, plotname='TA_PPO') |
| 96 | + bt.indicators.PPO(self.data, _movav=bt.indicators.SMA) |
| 97 | + |
| 98 | + elif self.p.ind == 'tema': |
| 99 | + bt.talib.TEMA(self.data, timeperiod=25, plotname='TA_TEMA') |
| 100 | + bt.indicators.TEMA(self.data, period=25) |
| 101 | + |
| 102 | + elif self.p.ind == 'roc': |
| 103 | + bt.talib.ROC(self.data, timeperiod=12, plotname='TA_ROC') |
| 104 | + bt.talib.ROCP(self.data, timeperiod=12, plotname='TA_ROCP') |
| 105 | + bt.talib.ROCR(self.data, timeperiod=12, plotname='TA_ROCR') |
| 106 | + bt.talib.ROCR100(self.data, timeperiod=12, plotname='TA_ROCR100') |
| 107 | + bt.indicators.ROC(self.data, period=12) |
| 108 | + bt.indicators.Momentum(self.data, period=12) |
| 109 | + bt.indicators.MomentumOscillator(self.data, period=12) |
| 110 | + |
| 111 | + elif self.p.ind == 'williamsr': |
| 112 | + bt.talib.WILLR(self.data.high, self.data.low, self.data.close, |
| 113 | + plotname='TA_WILLR') |
| 114 | + bt.indicators.WilliamsR(self.data) |
| 115 | + |
| 116 | + |
| 117 | +def runstrat(args=None): |
| 118 | + args = parse_args(args) |
| 119 | + |
| 120 | + cerebro = bt.Cerebro() |
| 121 | + |
| 122 | + dkwargs = dict() |
| 123 | + if args.fromdate: |
| 124 | + fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d') |
| 125 | + dkwargs['fromdate'] = fromdate |
| 126 | + |
| 127 | + if args.todate: |
| 128 | + todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d') |
| 129 | + dkwargs['todate'] = todate |
| 130 | + |
| 131 | + data0 = bt.feeds.YahooFinanceCSVData(dataname=args.data0, **dkwargs) |
| 132 | + cerebro.adddata(data0) |
| 133 | + |
| 134 | + cerebro.addstrategy(TALibStrategy, ind=args.ind, doji=not args.no_doji) |
| 135 | + |
| 136 | + cerebro.run(runcone=not args.use_next, stdstats=False) |
| 137 | + if args.plot: |
| 138 | + pkwargs = dict(style='candle') |
| 139 | + if args.plot is not True: # evals to True but is not True |
| 140 | + npkwargs = eval('dict(' + args.plot + ')') # args were passed |
| 141 | + pkwargs.update(npkwargs) |
| 142 | + |
| 143 | + cerebro.plot(**pkwargs) |
| 144 | + |
| 145 | + |
| 146 | +def parse_args(pargs=None): |
| 147 | + |
| 148 | + parser = argparse.ArgumentParser( |
| 149 | + formatter_class=argparse.ArgumentDefaultsHelpFormatter, |
| 150 | + description='Sample for sizer') |
| 151 | + |
| 152 | + parser.add_argument('--data0', required=False, |
| 153 | + default='../../datas/yhoo-1996-2015.txt', |
| 154 | + help='Data to be read in') |
| 155 | + |
| 156 | + parser.add_argument('--fromdate', required=False, |
| 157 | + default='2005-01-01', |
| 158 | + help='Starting date in YYYY-MM-DD format') |
| 159 | + |
| 160 | + parser.add_argument('--todate', required=False, |
| 161 | + default='2006-12-31', |
| 162 | + help='Ending date in YYYY-MM-DD format') |
| 163 | + |
| 164 | + parser.add_argument('--ind', required=False, action='store', |
| 165 | + default=TALibStrategy.INDS[0], |
| 166 | + choices=TALibStrategy.INDS, |
| 167 | + help=('Which indicator pair to show together')) |
| 168 | + |
| 169 | + parser.add_argument('--no-doji', required=False, action='store_true', |
| 170 | + help=('Remove Doji CandleStick pattern checker')) |
| 171 | + |
| 172 | + parser.add_argument('--use-next', required=False, action='store_true', |
| 173 | + help=('Use next (step by step) ' |
| 174 | + 'instead of once (batch)')) |
| 175 | + |
| 176 | + # Plot options |
| 177 | + parser.add_argument('--plot', '-p', nargs='?', required=False, |
| 178 | + metavar='kwargs', const=True, |
| 179 | + help=('Plot the read data applying any kwargs passed\n' |
| 180 | + '\n' |
| 181 | + 'For example (escape the quotes if needed):\n' |
| 182 | + '\n' |
| 183 | + ' --plot style="candle" (to plot candles)\n')) |
| 184 | + |
| 185 | + if pargs is not None: |
| 186 | + return parser.parse_args(pargs) |
| 187 | + |
| 188 | + return parser.parse_args() |
| 189 | + |
| 190 | + |
| 191 | +if __name__ == '__main__': |
| 192 | + runstrat() |
0 commit comments