Backtest

为精准测试和验证策略在实盘交易中的效果,DolphinDB 基于分布式存储和计算、多范式的编程语言和模拟撮合引擎插件,推出了事件型回测引擎,该引擎以插件的形式提供服务,其逻辑架构如图 1-1 所示。

1. 图 1-1 回测引擎架构图

回测引擎的主要工作流程如下:

  • 接收按时间顺序回放的行情数据流,内部将数据分发至模拟撮合引擎和对应的行情回调函数。

  • 行情回调函数处理策略逻辑并提交委托订单。

  • 回测引擎根据策略生成的委托订单执行风控管理。

  • 通过风控审核的订单会发送至模拟撮合引擎进行撮合处理。

  • 回测引擎根据成交情况实时更新持仓和资金管理。

  • 回测结束后返回策略的收益、成交明细等结果。

用户在使用回测引擎时,通常完成需要以下步骤,如图 1-2 所示:

2. 图 1-2 回测引擎使用流程
  • 在策略初始化中定义指标,并在各回调函数中编写自定义策略逻辑。

  • 配置策略的行情源、资金情况、订单延时和成交比例等参数。

  • 创建回测引擎。

  • 回放数据源并执行策略回测。

  • 获取回测结果,包括收益分析、成交明细等。

回测引擎插件支持多资产策略回测,涵盖股票、期权、期货、数字货币以及银行间债券。针对不同的资产类型和行情特征,回测引擎在配置、行情数据结构、回调函数输入参数及接口设计上均有所不同。本页面将重点介绍引擎接口,有关引擎配置、行情数据结构、策略函数说明、示例等方面内容,请至对应资产页面查看详细说明:股票、期权、期货、数字货币、银行间债券。

安装插件

版本要求

DolphinDB Server 2.00.14 和 3.00.2 及更高版本,支持 X86-64 的 Linux 和 Windows。

安装步骤

  1. 在 DolphinDB 客户端中使用 listRemotePlugins 命令查看插件仓库中的插件信息。

    注意:仅展示当前操作系统和 server 版本支持的插件。若无预期插件,可在 DolphinDB 用户社区进行反馈。

    login("admin", "123456")
    listRemotePlugins()
  2. 使用 installPlugin 命令完成插件安装。

    installPlugin("Backtest")
  3. 使用 loadPlugin 命令加载插件。

    loadPlugin("Backtest")

插件依赖

回测引擎插件内部依赖模拟撮合引擎插件,因此加载回测引擎之前需要先加载模拟撮合引擎,该插件同样可以通过插件市场安装。

  1. 使用 installPlugin 命令完成模拟撮合引擎插件安装。

    installPlugin("MatchingEngineSimulator")
  2. 使用 loadPlugin 命令加载模拟撮合引擎插件。

    loadPlugin("MatchingEngineSimulator")

引擎配置说明

创建回测引擎时,需要设置引擎的配置项(接口 createBacktester 的参数 config 或接口 createBacktestEngine 的参数 userConfig)。根据回测的资产和及所使用的行情类型的不同,配置项也有所区别。具体请参考对应资产页面。

行情数据结构说明

当行情数据作为参数 msg,通过接口 appendQuotationMsg 向引擎中插入数据时,根据回测的资产和及所使用的行情类型的不同,行情数据结构也有所区别。具体请参考对应资产页面。

策略回调函数说明

回测引擎采用事件驱动机制,提供多种事件函数,包括策略初始化、每日盘前与盘后回调、逐笔、快照和 K 线行情的回调,以及委托和成交回报函数。用户可以在策略初始化中定义指标,并在其他相应的回调函数中编写自定义策略。

回测引擎提供的事件函数如下表所示:

事件函数 说明
def initialize(mutable context){}

策略初始化函数,只触发一次。

参数 context 为逻辑上下文。可以在该函数中通过 context 参数初始化一些全局变量,或者进行策略订阅指标计算。

def beforeTrading(mutable context){}
盘前回调函数,每日盘前触发一次。可以在该函数中执行当日启动前的准备工作,如订阅行情等。
def onTick(mutable context, msg,indicator){}
逐笔行情回调函数,逐笔委托和逐笔成交行情更新时触发。
def onSnapshot(mutable context, msg,indicator){}
快照行情回调函数。
def onBar(mutable context, msg,indicator){}
中低频行情回调函数。
def onOrder(mutable context,orders){}
委托回报回调函数,每个订单状态发生变化时触发。
def onTrade(mutable context,trades){}
成交回报回调函数,发生成交时触发。
def afterTrading(mutable context){}
策略每日盘后的回调函数,每日盘后触发一次。可以在该函数统计当日的成交、持仓等信息。
def finalize(mutable context){}
策略结束之前回调一次该函数。

context 一个字典,用于设置策略的所有自定义变量。此外,引擎内部维护了 4 个变量:

  • context.tradeTime 获取行情的最新时间

  • context.tradeDate 获取当前日期

  • context.BarTime 快照降频为低频行情时的当前Bar 时间戳

  • context.engine 获取回测引擎实例

indicator 表示策略中订阅的指标,其数据形式由引擎配置中 msgAsTable 决定。

msg 表示行情数据,其数据形式由引擎配置中 msgAsTable 决定。

orders 一个字典,表示订单信息。

trades 一个字典,表示成交订单信息。

注:

msgorderstrades 根据回测的资产和及所使用的行情类型的不同,键值、字段也有所区别,具体请参考对应资产页面。

引擎接口说明

本节将介绍 DolphinDB 的回测引擎接口。用户可以基于自定义的策略创建回测引擎并执行回测,获取每日持仓、每日权益、收益概述、成交明细等回测结果。

createBacktester

语法

Backtest::createBacktester(name, config, eventCallbacks, [jit=false], [securityReference])

详情

创建回测引擎,同时设置所有的回调函数。该接口仅支持股票、期货、期权。

返回创建的回测引擎句柄。

参数

name STRING 类型标量,表示回测引擎名称。

config 一个字典,表示回测引擎的配置项。字典的 key 是 STRING 类型,代表配置项的名称,value 是该配置项的具体配置。

eventCallbacks 一个字典,表示策略回调函数。字典的 key 是 STRING 类型,代表回调函数,value 为对应函数的定义。key 的可选值为:
  • "initialize" 策略初始化回调函数,回测开始时触发调用。

  • "beforeTrading" 每日盘前回调函数,每日开盘前触发调用。

  • "onTick" 逐笔行情回调函数,可选参数。订阅逐笔行情时触发调用。

  • "onSnapshot" 快照行情回调函数,订阅快照行情时触发调用。

  • "onBar" 逐笔行情回调函数,可选参数。订阅快照行情时触发调用。

  • "onOrder" 委托回报通知函数,订单变更时触发调用。

  • "onTrade" 成交回报通知函数,订单交易时触发调用。

  • "afterTrading" 每日盘后回调函数,每日收盘时触发调用。

  • "finalize" 策略结束回调函数,回测结束时会触发调用。

