SimulatedExchangeEngine
DolphinDB 的 SimulatedExchangeEngine 插件实现了一个完整的模拟交易所系统,支持接收行情快照数据与交易员委托订单,实时构建订单簿,支持将不同的订单委托撮合成交。该插件可输出交易明细与订单明细,为量化策略回测提供真实的交易环境模拟。
安装插件
版本要求
DolphinDB Server 2.00.16 和 3.00.4,支持 Linux x86-64。
注:该插件仅支持 DolphinDB 商业版。
安装步骤
-
在 DolphinDB 客户端中使用
listRemotePlugins命令查看插件仓库中的插件信息。注:仅展示当前操作系统和 server 版本支持的插件。若无预期插件,可在 DolphinDB 用户社区进行反馈。
login("admin", "123456") listRemotePlugins() -
使用
installPlugin命令完成插件安装。installPlugin("SimulatedExchangeEngine") -
使用
loadPlugin命令加载插件。loadPlugin("SimulatedExchangeEngine")
接口说明
createSimulatedExchangeEngine
语法
createSimulatedExchangeEngine(name, config, quoteColMap)
详情
创建一个模拟交易所。返回一个句柄,可以用于其他接口。
参数
-
name 字符串标量,交易所唯一标识,不能为空字符串。
-
config 键为 STRING 类型的字典,表示模拟交易所引擎的配置项。目前支持的配置如下表:
| 配置项 | 类型 | 说明 |
|---|---|---|
| marketType | STRING | 必填,市场类型,目前仅支持 “CFETS_XBOND”。 |
| outputInterval | INT | 选填,输出快照的时间间隔,单位为毫秒,默认值为 3000。小于等于 0 或大于等于 1000,小于 0 表示不输出。 |
| sessionBegin | SECOND 类型向量 | 选填,表示快照输出时间区间的起止时刻。传入的时间区间必须按顺序从早到晚递增,且不能重叠。 |
| sessionEnd | SECOND 类型向量 |
-
quoteColMap 一个字典,类型为 (string, string),用于映射行情表中的列名。映射规则为“必须的列名 → 实际表中的列名”。必须的列名如下表所示:
| 名称 | 类型 | 说明 |
|---|---|---|
| symbol | STRING | 标的 |
| symbolSource | STRING | 证券市场 |
| bidSettlType | INT[] | 买清算速度 |
| bidQty | LONG[] | 买单数量列表 |
| bidYield | DOUBLE[] | 报买到期 |
| askSettlType | INT[] | 卖清算速度 |
| askQty | LONG[] | 卖单数量列表 |
| askYield | DOUBLE[] | 报卖到期 |
| channel | STRING | 撮合渠道 |
insertMsg
语法
insertMsg(engine, msg)
详情
插入深度行情表。
参数
-
engine 交易所句柄。
-
msg 行情表。表结构在首次调用接口后将被锁定,不可修改。表中必须包含在创建交易所时,由 quoteColMap 指定的列。
注:
-
行情中 askYield 必须是递减排序,bidYield 必须是递增排序,否则 SimulatedExchangeEngine 行为未定义。
-
askYield、askQty、askSettlType 长度相同;bidYield、bidQty、bidSettlType 长度相同。
submitOrder
语法
submitOrder(engine, msg)
详情
插入用户订单。撤单请使用 cancelOrder。
参数
-
engine 交易所句柄。
-
msg 一个元组,表示用户订单信息。按顺序包含如下信息:
-
symbol:STRING 类型标量,表示标的。
-
symbolSource:STRING 类型标量,表示市场。
-
orderType:整型标量,目前只支持 1,表示限价单。
-
settlType:整型标量,表示清算速度,可选值包括:0-当日清算,1-交易日后一个工作日清算,2-交易日后两个工作日清算。
-
matchPrice:整型标量。目前仅支持 1,表示到期收益率。
-
direction:整型标量。可选值包括:1-买,2-卖。
-
price:浮点型标量,表示价格。
-
qty:整型标量,表示数量。
-
userOrderID,字符串标量,表示用户自定义编号。
-
traderID:字符串标量,表示交易员编号。
-
timeInForce:整型标量,表示委托订单有效性。可选值包括:0-默认,1-FOK,2-FAK。
-
label:字符串标量,表示标签。
-
dropSimulatedExchangeEngine
语法
dropSimulatedExchangeEngine(engine)
详情
删除该交易所。
参数
-
engine 交易所句柄。
getOutputSchema
语法
getOutputSchema(engine, outputType)
详情
获取输出表的结构。
参数
-
engine 交易所句柄。
-
outputType 字符串标量,支持 orderDetails、tradeDetails 以及 snapshot。
snapshot 表结构参见 getSnapshot 章节。
orderDetails 表结构如下:
| 列名 | 类型 | 说明 |
|---|---|---|
| symbol | STRING | 标的 |
| submitTime | TIMESTAMP | 下单时间 |
| writeTime | TIMESTAMP | 写入表时间 |
| symbolSource | STRING | 市场 |
| orderType | INT | 委托类型 |
| settlType | INT | 清算速度 |
| matchPrice | INT | 价格类型 |
| direction | INT | 方向 |
| price | DOUBLE | 价格 |
| qty | LONG | 量 |
| userOrderID | STRING | 客户自定义编号 |
| traderID | STRING | 交易员号 |
| timeInForce | INT | 委托订单有效性 |
| label | STRING | 标签 |
| orderID | LONG | 订单号 |
| status | INT | 委托状态 |
| remainedQty | LONG | 未成交量 |
| turnover | DOUBLE | 成交总额 |
tradeDetails 表结构如下:
| 列名 | 类型 | 说明 |
|---|---|---|
| symbol | STRING | 标的 |
| tradeTime | TIMESTAMP | 成交时间 |
| tradeID | LONG | 成交编号 |
| bidUserOrderID | STRING | 客户自定义买编号 |
| askUserOrderID | STRING | 客户自定义卖编号 |
| symbolSource | STRING | 市场 |
| direction | INT | 方向 |
| tradePrice | DOUBLE | 成交价格 |
| tradeQty | LONG | 成交数量 |
| bidOrderID | LONG | 买委托订单号 |
| askOrderID | LONG | 卖委托订单号 |
| bidTraderID | STRING | 买交易员 |
| askTraderID | STRING | 卖交易员 |
setOutput
语法
setOutput(engine, output)
详情
设置输出表。如果设置了快照表,则每 3 秒获取一次当前快照输出到该表中。
参数
-
engine 交易所句柄。
-
output 键为 STRING 类型的字典,用于设置输出表。字典的 key 支持 orderDetails、tradeDetails 以及 snapshot。
getSnapshot
语法
getSnapshot(engine, [symbolList])
详情
获取快照。
参数
-
engine 交易所句柄。
-
symbolList 可选参数,字符串向量,用于指定 symbol。
返回的表结构如下:
| 列名 | 类型 | 说明 |
|---|---|---|
| symbol | STRING | 标的 |
| timestamp | TIMESTAMP | 时间 |
| bidSettlType | INT[] | 买清算速度 |
| bidQty | LONG[] | 买单数量列表 |
| bidYield | DOUBLE[] | 报买到期 |
| bidParty | ANY | 买报价方,traderID 数组 |
| askSettlType | INT[] | 卖清算速度 |
| askQty | LONG[] | 卖单数量列表 |
| askYield | DOUBLE[] | 报卖到期 |
| askParty | ANY | 卖报价方,traderID数组 |
| lastYield | DOUBLE | 最新成交价 |
| tradeQty | LONG | 总成交数量 |
cancelOrder
语法
cancelOrder(engine, symbol, orderID, [traderID], [label])
详情
根据订单 ID 取消订单,或者根据 traderID 和 label 取消订单。
当 orderID 不为空值时,系统根据指定的订单 ID 执行撤单操作。
当 orderID 为空值时,系统根据 traderID 和 label 撤单。
参数
-
engine 交易所句柄。
-
symbol 字符串标量,表示 symbol。
-
orderID 整型标量,订单 ID。
-
traderID 可选参数,字符串标量,交易员号。
-
label 可选参数,字符串标量,订单标签。
getOrderStatus
语法
getOrderStatus(engine, info)
详情
根据订单 ID 或者交易员号获取订单信息。返回的表的结构与 orderDetails 表相似,仅缺少 writeTime 列。
注:
-
如果只传入订单 ID,插件需要在全部交易订单中进行查找,可能会影响查询性能。建议同时传入 symbol 参数,以缩小查询范围并提升查询速度。
-
通过
setOutput设置 orderDetails 表并订阅该表,可在订单状态变化时实时接收通知。
参数
-
engine 交易所句柄。
-
info 查询条件参数。为字符串标量时表示交易员号,为整型数值时表示订单 ID。
resetSimulatedExchangeEngine
语法
resetSimulatedExchangeEngine(engine)
详情
重置交易所。取消所有尚未成交的用户订单,清空内部的所有行情。
参数
-
engine 交易所句柄。
getEngineList
语法
getEngineList()
详情
获取当前存在的所有交易所引擎。返回一个 key 为 name、value 为 engine 的字典对象。
使用示例
// 安装插件
login("admin", "123456")
listRemotePlugins()
installPlugin("SimulatedExchangeEngine")
loadPlugin("SimulatedExchangeEngine")
// 创建模拟交易所引擎
name = "cfets_xbond_engine"
config = dict(STRING, ANY)
config["marketType"] = "CFETS_XBOND"
config["outputInterval"] = 3000
quoteColMap = dict(
`symbol`symbolSource`bidSettlType`bidQty`bidYield`askSettlType`askQty`askYield`channel,
`symbol`symbolSource`bidSettlType`bidQty`bidYield`askSettlType`askQty`askYield`channel
)
engine = createSimulatedExchangeEngine(name, config, quoteColMap)
// 创建输出表
orderDetails = table(1000:0, `symbol`submitTime`writeTime`symbolSource`orderType`settlType`matchPrice`direction`price`qty`userOrderID`traderID`timeInForce`label`orderID`status`remainedQty`turnover, [STRING,TIMESTAMP,TIMESTAMP,STRING,INT,INT,INT,INT,DOUBLE,LONG,STRING,STRING,INT,STRING,LONG,INT,LONG,DOUBLE])
tradeDetails = table(1000:0, `symbol`tradeTime`tradeID`bidUserOrderID`askUserOrderID`symbolSource`direction`tradePrice`tradeQty`bidOrderID`askOrderID`bidTraderID`askTraderID, [STRING,TIMESTAMP,LONG,STRING,STRING,STRING,INT,DOUBLE,LONG,LONG,LONG,STRING,STRING])
snapshot = table(1000:0, `symbol`timestamp`bidSettlType`bidQty`bidYield`bidParty`askSettlType`askQty`askYield`askParty`lastYield`tradeQty, [STRING,TIMESTAMP,INT[],LONG[],DOUBLE[],ANY,INT[],LONG[],DOUBLE[],ANY,DOUBLE,LONG])
// 设置输出表
output = dict(STRING, ANY)
output["orderDetails"] = orderDetails
output["tradeDetails"] = tradeDetails
output["snapshot"] = snapshot
setOutput(engine, output)
msg = table(
["2024001", "CFETS_XBOND"] as symbol,
["CFETS", "CFETS"] as symbolSource,
[[0, 1], [0, 1]] as bidSettlType,
[[1000000, 2000000], [1000000, 2000000]] as bidQty,
[[2.5, 2.6], [2.5, 2.6]] as bidYield,
[[0, 1], [0, 1]] as askSettlType,
[[1000000, 2000000], [1000000, 2000000]] as askQty,
[[2.7, 2.8], [2.7, 2.8]] as askYield,
["CHANNEL1", "CHANNEL1"] as channel
)
insertMsg(engine, msg)
// 提交用户订单
// 买单
buyOrder = ("2024001", "CFETS_XBOND", 1, 0, 1, 1, 2.65, 1000000, "BUY_ORDER_001", "TRADER001", 0, "BUY_LABEL")
submitOrder(engine, buyOrder)
// 卖单
sellOrder = ("2024001", "CFETS_XBOND", 1, 0, 1, 2, 2.75, 1000000, "SELL_ORDER_001", "TRADER002", 0, "SELL_LABEL")
submitOrder(engine, sellOrder)
// 获取快照
snapshotData = getSnapshot(engine)
select * from snapshotData
// 获取订单状态
orderStatus = getOrderStatus(engine, "BUY_ORDER_001")
select * from orderStatus
// 撤单
cancelOrder(engine, "2024001", -1, "TRADER001", "BUY_LABEL")
// 重置交易所
resetSimulatedExchangeEngine(engine)
// 删除交易所
dropSimulatedExchangeEngine(engine)
// 获取交易所列表
engineList = getEngineList()
