Thanks to visit codestin.com
Credit goes to Github.com

Skip to content

Incredibly fast matching engine for HFT written in Golang

License

Notifications You must be signed in to change notification settings

GOnevo/matchingo

Repository files navigation

Go Report Card GitHub go.mod Go version GitHub

Matchingo

Incredibly fast matching engine for HFT written in Golang

Features

  • supports MARKET, LIMIT, STOP-LIMIT, OCO order types
  • supports time-in-force (GTK, FOK, IOC) parameters for LIMIT orders
  • does not use shopspring/decimal for higher performance
  • uses lite decimal for price and quantity arguments
  • well tested code
Order quantity

It is very important! Each SYMBOL is combination of BASE and QUOTE currencies. For example, BTC/USD where BTC is BASE currency, USD is QUOTE currency.

Each order MUST HAVE quantity parameter but pay attention: for MARKET BUY orders you have pass QUOTE quantity.

Examples for BTC/USD symbol:

  • for MARKET SELL order 10 BTC, you have to pass quantity=10
  • for MARKET BUY order 10 BTC, you have to pass maximum quantity of USD for attempt to buy 10 BTC

This may seem inconvenient, but it is a precautionary measure for double spending: when a user places a MARKET BUY in asynchronous way, you will be able to freeze the correct quantity on his balance.

Installation

go get github.com/gonevo/matchingo

Usage

Decimal

Matchingo works with fpdecimal values, so feel free to use:

  • matchingo.FromInt(number int)
  • matchingo.FromFloat(number float64)

Order instance initialization parameters

  • matchingo.NewMarketOrder(orderID string, side Side, quantity fpdecimal.Decimal)
  • matchingo.NewLimitOrder(orderID string, side Side, quantity, price fpdecimal.Decimal, tif TIF, oco string)
  • matchingo.NewStopOrder(orderID string, side Side, quantity, price, stop fpdecimal.Decimal, oco string)

oco parameter is ID of another order from OCO orders set

Order processing

  • matchingo.Process(order *Order) (done *Done, err Error)

Done instance

Process() returns Done instance which contains:

  • Order: processed order
  • Trades: slice of orders from the order book which are participants for this trade
    • OrderID: participant-order ID
    • Price: concrete trade price, string
    • Quantity: concrete trade quantity, string
    • Role: TAKER or MAKER, string
    • IsQuote: true for QUOTE quantity orders
  • Canceled: slice of order IDs which was cancelled for this processing (IOC, OCO), can be empty
  • Activated: slice of order IDs which was activated for this processing (STOP orders), can be empty
  • Left: fpdecimal.Decimal value of left quantity for this processing, can be fpdecimal.Zero
  • Processed: fpdecimal.Decimal value of processed quantity for this processing, can be fpdecimal.Zero
  • Stored: boolean, true if order or its part was appended to stop book or order book

For example:

{
  "order": {
    "orderID": "order2",
    "role": "TAKER",
    "price": "10.00000",
    "isQuote": false,
    "quantity": "9.00000"
  },
  "trades": [
    {
      "orderID": "order2",
      "role": "TAKER",
      "price": "10.00000",
      "isQuote": false,
      "quantity": "9.00000"
    },
    {
      "orderID": "order1",
      "role": "MAKER",
      "price": "10.00000",
      "isQuote": false,
      "quantity": "9.00000"
    }
  ],
  "canceled": [],
  "activated": [],
  "left": "0",
  "processed": "9.00000",
  "stored": false
}

Search

You can search your order at any time using ID

  • matchingo.GetOrder(id string) *Order

it returns an instance of Order or nil if Order not found

Canceling

You can cancel your order at any time

  • matchingo.CancelOrder(id string) *Order

it returns an instance of Order if it was canceled or nil if Order not found

Depth

You can see orderbook depth at any time

  • matchingo.Depth() map[string]string
  • matchingo.DepthJSON() string

For example:

{
   "ask": {
      "21.00000": "20.00000",
      "22.00000": "10.00000",
      "23.00000": "20.00000"
   },
   "bid": {
      "10.00000": "20.00000",
      "11.00000": "10.00000",
      "12.00000": "20.00000"
   }
}

where key is a price, value is a volume

Example

package main

import (
	"fmt"

	"github.com/gonevo/matchingo"
)

func main() {
	orderBook := matchingo.NewOrderBook()
	matchingo.SetDecimalFraction(5) // default is 3

	done1, _ := orderBook.Process(matchingo.NewLimitOrder("order1", matchingo.Sell, matchingo.FromInt(10), matchingo.FromInt(10), "", ""))
	fmt.Println(done1)
	fmt.Println(orderBook)

	done2, _ := orderBook.Process(matchingo.NewLimitOrder("order2", matchingo.Buy, matchingo.FromInt(5), matchingo.FromInt(10), "", ""))
	fmt.Println(done2)
	fmt.Println(orderBook)

	done3, _ := orderBook.Process(matchingo.NewMarketOrder("order3", matchingo.Buy, matchingo.FromFloat(5)))
	fmt.Println(done3)
	fmt.Println(orderBook)
}

Benchmark

goos: linux
goarch: amd64
cpu: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
BenchmarkLimitOrders-8 

Transactions per second (avg): 1139342.359570
 1000000              1755 ns/op            1011 B/op         14 allocs/op

License

matchingo is open-sourced software licensed under the MIT license.

Vano Devium


Made with ❤️ in Ukraine

"Buy Me A Coffee"

About

Incredibly fast matching engine for HFT written in Golang

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published