上述回调函数中,onTick, onBar, onSnapshot 的触发条件如下,使用时应根据 config 参数的配置,指定对应的回调函数,无需全部指定:
输入数据类型 frequency 参数设置 可触发的函数
dataType=0 frequency=0 onTick
frequency>0 onTick, onSnapshot
dataType=1或2 frequency=0 onSnapshot
frequency>0 onSnapshot, onBar

jit BOOL 类型标量,表示是否开启 JIT 优化。默认值为 false,表示不开启。

securityReference 合约的基本信息表。对期货、期权、数字货币回测时为必选参数,其他资产为可选参数。

createBacktestEngine

注:

此接口为 createBacktester 的旧版本接口。

语法

Backtest::createBacktestEngine(name, userConfig, [basicInfo], initialize, beforeTrading, onTick/onBar, onSnapshot, onOrder, onTrade, afterTrading, finalize)

详情

创建回测引擎,同时设置所有的回调函数。此接口为 createBacktester 的旧版本接口,适用于所有资产。

返回创建的回测引擎句柄。

参数

name STRING 类型标量,表示回测引擎名称。

userConfig 一个字典,表示回测引擎的配置项。key 是 STRING 类型,代表配置项的名称,value 是该配置项的具体配置。详情请参考

basicInfo 基础信息表,资产为期货时为必选参数,其他资产为可选参数。

initialize 初始化回调函数,回测开始时触发调用。

beforeTrading 每日盘前回调函数,每日开盘前触发调用。

onTick/onBar 逐笔/快照行情回调函数,可选参数,订阅逐笔/快照行情时触发调用。

onSnapshot 快照行情回调函数,订阅快照行情时触发调用。

onOrder 委托回报通知函数,订单变更时触发调用。

onTrade 成交回报通知函数,订单交易时触发调用。

afterTrading 每日盘后回调函数,每日收盘时触发调用。

finalize 策略结束回调函数,回测结束时会触发调用。

上述回调函数中,onTick, onBar, onSnapshot 的触发条件如下,使用时应根据 userConfig 参数的配置,指定对应的回调函数,无需全部指定:
输入数据类型 frequency 参数设置 可触发的函数
dataType=0 frequency=0 onTick
frequency>0 onTick, onSnapshot
dataType=1 或 2 frequency=0 onSnapshot
frequency>0 onSnapshot, onBar

appendQuotationMsg

语法

Backtest::appendQuotationMsg(engine, msg)

详情

插入行情执行策略回测。

参数

engine 回测引擎句柄。

msg 行情输入表,表结构请参考行情数据结构说明

subscribeIndicator

语法

Backtest::subscribeIndicator(engine, type, metrics)

详情

设置订阅的行情指标。

参数

engine 回测引擎句柄。

type STRING 类型标量,表示要订阅指标的行情类型,可选值为:

  • "snapshot" 快照。

  • "tick" 逐笔。

  • "kline" K 线。

  • "trade" 逐笔成交明细。

  • "snapshot_kline" 快照合成的 K 线。

metrics 一个字典,key 是 STRING 类型,代表指标名;value 是以元代码的形式表示计算公式,代表如何计算指标。状态因子的编写请参考 DolphinDB 响应式状态引擎介绍教程

示例

d=dict(STRING,ANY)
d["mavg"]=<mavg(lastPrice,20)>
Backtest::subscribeIndicator(contextDict["engine"], "snapshot", d) 
Backtest::subscribeIndicator(contextDict["engine"], "tick", d)
d=dict(STRING,ANY)
d["mavg"]=<mavg(trade,20)>
Backtest::subscribeIndicator(contextDict["engine"], "trade", d) 
d=dict(STRING,ANY)
d["mavg"]=<mavg(clsoe,20)>
Backtest::subscribeIndicator(contextDict["engine"], "kline", d)

setUniverse

语法

Backtest::setUniverse(engine, symbolList)

详情

为引擎设置标的池。

参数

engine 回测引擎句柄。

symbolList STRING 类型向量,表示标的。

dropBacktestEngine

语法

Backtest::dropBacktestEngine(engine)

详情

删除回测引擎。

参数

engine 回测引擎句柄。

getTradeDetails

语法

Backtest::getTradeDetails(engine)

参数

engine 回测引擎句柄。

详情

获取交易明细表,表结构如下:

字段 含义
orderId 订单号
symbol 证券代码
direction 订单委托买卖标志

1:买开;2:卖开;3:卖平;4:买平

sendTime 订单委托时间
orderPrice 订单委托价格
orderQty 订单委托数量
tradeTime 订单成交时间
tradePrice 成交价格
tradeQty 成交数量
orderStatus

表示订单状态:

4:已报

2:撤单成功

1:已成

0:部成

-1:审批拒绝

-2:撤单拒绝

-3:未成交的订单

label

标签

getAvailableCash

语法

Backtest::getAvailableCash(engine)

详情

查询账户可用现金。

参数

engine 回测引擎句柄。

getDailyPosition

语法

Backtest::getDailyPosition(engine, symbollist=[])

参数

engine 回测引擎句柄。

symbollist STRING 类型向量,可选参数,表示要获取的标的列表。默认为空,此时获取所有标的的持仓数据。

详情

通常在回测结束调用,返回每日盘后的持仓数据详情。盘中调用会丢失当日信息,返回前一天的持仓数据。

当资产为股票、期货、期权时,持仓数据详情表结构如下:

字段 含义
symbol 标的代码
tradeDate 交易日
lastDayLongPosition 昨日买持仓
lastDayShortPosition 昨日卖持仓
longPosition 买持仓量
longPositionAvgPrice 买成交均价
shortPosition 卖持仓量
shortPositionAvgPrice 卖成交均价
todayBuyVolume 当日买成交数量
todayBuyValue 当日买成交金额
todaySellVolume 当日卖成交数量
todaySellValue 当日卖成交金额

当为融资融券模式时,持仓数据详情表结构如下:

字段 名称
symbol 标的代码
tradeDate 交易日
lastDayMarginSecuPosition 昨日担保品买入持仓量
lastDayMarginDebt 昨日收盘融资负债
lastDaySecuLendingDebt 昨日收盘融券负债
marginSecuPosition 担保品买入持仓量
marginSecuAvgPrice 买持仓均价
marginBuyPosition 融资买入持仓量
marginBuyValue 融资买入金额
secuLendingPosition 融券卖出持仓量
secuLendingSellValue 融券卖出金额
closePrice 收盘价
longPositionConcentration 多头集中度
shortPositionConcentration 净空头集中度
marginBuyProfit 融资盈亏
financialFee 融资利息
secuLendingProfit 融券盈亏
secuLendingFee 融券费用

setTradingOutput

语法

Backtest::setTradingOutput(engine,indicator,position,totalPortfolios,tradeDetails,dailyPosition,dailyTotalPortfolios)

参数

engine 回测引擎句柄。

indicator 一个表,用于实时接收策略指标,其表结构可通过 getIndicatorSchema 获取。

position 一个表,用于实时更新持仓信息,其表结构可通过 getPosition 获取。

totalPortfolios 一个表,用于实时获取账户权益,其表结构可通过 getTotalPortfolios 获取。

