回测插件

回测插件基于 DolphinDB 模拟撮合功能进行订单撮合,可以基于逐笔数据或快照行情数据进行高频策略回测。

在插件市场安装插件

版本要求

  • DolphinDB Server: 2.00.12 及更高版本(例如 3.00.00)
  • 具有 DolphinDB 商用版 license

安装步骤

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

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

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

    loadPlugin("Backtest")

用户配置模块

用户可以配置回测的开始和结束日期,初始资金,手续费和印花税,订单的撮合模式。

key说明备注
"startDate"开始日期
"endDate"结束日期
"strategyGroup"策略类型暂时固定股票:"stock"
"cash"初始资金
"commission"手续费
"tax"印花税
"dataType"行情类型:0:逐笔 + 快照 1:快照 2:快照 + 成交 3: 分钟频率 4:日频frequency>0 and dataType=0 时,行情为逐笔行情,引擎内部合成 frequency 频率的快照行情触发 onSnapshot
“matchingMode“订单撮合模式日频:模式一,以收盘价撮合订单模式二,以开盘价撮合订单分钟频率:模式一,行情时间大于订单时间时撮合订单模式二,行情时间等于订单时间时以当前行情的收盘价撮合订单,后续未完成订单撮合订单通模式一
“benchmark”
“frequency”frequency>0 时,行情为逐笔行情,引擎内部合成 frequency 频率的行情触发 onSnapshot默认为 0
"msgAsTable"行情的数据格式行情的数据格式,table 或 dict
"latency"订单延时
“orderBookMatchingRatio”与行情订单薄的成交百分比
“matchingRatio”
“enableSubscriptionToTickQuotes”是否订阅逐笔行情设置为 true 时,需定义 onTick 回调函数
“outputQueuePosition”是否需要获取订单在行情中的位置设置为 true 时,当订单还没有完全成交时,可以通过 getOpenOrders 接口实时获取优于委托订单价格的行情未成交委托总量,次于委托订单价格的行情未成交委托总量,等于委托订单价格的行情未成交委托总量,等于委托订单价格的但早于委托的行情未成交委托总量;订单提交时,订单状态明细表也可以获取以上统计指标。
“prevClosePrice”前收盘价数据表为以下三列的表:[symbol,tradeDate,prevClosePrice]在深交所的逐笔行情时,科创版股票的前收盘价必须设置,否则订单撮合结果可能不符合预期
“stockDividend”分红除权基本信息表[symbol, endDate, annDate, recordDate, exDate, payDate, divListdate, bonusRatio, capitalConversion, afterTaxCashDiv, allotPrice, allotRatio]

分红除权基本信息表说明如下:

字段名称
symbol股票代码
endDate分红年度
annDate预案公告日
recordDate股权登记日
exDate除权除息日
payDate派息日
divListDate红股上市日
bonusRatio每股送股比例
capitalConversion每股转增比例
afterTaxCashDiv每股分红(税后)
allotPrice配股价格
allotRatio每股配股比例
userConfig=dict(STRING,ANY)        
userConfig["startDate"]= 2022.04.13       
userConfig["endDate"]= 2022.04.13
///策略类型,暂时固定股票///
userConfig["strategyGroup"]= "stock"
///初始资金
userConfig["cash"]= 100000000
///手续费,        
userConfig["commission"]= 0.00015
//印花税,
userConfig["tax"]= 0.001        
///以指定的频率通过逐笔数据合成快照。(只有快照行情时,frequency设置无效)
userConfig["frequency"]= 1000
///dataType=0表示逐笔模式撮合,
///dataType=1表示按快照模式一撮合,
///dataType=2按快照模式二撮合
userConfig["dataType"]= 2
//与行情订单薄的成交百分比
userConfig["orderBookMatchingRatio"]=1
///快照模式下,快照的区间成交百分比
userConfig["matchingRatio"]=1
////tick的数据格式,table或dict
userConfig["msgAsTable"]= false
try{Backtest::dropBacktestEngine("backtestMM")}catch(ex){print ex}
engine = Backtest::createBacktestEngine("backtestMM", userConfig,, 
initialize, beforeTrading,onTick,onSnapshot,onOrder,onTrade,afterTrading,finalize)

