Problem with implementing Custom Websockets into a Datafeed
-
Hello @backtrader would you or someone else explain to me how i can create a custom live datafeed using websockets?
I am a very big fan of this framework and everything works fine execept this websocket problem i cannot solve.
i know that backtrader works with lines and i already read the documentation and the feed.py many times and i looked into other projects on github how they managed the implementation(i dont want to create a store or something, hope its possible without), but its unclear for me how i can implement a running websocket into the datafeed.
i didnt find examples that matches what i am trying to do, yet.
when i try to start the websocket with a background thread in the start(self): i get a error (AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute '_laststatus')
when i try to start it in the init it gets skipped (i dont undertsand why)
i hope that i do not have to use asyncio, because that would be a problem.
heres a example of what ive done so far:
import backtrader as bt
import hmac
import json
import time
import websocket
from backtrader.utils.py3 import with_metaclass, queue
import threadingfrom collections import deque
from datetime import datetimefrom backtrader.feed import DataBase
from backtrader.utils.py3 import with_metaclassclass BybitWS(bt.DataBase):
def on_open(self, ws): print("Open") # Subscribe to the trade channel for BTCUSD perpetual swap contract ws.send(json.dumps({ "op": "subscribe", "args": [ "publicTrade.BTCUSDT"]})) # , # "publicTrade.ETHUSDT"]})) def on_message(self, ws, message): json_message = json.loads(message) # print("| Timestamp :", json_message['data'][0]['i'], # "| Price :", json_message['data'][0]['p'], # "| Volume :", json_message['data'][0]['v'], # "| Side :", json_message['data'][0]["S"], # "| BlockTrade :", json_message['data'][0]["BT"]) print(json_message) v = float(json_message['data'][0]['p']) self._data.append(v) def connect(self): socket = 'wss://stream-testnet.bybit.com/v5/public/spot' ws = websocket.WebSocketApp(socket, on_open=self.on_open, on_message=self.on_message) ws.run_forever() def __init__(self): DataBase.__init__(self) self._data = deque() # data queue for price data self._last_id = '' # last processed trade id for ohlcv self._last_ts = 0 # last processed timestamp for ohlcv self.thread = None # self.thread = threading.Thread(target=self.connect) # self.thread.daemon = True # self.thread.start() def haslivedata(self): return True def islive(self): return True def start(self): self.thread = threading.Thread(target=self.connect) self.thread.daemon = True self.thread.start() def _load(self): print("can do other stuff while websocket is running")
class PrintClose(bt.Strategy):
def start(self): print("---------Backtrader-Start------------") def next(self): print("Close:", self.data.close[0]) def stop(self): print("---------Backtrader-Stop------------")
cerebro = bt.Cerebro()
data = BybitWS()
cerebro.adddata(data)
cerebro.addstrategy(PrintClose)
cerebro.run()is there a way to implement a websocket that runs in a endless loop? Because it cannot be that complicated and i dont think i am the only one with that problem.
A quick example or explanation how i could solve that woudl be very nice
thx in advance.
-
-