tradeDetails 一个表,用于实时获取成交明细,其表结构可通过 getTradeDetails 获取。

dailyPosition 一个表,用于实时获取每日持仓,其表结构可通过 getTradeDetails 获取。

dailyTotalPortfolios 一个表,用于实时获取账户每日权益,其表结构可通过 getDailyTotalPortfolios 获取。

详情

为回测引擎设置实时输出表,信息将实时写入对应的表。

getIndicatorSchema

语法

Backtest::getIndicatorSchema(engine)

参数

engine 回测引擎句柄。

详情

返回一张策略指标空表,表结构如下:
列名 数据类型 说明
symbol SYMBOL 标的代码
timestamp TIMESTAMP 时间戳
订阅的指标名称 DOUBLE 订阅的指标

getTotalPortfolios

语法

Backtest::getTotalPortfolios(engine)

参数

engine 回测引擎句柄。

详情

获取当前策略权益指标表。表结构如下:
  • 股票,融资融券:
    字段名称 字段说明
    tradeDate 日期
    cash 可用资金
    totalMarketValue 账户总市值
    totalEquity 账户总权益
    netValue 账户单位净值
    totalReturn 截至当日的累计收益率
    ratio 账户每日收益率
    pnl 账户当日盈亏
  • 期货和期权:
    字段名称 字段说明
    tradeDate 日期
    margin 保证金占用
    floatingPnl 浮动盈亏
    realizedPnl 已实现累计盈亏
    totalPnl 累计盈亏
    cash 可用资金
    totalEquity 账户总权益
    marginRatio 保证金占用比例
    pnl 账户当日盈亏
    netValue 账户单位净值
    totalReturn 截至当日的累计收益率
    ratio 账户每日收益率

getDailyTotalPortfolios

语法

Backtest::getDailyTotalPortfolios(engine)

参数

engine 回测引擎句柄。

详情

通常在回测结束调用,获取策略每日权益指标表。回测的资产不同,返回表的结构也有所差异:
  • 股票:

    字段名称 字段说明
    tradeDate 日期
    cash 可用资金
    totalMarketValue 账户总市值
    totalEquity 账户总权益
    netValue 账户单位净值
    totalReturn 截至当日的累计收益率
    ratio 账户每日收益率
    pnl 账户当日盈亏
  • 融资融券:

    字段名称 字段说明
    tradeDate 日期
    lineOfCredit 授信额度
    availableCash 可用资金
    lastDayMarginDebt 昨日收盘融资负债
    lastDaySecuLendingDebt 昨日收盘融券负债
    marginSecuMarketValue 担保品买入市值
    marginDebt 融资负债
    secuLendingSellValue 融券卖出金额(融券负债)
    marginBalance 融资融券余额
    secuLendingDebt 融券负债
    financialFee 融资利息
    secuLendingFee 融券费用
    maintainanceMargin 维保比例
    availableMarginBalance 保证金可用余额
    totalMarketValue 账户总市值
    totalEquity 账户总权益
    netValue 账户单位净值
    totalReturn 截至当日的累计收益率
    yield 账户每日收益率
    pnl 账户当日盈亏
  • 期货/期权:
    字段名称 字段说明
    tradeDate 日期
    margin 保证金占用
    floatingPnl 浮动盈亏
    realizedPnl 已实现累计盈亏
    totalPnl 累计盈亏
    cash 可用资金
    totalEquity 账户总权益
    marginRatio 保证金占用比例
    pnl 账户当日盈亏
    netValue 账户单位净值
    totalReturn 截至当日的累计收益率
    ratio 账户每日收益率

getReturnSummary

语法

Backtest::getReturnSummary(engine)

参数

engine 回测引擎句柄。

详情

用于回测结束时计算策略的收益概述,返回一张收益概述表。收益表结构如下:

  • 股票/期货/期权:
    字段名称 字段说明
    totalReturn 总收益
    annualReturn 年化收益率
    annualVolatility 年化波动率
    annualSkew 收益率偏度
    annualKur 收益率峰度
    sharpeRatio 夏普率
    maxDrawdown 最大回撤
    drawdownRatio 收益回撤比
    beta beta系数
    alpha a系数
    benchmarkReturn 基准收益
    annualExcessReturn 年化超额收益
    turnoverRate 换手率
    dailyWinningRate 日胜率
    maxMarginRatio 策略最大保证金占用比例(期货期权独有字段)
  • 融资融券模式,返回的收益表除上述字段外 ,还包含以下字段:

    字段名称

    字段说明

    totalFee 佣金与手续费之和
    financialFee 融资利息
    secuLendingFee 融券费用
    bottomRet 底仓收益
    bottomExcessRet 底仓超额收益

getBacktestEngineList

语法

Backtest::getBacktestEngineList()

详情

获取所有的回测引擎。

getContextDict

语法

Backtest::getContextDict(engine)

参数

engine 回测引擎句柄。

详情

返回逻辑上下文。

setSecurityReferenceData

语法

Backtest::setSecurityReferenceData(engine, securityReferenceData)

参数

engine 回测引擎句柄。

securityReferenceData 该品种对应的基础信息表。

详情

设置基本信息表。

getTodayPnl

语法

Backtest::getTodayPnl(engine, symbol)

参数

engine 回测引擎句柄。

symbol STRING 类型标量,表示股票标的。

详情

该接口仅可用于股票,获取账户盈亏。

返回一个字典,结构如下:
key value
symbol 标的代码
pnl 当前账户中该标的的盈亏金额
todayPnl 当日账户中该标的的盈亏金额

submitOrder

语法

Backtest::submitOrder(engine, msg, label="", orderType=0)

详情

可在回调函数中调用此函数提交订单。

参数

engine 回测引擎句柄,在回调函数中可通过 contextDict["engine"] 获取。

