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 threading
from collections import deque
from datetime import datetime
from backtrader.feed import DataBase
from backtrader.utils.py3 import with_metaclass
class 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.