行情数据模块说明

逐笔 + 快照或逐笔合成快照行情

  • 行情为逐笔 + 快照或逐笔合成快照,输入表结构为:
colName=`msgTime`msgType`msgBody`symbol`channelNo`seqNum
colType= [TIMESTAMP, SYMBOL, BLOB,STRING,INT,LONG]
messageTable=streamTable(10000000:0, colName, colType)

标的代码 symbol 必须带有交易所标识(".XSHG",".XSHE")结尾,如 600000.XSHG,不然报错。

带有逐笔行情时,msgType 有 "entrust", "trade", "snapshot", "END" 四种,使用逐笔合成指定频率的快照时可以不用”snapshot"行情,其中三个表结构分别如下:

逐笔数据 entrust 和 trade 的表结构如下:

nametype备注
symbolsymbol股票代码上交所以".XSHG"结尾深交所以"XSHE"结尾
symbolSourceSTRING"XSHG"(上交所)或者"XSHE"(深交所)
timestampTIMESTAMP
sourceTypeINT0 代表委托数据 entrust;1 代表成交表 trade
orderTypeINTentrust:1 市价;2 限价;3 本方最优;10 撤单(仅上交所,即上交所撤单记录在 entrust 中)trade:0 成交;1 撤单(仅深交所,即深交所撤单记录在 trade 中)
priceDOUBLE订单价格
qtyLONG订单数量
buyNoLONGtrade 对应其原始数据;entrust 中的委托单号填充,
sellNoLONGtrade 对应其原始数据;entrust 中的委托单号填充,
directionINT1(买)or 2(卖)
channelNoINT通道号
seqNumLONG逐笔数据序号

逐笔行情时 snapshot 表如下:

nametype备注
symbolsymbol股票代码上交所以".XSHG"结尾深交所以"XSHE"结尾
symbolSourceSTRING"XSHG"(上交所)或者"XSHE"(深交所)
timestampTIMESTAMP时间戳
lastPriceDOUBLE最新成交价
upLimitPriceDOUBLE涨停价
downLimitPriceDOUBLE跌停价
totalBidQtyLONG区间买量
totalOfferQtyLONG区间卖量
bidPriceDOUBLE[]委买价格列表
bidQtyLONG[]委买量列表
offerPriceDOUBLE[]委卖价格列表
offerQtyLONG[]委卖量列表
signalDOUBLE[]指标列表
seqNumLONG逐笔数据序号
prevClosePriceDOUBLE前收盘价

msgType 为”END“时策略回测结束。可以在行情回放结束之后,增加一条 msgType 为”END“的消息。如下示例:

messageTable=select top 1* from messageTable where msgTime=max(msgTime)
update messageTable set msgType="END"
update messageTable set msgTime=concatDateTime(msgTime.date(),16:00:00)
Backtest::appendQuotationMsg(engine,messageTable)