msg 一个元组,表示订单信息。

  • orderType=0 时,格式如下:
    品种 格式 说明
    沪深交易所标的 (股票代码, 下单时间, 订单类型, 订单价格, 订单数量, 买卖方向)

    买卖方向:1:买开;2卖开;3:卖平;4:买平

    订单类型:

    上交所:

    0:市价单中最优五档即时成交剩余撤销委托订单

    1:市价单中最优五档即时成交剩余转限价委托订单

    2:市价单中本方最优价格委托订单

    3:市价单中对手方最优价格委托订单

    5:限价单

    6:撤单

    深交所:

    0:市价单中最优五档即时成交剩余撤销委托订单

    1:市价单中即时成交剩余撤销委托订单

    2:市价单中本方最优价格委托订单

    3: 市价单中对手方最优价格委托订单

    4:市价单中全额成交或撤销委托订单

    5:限价单

    6:撤单

    期货/期权 (标的代码, 交易所代码, 时间, 订单类型, 委托订单价格, 止损价/止盈价,委托订单数量,买卖方向,委托订单有效性)

    买卖方向:1:买开;2卖开;3:卖平;4:买平

    订单类型:

    5:限价单(默认值)

    6:撤单

    0:市价单,以涨跌停价委托,并遵循时间优先原则

    委托订单有效性:

    0:当日有效(默认值)

    1:立即全部成交否则自动撤销(FOK)

    2:立即成交剩余自动撤销(FAK)

    止损价/止盈价暂不支持,默认 0.

    融资融券 (股票代码、下单时间、订单类型、订单价格、订单数量、买卖标志)

    订单类型:

    0:市价单

    5:限价单

    买卖标志:

    1:担保品买入

    2:担保品卖出

    3:融资买入

    4:融券卖出

    5:直接还款

    6:卖券还款

    7:直接还券

    8:买券还券

    银行间债券 (标的代码,下单时间,订单类型,清算速度,委托买单到期收益率,委托买单订单价格,委托买订单数量,委托卖单到期收益率,委托卖单订单价格,委托卖订单数量,买卖标志,用户订单ID,撮合渠道)

    订单类型:

    1:限价单

    2:双边报价

    3 : 市价单转撤单

    4:市价单转限单

    5:弹性

    6:撤单

    数字货币 (标的代码, 交易所代码, 时间, 订单类型, 委托订单价格, 止损价,止盈价,委托订单数量,买卖方向,滑点,委托订单有效性,委托订单到期时间)

    买卖方向:1:买开;2卖开;3:卖平;4:买平

    订单类型:

    5:限价单(默认值)

    0:市价单,以涨跌停价委托,并遵循时间优先原则

    1:市价止损单

    2:市价止盈单

    3:限价止损单

    4:限价止盈单

    委托订单有效性:

    0:当日有效(默认值)

    1:立即全部成交否则自动撤销(FOK)

    2:立即成交剩余自动撤销(FAK)

  • orderType>0 时,格式为 (期货代码, 交易所代码, 时间, 订单类型, 委托订单价格, 止损价,止盈价,委托订单数量,买卖方向,滑点,委托订单有效性,委托订单到期时间)

label STRING 类型标量,对该订单设置标签,对该订单分类。

orderType INT 类型标量,可选值如下:
  • 0 :默认值,表示一般订单

  • 1:现价止盈订单

  • 2:市价止盈订单

  • 3:限价止损订单

  • 4:市价止损订单

  • 5:限价止盈止损订单

  • 6:市价止盈止损订单

其中 1-6 为算法订单,仅支持期货,可通过配置项 openAlgoOrder 开启。

cancelOrder

语法

Backtest::cancelOrder(engine, symbol="", orders=NULL, label="")

详情

取消订单。
  • symbol 不为空,则取消该标的的所有订单。

  • symbol 为空,orders 不为空,则取消 orders 中的订单。

  • symbol 为空,orders 为空,则取消 label 指定的订单。

参数

engine 回测引擎句柄,在回调函数中可通过 contextDict["engine"] 获取。

symbol SYMBOL 类型标量,要取消的订单的证券代码,可选参数。

orders DOUBLE 类型向量,要取消的订单 ID 列表,可选参数。

label STRING 类型标量,要取消的订单的备注信息。

getOpenOrders

语法

Backtest::getOpenOrders(engine, symbol=NULL, orders=NULL, label="", outputQueuePosition=false)

参数

engine 回测引擎句柄,在回调函数中可通过 contextDict["engine"] 获取。

symbol SYMBOL 类型标量,证券代码,可选参数。

orders DOUBLE 类型向量,订单 ID 列表,可选参数。

label STRING 类型标量,用作备注,可选参数。

outputQueuePosition BOOL 类型标量,是否输出详细信息(包括 openVolumeWithBetterPrice, openVolumeWithWorsePrice, openVolumeAtOrderPrice, priorOpenVolumeAtOrderPrice, depthWithBetterPrice)。可选参数,默认为 false,表示不输出。

详情

查询未成交订单。
  • symbol 不为空,则查询该标的的未成交订单。

  • symbol 为空,orders 不为空,则查询 orders 中未成交的订单。

  • symbol 为空,orders 为空,则查询 label 指定的未成交订单。

查询未成交订单信息。返回一个字典,结构如下:

key value 类型 value 说明
orderId LONG 订单 ID
timestamp TIMESTAMP 时间
symbol STRING 标的代码
price DOUBLE 委托价格
totalQty LONG 用户订单数量
openQty LONG 用户订单余量
direction INT 1(买 ),2(卖)
isMacthing INT 订单是否到达撮合时间
openVolumeWithBetterPrice LONG 优于委托价格的行情未成交委托单总量(仅当 outputQueuePosition=true 时返回)
openVolumeWithWorsePrice LONG 次于委托价格的行情未成交委托单总量(仅当 outputQueuePosition=true 时返回)
openVolumeAtOrderPrice LONG 等于委托价格行情未成交委托单总量(仅当 outputQueuePosition=true 时返回)
priorOpenVolumeAtOrderPrice LONG 等于委托价格行情且比自己早的行情未成交委托单总量(仅当 outputQueuePosition=true 时返回)
depthVolumeWithBetterPrice INT 优于委托价格的行情未成交价格档位深度(仅当 outputQueuePosition=true 时返回)
updateTime TIMESTAMP 最新更新时间

getPosition

语法

Backtest::getPosition(engine, symbol="")

参数

engine 回测引擎句柄,在回调函数中可通过 contextDict["engine"] 获取。

symbol STRING 类型标量,证券代码,可选参数。

详情

获取持仓信息。
  • 若不指定 symbol,返回表;

  • 若指定 symbol,返回字典;

  • 开启 JIT 优化时必须指定 symbol

返回结构如下:

字段 名称
symbol 标的代码
lastDayLongPosition 昨买持仓数量
lastDayShortPosition 昨卖持仓数量
longPosition 买持仓量
longPositionAvgPrice 买成交均价
shortPosition 卖持仓量
shortPositionAvgPrice 卖成交均价
todayBuyVolume 当日买成交数量
todayBuyValue 当日买成交金额
todaySellVolume 当日卖成交数量
todaySellValue 当日卖成交金额

getStockTotalPortfolios

语法

Backtest::getStockTotalPortfolios(engine)

参数

engine 回测引擎句柄,在回调函数中可通过 contextDict["engine"] 获取。

详情

获取当前的股票策略权益指标,返回一个字典,结构如下:

key

value

tradeDate 日期
cash 可用资金
totalMarketValue 账户总市值
totalEquity 账户总权益
netValue 账户单位净值
totalReturn 截至当日的累计收益率
ratio 账户每日收益率
pnl 账户当日盈亏

getFuturesTotalPortfolios

语法

Backtest::getFuturesTotalPortfolios(engine)

参数

engine 回测引擎句柄,在回调函数中可通过 contextDict["engine"] 获取。

详情

查询每日期货盈亏情况,返回表结构如下:

字段名称

字段说明

tradeDate 日期
margin 保证金占用
floatingPnl 浮动盈亏
realizedPnl 已实现累计盈亏
totalPnl 累计盈亏
cash 可用资金
totalEquity 账户总权益
marginRatio 保证金占用比例
pnl 账户当日盈亏
netValue 账户单位净值
totalReturn 截至当日的累计收益率
ratio 账户每日收益率

