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

Backtesting with tick data and ask/bid prices



  • Hi,

    I know similar questions have been already asked in the forums but I just want to make sure I understand everything correctly.

    I need to work with historical tick data (every price change) and ask/bid prices.

    From what I understand you can use this type of data in your backtests for calculations, resampling etc.

    But it's not possible to test solely on tick data because the Broker and the trade functions require close or open prices. When I tried it in practice I was able to read my custom data feed and print the prices. But when I started placing orders I got errors like for example: AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'close'

    The columns in the feed are just:
    datetime, bid, ask

    Thank you in advance for any comments on this. I can provide minimum example if needed.


  • administrators

    First and foremost: backtrader is not a backtesting engine which supports bid/ask for execution. In most cases, people use either the bid, ask or midpoint component to decide what's the current price

    When you say

    @malapija said in Backtesting with tick data and ask/bid prices:

    I need to work with historical tick data (every price change) and ask/bid prices.

    It would seem you have an extra component besides bid and ask

    @malapija said in Backtesting with tick data and ask/bid prices:

    The columns in the feed are just:
    datetime, bid, ask

    But you don't.

    @malapija said in Backtesting with tick data and ask/bid prices:

    But it's not possible to test solely on tick data because the Broker and the trade functions require close or open prices

    And high and low to make the best possible matching engine with Stop / Limit (and their combinations) orders.

    With all that in mind and if you still think you want to use backtrader, you could do the following:

    • Decide if you want to use bid, ask or midpoint
    • Load the data feed
      • If you are using bid, use the value for all components open, high, low and close
      • If you are using ask, use the value for all components open, high, low and close
      • If you have chosen midpoint, you may place bid in open and ask inclose`
        • Add a Filter which averages both the open and the close and uses the result to replace the values of the OHLC components

    Now you are ready to go.



  • Thank you for the quick reply!

    @backtrader said in Backtesting with tick data and ask/bid prices:

    It would seem you have an extra component besides bid and ask

    Indeed. I wanted to keep the example simple because I think if I can make this simple version work I'll be able to figure out the rest. But in fact I have a market depth with n-prices and n-volumes for multiple assets. I'm exploring triangular arbitrage in illiquid markets.

    Thank you for pointing me to the Filter. As I understand it you can use it to modify the incoming data feed. What complicates it in my case is that I sometimes need to use ask and sometimes bid based on the currently opened positions and the current arbitrage opportunity which is calculated in the strategy on each incoming tick.

    Concrete (simplified) example: Let's say we have two assets: A1, A2 with bid/ask prices A1.b, A1.a, A2.b, A2.a. An arbitrage opportunity between A1 and A2 appears and we need to go long on A1, short on A2. Therefore we need to use A1.a for entering the long position and A2.b for entering the short position (assuming Market orders). The difference between bid and ask is quite important in this case because with arbitrage we're going for tiny market inefficiencies.

    My current understanding from what I tried with backtrader and from what you wrote is that this probably won't be possible, right? I also explored all other Python backtesting frameworks you mention in Github README and it seems that none of them will be easily applicable to my use case although I need to explore QSTrader and QTPyLib in more depth.


  • administrators

    @malapija said in Backtesting with tick data and ask/bid prices:

    Concrete (simplified) example: Let's say we have two assets: A1, A2 with bid/ask prices A1.b, A1.a, A2.b, A2.a. An arbitrage opportunity between A1 and A2 appears and we need to go long on A1, short on A2. Therefore we need to use A1.a for entering the long position and A2.b for entering the short position (assuming Market orders). The difference between bid and ask is quite important in this case because with arbitrage we're going for tiny market inefficiencies.

    Your problem is that you are expecting an execution which is not part of backtrader. Backtrader works on the principle that a price which has been seen cannot used for matching. If you have seen A1.a and A2.b, the prices are gone. Your Market orders will be executed with the next incoming prices.

    In your case the cheat-on-close mode won't help, because for A2.b you would need to be matched with for example the current open price for A2 which is where you would code that information (A1.a would be encoded in the close price of A1)

    As stated at the beginning: backtrader was not conceived for bid/ask execution.

    @malapija said in Backtesting with tick data and ask/bid prices:

    My current understanding from what I tried with backtrader and from what you wrote is that this probably won't be possible, right? I also explored all other Python backtesting frameworks you mention in Github README and it seems that none of them will be easily applicable to my use case although I need to explore QSTrader and QTPyLib in more depth

    I don't think they are meant for bid/ask execution either, but the platforms (except for 2 or 3) were not explored in full detail.