fintech-algorithms

Tick Bars

Install and import

bash
npm install fintech-algorithms
ts
import { constructBars } from "fintech-algorithms/market-data-engineering/bar-construction/tick-bars";

Signature

constructBars(trades, config)

Closes a bar every N trades rather than every N seconds. Bars then arrive at the rate the market is transacting, so quiet periods produce fewer of them.

Parameters

NameTypeNotes
tradesTrade[]The raw tape in chronological order. Each trade carries tradeId, timestamp, session, symbol, price, volume and currency.
config{ targetTicks: number; closePartial?: boolean }targetTicks is the trade count that closes a bar. closePartial decides whether a final short bar is emitted.

Returns

Bar[] · length fewer

One bar per completed group of targetTicks trades.

Errors

  • When targetTicks is not a positive integer — throws

Complexity: time O(n), space O(bars).

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

trades
[
  {
    "tradeId": "T0001",
    "timestamp": "2026-01-05T14:30:00.000Z",
    "session": "2026-01-05",
    "symbol": "SYNTH",
    "price": 99.99,
    "volume": 36,
    "currency": "USD"
  },
  {
    "tradeId": "T0002",
    "timestamp": "2026-01-05T14:30:04.000Z",
    "session": "2026-01-05",
    "symbol": "SYNTH",
    "price": 99.99,
    "volume": 73,
    "currency": "USD"
  },
  {
    "tradeId": "T0003",
    "timestamp": "2026-01-05T14:30:07.000Z",
    "session": "2026-01-05",
    "symbol": "SYNTH",
    "price": 100,
    "volume": 110,
    "currency": "USD"
  }
]

Showing 3 of 240 elements.

config
{
  "closePartial": true,
  "targetTicks": 12
}

Call

constructBars(trades, config)

Returns

array of 20 objects

[
  {
    "barIndex": 0,
    "session": "2026-01-05",
    "startTime": "2026-01-05T14:30:00.000Z",
    "endTime": "2026-01-05T14:30:45.000Z",
    "lastTradeTime": "2026-01-05T14:30:45.000Z",
    "open": 99.99,
    "high": 100.06,
    "low": 99.98,
    "close": 100.06,
    "volume": 1254,
    "dollarValue": 125416.17,
    "tickCount": 12,
    "firstTradeId": "T0001",
    "lastTradeId": "T0012"
  },
  {
    "barIndex": 1,
    "session": "2026-01-05",
    "startTime": "2026-01-05T14:30:46.000Z",
    "endTime": "2026-01-05T14:31:43.000Z",
    "lastTradeTime": "2026-01-05T14:31:43.000Z",
    "open": 100.05,
    "high": 100.12,
    "low": 100.04,
    "close": 100.12,
    "volume": 1542,
    "dollarValue": 154318.41,
    "tickCount": 12,
    "firstTradeId": "T0013",
    "lastTradeId": "T0024"
  },
  {
    "barIndex": 2,
    "session": "2026-01-05",
    "startTime": "2026-01-05T14:31:48.000Z",
    "endTime": "2026-01-05T14:32:33.000Z",
    "lastTradeTime": "2026-01-05T14:32:33.000Z",
    "open": 100.11,
    "high": 100.18,
    "low": 100.1,
    "close": 100.18,
    "volume": 1640,
    "dollarValue": 164219.51,
    "tickCount": 12,
    "firstTradeId": "T0025",
    "lastTradeId": "T0036"
  }
]

Showing 3 of 20 elements.

Diagrams

Tick Bars — article hero
Tick Bars — boundary and state
Tick Bars — construction anatomy

Calculation flow

Causal construction flow — Tick Bars
flowchart TD
    A["Receive next trade in authoritative order"] --> B{"New session?"}
    B -->|Yes| C["Emit or discard partial tail"]
    C --> D["Reset current bar"]
    B -->|No| E["Keep current bar"]
    D --> F["Append the whole trade"]
    E --> F
    F --> G["Increment count by one"]
    G --> H{"Count equals targetTicks?"}
    H -->|No| A
    H -->|Yes| I["Emit threshold bar with lineage"]
    I --> J["Reset current bar"]
    J --> A

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