getOptionTotalPortfolios

语法

Backtest::getOptionTotalPortfolios(engine)

参数

engine 回测引擎句柄,在回调函数中可通过 contextDict["engine"] 获取。

详情

查询每日期权盈亏情况,返回表结构如下:

字段名称

字段说明

tradeDate 日期
margin 保证金占用
floatingPnl 浮动盈亏
realizedPnl 已实现累计盈亏
totalPnl 累计盈亏
cash 可用资金
totalEquity 账户总权益
marginRatio 保证金占用比例
pnl 账户当日盈亏
netValue 账户单位净值
totalReturn 截至当日的累计收益率
ratio 账户每日收益率

getMarginSecuPosition

语法

Backtest::getMarginSecuPosition(engine,symbollist)

参数

engine 回测引擎句柄,在回调函数中可通过 contextDict["engine"] 获取。

symbollist STRING 类型向量,表示股票代码列表。

详情

查询担保品买入持仓信息。返回表结构如下:

字段

名称

symbol 标的代码
lastDayLongPosition 昨日收盘时担保品买入持仓量
lastDayBuyValue 昨日收盘时担保品买入金额
longPosition 担保品买入持仓量
buyValue 担保品买入金额
todayBuyVolume 当日担保品买入成交数量
todayBuyValue 当日担保品买入成交金额

getMarginTradingPosition

语法

Backtest::getMarginTradingPosition(engine,symbollist)

参数

engine 回测引擎句柄,在回调函数中可通过 contextDict["engine"] 获取。

symbollist STRING 类型向量,表示股票代码列表。

详情

查询融资买入持仓信息,返回表结构如下:

字段

名称

symbol 标的代码
lastDayLongPosition 昨日收盘时融资买入持仓量
lastDayBuyValue 昨日收盘时融资买入金额
lastDayMarginDebt 昨日收盘时融资买入负债
longPosition 融资买入持仓量
buyValue 融资买入金额
todayBuyVolume 当日融资买入成交数量
todayBuyValue 当日融资买入金额
marginBuyProfit 融资盈亏
financialFee 融资利息

getSecuLendingPosition

语法

Backtest::getSecuLendingPosition(engine,symbollist)

参数

engine 回测引擎句柄,在回调函数中可通过 contextDict["engine"] 获取。

symbollist STRING 类型向量,表示股票代码列表。

详情

查询每日期权盈亏情况,返回表结构如下:

字段

名称

symbol 标的代码
lastDayShortPosition 昨日融券卖出持仓量
lastDayShortValue 昨日融券卖出金额
lastDaySecuLendingDebt 昨日收盘时融券卖出负债
shortPosition 融券卖出持仓量
shortValue 融券卖出金额
todayShortVolume 当日融券卖出成交量
todayShortValue 当日融券卖出金额
secuLendingProfit 融券盈亏
secuLendingFee 融券费用

数字货币接口

在数字货币回测中,多数引擎接口与其他资产一致。用户仍可通过这些接口创建引擎、执行回测、获取回测结果。需要注意,部分接口增加了相关参数:

contractType STRING 类型标量,表示订阅行情品种类型。可选值为 "spot", "futures", "option",分别代表现货、期货和永续合约、期权。

accountType STRING 类型标量,表示账户类型。可选值为 "spot", "futures", "option",分别代表现货账户、期货和永续合约账户、期权账户。默认值为 "spot"。

相关接口如下表所示:

接口

语法详情

subscribeIndicator

订阅指标:

Backtest::subscribeIndicator(contextDict["engine"], "snapshot", d,contractType)
submitOrder

下单接口:

Backtest::submitOrder(engine, msg,label="",orderType=0,accountType)
getAvailableCash

查询账户可用资金:

Backtest::getAvailableCash(long(engine),accountType)
getPosition

获取当前持仓:

Backtest::getPosition(engine,symbol="",accountType)
getDailyPosition

获取每日持仓:

Backtest::getDailyPosition(engine,accountType)
getDailyTotalPortfolios

获取策略每日权益指标:

Backtest::getDailyTotalPortfolios(engine,accountType)
getReturnSummary

获取策略的收益概述:

Backtest::getReturnSummary(engine,accountType)
getTradeDetails

获取交易明细表:

Backtest::getTradeDetails(engine,accountType)

回测示例参考

在完成 DolphinDB Script 策略编写后,回测引擎的使用可分为三个主要步骤:引擎配置、引擎创建与数据回放、回测结果获取。由于不同资产和行情类型会影响回测引擎的使用方式,相关细节已在前文中详细说明。本章将通过几个示例展示如何创建回测引擎,包括基于不同频率的行情和品种:快照型股票高频策略回测、逐笔与快照(宽表)结合的股票高频回测、分钟级期货策略回测,以及分钟级数字货币回测。接下来,我们将重点介绍脚本中的关键内容,并提供完整的代码示例与数据引用,供用户参考学习。

基于快照行情数据的股票回测示例

下面我们将从引擎配置设置、引擎创建及数据回放、回测结果获取这三个方面详细讲解基于快照行情数据的股票回测示例,本节所用的脚本文件见附件。

引擎配置

首先,我们从示例脚本的配置入手,展示如何设置对应的回测引擎配置选项。

userConfig = dict(STRING, ANY) 
userConfig["startDate"] = 2023.02.01        
userConfig["endDate"] = 2023.02.28       
userConfig["strategyGroup"] = "stock"      //策略类型:股票
userConfig["cash"] = 10000000
userConfig["commission"] = 0.0005
userConfig["tax"] = 0.001
userConfig["dataType"] = 1		       //行情为快照
userConfig["msgAsTable"] = false           
userConfig["frequency"] = 0    
//配置策略全局变量
Context = dict(STRING,ANY)
Context["initPrice"] = dict(SYMBOL,ANY)
Context["feeRatio"] = 0.00002
userConfig["context"]= Context

用户需根据回测策略确定策略类型以及行情类型,此处为快照的股票策略类型,即userConfig["strategyGroup"] = "stock"userConfig["dataType"] = 1

策略全局变量 context 为自定义的策略变量字典,用户可以根据策略需求定义。除此以外,还有一些策略的基础配置选项,如交易延时、手续费率、初始资金等等,用户可根据实际情况设置 。本示例行情回调函数中行情消息的数据类型为字典。在3.00.2 版本中,用户可以通过接口 createBacktester 创建引擎,并通过参数 JIT 选择是否开启 JIT 优化,这将显著地提升回测的效率。由于本教程不涉及JIT的教学,因此不做详细讲解。

引擎创建及数据回放

接下来,用户可根据自己的逻辑编写回测策略,并创建回测引擎。下面为该类型(快照的股票回测)创建引擎所需的事件函数。

