nkaz001 / hftbacktest

A high-frequency trading and market-making backtesting tool 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
1.73k stars 342 forks source link

How to load only depth, bookticker, and trade for backtesting #96

Closed zhangyiyan617 closed 3 weeks ago

zhangyiyan617 commented 1 month ago

I am currently using your framework for cryptocurrency trading backtesting. My arbitrage strategy requires only the depth, bookticker, and trade data, and does not need the snapshot data.

Could you please provide some guidance or examples on how to configure the system to load only these specific data types for my backtests?

Thank you for your help!

nkaz001 commented 1 month ago

Could you elaborate on what snapshot you are referring to? If you need depth data, you need an initial snapshot to build the depth at the beginning. If you are okay relying on natural refresh, you don't need to process the snapshot when creating normalized data (npz), and you don't need to input the initial snapshot. HftBacktest primarily uses depth and trade data. The snapshot is part of the depth data, used to recover depth after a connection loss or similar issues. If not provided, it relies on the natural refresh.

Regarding bookticker, do you intend to fuse L2 market depth and L1 data to get the best information? This feature is still unstable, not tested yet. The unstable_fuse feature providing FusedHashMapMarketDepth helps combine the two data sets and maintain up-to-date best bid and ask information. You need to process the bookticker data set event BBO_EVENT into the normalized data.

zhangyiyan617 commented 1 month ago

Thank you for the detailed response.

I am currently working on a cryptocurrency arbitrage strategy across different exchanges. While learning to perform backtesting, I noticed in your example that when creating the hbt instance, you used AssetBuilder::new().data(data).depth(depth.apply_snapshot("snapshot file.npz")).

However, I only collected the data and did not collect a snapshot file. When I skip the input of the snapshot file, it throws an error.

Could you please advise me on how to proceed without using a snapshot file?

Thank you for your assistance!

nkaz001 commented 1 month ago

Try it below

let hbt = MultiAssetMultiExchangeBacktest::builder()
        .add(
            AssetBuilder::new()
                .data(data)
                .latency_model(latency_model)
                .asset_type(asset_type)
                .maker_fee(-0.00005)
                .taker_fee(0.0007)
                .queue_model(queue_model)
                .depth(|| {
                    let mut depth = HashMapMarketDepth::new(0.000001, 1.0);
                    // Comment out below.
                    // depth.apply_snapshot(&read_npz("1000SHIBUSDT_20240501_SOD.npz").unwrap());
                    depth
                })
                .exchange(ExchangeKind::NoPartialFillExchange)
                .build()
                .unwrap(),
        )
        .build()
        .unwrap();
zhangyiyan617 commented 1 month ago

Thank you! I will try it shortly.