Skip to main content

OHLC Bars

This document describes the output message format of a component in the Deltix CryptoCortex software that can generate Bar messages out of Level2 market data. These bars come in different resolutions (1 minute, 10 minutes, 1 hour, 1 day, etc.) to support various use cases where approximate prices are needed (e.g., charts that display how the instrument price changed during each month).

Data Format

Basic Sample

A bar is a type of OHLC (Open;High;Low;Close) message that describes price statistics for a specified time period using the best order book ASK and BID values. Below is an example of this message:

{
symbol: '47C5F80A259B474EB74EB32C4EECB410',
exchangeCode: 'BITFINEX',
timestamp: '2021-04-15T15:04:28.000Z',
openTimestamp: '2021-04-15T15:04:27.175Z',
closeTimestamp: '2021-04-15T15:04:27.987Z',
barType: 'ONE_SECOND',
openAsk: '0.039243',
openBid: '0.039224',
highAsk: '0.039243',
highBid: '0.039224',
highMid: '0.0392335',
lowAsk: '0.039242',
lowBid: '0.039223',
lowMid: '0.0392325',
closeAsk: '0.039242',
closeBid: '0.039223',
volume: '1.1'
}

As you can see, each message has an open and close timestamp that defines the time range, symbol, and exchange that identify the instrument, as well as a set of price metrics that are described in detail in the next section.

Field Descriptions

The bar in CryptoCortex is represented by the class WCTBarMessage and has the following fields that define its attributes:

FieldDescription
isShadowDeprecated field. Previously used as indicator of data availability in the order book for the exchange of this bar in the time frame of this bar.
barType  Bar duration type. Can take next values:
  • ONE_SECOND – describe time periods that start and end in seconds, like from 'YYYY-MM-DDTHH:MM:01.000Z' to 'YYYY-MM-DDTHH:MM:02.000Z'.
  • ONE_MINUTE – describe time periods that start and end in minutes, like from 'YYYY-MM-DDTHH:31:00.000Z' to 'YYYY-MM-DDTHH:32:00.000Z'.
  • FIVE_MINUTES – describe time periods that start and end in minutes multiple of 5, like from 'YYYY-MM-DDTHH:05:00.000Z' to 'YYYY-MM-DDTHH:10:00.000Z'.
  • FIFTEEN_MINUTES – describe time periods that start and end in minutes multiple of 15, like from 'YYYY-MM-DDTHH:30:00.000Z' to 'YYYY-MM-DDTHH:45:00.000Z'.
  • THIRTY MINUTES  – describe time periods that start and end in minutes multiple of 30, like from 'YYYY-MM-DDTHH:00:00.000Z' to 'YYYY-MM-DDTHH:30:00.000Z'.
  • ONE_HOUR – describe time periods that start and end in hours, like from 'YYYY-MM-DDT01:00:00.000Z' to 'YYYY-MM-DDT02:00:00.000Z'.
  • FOUR_HOURS – describe time periods that start and end in hours multiple of 4, like from 'YYYY-MM-DDT04:00:00.000Z' to 'YYYY-MM-DDT08:00:00.000Z'.
  • EIGHT_HOURS – describe time periods that start and end in hours multiple of 8, like from 'YYYY-MM-DDT08:00:00.000Z' to 'YYYY-MM-DDT:00:00.000Z'.
  • DAY – describe time periods that start and end in days, like from 'YYYY-MM-01T00:00:00.000Z' to 'YYYY-MM-02T:00:00.000Z'
  • WEEK – describe time periods which started that start and end on Thursday, because the Unix epoch is 00:00:00 UTC on 1 January 1970(Thursday).
  • MONTH – describe time periods that start and end in months, like from 'YYYY-01-00T00:00:00.000Z' to 'YYYY-02-00T:00:00.000Z'
exchangeCodeThis bar contains information about market data from this exchange code
timestampBar start time. Always a multiple of the bar duration. You can see barType field description to clarify how time period for a bar is calculated.
openTimestampTimestamp of the first quote (first incremental update or snapshot) in bar time period coming from bar exchange.
closeTimestampTimestamp of the last quote (last incremental update or snapshot) in bar time period coming from the bar exchange.
symbolThe symbol (instrument name) for which this bar is built. Standard component uses GUID to identify instruments inside CryptoCortex part of the system.
openAskBest ASK price when the first update is coming to this bar for the bar exchange, or last best ASK price for the bar exchange if there were no updates.
closeAskBest ASK price when the last update is coming to this bar for the bar exchange, or last best ASK price for the bar exchange if there were no updates.
lowAskThe minimum value of all best ASK prices in this bar time period for the bar exchange.
highAskThe maximum value of all best ASK prices in this bar time period for the bar exchange.
openBidBest BID price when the first update is coming to this bar for the bar exchange, or last best BID price for the bar exchange if there were no updates.
closeBidBest BID price when the last update is coming to this bar for the bar exchange, or last best BID price for the bar exchange if there were no updates.
lowBidThe minimum value of all best BID prices in this bar time period for the bar exchange.
highBidThe maximum value of all best BID prices in this bar time period for the bar exchange.
lowMidThe lowest mid-price value which calculated like  minimum of all (currentAsk(t) + currentBid(t)) / 2 values, where t is any time point in the bar time period, currentAsk is the best ASK value at this time point and currentBid is the best BID value at this time point for the bar exchange.
highMidThe highest mid-price value which calculated like  minimum of all (currentAsk(t) + currentBid(t)) / 2 values, where t is any time point in the bar time period, currentAsk is the best ASK value at this time point and currentBid is the best BID value at this time point for the bar exchange.
volumeTotal trade volume happened on bar exchange in this bar time period.
closeAskQuoteIdUnique identifier of best ASK quote when the last update is coming to this bar. Represents like byte array of size 32, each byte can have value from 0 to 255.
closeBidQuoteIdUnique identifier of best BID quote when the last update is coming to this bar. Represents like byte array of size 32, each byte can have value from 0 to 255.
currencyCodeDeprecated field. Value is always 999 (unknown based on ISO 4217)