def initialize(mutable context){
}
def beforeTrading(mutable context){
}
def onSnapshot(mutable context,msg, indicator){
}
def onOrder(mutable context,orders){
}
def onTrade(mutable context,trades){
}
def afterTrading(mutable context){
}
def finalize(mutable context){
}
创建回测引擎:
callbacks = dict(STRING, ANY)
callbacks["initialize"] = initialize
callbacks["beforeTrading"] = beforeTrading
callbacks["onSnapshot"] = onSnapshot
callbacks["onOrder"] = onOrder
callbacks["onTrade"] = onTrade
callbacks["afterTrading"] = afterTrading
callbacks["finalize"] = finalize
strategyName = "Backtest_test1"
try{Backtest::dropBacktestEngine(strategyName)}catch(ex){print ex}
engine = Backtest::createBacktester(strategyName, userConfig, callbacks, )
timer Backtest::appendQuotationMsg(engine, tb)

//开启JIT优化
strategyName = "Backtest_test2"
try{Backtest::dropBacktestEngine(strategyName)}catch(ex){print ex}
engine2 = Backtest::createBacktester(strategyName, userConfig, callbacks, true, )
timer Backtest::appendQuotationMsg(engine2, tb)

通过上述方式创建引擎时,参数 callbacks 为策略回调函数的一个字典,用户可根据策略自定义编写对应的策略回调函数。此处为快照的数据类型,因此只需调用 onSnapshot 行情回调函数即callbacks["onSnapshot"] = onSnapshot

在 3.00.2 版本中,用户可以使用接口createBacktester创建回测引擎,并选择是否开启 JIT 优化。另外,'try' 语句是为了删除该名称的回测引擎,从而避免无法创建新的回测引擎。如果没有该引擎,这句命令也不会报错。

数据回放:

不同资产或者同资产不同频率的行情字段稍微有些区别,用户必须按照特定数据结构传入回测引擎,否则导致回测运行失败。若现有的行情数据与回测引擎要求的字段名称、字段顺序、数据类型不匹配,用户可在数据导入中按照要求进行数据转换操作再传入即可。下面为快照行情的股票回测的数据结构要求:
colName = ["symbol", "symbolSource", "timestamp", "lastPrice", "upLimitPrice",
"downLimitPrice", "bidPrice", "bidQty",
"offerPrice", "offerQty", "signal", "prevClosePrice"]
colType = ["STRING", "STRING", "TIMESTAMP", "DOUBLE", "DOUBLE", "DOUBLE", "LONG",
"LONG", "DOUBLE[]", "LONG[]", "DOUBLE[]", "DOUBLE"]
tb=table(1:0, colName, colType)
//若不符合要求,可参考下面方式进行转换:
//tb = select ContractID as symbol,Market as symbolSource,concatDateTime(Date, BarTime) as timestamp,LastPrice as lastPrice,
//UPLimitPrice as upLimitPrice,downLimitPrice as downLimitPrice, //......
//from t 

执行回测:

通过接口appendQuotationMsg 将符合要求的行情数据插入回测引擎中,并执行回测:
Backtest::appendQuotationMsg(engine, tb)

回测结果获取

最后,用户可根据需要通过引擎接口获取回测结果。

tradeDetails = Backtest::getTradeDetails(engine)		  	//成交明细
openOrders = Backtest::getOpenOrders(long(engine))      	//查询当前的未成交(未完成)订单列表
dailyPosition = Backtest::getDailyPosition(long(engine))	//每日持仓

上述为部分回测结果的展示,更多接口信息请参考前文。

基于逐笔+快照(宽表)数据的股票回测示例

下面我们将从引擎配置、引擎创建及数据回放、回测结果获取这三个方面详细讲解基于逐笔+快照(宽表)行情数据的股票回测示例,本节所用的脚本文件见附件。

引擎配置

首先,我们从示例脚本的配置入手,展示如何设置对应的回测引擎配置选项。

userConfig = dict(STRING, ANY) 
userConfig["startDate"] = 2023.02.01        
userConfig["endDate"] = 2023.02.28       
userConfig["strategyGroup"] = "stock"      //策略类型:股票
userConfig["cash"] = 10000000
userConfig["commission"] = 0.0005
userConfig["tax"] = 0.001
userConfig["dataType"] = 6		       //行情为逐笔+快照(宽表)
userConfig["msgAsTable"] = false           
userConfig["frequency"] = 0   
userConfig["enableSubscriptionToTickQuotes"] = true 
userConfig["outputQueuePosition"] = 1   
//配置策略全局变量
Context = dict(STRING,ANY)
Context["maxBidAskSpread"] = 0.03 
Context["maxVolatility_1m"] = 0.05
userConfig["context"] =  Context

用户需根据回测策略确定策略类型以及行情类型,此处为逐笔+快照(宽表)的股票策略类型,即userConfig["strategyGroup"] = "stock"userConfig["dataType"] = 6

策略全局变量 context 为自定义的策略变量字典,用户可以根据策略需求定义。除此以外,还有一些策略的基础配置选项,如交易延时、手续费率、初始资金等等,用户可根据实际情况设置。本示例行情回调函数中行情消息的数据类型为字典。在 3.00.2 版本中,用户可以通过接口 createBacktester 创建引擎,并通过参数 JIT 选择是否开启 JIT 优化,这将显著地提升回测的效率。由于本教程不涉及 JIT 的教学,因此不做详细讲解。

引擎创建及数据回放

接下来,用户可根据自己的逻辑编写回测策略,并创建回测引擎。下列为该类型(逐笔+快照) 宽表的股票回测)创建引擎所需的事件函数。

def initialize(mutable context){
}
def beforeTrading(mutable context){
}
def onTick(mutable context, msg, indicator){
}
def onSnapshot(mutable context, msg, indicator){
}
def onOrder(mutable context, orders){
}
def onTrade(mutable context, trades){
}
def afterTrading(mutable context){
}
def finalize(mutable context){
}

创建回测引擎:

callbacks = dict(STRING,  ANY)
callbacks["initialize"] = initialize
callbacks["beforeTrading"] = beforeTrading
callbacks["onTick"] = onTick
callbacks["onSnapshot"] = onSnapshot
callbacks["onOrder"] = onOrder
callbacks["onTrade"] = onTrade
callbacks["afterTrading"] = afterTrading
callbacks["finalize"] = finalize
strategyName = "Backtest_test1"
try{Backtest::dropBacktestEngine(strategyName)}catch(ex){print ex}
engine = Backtest::createBacktester(strategyName, userConfig, callbacks, )
timer Backtest::appendQuotationMsg(engine, tb)
//开启JIT优化
strategyName = "Backtest_test2"
try{Backtest::dropBacktestEngine(strategyName)}catch(ex){print ex}
engine2 = Backtest::createBacktester(strategyName, userConfig, callbacks, true, )
timer Backtest::appendQuotationMsg(engine2, tb)

通过上述方式创建引擎时,参数 callbacks 为策略回调函数的一个字典,用户可根据策略自定义编写对应的策略回调函数。此处为逐笔+快照(宽表)的数据类型,因此可以调用onSnapshot,即 callbacks["onSnapshot"]=onSnapshot

在 3.00.2 版本中,用户可以使用接口 createBacktester 创建回测引擎,并选择是否开启 JIT 优化。另外,'try' 语句是为了删除该名称的回测引擎,从而避免无法创建新的回测引擎。如果没有该引擎,这句命令也不会报错。