快照或快照 + 成交行情

  • 为快照行情时:

    colName=["symbol","symbolSource","timestamp","lastPrice","upLimitPrice",
    "downLimitPrice","totalBidQty","totalOfferQty","bidPrice","bidQty",
    "offerPrice","offerQty","signal","prevClosePrice"]
    colType= ["STRING","STRING","TIMESTAMP","DOUBLE","DOUBLE","DOUBLE","LONG",
    "LONG","DOUBLE[]","LONG[]","DOUBLE[]","LONG[]","DOUBLE[]","DOUBLE"]
    messageTable=table(10000000:0, colName, colType)
  • 为快照 + 成交行情时:

    colName=["symbol","symbolSource","timestamp","lastPrice","upLimitPrice",
    		"downLimitPrice","totalBidQty","totalOfferQty","bidPrice","bidQty",
    		"offerPrice","offerQty","tradePrice","tradeQty","signal","prevClosePrice"]
    		colType= ["STRING","STRING","TIMESTAMP","DOUBLE","DOUBLE","DOUBLE","LONG",
    		"LONG","DOUBLE[]","LONG[]","DOUBLE[]","LONG[]","DOUBLE[]","LONG[]","DOUBLE[]","DOUBLE"]
    		messageTable=table(10000000:0, colName, colType)

    标的代码 symbol 必须带有交易所标识(".XSHG",".XSHE")结尾,如 600000.XSHG,不然报错。

    快照 (dataType=1) 或快照 + 成交 (dataType=2) 行情数据字段如下(dataType=1 时,没有 tradePrice 和 tradeQty 两个字段)

    nametype备注
    symbolsymbol股票代码上交所以".XSHG"结尾深交所以"XSHE"结尾
    symbolSourceSTRING"XSHG"(上交所)或者"XSHE"(深交所)
    timestampTIMESTAMP
    lastPriceDOUBLE最新成交价
    upLimitPriceDOUBLE
    downLimitPriceDOUBLE
    totalBidQtyLONG
    totalOfferQtyLONG
    bidPriceDOUBLE[]
    bidQtyLONG[]
    offerPriceDOUBLE[]
    offerQtyLONG[]
    tradePriceDOUBLE[]dataType = 2 时才有
    tradeQtyLONG[]dataType = 2 时才有
    signalDOUBLE[]指标列表
    prevClosePriceDOUBLE

    引擎接收到 symbol 为”END”时,表示策略回测结束

    一般在回测行情回放结束之后,再发送一条 symbol 为”END”的消息,如下示例:

    messageTable=select top 1* from messageTable where timestamp=max(timestamp)
    update messageTable set symbol="END"
    //update messageTable set msgTime=concatDateTime(timestamp.date(),16:00:00)
    Backtest::appendQuotationMsg(engine,messageTable)

分钟频率或日频

为分钟频率或日频:

colName=`symbol`tradeTime`open`low`high`close`volume`amount`upLimitPrice`downLimitPrice`prevClosePrice`signal
colType=[SYMBOL,TIMESTAMP,DOUBLE,DOUBLE,DOUBLE,DOUBLE,LONG,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE[]]
messageTable=table(10000000:0, colName, colType)
  1. 标的代码 symbol 必须带有交易所标识(".XSHG",".XSHE")结尾,如 600000.XSHG,不然报错。
  2. 引擎接收到 symbol 为”END”时,表示策略回测结束
  3. 涨停价 upLimitPrice 不为 0 时,委托买单价格大于等于涨停价会被拒单
  4. 跌停价 downLimitPrice 不为 0 时,委托卖单价格小于等于跌停价会被拒单

一般在回测行情回放结束之后,可以再发生一条 symbol 为”END”的消息,如下示例:

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)

策略编写模块

使用回测引擎进行策略回测时采取的是事件驱动机制,策略回测架构提供以下多个事件函数。

事件函数说明
def initialize(mutable contextDict){}策略初始化函数,只触发一次。可以在该函数中初始化一些变量,或者订阅指标计算。回调函数传入参数 contextDict 为逻辑上下文,是由回测引擎创建的字典变量
def beforeTrading(mutable contextDict){}策略盘前交易函数,每日盘前触发一次。可以在该函数中一些启动前的准备,如订阅行情等
def onTick(mutable contextDict, msg){}逐笔行情通知函数,行情更新时的处理函数,逐笔委托和成交。
def onSnapshot(mutable contextDict, msg){}快照行情通知函数
def onOrder(mutable contextDict,orders){}委托回报通知函数,每个订单状态有变化时会触发。
def onTrade(mutable contextDict,trades){}成交回报通知函数,有成交时会触发。
def afterTrading(mutable contextDict){}策略每日盘后回调函数,每日盘后触发一次。可以在该函数统计当日的成交等信息
def finalize(mutable contextDict){}策略结束之后回调函数

