createOrderBookSnapshotEngine

Syntax

createOrderBookSnapshotEngine(name, exchange, orderbookDepth, intervalInMilli, date, startTime, prevClose, dummyTable, outputTable, inputColMap, [outputColMap], [outputCodeMap], [snapshotDir], [snapshotIntervalInMsgCount], [raftGroup], [outputIntervalOffsetMap], [checkRestrict], [maxPrice], [minPrice], [userDefinedMetrics], [priceNullFill], [triggerType], [forceTriggerTime], [precision], [orderBySeq], [skipCrossedMarket=true], [orderBookDetailDepth=0], [orderBookAsArray=false],[useSystemTime=false],[independentForceTriggerTime],[includeImmediateExecution=false], [securitySubType='ConvertibleBond'], [priceScale=10000], [endTime])

Note:

This order book engine is not currently supported under the Community Edition license. If you need this feature, contact technical support.

Details

Creates an order book engine. This engine generates order book snapshots in real time at a specified frequency, such as 1 second, 100 ms, or 30 ms, based on tick-by-tick order and trade data.

The output includes:

  • Full-depth order book information
  • Window-based statistics
  • Cumulative statistics for the full trading day

This engine supports both real-time data streaming and historical tick-by-tick replay.

If the engine produces no output or very little output after you feed in data, see section 7.5 of the order book engine tutorial to troubleshoot the issue.

Supported Instrument Types

The engine currently supports building an order book for Shenzhen Stock Exchange (SZSE) stocks, SZSE bonds, and SZSE funds, as well as Shanghai Stock Exchange (SSE) stocks, SSE bonds, and SSE funds.

Note:

Bond order matching follows the new rules issued after August 2022.

Windowing Rules

If you do not specify outputIntervalOffsetMap, the windowing rules are as follows:

The intervalInMilli parameter specifies the window length in time, and the timestamp in the output table indicates the right boundary of the window. The last window is open on both ends, while all other windows are left-open and right-closed.

The upper bound of the last window's right boundary is as follows:

  • If endTime is specified, the upper bound of the last window's right boundary is endTime.
  • If endTime is not specified:
    • When exchange = “XSHGBOND”, the upper bound of the last window's right boundary is 15:00:00.000.
    • For any other value of exchange, the upper bound of the last window's right boundary is 14:57:00.000.

If you specify outputIntervalOffsetMap, the window length and boundaries are adjusted based on the offset configured in outputIntervalOffsetMap.

  • First window: The interval is [startTime, startTime + intervalInMilli + offset].
  • Intermediate windows: Each interval runs from the right boundary of the previous window to the current right boundary, with a fixed length of intervalInMilli.
  • Last window: The length is intervalInMilli - offset.

For example: intervalInMilli = 500 ms and offset = 50 ms.

  • First window: 09:30:00.000 - 09:30:00.550 (length: 550 ms)
  • Second window: 09:30:00.550 - 09:30:01.050 (length: 500 ms)
  • ...
  • Last window (assuming endTime is 14:57:00): 14:56:59.550 - 14:57:00.000 (length: 450 ms)

Trigger Rules

The first output is triggered by the first input record whose timestamp is greater than startTime + intervalInMilli. In this case, the timestamp in the output record is startTime + intervalInMilli. Then, when a new tick arrives with a timestamp beyond the current window's right boundary, the engine outputs a snapshot for either a single instrument or all instruments, depending on the value of triggerType.

Note:
  • An engine can accept data for at most one trading day and one channel, covering all instruments.
  • You must ensure that the tick-by-tick data inserted into the engine is sorted by its sequence number recorded by the exchange.

Parameters

Note:

You must specify parameter names when passing arguments.

name: A STRING scalar that specifies the name of the order book engine. It can contain letters, digits, and underscores (_), but must start with a letter.

exchange: A STRING scalar that specifies the exchange and instrument type. Valid values:

  • "XSHE" or "XSHESTOCK": SZSE stocks
  • "XSHEBOND": SZSE bonds
  • "XSHEFUND": SZSE funds
  • "XSHG" or "XSHGSTOCK": SSE stocks
  • "XSHGBOND": SSE bonds
  • "XSHGFUND": SSE funds

orderbookDepth: A positive integer that specifies the maximum number of bid and ask levels displayed in the order book.

intervalInMilli: A positive integer that specifies the interval (in milliseconds) at which a snapshot is generated and output.

date: A DATE scalar that specifies the trading date. This parameter, together with the window's right boundary, forms the TIMESTAMP column in the output table.

startTime: A TIME scalar that specifies the start time for triggering output. The engine outputs only data after the aligned time specified by this parameter.

prevClose: A dictionary whose keys are STRING scalars or vectors that specify instrument symbols, and whose values are numeric values that specify the previous trading day's closing price for each instrument symbol. Note: If the value is a floating-point number, the engine treats it as the actual price and multiplies it by priceScale during processing to match the precision of priceColumn in the input table. If it is an integer, the engine assumes it already has the same precision as priceColumn and does not scale it further.

dummyTable: A table object whose schema matches that of the input stream table. It can contain data or be empty.

outputTable: A table object. If you specify userDefinedMetrics, the system defines the schema of the output table based on basic and depth specified by the genOutputColumnsForOBSnapshotEngine function, as well as the user-defined metrics. Otherwise, the system defines the table schema based on the outputColMap setting.

Note:

If you need to output tradeBuyOrderTypeList and tradeSellOrderTypeList in tradeDetail, add them to outputColMap.

inputColMap: A dictionary that maps column names in the input table to the columns required by the engine for computation. Where:

  • Each key is a string that identifies a fixed input column required by the engine. See the table below for the column names and their descriptions. Note that these keys are case-sensitive. You must specify all of them, but you can provide them in any order.
  • Each value is a string that specifies a column name in the input table.
Key Data Type of Column Specified by Value Description
"codeColumn" SYMBOL Instrument symbol (for example, 300010.SZ)
"timeColumn" TIME Trade time
"typeColumn" INT Trade type:
  • For tick-by-tick orders:
    • 1 indicates a market order
    • 2 indicates a limit order
    • 3 indicates a same-side best order
    • 10 indicates an order cancellation (SSE only)
    • 11 indicates market status (SSE only)
  • For tick-by-tick trades:
    • 0 indicates a trade
    • 1 indicates a cancellation (SZSE only)
"priceColumn" LONG Price. The scale is determined by priceScale; by default, it is the actual price × 10000.
"qtyColumn" LONG Number of shares
"buyOrderColumn" LONG
  • Tick-by-tick trade: the buy order sequence number in the original trade record.
  • Tick-by-tick order:
    • SSE: Populate this field with the original order sequence number from the original order data, which is the unique identifier (OrderNo) used by the exchange to identify an order when adding and canceling orders.
    • SZSE: Populate this field with 0. In the SZSE data, this field is a redundant column added to align with the SSE data format.