数据回放:

不同资产或者同资产不同频率的行情字段稍微有些区别,用户必须按照特定数据结构传入回测引擎,否则导致回测运行失败。若现有的行情数据与回测引擎要求的字段名称、字段顺序、数据类型不匹配,用户可在数据导入中按照要求进行数据转换操作再传入即可。下面为逐笔+快照(宽表)行情的股票回测的数据结构要求:
colName = ["symbol", "symbolSource", "timestamp", "sourceType", "orderType", "price", "qty", "buyNo",
"sellNo", "direction", "channelNo", "seqNum", "lastPrice", "upLimitPrice",
"downLimitPrice", "totalBidQty", "totalOfferQty", "bidPrice", "bidQty",
"offerPrice", "offerQty", "signal", "prevClosePrice"]
colType=["SYMBOL", "STRING", "TIMESTAMP", "INT", "INT", "DOUBLE", "LONG", "LONG",
"LONG", "INT","INT", "LONG", "DOUBLE", "DOUBLE", "DOUBLE", "LONG",
"LONG", "DOUBLE[]", "LONG[]", "DOUBLE[]", "LONG[]", "DOUBLE[]", "DOUBLE"]
tb = table(1:0, colName, colType)
//若不符合要求,可参考下面方式进行转换:
//tb = select ContractID as symbol,Market as symbolSource,concatDateTime(Date,BarTime) as timestamp,sourceType as sourceType,Price as price,
//Qty as qty,...... from t 

执行回测:

通过接口appendQuotationMsg 将符合要求的行情数据插入回测引擎中,并执行回测:
timer Backtest::appendQuotationMsg(engine, tb)

回测结果获取

最后,用户可根据需要通过引擎接口获取回测结果。
tradeDetails = Backtest::getTradeDetails(long(engine))
openOrders = Backtest::getOpenOrders(long(engine))
dailyPosition = Backtest::getDailyPosition(long(engine)) //每日持仓
enableCash  = Backtest::getAvailableCash(long(engine)) //可用资金

基于分钟频数据的期货回测示例

下面我们将从引擎配置、引擎创建及数据回放、回测结果获取这三个方面详细讲解基于分钟频行情数据的期货回测示例,本节所用的脚本文件见附件。

引擎配置

首先,我们从示例脚本的配置入手,展示如何设置对应的回测引擎配置选项。

userConfig = dict(STRING, ANY) 
userConfig["startDate"] = 2023.02.01        
userConfig["endDate"] = 2023.02.28       
userConfig["strategyGroup"] = "futures"        //策略类型:期货
userConfig["cash"] = 10000000
userConfig["commission"] = 0.0005
userConfig["tax"] = 0.001
userConfig["dataType"] = 3		       //行情为分钟频率        
userConfig["frequency"] = 0            
Context = dict(STRING,ANY)                //策略全局变量context 
Context["buySignalRSI"] = 70.
Context["sellSignalRSI"] = 30.
Context["highPrice"] = dict(STRING, ANY)
userConfig["context"] = Context       

用户需根据回测策略确定策略类型以及行情类型,此处为分钟频的期货策略类型,即userConfig["strategyGroup"] = "futures"userConfig["dataType"] = 3 。策略全局变量 context 为自定义的策略变量字典,用户可以根据策略需求定义。除此以外,还有一些策略的基础配置选项,如交易延时、手续费率、初始资金等等,用户可根据实际情况设置。本示例行情回调函数中行情消息的数据类型为字典。在3.00.2 版本中,用户可以通过接口 createBacktester 创建引擎,并通过参数 JIT 选择是否开启 JIT 优化,这将显著地提升回测的效率。由于本教程不涉及 JIT 的教学,因此不做详细讲解。

引擎创建及数据回放

接下来,用户可根据自己的逻辑编写回测策略,并创建回测引擎。下列为该类型(分钟频的期货回测)创建引擎所需的事件函数。

def initialize(mutable context){
}
def beforeTrading(mutable context){
}
def onBar(mutable context, msg, indicator){
}
def onOrder(mutable context, orders){
}
def onTrade(mutable context, trades){
}
def afterTrading(mutable context){
}
def finalize(mutable context){
}
创建回测引擎:
callbacks = dict(STRING, ANY)
callbacks["initialize"] = initialize
callbacks["beforeTrading"] = beforeTrading
callbacks["onBar"] = onBar
callbacks["onOrder"] = onOrder
callbacks["onTrade"] = onTrade
callbacks["afterTrading"] = afterTrading
callbacks["finalize"] = finalize 
strategyName = "Backtest_test1"
try{Backtest::dropBacktestEngine(strategyName)}catch(ex){print ex}
engine = Backtest::createBacktester(strategyName, userConfig, callbacks, , securityReference)

//开启JIT优化
strategyName = "Backtest_test2"
try{Backtest::dropBacktestEngine(strategyName)}catch(ex){print ex}
engine2 = Backtest::createBacktester(strategyName, userConfig, callbacks, true, securityReference)

通过上述方式创建引擎时,参数 callbacks 为策略回调函数的一个字典,用户可根据策略自定义编写对应的策略回调函数。此处为分钟频的数据类型,因此只需调用 onBar 行情回调函数,即 callbacks["onBar"]=onBar。另外,用户可以使用该接口createBacktester创建回测引擎,并选择是否开启 JIT 优化。

  • 'try' 语句是为了删除该名称的回测引擎,从而避免无法创建新的回测引擎。如果没有该引擎,这句命令也不会报错。

  • 期货回测需要设置合约基本信息表 securityReference ,相关信息见期货页面的"合约基本信息表说明" 一节 。

securityReference = table(symbol as symbol, take(100., size(symbol)) as multiplier, take(0.2, size(symbol)) as marginRatio,
				take(0.01, size(symbol)) as tradeUnit, take(0.02,size(symbol)) as priceUnit, 
				take(0.03, size(symbol)) as priceTick, take(1.5, size(symbol)) as commission, take(1, size(symbol)) as deliveryCommissionMode)

数据回放:

不同资产或者同资产不同频率的行情字段稍微有些区别,用户必须按照特定数据结构传入回测引擎,否则导致回测运行失败。若现有的行情数据与回测引擎要求的字段名称、字段顺序、数据类型不匹配,用户可在数据导入中按照要求进行数据转换操作再传入即可。下面为分钟频行情的期货回测的数据结构要求:
colName = ["symbol", "symbolSource", "tradeTime", "tradingDay", "open", "low", "high", "close",
"volume", "amount", "upLimitPrice", "downLimitPrice", "signal", "prevClosePrice",
"settlementPrice", "prevSettlementPrice"]
colType = [SYMBOL, SYMBOL, TIMESTAMP, DATE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, LONG, DOUBLE,
DOUBLE, DOUBLE, DOUBLE[], DOUBLE, DOUBLE, DOUBLE]
tb = table(1:0, colName, colType)
//若不符合要求,可参考下面方式进行转换:
//tb = select ContractID as symbol, Market as symbolSource, concatDateTime(Date, BarTime) as tradeTime, TradeDate as tradingDay, OpenPrice as open,
//LowPrice as low, HighPrice as high, ClosePrice as close, long(volume) as volume, Value*1.0 as amount, ULimitPrice as upLimitPrice,
//LLimitPrice as downLimitPrice,...... from t 

