Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    1. Home
    2. cortex
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
    C
    • Profile
    • Following 0
    • Followers 0
    • Topics 6
    • Posts 20
    • Best 1
    • Groups 0

    cortex

    @cortex

    1
    Reputation
    972
    Profile views
    20
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    cortex Unfollow Follow

    Best posts made by cortex

    • Use the GPU during optimisation

      Hello,
      does anyone knows if it is possible to use the GPU during the optimisation ?
      I have seen the parameter maxcpu but I don't if it include GPU.
      https://www.backtrader.com/docu/optimization-improvements.html

      posted in General Discussion
      C
      cortex

    Latest posts made by cortex

    • RE: Oandatest no attribute 'contractdetails'

      @backtrader
      I have asked for a legacy account . at the end of the year legacy account wont access the api service anymore.
      I try with the legacy account (2121212 )

      here the code :
      from future import (absolute_import, division, print_function,
      unicode_literals)

      import argparse
      import datetime

      The above could be sent to an independent module

      import backtrader as bt
      from backtrader.utils import flushfile # win32 quick stdout flushing

      StoreCls = bt.stores.OandaStore
      DataCls = bt.feeds.OandaData
      #BrokerCls = bt.brokers.OandaBroker

      class TestStrategy(bt.Strategy):
      params = dict(
      smaperiod=5,
      trade=False,
      stake=10,
      exectype=bt.Order.Market,
      stopafter=0,
      valid=None,
      cancel=0,
      donotcounter=False,
      sell=False,
      usebracket=False,
      )

      def __init__(self):
          # To control operation entries
          self.orderid = list()
          self.order = None
      
          self.counttostop = 0
          self.datastatus = 0
      
          # Create SMA on 2nd data
          self.sma = bt.indicators.MovAv.SMA(self.data, period=self.p.smaperiod)
      
          print('--------------------------------------------------')
          print('Strategy Created')
          print('--------------------------------------------------')
      
      def notify_data(self, data, status, *args, **kwargs):
          print('*' * 5, '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, 'STORE NOTIF:', msg)
      
      def notify_order(self, order):
          if order.status in [order.Completed, order.Cancelled, order.Rejected]:
              self.order = None
      
          print('-' * 50, 'ORDER BEGIN', datetime.datetime.now())
          print(order)
          print('-' * 50, 'ORDER END')
      
      def notify_trade(self, trade):
          print('-' * 50, 'TRADE BEGIN', datetime.datetime.now())
          print(trade)
          print('-' * 50, 'TRADE END')
      
      def prenext(self):
          self.next(frompre=True)
      
      def next(self, frompre=False):
          txt = list()
          txt.append('Data0')
          txt.append('%04d' % len(self.data0))
          dtfmt = '%Y-%m-%dT%H:%M:%S.%f'
          txt.append('{:f}'.format(self.data.datetime[0]))
          txt.append('%s' % self.data.datetime.datetime(0).strftime(dtfmt))
          txt.append('{:f}'.format(self.data.open[0]))
          txt.append('{:f}'.format(self.data.high[0]))
          txt.append('{:f}'.format(self.data.low[0]))
          txt.append('{:f}'.format(self.data.close[0]))
          txt.append('{:6d}'.format(int(self.data.volume[0])))
          txt.append('{:d}'.format(int(self.data.openinterest[0])))
          txt.append('{:f}'.format(self.sma[0]))
          print(', '.join(txt))
      
          if len(self.datas) > 1 and len(self.data1):
              txt = list()
              txt.append('Data1')
              txt.append('%04d' % len(self.data1))
              dtfmt = '%Y-%m-%dT%H:%M:%S.%f'
              txt.append('{}'.format(self.data1.datetime[0]))
              txt.append('%s' % self.data1.datetime.datetime(0).strftime(dtfmt))
              txt.append('{}'.format(self.data1.open[0]))
              txt.append('{}'.format(self.data1.high[0]))
              txt.append('{}'.format(self.data1.low[0]))
              txt.append('{}'.format(self.data1.close[0]))
              txt.append('{}'.format(self.data1.volume[0]))
              txt.append('{}'.format(self.data1.openinterest[0]))
              txt.append('{}'.format(float('NaN')))
              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 not self.p.usebracket:
                  if not self.p.sell:
                      # price = round(self.data0.close[0] * 0.90, 2)
                      price = self.data0.close[0] - 0.005
                      self.order = self.buy(size=self.p.stake,
                                            exectype=self.p.exectype,
                                            price=price,
                                            valid=self.p.valid)
                  else:
                      # price = round(self.data0.close[0] * 1.10, 4)
                      price = self.data0.close[0] - 0.05
                      self.order = self.sell(size=self.p.stake,
                                             exectype=self.p.exectype,
                                             price=price,
                                             valid=self.p.valid)
      
              else:
                  print('USING BRACKET')
                  price = self.data0.close[0] - 0.05
                  self.order, _, _ = self.buy_bracket(size=self.p.stake,
                                                      exectype=bt.Order.Market,
                                                      price=price,
                                                      stopprice=price - 0.10,
                                                      limitprice=price + 0.10,
                                                      valid=self.p.valid)
      
              self.orderid.append(self.order)
          elif self.position and not self.p.donotcounter:
              if self.order is None:
                  if not self.p.sell:
                      self.order = self.sell(size=self.p.stake // 2,
                                             exectype=bt.Order.Market,
                                             price=self.data0.close[0])
                  else:
                      self.order = self.buy(size=self.p.stake // 2,
                                            exectype=bt.Order.Market,
                                            price=self.data0.close[0])
      
              self.orderid.append(self.order)
      
          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('-- Contract Details:')
              print(self.data0.contractdetails)
      
          header = ['Datetime', 'Open', 'High', 'Low', 'Close', 'Volume',
                    'OpenInterest', 'SMA']
          print(', '.join(header))
      
          self.done = False
      

      def runstrategy():
      args = parse_args()

      # Create a cerebro
      cerebro = bt.Cerebro()
      
      storekwargs = dict(
          token=args.token,
          account=args.account,
          practice=not args.live
      )
      
      if not args.no_store:
          store = StoreCls(**storekwargs)
      
      if args.broker:
          if args.no_store:
              broker = BrokerCls(**storekwargs)
          else:
              broker = store.getbroker()
      
          cerebro.setbroker(broker)
      
      timeframe = bt.TimeFrame.TFrame(args.timeframe)
      # Manage data1 parameters
      tf1 = args.timeframe1
      tf1 = bt.TimeFrame.TFrame(tf1) if tf1 is not None else timeframe
      cp1 = args.compression1
      cp1 = cp1 if cp1 is not None else args.compression
      
      if args.resample or args.replay:
          datatf = datatf1 = bt.TimeFrame.Ticks
          datacomp = datacomp1 = 1
      else:
          datatf = timeframe
          datacomp = args.compression
          datatf1 = tf1
          datacomp1 = cp1
      
      fromdate = None
      if args.fromdate:
          dtformat = '%Y-%m-%d' + ('T%H:%M:%S' * ('T' in args.fromdate))
          fromdate = datetime.datetime.strptime(args.fromdate, dtformat)
      
      DataFactory = DataCls if args.no_store else store.getdata
      
      datakwargs = dict(
          timeframe=datatf, compression=datacomp,
          qcheck=args.qcheck,
          historical=args.historical,
          fromdate=fromdate,
          bidask=args.bidask,
          useask=args.useask,
          backfill_start=not args.no_backfill_start,
          backfill=not args.no_backfill,
          tz=args.timezone
      )
      
      if args.no_store and not args.broker:   # neither store nor broker
          datakwargs.update(storekwargs)  # pass the store args over the data
      
      data0 = DataFactory(dataname=args.data0, **datakwargs)
      
      data1 = None
      if args.data1 is not None:
          if args.data1 != args.data0:
              datakwargs['timeframe'] = datatf1
              datakwargs['compression'] = datacomp1
              data1 = DataFactory(dataname=args.data1, **datakwargs)
          else:
              data1 = data0
      
      rekwargs = dict(
          timeframe=timeframe, compression=args.compression,
          bar2edge=not args.no_bar2edge,
          adjbartime=not args.no_adjbartime,
          rightedge=not args.no_rightedge,
          takelate=not args.no_takelate,
      )
      
      if args.replay:
          cerebro.replaydata(data0, **rekwargs)
      
          if data1 is not None:
              rekwargs['timeframe'] = tf1
              rekwargs['compression'] = cp1
              cerebro.replaydata(data1, **rekwargs)
      
      elif args.resample:
          cerebro.resampledata(data0, **rekwargs)
      
          if data1 is not None:
              rekwargs['timeframe'] = tf1
              rekwargs['compression'] = cp1
              cerebro.resampledata(data1, **rekwargs)
      
      else:
          cerebro.adddata(data0)
          if data1 is not None:
              cerebro.adddata(data1)
      
      if args.valid is None:
          valid = None
      else:
          valid = datetime.timedelta(seconds=args.valid)
      # Add the strategy
      cerebro.addstrategy(TestStrategy,
                          smaperiod=args.smaperiod,
                          trade=args.trade,
                          exectype=bt.Order.ExecType(args.exectype),
                          stake=args.stake,
                          stopafter=args.stopafter,
                          valid=valid,
                          cancel=args.cancel,
                          donotcounter=args.donotcounter,
                          sell=args.sell,
                          usebracket=args.usebracket)
      
      # Live data ... avoid long data accumulation by switching to "exactbars"
      cerebro.run(exactbars=args.exactbars)
      if args.exactbars < 1:  # plotting is possible
          if args.plot:
              pkwargs = dict(style='line')
              if args.plot is not True:  # evals to True but is not True
                  npkwargs = eval('dict(' + args.plot + ')')  # args were passed
                  pkwargs.update(npkwargs)
      
              cerebro.plot(**pkwargs)
      

      def parse_args(pargs=None):
      parser = argparse.ArgumentParser(
      formatter_class=argparse.ArgumentDefaultsHelpFormatter,
      description='Test Oanda integration')

      parser.add_argument('--exactbars', default=1, type=int,
                          required=False, action='store',
                          help='exactbars level, use 0/-1/-2 to enable plotting')
      
      parser.add_argument('--stopafter', default=0, type=int,
                          required=False, action='store',
                          help='Stop after x lines of LIVE data')
      
      parser.add_argument('--no-store',
                          required=False, action='store_true',
                          help='Do not use the store pattern')
      
      parser.add_argument('--debug',
                          required=False, action='store_true',
                          help='Display all info received from source')
      
      parser.add_argument('--token', default=None,
                          required=True, action='store',
                          help='Access token to use')
      
      parser.add_argument('--account', default=None,
                          required=True, action='store',
                          help='Account identifier to use')
      
      parser.add_argument('--live', default=None,
                          required=False, action='store',
                          help='Go to live server rather than practice')
      
      parser.add_argument('--qcheck', default=0.5, type=float,
                          required=False, action='store',
                          help=('Timeout for periodic '
                                'notification/resampling/replaying check'))
      
      parser.add_argument('--data0', default=None,
                          required=True, action='store',
                          help='data 0 into the system')
      
      parser.add_argument('--data1', default=None,
                          required=False, action='store',
                          help='data 1 into the system')
      
      parser.add_argument('--timezone', default=None,
                          required=False, action='store',
                          help='timezone to get time output into (pytz names)')
      
      parser.add_argument('--bidask', default=None,
                          required=False, action='store_true',
                          help='Use bidask ... if False use midpoint')
      
      parser.add_argument('--useask', default=None,
                          required=False, action='store_true',
                          help='Use the "ask" of bidask prices/streaming')
      
      parser.add_argument('--no-backfill_start',
                          required=False, action='store_true',
                          help='Disable backfilling at the start')
      
      parser.add_argument('--no-backfill',
                          required=False, action='store_true',
                          help='Disable backfilling after a disconnection')
      
      parser.add_argument('--historical',
                          required=False, action='store_true',
                          help='do only historical download')
      
      parser.add_argument('--fromdate',
                          required=False, action='store',
                          help=('Starting date for historical download '
                                'with format: YYYY-MM-DD[THH:MM:SS]'))
      
      parser.add_argument('--smaperiod', default=5, type=int,
                          required=False, action='store',
                          help='Period to apply to the Simple Moving Average')
      
      pgroup = parser.add_mutually_exclusive_group(required=False)
      
      pgroup.add_argument('--replay',
                          required=False, action='store_true',
                          help='replay to chosen timeframe')
      
      pgroup.add_argument('--resample',
                          required=False, action='store_true',
                          help='resample to chosen timeframe')
      
      parser.add_argument('--timeframe', default=bt.TimeFrame.Names[1],
                          choices=bt.TimeFrame.Names,
                          required=False, action='store',
                          help='TimeFrame for Resample/Replay')
      
      parser.add_argument('--compression', default=1, type=int,
                          required=False, action='store',
                          help='Compression for Resample/Replay')
      
      parser.add_argument('--timeframe1', default=None,
                          choices=bt.TimeFrame.Names,
                          required=False, action='store',
                          help='TimeFrame for Resample/Replay - Data1')
      
      parser.add_argument('--compression1', default=None, type=int,
                          required=False, action='store',
                          help='Compression for Resample/Replay - Data1')
      
      parser.add_argument('--no-takelate',
                          required=False, action='store_true',
                          help=('resample/replay, do not accept late samples'))
      
      parser.add_argument('--no-bar2edge',
                          required=False, action='store_true',
                          help='no bar2edge for resample/replay')
      
      parser.add_argument('--no-adjbartime',
                          required=False, action='store_true',
                          help='no adjbartime for resample/replay')
      
      parser.add_argument('--no-rightedge',
                          required=False, action='store_true',
                          help='no rightedge for resample/replay')
      
      parser.add_argument('--broker',
                          required=False, action='store_true',
                          help='Use Oanda as broker')
      
      parser.add_argument('--trade',
                          required=False, action='store_true',
                          help='Do Sample Buy/Sell operations')
      
      parser.add_argument('--sell',
                          required=False, action='store_true',
                          help='Start by selling')
      
      parser.add_argument('--usebracket',
                          required=False, action='store_true',
                          help='Test buy_bracket')
      
      parser.add_argument('--donotcounter',
                          required=False, action='store_true',
                          help='Do not counter the 1st operation')
      
      parser.add_argument('--exectype', default=bt.Order.ExecTypes[0],
                          choices=bt.Order.ExecTypes,
                          required=False, action='store',
                          help='Execution to Use when opening position')
      
      parser.add_argument('--stake', default=10, type=int,
                          required=False, action='store',
                          help='Stake to use in buy operations')
      
      parser.add_argument('--valid', default=None, type=float,
                          required=False, action='store',
                          help='Seconds to keep the order alive (0 means DAY)')
      
      parser.add_argument('--cancel', default=0, type=int,
                          required=False, action='store',
                          help=('Cancel a buy order after n bars in operation,'
                                ' to be combined with orders like Limit'))
      
      # Plot options
      parser.add_argument('--plot', '-p', nargs='?', required=False,
                          metavar='kwargs', const=True,
                          help=('Plot the read data applying any kwargs passed\n'
                                '\n'
                                'For example (escape the quotes if needed):\n'
                                '\n'
                                '  --plot style="candle" (to plot candles)\n'))
      
      if pargs is not None:
          return parser.parse_args(pargs)
      
      return parser.parse_args()
      

      if name == 'main':
      runstrategy()

      posted in General Discussion
      C
      cortex
    • RE: Oandatest no attribute 'contractdetails'

      @backtrader
      please forget the my question : V20 is not supported with ondatest.py I need to ask the support for a oldversion account.

      posted in General Discussion
      C
      cortex
    • RE: Oandatest no attribute 'contractdetails'

      @backtrader
      Hello Dro,
      I'm trying to use the sample oandatest.py but I have this error message.
      "
      traceback (most recent call last):
      File "C:/Users/demo/PycharmProjects/oandatest.py", line 31, in <module>
      StoreCls = bt.stores.OandaStore
      AttributeError: 'module' object has no attribute 'OandaStore'
      "

      I use the last version of backtrader and I have installed ondapyV20
      I use the token and account name not the account number .
      My account is a V20 type.

      I utilise the last version of the sample oandatest.py.

      do you have any idea how to make this sample works ? did anyone had the same problem ?

      posted in General Discussion
      C
      cortex
    • RE: IndexError: array assignment index out of range

      My period of observation was to small. it does work when I put more days .

      posted in General Code/Help
      C
      cortex
    • IndexError: array assignment index out of range

      Hello I 'm using "analyzer-annualreturn.py" that I have modified to use generic data .
      the problem is that I have a data of gold that doesn't have neither volume nor openinterest.

      *when I try to use the program I have the following error:

      C:\Users\bobwilson\Anaconda2\python.exe C:/Users/bobwilson/PycharmProjects/PYondaSMA/goldcross.py --plot
      Traceback (most recent call last):
        File "C:/Users/bobwilson/PycharmProjects/PYondaSMA/goldcross.py", line 273, in <module>
          runstrategy()
        File "C:/Users/bobwilson/PycharmProjects/PYondaSMA/goldcross.py", line 206, in runstrategy
          cerebro.run()
        File "C:\Users\bobwilson\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 809, in run
          runstrat = self.runstrategies(iterstrat)
        File "C:\Users\bobwilson\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 926, in runstrategies
          self._runonce(runstrats)
        File "C:\Users\bobwilson\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1245, in _runonce
          strat._once()
        File "C:\Users\bobwilson\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 274, in _once
          indicator._once()
        File "C:\Users\bobwilson\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 274, in _once
          indicator._once()
        File "C:\Users\bobwilson\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 294, in _once
          self.oncestart(self._minperiod - 1, self._minperiod)
        File "C:\Users\bobwilson\Anaconda2\lib\site-packages\backtrader\indicators\basicops.py", line 371, in oncestart
          super(ExponentialSmoothing, self).once(start, end)
        File "C:\Users\bobwilson\Anaconda2\lib\site-packages\backtrader\indicators\basicops.py", line 334, in once
          dst[i] = math.fsum(src[i - period + 1:i + 1]) / period
      IndexError: array assignment index out of range*
      
      # Create the 1st data
          data = btfeeds.GenericCSVData(
              dataname='C:/Users/bobwilson/PycharmProjects/PYondaSMA/eurusd24122016.csv',
      
              fromdate=datetime.datetime(2016, 1, 8),
              todate=datetime.datetime(2016, 1, 23),
      
              nullvalue=0.0,
      
              dtformat=('%Y-%m-%d %H:%M:%S'),
              # tmformat=('%H:%M:%S'),
              datetime=0,
              high=2,
              low=3,
              open=4,
              close=1,
              volume=5,
              openinterest=-1, )
          # Add the 1st data to cerebro
          cerebro.adddata(data)
      

      this is the sample of my data :

      Date,PX_OPEN,PX_HIGH,PX_LOW,PX_SETTLE
      10/09/2010,1243.75,1251.25,1236.8,1246.25
      13/09/2010,1244.25,1249.1,1241.32,1245.6
      14/09/2010,1245.65,1274.95,1244.82,1268.15
      15/09/2010,1268.2,1271.97,1263.2,1268.05
      16/09/2010,1268.1,1278.02,1264.93,1275.25
      17/09/2010,1275.1,1282.97,1272,1274.3
      20/09/2010,1277.15,1283.8,1274.35,1278.35
      21/09/2010,1278.25,1291,1270.9,1287.15
      22/09/2010,1287.25,1296.3,1286.45,1291.35
      23/09/2010,1291.45,1296.1,1287.05,1292.45
      24/09/2010,1292.35,1300.07,1291.4,1295.95
      27/09/2010,1297.8,1300.15,1294.25,1294.35
      28/09/2010,1294.35,1310.2,1283.15,1309.05
      29/09/2010,1309.2,1313.45,1305.73,1309.85
      30/09/2010,1309.95,1315.95,1295.85,1308.35
      01/10/2010,1308.53,1320.7,1306.15,1319.1
      04/10/2010,1319.95,1320.63,1312.58,1315.25
      05/10/2010,1315.35,1341.81,1312.55,1340.65
      06/10/2010,1340.75,1349.8,1339.03,1349.05
      07/10/2010,1349,1364.77,1325.88,1333.55
      08/10/2010,1333.6,1349.8,1325.2,1346.74
      11/10/2010,1346.6,1355.65,1340.35,1354.05
      12/10/2010,1353.95,1355.77,1340.8,1350.35
      13/10/2010,1350.45,1374.35,1349,1372.15
      14/10/2010,1372.05,1387.35,1370.6,1381.15
      15/10/2010,1381.1,1385.65,1362.38,1368.4
      18/10/2010,1370.07,1375.14,1353.18,1368.45
      19/10/2010,1368.65,1371.2,1328.3,1332.05
      20/10/2010,1331.95,1347.35,1330.38,1346.25
      21/10/2010,1346.15,1349.25,1318,1325.68
      22/10/2010,1325.75,1328.65,1315.45,1328.45
      25/10/2010,1329.3,1349.3,1329.15,1339.85
      26/10/2010,1339.95,1343.75,1328.25,1340.45
      27/10/2010,1340.55,1343.8,1319.2,1325.35
      28/10/2010,1325.35,1346.1,1322.93,1344.05
      29/10/2010,1344.15,1359.7,1335.35,1359.4
      01/11/2010,1361.22,1365.85,1349.05,1353.85
      02/11/2010,1353.47,1359.75,1350.52,1357.45
      03/11/2010,1357.35,1364.6,1325.82,1348.55
      04/11/2010,1348.65,1393.55,1346.95,1392.5
      05/11/2010,1392.55,1398.27,1374.05,1393.65
      08/11/2010,1394.35,1410.6,1386.82,1409.55
      09/11/2010,1409.65,1424.6,1382.8,1392.9
      

      Does anyone knows why I have this problem ?

      posted in General Code/Help
      C
      cortex
    • integration with xbtce

      Hello ,
      I 'm trying to see how to integrate Xbtce with BT.
      the way xbtce give the historical data is strange. there is Ask bars historical data and bidbars historical data .
      usually , I use YAhoo historical data and there is not this distinction .
      do you wich data stream should be use for trading Ask Bars or Bid bars ?
      here the link of the documentation : https://www.xbtce.cc/tradeapi

      posted in General Discussion
      C
      cortex
    • RE: Use the GPU during optimisation

      Thank you , My dream was it would be simple to implement . Now , back to the reality :) good night

      posted in General Discussion
      C
      cortex
    • Use the GPU during optimisation

      Hello,
      does anyone knows if it is possible to use the GPU during the optimisation ?
      I have seen the parameter maxcpu but I don't if it include GPU.
      https://www.backtrader.com/docu/optimization-improvements.html

      posted in General Discussion
      C
      cortex
    • RE: 3 bars delay in the backtest

      thank you very much for your answer.
      next time I'll use the function snippet.

      posted in General Discussion
      C
      cortex
    • RE: 3 bars delay in the backtest

      here the code in text :

      #!/usr/bin/env python
      # -*- coding: utf-8; py-indent-offset:4 -*-
      ###############################################################################
      #
      # Copyright (C) 2015, 2016 Daniel Rodriguez
      #
      # This program is free software: you can redistribute it and/or modify
      # it under the terms of the GNU General Public License as published by
      # the Free Software Foundation, either version 3 of the License, or
      # (at your option) any later version.
      #
      # This program is distributed in the hope that it will be useful,
      # but WITHOUT ANY WARRANTY; without even the implied warranty of
      # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      # GNU General Public License for more details.
      #
      # You should have received a copy of the GNU General Public License
      # along with this program.  If not, see <http://www.gnu.org/licenses/>.
      #
      ###############################################################################
      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      import argparse
      import datetime
      
      # The above could be sent to an independent module
      import backtrader as bt
      import backtrader.feeds as btfeeds
      import backtrader.indicators as btind
      from backtrader.analyzers import (SQN, AnnualReturn, TimeReturn, SharpeRatio,
                                        TradeAnalyzer)
      
      
      class LongShortStrategy(bt.Strategy):
          '''This strategy buys/sells upong the close price crossing
          upwards/downwards a Simple Moving Average.
      
          It can be a long-only strategy by setting the param "onlylong" to True
          '''
          params = dict(
              period=15,
              stake=1,
              printout=False,
              onlylong=False,
              csvcross=False,
          )
      
          def start(self):
              pass
      
          def stop(self):
              pass
      
          def log(self, txt, dt=None):
              if self.p.printout:
                  dt = dt or self.data.datetime[0]
                  dt = bt.num2date(dt)
                  print('%s, %s' % (dt.isoformat(), txt))
      
          def __init__(self):
              # To control operation entries
              self.orderid = None
      
              # Create SMA on 2nd data
              sma = btind.MovAv.SMA(self.data, period=self.p.period)
              sma2 = btind.MovAv.SMA(self.data, period=self.p.period * 2)
              # Create a CrossOver Signal from close an moving average
              self.signal = btind.CrossOver(self.data.close, sma)
              self.signal2 = btind.CrossOver(sma, sma2)
              self.signal2.csv = self.p.csvcross
      
          def next(self):
              if self.orderid:
                  return  # if an order is active, no new orders are allowed
      
              if self.signal2 > 0.0:  # cross upwards
                  if self.position:
                      self.log('CLOSE SHORT , %.2f' % self.data.close[0])
                      self.close()
      
                  self.log('BUY CREATE , %.2f' % self.data.close[0])
                  self.buy(size=self.p.stake)
      
              elif self.signal2 < 0.0:
                  if self.position:
                      self.log('CLOSE LONG , %.2f' % self.data.close[0])
                      self.close()
      
                  if not self.p.onlylong:
                      self.log('SELL CREATE , %.2f' % self.data.close[0])
                      self.sell(size=self.p.stake)
      
          def notify_order(self, order):
              if order.status in [bt.Order.Submitted, bt.Order.Accepted]:
                  return  # Await further notifications
      
              if order.status == order.Completed:
                  if order.isbuy():
                      buytxt = 'BUY COMPLETE, %.2f' % order.executed.price
                      self.log(buytxt, order.executed.dt)
                  else:
                      selltxt = 'SELL COMPLETE, %.2f' % order.executed.price
                      self.log(selltxt, order.executed.dt)
      
              elif order.status in [order.Expired, order.Canceled, order.Margin]:
                  self.log('%s ,' % order.Status[order.status])
                  pass  # Simply log
      
              # Allow new orders
              self.orderid = None
      
          def notify_trade(self, trade):
              if trade.isclosed:
                  self.log('TRADE PROFIT, GROSS %.2f, NET %.2f' %
                           (trade.pnl, trade.pnlcomm))
      
              elif trade.justopened:
                  self.log('TRADE OPENED, SIZE %2d' % trade.size)
      
      
      def runstrategy():
          args = parse_args()
      
          # Create a cerebro
          cerebro = bt.Cerebro()
      
          # Get the dates from the args
          fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d')
          todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d')
      
          # Create the 1st data
          data = btfeeds.BacktraderCSVData(
              dataname=args.data,
              fromdate=fromdate,
              todate=todate)
      
          # Add the 1st data to cerebro
          cerebro.adddata(data)
      
          # Add the strategy
          cerebro.addstrategy(LongShortStrategy,
                              period=args.period,
                              onlylong=args.onlylong,
                              csvcross=args.csvcross,
                              stake=args.stake)
      
          # Add the commission - only stocks like a for each operation
          cerebro.broker.setcash(args.cash)
      
          # Add the commission - only stocks like a for each operation
          cerebro.broker.setcommission(commission=args.comm,
                                       mult=args.mult,
                                       margin=args.margin)
      
          tframes = dict(
              days=bt.TimeFrame.Days,
              weeks=bt.TimeFrame.Weeks,
              months=bt.TimeFrame.Months,
              years=bt.TimeFrame.Years)
      
          # Add the Analyzers
          cerebro.addanalyzer(SQN)
          if args.legacyannual:
              cerebro.addanalyzer(AnnualReturn)
              cerebro.addanalyzer(SharpeRatio, legacyannual=True)
          else:
              cerebro.addanalyzer(TimeReturn, timeframe=tframes[args.tframe])
              cerebro.addanalyzer(SharpeRatio, timeframe=tframes[args.tframe])
      
          cerebro.addanalyzer(TradeAnalyzer)
      
          cerebro.addwriter(bt.WriterFile, csv=args.writercsv, rounding=4)
      
          # And run it
          cerebro.run()
      
          # Plot if requested
          if args.plot:
              cerebro.plot(numfigs=args.numfigs, volume=False, zdown=False)
      
      
      def parse_args():
          parser = argparse.ArgumentParser(description='TimeReturn')
      
          parser.add_argument('--data', '-d',
                              default='../../datas/2005-2006-day-001.txt',
                              help='data to add to the system')
      
          parser.add_argument('--fromdate', '-f',
                              default='2005-01-01',
                              help='Starting date in YYYY-MM-DD format')
      
          parser.add_argument('--todate', '-t',
                              default='2006-12-31',
                              help='Starting date in YYYY-MM-DD format')
      
          parser.add_argument('--period', default=15, type=int,
                              help='Period to apply to the Simple Moving Average')
      
          parser.add_argument('--onlylong', '-ol', action='store_true',
                              help='Do only long operations')
      
          parser.add_argument('--writercsv', '-wcsv', action='store_true',
                              help='Tell the writer to produce a csv stream')
      
          parser.add_argument('--csvcross', action='store_true',
                              help='Output the CrossOver signals to CSV')
      
          group = parser.add_mutually_exclusive_group()
          group.add_argument('--tframe', default='years', required=False,
                             choices=['days', 'weeks', 'months', 'years'],
                             help='TimeFrame for the returns/Sharpe calculations')
      
          group.add_argument('--legacyannual', action='store_true',
                             help='Use legacy annual return analyzer')
      
          parser.add_argument('--cash', default=100000, type=int,
                              help='Starting Cash')
      
          parser.add_argument('--comm', default=2, type=float,
                              help='Commission for operation')
      
          parser.add_argument('--mult', default=10, type=int,
                              help='Multiplier for futures')
      
          parser.add_argument('--margin', default=2000.0, type=float,
                              help='Margin for each future')
      
          parser.add_argument('--stake', default=1, type=int,
                              help='Stake to apply in each operation')
      
          parser.add_argument('--plot', '-p', default=True, action='store_true',
                              help='Plot the read data')
      
          parser.add_argument('--numfigs', '-n', default=1,
                              help='Plot using numfigs figures')
      
          return parser.parse_args()
      
      
      if __name__ == '__main__':
          runstrategy()
      
      posted in General Discussion
      C
      cortex