Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Anyone use backtrader to do live trading on Bitcoin exchange?

    General Discussion
    pairs trading crypto
    79
    325
    134503
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      tw00000 @Jacob last edited by tw00000

      Thanks @Ed-Bartosh for all your work on this.

      Running a slightly modified version of your minimal example:

      #!/usr/bin/env python
      # -*- coding: utf-8; py-indent-offset:4 -*-
      ###############################################################################
      #
      # Copyright (C) 2017 Ed Bartosh
      #
      # 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 sys
      import time
      import ccxt
      
      from datetime import datetime, timedelta
      
      import backtrader as bt
      
      class TestStrategy(bt.Strategy):
          def next(self):
              for data in self.datas:
                  print('*' * 5, 'NEXT:', bt.num2date(data.datetime[0]), data._name, data.open[0], data.high[0],
                        data.low[0], data.close[0], data.volume[0],
                        bt.TimeFrame.getname(data._timeframe), len(data))
                  if not self.getposition(data):
                      order = self.buy(data, exectype=bt.Order.Limit, size=10, price=0.069)
                  else:
                      order = self.sell(data, exectype=bt.Order.Limit, size=10, price=0.07)
      
          def notify_order(self, order):
              print('*' * 5, "NOTIFY ORDER", order)
      
      def runstrategy(argv):
          # Create a cerebro
          cerebro = bt.Cerebro()
      
          # Create broker
          broker_config = {'urls': {'api': 'https://api.sandbox.gemini.com'},
                           'apiKey': 'lnedXPZCM71YNDdfXRol',
                           'secret': '2SoHTmuUAC6AAiAd1bgtSrALo64g', 
                           'nonce': lambda: str(int(time.time() * 1000))
                          }
          broker = bt.brokers.CCXTBroker(exchange='gemini', currency='USD', config=broker_config)
          cerebro.setbroker(broker)
      
          # # Create data feeds
          # data_ticks = bt.feeds.CCXT(exchange='gdax', symbol='BTC/USD', name="btc_usd_tick",
          #                            timeframe=bt.TimeFrame.Ticks, compression=5)
          # cerebro.adddata(data_ticks)
      
          hist_start_date = datetime.utcnow() - timedelta(minutes=30)
          data_min = bt.feeds.CCXT(exchange="binance", 
                                  symbol="ETH/BTC", 
                                  # name="btc_usd_min",
                                  timeframe=bt.TimeFrame.Minutes, 
                                  fromdate=hist_start_date)
          cerebro.adddata(data_min)
      
          # Add the strategy
          cerebro.addstrategy(TestStrategy)
      
          # Run the strategy
          cerebro.run()
      
      if __name__ == '__main__':
          sys.exit(runstrategy(sys.argv))
      
      

      My error is:

      $ python gemini-ccxt-test.py
      ***** NEXT: 2018-07-31 14:17:00  0.055565 0.05561 0.055546 0.055593 133.594 Minute 1
      Traceback (most recent call last):
        File "gemini-ccxt-test.py", line 79, in <module>
          sys.exit(runstrategy(sys.argv))
        File "gemini-ccxt-test.py", line 76, in runstrategy
          cerebro.run()
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/cerebro.py", line 1127, in run
          runstrat = self.runstrategies(iterstrat)
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/cerebro.py", line 1298, in runstrategies
          self._runnext(runstrats)
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/cerebro.py", line 1630, in _runnext
          strat._next()
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/strategy.py", line 325, in _next
          super(Strategy, self)._next()
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/lineiterator.py", line 268, in _next
          self.nextstart()  # only called for the 1st value
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/lineiterator.py", line 342, in nextstart
          self.next()
        File "gemini-ccxt-test.py", line 41, in next
          order = self.sell(data, exectype=bt.Order.Limit, size=10, price=0.07)
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/strategy.py", line 947, in sell
          **kwargs)
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/brokers/ccxtbroker.py", line 102, in sell
          return self._submit(owner, data, exectype, 'sell', size, price, kwargs)
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/brokers/ccxtbroker.py", line 88, in _submit
          order = CCXTOrder(owner, data, _order)
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/metabase.py", line 88, in __call__
          _obj, args, kwargs = cls.doinit(_obj, *args, **kwargs)
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/metabase.py", line 78, in doinit
          _obj.__init__(*args, **kwargs)
        File "/Users/tw/.local/lib/python3.6/site-packages/backtrader/brokers/ccxtbroker.py", line 33, in __init__
          self.ordtype = self.Buy if ccxt_order['side'] == 'buy' else self.Sell
      KeyError: 'side'
      

      This could just be an error related to using Gemini, although I don't know, and I don't want to set any bots on my Binance account at the moment!

      Thanks for any help.

      E 1 Reply Last reply Reply Quote 0
      • E
        Ed Bartosh @tw00000 last edited by

        @tw00000 Thank you for the great report. It should be fixed now by this commit. Please, try it and let us know if it works for you.

        PS: I've rebased my ccxt branch on top of the latest backtrader release 1.9.65.122 and tested it with the latest ccxt release 1.17.76

        1 Reply Last reply Reply Quote 0
        • S
          Samy David last edited by

          Hi @Ed-Bartosh -
          i am getting this error - looks like versioning issue?

          in one of the ccxtbroker.py versions you published we had this line:
          ccxt_order = self.ccxt.exchange.create_order(symbol=data.ccxt.symbol, type=order_type, side=side, amount=amount, price=price, params=params)

          and i got this error:

          File "/anaconda3/lib/python3.6/site-packages/backtrader/brokers/ccxtbroker.py", line 96, in buy
          return self._submit(owner, data, exectype, 'buy', size, price, kwargs)
          File "/anaconda3/lib/python3.6/site-packages/backtrader/brokers/ccxtbroker.py", line 86, in _submit
          _order = self.store.create_order(symbol=data.symbol, order_type=order_type, side=side,
          File "/anaconda3/lib/python3.6/site-packages/backtrader/lineseries.py", line 461, in getattr
          return getattr(self.lines, name)
          AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'symbol'

          E 1 Reply Last reply Reply Quote 0
          • E
            Ed Bartosh @Samy David last edited by

            @samy-david Thank you for the report. Can you provide more details, please? Which version of my code and ccxt do you use?

            S 1 Reply Last reply Reply Quote 0
            • S
              Samy David @Ed Bartosh last edited by

              @ed-bartosh i am using your fork with the latest bt (1.9.65.122)
              including this commit for fixing the keyerror

              also including this commit
              for merging the CCXTOrder into the CCXTStore.

              I am sure i lost sync somewhere ... can you kindly supply the step by step for re-installing BT and CCXT ?

              E 1 Reply Last reply Reply Quote 0
              • E
                Ed Bartosh @Samy David last edited by

                @samy-david I don't think you lost sync as far as I can see from the traceback. Can you show simple code to reproduce this issue?

                S 1 Reply Last reply Reply Quote 0
                • S
                  Samy David @Ed Bartosh last edited by

                  @ed-bartosh

                  i am passing the data received in notify_order to the broker buy/sell method

                  self.broker.sell(owner=self,data=order.data, exectype=Order.Limit,
                  size=limit_size, price=price)

                  then the Error is as following:
                  File "/anaconda3/lib/python3.6/site-packages/backtrader/brokers/ccxtbroker.py", line 92, in sell
                  return self._submit(owner, data, exectype, 'sell', size, price, kwargs)
                  File "/anaconda3/lib/python3.6/site-packages/backtrader/brokers/ccxtbroker.py", line 76, in _submit
                  _order = self.store.create_order(symbol=data.symbol, order_type=order_type, side=side,
                  File "/anaconda3/lib/python3.6/site-packages/backtrader/lineseries.py", line 461, in getattr
                  return getattr(self.lines, name)
                  AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'symbol'

                  E 1 Reply Last reply Reply Quote 0
                  • E
                    Ed Bartosh @Samy David last edited by

                    @samy-david said in Anyone use backtrader to do live trading on Bitcoin exchange?:

                    self.broker.sell(owner=self,data=order.data, exectype=Order.Limit,
                    size=limit_size, price=price)

                    What's order.data in your example? It's definitely not a CCXT feed data as it doesn't have 'symbol' attribute, which causes ccxtbroker failure.

                    S 2 Replies Last reply Reply Quote 0
                    • S
                      Samy David @Ed Bartosh last edited by Samy David

                      @ed-bartosh
                      the data comes form the strategy - self.datas - the single data object is passed to the order:
                      order_op = self.broker.sell
                      :
                      order_op(owner=self,data=data, size=order_size, exectype=Order.Market)

                      the data is then returned as part of notify_order and forward to a limit order
                      :
                      self.broker.sell(owner=self,data=order.data, exectype=Order.Limit,
                      size=limit_size, price=price)

                      cerebro feed is defined as following:
                      data = bt.feeds.CCXT(exchange='bitmex', symbol='BTC/USD', name="btc_usd_min",
                      timeframe=bt.TimeFrame.Minutes, compression=1,backfill_start=True,fromdate=hist_start_date,config=feed_config)

                      Resample of data
                      cerebro.resampledata(data,name="btc_usd_min",timeframe=bt.TimeFrame.Minutes, compression=5)

                      here is a simple print of the object from the log
                      data <backtrader.feeds.ccxt.CCXT object at 0x10b076588>

                      E 1 Reply Last reply Reply Quote 0
                      • S
                        Samy David @Ed Bartosh last edited by Samy David

                        @ed-bartosh

                        i did further digging into the code and i think could be a CCXT issue.
                        there are few reasons that could trigger the issue:

                        Reason 1:
                        the missing symbol comes from resampled data -

                        • i fetch the historical data in 1m compression
                        • i resample the data to 1 & 2 minutes (and higher ...)

                        -- update - 1m timeframe data exists, all other timeframes (resample/replay) come with a missing symbol and potentially other data

                        the log shows a successful order for 1 minute signal, but missing the data for higher TF's:

                        Reason 2:
                        i think i saw a thread about loading historical data doesn't work for IB's - could it be a similar issue?
                        found it ... (this issue)

                        -- update - although related, it is not relevant for our case here , i ran the process with only live data (not historical) and still there was an issue

                        Reason 3
                        should i use replay data instead of resample data for higher TFs ?
                        so 1m is resampled, and all higher TFs are replayed - could this fix the missing data?

                        -- update - i tried running higher TFs with replay, still same error

                        Reason 4
                        looking at the _GRANULARITIES in ccxtstore - i was using 2m TFs - could this be the issue? (unsupported TF) ?

                        • update - this could be a potential candidate, however i ran it with supported TFs and still same error:

                        as a reference - here is the error from the log:

                        this line is my code -
                        order_op(owner=self,data=data, size=order_size, exectype=Order.Market)
                        File "/anaconda3/lib/python3.6/site-packages/backtrader/brokers/ccxtbroker.py", line 88, in buy
                        return self._submit(owner, data, exectype, 'buy', size, price, kwargs)
                        File "/anaconda3/lib/python3.6/site-packages/backtrader/brokers/ccxtbroker.py", line 77, in _submit
                        _order = self.store.create_order(symbol=data.symbol, order_type=order_type, side=side,
                        File "/anaconda3/lib/python3.6/site-packages/backtrader/lineseries.py", line 461, in getattr
                        return getattr(self.lines, name)
                        AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'symbol'

                        E 1 Reply Last reply Reply Quote 0
                        • E
                          Ed Bartosh @Samy David last edited by

                          @samy-david said in Anyone use backtrader to do live trading on Bitcoin exchange?:

                          1m timeframe data exists, all other timeframes (resample/replay) come with a missing symbol and potentially other data

                          I can't reproduce it. I can see 'symbol' attribute in the data after resampling:

                          $ ./test.py 
                          data.symbol after resampling: BTC/USD
                          
                          $ cat test.py 
                          #!/usr/bin/env python
                          
                          import sys
                          import backtrader as bt
                          
                          cerebro = bt.Cerebro()
                          
                          data = bt.feeds.CCXT(exchange="bitmex", symbol="BTC/USD", timeframe=bt.TimeFrame.Minutes)
                          
                          cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=2)
                          
                          print("data.symbol after resampling:", data.symbol)
                          
                          1 Reply Last reply Reply Quote 0
                          • E
                            Ed Bartosh @Samy David last edited by

                            @samy-david said in Anyone use backtrader to do live trading on Bitcoin exchange?:

                            self.broker.sell(owner=self,data=order.data, exectype=Order.Limit, size=limit_size, price=price)

                            What's the reason to use self.broker.sell instead of self.sell?

                            Can you sketch small script that I can run to reproduce the issue? Without this it'll be guessing game and it can take much longer.

                            S 1 Reply Last reply Reply Quote 0
                            • J
                              jf last edited by

                              Dear CCXT adopters,

                              I have a question regarding base currencies in pairs trading that you might have solved:

                              • My "backtrader currency" (value of account at broker etc) is USD, as I want all data in USD
                              • I trade alt coins vs BTC or also vs ETH. So for example, I would go long LTC/BTC and at the same time short IOT/ETH

                              How can I handle that in backtrader? The problem is that the system assumes that all prices are in USD, so backtrader assumes that my LTC/BTC price feed is a price in USD, which messes up position sizing, portfolio composition, etc.

                              If someone ran into the same issue and could share his solution that would be highly appreciated!

                              Thanks,
                              JF

                              1 Reply Last reply Reply Quote 0
                              • J
                                John Land @fivo last edited by

                                I am still having the same issue while pulling data from Bitmex; the live data is all unfinished. Has this issue been resolved? Anybody else still getting it?

                                @fivo said in Anyone use backtrader to do live trading on Bitcoin exchange?:

                                @fivo said in Anyone use backtrader to do live trading on Bitcoin exchange?:

                                There seems to be a problem when fetching live data. The backfilling works correctly, but once the live data is used the feeds receives the data of the current minute (assuming we are trading minute data) that is not yet finished. Essentially the opening value is correct, but the rest (close high low vol) is not.

                                It doesn't seem to be ccxt as the following little script produces the correct values. I think the code around this line seems to be fetching data as soon as some data of the currently running minute is available. I will try look into it.

                                # !/usr/bin/env python
                                # -*- coding: utf-8; py-indent-offset:4 -*-
                                
                                from datetime import datetime, timedelta
                                import time
                                
                                import ccxt
                                
                                binance = ccxt.binance()
                                
                                while True:
                                    fromdate = datetime.utcnow() - timedelta(minutes=2)
                                    since = int((fromdate - datetime(1970, 1, 1)).total_seconds() * 1000)
                                    ohlcvs = binance.fetch_ohlcv('BTC/USDT', '1m', since=since, limit=1)
                                    if not ohlcvs:
                                        continue
                                
                                    ohlcv = ohlcvs[0]
                                
                                    print(datetime.utcfromtimestamp(ohlcv[0]/1000), ohlcv[1], ohlcv[2],
                                          ohlcv[3], ohlcv[4], ohlcv[5])
                                
                                    time.sleep(1)
                                

                                Can anybody reproduce this issue?

                                S 1 Reply Last reply Reply Quote 0
                                • S
                                  Samy David @John Land last edited by

                                  @john-land i think i have the same issue - not sure if it is related.

                                  but the data from cerebro is missing symbol

                                  File "/anaconda3/lib/python3.6/site-packages/backtrader/strategy.py", line 917, in buy
                                  **kwargs)
                                  File "/anaconda3/lib/python3.6/site-packages/backtrader/brokers/ccxtbroker.py", line 88, in buy
                                  return self._submit(owner, data, exectype, 'buy', size, price, kwargs)
                                  File "/anaconda3/lib/python3.6/site-packages/backtrader/brokers/ccxtbroker.py", line 77, in _submit
                                  _order = self.store.create_order(symbol=data.symbol, order_type=order_type, side=side,
                                  File "/anaconda3/lib/python3.6/site-packages/backtrader/lineseries.py", line 461, in getattr
                                  return getattr(self.lines, name)
                                  AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'symbol'

                                  1 Reply Last reply Reply Quote 0
                                  • S
                                    Samy David @Ed Bartosh last edited by

                                    @ed-bartosh i am using Ichimoku indicator which require a history of 120 candles for 1 minute - so for 5 minutes it is 600 candles. i am loading 720.

                                    i think this is some how related to the post @John-Land mentioned about incomplete data.

                                    1 Reply Last reply Reply Quote 0
                                    • Jacob
                                      Jacob last edited by

                                      @Ed-Bartosh I have a special use case.
                                      I'm trying to setup a live feed for Bitstamp and using indicators requires backfilling as well.

                                      The problem I'm facing is that bitstamp doesn't offer ohlcv data as part of it's API's. (i'm assuming ohlcv is required)

                                      side note:
                                      Didn't find any reference in the code to the use of 'backfill_start'?

                                      I have the historical data in a .csv file. is there a way maybe to stitch the two together?

                                      found this in ibdata.py:

                                        ``backfill_from`` (default: ``None``)
                                      
                                         An additional data source can be passed to do an initial layer of
                                      
                                         backfilling. Once the data source is depleted and if requested,
                                      
                                         backfilling from IB will take place. This is ideally meant to backfill
                                      
                                         from already stored sources like a file on disk, but not limited to.
                                      
                                      E 1 Reply Last reply Reply Quote 0
                                      • E
                                        Ed Bartosh @Jacob last edited by

                                        @jacob

                                        I have the historical data in a .csv file. is there a way maybe to stitch the two together?

                                        Currently backfill_from is not supported. I'll be happy to see this implemented. I hope it's not that hard to implement considering working example from ibdata.py.

                                        Jacob 1 Reply Last reply Reply Quote 0
                                        • S
                                          sfkiwi last edited by

                                          I've been using backtrader for sometime but I'm new to the ccxt live data. Thank you @Ed-Bartosh for all the work you've done on this. amazing!

                                          When using live data I'm noticing quite a significant delay of the data by about 30 seconds or so. Is this expected behavior? My hope is to run this as close to real-time as possible.

                                          Even though the data status shows LIVE, the first data is actually about 15mins behind real-time but starts to catch up after around 30 seconds, although it never actually fully catches up and ends up always being about 10-15 seconds behind the real-time data. I'm using TradingView and pro.coinbase.com as my benchmark as I'm using gdax as the feed.

                                          ***** DATA NOTIF: LIVE
                                          ***** NEXT: 2018-08-21 08:15:33.492003 btc_usd_tick 6475.01 6475.01 6475.01 6475.01 0.01 Tick 1
                                          ***** NEXT: 2018-08-21 08:15:33.532004 btc_usd_tick 6475.91 6475.91 6475.91 6475.91 0.57164401 Tick 2
                                          ***** NEXT: 2018-08-21 08:15:46.381995 btc_usd_tick 6475.91 6475.91 6475.91 6475.91 0.0016879 Tick 3
                                          ***** NEXT: 2018-08-21 08:15:53.060997 btc_usd_tick 6475.9 6475.9 6475.9 6475.9 0.0034 Tick 4
                                          ***** NEXT: 2018-08-21 08:16:04.493001 btc_usd_tick 6475.91 6475.91 6475.91 6475.91 0.0028 Tick 5
                                          ***** NEXT: 2018-08-21 08:16:16.126000 btc_usd_tick 6475.9 6475.9 6475.9 6475.9 0.0097 Tick 6
                                          ***** NEXT: 2018-08-21 08:16:28.048999 btc_usd_tick 6475.9 6475.9 6475.9 6475.9 0.1667 Tick 7
                                          ***** NEXT: 2018-08-21 08:16:45.003001 btc_usd_tick 6475.9 6475.9 6475.9 6475.9 1.0 Tick 8
                                          ***** NEXT: 2018-08-21 08:16:45.043002 btc_usd_tick 6474.6 6474.6 6474.6 6474.6 0.001 Tick 9
                                          ***** NEXT: 2018-08-21 08:16:49.953004 btc_usd_tick 6471.01 6471.01 6471.01 6471.01 0.00345867 Tick 10
                                          ***** NEXT: 2018-08-21 08:16:50.023995 btc_usd_tick 6471.01 6471.01 6471.01 6471.01 0.045419 Tick 11
                                          ***** NEXT: 2018-08-21 08:17:05.876002 btc_usd_tick 6471.01 6471.01 6471.01 6471.01 0.15756512 Tick 12
                                          ***** NEXT: 2018-08-21 08:17:10.691003 btc_usd_tick 6471.01 6471.01 6471.01 6471.01 0.0079974 Tick 13
                                          ***** NEXT: 2018-08-21 08:17:17.021002 btc_usd_tick 6471.01 6471.01 6471.01 6471.01 0.00315375 Tick 14
                                          ***** NEXT: 2018-08-21 08:17:21.066002 btc_usd_tick 6468.35 6468.35 6468.35 6468.35 0.00062 Tick 15
                                          ***** NEXT: 2018-08-21 08:17:21.703003 btc_usd_tick 6467.06 6467.06 6467.06 6467.06 0.01 Tick 16
                                          ***** NEXT: 2018-08-21 08:17:49.377999 btc_usd_tick 6465.19 6465.19 6465.19 6465.19 0.03187985 Tick 17
                                          ***** NEXT: 2018-08-21 08:18:01.357998 btc_usd_tick 6465.19 6465.19 6465.19 6465.19 0.0515 Tick 18
                                          ***** NEXT: 2018-08-21 08:18:04.042001 btc_usd_tick 6465.2 6465.2 6465.2 6465.2 0.00384762 Tick 19
                                          ***** NEXT: 2018-08-21 08:18:11.765002 btc_usd_tick 6465.19 6465.19 6465.19 6465.19 0.00383559 Tick 20
                                          ***** NEXT: 2018-08-21 08:18:11.801997 btc_usd_tick 6465.0 6465.0 6465.0 6465.0 4.99793959 Tick 21
                                          
                                          class TestStrategy(bt.Strategy):
                                              def next(self):
                                                  for data in self.datas:
                                                      print('*' * 5, 'NEXT:', bt.num2date(data.datetime[0]), data._name, data.open[0], data.high[0],
                                                            data.low[0], data.close[0], data.volume[0],
                                                            bt.TimeFrame.getname(data._timeframe), len(data))
                                          
                                              def notify_order(self, order):
                                                  print('*' * 5, "NOTIFY ORDER", order)
                                                  
                                              def notify_data(self, data, status, *args, **kwargs):
                                                  print('*' * 5, 'DATA NOTIF:', data._getstatusname(status), *args)
                                          
                                          def runstrategy(argv):
                                              # Create a cerebro
                                              cerebro = bt.Cerebro()
                                          
                                              # Create broker
                                              broker_config = {'urls': {'api': 'https://api.pro.coinbase.com'},
                                                               'apiKey': '{}'.format(gdax.apiKey),
                                                               'secret': '{}'.format(gdax.secret),
                                                               'password': '{}'.format(gdax.password)
                                                              }
                                          
                                              # Create data feeds
                                              data_ticks = bt.feeds.CCXT(exchange='gdax', symbol='BTC/USD', name="btc_usd_tick",
                                                                         timeframe=bt.TimeFrame.Ticks, compression=1)
                                              cerebro.adddata(data_ticks)
                                          
                                              # Add the strategy
                                              cerebro.addstrategy(TestStrategy)
                                          
                                              # Run the strategy
                                              cerebro.run()
                                          
                                          1 Reply Last reply Reply Quote 0
                                          • S
                                            sfkiwi last edited by

                                            I noticed something strange with the ccxt fetchohlc() in that sometimes it returns candles up to the last closed candle and sometimes it returns the current live (not yet closed candle).

                                            I used the follow code to get the last 20 candles which uses the same method that the ccxt backtrader uses to get live candle data.

                                            df = pd.DataFrame(gdax.fetchOhlcv('BTC/USD', timeframe='1m', limit=20))
                                            df['Date'] = pd.to_datetime(df[0], unit='ms')
                                            df.set_index('Date', inplace=True)
                                            df.drop(0, axis=1, inplace=True)
                                            df.columns = ['open', 'high','low','close','volume']
                                            df['highlow'] = df['high'] - df['low']; df
                                            

                                            This outputs a dataframe:

                                                                       
                                            Date	                open    high    low     close   volume        highlow
                                            2018-08-21 09:15:00	6452.99	6453.00	6452.99	6452.99	0.382287	0.01
                                            2018-08-21 09:16:00	6453.00	6453.00	6452.99	6453.00	0.231581	0.01
                                            2018-08-21 09:17:00	6453.00	6453.00	6453.00	6453.00	0.033058	0.00
                                            2018-08-21 09:18:00	6453.00	6453.00	6452.99	6453.00	0.244911	0.01
                                            2018-08-21 09:19:00	6453.00	6453.00	6452.99	6452.99	2.142046	0.01
                                            2018-08-21 09:20:00	6453.00	6453.00	6438.91	6441.62	10.994071	14.09
                                            2018-08-21 09:21:00	6441.62	6445.98	6441.62	6445.98	1.862376	4.36
                                            2018-08-21 09:22:00	6445.97	6445.97	6431.64	6437.10	12.625005	14.33
                                            2018-08-21 09:23:00	6437.10	6445.67	6437.10	6443.40	1.902326	8.57
                                            2018-08-21 09:24:00	6443.39	6443.40	6443.39	6443.39	0.531487	0.01
                                            2018-08-21 09:25:00	6443.40	6443.40	6435.62	6435.62	1.435376	7.78
                                            2018-08-21 09:26:00	6436.35	6437.32	6433.71	6433.71	1.582333	3.61
                                            2018-08-21 09:27:00	6435.23	6435.23	6435.22	6435.22	0.054494	0.01
                                            2018-08-21 09:28:00	6435.22	6436.00	6435.22	6436.00	0.099945	0.78
                                            2018-08-21 09:29:00	6435.99	6435.99	6433.71	6433.71	1.374433	2.28
                                            2018-08-21 09:30:00	6433.71	6433.71	6431.00	6432.77	1.015340	2.71
                                            2018-08-21 09:31:00	6433.62	6433.62	6432.76	6433.00	0.172707	0.86
                                            2018-08-21 09:32:00	6432.99	6433.00	6432.99	6432.99	0.555686	0.01
                                            2018-08-21 09:33:00	6432.99	6432.99	6427.75	6431.62	3.599003	5.24
                                            2018-08-21 09:34:00	6431.63	6431.63	6431.63	6431.63	0.059508	0.00
                                            

                                            When I ran this 4 times consecutively within less than 1 second I got the following results (only last 3 lines shown)

                                            2018-08-21 09:32:00	6432.99	6433.00	6432.99	6432.99	0.555686	0.01
                                            2018-08-21 09:33:00	6432.99	6432.99	6427.75	6431.62	3.599003	5.24
                                            2018-08-21 09:34:00	6431.63	6431.63	6431.63	6431.63	0.059508	0.00
                                            
                                            2018-08-21 09:31:00	6433.62	6433.62	6432.76	6433.00	0.172707	0.86
                                            2018-08-21 09:32:00	6432.99	6433.00	6432.99	6432.99	0.555686	0.01
                                            2018-08-21 09:33:00	6432.99	6432.99	6427.75	6431.62	3.599003	5.24
                                            
                                            2018-08-21 09:32:00	6432.99	6433.00	6432.99	6432.99	0.555686	0.01
                                            2018-08-21 09:33:00	6432.99	6432.99	6427.75	6431.62	3.599003	5.24
                                            2018-08-21 09:34:00	6431.63	6431.63	6431.63	6431.63	0.062508	0.00
                                            
                                            2018-08-21 09:32:00	6432.99	6433.00	6432.99	6432.99	0.555686	0.01
                                            2018-08-21 09:33:00	6432.99	6432.99	6427.75	6431.62	3.599003	5.24
                                            2018-08-21 09:34:00	6431.63	6431.63	6431.63	6431.63	0.059508	0.00
                                            

                                            As you can see, sometimes it returns the 9:34 candle (which at the time had not closed) and sometimes it returns the 9:33 candle (which has closed) as the most recent.

                                            When I ran this a few minutes later I get

                                            2018-08-21 09:32:00	6432.99	6433.00	6432.99	6432.99	0.555686	0.01
                                            2018-08-21 09:33:00	6432.99	6432.99	6427.75	6431.62	3.599003	5.24
                                            2018-08-21 09:34:00	6431.63	6433.00	6431.62	6433.00	4.551569	1.38
                                            2018-08-21 09:35:00	6433.38	6434.68	6433.38	6434.68	12.601649	1.30
                                            2018-08-21 09:36:00	6436.36	6444.00	6436.36	6443.99	3.252023	7.64
                                            

                                            As you can see the 9:34 candle closed at 6433.00 not at 6431.63.

                                            This means that when you are getting 1m live data from backtrader you may actually be getting a live candle instead of the actual data because backtrader/ccxt will record the time of the latest candle and only give candles with timestamps later than the previous.

                                            In fact this actually looks like what I'm getting

                                            ***** DATA NOTIF: LIVE
                                            ***** NEXT: 2018-08-21 09:04:00 btc_usd_min 6459.99 6460.0 6459.99 6460.0 0.02234232 Minute 3
                                            ***** NEXT: 2018-08-21 09:05:00 btc_usd_min 6455.06 6455.06 6455.06 6455.06 0.05325761 Minute 4
                                            ***** NEXT: 2018-08-21 09:06:00 btc_usd_min 6455.06 6460.92 6455.06 6460.92 0.75941057 Minute 5
                                            ***** NEXT: 2018-08-21 09:07:00 btc_usd_min 6460.95 6460.95 6460.95 6460.95 0.00362068 Minute 6
                                            ***** NEXT: 2018-08-21 09:08:00 btc_usd_min 6457.84 6457.84 6457.84 6457.84 0.03702458 Minute 7
                                            ***** NEXT: 2018-08-21 09:09:00 btc_usd_min 6452.82 6452.82 6452.82 6452.82 1.21548925 Minute 8
                                            ***** NEXT: 2018-08-21 09:10:00 btc_usd_min 6452.81 6452.81 6452.81 6452.81 0.0226 Minute 9
                                            

                                            Minute 5 appears to be a full candle whereas Minute 7 (for example) appears to be a partially completed live candle

                                            E 1 Reply Last reply Reply Quote 0
                                            • 1
                                            • 2
                                            • 11
                                            • 12
                                            • 13
                                            • 14
                                            • 15
                                            • 16
                                            • 17
                                            • 13 / 17
                                            • First post
                                              Last post
                                            Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors