Order System Development (Limit, Market, Stop)

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Order System Development (Limit, Market, Stop)
Complex
~1-2 weeks
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Order System Development (Limit, Market, Stop)

The order system is the heart of any exchange. This is where all trading logic is concentrated, and this is where the cost of error is maximum: a bug in matching engine can liquidate liquidity or create unfair executions in seconds. Let's explore architecture from data model to matching algorithm.

Order Types and Their Semantics

Limit Order

User specifies price and volume. Order executes only if market reaches specified price or better.

  • Buy limit: executes at price ≤ specified
  • Sell limit: executes at price ≥ specified
  • Can be partially filled
  • Unfilled part remains in order book

Additional modifiers: GTC (Good Till Cancelled), GTD (Good Till Date), IOC (Immediate Or Cancel), FOK (Fill Or Kill), Post-Only.

Market Order

Executes immediately at best available price. Guarantees execution, not price. On illiquid markets can have significant slippage.

Safe implementation: slippage limit. If execution requires traversing the book more than X%, order is rejected with PRICE_IMPACT_TOO_HIGH.

Stop Order

Trigger order. Activates when market price reaches stop price. After activation becomes market or limit order.

  • Stop-Market: market order is created when stop price reached
  • Stop-Limit: limit order is created with specified limit price
  • Trailing Stop: stop price follows market at specified distance

Matching Engine Architecture

Order Book Data Structure

Classic implementation — two sorted maps (bid side and ask side) with price as key. At each price level — queue of orders (FIFO for price-time priority).

type PriceLevel struct {
    Price   decimal.Decimal
    Orders  []*Order // FIFO queue
    Total   decimal.Decimal // cached volume
}

type OrderBook struct {
    Bids    *btree.BTree // descending (max bid first)
    Asks    *btree.BTree // ascending (min ask first)
    mu      sync.RWMutex
}

Data structure choice is critical for performance:

  • Red-Black Tree (Go btree, Java TreeMap): O(log n) insert/delete
  • Skip List: concurrent without global lock
  • Array + binary search: faster for reads on small books

For exchange with <10,000 active orders in book — btree is more than enough.

Matching Algorithm

Price-time priority (FIFO matching) — standard for most exchanges.

Data Model

CREATE TABLE orders (
    id              UUID PRIMARY KEY,
    user_id         BIGINT NOT NULL,
    pair_id         SMALLINT NOT NULL,
    side            SMALLINT NOT NULL, -- 0=buy, 1=sell
    type            SMALLINT NOT NULL, -- 0=limit, 1=market, 2=stop_limit, 3=stop_market
    status          SMALLINT NOT NULL DEFAULT 0, -- 0=open, 1=partial, 2=filled, 3=cancelled
    price           NUMERIC(36,18),
    stop_price      NUMERIC(36,18),
    quantity        NUMERIC(36,18) NOT NULL,
    filled_qty      NUMERIC(36,18) NOT NULL DEFAULT 0,
    time_in_force   SMALLINT NOT NULL DEFAULT 0,
    expire_at       TIMESTAMPTZ,
    client_order_id VARCHAR(64),
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE trades (
    id              BIGSERIAL PRIMARY KEY,
    pair_id         SMALLINT NOT NULL,
    taker_order_id  UUID NOT NULL,
    maker_order_id  UUID NOT NULL,
    taker_user_id   BIGINT NOT NULL,
    maker_user_id   BIGINT NOT NULL,
    price           NUMERIC(36,18) NOT NULL,
    quantity        NUMERIC(36,18) NOT NULL,
    taker_fee       NUMERIC(36,18) NOT NULL,
    maker_fee       NUMERIC(36,18) NOT NULL,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Critical moment: matching engine works in memory, database used only for persistence. On startup server loads all open orders into memory. Database writes are asynchronous through queue.

Stop Orders and Trigger Mechanism

Stop orders stored in separate structure — sorted by stop price. On each trade, matching engine publishes last price. Stop orders processor subscribes to price updates.

Trailing stop — special case. When price moves in user's favor, stop price recalculates.

Balance Control and Atomicity

Before placing order need to reserve funds:

  • Buy limit: reserve price * quantity in quote currency
  • Sell limit: reserve quantity in base currency
  • Market buy: reserve maxSpend

On cancellation — release reserve. On fill — move reserve to real counterparty balance.

Atomicity through database transactions, but matching engine can't hit database on each match — bottleneck. Solution: in-memory balance with asynchronous synchronization to database.

Decimal Precision and Floating Point

Never use float64 for financial calculations. For finance use:

  • Go: shopspring/decimal
  • Python: decimal.Decimal
  • Java: BigDecimal
  • JavaScript: decimal.js or bignumber.js

All stored values in database — NUMERIC(36,18) or strings.

Performance and Scaling

One Go matching engine handles 50,000–100,000 orders/sec on modern hardware at latency <1ms. For most CEX this is sufficient.

When scaling needed — sharding by trading pair. BTC/USDT — separate instance, ETH/USDT — separate. Pairs don't interact at matching level.

Component Technology Latency
In-memory order book Go btree <100µs
Stop orders processor Go goroutine <1ms
Balance check In-memory map <10µs
DB persistence PostgreSQL async 5–20ms
WebSocket broadcast Go channels <1ms

Testing

Matching engine covered with unit tests on edge cases:

  • Partial fill with remainder
  • FOK with insufficient liquidity
  • IOC with partial execution
  • Simultaneous cancellation and fill
  • Stop order triggering at placement moment
  • Decimal overflow at extreme values

Property-based testing (fuzzing) — random order sequences generated, invariant checked: total buy volume = total sell volume, balances reconcile.

Development Timeline

  • MVP (limit + market, no stop, no time-in-force): 3–4 weeks
  • Full system with stop orders, all TIF modifiers, trailing stop: 8–12 weeks
  • Production-ready with audit, load tests, monitoring: +4–6 weeks

Cost depends on throughput requirements and availability of ready components (balance, fees, WebSocket).