====== T4 Chart API ======
Our chart API provides data in aggregated or non-aggregated (raw trade) formats.
All times are in CST.
The complete API documentation is available via Swagger UI at:
[[https://api-sim.t4login.com/chart/swagger/index.html|T4 Chart API Documentation]]
The Swagger documentation provides:
* Complete list of available endpoints
* Request parameters and response formats
* Interactive testing capability
* Authentication requirements
**What changed in this revision** \\
This page documents the **open-source decoder libraries** that consume the chart API's compact binary response:
* A top-level section **[[#Decoder Libraries]]** documenting the JavaScript (``@t4/chart-decoder``), Python (``t4login``) and .NET (``T4APIDemo``) reference decoders, including the streaming handler interface, the ``ChartDataState`` field reference, and the ``ChartDataChange`` / ``MarketMode`` / ``BidOffer`` enumerations.
See **[[#Revision Notes / Changelog]]** at the bottom for the detailed list.
===== Aggregated Chart Data =====
==== Overview ====
The **GetBarChart** API retrieves bar chart data for a specified trading instrument over a given date range. This API supports various chart types and bar intervals, tailored for detailed data analysis in financial contexts.
==== API Endpoint ====
GET https://api-sim.t4login.com/chart/barchart
==== Headers ====
For proper access and response handling, the **GetBarChart** API requires certain HTTP headers to be set in the request.
^ Header ^ Value ^ Description ^
| Authorization | Bearer | **Required**. A valid bearer token to authenticate the request. |
**Examples:**
* To authorize the request, include the bearer token:
Authorization: Bearer YOUR_ACCESS_TOKEN
==== Parameters ====
^ Parameter ^ Description ^
| **exchangeId** | **Required**. Identifier for the exchange. |
| **contractId** | **Required**. Identifier for the contract. |
| **chartType** | **Required**. Type of chart to compute. Currently, only **Bar** type is supported. |
| **barInterval** | **Required**. Interval at which bars are aggregated. Possible values:\\ • **Tick**: Bars aggregated based on trade count.\\ • **TickRange**: Bars aggregated based on price range.\\ • **Volume**: Bars aggregated based on number of contracts traded.\\ • **Second**: Bars aggregated into multiples of seconds.\\ • **Minute**: Bars aggregated into multiples of minutes.\\ • **Hour**: Bars aggregated into multiples of hours.\\ • **Day**: Bars aggregated into multiples of days.\\ • **Week**: Bars aggregated into multiples of weeks. |
| **barPeriod** | **Required**. Period for the bars. |
| **tradeDateStart** | **Required**. Start date for the trade data. |
| **tradeDateEnd** | **Required**. End date for the trade data. |
| marketID | Market ID (optional). Can be omitted when using ContinuationType. |
| continuationType | Method of continuation for the chart. Only **Volume** is currently supported. |
| resetInterval | Interval at which bar computations reset (not applicable when ContinuationType.Volume is used). \\ Defaults to **TradingDay**. Other possible values:\\ • **None**: No reset interval.\\ • **TradingWeek**: Reset on the trading week boundary.\\ • **ExpiryChange**: Reset on an expiry change. |
| contractMonths | Contract months to include (not applicable when **ContinuationType.Volume** is used). |
| rolloverThreshold| Rollover threshold (not applicable when **ContinuationType.Volume** is used). |
| forwardMonths | Forward months (not applicable when **ContinuationType.Volume** is used). |
==== Response ====
The response from the **GetBarChart** API is a JSON object containing detailed information about the bar chart data. Below is the structure of the response along with a description of each element:
=== Bars ===
^ Element ^ Description ^
| tradeDate | Date of the trade. |
| time | Time when the bar data starts. |
| closeTime | Time when the bar data ends. |
| marketID | Identifier for the market. |
| openPrice | Opening price for this bar. |
| highPrice | Highest price in this bar. |
| lowPrice | Lowest price in this bar. |
| closePrice | Closing price for this bar. |
| volume | Total volume of trades in this bar. |
| volumeAtBid | Volume of trades at the bid price. |
| volumeAtOffer | Volume of trades at the offer price. |
| trades | Total number of trades in this bar. |
| tradesAtBid | Number of trades at the bid price. |
| tradesAtOffer | Number of trades at the offer price. |
=== MarketDefinitions ===
^ Element ^ Description ^
| marketID | Identifier for the market. |
| minPriceIncrement | Minimum increment of the market's price. |
| priceCode | Code related to the pricing of the market. |
| tickValue | Value of each tick in the market's pricing. |
| vpt | Additional market-specific information (variable). |
=== ModeChanges ===
^ Element ^ Description ^
| marketID | Identifier for the market. |
| tradeDate | Date of the trade. |
| time | Time when the mode change occurred. |
| marketMode | The mode of the market at the given time. |
=== OpenInterests ===
^ Element ^ Description ^
| marketID | Identifier for the market. |
| tradeDate | Date of the trade. |
| time | Time of the recorded open interest. |
| openInterest | The amount of open interest. |
=== Settlements ===
^ Element ^ Description ^
| marketID | Identifier for the market. |
| tradeDate | Date of the trade. |
| time | Time when the settlement information was recorded. |
| settlementPrice | Price at which the trade was settled. |
| isHeld | Indicates if the settlement was held (boolean). |
==== Example JSON Response ====
{
"tradeDateStart": "2024-01-08T00:00:00",
"tradeDateEnd": "2024-01-08T00:00:00",
"activeMarket": "XCME_Eq ES (H24)",
"bars": [
{
"tradeDate": "2024-01-08T00:00:00",
"time": "2024-01-08T00:00:00",
"closeTime": "2024-01-08T15:59:59.5853624",
"marketID": "XCME_Eq ES (H24)",
"openPrice": "473575",
"highPrice": "480325",
"lowPrice": "471525",
"closePrice": "479800",
"volume": 1339989,
"volumeAtBid": 665050,
"volumeAtOffer": 674939,
"trades": 320624,
"tradesAtBid": 152333,
"tradesAtOffer": 168291
}
],
"marketDefinitions": [
{
"marketID": "XCME_Eq ES (H24)",
"minPriceIncrement": "25",
"priceCode": "",
"tickValue": 12.5,
"vpt": ""
}
],
"modeChanges": [
{
"marketID": "XCME_Eq ES (H24)",
"tradeDate": "2024-01-08T00:00:00",
"time": "2024-01-07T08:04:27.7736882",
"marketMode": 5
},
// ... additional mode changes ...
],
"openInterests": [
{
"marketID": "XCME_Eq ES (H24)",
"tradeDate": "2024-01-08T00:00:00",
"time": "2024-01-07T12:43:16.8256856",
"openInterest": 2211632
},
// ... additional open interests ...
],
"settlements": [
{
"marketID": "XCME_Eq ES (H24)",
"tradeDate": "2024-01-08T00:00:00",
"time": "2024-01-05T16:38:39.9345143",
"settlementPrice": "473475"
},
{
"marketID": "XCME_Eq ES (H24)",
"tradeDate": "2024-01-08T00:00:00",
"time": "2024-01-08T15:01:01.4810068",
"isHeld": true
}
// ... additional settlements ...
]
}
===== Non-Aggregated Chart Data (Trade History) =====
==== Overview ====
The **GetTradeHistory** API retrieves historical trade data for a specified trading instrument within a given date and time range. This API allows for querying trade data based on the trade date or specific start and end timestamps.
==== API Endpoint ====
GET https://api-sim.t4login.com/chart/tradehistory
==== Headers ====
^ Header ^ Value ^ Description ^
| Authorization | Bearer | **Required**. A valid bearer token to authenticate the request. |
==== Parameters ====
^ Parameter ^ Description ^
| exchangeId | **Required**. Identifier for the exchange. |
| contractId | **Required**. Identifier for the contract. |
| marketID | Market ID (optional). |
| tradeDateStart | The start date for the trade history based on trade dates (optional). |
| tradeDateEnd | The end date for the trade history based on trade dates (optional). |
| start | The calendar start date and time for the request in CST (optional). |
| end | The calendar end date and time for the request in CST (optional). |
| since | Filters data to only include trades after the specified date and time (optional). |
**Note:** Pass either **tradeDateStart** and **tradeDateEnd** OR **start** and **end**. Including both will result in an error. Use **since** to further filter data to only include trades after the specified date and time.
=== Response ===
^ Element ^ Description ^
| exchangeID | Identifier for the exchange. |
| contractID | Identifier for the contract. |
| marketID | Identifier for the market. |
| requestStatusMessage| Any status messages or errors related to the request. |
| tradeDateStart | The starting date of the trade data. |
| tradeDateEnd | The ending date of the trade data. |
| trades | An array of trade objects, each detailing individual trades. |
| marketDefinitions | An array of market definition objects, detailing market-specific information. |
| modeChanges | An array of mode change objects, each showing changes in the market mode. |
| openInterests | An array containing information about open interests. |
| settlements | An array detailing settlement information, including prices. |
| vwaPs | An array detailing volume-weighted average prices (VWAP). |
=== Trades ===
^ Element ^ Description ^
| marketID | Identifier for the market. |
| tradeDate | The date of the trade as per trade date convention. |
| time | The specific time when the trade occurred. |
| tradePrice | The price at which the trade was executed. |
| aggressorSide | Indicates the side of the aggressor of the trade. 1 for buyer, -1 for seller. |
=== VWAP(s) ===
^ Element ^ Description ^
| marketID | Identifier for the market. |
| tradeDate | The date of the trade as per trade date convention. |
| time | The specific time when the VWAP is calculated. |
| vwapPrice | The volume-weighted average price for the trades up to the specified time. |
==== Example JSON Response ====
{
"exchangeID": "CME_E",
"contractID": "YM",
"marketID": "XCME_E YM (H24)",
"requestStatusMessage": "",
"tradeDateStart": "2024-01-08T00:00:00",
"tradeDateEnd": "2024-01-08T00:00:00",
"trades": [
{
"marketID": "XCME_E YM (H24)",
"tradeDate": "2024-01-08T00:00:00",
"time": "2024-01-07T17:00:00",
"tradePrice": "37674",
"aggressorSide": 1
},
...
],
"marketDefinitions": [],
"modeChanges": [
...
],
"openInterests": [
...
],
"settlements": [
...
],
"vwaPs": [
...
]
}
The response is structured as a JSON object with various elements containing detailed trade data and related information for the specified contract and exchange within the requested time frame.
===== Decoder Libraries =====
Open-source reference decoders are maintained alongside this API so you do not have to implement the binary format by hand. The libraries are line-for-line ports of the original Java ``com.t4login`` chart-data reader and are validated against each other and against the CSV/JSON output.
All of the tools below live in the public **CTS-Futures/t4-api-tools** repository:
[[https://github.com/CTS-Futures/t4-api-tools/tree/main/tools|https://github.com/CTS-Futures/t4-api-tools/tree/main/tools]]
^ Language ^ Package / module ^ Location in the repo ^
| JavaScript | ``@t4/chart-decoder`` (ES modules) | ``tools/JavaScript/t4-javascript-api/`` (and a browser copy under ``tools/JavaScript/JSDemo/decoder/``) |
| Python | ``t4login`` | ``tools/Python/t4-pythonConversion-api/src/t4login/`` |
| .NET (C#) | ``T4APIDemo`` (NuGet) | ``tools/dotNet/T4APIDemo/`` |
==== JavaScript: @t4/chart-decoder ====
Requires **Node 18+** (uses global ``fetch``) or any modern browser. The only runtime dependency is **decimal.js**.
=== Install ===
Clone the [[https://github.com/CTS-Futures/t4-api-tools/tree/main/tools|t4-api-tools]] repository, then install dependencies:
git clone https://github.com/CTS-Futures/t4-api-tools.git
cd t4-api-tools/tools/JavaScript/t4-javascript-api
npm install
=== Aggregated barchart (push / handler model) ===
``ChartDataStreamReaderAggr`` decodes the whole stream and dispatches each record to a handler. Any subset of callbacks may be supplied; missing callbacks are skipped.
import { ChartClient } from '@t4/chart-decoder';
const client = new ChartClient({ token: 'YOUR_ACCESS_TOKEN' });
await client.getBarchartBinary({
exchangeId: 'CME_Eq',
contractId: 'ESM6',
barInterval: 'Minute',
barPeriod: 1,
tradeDateStart: '2026-05-01',
tradeDateEnd: '2026-05-02',
handler: {
onMarketDefinition(def) { /* def.MarketID, def.TickValue, ... */ },
onBar(bar) { console.log(bar.Time.toString(), bar.ClosePrice.toString()); },
onModeChange(marketId, tradeDate, time, mode) { /* ... */ },
onSettlement(marketId, tradeDate, time, price, held) { /* ... */ },
onOpenInterest(marketId, tradeDate, time, oi) { /* ... */ },
},
});
The handler interface:
^ Callback ^ Emitted for tag(s) ^
| ``onMarketDefinition(marketDefinition)`` | ``CTAG_MARKET_DEFINITION`` |
| ``onBar(bar)`` | ``CTAG_BAR``, ``CTAG_BAR_DELTA`` |
| ``onModeChange(marketId, tradeDate, time, mode)`` | ``CTAG_MARKET_MODE`` |
| ``onSettlement(marketId, tradeDate, time, settlementPrice, held)`` | ``CTAG_SETTLEMENT_PRICE`` |
| ``onOpenInterest(marketId, tradeDate, time, openInterest)`` | ``CTAG_OPEN_INTEREST`` |
=== Non-aggregated trade history (pull / state model) ===
``ChartDataStreamReader`` is a sequential cursor. Each ``read()`` consumes one record and mutates the public ``reader.state`` object; ``read()`` returns ``false`` at end-of-stream. Branch on ``state.Change``:
import { ChartClient, ChartDataChange } from '@t4/chart-decoder';
const reader = await client.getTradehistoryBinary({
exchangeId: 'CME_E',
contractId: 'YM',
tradeDateStart: '2024-01-08',
tradeDateEnd: '2024-01-08',
});
while (reader.read()) {
const s = reader.state;
switch (s.Change) {
case ChartDataChange.Trade:
console.log(s.LastTimeTicks, s.LastTradePrice.toString(), s.TradeVolume, s.AtBidOrOffer);
break;
case ChartDataChange.Quote:
console.log('BBO', s.BidPrice.toString(), s.OfferPrice.toString());
break;
case ChartDataChange.Settlement:
console.log('settle', s.SettlementPrice?.toString());
break;
// ... MarketMode, OpenInterest, VWAP, TPO, TradeBar, TickChange, RFQ ...
}
}
=== Lower-level / advanced usage ===
You can also decode bytes you already have (e.g. from a saved file) without the HTTP client:
import {
ByteReader, NDateTime, ChartDataType,
ChartDataStreamReader, ChartDataStreamReaderAggr,
extractT4BinPayload,
} from '@t4/chart-decoder';
// Aggregated:
ChartDataStreamReaderAggr.read(extractT4BinPayload(bytes), handler);
// Non-aggregated:
const reader = new ChartDataStreamReader({
data: new ByteReader(extractT4BinPayload(bytes)),
tradeDate: new NDateTime(0n),
marketId: 'XCME_E YM (H24)',
dataType: ChartDataType.get(0), // Tick
});
=== Browser (no bundler) ===
The JSDemo copy ships a ``decoder/loader.js`` ES-module entry point that publishes the decoder on ``window.T4ChartDecoder`` and fires a ``t4-decoder-ready`` event, so classic ``
==== Python: t4login ====
The Python package mirrors the JavaScript API one-to-one (same class names, same field names). It is the original conversion the JavaScript port was derived from.
=== Install ===
Clone the [[https://github.com/CTS-Futures/t4-api-tools/tree/main/tools|t4-api-tools]] repository, then install dependencies:
git clone https://github.com/CTS-Futures/t4-api-tools.git
cd t4-api-tools/tools/Python/t4-pythonConversion-api
pip install -e . # installs from pyproject.toml
=== Usage ===
from t4login.client.chart_client import ChartClient
from t4login.definitions.chartdata.chart_data_change import ChartDataChange
client = ChartClient(token="YOUR_ACCESS_TOKEN")
# Aggregated (handler model)
client.get_barchart_binary(
exchange_id="CME_Eq", contract_id="ESM6",
trade_date_start="2026-05-01", trade_date_end="2026-05-02",
handler=my_handler,
)
# Non-aggregated (state model)
reader = client.get_tradehistory_binary(
exchange_id="CME_E", contract_id="YM",
trade_date_start="2024-01-08", trade_date_end="2024-01-08",
)
while reader.read():
s = reader.state
if s.Change == ChartDataChange.Trade:
print(s.LastTradePrice, s.TradeVolume)
==== .NET: T4APIDemo ====
The .NET reference decoder ships as the ``T4APIDemo`` NuGet package in the same repository, under ``tools/dotNet/T4APIDemo/``. It mirrors the JavaScript and Python decoders (same class, handler and ``ChartDataState`` field names) for 1:1 parity across all implementations.
=== Install ===
Clone the [[https://github.com/CTS-Futures/t4-api-tools/tree/main/tools|t4-api-tools]] repository, then restore and build the project:
git clone https://github.com/CTS-Futures/t4-api-tools.git
cd t4-api-tools/tools/dotNet/T4APIDemo
dotnet restore
dotnet build
==== ChartDataState field reference (T4Bin) ====
Populated by ``ChartDataStreamReader``. Field names are PascalCase for parity across Java/Python/JS. Prices are ``Price`` objects (call ``.toString()`` / Python ``str()``); 64-bit tick times are ``BigInt`` in JS.
^ Group ^ Fields ^
| Change | ``Change`` (a **[[#ChartDataChange]]** value) |
| Trade date | ``TradeDate``, ``TradeDateTicks`` |
| Market def. | ``MarketDefined``, ``MarketID``, ``Numerator``, ``Denominator``, ``PriceCode``, ``TickValue``, ``VPT``, ``MinCabPrice``, ``MinPriceIncrement``, ``PointValue`` |
| Last trade | ``LastTradePrice``, ``TradeVolume``, ``LastTTV``, ``LastTimeTicks``, ``AtBidOrOffer`` (**[[#BidOffer]]**), ``DueToSpread``, ``OrderVolumes`` |
| Bar | ``BarStartTime``, ``BarCloseTime``, ``BarOpenPrice``, ``BarHighPrice``, ``BarLowPrice``, ``BarClosePrice``, ``BarVolume``, ``BarBidVolume``, ``BarOfferVolume``, ``BarTrades``, ``BarTradesAtBid``, ``BarTradesAtOffer`` |
| TPO | ``TPOStartTime``, ``TPOBasePrice``, ``TPOPrice``, ``TPOVolume``, ``TPOVolumeAtBid``, ``TPOVolumeAtOffer``, ``TPOIsOpening``, ``TPOIsClosing`` |
| Quote | ``BidPrice``, ``BidRealVolume``, ``BidImpliedVolume``, ``OfferPrice``, ``OfferRealVolume``, ``OfferImpliedVolume`` |
| Session | ``Mode`` (**[[#MarketMode]]**), ``SettlementPrice``, ``SettlementHeldPrice``, ``ClearedVolume``, ``OpenInterest``, ``VWAP_Price`` |
| RFQ | ``RFQBuySell`` (**[[#BidOffer]]**), ``RFQVolume`` |
==== Enumerations ====
=== ChartDataChange ===
The ``state.Change`` discriminator after each ``read()``.
^ Value ^ Name ^ ^ Value ^ Name ^
| 0 | ``NONE`` | | 8 | ``TickChange`` |
| 1 | ``Trade`` | | 9 | ``RFQ`` |
| 2 | ``Quote`` | | 10 | ``HeldSettlement``|
| 3 | ``MarketMode`` | | 11 | ``ClearedVolume`` |
| 4 | ``Settlement`` | | 12 | ``OpenInterest`` |
| 5 | ``TradeBar`` | | 13 | ``VWAP`` |
| 6 | ``TradeDate`` | | 14 | ``MarketSwitch`` |
| 7 | ``TPO`` | | 15 | ``MarketDefinition`` |
=== MarketMode ===
Exchange session lifecycle state (the ``marketMode`` field in JSON, and ``state.Mode`` / ``onModeChange`` in binary).
^ Value ^ Name ^ ^ Value ^ Name ^
| 0 | ``Undefined`` | | 8 | ``Failed`` |
| 1 | ``PreOpen`` | | 9 | ``PreCross`` |
| 2 | ``Open`` | | 10 | ``Cross`` |
| 3 | ``RestrictedOpen`` | | 11 | ``Expired`` |
| 4 | ``PreClosed`` | | 12 | ``Rejected`` |
| 5 | ``Closed`` | | 13 | ``Unavailable`` |
| 6 | ``Suspended`` | | 14 | ``NoPermission`` |
| 7 | ``Halted`` | | 15 | ``TrialExpired`` |
=== BidOffer ===
Which side of the market a trade/RFQ executed against (mirrors the JSON ``aggressorSide``).
^ Value ^ Name ^
| 1 | ``Bid`` |
| 0 | ``Undefined`` |
| -1 | ``Offer`` |
===== Revision Notes / Changelog =====
^ Area ^ Change ^
| New section | **Decoder Libraries** — JavaScript (``@t4/chart-decoder``), Python (``t4login``) and .NET (``T4APIDemo``) usage, the aggregated handler interface, the non-aggregated state-cursor model, browser loader, the ``ChartDataState`` field reference, and the ``ChartDataChange`` / ``MarketMode`` / ``BidOffer`` enumerations. |
**Source of truth:** the field and enumeration tables above are generated from the decoder source under
``tools/JavaScript/t4-javascript-api/src`` (mirror under ``tools/JavaScript/JSDemo/decoder``),
``tools/Python/t4-pythonConversion-api/src/t4login`` and ``tools/dotNet/T4APIDemo``.
The response is structured as a JSON object with various elements containing detailed trade data and related information for the specified contract and exchange within the requested time frame.