Futures Backtesting Configurations

The backtesting platform supports the following types of futures market data: snapshot, minute-level, and daily data.

Engine Configurations

Configuration for config in the createBacktester and createBacktestEngine interface:

Key Description Note
"startDate" Start date DATE type, required (e.g. 2020.01.01).
"endDate" End date DATE type, required (e.g. 2020.01.01).
"strategyGroup" Strategy type STRING type, required (e.g. "futures").
"cash" Initial funds DOUBLE type, required.
"dataType" Market data type

INT type, required. It can be:

  • 1: Snapshot data

  • 3: Minute-level data

  • 4: Daily data

  • 7: Snapshot + minute-level data (This mode is supported only by engines created through the createBacktester interface and does not support JIT.)

"frequency" Generates bars from snapshot data at the specified frequency

INT type. Default is 0, in milliseconds.

  • When frequency = 0, Bar market data is not aggregated and this parameter is ineffective.

  • When dataType=1 and frequency > 0, the engine generates Bar market data at the specified frequency and triggers the onBar callback.

"msgAsTable" Market data format

BOOL type.

  • false (default): dictionary.

  • true: table (the engine can only be created via createBacktestEngine).

"matchingMode" Order matching mode

INT type. Valid values depend on the market data type:

  • 1:

    • Daily data: Matches orders at the closing price.

    • Minute-level data: Matches orders when the market data timestamp is later than the order timestamp.

  • 2:

    • Daily data: Matches orders at the opening price.

    • Minute-level data: When the market data timestamp equals the order timestamp, it matches the order at the closing price of the current market data. Subsequent matching of unfilled orders follows matchingMode=1.

  • 3: Matches orders at the order price.

When dataType=1, setting this parameter to 1 or 2 is invalid. Orders are matched by the order matching simulator by default.

"enableSettlementPrice" Whether to use the settlement price to calculate the portfolio equity metrics after each trading day

BOOL type. Optional

  • true: When calculating the portfolio equity metrics after each trading day, it uses the latest settlementPrice for the security in the market data table as the valuation price. This setting applies only to the getDailyTotalPortfolios interface and to getTotalPortfolios calls made in the afterTrading callback function. When getTotalPortfolios is called from other callback functions, it continues to use the latest price.

  • false: Uses the latest price to calculate the portfolio equity metrics.

When set to true, the input snapshot, minute-level, or daily market data must include the settlementPrice field; otherwise, the backtest fails.

"benchmark" Benchmark instrument

STRING type.

For example, "A2305" specifies the benchmark security used by the getReturnSummary interface to compare return performance.

"latency" Order latency INT type, in milliseconds. Simulates the latency between the time a user's order is submitted and the time it is processed. The default is 0, which means no delay.
"maintenanceMargin" Maintenance margin ratio DOUBLE type. The default is 0.75. The value must be between 0 and 1.0.
"enableAlgoOrder" Whether to enable algorithmic orders

BOOL type:

  • true: Enabled.

  • false(default): Disabled.

"futuresType" The futures product type, such as stock index futures or commodity futures STRING type.
"enableIndicatorOptimize" Whether to enable indicator optimization

BOOL type.

  • true: Enabled.

  • false (default): Disabled.

"isBacktestMode" Whether it is backtesting mode or matching mode

BOOL type.

  • true (default): Backtesting

  • false: Matching.

"dataRetentionWindow" Data retention window when indicator optimization starts

STRING type. Effective only when enableIndicatorOptimize = true.

  • When isBacktestMode = true, the default is "None". You can set it to:

    • "ALL": Retains all data

    • "20d": Retains data by trading days. e.g., "20d" retains 20 trading days.

    • "None": Does not retain data

    • "20": Retains data by row count. e.g., "20" retains the latest 20 rows per symbol.

  • This parameter does not need to be set when isBacktestMode = false.

"addTimeColumnInIndicator" Whether to add a time column to the indicator table when subscribing to indicators

BOOL type.

  • true: Add the time column.

  • false (default): Do not add the time column.

"context" Strategy logic context structure

DICT type. A dictionary of strategy global variables, for example:

