Options#
The backtesting engine supports the following types of market data: snapshot, minute-level, and daily data.
Engine Configuration#
The following table describes the config parameter in createBacktester and the userConfig parameter in createBacktestEngine.
Key |
Description |
Remarks |
|---|---|---|
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 |
required, must be “option”. |
cash |
initial capital |
DOUBLE type, required. |
dataType |
market data type |
INT type, required.
|
frequency |
bar frequency for snapshot data |
INT type, default = 0. Applicable only when
|
msgAsTable |
market data format |
BOOL type, default =
|
matchingMode |
order matching mode |
INT type, options:
match orders at the order price. Note: When dataType = 1, values 1 and 2 are invalid; orders are matched by the simulated matching engine by default. |
benchmark |
benchmark instrument |
STRING or SYMBOL type, e.g. “A2305”. |
latency |
order latency (ms) |
INT type, the latency from order submission to execution. |
maintenanceMargin |
maintenance margin ratio |
DOUBLE type, default = 1.0. value range: 0–1.0. |
enableAlgoOrder |
enable algorithmic orders |
|
enableIndicatorOptimize |
enable indicator optimization |
|
isBacktestMode |
backtest mode flag |
|
dataRetentionWindow |
data retention policy for indicator optimization |
STRING/INT type. Effective only when both enableIndicatorOptimize = true and isBacktestMode = true:
|
addTimeColumnInIndicator |
add time column to indicator subscription results |
|
context |
strategy context structure |
A dictionary consisting of global strategy variables, for example: |
callbackForSnapshot |
snapshot callback mode |
Available only for
frequency > 0, must trigger onBar (callbackForSnapshot = 1 or 2). |
orderBookMatchingRatio |
the proportion of an order that gets filled |
DOUBLE type, default = 1.0, value range: 0–1.0. Applicable only when |
matchingRatio |
matching ratio within price intervals |
DOUBLE type, default 1.0, value range: 0–1.0. Applicable only when |
Note:
The available engine configuration parameters differ depending on the data type (dataType).
The parameters callbackForSnapshot, orderBookMatchingRatio, and matchingRatio are only applicable when dataType = 1.
Reference Table Description#
The securityReference parameter in both the createBacktester and createBacktestEngine interfaces should follow the field definitions below:
Field |
Type |
Description |
|---|---|---|
symbol |
SYMBOL or STRING |
contract code. |
underlyingAssetType |
INT |
option category:
|
multiplier |
DOUBLE |
contract multiplier. |
type |
INT |
option type:
|
strikePrice |
DOUBLE |
strike price. |
marginRatio |
DOUBLE |
margin ratio. |
tradeUnit |
DOUBLE |
contract unit. |
priceUnit |
DOUBLE |
quotation unit. |
priceTick |
DOUBLE |
minimum price fluctuation. |
commission |
DOUBLE |
commission fee. |
deliveryCommissionMode |
INT |
commission calculation mode:
|
lastTradingDay |
DATE |
contract’s last trading day. |
exerciseDate |
DATE |
option exercise date. |
exerciseSettlementDate |
DATE |
option settlement date. |
exDate |
DATE |
ex-dividend or interest payment date. when the trading date ≥ |
adjStrikePrice |
DOUBLE |
adjusted strike price (used when trading date ≥ |
adjMultiplier |
DOUBLE |
adjusted contract multiplier (used when trading date ≥ |
Snapshot#
Market Data Structure#
The structure of the quotation table written by Backtest::appendQuotationMsg is as follows:
message_table = sf.table(
types={
"symbol": "STRING",
"symbolSource": "STRING",
"timestamp": "TIMESTAMP",
"tradingDay": "DATE",
"lastPrice": "DOUBLE",
"upLimitPrice": "DOUBLE",
"downLimitPrice": "DOUBLE",
"totalBidQty": "LONG",
"totalOfferQty": "LONG",
"bidPrice": "DOUBLE[]",
"bidQty": "LONG[]",
"offerPrice": "DOUBLE[]",
"offerQty": "LONG[]",
"highPrice": "DOUBLE",
"lowPrice": "DOUBLE",
"signal": "DOUBLE",
"prevClosePrice": "DOUBLE",
"settlementPrice": "DOUBLE",
"prevSettlementPrice": "DOUBLE",
"underlyingPrice": "DOUBLE",
"Theta": "DOUBLE",
"Vega": "DOUBLE",
"Gamma": "DOUBLE",
"Delta": "DOUBLE",
"IV": "DOUBLE"
},
size=0,
capacity=10000000
)
Note:
The above structure applies to snapshot data (
callbackForSnapshot = 0), i.e., input structure for non-bar snapshot data.Field names must exactly match those listed below. Except for the first column
symbol, the field order is not restricted. Additional columns of type INT, DOUBLE, STRING, or a DOUBLE ARRAY VECTOR field namedsignalare supported as extensions.
The required fields for snapshot data are as follows:
Field |
Type |
Description |
|---|---|---|
symbol |
SYMBOL |
option code |
symbolSource |
STRING |
exchange |
timestamp |
TIMESTAMP |
timestamp |
tradingDay |
DATE |
trading/settlement date |
lastPrice |
DOUBLE |
last traded price |
upLimitPrice |
DOUBLE |
upper limit price |
downLimitPrice |
DOUBLE |
lower limit price |
totalBidQty |
LONG |
total buy quantity in the interval |
totalOfferQty |
LONG |
total sell quantity in the interval |
bidPrice |
DOUBLE[] |
bid prices |
bidQty |
LONG[] |
bid quantities |
offerPrice |
DOUBLE[] |
offer prices |
offerQty |
LONG[] |
offer quantities |
highPrice |
DOUBLE |
highest price |
lowPrice |
DOUBLE |
lowest price |
signal |
DOUBLE[] |
other field list (required only in JIT mode) |
prevClosePrice |
DOUBLE |
previous close price (required only in JIT mode) |
settlementPrice |
DOUBLE |
settlement price (required only in JIT mode) |
prevSettlementPrice |
DOUBLE |
previous settlement price (required only in JIT mode) |
underlyingPrice |
DOUBLE |
underlying price |
Theta |
DOUBLE |
/ |
Vega |
DOUBLE |
/ |
Gamma |
DOUBLE |
/ |
Delta |
DOUBLE |
/ |
IV |
DOUBLE |
/ |
When snapshot data is aggregated into bars (frequency > 0 and callbackForSnapshot = 1 or 2), the structure is as follows:
message_table = sf.table(
types={
"symbol": "STRING",
"symbolSource": "STRING",
"timestamp": "TIMESTAMP",
"tradingDay": "DATE",
"lastPrice": "DOUBLE",
"upLimitPrice": "DOUBLE",
"downLimitPrice": "DOUBLE",
"totalBidQty": "LONG",
"totalOfferQty": "LONG",
"bidPrice": "DOUBLE[]",
"bidQty": "LONG[]",
"offerPrice": "DOUBLE[]",
"offerQty": "LONG[]",
"highPrice": "DOUBLE",
"lowPrice": "DOUBLE",
"prevClosePrice": "DOUBLE",
"settlementPrice": "DOUBLE",
"prevSettlementPrice": "DOUBLE",
"underlyingPrice": "DOUBLE",
"Theta": "DOUBLE",
"Vega": "DOUBLE",
"Gamma": "DOUBLE",
"Delta": "DOUBLE",
"IV": "DOUBLE",
"open": "DOUBLE",
"close": "DOUBLE",
"low": "DOUBLE",
"high": "DOUBLE",
"volume": "LONG"
},
size=0,
capacity=10000000
)
Note:
When snapshot bars are synthesized (
frequency > 0andcallbackForSnapshot = 1 or 2), five additional fields must be included:"open","close","low","high", and"volume".Field names must exactly match those below. except for the first column
symbol, the field order is not restricted. additional columns of type INT, DOUBLE, STRING, or a DOUBLE ARRAY VECTOR field namedsignalare supported as extensions.
Required fields for snapshot bar data:
Field |
Type |
Description |
|---|---|---|
symbol |
SYMBOL |
option code |
symbolSource |
STRING |
exchange |
timestamp |
TIMESTAMP |
timestamp |
tradingDay |
DATE |
trading/settlement date |
lastPrice |
DOUBLE |
last traded price |
upLimitPrice |
DOUBLE |
upper limit price |
downLimitPrice |
DOUBLE |
lower limit price |
totalBidQty |
LONG |
total buy quantity in the interval |
totalOfferQty |
LONG |
total sell quantity in the interval |
bidPrice |
DOUBLE[] |
bid prices |
bidQty |
LONG[] |
bid quantities |
offerPrice |
DOUBLE[] |
offer prices |
offerQty |
LONG[] |
offer quantities |
highPrice |
DOUBLE |
highest price |
lowPrice |
DOUBLE |
lowest price |
signal |
DOUBLE[] |
other field list (required only in JIT mode) |
prevClosePrice |
DOUBLE |
previous close price (required only in JIT mode) |
settlementPrice |
DOUBLE |
settlement price (required only in JIT mode) |
prevSettlementPrice |
DOUBLE |
previous settlement price (required only in JIT mode) |
underlyingPrice |
DOUBLE |
underlying price |
Theta |
DOUBLE |
/ |
Vega |
DOUBLE |
/ |
Gamma |
DOUBLE |
/ |
Delta |
DOUBLE |
/ |
IV |
DOUBLE |
/ |
open |
DOUBLE |
open price of the synthesized bar |
close |
DOUBLE |
close price of the synthesized bar |
low |
DOUBLE |
lowest price of the synthesized bar |
high |
DOUBLE |
highest price of the synthesized bar |
volume |
LONG |
trading volume of the synthesized bar |
At the end of backtest replay, a message with symbol = "END" must be sent:
message_table = sf.sql(
"SELECT TOP 1 * FROM messageTable WHERE timestamp = max(timestamp)",
vars={
'messageTable': message_table
}
)
# demo of signal field generation
# sf.sql(
# "UPDATE messageTable SET signal = fixedLengthArrayVector([close])",
# vars={'messageTable': message_table, 'fixedLengthArrayVector': F.fixedLengthArrayVector}
# )
sf.sql(
"UPDATE messageTable SET symbol = `END",
vars={'messageTable': message_table}
)
backtester.append_data(message_table)
Callback Function#
Snapshot callback function onSnapshot: input parameter msg
When msg is a dictionary, it uses symbol as the key and stores snapshot data for each symbol.
Each snapshot object includes the following fields:
Field |
Type |
Description |
|---|---|---|
symbol |
SYMBOL |
option code |
symbolSource |
STRING |
exchange |
timestamp |
TIMESTAMP |
timestamp |
tradingDay |
DATE |
trading/settlement date |
lastPrice |
DOUBLE |
last traded price |
upLimitPrice |
DOUBLE |
upper limit price |
downLimitPrice |
DOUBLE |
lower limit price |
totalBidQty |
LONG |
total buy quantity in the interval |
totalOfferQty |
LONG |
total sell quantity in the interval |
bidPrice |
DOUBLE[] |
bid prices |
bidQty |
LONG[] |
bid quantities |
offerPrice |
DOUBLE[] |
offer prices |
offerQty |
LONG[] |
offer quantities |
highPrice |
DOUBLE |
highest price |
lowPrice |
DOUBLE |
lowest price |
signal |
DOUBLE[] |
other field list |
prevClosePrice |
DOUBLE |
previous close price |
settlementPrice |
DOUBLE |
settlement price |
prevSettlementPrice |
DOUBLE |
previous settlement price |
underlyingPrice |
DOUBLE |
underlying price |
Theta |
DOUBLE |
/ |
Vega |
DOUBLE |
/ |
Gamma |
DOUBLE |
/ |
Delta |
DOUBLE |
/ |
IV |
DOUBLE |
/ |
open |
DOUBLE |
open price of synthesized bar (available only when |
close |
DOUBLE |
close price of synthesized bar (available only when |
low |
DOUBLE |
lowest price of synthesized bar (available only when |
high |
DOUBLE |
highest price of synthesized bar (available only when |
volume |
LONG |
trading volume of synthesized bar (available only when |
Note:
When snapshot bars are synthesized (
frequency > 0andcallbackForSnapshot = 1 or 2), five additional fields"open","close","low","high", and"volume"must be included inmsg.When
callbackForSnapshot = 1 or 2, theonBarcallback function will also be triggered. the structure of itsmsgparameter is described below.
Callback Function#
Callback function onBar: input parameter msg
When msg is a dictionary, it uses symbol as the key and stores minute-level bar data for each symbol.
Each bar object includes the following fields:
Field |
Type |
Description |
|---|---|---|
symbol |
SYMBOL |
option code |
symbolSource |
STRING |
exchange |
tradeTime |
TIMESTAMP |
timestamp |
tradingDay |
DATE |
trading/settlement date |
open |
DOUBLE |
open price |
low |
DOUBLE |
the lowest price |
high |
DOUBLE |
the highest price |
close |
DOUBLE |
close price |
volume |
LONG |
trading volume |
amount |
DOUBLE |
trading amount |
upLimitPrice |
DOUBLE |
limit-up price |
downLimitPrice |
DOUBLE |
limit-down price |
signal |
DOUBLE[] |
other field list |
prevClosePrice |
DOUBLE |
previous close price |
settlementPrice |
DOUBLE |
settlement price |
prevSettlementPrice |
DOUBLE |
previous settlement price |
underlyingPrice |
DOUBLE |
underlying price |
Theta |
DOUBLE |
/ |
Vega |
DOUBLE |
/ |
Gamma |
DOUBLE |
/ |
Delta |
DOUBLE |
/ |
IV |
DOUBLE |
/ |
Minute-level or daily data#
Market data structure description#
The market data table structure written by Backtest::appendQuotationMsg is as follows:
message_table = sf.table(
types={
"symbol": "SYMBOL",
"symbolSource": "SYMBOL",
"tradeTime": "TIMESTAMP",
"tradingDay": "DATE",
"open": "DOUBLE",
"low": "DOUBLE",
"high": "DOUBLE",
"close": "DOUBLE",
"volume": "LONG",
"amount": "DOUBLE",
"upLimitPrice": "DOUBLE",
"downLimitPrice": "DOUBLE",
"prevClosePrice": "DOUBLE",
"settlementPrice": "DOUBLE",
"prevSettlementPrice": "DOUBLE",
"underlyingPrice": "DOUBLE",
"Theta": "DOUBLE",
"Vega": "DOUBLE",
"Gamma": "DOUBLE",
"Delta": "DOUBLE",
"IV": "DOUBLE"
},
size=0,
capacity=10000000
)
Note:
The column names must exactly match the table below. Apart from the first column, which must be symbol, the order of other columns is not required.
Additionally, columns of type INT, DOUBLE, or STRING, or a DOUBLE ARRAY VECTOR column named signal, are supported as extension fields.
The required fields for the minute-level data table are as follows:
Field |
Type |
Description |
|---|---|---|
symbol |
SYMBOL |
option code |
symbolSource |
STRING |
exchange |
tradeTime |
TIMESTAMP |
timestamp |
tradingDay |
DATE |
trading day / settlement date |
open |
DOUBLE |
opening price |
low |
DOUBLE |
lowest price |
high |
DOUBLE |
highest price |
close |
DOUBLE |
closing price |
volume |
LONG |
trading volume |
amount |
DOUBLE |
transaction amount (required only in JIT mode) |
upLimitPrice |
DOUBLE |
upper limit price |
downLimitPrice |
DOUBLE |
lower limit price |
signal |
DOUBLE[] |
additional field list (required only in JIT mode) |
prevClosePrice |
DOUBLE |
previous closing price (required only in JIT mode) |
settlementPrice |
DOUBLE |
settlement price (required only in JIT mode) |
prevSettlementPrice |
DOUBLE |
previous settlement price (required only in JIT mode) |
underlyingPrice |
DOUBLE |
underlying asset price |
Theta |
DOUBLE |
/ |
Vega |
DOUBLE |
/ |
Gamma |
DOUBLE |
/ |
Delta |
DOUBLE |
/ |
IV |
DOUBLE |
/ |
When the backtest market data playback ends, send a message with symbol = “END”:
message_table = sf.sql(
"SELECT TOP 1 * FROM messageTable",
vars={
'messageTable': message_table
}
)
# demo for generating signal field
# sf.sql(
# "UPDATE messageTable SET signal = fixedLengthArrayVector([close])",
# vars={'messageTable': message_table, 'fixedLengthArrayVector': F.fixedLengthArrayVector}
# )
sf.sql(
"UPDATE messageTable SET symbol = `END",
vars={'messageTable': message_table}
)
backtester.append_data(message_table)
Callback Function#
OHLC callback function onBar: input parameter msg
When msg is a dictionary, it uses symbol as the key for minute-level snapshot data. Each bar contains the following fields:
Field |
Type |
Description |
|---|---|---|
symbol |
SYMBOL |
option code |
symbolSource |
STRING |
exchange |
tradeTime |
TIMESTAMP |
timestamp |
tradingDay |
DATE |
trading day / settlement date |
open |
DOUBLE |
opening price |
low |
DOUBLE |
lowest price |
high |
DOUBLE |
highest price |
close |
DOUBLE |
closing price |
volume |
LONG |
trading volume |
amount |
DOUBLE |
transaction amount |
upLimitPrice |
DOUBLE |
upper limit price |
downLimitPrice |
DOUBLE |
lower limit price |
signal |
DOUBLE[] |
additional field list (required only in JIT mode) |
prevClosePrice |
DOUBLE |
previous closing price (required only in JIT mode) |
settlementPrice |
DOUBLE |
settlement price (required only in JIT mode) |
prevSettlementPrice |
DOUBLE |
previous settlement price (required only in JIT mode) |
underlyingPrice |
DOUBLE |
underlying asset price |
Theta |
DOUBLE |
/ |
Vega |
DOUBLE |
/ |
Gamma |
DOUBLE |
/ |
Delta |
DOUBLE |
/ |
IV |
DOUBLE |
/ |