逐笔行情回调函数 onTick

contextDict 为上下文

msg 为 tick 数据,为表或者字典。

字典是,包含 symbol 为 key 值的 tick 数据字典,每个 tick 对象包含字段如下:

nametype备注
symbolsymbol股票代码
symbolSourceSTRING
timestampTIMESTAMP
sourceTypeINT0 代表委托数据 entrust;1 代表成交表 trade
orderTypeINTentrust:1 市价;2 限价;3 本方最优;10 撤单(仅上交所,即上交所撤单记录在 entrust 中)trade:0 成交;1 撤单(仅深交所,即深交所撤单记录在 trade 中)
priceDOUBLE订单价格
qtyLONG订单数量
buyNoLONG
sellNoLONG
directionINT1(买)or 2(卖)
channelNoINT通道号
seqNumLONG逐笔数据序号

快照行情回调函数 onSnapshot

contextDict 为上下文

msg 为 snapShot 数据,为表或者字典。

字典是,包含 symbol 为 key 值的 snapShot 数据字典,每个 snapShot 对象包含字段如下:

名称类型含义
symbolSYMBOL股票标的
symbolSourceSYMBOL证券市场:深交所、上交所
timestampTIMESTAMP时间
lastPriceDOUBLE最新成交价
upLimitPriceDOUBLE涨停板价
downLimitPriceDOUBLE跌停板价
totalBidQtyLONG买单成交数量总和
totalOfferQtyLONG卖单成交数量总和
bidPriceDOUBLE[]买单价格列表
bidQtyLONG[]买单数量列表
offerPriceDOUBLE[]卖单价格列表
offerQtyLONG[]卖单数量列表
signalDOUBLE[]

K 线行情回调函数 onBar

contextDict 为上下文

msg 为 K 线数据,为表或者字典。

字典是,包含 symbol 为 key 值的日频或者分钟频率的 K 线数据字典,每个 K 线包含字段如下

字段类型名称备注
symbolSYMBOL标的代码“.XSHE”或者“.XSHG”结尾标识
tradeTimeTIMESTAMP交易日
openDOUBLE开盘价
lowDOUBLE最低价
highDOUBLE最高价
closeDOUBLE收盘价
volumeLONG成交量
amountDOUBLE成交额
upLimitPriceDOUBLE涨停价
downLimitPriceDOUBLE跌停价
prevClosePriceDOUBLE前收盘价
signalDOUBLE[]其它

委托回报 onOrder

contextDict 为上下文

orders 为订单信息的字典列表:

名称含义类型
orderId委托订单 idint → long
symbol标的代码
timestamp委托时间
qty委托数量
price委托价格
status委托状态 4:已报 0:部成 1:已成 2:撤单成功 -1:审批拒绝 -2:撤单拒绝
direction委托方向
tradeQty成交数量
tradeValue成交金额
label
updateTime

成交回报函数 onTrade

contextDict 为上下文

trades 为订单信息的字典列表:

字段名称备注
orderId委托订单 id
symbol标的代码
tradePrice成交价格
tradeQty成交数量int
tradeValue成交金额
totalFee
totalVolume累计成交量
totalValue累计成交金额
direction委托方向
tradeTime成交时间
orderPrice委托价格
label

示例