执行回测:

通过接口appendQuotationMsg 将符合要求的行情数据插入回测引擎中,并执行回测:

timer Backtest::appendQuotationMsg(engine, tb)

回测结果获取

最后,用户可根据需要通过引擎接口获取回测结果。

res1 = select * from Backtest::getTradeDetails(engine) where orderStatus in [0,1]
availCash1 = Backtest::getAvailableCash(engine)  //可用资金
dailyPos1 = Backtest::getDailyPosition(engine)  //每日盘后持仓

基于分钟频数据的数字货币回测示例

下面我们将从引擎配置、引擎创建及数据回放、回测结果获取这三个方面详细讲解基于分钟频行情数据的数字货币回测示例,本节所用的脚本文件见附件。

引擎配置

首先,我们从示例脚本的配置入手,展示如何设置对应的回测引擎配置选项。

userConfig = dict(STRING, ANY)
userConfig["startDate"] = 2023.02.01        
userConfig["endDate"] = 2023.02.28    
userConfig["strategyGroup"] = "cryptocurrency"  //策略类型:数字货币
userConfig["frequency"] = 0
cash = dict(STRING, DOUBLE)
cash["spot"] = 100000.
cash["futures"] = 100000.
cash["option"] = 100000.
userConfig["cash"] = cash
userConfig["dataType"] = 3         //分钟频
userConfig["matchingMode"] = 1
userConfig["msgAsTable"] = false
//资金费率表
//userConfig["fundingRate"] = select  symbol, settlementTime,decimal128(lastFundingRate,8) as lastFundingRate from CryptoFundingRate 
userConfig["fundingRate"] = table(1:0, [`symbol, `settlementTime, `lastFundingRate], [STRING, TIMESTAMP, DECIMAL128(8)])
//配置策略全局变量
Context = dict(STRING, ANY)
Context["initPrice"] = dict(SYMBOL, ANY)
Context["feeRatio"] = 0.00002
Context["N"] = dict(SYMBOL, ANY)
userConfig["context"] = Context

用户需根据回测策略确定策略类型以及行情类型,此处为分钟频的数字货币策略类型,即userConfig["strategyGroup"] = "cryptocurrency"userConfig["dataType"]=3 。与其他资产策略不同的是,在数字货币的策略中,用户需要分别设置 spot、futures、option 三种的账户初始资金,并存入一个字典userConfig["cash"]中;另外还需要设置永续合约资金费率表userConfig["fundingRate"]

策略全局变量 context 为自定义的策略变量字典,用户可以根据策略需求定义。除此以外,还有一些策略的基础配置选项,如交易延时、手续费率、初始资金等等,用户可根据实际情况设置。本示例行情回调函数中行情消息的数据类型为字典。目前数字货币暂时不支持通过接口 createBacktester 创建引擎,仅可使用createBacktestEngine 来创建,并且不支持 JIT 优化。

引擎创建及数据回放

接下来,用户可根据自己的逻辑编写回测策略,并创建回测引擎。下列为该类型(分钟频的数字货币回测)创建引擎所需的事件函数。
def initialize(mutable context){
}
def beforeTrading(mutable context){
}
def onBar(mutable context,msg,indicator){
}
def onOrder(mutable context,orders){
}
def onTrade(mutable context,trades){
}
def afterTrading(mutable context){
}
def finalize(mutable context){
}
创建回测引擎:
strategyName = "Backtest_test1"
try{Backtest::dropBacktestEngine(strategyName)}catch(ex){print ex}
engine = Backtest::createBacktestEngine(strategyName, userConfig, securityReference, 
initialize, beforeTrading, onBar, , onOrder, onTrade, afterTrading, finalize)
go

通过上述方式创建引擎时,用户可根据策略自定义编写对应的策略回调函数,并在引擎创建时调用。此处为分钟频的数据类型,因此只需调用 onBar 行情回调函数。另外,用户可以使用该接口 createBacktestEngine 创建回测引擎,对于不使用的行情回调函数 onSnapshot,需要用空格留出位置。

  • 'try' 语句是为了删除该名称的回测引擎,从而避免无法创建新的回测引擎。如果没有该引擎,这句命令也不会报错。

  • 数字货币回测需要设置securityReference

securityReference=select last(contractType)  as contractType from tb group by symbol
update securityReference set optType=1
update securityReference set strikePrice=decimal128(0, 8)
update securityReference set contractSize=decimal128(100.,8) //......

数据回放

不同资产或者同资产不同频率的行情字段稍微有些区别,用户必须按照特定数据结构传入回测引擎,否则导致回测运行失败。若现有的行情数据与回测引擎要求的字段名称、字段顺序、数据类型不匹配,用户可在数据导入中按照要求进行数据转换操作再传入即可。下面为分钟频行情的数字货币回测的数据结构要求:

colName = [`symbol, `symbolSource, `tradeTime, `tradingDay, `open, `low, `high, `close, `volume, `amount, `upLimitPrice,
        `downLimitPrice, `signal, `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), DOUBLE[], DECIMAL128(8), DECIMAL128(8), DECIMAL128(8), INT]
tb=table(1:0, colName, colType)
//若不符合要求,可参考下面方式进行转换:
tb = select symbol+"_"+string(contractType) as symbol,symbolSource,tradeTime,tradingDay,decimal128(open,8) as open,decimal128(low,8) as low,
decimal128(high,8) as high,decimal128(close,8) as close,decimal128(volume,8) as volume,decimal128(amount,8) as amount,
decimal128(upLimitPrice,8) as upLimitPrice,decimal128(downLimitPrice,8) as downLimitPrice,signal,decimal128(prevClosePrice,8) as prevClosePrice,
decimal128(settlementPrice,8) as settlementPrice,decimal128(prevSettlementPrice,8) as prevSettlementPrice,contractType from Crypto1minData

回测结果获取

最后,用户可根据需要通过引擎接口获取回测结果。

tradeDetails_spot = Backtest::getTradeDetails(engine, "spot")     //成交明细
tradeDetails_futeres = Backtest::getTradeDetails(engine, "futures")
Backtest::getDailyPosition(engine, "spot")  //每日持仓

上述为部分回测结果的展示,数字货币的部分接口需要指定账户类型(spot、futures、option)。

旧版本使用说明

在 3.00.2 之前的版本中,用户只能通过接口 createBacktestEngine创建引擎,且无法开启 JIT 优化。在旧版本中,配置项 msgAsTable = false 时行情 msg 与指标 indicator 为字典类型,其数据结构及相关用法与新版并无差异;配置项 msgAsTable = true 时行情 msg 与指标 indicator 为表结构,此时应使用不同的编写方式来获取表中的相关数据,如 msg.a[i] 为 msg 表的第 i 行的 ”a“ 字段。若用户想了解这部分的使用方法,可以自行参考下列脚本。