"sellOrderColumn" LONG
  • Tick-by-tick trade: the sell order sequence number from the original trade data.
  • Tick-by-tick order:
    • SSE: Populate this field with the original order sequence number from the original order data, which is the unique identifier (OrderNo) used by the exchange to identify an order when adding and canceling orders.
    • SZSE: Populate this field with 0. In the SZSE data, this field is a redundant column added to align with the SSE data format.
"sideColumn" INT Buy/sell:
  • 1 indicates a buy order
  • 2 indicates a sell order
Note:
  • For order submission, BSFlag is required.
  • For order cancellation, BSFlag is determined by the original order and is required.
  • For order execution, BSFlag is optional.
"msgTypeColumn" INT Data type:
  • 0 indicates tick-by-tick orders
  • 1 indicates tick-by-tick trades
  • -1 indicates product status
"seqColumn" LONG The tick-by-tick data sequence number that starts from 1 and increments within each channel. For SZSE, use the appseqlnum field. If the index field is included, you can also use index. For SSE, use the bizIndex field.
"receiveTime" NANOTIMESTAMP The time when the tick-by-tick data was received.
Note:

The columns listed above are defined using predefined enum values. Input values must strictly follow the defined conventions to ensure correct results. For example, the column in the input table mapped to sideColumn must use 1 for buy and 2 for sell.

outputColMap (optional): A STRING vector that specifies the names of the columns to output. Column names are case-insensitive. For convenience, you can use the genOutputColumnsForOBSnapshotEngine function to generate the required output column names and assign the first element of the return value to outputColMap.

Note:

The column list generated by the genOutputColumnsForOBSnapshotEngine function does not include the following columns:

  • tradeBuyOrderTypeList and tradeSellOrderTypeList in tradeDetail.
  • withdrawBuyOrderNoList and withdrawSellOrderNoList in withdrawDetail.
  • ResidualBidOrderNoList and ResidualAskOrderNoList in residualDetail.

To output the preceding columns, add them to outputColMap.

outputCodeMap (optional): A STRING vector that specifies instrument symbols, for example: "000803.SZ". If you specify this parameter, the engine outputs data only for the specified instruments.

outputIntervalOffsetMap (optional): A vector or dictionary that specifies the time offset, in milliseconds, for triggering calculation of each instrument in the output table.

  • Calculation logic: The engine redefines the window boundaries for each instrument based on the offset. The first window automatically includes all tick-by-tick data from startTime to startTime + intervalInMilli + offset, ensuring that data generated during the offset period is included in the current snapshot calculation.
  • Vector: The engine automatically splits the input instruments evenly based on the size of the vector. For example, outputIntervalOffsetMap = [400, 500] means the engine automatically splits the input instruments into two equal groups. It outputs one group's data after intervalInMilli + 400 (ms), and the other group's data after intervalInMilli + 500 (ms).
  • Dictionary: Each key is a string that specifies an instrument symbol, and each value is an integer that specifies a time offset. For example, outputIntervalOffsetMap =dict(["127053.sz","123082.SZ"],[400, 500]) means the engine outputs data for 127053.sz after intervalInMilli + 400 (ms), and for 123082.SZ after intervalInMilli + 500 (ms).

checkRestrict (optional): A Boolean value. The default value is true, which enables the price band mechanism. If you set it to false, the mechanism is disabled, and instrument trading restrictions are removed; in that case, generated snapshots for ChiNext instruments may be inaccurate.

Note:

SZSE applies a price cage mechanism to ChiNext instruments whose symbol starts with 3. When checkRestrict=true, the engine determines whether to apply the price cage mechanism solely by checking whether the first character of the instrument symbol is 3. Therefore, when you feed ChiNext data into the engine, the instrument symbol must start with 3.

maxPrice (optional): A dictionary. Each key is a string that specifies the instrument symbol, and each value is of type DOUBLE or INT and specifies the limit up price. Note: If maxPrice is a floating-point number, the engine treats it as the actual price and multiplies it by priceScale during processing to match the precision of priceColumn in the input table. If it is an integer, the engine assumes it already has the same precision as priceColumn and does not scale it further.

minPrice (optional): A dictionary. Each key is a string that specifies the instrument symbol, and each value is of type DOUBLE or INT and specifies the limit down price. Note: If minPrice is a floating-point number, the engine treats it as the actual price and multiplies it by priceScale during processing to match the precision of priceColumn in the input table. If it is an integer, the engine assumes it already has the same precision as priceColumn and does not scale it further.

userDefinedMetrics (optional): An unary function.

  • The function takes a table as input. Each row specifies an instrument, and the columns contain the snapshot data for that instrument. If you specify outputColMap, the table contains the columns configured in outputColMap. Otherwise, it contains the basic columns plus bid/ask prices and quantities.
  • The function returns a tuple. Each element in the tuple is a vector containing the results of the corresponding metric calculated for each instrument.

priceNullFill: A numeric value. This parameter is used to fill missing price levels in the bid/ask ladders in the output table. For example, after an instrument reaches the limit up price, all ask prices may be NULL. If you want the ask price to be output as 0 in this case, set priceNullFill=0.

triggerType (optional): A STRING scalar that specifies the trigger mode. Valid values:

  • "mutual" (default): When the engine receives a new tick whose timestamp is greater than the right boundary of the current window, it triggers snapshot generation for all instruments whose snapshot has not yet been generated. The record that triggers the calculation is not included.
  • "independent": When the engine receives a new tick whose timestamp is greater than the right boundary of the window, it triggers snapshot generation only for the corresponding instrument whose snapshot has not yet been generated. The record that triggers the calculation is not included.
  • "perRow": When the engine receives any new tick, it triggers snapshot generation for the corresponding instrument and includes the triggering record in the calculation.

forceTriggerTime (optional): A non-negative integer, in milliseconds. In addition to normal snapshot generation triggers, some out-of-order data may fail to trigger snapshot generation and instead be cached in the engine. In this case, you can use this parameter to force the engine to generate snapshots from tick-by-tick data that has remained unprocessed for an extended period. Trigger rules:

  1. If the timestamp (t) of the most recently received tick-by-tick data minus the timestamp (t0) of the last processed trade record is greater than or equal to forceTriggerTime, the engine triggers snapshot generation for the unprocessed record with the smallest sequence number and updates the timestamp of the last processed trade record to t1.
  2. The engine repeats the preceding step. If t-t1 >= forceTriggerTime, it triggers snapshot generation for the unprocessed record with the smallest sequence number and updates the timestamp of the last processed trade record to t2. It continues until the difference between the two timestamps is less than forceTriggerTime, at which point snapshot generation stops.

