金融界2025年8月20日消息,国家知识产权局信息显示,江苏武进液压启闭机有限公司取得一项名为“一种活塞密封圈可形变的液压缸及其启闭机”的专利,授权公...
2025-08-20 0
使用 DolphinDB 脚本来编写回测策略,通常包含以下步骤:
本文将通过示例演示如何使用 DolphinDB 回测插件完成策略编写与回测执行。示例适用于 DolphinDB Server 2.00.14.1、3.00.2.1 及以上版本。在执行本文示例前,请参照“插件安装”小节完成插件安装。
DolphinDB 回测框架基于 DolphinDB Server,通过插件形式提供适用于多种资产的回测引擎。本章将通过一个简单的中高频交易策略,演示如何使用回测引擎进行策略回测。
基于分钟 K 线行情,对于每一只标的,当持仓为空时,执行买入操作。本示例使用的数据见附件。
//step 1:编写策略逻辑def onBar(mutable context, msg, indicator){ for(istock in msg.keys()){ &pos=Backtest::getPosition(context.engine,istock) price=msg[istock].close //没有持仓时,买入 if(pos.longPosition<1){ Backtest::submitOrder(context.engine, (istock, context.tradeTime,5, price+0.02,100, 1),"buyOpen") } }}//step 2:配置参数config = { startDate: 2023.07.11 ,//回测开始日期 endDate: 2023.07.11 , //回测结束日期 strategyGroup: `stock,//股票策略 cash: 1000000., //策略初始资金 commission: 0.00015,//费用 tax: 0.001, dataType: 3//回测行情,dataType = 3 表示分钟行情}callbacks = { onBar:onBar}try{Backtest::dropBacktestEngine("test01")}catch(ex){print ex}//删除引擎 //step 3:创建引擎,不开启JIT engine = Backtest::createBacktester("test01", config, callbacks, false) // step 4:执行回测,获取结果colName=`symbol`tradeTime`open`low`high`close`volume`amount`upLimitPrice`downLimitPricecolType=["SYMBOL","TIMESTAMP","DOUBLE","DOUBLE","DOUBLE","DOUBLE","LONG","DOUBLE","DOUBLE","DOUBLE"]dayData = loadText(filename="./barData.csv",schema=table(colName as name ,colType as type ))Backtest::appendQuotationMsg(engine, dayData) //执行策略回测tradeDetails = Backtest::getTradeDetails(engine) ret = Backtest::getReturnSummary(engine)
在完成回测之后,用户可以通过相关接口获取回测结果。以下为通过 getTradeDetails 接口获得的部分交易明细表的内容。其中字段 “direction” 表示订单委托买卖方向,1 表示买开,2 表示卖开;“orderPrice”,“orderQty” 分别表示委托的价格以及数量;“label” 为标签,是方便标识的字符串,可在下单时自行设置。
下面我们将详细讲解 1.1 中的策略代码,以便于读者理解以及学习回测插件的使用。 第 1-12 行定义的 onBar 为 K 线行情回调函数,用户可以在该函数中编写策略逻辑,如开仓、平仓等。该函数包含三个参数,分别为 context、msg、indicator。其中 context 为逻辑上下文,需要在引擎配置参数 userConfig 中定义;msg 为 K 线行情数据,在第 31 行回测引擎将插入的行情数据逐条传入 onBar 中进行策略实现;indicator 为指标,用户不仅可以将已有的指标传入,也可通过内置引擎计算自定义指标并订阅,下一章将详细介绍指标的定义。在 onBar 策略中,通过接口 getPosition 获取当前的持仓情况,作为后续策略判断;最后通过接口 submitOrder 进行委托下单。 第 14-22 行中配置了回测引擎的基本参数,如回测开始日期、结束日期、策略类型、初始资金、手续费用等等,用户必须正确配置才能保证回测的进行。而 context 则为策略所需的参数,可以根据实际需求设置。 第 26 行通过接口createBacktester创建回测引擎。需要注意的是,“test01” 为引擎的名称,若已有该名称的引擎则会创建失败,因此可以先删除同名的引擎,如第 24 行。在创建引擎前,需要确保所有的参数已经定义完成。其中 config 为引擎参数,callbacks 为事件回调函数(第 23 行),false 表示不开启 JIT 优化。 第 28-30 行获取行情数据,并插入引擎中执行策略回测。由于回测引擎对行情数据结构有明确的要求,因此可以通过 schema 确保结构一致再传入。 最后,通过不同的引擎接口,获取不同回测结果,如第 32-33 行。
本章将从上一章的简单策略出发,介绍如何利用回测引擎的事件驱动机制,灵活运用各类事件函数,逐步扩展和优化策略逻辑。
回测引擎采用灵活高效的事件驱动机制,针对用户不同的策略需求提供了一系列丰富的事件函数,其中包括用于策略参数和环境初始化的初始化函数(initialize),用于实现每日盘前准备工作的盘前回调函数(beforeTrading)以及每日盘后策略总结分析的盘后回调函数(afterTrading);在行情处理方面,引擎不仅提供了用于实时快照数据处理的回调函数(onSnapshot),还为不同时间粒度的数据提供了分钟和日频的行情回调函数(onBar),能够有效支持多种交易频率的策略;此外,引擎还为交易过程中的委托和成交事件分别提供了委托状态回调函数(onOrder)和成交回报回调函数(onTrade),方便用户实时监控和调整策略的执行过程。通过这些丰富的事件回调函数,用户可以轻松地实现精细化、自定义的策略逻辑。 接下来我们将通过具体的例子来讲解上述事件函数该如何使用。
策略初始化函数在策略回测过程中只触发一次。用户可在此函数中初始化全局变量 context,设定策略所需的全局参数或状态;同时,也可在此阶段订阅或配置策略运行期间需要使用的各类指标计算,以确保后续策略运行过程中能获取相关指标数据。 为展示策略初始化函数的作用,我们将实现一个简化的示例策略,完整代码将在下一节介绍 onSnapshot 函数时给出。该策略以股票的快照数据为行情源,当当日最新价格相较昨日收盘价上涨超过 1%,买入 100股,单日最多开仓一次,最大持仓不超过 500 股。在初始化函数中,我们定义了一个名为 pctChg 的指标,用于计算当前 tick 与昨日收盘价之间的收益率变化,用作交易信号的触发依据。
@statedef pctChg(lastPrice, prevClosePrice){ return lastPrice\prevClosePrice - 1}def initialize(mutable context){ //初始化回调函数 print("initialize") //订阅快照行情的指标 d = dict(STRING,ANY) d["pctChg"] = <pctChg(lastPrice, prevClosePrice)> Backtest::subscribeIndicator(context["engine"], "snapshot", d) context["maxPos"] = 500}
在策略中,如果想要订阅最新价格与昨日收盘价的指标,可以使用引擎提供的 Backtest::subscribeIndicator 接口,指定相应的因子名称和因子表达式即可实现该的策略指标的订阅。该接口使用示例如下:
Backtest::subscribeIndicator(engine, quote, indicatorDict)
订阅指标之后,在 onSnapshot策略回调函数中可以通过 indicator.pctChg 获取相应的指标计算结果。
基于上一节的策略思路,下面将展示基于股票快照行情调用 onSnapshot 实现策略的代码。onSnapshot 的 msg 参数,为回测引擎传来的最新快照行情;indicator 中包含 initialize 中策略订阅的指标值。回调函数的行情 msg 和 indicator 为字典,msg.bidPrice 返回的是该标的最新十档买价,而 indicator.pctChg 返回的就是最新价相比于前价的收益率。本示例的完整回测代码及数据模拟代码见附件。
def onSnapshot(mutable context, msg, indicator){ //查询目前该的持仓 &pos = Backtest::getPosition(context["engine"], msg.symbol) if (indicator.pctChg > 0.01 and pos.longPosition <= context.maxPos and context["open"][msg.symbol] != true){ Backtest::submitOrder(context["engine"], (msg.symbol, context["tradeTime"], 5, msg.offerPrice[0], 100, 1), "buy") context["open"][msg.symbol] = true }}
DolphinDB 的回测引擎支持多种行情消息的策略回测,以满足不同用户的回测需求,除了上述示例展示的 onBar 和 onSnapshot 以外,用户同样可以基于不同的行情数据通过调用相对应的事件回调函数来实现策略,行情的类型通过配置参数的 dataType 配置项指定。
不同的品种同频率的行情数据也稍有差别,如银行间债券快照频率的数据包括到期收益率字段。具体可以参考 Backtest插件该品种的指定频率的行情数据说明,不同类型的行情输入表均支持 DOUBLE、STRING、INT 类型的扩展字段。
除了不同频率的行情以外,DolphinDB 回测引擎不仅支持对各类资产品种(如 “stocks”、“futures”、“options”、 “bond”和 “universal”等)进行单一品种的策略回测,还支持在同一个回测引擎中对多个资产进行联合回测。同时,用户可以通过单一账户或多个账户对相应的多个资产进行现金和持仓管理。针对不同的品种,用户需要在创建引擎时通过配置参数的 strategyGroup 配置项指定策略类型。
当指定配置项 strategyGroup为 “multiAsset” 时,初始资金 cash 配置项为字典,支持使用同一个账户或多个账户分别管理不同资产的资金。如 cashDict["futures, options"]=100000000. 代表 futures 和 options 多资产类型使用同一个资金账户,如 cashDict["futures"]=100000000. 则代表 futures 独立使用一个资金账户。cash 配置项不仅决定了账户资金,还控制子回测引擎和模拟撮合引擎的创建。仅当资产类型在 cash 配置项中被指定时,才会创建对应的回测和模拟撮合引擎。 下面将通过一个股票与期货使用独立资金账户的案例,展示如何在 DolphinDB 中实现多资产混合回测。为简化策略逻辑,选取一只股票和一只期货作为回测标的,基于二者的分钟频 K 线行情,当账户无持仓时触发买入操作。案例所使用的数据及完整回测代码详见附件。
//step 1:选取回测标的def beforeTrading(mutable context){ context["futuresCode"] = "IC2401" context["stockCode"] = "600000"}//step 2:编写策略逻辑def onBar( mutable context, msg, indicator){ longPos = Backtest::getPosition(context.engine, context["stockCode"], "stock").longPosition if(longPos < 0 and context["stockCode"] in msg.keys() ){ price = msg[context["stockCode"]].close symbolSource = msg[context["stockCode"]].symbolSource orderMsg=(context["stockCode"],msg[context["stockCode"]].symbolSource , context.tradeTime, 5, price, ,,100,1,,,) //print("委托订单") Backtest::submitOrder(context.engine, orderMsg,"买入股票",0) } longPos = Backtest::getPosition(context.engine, context["futuresCode"], "futures").longPosition if(longPos<1 and context["futuresCode"] in msg.keys()){ futuresPrice = msg[context["futuresCode"]].close symbolSource = msg[context["futuresCode"]].symbolSource orderMsg=(context["futuresCode"],msg[context["futuresCode"]].symbolSource , context.tradeTime, 5, futuresPrice, ,,100,1,,,) //print("委托订单") Backtest::submitOrder(context.engine, orderMsg,"买入期货",0,"futures") }}//step 3:配置参数config = { startDate:2000.01.01, endDate:2025.12.31, strategyGroup: "multiAsset", cash: { stocks:100000000., futures:100000000. }, dataType:3, matchingMode:3, frequency:0, outputOrderInfo:true, multiAssetQuoteUnifiedInput:false, depth:5, commission: 0.00, tax:0.00}callbacks = { onBar:onBar,beforeTrading:beforeTrading}
DolphinDB 回测引擎从 3.00.2.1 JIT 版本中支持 JIT 优化,只需在创建回测引擎时把 Backtest::createBacktester 函数的 jit 参数设置为 true 即可。JIT 相关内容可以参考 DolphinDB 回测平台使用和性能优化攻略文档。
本章将介绍在使用 DolphinDB 回测引擎过程中应关注的重要事项,涵盖事件回调函数参数的说明、行情数据细节、JIT 优化兼容性等内容。
通过接口 Backtest::appendQuotationMsg(engine, msg) 执行策略回测时报错,通常是由于 msg 的数据结构与策略所配置的行情类型不一致。不同品种或相同品种在不同行情频率下,其行情字段略有差异。建议仔细检查当前行情数据表的字段及其类型是否与相应的行情类型严格匹配。
1.1 示例使用的分钟频数据 DolphinDB 回测插件快速上手
2.2 股票快照行情示例代码 DolphinDB 回测插件快速上手
2.5 多资产回测示例数据及完整代码 DolphinDB 回测插件快速上手
相关文章
金融界2025年8月20日消息,国家知识产权局信息显示,江苏武进液压启闭机有限公司取得一项名为“一种活塞密封圈可形变的液压缸及其启闭机”的专利,授权公...
2025-08-20 0
金融界2025年8月20日消息,国家知识产权局信息显示,润丰源工程集团股份有限公司申请一项名为“一种水库除险加固结构”的专利,公开号CN1205059...
2025-08-20 0
运营商财经网 吴碧慧/文据知情人士向运营商财经网独家透露,天津移动在2024年实现营收规模已突破60亿元,虽然还不敌天津联通,但这几年也算是尽力了,而...
2025-08-20 0
8月12日,在郑州机场T2航站楼24号安检通道,一位手臂打着厚厚石膏的王先生,现场没有拆卸纱布与石膏,轻松愉悦的通过了安全检查,并称赞:“郑州机场这个...
2025-08-20 0
金融界2025年8月20日消息,国家知识产权局信息显示,浙江捷昌线性驱动科技股份有限公司取得一项名为“一种电动推杆”的专利,授权公告号CN223246...
2025-08-20 0
金融界2025年8月20日消息,国家知识产权局信息显示,深圳市前沿材料技术有限公司取得一项名为“一种用于钨粉烧结炉的连续上料装置”的专利,授权公告号C...
2025-08-20 0
8月19日,小米集团发布2025年Q2财报。本季度小米业绩稳中有进,再创历史新高:总营收1160亿元,连续三个季度超千亿,同比增长30.5%;经调整净...
2025-08-20 0
发表评论