Complete Sample

{
'$type': 'deltix.wct.marketdata.historical.WCTBarMessage',
symbol: '47C5F80A259B474EB74EB32C4EECB410',
timestamp: '2021-04-15T15:04:28.000Z',
currencyCode: 999,
barType: 'ONE_SECOND',
closeAsk: '0.039242',
closeBid: '0.039223',
closeTimestamp: '2021-04-15T15:04:27.987Z',
exchangeCode: 'BITFINEX',
highAsk: '0.039243',
highBid: '0.039224',
highMid: '0.0392335',
isShadow: false,
lowAsk: '0.039242',
lowBid: '0.039223',
lowMid: '0.0392325',
openAsk: '0.039243',
openBid: '0.039224',
openTimestamp: '2021-04-15T15:04:27.175Z',
volume: '1.1'
}

Appendix A: Docker container usage example

Deltix provides special BarGenerator container service that can be used to generate bars from market data streams in Universal Market Data format.

  • BarGenerator works by building bars based on all timebase stream's that contain PackageHeader messages. The set of these streams can be either specified explicitly, or inferred by tool (option autoSubscription = true).  When using the latter option, tool selects all polymorphic streams (apart from explicitly excluded) that contain PackageHeader in descriptor.  
  • Bars resolutions are limited to 1/5/30 seconds, 1/5/15/30 minutes, 1/4/8/24 hours, 7 days or 1 Gregorian calendar month. 
  • Bars are build iteratively from lower resolution to higher. 
  • Built bars are written into user specified streams. Tool will write "flat" bars in case of missing live data.
  • There are other specific settings for bars verbosity, output symbols mapping, time range of bars creation.

The following docker-compose snippet shows how an example of the container usage:

services:
bargenerator:
image: "registry.deltixhub.com/deltix.docker/crypto-cortex/messages-convert-tool:2.2.18"
command: ["--fromCommandLine=true", "--live=true", "--timeBaseUrl=dxtick://localhost:8011", "--input-streams-names=BINANCE;COINBASE;BITMEX", "--output-streams-names=1MIN;5MIN", "--steps=60000;300000"]
restart: unless-stopped
deploy:
resources:
limits:
cpus: '0.5'
memory: 1050M
network_mode: host

Command line parameters:

  • --timebaseUrl - Points to TimeBase server (usually dxtick://timebase:8011 when this container runs on the same docker compose as TimeBase server, could also be dxtick://localhost:8011 when running in host networking mode).
  • --input-streams-names - List of input market data streams for which bars will be generated, separated by semicolons (;).
  • --steps - This parameter lists desired bar periodicity, in milliseconds, also separated by semicolons (;). For example, value 60000 will instruct this service to generate 60 seconds (1 minute) bars.
  • --output-streams-names - This parameter defines names of TimeBase streams to record bars of each periodicity. Names are separated by semicolons (;). Number of streams should match number of different values defined for --steps parameter.
  • --live - This flag indicate whether input streams should be read in live (real time) mode. Default value is false, which means, that the tool will not read data in live mode.
  • --start-time - Optional parameter. Start time for reading market data in a format like YYYY-MM-DDTHH:mm:ss.sssZ. If this parameter is unspecified, or it's value is less than bars last timestamp from output streams, then tool will process input market data from the bars last timestamp from output streams.
  • --finish-time - Optional parameter. Finish time for reading market data in a format like YYYY-MM-DDTHH:mm:ss.sssZ. If this parameter is unspecified, then tool will not stop reading historical market data until it runs out. This parameter works only if --live parameter is false.
  • --autoSubscription - Optional flag that indicates whether tool should add auto-discover streams with PackageHeader message classes on-fly. Default value is false, which mean that tool shouldn't do it.
  • --excluded-streams-names - Optional parameter that may specify list of TimeBase streams which tool shouldn't add on-fly, if --autoSubscription parameter is true. Once again semicolon is used as separator.
  • --recordTradingInformation - Optional parameter that enables or disables additional fields related to trade information like openTrade, highTrade, lowTrade, closeTrade.

Appendix B: Bars using TimeBase QQL

WITH
(orderbook{maxDepth:1}(packageType, entries) as array(L2EntryNew)) as book,
book[side == ASK and level == 0][0] as ask,
book[side == BID and level == 0][0] as bid,
(ask.price + bid.price) / 2 as midPrice
SELECT
first{}(ask.price) AS 'openAsk',
last{}(ask.price) AS 'closeAsk',
max{}(ask.price) AS 'highAsk',
min{}(ask.price) AS 'lowAsk',
first{}(bid.price) AS 'openBid',
last{}(bid.price) AS 'closeBid',
max{}(bid.price) AS 'highBid',
min{}(bid.price) AS 'lowBid',
max{}(midPrice) AS 'highMid',
min{}(midPrice) AS 'lowLow',
first{}(timestamp) AS 'openTimestamp',
last{}(timestamp) AS 'closeTimestamp',
sum{}(ask.size + bid.size) AS 'volume',
ask.exchangeId AS 'exchangeCode'
TYPE "deltix.wct.marketdata.historical.WCTBarMessage"
FROM "KRAKEN"
over time(1m)
WHERE book != null
GROUP BY symbol