precision (optional): An integer that specifies the number of decimal places. Valid range: [-1, 4].

  • When precision = -1, the engine outputs price-related columns as integers. Note: The corresponding columns in the output table can be of either integer or decimal values.
  • When precision is set to a value in [0, 4], it specifies the number of decimal places. All prices in the output table are rounded to the specified number of decimal places. Otherwise, the engine outputs the original results.

orderBySeq (optional): A tuple or Boolean value.

  • If you specify this parameter to a Boolean value, it indicates whether the engine processes data in ascending order of the values in the seqColumn column of the tick-by-tick data. When exchange = "XSHG" or "XSHGFUND", the default value is true. In all other cases, the default value is false.
    • When orderBySeq = true, the engine processes tick-by-tick data in sequence order and then calculates and outputs the results. For example, if the engine receives records with sequence numbers 1 and 3, it caches both because record 2 is missing. It does not calculate or output results until record 2 arrives. In this case, you can also specify forceTriggerTime to force the engine to calculate and output results.
    • When orderBySeq = false, the engine calculates and outputs results immediately each time it receives a record. In this case, you cannot set forceTriggerTime.
  • If you specify this parameter to a tuple, use the form (BOOL, INTEGER, [STRING]), where:
    • The first element is a Boolean value that specifies whether to output results in sequence order for tick-by-tick data. Its effect is the same as described above.
    • The second element is a positive integer that specifies the time interval, in milliseconds, at which the amount of cached input data is recorded.
    • The third element is an optional STRING scalar that specifies the output log level. Valid values are "DEBUG" (default) and "INFO", which correspond to Debug-level and Info-level log output, respectively.

skipCrossedMarket (optional): A Boolean value that specifies whether to output results when the best ask and best bid cross.

  • When skipCrossedMarket = true (default), if useSystemTime = false and the best ask and best bid cross, that is, the ask price <= the bid price, the engine does not output that result. If useSystemTime = true, the engine temporarily suppresses that snapshot when the best ask and best bid cross; if subsequently received data no longer shows a crossed market, the engine immediately outputs that snapshot.
  • When skipCrossedMarket = false, the engine still outputs the result even if the best ask and best bid cross.

orderBookDetailDepth (optional): An integer that specifies the depth of the order book. The default value is 0, which means no output. This parameter must match the value of the orderBookDetailDepth column in outputColMap.

orderBookAsArray (optional): A Boolean value that specifies whether to output bid/ask prices and quantities as array vectors. The default value is false, in which case prices and quantities are output in multiple columns.

Note:

If you specify userDefinedMetrics, orderBookAsArray determines how prices and quantities are output. Otherwise, outputColMap determines the output format of prices and quantities, and orderBookAsArray is ignored.

useSystemTime (optional): A Boolean value that specifies whether to use system time to trigger snapshot output.

  • When useSystemTime = true, during trading hours, the engine uses the current system time to trigger snapshot output at the interval specified by intervalInMilli. In this case, the engine does not output data during the midday break ((11:30:00.000, 13:00:00.000]), and the timestamp of the first afternoon output window is 13:00:00.000+intervalInMilli. Note: If useSystemTime = true, you cannot specify forceTriggerTime. You can leave triggerType unspecified or set triggerType = "mutual".
  • When useSystemTime = false (default), the engine triggers snapshot output based on event time.

independentForceTriggerTime (optional): A non-negative integer, in milliseconds, that specifies the interval for forcing snapshot output for groups that have not output a snapshot for an extended period. This parameter takes effect only when triggerType = "independent".

For example, assume that among the data processed so far, the timestamp of the most recent record is t. For each group, let ti denote the snapshot time that should have triggered an output based on the data processed for that group. If t - ti > independentForceTriggerTime, the engine triggers snapshot output for the corresponding group.

includeImmediateExecution (optional): A Boolean value that specifies whether immediate execution information is included in orderDetail statistics. The default value is false. This parameter takes effect only when generating SSE order books, and applies to stock and fund data (exchange set to "XSHG", "XSHGSTOCK", or "XSHGFUND").

Note:

If this parameter is set to true, inputColMap must ensure that OrderNo values in the input data are globally ordered. Also, ensure that any previously unrecorded orderNo in immediate execution records is greater than or equal to the latest recorded OrderNo.

securitySubType (optional): A case-insensitive STRING scalar that specifies the subtype of the instrument for which to generate the order book. It applies only when exchange is "XSHEBOND" or "XSHGBOND". Valid values:

  • "ConvertibleBond" (default): For "XSHEBOND", the order book includes only bonds with symbol prefixes "123", "127", or "128". For "XSHGBOND", the order book includes only bonds with symbol prefixes "110", "111", "113", or "118".
  • "All": Includes all bonds, with no symbol prefix restrictions.

priceScale (optional): A positive integer that specifies the scaling factor for the priceColumn column in the input table. The default value is 10000. When outputting results, the engine divides the calculated values by priceScale.

endTime (optional): A TIME scalar that specifies the upper bound of the last snapshot output window's right boundary. The engine outputs snapshot data for a window only if the window's right boundary timestamp is less than endTime.

You can set this parameter only when triggerType = "mutual". If you do not specify it, the default value of endTime is 15:00:00.000 when exchange = "XSHGBOND"; for all other values of exchange, the default value of endTime is 14:57:00.000.

To enable the snapshot mechanism, you must specify both snapshotDir and snapshotIntervalInMsgCount.

snapshotDir (optional): A STRING scalar that specifies the directory where engine snapshots are stored.

  • The specified directory must already exist; otherwise, the system raises an exception.
  • When you create a streaming engine with snapshotDir specified, the system checks whether snapshots exist in that directory. If a snapshot exists, the system loads it and restores the engine state.
  • The system distinguishes snapshot files by engine name to allow multiple engines to use the same directory.
  • An engine snapshot may use three filenames:
    • For temporary snapshot storage, the snapshot is named as .tmp.
    • After the snapshot is generated and flushed to disk, it is saved as .snapshot.
    • If a snapshot with the same name already exists, the older snapshot is automatically renamed to .old.

snapshotIntervalInMsgCount (optional): An integer that specifies how many records trigger one snapshot save for the streaming engine.

Returns

A table.

Examples

Before you run the code, download the file orderbookDemoInput.zip.

Example 1: This example shows how to build a high-frequency order book from historical tick-by-tick data. In this example, the engine is configured to compute and output a 10-level bid-ask order book for SZSE stocks every second. It demonstrates the complete data processing workflow, including data loading, engine creation, data insertion, and result verification.

// Log in to the DolphinDB server
login("admin", "123456")

// Release any existing engine
try { dropStreamEngine("demo") } catch(ex) { print(ex) }