context=dict(STRING,ANY)
context["buySignalRSI"]=70.
userConfig["context"]=context
"callbackForSnapshot" Callback mode triggered by snapshot data

Effective when dataType = 1. INT type. Available values are:

  • 0: Triggers only the onSnapshot callback function.

  • 1: Triggers both the onSnapshot and onBar callback functions.

  • 2: Triggers only the onBar callback function.

Default is 0. When frequency > 0, the onBar callback function must be triggered. In other words, callbackForSnapshot must be set to 1 or 2.

"orderBookMatchingRatio" Fill percentage against the market order book Effective when dataType = 1. DOUBLE type, default is 1.0,valid range: [0-1.0].
"matchingRatio" Interval order matching ratio Effective when dataType = 1. DOUBLE type,valid range: [0-1.0]. If not specified, it takes the value of orderBookMatchingRatio;
"msgAs​PiecesOnSnapshot" How the onSnapshot callback is triggered

BOOL type.

  • false (default): Each data record triggers onSnapshot in sequence.

  • true: All records with the same timestamp trigger onSnapshot simultaneously.

Note:

The engine configuration parameters available vary by futures market data type (dataType). Of these parameters, callbackForSnapshot, orderBookMatchingRatio, and matchingRatio take effect only when dataType = 1 (snapshot data).

Schema of securityReference

Fields of the securityReference parameter in the createBacktester and setSecurityReference interfaces are described below.

securityReference supports the following two modes:

  • Static mode: The table does not contain a tradeDate column. The configured contract specifications are used throughout the backtest.

  • Trading-date mode: The table contains a tradeDate column. Before the market opens on each trading day, the engine reads the contract specifications for each futures contract according to the following rules:

    • If a record with a tradeDate equal to the current trading day exists, use that record.

    • Otherwise, use the latest record whose tradeDate is less than or equal to the current trading day.

Static mode and trading-date mode cannot be mixed within the same engine. Whether the securityReference passed when creating the engine contains tradeDate must be consistent with the contract specification table subsequently passed through Backtest::setSecurityReference.

Field Type Description
symbol SYMBOL or STRING Futures contract code
tradeDate DATE Trading date. Cannot contain null values.
multiplier DOUBLE Contract multiplier
marginRatio DOUBLE Margin ratio
tradeUnit DOUBLE Contract unit
priceUnit DOUBLE Quote unit
priceTick DOUBLE Minimum price increment
commission DOUBLE Fees
deliveryCommissionMode INT

Billing method:

  • 1: fee × number of contracts

  • 2: fee × notional amount

lastTradingDay DATE

The contract's last trading day. Positions are automatically closed at the close of that day.

Automatic position closing does not trigger onOrder or onTrade. In the trade detail table, a record with orderStatus set to 1 and label set to __auto_close_position_on_last_trading_day indicates that the system automatically closed the position.

deliveryPrice DOUBLE

Delivery price.

When the system automatically closes positions on the last trading day, it executes the trades according to the following price priority. If a higher-priority price is not set or is unavailable, the next price in the priority order is used:

1. Delivery price

2. Settlement price (settlement)

3. Latest traded price (lastPrice)

intradayClosingFee DOUBLE Intraday position-closing fee

In trading-date mode, you can update contract specifications such as marginRatio and commission using records with different tradeDate values. For the same contract, multiplier and tradeUnit always use the values loaded initially. Changes in subsequent records do not take effect, and the system does not report an error.

Snapshot

Schema of Snapshot Data

When appending data into the backtest engine via Backtest::appendQuotationMsg , the msg is:

colName=["symbol","symbolSource","timestamp","tradingDay","lastPrice","upLimitPrice",
 "downLimitPrice","totalBidQty","totalOfferQty","bidPrice","bidQty","offerPrice",
 "offerQty","highPrice","lowPrice"]
colType= ["STRING","STRING","TIMESTAMP","DATE","DOUBLE","DOUBLE","DOUBLE","LONG","LONG",
 "DOUBLE[]","LONG[]","DOUBLE[]","LONG[]","DOUBLE","DOUBLE"]
messageTable=table(10000000:0, colName, colType)

