GithubHelp home page GithubHelp logo

joytrust0609 / hftbacktest Goto Github PK

View Code? Open in Web Editor NEW

This project forked from nkaz001/hftbacktest

0.0 0.0 0.0 119.49 MB

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

License: MIT License

Python 19.43% Rust 80.57%

hftbacktest's Introduction

HftBacktest

CodeQL Python Version Package Version Downloads Rust Version Rust crates.io version License Documentation Status 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

The experimental features are currently in the early stages of development, having been completely rewritten in Rust to support the following features.

  • Working in Numba 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 L2 Market-By-Price and L3 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 using the same algorithm code: currently for Binance Futures and Bybit. (Rust-only)

Documentation

See full document here.

Getting started

Installation

hftbacktest supports Python 3.10+. You can install hftbacktest using pip:

pip install hftbacktest

Or you can clone the latest development version from the Git repository with:

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:

@njit
def market_making_algo(hbt):
    asset_no = 0
    tick_size = hbt.depth(asset_no).tick_size
    lot_size = hbt.depth(asset_no).lot_size

    # in nanoseconds
    while hbt.elapse(10_000_000) == 0:
        hbt.clear_inactive_orders(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

        max_notional_position = 1000
        notional_qty = 100

        depth = hbt.depth(asset_no)

        mid_price = (depth.best_bid + 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
        reservation_price = mid_price + a * forecast - b * risk
        new_bid = reservation_price - half_spread
        new_ask = reservation_price + half_spread

        new_bid_tick = min(np.round(new_bid / tick_size), depth.best_bid_tick)
        new_ask_tick = max(np.round(new_ask / tick_size), depth.best_ask_tick)

        order_qty = np.round(notional_qty / mid_price / lot_size) * lot_size

        # Elapses a process time.
        if not hbt.elapse(1_000_000) != 0:
            return False

        last_order_id = -1
        update_bid = True
        update_ask = True
        buy_limit_exceeded = position * mid_price > max_notional_position
        sell_limit_exceeded = position * mid_price < -max_notional_position
        orders = hbt.orders(asset_no)
        order_values = orders.values()
        while order_values.has_next():
            order = order_values.get()
            if order.side == BUY:
                if order.price_tick == new_bid_tick or buy_limit_exceeded:
                    update_bid = False
                if order.cancellable and (update_bid or buy_limit_exceeded):
                    hbt.cancel(asset_no, order.order_id, False)
                    last_order_id = order.order_id
            elif order.side == SELL:
                if order.price_tick == new_ask_tick or sell_limit_exceeded:
                    update_ask = False
                if order.cancellable and (update_ask or sell_limit_exceeded):
                    hbt.cancel(asset_no, order.order_id, False)
                    last_order_id = 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 new_bid_tick used as the order ID.
            order_id = new_bid_tick
            hbt.submit_buy_order(asset_no, order_id, new_bid_tick * tick_size, order_qty, GTX, LIMIT, False)
            last_order_id = order_id
        if update_ask:
            # There is only one order at a given price, with new_ask_tick used as the order ID.
            order_id = new_ask_tick
            hbt.submit_sell_order(asset_no, order_id, new_ask_tick * tick_size, order_qty, GTX, LIMIT, False)
            last_order_id = order_id

        # All order requests are considered to be requested at the same time.
        # Waits until one of the order responses is received.
        if last_order_id >= 0:
            # Waits for the order response for a maximum of 5 seconds.
            timeout = 5_000_000_000
            if not hbt.wait_order_response(asset_no, last_order_id, timeout):
                return False

    return True

Tutorials

Examples

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

Currently, new features are being implemented in Rust due to the limitations of Numba, as performance is crucial given the size of the high-frequency data. The imminent task is to integrate hftbacktest in Python with hftbacktest in Rust by using the Rust implementation as the backend. Meanwhile, the data format, which is currently different, needs to be unified. On the pure Python side, the performance reporting tool should be improved to provide more performance metrics with increased speed.

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.

hftbacktest's People

Contributors

nkaz001 avatar bohblue2 avatar roykim98 avatar arthpatel01 avatar wannabebotter avatar richwomanbtc avatar xtma avatar d23rojew avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.