Free, open source, a high frequency trading and market making backtesting and trading bot, which accounts for limit orders, queue positions, and latencies, utilizing full tick data for trades and order books(Level-2 and Level-3), with real-world crypto trading examples for Binance and Bybit
=========== HftBacktest ===========
|codeql| |python| |pypi| |downloads| |rustc| |crates| |license| |docs| |roadmap| |github|
High-Frequency Trading Backtesting Tool =======================================
This framework is designed for developing high frequency trading and market making strategies. It focuses on accounting for both feed and order latencies, as well as the order queue position for order fill simulation. The framework aims to provide more accurate market replay-based backtesting, based on full order book and trade tick feed data.
Key Features ============
- Working in
Numba <https://numba.pydata.org/>_ JIT function (Python). - Complete tick-by-tick simulation with a customizable time interval or based on the feed and order receipt.
- Full order book reconstruction based on Level-2 Market-By-Price and Level-3 Market-By-Order feeds.
- Backtest accounting for both feed and order latency, using provided models or your own custom model.
- Order fill simulation that takes into account the order queue position, using provided models or your own custom model.
- Backtesting of multi-asset and multi-exchange models
- Deployment of a live trading bot for quick prototyping and testing using the same algorithm code: currently for Binance Futures and Bybit. (Rust-only)
See full document here <https://hftbacktest.readthedocs.io/>_.
Tutorials you’ll likely find interesting:
High-Frequency Grid Trading - Simplified from GLFT <https://hftbacktest.readthedocs.io/en/latest/tutorials/High-Frequency%20Grid%20Trading%20-%20Simplified%20from%20GLFT.html>_Market Making with Alpha - Order Book Imbalance <https://hftbacktest.readthedocs.io/en/latest/tutorials/Market%20Making%20with%20Alpha%20-%20Order%20Book%20Imbalance.html>_Market Making with Alpha - APT <https://hftbacktest.readthedocs.io/en/latest/tutorials/Market%20Making%20with%20Alpha%20-%20APT.html>_Accelerated Backtesting <https://hftbacktest.readthedocs.io/en/latest/tutorials/Accelerated%20Backtesting.html>_Pricing Framework <https://hftbacktest.readthedocs.io/en/latest/tutorials/Pricing%20Framework.html>_
Trading is a highly competitive field where only the small edges usually exist, but they can still make a significant difference. Because of this, backtesting must accurately simulate real-world conditions.: It should neither rely on an overly pessimistic approach that hides these small edges and profit opportunities, nor on an overly optimistic one that overstates them through unrealistic simulation. Or at the very least, you should clearly understand what differs from live trading and by how much, since sometimes fully accurate backtesting is not practical due to the time it requires.
This is not about overfitting at the start—before you even consider issues like overfitting, you need confidence that your backtesting truly reflects real-world execution. For example, if you run a live trading strategy in January 2025, the backtest for that exact period should produce results that closely align with the actual results. Once you’ve validated that your backtesting can accurately reproduce live trading results, then you can proceed to deeper research, optimization, and considerations around overfitting.
Accurate backtesting is the foundation. Without it, all further analysis—whether conservative or aggressive—becomes unreliable.
Getting started ===============
Installation
hftbacktest supports Python 3.11+. You can install hftbacktest using `pip:
.. code-block:: console
pip install hftbacktest
Or you can clone the latest development version from the Git repository with:
.. code-block:: console
git clone https://github.com/nkaz001/hftbacktest
Data Source & Format
Please see Data or Data Preparation .
You can also find some data here _, hosted by the supporter.
A Quick Example
Get a glimpse of what backtesting with hftbacktest looks like with these code snippets:
.. code-block:: python
@njit def marketmakingalgo(hbt): asset_no = 0 ticksize = hbt.depth(assetno).tick_size lotsize = hbt.depth(assetno).lot_size
# in nanoseconds while hbt.elapse(10000000) == 0: hbt.clearinactiveorders(asset_no)
a = 1 b = 1 c = 1 hs = 1
# Alpha, it can be a combination of several indicators. forecast = 0 # In HFT, it can be various measurements of short-term market movements, # such as the high-low range in the last X minutes. volatility = 0 # Delta risk, it can be a combination of several risks. position = hbt.position(asset_no) risk = (c + volatility) * position half_spread = (c + volatility) * hs
maxnotionalposition = 1000 notional_qty = 100
depth = hbt.depth(asset_no)
midprice = (depth.bestbid + depth.best_ask) / 2.0
# fair value pricing = mid_price + a * forecast # or underlying(correlated asset) + adjustment(basis + cost + etc) + a * forecast # risk skewing = -b * risk reservationprice = midprice + a forecast - b risk newbid = reservationprice - half_spread newask = reservationprice + half_spread
newbidtick = min(np.round(newbid / ticksize), depth.bestbidtick) newasktick = max(np.round(newask / ticksize), depth.bestasktick)
orderqty = np.round(notionalqty / midprice / lotsize) * lot_size
# Elapses a process time. if not hbt.elapse(1000000) != 0: return False
lastorderid = -1 update_bid = True update_ask = True buylimitexceeded = position * midprice > maxnotional_position selllimitexceeded = position * midprice < -maxnotional_position orders = hbt.orders(asset_no) order_values = orders.values() while ordervalues.hasnext(): order = order_values.get() if order.side == BUY: if order.pricetick == newbidtick or buylimit_exceeded: update_bid = False if order.cancellable and (updatebid or buylimit_exceeded): hbt.cancel(assetno, order.orderid, False) lastorderid = order.order_id elif order.side == SELL: if order.pricetick == newasktick or selllimit_exceeded: update_ask = False if order.cancellable and (updateask or selllimit_exceeded): hbt.cancel(assetno, order.orderid, False) lastorderid = order.order_id
# It can be combined with a grid trading strategy by submitting multiple orders to capture better spreads and # have queue position. # This approach requires more sophisticated logic to efficiently manage resting orders in the order book. if update_bid: # There is only one order at a given price, with newbidtick used as the order ID. orderid = newbid_tick hbt.submitbuyorder(assetno, orderid, newbidtick * ticksize, orderqty, GTX, LIMIT, False) lastorderid = order_id if update_ask: # There is only one order at a given price, with newasktick used as the order ID. orderid = newask_tick hbt.submitsellorder(assetno, orderid, newasktick * ticksize, orderqty, GTX, LIMIT, False) lastorderid = order_id
# All order requests are considered to be requested at the same time. # Waits until one of the order responses is received. if lastorderid >= 0: # Waits for the order response for a maximum of 5 seconds. timeout = 5000000_000 if not hbt.waitorderresponse(assetno, lastorder_id, timeout): return False
return True
Tutorials =========
- Data Preparation
_ - Getting Started
_ - Working with Market Depth and Trades
_ - Integrating Custom Data
_ - Making Multiple Markets - Introduction
_ - High-Frequency Grid Trading
_ - High-Frequency Grid Trading - Comparison Across Other Exchanges
_ - High-Frequency Grid Trading - Simplified from GLFT
_ - Impact of Order Latency
_ - Order Latency Data
_ - Guéant–Lehalle–Fernandez-Tapia Market Making Model and Grid Trading
_ - Making Multiple Markets
_ - Risk Mitigation through Price Protection in Extreme Market Conditions
_ - Level-3 Backtesting
_ - Market Making with Alpha - Order Book Imbalance
_ - Market Making with Alpha - Basis
_ - Market Making with Alpha - APT
_ - Queue-Based Market Making in Large Tick Size Assets
_ - Fusing Depth Data
_ - Accelerated Backtesting
_ - Pricing Framework
_
You can find more examples in examples directory and Rust examples .
The complete process of backtesting Binance Futures
high-frequency gridtrading
_: The complete process of backtesting Binance Futures using a high-frequency grid trading strategy implemented in Rust.
Migration to V2 =============== Please see the
migration guide _.
Roadmap =======
Please see the
roadmap _.
Contributing ============
Thank you for considering contributing to hftbacktest! Welcome any and all help to improve the project. If you have an idea for an enhancement or a bug fix, please open an issue or discussion on GitHub to discuss it.
The following items are examples of contributions you can make to this project:
Please see the
roadmap .. |python| image:: https://shields.io/badge/python-3.11+-blue :alt: Python Version :target: https://www.python.org/
.. |codeql| image:: https://github.com/nkaz001/hftbacktest/actions/workflows/codeql.yml/badge.svg?branch=master&event=push :alt: CodeQL :target: https://github.com/nkaz001/hftbacktest/actions/workflows/codeql.yml
.. |pypi| image:: https://badge.fury.io/py/hftbacktest.svg :alt: Package Version :target: https://pypi.org/project/hftbacktest
.. |downloads| image:: https://static.pepy.tech/badge/hftbacktest :alt: Downloads :target: https://pepy.tech/project/hftbacktest
.. |crates| image:: https://img.shields.io/crates/v/hftbacktest.svg :alt: Rust crates.io version :target: https://crates.io/crates/hftbacktest
.. |license| image:: https://img.shields.io/badge/License-MIT-green.svg :alt: License :target: https://github.com/nkaz001/hftbacktest/blob/master/LICENSE
.. |docs| image:: https://readthedocs.org/projects/hftbacktest/badge/?version=latest :target: https://hftbacktest.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status
.. |roadmap| image:: https://img.shields.io/badge/Roadmap-gray :target: https://github.com/nkaz001/hftbacktest/blob/master/ROADMAP.md :alt: Roadmap
.. |github| image:: https://img.shields.io/github/stars/nkaz001/hftbacktest?style=social :target: https://github.com/nkaz001/hftbacktest :alt: Github
.. |rustc| image:: https://shields.io/badge/rustc-1.90-blue :alt: Rust Version :target: https://www.rust-lang.org/