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.
Options:

  • 1: snapshot;
  • 3: minute-level;
  • 4: daily data.

frequency

bar frequency for snapshot data

INT type, default = 0. Applicable only when dataType = 1.

  • When frequency = 0, this parameter is ignored.
  • When dataType = 1 and frequency > 0, the engine internally calculates bars at the specified frequency and triggers the onBar callback.

msgAsTable

market data format

BOOL type, default = false.

  • false: dictionary format
  • true: table format (only supported when creating the engine via createBacktestEngine).

matchingMode

order matching mode

INT type, options:
1:

  • daily data: match at close
  • minute-level data: orders will be matched with market data whose time is later than the order time
2:
  • daily data: match at open.
  • minute-level data: match when data time = order time, using the close price
3:
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

  • true: enable;
  • false: disable.

enableIndicatorOptimize

enable indicator optimization

  • true: enable;
  • false (default): disable.

isBacktestMode

backtest mode flag

  • true (default): backtest mode;
  • false: simulated trading mode.

dataRetentionWindow

data retention policy for indicator optimization

STRING/INT type. Effective only when both enableIndicatorOptimize = true and isBacktestMode = true:

  • ”None”(default): Retain no data.
  • ”ALL”: Retain all data.
  • Retain data by trading days, e.g., “20d” retains 20 trading days.
  • Retain data by row count, e.g., “20” retains the latest 20 rows per symbol.

addTimeColumnInIndicator

add time column to indicator subscription results

  • false (default): omit time column
  • true: add time column

context

strategy context structure

A dictionary consisting of global strategy variables, for example:

context = {}
context[“buySignalRSI”] = 30.0
config[“context”] = context

callbackForSnapshot

snapshot callback mode

Available only for dataType=1. INT type, default 0.

  • 0: trigger onSnapshot only
  • 1: trigger both onSnapshot and onBar
  • 2: trigger onBar only
If 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 dataType = 1.

matchingRatio

matching ratio within price intervals

DOUBLE type, default 1.0, value range: 0–1.0. Applicable only when dataType = 1.

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:

  • 1: commodity option;
  • 2: stock index option;
  • 3: etf option

multiplier

DOUBLE

contract multiplier.

type

INT

option type:

  • 1: call;
  • 2: put.

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:

  • 1: commission × number of contracts traded
  • 2: commission × trade value.

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 ≥ exDate, use adjStrikePrice and adjMultiplier.

adjStrikePrice

DOUBLE

adjusted strike price (used when trading date ≥ exDate).

adjMultiplier

DOUBLE

adjusted contract multiplier (used when trading date ≥ exDate).

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 named signal are 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 > 0 and callbackForSnapshot = 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 named signal are 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 dataType = 1 or 2 and callbackForSnapshot = 1 or 2)

close

DOUBLE

close price of synthesized bar (available only when dataType = 1 or 2 and callbackForSnapshot = 1 or 2)

low

DOUBLE

lowest price of synthesized bar (available only when dataType = 1 or 2 and callbackForSnapshot = 1 or 2)

high

DOUBLE

highest price of synthesized bar (available only when dataType = 1 or 2 and callbackForSnapshot = 1 or 2)

volume

LONG

trading volume of synthesized bar (available only when dataType = 1 or 2 and callbackForSnapshot = 1 or 2)

Note:

  • When snapshot bars are synthesized (frequency > 0 and callbackForSnapshot = 1 or 2), five additional fields "open", "close", "low", "high", and "volume" must be included in msg.

  • When callbackForSnapshot = 1 or 2, the onBar callback function will also be triggered. the structure of its msg parameter 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

/