Cryptocurrency Backtesting Configurations

DolphinDB’s backtesting plugin supports cryptocurrency market data across multiple frequencies, including snapshot, minute-level, and daily data.

The backtesting engine supports managing multiple spot and futures accounts within a single engine for cryptocurrency. The multi-account design:

  1. The market data can include different contract types. The onBar callback provides all data for all contract types within the specified period at once, making it easier to design strategies based on market conditions across different contracts.
  2. Backtesting cryptocurrency supports an optional accountType parameter to specify the account to operate on. If accountType is not specified, the interface used in the strategy (such as placing or canceling orders, getting unfilled orders, checking positions, etc.) defaults to the spot account. Interfaces called after backtesting (such as trade details, daily positions, etc.) return results for all accounts by default.

1. Engine Configurations

Configurations for config in the createBacktester interface and userConfig in the 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 group Must be "cryptocurrency"
"cash"

Initial cash flow (of dictionary form) for each account

{

"spot": 100000.

"futures": 100000.

"option": 100000.

}

DOUBLE type, required.

  • spot: spot account

  • futures: futures and perpetual futures account

  • option: options account

"dataType" Market data type

INT type, required. It can be:

  • 1: snapshot

  • 3: minute-level data

  • 4: daily data

"msgAsTable" Process the input market data as a table or dictionary

BOOL type.

  • false (default): dictionary

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

"matchingMode" Matching mode

INT type.

Daily data:

  • 1: matching with the closing price.
  • 2: matching with the open price.

Minute-level data:

  • 1: matching when market time > order time.
  • 2: matching with the closing price when market time = order time; matching unfilled orders with mode 1.

Snapshot data:

  • Matching with the order price.
"benchmark" Benchmark instrument STRING or SYMBOL type, used in getReturnSummary (e.g., "BTCUSDT_0").
"latency" The latency from order submission to execution DOUBLE type, in milliseconds. Defaults to 0, indicating no latency.
"fundingRate" Funding rate Accepts a table. For a detailed schema, see the table below.
"enableIndicatorOptimize" Whether to enable indicator calculation optimization

BOOL type.

  • true: enable
  • false (default): disable
"addTimeColumnInIndicator" Whether to add a time column to the indicator subscription results

BOOL type.

  • true: add time column

  • false (default): omit time column

"isBacktestMode" Backtesting or matching mode

BOOL type.

  • true (default): backtesting

  • false: matching

"dataRetentionWindow" Data retention policy for indicator optimization

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

  • "ALL": Retain all data.

  • "None" (default): Retain no 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.

"context" Strategy context structure

A dictionary consisting of global strategy variables, for example:

context=dict(STRING,ANY)
context["buySignalRSI"]=70.
context["buySignalRSI"]=30. 
userConfig["context"]=context
"orderBookMatchingRatio" The proportion of an order that gets filled

Effective when "dataType" = 1 or 2.

DOUBLE type, default is 1.0, valid range: [0-1.0].

"matchingRatio" The matching ratio within price intervals

Effective when “dataType” = 1 or 2.

DOUBLE type, valid range: [0-1.0]. By default, it equals the "orderBookMatchingRatio".

"msgAs​PiecesOnSnapshot" Whether each data record triggers the onSnapshot callback in sequence, or all records with the same timestamp trigger it at the same time

BOOL type.

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

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

Figure 1. Table 1-1 Engine Configurations

Note that the engine configuration parameters vary for different types of cryptocurrency market data. The "orderBookMatchingRatio" and "matchingRatio" keys are only effective when the market data type is snapshot (i.e., dataType = 1 or 2).

Field Data Type Note
symbol STRING or SYMBOL Instrument symbol
settlementTime TIMESTAMP Settlement time
lastFundingRate DECIMAL128(8) Funding rate at settlement
markPrice DECIMAL128(8)

Mark price at settlement, used to calculate the funding rate payment amount:

  • If it exists and is greater than 0, the system settles the rate using this price.

  • If it is empty or less than or equal to 0, the system settles the rate using the latest market price.

Figure 2. Table 1-2 Schema of "fundingRate"

Schema of securityReference

Fields of the securityReference parameter in the createBacktester and createBacktestEngine interfaces:

Field Data Type Description
symbol SYMBOL or STRING Instrument symbol
contractType INT

