fintech-algorithms
Using a coding agent? Give it the skill: npx skills add IslamBaraka90/Fintech-Algorithms-Library What it does →

Volume Bars

Install and import#

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

Signature#

constructBars(trades, config)

Closes a bar once a target share volume has traded. Sampling by volume rather than by clock gives series with far more stable statistical properties than time bars.

Parameters#

NameTypeNotes
tradesTrade[]The raw tape in chronological order. Each trade carries tradeId, timestamp, session, symbol, price, volume and currency.
config{ targetVolume: number; closePartial?: boolean }targetVolume is the cumulative share volume that closes a bar. A single trade larger than the target closes a bar on its own. closePartial decides whether a final short bar is emitted.

Returns#

Bar[] · length fewer

One bar per completed volume bucket.

Errors#

  • When targetVolume is not positive — throws

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

Worked example#

verified This is the worked example published in the article, replayed by the test suite on every run. The output cannot drift.

Input#

trades
[
  {
    "tradeId": "W001",
    "timestamp": "2026-01-05T14:30:00.000Z",
    "session": "2026-01-05",
    "symbol": "SYNTH",
    "price": 100,
    "volume": 400,
    "currency": "USD"
  },
  {
    "tradeId": "W002",
    "timestamp": "2026-01-05T14:30:01.000Z",
    "session": "2026-01-05",
    "symbol": "SYNTH",
    "price": 101,
    "volume": 350,
    "currency": "USD"
  },
  {
    "tradeId": "W003",
    "timestamp": "2026-01-05T14:30:02.000Z",
    "session": "2026-01-05",
    "symbol": "SYNTH",
    "price": 99,
    "volume": 500,
    "currency": "USD"
  }
]

Showing 3 of 6 elements.

config
{
  "targetVolume": 1000,
  "closePartial": true
}

Call#

constructBars(trades, config)

Returns#

array of 3 objects

[
  {
    "barIndex": 0,
    "session": "2026-01-05",
    "startTime": "2026-01-05T14:30:00.000Z",
    "endTime": "2026-01-05T14:30:02.000Z",
    "lastTradeTime": "2026-01-05T14:30:02.000Z",
    "open": 100,
    "high": 101,
    "low": 99,
    "close": 99,
    "volume": 1250,
    "dollarValue": 124850,
    "tickCount": 3,
    "firstTradeId": "W001",
    "lastTradeId": "W003"
  },
  {
    "barIndex": 1,
    "session": "2026-01-05",
    "startTime": "2026-01-05T14:30:03.000Z",
    "endTime": "2026-01-05T14:30:04.000Z",
    "lastTradeTime": "2026-01-05T14:30:04.000Z",
    "open": 99.5,
    "high": 100.5,
    "low": 99.5,
    "close": 100.5,
    "volume": 1000,
    "dollarValue": 99900,
    "tickCount": 2,
    "firstTradeId": "W004",
    "lastTradeId": "W005"
  },
  {
    "barIndex": 2,
    "session": "2026-01-05",
    "startTime": "2026-01-05T14:30:05.000Z",
    "endTime": "2026-01-05T14:30:05.000Z",
    "lastTradeTime": "2026-01-05T14:30:05.000Z",
    "open": 101,
    "high": 101,
    "low": 101,
    "close": 101,
    "volume": 250,
    "dollarValue": 25250,
    "tickCount": 1,
    "firstTradeId": "W006",
    "lastTradeId": "W006"
  }
]

Diagrams#

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

Calculation flow#

Causal construction flow - Volume Bars
flowchart TD
    A["Receive next cleaned eligible trade"] --> B{"New session?"}
    B -->|Yes| C["Apply partial-tail policy; reset to zero"]
    B -->|No| D["Keep open bar"]
    C --> E["Add the whole trade"]
    D --> E
    E --> F{"Cumulative shares >= target?"}
    F -->|No| A
    F -->|Yes| G["Emit OHLCV, close reason, and lineage"]
    G --> H["Reset to zero; do not carry overshoot"]
    H --> 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#

The rest of the Bar Construction family#