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/

    Live Data Feed

    General Code/Help
    3
    4
    237
    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.
    • Hùng Nguyễn
      Hùng Nguyễn last edited by

      Hi,
      I have a custom live data feed that is listening data from WebSocket.
      If I have timeframe as Daily, with the last bar is Today, when I have a new tick, how can I update the value of the Daily last bar
      If I try to update via self.lines then I will add one more data into the list and make wrong calculation for SMA

      Thanks

      1 Reply Last reply Reply Quote 0
      • Xu Liu
        Xu Liu last edited by

        I can provide an example of myself

        import _thread
        from datetime import datetime
        import time
        import backtrader as bt
        from backtrader import date2num
        from backtrader.feeds import DataBase
        
        
        class LiveDataStream(DataBase):
        
            def __init__(self):
                self.isOpen = True
                self.i = 0
                _thread.start_new_thread(self._timerstart, (1,))
        
            def start(self):
                super(LiveDataStream, self).start()
        
            def _timerstart(self, n):
                while True:
                    if self.isOpen == False:
                        self.isOpen = True
                    time.sleep(n)
        
            def _load(self):
                if self.isOpen == True:
                    # print(self.i)
                    self.i += 1
                    self.lines.datetime[0] = date2num(datetime.now())
                    # Get the rest of the unpacked data
                    self.lines.open[0] = 100 + self.i
                    self.lines.high[0] = 120 + self.i
                    self.lines.low[0] = 80 + self.i
                    self.lines.close[0] = 90 + self.i
                    self.lines.volume[0] = 2342 + self.i
                    self.lines.openinterest[0] = 443 + self.i
                    self.isOpen = False
                    return True
                else:
                    return None
        
            def islive(self):
                '''Returns ``True`` to notify ``Cerebro`` that preloading and runonce
                should be deactivated'''
                return True
        
            def stop(self):
                '''Stops and tells the store to stop'''
                super().stop()
        
        
        class MyStrategy(bt.Strategy):
            def __init__(self):
                pass
        
            def next(self):
                print('{} -- {} -- {}'.format(self.data.open[0], self.data.high[0], self.data.close[0]))
        
            def notify_data(self, data, status, *args, **kwargs):
                if status == data.LIVE:
                    print("live data")
                elif status == data.DELAYED:
                    print("DELAYED data")
        
        
        cerebro = bt.Cerebro()
        cerebro.addstrategy(MyStrategy)
        cerebro.adddata(LiveDataStream())
        cerebro.run()
        cerebro.plot()
        print("over")
        
        
        Xu Liu 1 Reply Last reply Reply Quote 0
        • Xu Liu
          Xu Liu @Xu Liu last edited by

          @Xu-Liu emmm, ‘return None return’ None should be changed ‘continue’

          1 Reply Last reply Reply Quote 0
          • R
            rajanprabu last edited by

            Hey @Xu-Liu

            Thanks for the example. Using your example and by reading other posts in this forum I could get it started, but unable to get it to work correctly so far. I certainly see that price information is correctly streaming. But I cant feed this in to BT. My class is the following.

            class BrokerFeed(DataBase):
            
                params = (('dataname', None),
                    # ('fromdate', datetime.datetime.min),
                    # ('todate', datetime.datetime.max),
                    ('name', ''),
                    ('compression', 1),
                    ('timeframe', TimeFrame.Ticks),
                    ('sessionend', None),
                    )
            
                def __init__(self, user_data, access_data, scrip_code):
            
                    self.ws = broker_ws(user_data, access_data)
                    self.scrip_code = scrip_code
                    self.price = None
                    
                def start(self):
                
                    self.ws.on_ticks = self.on_price
                    self.ws.on_connect = self.on_join
                    self.ws.connect()
            
                def on_join(self, ws, response):
            
                    self.ws.subscribe([self.scrip_code])
                    self.ws.set_mode(ws.MODE_FULL, [self.scrip_code])
            
                def on_price(self, ws, price):
            
                    self.price = price
                    self._load()
            
                def _load(self):
                    price = self.price
            
                    t = price[0]['timestamp']
                    o = price[0]['ohlc']['open']
                    h = price[0]['ohlc']['high']
                    l = price[0]['ohlc']['low']
                    c = price[0]['ohlc']['close']
                    v = price[0]['volume']
                    oi = price[0]['oi'] 
                    print (t,o,h,l,c,v,oi )
            
                    dt = bt.date2num (t)
                    
                    # self.lines.datetime[0] = dt
                    # self.lines.open[0] = o
                    # self.lines.high[0] = h
                    # self.lines.low[0] = l
                    # self.lines.close[0] = c
                    # self.lines.volume[0] = v
            
                    return True
            
                def haslivedata(self):
                     return True  # must be overriden for those that can
            
                def islive(self):
                    return True
            
            data = BrokerFeed(user_data, access_data, scrip_code = 10567, timeframe=bt.TimeFrame.Ticks, compression=1 ).start()
            cerebro.adddata(data)
            

            Above class receives the data and print ( using print (t,o,h,l,c,v,oi ) in _load() ) the candles correctly as shown below.

            (base) GRACE:>>[516] python /Users/prabu/python/BT/BT_feed_test.py
            2020-11-20 09:50:41 3129.0 3129.0 3097.0 3093.0 18596 3020
            2020-11-20 09:50:42 3129.0 3129.0 3097.0 3093.0 18596 3020
            2020-11-20 09:50:42 3129.0 3129.0 3097.0 3093.0 18596 3020
            2020-11-20 09:50:43 3129.0 3129.0 3097.0 3093.0 18597 3021
            2020-11-20 09:50:44 3129.0 3129.0 3097.0 3093.0 18597 3021
            2020-11-20 09:50:44 3129.0 3129.0 3097.0 3093.0 18597 3021
            2020-11-20 09:50:45 3129.0 3129.0 3097.0 3093.0 18598 3021
            2020-11-20 09:50:47 3129.0 3129.0 3097.0 3093.0 18598 3021
            2020-11-20 09:50:48 3129.0 3129.0 3097.0 3093.0 18598 3021
            2020-11-20 09:50:48 3129.0 3129.0 3097.0 3093.0 18598 3021
            2020-11-20 09:50:48 3129.0 3129.0 3097.0 3093.0 18599 3022
            2020-11-20 09:50:49 3129.0 3129.0 3097.0 3093.0 18600 3022
            2020-11-20 09:50:50 3129.0 3129.0 3097.0 3093.0 18600 3022
            2020-11-20 09:50:50 3129.0 3129.0 3097.0 3093.0 18631 3009
            2020-11-20 09:50:51 3129.0 3129.0 3097.0 3093.0 18632 3009
            

            But when I try to load the data to the BT by removing the comment marks before the following lines in _load(self)

                    self.lines.datetime[0] = dt
                    self.lines.open[0] = o
                    self.lines.high[0] = h
                    self.lines.low[0] = l
                    self.lines.close[0] = c
                    self.lines.volume[0] = v
            

            I get the following error

            File "/Users/prabu/python/BT/BT_feed_test.py", line 47, in on_price
                self._load()
              File "/Users/prabu/python/BT/BT_feed_test.py", line 63, in _load
                self.lines.datetime[0] = dt
              File "/Users/prabu/opt/anaconda3/lib/python3.8/site-packages/backtrader/linebuffer.py", line 222, in __setitem__
                self.array[self.idx + ago] = value
            builtins.IndexError: array assignment index out of range
            

            I followed the example in Backtrader Binary data feed tutorial as well as the cctx thread @Ed-Bartosh example but couldn't make it to work. It could be my lack of OOP/decorators knowledge. Any advice would be very helpful. Thank in advance for your time and help.

            1 Reply Last reply Reply Quote 0
            • 1 / 1
            • First post
              Last post
            Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
            $(document).ready(function () { app.coldLoad(); }); }