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:
|
| "frequency" | Generates bars from snapshot data at the specified frequency |
INT type. Default is 0, in milliseconds.
|
| "msgAsTable" | Market data format |
BOOL type.
|
| "matchingMode" | Order matching mode |
INT type. Valid values depend on the market data type:
When |
| "enableSettlementPrice" | Whether to use the settlement price to calculate the portfolio equity metrics after each trading day |
BOOL type. Optional
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 |
| "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:
|
| "futuresType" | The futures product type, such as stock index futures or commodity futures | STRING type. |
| "enableIndicatorOptimize" | Whether to enable indicator optimization |
BOOL type.
|
| "isBacktestMode" | Whether it is backtesting mode or matching mode |
BOOL type.
|
| "dataRetentionWindow" | Data retention window when indicator optimization starts |
STRING type. Effective only when
|
| "addTimeColumnInIndicator" | Whether to add a time column to the indicator table when subscribing to indicators |
BOOL type.
|
| "context" | Strategy logic context structure |
DICT type. A dictionary of strategy global variables, for example:
|
| "callbackForSnapshot" | Callback mode triggered by snapshot data |
Effective when
Default is 0. When |
| "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; |
| "msgAsPiecesOnSnapshot" | How the onSnapshot callback is triggered |
BOOL type.
|
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:
|
| lastTradingDay | DATE |
The contract's last trading day. Positions are automatically closed at the close of that day. Automatic position closing does not trigger |
| 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
onBarcallback 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
onBarcallback. 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 usesubscribeIndicatorto subscribe to 'ohlc' indicators.