def initialize(mutable contextDict){
	//订阅指标
	print("initialize")
	d=dict(STRING,ANY)
	d["zdf"]=<zdf(lastPrice,prevClosePrice)>
	d["totalSellAmount"]=<totalSellAmount(offerQty)>
	Backtest::subscribeIndicator(contextDict["engine"], "snapshot", d) 
	//订阅逐笔行情的指标
	d=dict(STRING,ANY)
	d["zdf_30s"]=<zdf_30s(price,time,sourceType,orderType)>
	d["tradeVol_5m"]=< tradeVol_5m(qty,time,sourceType,orderType)>
	//d["sourceType"]=<sourceType>
	Backtest::subscribeIndicator(contextDict["engine"], "tick", d) 
}
def beforeTrading(mutable contextDict){
	//每日盘前回调函数
	//1、通过contextDict["tradeDate"]可以获取当日;
	print("before_trading")
}  
def onTick(mutable contextDict, msg){
	////msg可以为字典或表,最新时刻的tick数据
	///1、通过contextDict["tradeTime"]获取最新时间
	for (istock in msg.keys()){
		askPrice=msg[istock]["offerPrice"][0]
		bidPrice=msg[istock]["bidPrice"][0]
		if(any([askPrice,bidPrice]<=0) or any(isNull([askPrice,bidPrice]))){
			continue
			}
		buyQty=100
		sellQty=100
		buyOrderId=Backtest::submitOrder(contextDict["engine"], 
		(istock, contextDict["tradeTime"], 5, bidPrice, buyQty, 1, 1))[0]
	}			
}
def onOrder( mutable contextDict,orders){
	/*
	 orderId->474
	symbol->688157.XSHG
	timestamp->2022.04.11T09:50:43.000
	amount->1100
	price->94.319999999999993
	status->9
	direction->2
	tradeQty->1100
	tradeValue->0
	label->"a"
	updateTime->2022.04.11T09:50:43.000
	 */
}
def onTrade(mutable contextDict,trades){
	/*
	 * trades为字典列表
	orderId->376
	symbol->688157.XSHG
	tradePrice->93.959999999999993
	tradeQty->200
	tradeTime->2022.04.11T09:53:16.220
	direction->2
	tradeValue->18792//成交金额
	label->
	 */
	///成交主推回调
	for(itrade in trades){}
}
def afterTrading(mutable contextDict){
	print ("after_trading")
	//print 
	//每日盘后回调函数
	
	}
def finalize(mutable contextDict){
    //回测结束前回调函数
	
 }

引擎接口

createBacktestEngine 创建回测引擎,设置所有的回调函数

Backtest::createBacktestEngine(name, userConfig,basicInfo, 
initialize, beforeTrading,onTick,onSnapshot,onOrder,onTrade,afterTrading,finalize)
入参名称类型是否是必填项备注
name回测引擎名称string
userConfig回测引擎的设置dict
basicInfo
initialize初始化回调函数
beforeTrading
onTick/onBar逐笔行情回调函数 订阅逐笔行情的时候触发
onSnapshot快照行情回调函数
onOrder
onTrade
afterTrading
finalize

appendQuotationMsg 插入行情执行策略回测

Backtest::appendQuotationMsg(engine,msg)
入参名称是否是必填项
engine回测引擎
msg行情

subscribeIndicator 订阅指标

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)

订阅行情指标时,内部创建了相应的响应式状态引擎,状态因子的编写参考:DolphinDB 响应式状态引擎介绍教程

submitOrder 下单接口

Backtest::submitOrder(engine, msg,label="")
入参名称类型是否是必填项备注
engine回测引擎名称 在回测框架里通过 contextDict["engine"]模式调用当前的引擎名称
msg订单信息元组或表(股票代码,下单时间,订单类型,订单价格,订单数量,买卖方向) 买卖方向:1:买开;2 卖开;3:卖平;4:买平订单类型:上交所:0:市价单中最优五档即时成交剩余撤销委托订单 1:市价单中最优五档即时成交剩余转限价委托订单 2:市价单中本方最优价格委托订单 3:市价单中对手方最优价格委托订单 5:限价单 6:撤单深交所:0:市价单中最优五档即时成交剩余撤销委托订单 1:市价单中即时成交剩余撤销委托订单 2:市价单中本方最优价格委托订单 3: 市价单中对手方最优价格委托订单 4:市价单中全额成交或撤销委托订单 5:限价单 6:撤单
label备注string这个用户可以设置,用于对订单进行分类

setUniverse 设置股票池

Backtest::setUniverse(engine,symbolList)

其中 symbolList 是一个 string vector,内含股票代码

cancelOrder 取消订单接口

