nkaz001 / hftbacktest

A high-frequency trading and market-making backtesting and trading bot in Python and Rust, which accounts for limit orders, queue positions, and latencies, utilizing full tick data for trades and order books, with real-world crypto market-making examples for Binance Futures
MIT License
2.01k stars 395 forks source link

Orders are getting filled without any trade occuring #158

Open mmertc opened 1 week ago

mmertc commented 1 week ago

Hello,

I'm trying to backtest a strategy using hftbacktest. My dataset is binance btcusdt spot for 01.11.2024, which I downloaded as a sample via tardis. However, when I iterate using elapse and save the position value for each iteration, I see that my position becomes non-zero and some of my orders get filled on the timestamp shown below:

image

However, my trade data does only have a single trade occurring between the row 5540's and 5607's timestamps, as shown below:

image

i.e. only the trade on row 51 happens between the timestamps I mentioned previously. But the problem is that my position value decreases, implying a buy trade happening but there is none in the related time period. How this can be possible? I'm saving the position value on each iteration using hbt.position(0).

nkaz001 commented 1 week ago

The trades you are referring to are those occurring on the market, correct? An order fill can occur not only through market trades but also through crossed BBO. For example, if your bid order is at $10 and the best ask drops to $10 (with the BBO being $9 and $10, changing from $10 and $11), your bid order will be filled. This happens because Hftbacktest is a market-data-replay-based backtesting tool, which cannot alter the market, making the no-market-impact assumption crucial. In a liquid market with sufficiently small order quantity, this assumption can align well with live results. But, it is always essential to compare backtesting results with live results and tune the backtesting (order fill model) accordingly. For more details on order fill conditions, please see here.

mmertc commented 1 week ago

Hello,

Thanks for your reply. However it seems there is also no change in the best ask bid prices. So in this case position is changing without a trade occuring and without a change in ask bid prices. Could there be another explanation?

image

For example, image shows that there were no change in the ask prices, it is the same case for the bids.

nkaz001 commented 1 week ago

Can you check the order's exchange timestamp when the order is filled? Since the order fill occurs at the exchange, it should be identified based on the exchange timestamp. Due to the order latency, it could be misleading if you record your position changes at local timestamp.