// Create an output table, which will be passed to the outputTable parameter
suffix = string(1..10)
colNames = `SecurityID`timestamp`lastAppSeqNum`tradingPhaseCode`modified`turnover`volume`tradeNum`totalTurnover`totalVolume`totalTradeNum`lastPx`highPx`lowPx`ask`bid`askVol`bidVol`preClosePx`invalid  join ("bids" + suffix) join ("bidVolumes" + suffix) join ("bidOrderNums" + suffix) join ("asks" + suffix)  join ("askVolumes" + suffix) join ("askOrderNums" + suffix) 
colTypes = [SYMBOL,TIMESTAMP,LONG,INT,BOOL,DOUBLE,LONG,INT,DOUBLE,LONG,INT,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,LONG,LONG,DOUBLE,BOOL] join take(DOUBLE, 10) join take(LONG, 10) join take(INT, 10) join take(DOUBLE, 10) join take(LONG, 10) join take(INT, 10) 
share table(10000000:0, colNames, colTypes) as outTable

// Create a dummy table to define the schema of the input table, which will be passed to the dummyTable parameter
colNames = `SecurityID`Date`Time`SecurityIDSource`SecurityType`Index`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo
colTypes = [SYMBOL, DATE, TIME, SYMBOL, SYMBOL, LONG, INT, INT, LONG, LONG, INT, LONG, LONG, LONG, INT]
dummyOrderStream = table(1:0, colNames, colTypes)

// Create a dictionary to define the meaning of each column in the input table, which will be passed to the inputColMap parameter
inputColMap = dict(`codeColumn`timeColumn`typeColumn`priceColumn`qtyColumn`buyOrderColumn`sellOrderColumn`sideColumn`msgTypeColumn`seqColumn, `SecurityID`Time`Type`Price`Qty`BuyNo`SellNo`BSFlag`SourceType`ApplSeqNum)

// Create a dictionary to define the previous day's closing prices, which will be passed to the prevClose parameter. prevClose does not affect any output columns other than the previous day's closing prices.
prevClose = dict(`000587.SZ`002694.SZ`002822.SZ`000683.SZ`301063.SZ`300459.SZ`300057.SZ`300593.SZ`301035.SZ`300765.SZ, [1.66, 6.56, 6.10, 8.47, 38.10, 5.34, 9.14, 48.81, 60.04, 16.52])

// Create the engine to compute and output a 10-level bid-ask order book for SZSE stocks every second
engine = createOrderBookSnapshotEngine(name="demo", exchange="XSHE", orderbookDepth=10, intervalInMilli = 1000, date=2022.01.10, startTime=09:15:00.000, prevClose=prevClose, dummyTable=dummyOrderStream, outputTable=outTable, inputColMap=inputColMap)

filePath = "./orderbookDemoInput.csv"
colNames = `SecurityID`Date`Time`SecurityIDSource`SecurityType`Index`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo
colTypes = [SYMBOL, DATE, TIME, SYMBOL, SYMBOL, LONG, INT, INT, LONG, LONG, INT, LONG, LONG, LONG, INT]
orderTrade = table(1:0, colNames, colTypes)
orderTrade.append!(select * from loadText(filePath) order by Time)

// Batch-insert tick-by-tick data of 10 stocks into the order book engine
engine.append!(orderTrade)
select count(*) from outTable where SecurityID="300593.SZ", timestamp between 2022.01.10T13:15:01.000 and 2022.01.10T13:15:10.000

//output: 10

Example 2: This example demonstrates price control and output filtering. Key parameters are set as follows:

  • Use maxPrice and minPrice to set the limit up price and limit down price.
  • Set priceNullFill = 0 to fill missing prices with 0.
  • Use priceScale and precision to set the price scaling factor and the number of decimal places for output prices, respectively.
  • Set skipCrossedMarket = false to allow output of crossed bid-ask results.
try { dropStreamEngine("demo") } catch(ex) { print(ex) }  
  
filePath = "./orderbookDemoInput.csv"  
  