Backtest::cancelOrder(engine,symbol=NULL,orders=NULL,label="")
入参名称类型是否是必填项备注
engine引擎
symbol证券代码Symbol只支持单个
orders订单列表[]orders 不为空时,取消指定订单
label

getOpenOrders 获取未成交订单

查询未成交订单

Backtest::getOpenOrders(engine,symbol=NULL,orders=NULL,label="",outputQueuePosition=false)
入参名称类型是否是必填项备注
engine引擎名称
symbol证券代码Symbol否(返回所有的未成交订单)只支持单个
orders订单列表listorders 不为空时,查询指定订单
label string
outputQueuePosition BOOL

返回如下:

返回值是一个表。包含如下列:

注意:仅当 outputQueuePosition=1 和 2 时,包含 openVolumeWithBetterPrice, openVolumeWithWorsePrice, openVolumeAtOrderPrice, priorOpenVolumeAtOrderPrice, depthWithBetterPrice 五列。

名称类型含义
orderIdLONG订单 ID
timestampTIMESTAMP时间
symbolSTRING股票标的
priceDOUBLE委托价格
totalQtyLONG用户订单数量
openQtyLONG用户订单余量
directionINT1(买),2(卖)
isMacthingINT订单是否到达撮合时间
openVolumeWithBetterPriceLONG优于委托价格的行情未成交委托单总量
openVolumeWithWorsePriceLONG次于委托价格的行情未成交委托单总量
openVolumeAtOrderPriceLONG等于委托价格行情未成交委托单总量
priorOpenVolumeAtOrderPriceLONG等于委托价格行情且比自己早的行情未成交委托单总量
depthVolumeWithBetterPriceINT优于委托价格的行情未成交价格档位深度
updateTimeTIMESTAMP最新更新时间

dropBacktestEngine 删除回测引擎

Backtest::dropBacktestEngine(engine)

getPosition 获取持仓

Backtest::getPosition(engine,symbol="")
入参名称类型是否是必填项备注
engine回测引擎名称long在回测框架里通过 contextDict["engine"]模式调用当前的引擎名称
symbol股票代码string"688157.XSHG"

返回表如下:

字段名称
symbol标的代码
lastDayLongPosition昨买持仓数量昨日收盘时的买开的持仓量买开,买卖标志为 1
lastDayShortPosition昨卖持仓数量昨日收盘时的卖开的持仓量卖开,买卖标志为 2
longPosition买持仓量sum(买开成交数量 - 卖平成交数量)买卖标志为 1 的成交数量 - 买卖标志为 3 的成交数量
longPositionAvgPrice买成交均价sum(买开成交数量*买开成交价格)\sum(买开成交数量)买开时计算
shortPosition卖持仓量sum(卖开成交数量 - 买平成交量)卖开,买卖标志为 2
shortPositionAvgPrice卖成交均价sum(卖开成交数量*卖开成交价格)\sum(卖成交数量)卖开时计算
todayBuyVolume当日买成交数量sum(当日买开成交数量)
todayBuyValue当日买成交金额sum(当日买开成交数量*当日买开成交价格)
todaySellVolume当日卖成交数量sum(当日卖开成交数量)
todaySellValue当日卖成交金额sum(当日卖开成交数量*当日卖开成交价格)

getTradeDetails 获取交易明细表

Backtest::getTradeDetails(long(engine))

返回明细表

字段含义
orderId订单号
symbol
direction订单委托买卖标志
sendTime订单委托时间
orderPrice订单委托价格
orderQty订单委托数量
tradeTime订单成交时间
tradePrice成交价格
tradeQty成交数量
orderStatusorderStatus 表示订单状态,4:已报 0:部成 1:已成 2:撤单成功 -1:审批拒绝 -2:撤单拒绝 -3:未成交的订单
label

getAvailableCash 查询账户可用现金

Backtest::getAvailableCash(long(engine))
///100135665.66910028

getTodayPnl 查询当日股票盈亏情况

