For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Does Backtrader support multiple brokers?



  • I'm writing an arbitrage strategy and will have to deal with two brokers.
    Is it possible in Backtrader to have more than one broker?


  • administrators

    No, it doesn't.



  • I'm exploring workaround solutions to work with more then one broker.

    • is it possible to change the broker at runtime (at strategy)?
    • if not possible to change directly. will it make sense to create a wrapper that will hold several brokers and will cycle between them by **kwargs?

    I can imagine any alteration on the broker will cripple the backtesting, but how about live trade?


  • administrators

    @jacob said in Does Backtrader support multiple brokers?:

    is it possible to change the broker at runtime (at strategy)?

    Changing the value held by an attribute in Python is always possible. It will probably break lots of things.

    @jacob said in Does Backtrader support multiple brokers?:

    if not possible to change directly. will it make sense to create a wrapper that will hold several brokers and will cycle between them by **kwargs?

    As long as your wrapper looks and conforms to what's expected from the broker.



  • @backtrader said in Does Backtrader support multiple brokers?:

    As long as your wrapper looks and conforms to what's expected from the broker.

    to give some context to my question I want to use @Ed-Bartosh ccxt development for backtrader.
    ccxt is already a wrapper for multiple crypto brokers, so as I see it, all that is needed is to change the 'exchange' value at the store.

    I'm trying to understand what will be the implications (if any) of making those switches at runtime?
    (backtesting, analyzers, observers...)



  • I tested a bit the idea of using a wrapper for multiple brokers (by changing the 'exchange' value in ccxt store).

    In principle it seem it can be done.

    My problem is that almost all the BrokerBase methods doesn't have a way to pass the 'exchange' I want to refer to as an argument. so I have difficulties syncing between the action/info I want and the 'exchange' I want it from.

    A possible solution to the issue can be to set the 'exchange' value to the wanted 'exchange' that I want to work with before executing a certain part of the logic.
    (using a set_exchange at the broker/store level).
    but it feels a bit fragile and prone to errors. (and cripple parallel calculation that i might want to use in the future)

    any ideas on the subject would be most welcome? even solution on the design level...



  • I've been looking at similar, we have our own multi-exchange price and order engine so am looking at writing a custom broker for that.

    I found some notes in the IB Broker https://github.com/backtrader/backtrader/blob/master/backtrader/brokers/ibbroker.py

    that might help, looks like you can extend:

      Example: if the 4 order execution types directly supported by
      ``backtrader`` are not enough, in the case of for example
    
      *Interactive Brokers* the following could be passed as *kwargs*::
        orderType='LIT', lmtPrice=10.0, auxPrice=9.8
    

    So inside the Order, you could add kwargs and select broker then, I've not looked into whether this works on price/etc etc yet. I guess you could initialise the class with it.

    Let me know if you find out anything else



  • @tomtom when looking at 'BrokerBase' class only the 'buy' and 'sell' methods have **kwargs. where as all the other methods doesn't.

    The problem is that the signature of this functions cannot be change as they are used by backtrader in a variety of places. This is the real challenge here.

    But maybe we can really use the 'order' object and add there the information of the exchange. this can make the functions 'cancel' and 'get_notification' usable.

    get_ cash and get_value maybe need to be an aggregation from all exchanges. and a new custom function should be made that the strategy need to call specifically

    (getposition need to be check ???)

    this might work



  • you're right. I will keep looking into this too. Let me know how you get on.



  • @jacob It would be great to have more generic solution for this. It's great that ccxt supports multiple exchanges, but it would be much better to implement special broker that supports one or more brokers and switching between them.

    Something like this may be?

     broker1 = bt.brokers.CCXTBroker(exchange='gemini')
     broker2 = bt.brokers.CCXTBroker(exchange='bitmex')
     cerebro.setbroker(bt.brokers.MultiBroker({'gemini': broker1, 'bitmex': broker2})
    

    MultiBroker should have a way to change the broker that can be called from the strategy:

    multibroker.switch('gemini')
    

    This shouldn't be hard to implement I guess.



  • @Ed-Bartosh the problem is not switching between brokers.

    Backtrader is using some of the broker capabilities internally (like get_notification, get_cash, get_value, get_position) for stuff like analyzers and observers.
    and when Backtrader try to internally get cash, value and position it make sense to aggregate and not give broker specific info as it will show only part of the whole portfolio.

    buy/sell seem to be the only methods to have some degree of freedom using **kwargs. I was thinking to use it for saving also 'broker/exchange' data into the order object.



  • @jacob switching between brokers was just one example based on the concern you've expressed in your previous post.

    The rest of the broker API should be also implemented for the MultiBroker of course. For example get_cash, get_value and get_position would query all underlying brokers for this info and combine it, I guess. It's pretty staightforward to implement in my opinion.



  • I have created a project on github based on @Ed-Bartosh work.
    it support working simultaneously on multiple ccxt exchanges.

    CCXTMultiBroker

    key features:

    • after creating the multibroker each exchange need to be added manually using 'add_exchange'
    • most methods have a 'exchange' param to refer to the wanted exchange. some methods use the exchange info buried in the 'data' (ccxt feed object)
    • cash and value defaults are aggregations of all exchanges.
    • each exchange have special param 'currency_conversion_rate' that can be updated to convert amounts to one single currency


  • @jacob Can it be done in more generic manner, i.e. independent from CCXT?



  • @ed-bartosh ccxt had some unique properties that made it possible to implement the broker straight from BrokerBase and give access to more then 1 exchange simultaneously in a way that feel very integrated and easy to use. remember that ccxt project is all about unifying the variety of exchanges under one api.
    and a key part of my development was that the feed had some exchange info inside it.

    but to make a more generic broker means to really create a broker that hold a collection of brokers inside (that are not really unified) and switching between them like you proposed before.

    The biggest problem this way, is that there are still methods that will get called by Backtrader in the background on the 'active' broker without the intention of the user.

    A better solution that may work more like what i wrote is if every feed will hold some broker information in a well known way and then you don't need to guess on what broker.