Note:

  • The schema above applies to the input table for snapshot data (callbackForSnapshot=0). It does not apply when bars are generated from snapshot data.

  • Field names must exactly match the definitions in the table below. The first column must be named symbol, the other columns may appear in any order. The input table may also include extended fields of type INT, DOUBLE, or STRING, or a field named signal of type DOUBLE[].

Schema of snapshot data:

Field Type Note
symbol SYMBOL or STRING Futures contract code
symbolSource SYMBOL or STRING Exchange
timestamp TIMESTAMP Timestamp
tradingDay DATE Trading date/settlement date
lastPrice DOUBLE Latest traded price
upLimitPrice DOUBLE Limit up price
downLimitPrice DOUBLE Limit down price
totalBidQty LONG Total bid volume
totalOfferQty LONG Total ask volume
bidPrice DOUBLE[] Bid price
bidQty LONG[] Bid size
offerPrice DOUBLE[] Ask price
offerQty LONG[] Ask size
highPrice DOUBLE High price
lowPrice DOUBLE Low price

Table schema for generating bars from snapshot data (frequency>0, callbackForSnapshot=1 or 2):

colName=["symbol","symbolSource","timestamp","tradingDay","lastPrice","upLimitPrice",
 "downLimitPrice","totalBidQty","totalOfferQty","bidPrice","bidQty","offerPrice",
 "offerQty","highPrice","lowPrice","open", "close","low","high","volume"]
colType= ["STRING","STRING","TIMESTAMP","DATE","DOUBLE","DOUBLE","DOUBLE","LONG","LONG",
 "DOUBLE[]","LONG[]","DOUBLE[]","LONG[]","DOUBLE","DOUBLE","DOUBLE","DOUBLE",
 "DOUBLE","DOUBLE","LONG"]
messageTable=table(10000000:0, colName, colType)

Note:

  • When generating bars from snapshot data, the input table must also contain the five fields: open, close, low, high, and volume.

  • Field names must exactly match the definitions in the table below. Except that the first column must be named symbol, the other fields may appear in any order. The input table may also contain additional fields of type INT, DOUBLE, or STRING, or a field named signal of type DOUBLE[].

The required fields for the snapshot data table used to generate bars are as follows:

Field Type Note
symbol SYMBOL or STRING Futures contract code
symbolSource SYMBOL or STRING Exchange
timestamp TIMESTAMP Timestamp
tradingDay DATE Trading date/settlement date
lastPrice DOUBLE Latest traded price
upLimitPrice DOUBLE Limit up price
downLimitPrice DOUBLE Limit down price
totalBidQty LONG Total bid volume
totalOfferQty LONG Total ask volume
bidPrice DOUBLE[] Bid price
bidQty LONG[] Bid size
offerPrice DOUBLE[] Ask price
offerQty LONG[] Ask size
highPrice DOUBLE High price
lowPrice DOUBLE Low price
open DOUBLE Opening price of the generated Bar
close DOUBLE Closing price of the generated Bar
low DOUBLE Low price of the generated Bar
high DOUBLE High price of the generated Bar
volume LONG Trading volume of the generated Bar

After the replay of historical data in backtesting is completed, you can append a message with the symbol set to "END" to indicate the end of the strategy backtest. For example:

messageTable=select top 1 * from messageTable
update messageTable set symbol="END" 
Backtest::appendQuotationMsg(engine,messageTable)

Snapshot Callback Function

The input parameter for the snapshot data callback function onSnapshot is msg.

msg is a dictionary, its keys are symbols, and its values are the corresponding snapshot data (snapShot). Each snapshot data contains the following fields:

Field Type Note
symbol SYMBOL or STRING Futures contract code
symbolSource SYMBOL or STRING Exchange
timestamp TIMESTAMP Timestamp
tradingDay DATE Trading date/settlement date
lastPrice DOUBLE Latest traded price
upLimitPrice DOUBLE Limit up price
downLimitPrice DOUBLE Limit down price
totalBidQty LONG Total bid volume
totalOfferQty LONG Total ask volume
bidPrice DOUBLE[] Bid price
bidQty LONG[] Bid size
offerPrice DOUBLE[] Ask price
offerQty LONG[] Ask size
highPrice DOUBLE High price
lowPrice DOUBLE Low price
signal DOUBLE[] Other fields
prevClosePrice DOUBLE Previous closing price
settlementPrice DOUBLE Settlement price
prevSettlementPrice DOUBLE Previous settlement price
open DOUBLE Opening price of the generated Bar. This field is included only when dataType=1 and callbackForSnapshot=1 or 2.
close DOUBLE Closing price of the generated Bar. This field is included only when dataType=1 and callbackForSnapshot=1 or 2.
low DOUBLE Low price of the generated Bar. This field is included only when dataType=1 and callbackForSnapshot=1 or 2.
high DOUBLE High price of the generated Bar. This field is included only when dataType=1 and callbackForSnapshot=1 or 2.
volume LONG Trading volume of the generated Bar. This field is included only when dataType=1 and callbackForSnapshot=1 or 2.

Note:

  • When generating bars from snapshot data, the input parameter msg also contains the five fields open, close, low, high, and volume.

  • When callbackForSnapshot=1, the onBar callback function is also triggered. The data structure of its input parameter msg is as follows.

The input parameter for the OHLC bar market data callback function onBar is msg.

msg is a dictionary, each key is a symbol, and each value is the corresponding minute-level OHLC bar data. Each OHLC bar contains the following fields:

Field Type Note
symbol SYMBOL or STRING Futures contract code
symbolSource SYMBOL or STRING Exchange
timestamp TIMESTAMP Timestamp
tradingDay DATE Trading date/settlement date
lastPrice DOUBLE Latest traded price
upLimitPrice DOUBLE Limit up price
downLimitPrice DOUBLE Limit down price
totalBidQty LONG Total bid volume
totalOfferQty LONG Total ask volume
bidPrice DOUBLE[] Bid price
bidQty LONG[] Bid size
offerPrice DOUBLE[] Ask price
offerQty LONG[] Ask size
highPrice DOUBLE High price
lowPrice DOUBLE Low price
signal DOUBLE[] Other fields
prevClosePrice DOUBLE Previous closing price
settlementPrice DOUBLE Settlement price
prevSettlementPrice DOUBLE Previous settlement price

Minute-Level or Daily Frequency

Schema of Minute-Level and Daily Market Data

When appending data into the backtest engine via Backtest::appendQuotationMsg , the msg is:

colName=["symbol","symbolSource","tradeTime","tradingDay","open","low","high","close",
"volume","upLimitPrice","downLimitPrice"]
colType=["SYMBOL","SYMBOL","TIMESTAMP","DATE","DOUBLE","DOUBLE","DOUBLE","DOUBLE","LONG",
"DOUBLE","DOUBLE"]
messageTable=table(10000000:0, colName, colType)

Note:

Field names must exactly match the definitions in the following table. The first column must be named symbol, the other columns may appear in any order. The market data table may also include the following extended fields: fields of type INT, DOUBLE, or STRING, as well as a field named signal of type DOUBLE[].

Schema of minute-level and daily market data:

Field Type Note
symbol SYMBOL or STRING Futures contract code
symbolSource SYMBOL or STRING Exchange
tradeTime TIMESTAMP Timestamp
tradingDay DATE Trading date/settlement date
open DOUBLE Opening price
low DOUBLE Low price
high DOUBLE High price
close DOUBLE Closing price
volume LONG Filled Quantity
upLimitPrice DOUBLE Limit up price
downLimitPrice DOUBLE Limit down price

After the replay of historical data in backtesting is completed, you can append a message with the symbol set to "END" to indicate the end of the strategy backtest. For example:

messageTable=select top 1 * from messageTable
update messageTable set symbol="END" 
Backtest::appendQuotationMsg(engine,messageTable)

OHLC Callback Function

The input parameter for the OHLC callback function onBar is msg.

msg is a dictionary, each key is a symbol, and each value is the corresponding minute-level OHLC bar data. Each OHLC bar contains the following fields:

Field Type Note
symbol SYMBOL or STRING Futures contract code
symbolSource SYMBOL or STRING Exchange
timestamp TIMESTAMP Timestamp
tradingDay DATE Trading date/settlement date
lastPrice DOUBLE Latest traded price
upLimitPrice DOUBLE Limit up price
downLimitPrice DOUBLE Limit down price
totalBidQty LONG Total bid volume
totalOfferQty LONG Total ask volume
bidPrice DOUBLE[] Bid price
bidQty LONG[] Bid size
offerPrice DOUBLE[] Ask price
offerQty LONG[] Ask size
highPrice DOUBLE High price
lowPrice DOUBLE Low price
signal DOUBLE[] Other fields
prevClosePrice DOUBLE Previous closing price
settlementPrice DOUBLE Settlement price
prevSettlementPrice DOUBLE Previous settlement price

Snapshot + Minute-Level

Schema of Snapshot + Minute-Level Data

When data is inserted into the engine through the appendQuotationMsg interface, msg is a dictionary that supports the following three keys: 'ohlc', 'snapshot', and 'indicator':

  • 'ohlc' is the minute-level market data table, with the following schema:

    colName=["symbol","symbolSource","tradeTime","tradingDay","open","low","high","close",
    "volume","upLimitPrice","downLimitPrice"]
    colType=["SYMBOL","SYMBOL","TIMESTAMP","DATE","DOUBLE","DOUBLE","DOUBLE","DOUBLE","LONG",
    "DOUBLE","DOUBLE"]
    messageTable=table(10000000:0, colName, colType)

    Note:

    Field names must exactly match the definitions in the following table. The first column must be named symbol, the other columns may appear in any order. The market data table may also include the following extended fields: fields of type INT, DOUBLE, or STRING, as well as a field named signal of type DOUBLE[].

    The required fields for a minute-level market data table are shown below:

    Field Type Note
    symbol SYMBOL or STRING Futures contract code
    symbolSource SYMBOL or STRING Exchange
    tradeTime TIMESTAMP Timestamp
    tradingDay DATE Trading date/settlement date
    open DOUBLE Opening price
    low DOUBLE Low price
    high DOUBLE High price
    close DOUBLE Closing price
    volume LONG Filled Quantity
    upLimitPrice DOUBLE Limit up price
    downLimitPrice DOUBLE Limit down price
  • 'snapshot' is the snapshot data table, with the following schema:

    colName=["symbol","symbolSource","timestamp","tradingDay","lastPrice","upLimitPrice",
     "downLimitPrice","totalBidQty","totalOfferQty","bidPrice","bidQty","offerPrice",
     "offerQty","highPrice","lowPrice"]
    colType= ["STRING","STRING","TIMESTAMP","DATE","DOUBLE","DOUBLE","DOUBLE","LONG","LONG",
     "DOUBLE[]","LONG[]","DOUBLE[]","LONG[]","DOUBLE","DOUBLE"]
    messageTable=table(10000000:0, colName, colType)

    Note:

    • The schema above applies to the input table for snapshot data (callbackForSnapshot=0). It does not apply when bars are generated from snapshot data.

    • Field names must exactly match the definitions in the table below. The first column must be named symbol, the other columns may appear in any order. The input table may also include extended fields of type INT, DOUBLE, or STRING, or a field named signal of type DOUBLE[].

    Schema of snapshot data:

    Field Type Note
    symbol SYMBOL or STRING Futures contract code
    symbolSource SYMBOL or STRING Exchange
    timestamp TIMESTAMP Timestamp
    tradingDay DATE trading date/settlement date
    lastPrice DOUBLE Latest traded price
    upLimitPrice DOUBLE Limit up price
    downLimitPrice DOUBLE Limit down price
    totalBidQty LONG Total bid volume
    totalOfferQty LONG Total ask volume
    bidPrice DOUBLE[] Bid price
    bidQty LONG[] Bid size
    offerPrice DOUBLE[] Ask price
    offerQty LONG[] Ask size
    highPrice DOUBLE High price
    lowPrice DOUBLE Low price
  • 'indicator' is a historical indicator data table used by the onBar callback. This table must contain the fields symbol and timestamp. The remaining fields may be used as extended fields and must be of type INT, DOUBLE, or STRING. Once configured, you cannot simultaneously use subscribeIndicator to subscribe to 'ohlc' indicators.