Backtest::getTodayPnl(long(engine),"688157.XSHG")

输出表

字段名称
symbol标的代码
pnl当日账户盈亏金额(包含昨仓)
todayPnl当日盈亏金额(不包含昨仓)

getDailyPosition 获取每日持仓数据详情

一般回测结束调用,返回每日盘后的持仓数据表

Backtest::getDailyPosition(engine)  //        

股票每日持仓返回统计字段:

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

getDailyTotalPortfolios 获取策略每日权益指标

Backtest::getTotalPortfolios 接口实时获取账户盈亏。

可以在回测结束时调用,每日结束时计算该账户的权益指标:

Backtest::getDailyTotalPortfolios(engine)          
字段字段说明
engine引擎

计算字段:

InitialCash−账户的初始现金

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

getReturnSummary 获取策略的收益概述

回测结束时计算该模块

Backtest::getReturnSummary(engine)          
字段字段说明
engine引擎

输出字段:

计算公式中的

value:为每日净值 netValue

price:基准每日净值数据(设置 benchmark 时)

字段名称字段说明计算公式
totalReturn总收益last(value)-1
annualReturn年化收益率pow(last(value), 252\size(value)) - 1
annualVolatility年化波动率std(deltas(value)\prev(value)) * sqrt(252)
annualSkew收益率偏度skew(deltas(value)\prev(value))
annualKur收益率峰度kurtosis(deltas(value)\prev(value))
sharpeRatio夏普率(getAnnualReturn(value) - r)\getAnnualVolatility(value)
maxDrawdown最大回撤i = imax((cummax(value) - value) \ cummax(value)) if (i==0){ return 0 } j = imax(value[:i])(value[j] - value[i]) \ (value[j])
drawdownRatio收益回撤比getAnnualReturn(value) \ getMaxDrawdown(value)
betabeta 系数covar(deltas(value)\prev(value), deltas(price)\prev(price)) \ std(deltas(price)\prev(price))
alphaa 系数annualReturn(value) - beta(value, price) * (annualReturn(price) )
turnoverRate换手率每日换手率 len(set(当日持股股票集合)-set(前一交易日股票集合))/len(set(前一交易日股票集合));avg(abs(每日换手率))
dailyWinningRate日胜率当日盈亏大于 0 的次数/总的交易日

getBacktestEngineList 获取所有的回测引擎

 Backtest::getBacktestEngineList()

getContextDict 回测结束,返回逻辑上下文

Backtest::getContextDict(long(engine))

使用示例

编写好策略之后,进行策略配置以及创建回测引擎并执行策略回测

userConfig=dict(STRING,ANY)        
userConfig["startDate"]= 2022.04.13       
userConfig["endDate"]= 2022.04.13
///策略类型,暂时固定股票///
userConfig["strategyGroup"]= "stock"
///初始资金
userConfig["cash"]= 100000000
///手续费,        
userConfig["commission"]= 0.00015
//印花税,
userConfig["tax"]= 0.001        
userConfig["latency"]= 10
///以指定的频率通过逐笔数据合成快照。(只有快照行情时,frequency设置无效)
userConfig["frequency"]= 1000
///dataType=0表示,逐笔模式撮合,
///dataType=1表示按快照模式一撮合,
///dataType=2按快照模式二撮合
userConfig["dataType"]= 2
//与行情订单薄的成交百分比,(逐笔撮合时,orderBookMatchingRatio参数无效)
userConfig["orderBookMatchingRatio"]=1
///快照模式下,快照的区间成交百分比,(逐笔撮合时,matchingRatio参数无效)
userConfig["matchingRatio"]=1
////tick的数据格式,table或dict
userConfig["msgAsTable"]= false
name="test01"
try{Backtest::dropBacktestEngine(strategyName)}catch(ex){print ex}
engine = Backtest::createBacktestEngine(name, userConfig,, 
initialize, beforeTrading,onTick,onSnapshot,onOrder,onTrade,afterTrading,finalize)