Contract type:

  • 0: spot

  • 1: delivery futures

  • 2: perpetual futures

  • 3: options

optType INT

Options type:

  • 1: call

  • 2: put

strikePrice DECIMAL128(8) Strike price
contractSize DECIMAL128(8) Contract multiplier
marginRatio DECIMAL128(8) Margin ratio
tradeUnit DECIMAL128(8) Trade unit
priceUnit DECIMAL128(8) Price unit
priceTick DECIMAL128(8) Price tick
takerRate DECIMAL128(8) Taker fee rate
makerRate DECIMAL128(8) Maker fee rate
deliveryCommissionMode INT

Specifies how the transaction fee is calculated when a trade is executed:

  • 1: makerRate (or takerRate) per lot

  • 2: Trade value × makerRate (or takerRate)

fundingSettlementMode INT

Defines how the funding fee is settled between long and short positions for perpetual futures:

  • 1: lastFundingRate per lot

  • 2: Notional value × lastFundingRate

lastTradeTime TIMESTAMP Last trade time
Figure 3. Table 1-3 Schema of securityReference
Note:
  • The calculation of trading costs depends on parameters configured in the table above for each contract, such as margin ratio, fee rates, price units, etc. Since different contracts may have different trading rules and fee standards, the required parameters must be configured individually for each contract.
  • For perpetual futures (contractType = 2), funding fees must be settled periodically while holding a position. The settlement method is defined by the fundingSettlementMode field, while the actual funding rate (e.g., lastFundingRate) should be retrieved from a separately configured funding rate table for perpetual futures.

2. Snapshot

2.1 Schema of Snapshot Data

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

colName=["symbol","symbolSource","timestamp","tradingDay","lastPrice","upLimitPrice",
        "downLimitPrice","totalBidQty","totalOfferQty","bidPrice","bidQty","offerPrice",
        "offerQty","highPrice","lowPrice","prevClosePrice","settlementPrice",
        "prevSettlementPrice","contractType"]
colType= ["STRING","STRING","TIMESTAMP","DATE","DECIMAL128(8)","DECIMAL128(8)","DECIMAL128(8)","DECIMAL128(8)","DECIMAL128(8)",
        "DECIMAL128(8)[]","DECIMAL128(8)[]","DECIMAL128(8)[]","DECIMAL128(8)[]","DECIMAL128(8)","DECIMAL128(8)",
        "DECIMAL128(8)","DECIMAL128(8)","DECIMAL128(8)","INT"]
messageTable=table(10000000:0, colName, colType)
Field Data type Description
symbol STRING Instrument symbol
symbolSource STRING Exchange
timestamp TIMESTAMP Timestamp
tradingDay DATE Trading day / settlement date
lastPrice DECIMAL128(8) Last price
upLimitPrice DECIMAL128(8) Limit up price
downLimitPrice DECIMAL128(8) Limit down price
totalBidQty DECIMAL128(8) Total bid volume
totalOfferQty DECIMAL128(8) Total ask volume
bidPrice DECIMAL128(8)[] Bid price
bidQty DECIMAL128(8)[] Bid volume
offerPrice DECIMAL128(8)[] Ask price
offerQty DECIMAL128(8)[] Ask volume
highPrice DECIMAL128(8) High price
lowPrice DECIMAL128(8) Low price
signal DOUBLE[] A list of user-defined field(s)
prevClosePrice DECIMAL128(8) Previous closing price
settlementPrice DECIMAL128(8) Settlement price
prevSettlementPrice DECIMAL128(8) Previous settlement price
contractType INT

Contract type:

  • 0: spot

  • 1: delivery futures

  • 2: perpetual futures

  • 3: option

Figure 4. Table 2-1 Schema of Snapshot Data

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 where tradeTime=max(tradeTime)
update messageTable set symbol="END"
update messageTable set tradeTime=concatDateTime(tradeTime.date(),16:00:00)
Backtest::appendQuotationMsg(engine,messageTable)

2.2 Snapshot Callback Function onSnapshot

Snapshot callback function onSnapshot: input the msg parameter.

msg is a dictionary. Each key represents a symbol, and the corresponding value contains snapshot data for that symbol. Each snapshot data contains the following fields:

Field Data type Description
symbol STRING Instrument symbol
symbolSource STRING Exchange
timestamp TIMESTAMP Timestamp
tradingDay DATE Trading day / settlement date
lastPrice DECIMAL128(8) Last price
upLimitPrice DECIMAL128(8) Limit up price
downLimitPrice DECIMAL128(8) Limit down price
totalBidQty DECIMAL128(8) Total bid volume
totalOfferQty DECIMAL128(8) Total ask volume
bidPrice DECIMAL128(8)[] Bid price
bidQty DECIMAL128(8)[] Bid volume
offerPrice DECIMAL128(8)[] Ask price
offerQty DECIMAL128(8)[] Ask volume
highPrice DECIMAL128(8) High price
lowPrice DECIMAL128(8) Low price
signal DOUBLE[] A list of user-defined field(s)
prevClosePrice DECIMAL128(8) Previous closing price
settlementPrice DECIMAL128(8) Settlement price
prevSettlementPrice DECIMAL128(8) Previous settlement price
contractType INT

Contract type:

  • 0: spot

  • 1: delivery futures

  • 2: perpetual futures

  • 3: option

Figure 5. Table 2-2 Schema of Snapshot Data

3. Minute-Level and Daily Frequency

3.1 Schema of Minute-Level and Daily Market Data

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

colName=[`symbol,`symbolSource,`tradeTime,`tradingDay,`open,`low,`high,`close,`volume,`amount,`upLimitPrice,
        `downLimitPrice,`prevClosePrice,`settlementPrice,`prevSettlementPrice,`contractType]
colType=[SYMBOL,SYMBOL,TIMESTAMP,DATE,DECIMAL128(8),DECIMAL128(8),DECIMAL128(8),DECIMAL128(8),DECIMAL128(8),
DECIMAL128(8),DECIMAL128(8),DECIMAL128(8),DECIMAL128(8),DECIMAL128(8),DECIMAL128(8),INT]
messageTable=table(10000000:0, colName, colType)
Field Data type Description
symbol SYMBOL Instrument symbol
symbolSource SYMBOL Exchange
tradeTime TIMESTAMP Timestamp
tradingDay DATE Trading day / settlement date
open DECIMAL128(8) Opening price
low DECIMAL128(8) Low price
high DECIMAL128(8) High price
close DECIMAL128(8) Closing price
volume DECIMAL128(8) Trading volume
amount DECIMAL128(8) Trading value
upLimitPrice DECIMAL128(8) Limit up price
downLimitPrice DECIMAL128(8) Limit down price
signal DOUBLE[] A list of user-defined field(s)
prevClosePrice DECIMAL128(8) Previous closing price
settlementPrice DECIMAL128(8) Settlement price
prevSettlementPrice DECIMAL128(8) Previous settlement price
contractType INT

Contract type:

  • 0: spot

  • 1: delivery futures

  • 2: perpetual futures

  • 3: option

Figure 6. Table 3-1 Schema of Minute-Level and Daily Market Data

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 where tradeTime=max(tradeTime)
update messageTable set symbol="END"
update messageTable set tradeTime=concatDateTime(tradeTime.date(),16:00:00)
Backtest::appendQuotationMsg(engine,messageTable)

3.2 OHLC Callback Function onBar

OHLC callback function onBar: sinput the msg parameter.

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

Field Data type Description
symbol SYMBOL Instrument symbol
symbolSource SYMBOL Exchange
tradeTime TIMESTAMP Timestamp
tradingDay DATE Trading day / settlement date
open DECIMAL128(8) Opening price
low DECIMAL128(8) Low price
high DECIMAL128(8) High price
close DECIMAL128(8) Closing price
volume DECIMAL128(8) Trading volume
amount DECIMAL128(8) Trading value
upLimitPrice DECIMAL128(8) Limit up price
downLimitPrice DECIMAL128(8) Limit down price
signal DOUBLE[] A list of user-defined field(s)
prevClosePrice DECIMAL128(8) Previous closing price
settlementPrice DECIMAL128(8) Settlement price
prevSettlementPrice DECIMAL128(8) Previous settlement price
contractType INT

Contract type:

  • 0: spot

  • 1: delivery futures

  • 2: perpetual futures

  • 3: option

Figure 7. Table 3-2 Schema of OHLC Data