fintech-algorithms

Self-Trade Prevention

Install and import

bash
npm install fintech-algorithms
ts
import { selfTradePrevention } from "fintech-algorithms/matching-engines-and-venue-logic/order-controls/self-trade-prevention";

Signature

selfTradePrevention(incoming_order, resting_orders, mode)

Stops a participant trading with itself — required by most venues, and the *mode* determines who loses their order. Cancel-newest, cancel-oldest and cancel-both give materially different outcomes for queue position.

Parameters

NameTypeNotes
incoming_orderOrderThe aggressing order with its participant identifier.
resting_ordersOrder[]Resting orders that would otherwise match.
modestringPrevention mode — cancel newest, cancel oldest, cancel both, or decrement.

Returns

{ action, cancelled, remaining, mode, … }

Which orders were cancelled and which survive, under the mode applied.

Errors

  • When the mode is unrecognised — throws

Complexity: time O(resting), space O(cancelled).

Worked example

executed Captured by running this function on the input its own test provides. Real output of real code — but not asserted against a published figure.

Input

incoming_order
{
  "order_id": "IN-1",
  "side": "buy",
  "price_atoms": 1000200,
  "quantity": 600,
  "participant_id": "P-1",
  "stp_group": "G-1"
}
resting_orders
[
  {
    "order_id": "R-EXT-1",
    "side": "sell",
    "price_atoms": 1000000,
    "quantity": 150,
    "participant_id": "P-EXT",
    "stp_group": "G-X",
    "sequence": 1
  },
  {
    "order_id": "R-SELF",
    "side": "sell",
    "price_atoms": 1000100,
    "quantity": 220,
    "participant_id": "P-1",
    "stp_group": "G-1",
    "sequence": 2
  },
  {
    "order_id": "R-EXT-2",
    "side": "sell",
    "price_atoms": 1000200,
    "quantity": 300,
    "participant_id": "P-EXT",
    "stp_group": "G-X",
    "sequence": 3
  }
]
mode
"cancel_newest"

Call

selfTradePrevention(incoming_order, resting_orders, mode)

Returns

object with 11 fields: mode, incoming_order_id, original_incoming_quantity, external_executed_quantity, prevented_self_quantity, canceled_incoming_quantity, canceled_resting_quantity, remaining_incoming_quantity, …

{
  "mode": "cancel_newest",
  "incoming_order_id": "IN-1",
  "original_incoming_quantity": 600,
  "external_executed_quantity": 150,
  "prevented_self_quantity": 220,
  "canceled_incoming_quantity": 450,
  "canceled_resting_quantity": 0,
  "remaining_incoming_quantity": 0,
  "events": [
    {
      "action": "execute-external",
      "incoming_order_id": "IN-1",
      "resting_order_id": "R-EXT-1",
      "quantity": 150,
      "price_atoms": 1000000
    },
    {
      "action": "cancel-incoming",
      "incoming_order_id": "IN-1",
      "resting_order_id": "R-SELF",
      "prevented_quantity": 220
    }
  ],
  "resting_orders": [
    {
      "order_id": "R-SELF",
      "side": "sell",
      "price_atoms": 1000100,
      "quantity": 220,
      "participant_id": "P-1",
      "stp_group": "G-1",
      "sequence": 2
    },
    {
      "order_id": "R-EXT-2",
      "side": "sell",
      "price_atoms": 1000200,
      "quantity": 300,
      "participant_id": "P-EXT",
      "stp_group": "G-X",
      "sequence": 3
    }
  ],
  "state": "self-trade-prevented"
}

Other exports

This module also exports tickSizeValidation, priceBandValidation, cancelOnDisconnect, fatFingerLimit, circuitBreakerTrigger, calculate. Every module additionally exports run as an alias of its primary function, and a meta object carrying its catalog id, domain, family, shape and article URL.

Diagrams

Self-Trade Prevention — system map

How it works

This page states the contract — how to call it correctly. The article explains the concept: why it works, and where it breaks.

Read the article →

References