// Create a dummy table to define the schema of the input table, which will be passed to the dummyTable parameter
colNames = `SecurityID`Date`Time`SecurityIDSource`SecurityType`Index`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo  
colTypes = [SYMBOL, DATE, TIME, SYMBOL, SYMBOL, LONG, INT, INT, LONG, LONG, INT, LONG, LONG, LONG, INT]  
share table(1:0, colNames, colTypes) as dummyOrderStream  
  
// Create a dictionary to define the meaning of each column in the input table, which will be passed to the inputColMap parameter
inputColMap = dict(`codeColumn`timeColumn`typeColumn`priceColumn`qtyColumn`buyOrderColumn`sellOrderColumn`sideColumn`msgTypeColumn`seqColumn, `SecurityID`Time`Type`Price`Qty`BuyNo`SellNo`BSFlag`SourceType`ApplSeqNum)  
  
// Create a dictionary to define the previous day's closing prices, which will be passed to the prevClose parameter
prevClose = dict(`000587.SZ`002694.SZ`002822.SZ`000683.SZ`301063.SZ`300459.SZ`300057.SZ`300593.SZ`301035.SZ`300765.SZ, [1.66, 6.56, 6.10, 8.47, 38.10, 5.34, 9.14, 48.81, 60.04, 16.52])  
  
// Set the limit up price and limit down price (actual prices; the engine automatically multiplies them by priceScale)
maxPrice = dict(`000587.SZ`002694.SZ`002822.SZ, [1.83, 7.22, 6.71])  
minPrice = dict(`000587.SZ`002694.SZ`002822.SZ, [1.49, 5.90, 5.49])  
  
// Specify which stocks to output by symbol
outputCodeMap = `000587.SZ`002694.SZ`002822.SZ  
  
// Create the output table schema
outputColMap, outputTableSch = genOutputColumnsForOBSnapshotEngine(basic=true, time=false, depth=(10, true), tradeDetail=true, orderDetail=false, withdrawDetail=false, orderBookDetailDepth=0, prevDetail=false)  
  
// Create the engine and set price-related parameters and output filters
engine = createOrderBookSnapshotEngine(  
    name="demo",   
    exchange="XSHE",   
    orderbookDepth=10,   
    intervalInMilli = 1000,   
    date=2022.01.10,   
    startTime=09:15:00.000,   
    prevClose=prevClose,   
    dummyTable=dummyOrderStream,   
    outputTable=outputTableSch,   
    inputColMap=inputColMap,   
    outputColMap=outputColMap,  
    outputCodeMap=outputCodeMap,  // Output only the specified stocks
    maxPrice=maxPrice,          // Set the limit up price
    minPrice=minPrice,          // Set the limit down price
    priceNullFill=0,            // Fill missing prices with 0
    priceScale=10000,           // Price scaling factor
    precision=2,                // Keep 2 decimal places for prices
    skipCrossedMarket=false     // Allow output with crossed bid and ask prices
)  
  
// Insert data
engine.append!(select * from loadText(filePath) order by Time)  
select top 10 * from outputTableSch where code in outputCodeMap, timestamp between 2022.01.10T13:15:01.000 and 2022.01.10T13:15:10.000

Example 3: This example demonstrates the trigger mechanism and time control. Key parameters are set as follows:

  • Set triggerType = "independent" to enable independent trigger mode.
  • Set forceTriggerTime to specify the interval for forced triggers.
  • Set orderBySeq=true to ensure that data is processed in sequence order.
  • Set independentForceTriggerTime to specify the forced trigger time for groups in independent trigger mode.
try { dropStreamEngine("demo") } catch(ex) { print(ex) }  
  
filePath = "./orderbookDemoInput.csv"  
  
// Create a dummy table to define the schema of the input table, which will be passed to the dummyTable parameter
colNames = `SecurityID`Date`Time`SecurityIDSource`SecurityType`Index`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo  
colTypes = [SYMBOL, DATE, TIME, SYMBOL, SYMBOL, LONG, INT, INT, LONG, LONG, INT, LONG, LONG, LONG, INT]  
share table(1:0, colNames, colTypes) as dummyOrderStream  
  
// Create a dictionary to define the meaning of each column in the input table, which will be passed to the inputColMap parameter
inputColMap = dict(`codeColumn`timeColumn`typeColumn`priceColumn`qtyColumn`buyOrderColumn`sellOrderColumn`sideColumn`msgTypeColumn`seqColumn, `SecurityID`Time`Type`Price`Qty`BuyNo`SellNo`BSFlag`SourceType`ApplSeqNum)  
  
// Create a dictionary to define the previous day's closing prices, which will be passed to the prevClose parameter
prevClose = dict(`000587.SZ`002694.SZ`002822.SZ`000683.SZ`301063.SZ`300459.SZ`300057.SZ`300593.SZ`301035.SZ`300765.SZ, [1.66, 6.56, 6.10, 8.47, 38.10, 5.34, 9.14, 48.81, 60.04, 16.52])  
    
// Create the output table schema
outputColMap, outputTableSch = genOutputColumnsForOBSnapshotEngine(basic=true, time=false, depth=(10, true), tradeDetail=true, orderDetail=false, withdrawDetail=false, orderBookDetailDepth=0, prevDetail=false)  
  
// Create the engine and set the trigger mechanism and time control
engine = createOrderBookSnapshotEngine(  
    name="demo",   
    exchange="XSHE",   
    orderbookDepth=10,   
    intervalInMilli = 1000,   
    date=2022.01.10,   
    startTime=09:15:00.000,   
    prevClose=prevClose,   
    dummyTable=dummyOrderStream,   
    outputTable=outputTableSch,   
    inputColMap=inputColMap,   
    outputColMap=outputColMap,  
    triggerType="independent",                      // Independent trigger mode
    forceTriggerTime=5000,                          // Force a trigger after 5 seconds
 orderBySeq=true, // Process data in ID order
    independentForceTriggerTime=3000                // Forced trigger time for independent groups
)  

// Insert data
engine.append!(select * from loadText(filePath) order by Time)  
select top 10 * from outputTableSch where timestamp between 2022.01.10T13:15:01.000 and 2022.01.10T13:15:10.000

Example 4: This example uses outputIntervalOffsetMap to specify different time offsets for specific stocks. Because outputIntervalOffsetMap cannot be used with triggerType = "independent" or triggerType = "perRow", this example sets triggerType = "mutual" (default).

try { dropStreamEngine("demo") } catch(ex) { print(ex) }  
  
filePath = "./orderbookDemoInput.csv"  
  
// Create a dummy table to define the schema of the input table, which will be passed to the dummyTable parameter
colNames = `SecurityID`Date`Time`SecurityIDSource`SecurityType`Index`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo  
colTypes = [SYMBOL, DATE, TIME, SYMBOL, SYMBOL, LONG, INT, INT, LONG, LONG, INT, LONG, LONG, LONG, INT]  
share table(1:0, colNames, colTypes) as dummyOrderStream  
  
// Create a dictionary to define the meaning of each column in the input table, which will be passed to the inputColMap parameter
inputColMap = dict(`codeColumn`timeColumn`typeColumn`priceColumn`qtyColumn`buyOrderColumn`sellOrderColumn`sideColumn`msgTypeColumn`seqColumn, `SecurityID`Time`Type`Price`Qty`BuyNo`SellNo`BSFlag`SourceType`ApplSeqNum)  
  
// Create a dictionary to define the previous day's closing prices, which will be passed to the prevClose parameter
prevClose = dict(`000587.SZ`002694.SZ`002822.SZ`000683.SZ`301063.SZ`300459.SZ`300057.SZ`300593.SZ`301035.SZ`300765.SZ, [1.66, 6.56, 6.10, 8.47, 38.10, 5.34, 9.14, 48.81, 60.04, 16.52])  
  
// Set output time offsets as a dictionary to assign different output time offsets to different stocks
outputIntervalOffsetMap = dict(`000587.SZ`002694.SZ`002822.SZ, [100, 200, 300])  // Different stocks use offsets of 100 ms, 200 ms, and 300 ms
  
// Create the output table schema
outputColMap, outputTableSch = genOutputColumnsForOBSnapshotEngine(basic=true, time=false, depth=(10, true), tradeDetail=true, orderDetail=false, withdrawDetail=false, orderBookDetailDepth=0, prevDetail=false)  
  
// Create the engine and use the default triggerType="mutual" with outputIntervalOffsetMap
engine = createOrderBookSnapshotEngine(  
    name="demo",   
    exchange="XSHE",   
    orderbookDepth=10,   
    intervalInMilli = 1000,   
    date=2022.01.10,   
    startTime=09:15:00.000,   
    prevClose=prevClose,   
    dummyTable=dummyOrderStream,   
    outputTable=outputTableSch,   
    inputColMap=inputColMap,   
    outputColMap=outputColMap,  
    outputIntervalOffsetMap=outputIntervalOffsetMap  // Set time offsets
)  
  
// Insert data
engine.append!(select * from loadText(filePath) order by Time)  
  
// View differences in output timestamps for different stocks
select * from outputTableSch where code in `000587.SZ`002694.SZ`002822.SZ, timestamp between 2022.01.10T13:15:00.000 and 2022.01.10T13:15:02.000 order by code, timestamp

Some results are shown below:

Example 5: Use outputColMap to specify the columns to output. The first element returned by genOutputColumnsForOBSnapshotEngine is outputColMap, and the second element determines the schema of outputTable.

try { dropStreamEngine("demo") } catch(ex) { print(ex) }

filePath = "./orderbookDemoInput.csv"

// Create a dummy table to define the schema of the input table, which will be passed to the dummyTable parameter
colNames = `SecurityID`Date`Time`SecurityIDSource`SecurityType`Index`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo
colTypes = [SYMBOL, DATE, TIME, SYMBOL, SYMBOL, LONG, INT, INT, LONG, LONG, INT, LONG, LONG, LONG, INT]
share table(1:0, colNames, colTypes) as dummyOrderStream

// Create a dictionary to define the meaning of each column in the input table, which will be passed to the inputColMap parameter
inputColMap = dict(`codeColumn`timeColumn`typeColumn`priceColumn`qtyColumn`buyOrderColumn`sellOrderColumn`sideColumn`msgTypeColumn`seqColumn, `SecurityID`Time`Type`Price`Qty`BuyNo`SellNo`BSFlag`SourceType`ApplSeqNum)

// Create a dictionary to define the previous day's closing prices, which will be passed to the prevClose parameter. prevClose does not affect any output columns other than the previous day's closing prices.
prevClose = dict(`000587.SZ`002694.SZ`002822.SZ`000683.SZ`301063.SZ`300459.SZ`300057.SZ`300593.SZ`301035.SZ`300765.SZ, [1.66, 6.56, 6.10, 8.47, 38.10, 5.34, 9.14, 48.81, 60.04, 16.52])

//Create outputColMap and outputTableSch to receive the return values of genOutputColumnsForOBSnapshotEngine. They are used to define outputColMap and the schema of outputTable, respectively.
outputColMap, outputTableSch = genOutputColumnsForOBSnapshotEngine(basic=true, time=false, depth=(10, true), tradeDetail=true, orderDetail=false, withdrawDetail=false, orderBookDetailDepth=0, prevDetail=false)

engine = createOrderBookSnapshotEngine(name="demo", exchange="XSHE", orderbookDepth=10, intervalInMilli = 1000, date=2022.01.10, startTime=09:15:00.000, prevClose=prevClose, dummyTable=dummyOrderStream, outputTable=outputTableSch, inputColMap=inputColMap, outputColMap=outputColMap, orderBookAsArray=true)

// Batch-insert tick-by-tick data of 10 stocks into the order book engine
engine.append!(select * from loadText(filePath) order by Time)
select top 10 * from outputTableSch where code="300593.SZ", timestamp between 2022.01.10T13:15:01.000 and 2022.01.10T13:15:10.000

Some results are shown below:

You can use genOutputColumnsForOBSnapshotEngine to output only the columns you need. Suppose you need to output only some columns from tradeDetail in the example, such as excluding the last four columns. You can process the return values of genOutputColumnsForOBSnapshotEngine as follows:

outputColMap = outputColMap[0 : (size(outputColMap) - 4)]
outputTableSch = outputTableSch[, 0 : (outputTableSch.columns() - 4)]
engine = createOrderBookSnapshotEngine(name="demo", exchange="XSHE", orderbookDepth=10, intervalInMilli = 1000, date=2022.01.10, startTime=09:15:00.000, prevClose=prevClose, dummyTable=dummyOrderStream, outputTable=outputTableSch, inputColMap=inputColMap, outputColMap=outputColMap, orderBookAsArray=true)

Example 6: This example uses userDefinedMetrics to add user-defined metrics to the engine, enabling output of user-defined metrics in addition to standard order book data.

try { dropStreamEngine("demo") } catch(ex) { print(ex) }

filePath = "./orderbookDemoInput.csv"

// Create a dummy table to define the schema of the input table, which will be passed to the dummyTable parameter
colNames = `SecurityID`Date`Time`SecurityIDSource`SecurityType`Index`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo`ReceiveTime
colTypes = [SYMBOL, DATE, TIME, SYMBOL, SYMBOL, LONG, INT, INT, LONG, LONG, INT, LONG, LONG, LONG, INT, NANOTIMESTAMP]
share table(1:0, colNames, colTypes) as dummyOrderStream

// Create a dictionary to define the meaning of each column in the input table, which will be passed to the inputColMap parameter
inputColMap = dict(`codeColumn`timeColumn`typeColumn`priceColumn`qtyColumn`buyOrderColumn`sellOrderColumn`sideColumn`msgTypeColumn`seqColumn`receiveTime, `SecurityID`Time`Type`Price`Qty`BuyNo`SellNo`BSFlag`SourceType`ApplSeqNum`ReceiveTime)

// Create a dictionary to define the previous day's closing prices, which will be passed to the prevClose parameter. prevClose does not affect any output columns other than the previous day's closing prices.
prevClose = dict(`000587.SZ`002694.SZ`002822.SZ`000683.SZ`301063.SZ`300459.SZ`300057.SZ`300593.SZ`301035.SZ`300765.SZ, [1.66, 6.56, 6.10, 8.47, 38.10, 5.34, 9.14, 48.81, 60.04, 16.52])

//Define only outputColMap to receive the first return value of genOutputColumnsForOBSnapshotEngine. Because the metrics defined in userDefinedMetrics require order details and withdrawal details, you must call genOutputColumnsForOBSnapshotEngine with orderDetail=false and withdrawDetail=true
outputColMap = genOutputColumnsForOBSnapshotEngine(basic=true, time=false, depth=(10, true), tradeDetail=true, orderDetail=false, withdrawDetail=true, orderBookDetailDepth=0, prevDetail=false)[0]


//// Define user-defined metrics
def userDefinedFunc(t){
        AvgBuyDuration = rowAvg(t.TradeMDTimeList-t.TradeOrderBuyNoTimeList).int()
        AvgSellDuration = rowAvg(t.TradeMDTimeList-t.TradeOrderSellNoTimeList).int()        
        BuyWithdrawQty = rowSum(t.WithdrawBuyQtyList)
        SellWithdrawQty = rowSum(t.WithdrawSellQtyList)
        return (AvgBuyDuration, AvgSellDuration, BuyWithdrawQty, SellWithdrawQty)
}

// Define the output table for the order book engine. It must include the basic columns, multiple levels of bid/ask prices and quantities (depth), and the output of the user-defined metrics in userDefinedMetrics
outputTableSch = genOutputColumnsForOBSnapshotEngine(basic=true, time=false, depth=(10, true), tradeDetail=false, orderDetail=false, withdrawDetail=false, orderBookDetailDepth=0, prevDetail=false)[1]
colNames = outputTableSch.schema().colDefs.name join (`AvgBuyDuration`AvgSellDuration`BuyWithdrawQty`SellWithdrawQty)
colTypes = outputTableSch.schema().colDefs.typeString join (`INT`INT`INT`INT) 
outputTable = table(1:0, colNames, colTypes)

// Create the engine to generate a 10-level order book for SZSE stocks every second

engine = createOrderBookSnapshotEngine(name="demo", exchange="XSHE", orderbookDepth=10, intervalInMilli = 1000, date=2022.01.10, startTime=09:30:00.000, prevClose=prevClose, dummyTable=dummyOrderStream, outputTable=outputTable, inputColMap=inputColMap, outputColMap=outputColMap, orderBookAsArray=true, userDefinedMetrics=userDefinedFunc)

t = select * from loadText(filePath) order by Time
update t set ReceiveTime = now(true) // Set the ReceiveTime column

getStreamEngine("demo").append!(t)

select top 10 * from outputTable where code="300593.SZ", timestamp between 2022.01.10T13:15:01.000 and 2022.01.10T13:15:10.000

Some results are shown below:

Related function: genOutputColumnsForOBSnapshotEngine

Related tutorial: DolphinDB Order Book Engine: Build High-Frequency Order Books from Tick-by-Tick Data

Appendix

basic (basic columns)

If neither outputColMap nor userDefinedMetrics is spexified, the engine outputs all columns except openPrice, maxPrice, and minPrice.

Column Name Type Description
code SYMBOL Instrument symbol
timestamp TIMESTAMP Snapshot timestamp. For example, snapshots are generated at 1-second intervals: 2022.08.01T09:20:00.000, 2022.08.01T09:20:01.000
lastSeq LONG Sequence number of the last tick-by-tick record
tradingPhaseCode INT Trading phase code. Enum values:
  • 0 (pre-open, startup)
  • 1 (opening call auction)
  • 2 (after the opening call auction ends and before continuous auction begins)
  • 3 (continuous auction)
  • 4 (midday break)
  • 5 (closing call auction)
modified BOOL If no input data is available for the current period for a given instrument, this column is false in the corresponding output row; otherwise, it is true.
turnover DOUBLE Trading value for the current period
volume LONG Trading volume for the current period
tradeNum INT Number of trades in the current period
ttlTurnover DOUBLE Trading value from the open to the current time
ttlVolume LONG Trading volume from the open to the current time
ttlTradeNum INT Number of trades from the open to the current time
lastPrice DOUBLE Most recent trade price
highPrice DOUBLE Highest price since the open
lowPrice DOUBLE Lowest price since the open
openPrice DOUBLE Opening price
avgAskPrice DOUBLE Weighted average sell price = sum of price × quantity across all ask levels / total ask quantity
avgBidPrice DOUBLE Weighted average buy price = sum of price × quantity across all bid levels / total bid quantity
askQty LONG Current ask order volume
bidQty LONG Current bid order volume
preClosePrice DOUBLE/INT Previous closing priceDefine the previous closing prices and pass it to the engine as a dictionary.
abnormal BOOL Indicates whether the input data is invalid:
  • true indicates that the input data is invalid, or that the data is the first batch of order book data generated by forced trigger from discontinuous data after you set forceTriggerTime, as well as all subsequent data. Here, invalid data means the engine received tick-by-tick trades or cancellations but could not find the corresponding order.
  • false indicates that the input data is valid.
maxPrice DOUBLE/INT Limit up price. Define the limit up price and pass it to the engine as a dictionary.
minPrice DOUBLE/INT Limit down price. Define the limit down price and pass it to the engine as a dictionary.

time (time columns)

Column Name Type Description
mdTime TIME Snapshot timestamp. For example, snapshots are generated at 1-second intervals: 09:20:00.000, 09:20:01.000
mdDate DATE Snapshot date. Define the snapshot date and pass it to the engine through the date parameter.
UpdateTime1 NANOTIMESTAMP The receiveTime of the input record that triggers the window to close.
UpdateTime2 NANOTIMESTAMP The system time when computation completes after the window closes; that is, the system time when the result is output.

depth (bid/ask levels)

If neither outputColMap nor userDefinedMetrics is specified, the engine outputs all columns in depth. There are two ways to store depth data. You can use only one of them:

  • Output one column for each level. For example, if bidsPrice has 10 levels, the engine outputs 10 bidsPrice columns: bidsPrice1, bidsPrice2, …, bidsPrice10.
    Column Name Type Description
    bidsPrice DOUBLE Multiple columns, each storing a bid price at one level; the number of levels is determined by depth.
    bidsQty LONG Multiple columns, each storing the bid volume at one level; the number of levels is determined by depth.
    bidsCount INT Multiple columns, each storing the number of bid orders at one level; the number of levels is determined by depth.
    asksPrice DOUBLE Multiple columns, each storing an ask price at one level; the number of levels is determined by depth.
    asksQty LONG Multiple columns, each storing the ask volume at one level; the number of levels is determined by depth.
    asksCount INT Multiple columns, each storing the number of ask orders at one level; the number of levels is determined by depth.
  • Output multiple levels into a single column whose type is an array vector. For example, if bidsPrice has 10 levels, the engine outputs those 10 levels as an array vector in a single column: bidsPriceList.
    Column Name Type Description
    bidsPriceList DOUBLE[] Array vector storing bid prices at multiple levels; the number of levels is determined by depth.
    bidsQtyList LONG[] Array vector storing bid volumes at multiple levels; the number of levels is determined by depth.
    bidsCountList INT[] Array vector storing the number of bid orders at multiple levels; the number of levels is determined by depth.
    asksPriceList DOUBLE[] Array vector storing ask prices at multiple levels; the number of levels is determined by depth.
    asksQtyList LONG[] Array vector storing ask volumes at multiple levels; the number of levels is determined by depth.
    asksCountList INT[] Array vector storing the number of ask orders at multiple levels; the number of levels is determined by depth.

tradeDetail

Note:
  • For SSE order books, if you set includeImmediateExecution = true, the engine outputs immediately executed orders in the order details. In this case, the system uses the trade execution time in the trade record as the order submission time and displays it in the tradeOrderBuyNoTimeList and tradeOrderSellNoTimeList columns.
  • When you call the genOutputColumnsForOBSnapshotEngine function with tradeDetail = true, the engine does not output the tradeBuyOrderTypeList and tradeSellOrderTypeList columns by default.
Basic Derived Column Type Description
buyQty LONG Total buy volume in the current period = sum(trading volume where BSFlag=1). The unit is the same as in the raw data.
sellQty LONG Total sell volume in the current period = sum(trading volume where BSFlag=2). The unit is the same as in the raw data.
buyMoney DOUBLE Total buy amount in the current period = sum(trading volume × price where BSFlag=1).
sellMoney DOUBLE Total sell amount in the current period = sum(trading volume × price where BSFlag=2).
tradePriceList DOUBLE[] List of trade prices in the current interval
tradeQtyList LONG[] List of trading volumes in the current interval; the unit is the same as in the raw data.
tradeTypeList INT[] List of trade types in the current interval
tradeBSFlagList INT[] List of trade directions in the current interval
tradeMDTimeList TIME[] List of trade times in the current interval
tradeBuyNoList LONG[] List of buy order sequence numbers in the current interval
tradeSellNoList LONG[] List of sell order sequence numbers in the current interval
tradeOrderBuyNoTimeList TIME[] Submission times of the buy orders corresponding to valid trades in the current interval
tradeOrderSellNoTimeList TIME[] Submission times of the sell orders corresponding to valid trades in the current interval
tradeBuyOrderTypeList INT[] Types of buy orders corresponding to valid trades in the current interval
tradeSellOrderTypeList INT[] Types of sell orders corresponding to valid trades in the current interval

orderDetail

Note:
For SSE order books, if you set includeImmediateExecution = true, the order details will include orders executed immediately.
Basic Derived Column Type Description
orderPriceList DOUBLE[] List of order prices in the current interval
orderQtyList LONG[] List of order quantities in the current interval; the unit is the same as in the raw data.
orderTypeList INT[] List of order types in the current interval
orderBSFlagList INT[] List of buy/sell flags for orders in the current interval
orderMDTimeList TIME[] List of order times in the current interval
orderNoList LONG[] List of order sequence number in the current interval

withdrawDetail (cancellation details)

Note:

  • For SSE order books, if you set includeImmediateExecution = true, the engine outputs immediately executed orders in the order details. In this case, the withdrawBuyOrderQtyList and WithdrawSellOrderQtyList columns will include immediately executed quantities.
  • When you call genOutputColumnsForOBSnapshotEngine, if withdrawDetail=true, it does not output the withdrawBuyOrderNoList and withdrawSellOrderNoList columns by default.
Basic Derived Column Type Description
withdrawBuyPriceList DOUBLE[] Prices of canceled buy-side orders in the current interval
withdrawBuyQtyList LONG[] Quantities of canceled buy-side orders in the current interval; the unit is the same as in the raw data.
withdrawBuyOrderTypeList INT[] Types of canceled buy orders in the current interval.
withdrawBuyMDTimeList TIME[] Cancellation times of buy orders in the current interval
withdrawBuyOrderMDTimeList TIME[] Order submission times corresponding to canceled buy orders in the current interval
WithdrawBuyOrderQtyList LONG[] Order quantities in the original order data corresponding to canceled buy orders in the current interval; the unit is the same as in the raw data.
withdrawSellPriceList DOUBLE[] Prices of canceled sell orders in the current interval
withdrawSellQtyList LONG[] Quantities of canceled sell orders in the current interval; the unit is the same as in the raw data.
withdrawSellOrderTypeList INT[] Types of canceled sell orders in the current interval
withdrawSellMDTimeList TIME[] Cancellation times of sell orders in the current interval
withdrawSellOrderMDTimeList TIME[] Order submission times corresponding to canceled sell orders in the current interval
WithdrawSellOrderQtyList LONG[] Order quantities in the original order data corresponding to canceled sell orders in the current interval; the unit is the same as in the raw data.
withdrawBuyOrderNoList LONG[] Order sequence numbers in the original order data corresponding to canceled buy orders in the current interval
withdrawSellOrderNoList LONG[] Order sequence numbers in the original order data corresponding to canceled sell orders in the current interval

prevDetail (details of the previous trade)

Note:

For SSE order books, if you set includeImmediateExecution = true, the engine outputs immediately executed orders in the order details. In this case, if the immediate execution price matches BuyPrice1/SellPrice1 in the previous snapshot, the prevBuyAddQtyList1 and prevSellAddQtyList1 columns will include the corresponding immediately executed order details.

Basic Derived Column Type Description
prevBuyPrice1 DOUBLE BuyPrice1 from the previous snapshot
prevSellPrice1 DOUBLE SellPrice1 from the previous snapshot
prevBuyAddQtyList1 LONG[] Order addition details in the current interval at the previous snapshot's BuyPrice1; the unit is the same as in the raw data.
prevSellAddQtyList1 LONG[] Order addition details in the current interval at the previous snapshot's SellPrice1; the unit is the same as in the raw data.
prevBuyWithdrawQtyList1 LONG[] Cancellation details in the current interval at the previous snapshot's BuyPrice1; the unit is the same as in the raw data.
prevSellWithdrawQtyList1 LONG[] Cancellation details in the current interval at the previous snapshot's SellPrice1; the unit is the same as in the raw data.

orderBookDetailDepth

The engine outputs one column for each level, and each column is an array vector. For example, if buyQtyList has 20 levels, the engine outputs 20 buyQtyList fields: buyQtyList1, buyQtyList2, …, buyQtyList20. The same applies to buyValueList, sellQtyList, and sellValueList.

Basic Derived Column Type Description
buyQtyList LONG[] Quantity of each buy order at each level in the latest order book
buyValueList DOUBLE[] Value of each buy order at each level in the latest order book
sellQtyList LONG[] Quantity of each sell order at each level in the latest order book
sellValueList DOUBLE[] Value of each sell order at each level in the latest order book

seqDetail

Note:

For SSE order books, if you set includeImmediateExecution = true, the engine outputs immediately executed orders in the order details. In this case, the orderSeqList column will include order submission records for immediate executions.

Basic Derived Column Type Description
tradeSeqList LONG[] List of trade sequence numbers in the current interval
orderSeqList LONG[] List of order sequence numbers in the current interval
withdrawBuySeqList LONG[] List of buy-side canceled order sequence numbers in the current interval
withdrawSellSeqList LONG[] List of sell-side canceled order sequence numbers in the current interval

residualDetail (remaining order details)

Note:
  • In the sell-side columns (ResidualAskPriceList, ResidualAskQtyList, ResidualAskTimeList, ResidualAskApplSeqNumList), entries at each price level are sorted in ascending order by price, then by trade time. If price and trade time are the same, the data is then sorted by the time it entered the engine in ascending order.
  • In the buy-side columns (ResidualBidPriceList, ResidualBidQtyList, ResidualBidTimeList, ResidualBidApplSeqNumList), entries at each price level are sorted in descending order by price and ascending order by trade time. If price and trade time are the same, the data is then sorted by the time it entered the engine in ascending order.
  • When you call genOutputColumnsForOBSnapshotEngine, if residualDetail=true, the ResidualBidOrderNoList and ResidualAskOrderNoList columns are not output by default.
Column Name Type Description
ResidualAskPriceList DOUBLE[] Price list of remaining sell orders
ResidualAskQtyList LONG[] Quantity list of remaining sell orders
ResidualAskTimeList TIME[] Time list of remaining sell orders
ResidualAskApplSeqNumList LONG[] ApplSeqNum list of remaining sell-side orders
ResidualBidPriceList DOUBLE[] Price list of remaining buy orders
ResidualBidQtyList LONG[] Quantity list of remaining buy orders
ResidualBidTimeList TIME[] Time list of remaining buy orders
ResidualBidApplSeqNumList LONG[] ApplSeqNum list of remaining buy orders
ResidualBidOrderNoList LONG[] Sequence number list of remaining buy orders
ResidualAskOrderNoList LONG[] Sequence number list of remaining sell orders