一招搞定WonderTrader本地仿真环境

image

前言

  最近群里的小伙伴们都在讨论simnow停用的事情,从3月31日开始,要持续一个半月,不出意外的话也要5月中旬才能恢复。因而不少搞CTA的研发人员可能最近都面临着到哪里去找仿真环境的问题。
  笔者不禁得想起来,若干年前市面上尚未simnow的时候,要找一个期货仿真环境真的是很麻烦。一方面要看期货公司是否是部署了仿真环境,只有期货公司有仿真环境才好测试;另外一方面,可以交易的交易所和合约也是很是有限的;并且,全部的订单都须要对手盘,否则根本不会撮合,因此在测试的过程当中还须要请期货公司的人帮忙下对手单,要否则就只有本身搞自成交了。
  本文主要内容就是介绍如何利用WonderTrader搭建本地仿真环境python

TraderMocker简介

  WonderTraderv0.3.6发布的时候,发布过一个TraderMocker模块,基于该模块用户能够很是容易地搭建一个纯本地的仿真环境,而不用依赖任何第三方环境。
  笔者最初在设计TraderMocker的时候,正在给WonderTrader适配股票交易。当时接入的是中泰XTP接口,XTP比较流行也比较容易接入,有互联网的测试环境,API也很是友好。
  不过市面上不少股票测试环境多少都有一些问题,总结下来大概以下:git

  • 有些仿真环境是基于撮合的,若是没有对手盘,根本没法成交
  • 有些仿真环境是按概率撮合的,若是下单时没有成交,那就永远不会成交了,不符合正常的撮合逻辑
  • 有些仿真环境多是没有接入实时行情,因此无论当前什么价格,价格如何变更,成交价都是挂单价

  显然在这样的仿真环境下测试,策略仿真的结果实际上是有很大的迷惑性的。在这样的状况下,笔者便决定本身开发一个仿真环境。可是WonderTrader做为一个量化交易框架,自己都是各用户独立部署的,也没有中心化的服务,开发一套C/S的仿真环境,还须要硬件投入。对于WonderTrader这样的开源平台来讲,成本过高的话是不现实的。另外仿真环境的部署通常要根据市场、品种分别部署,对于WonderTrader这样面向全市场全品种的平台来讲,成本就更是翻了好几倍了。笔者纵然愿意分享源码,可是也没有办法持续性的投入资金去维护这样的仿真服务。基于这些基本考量,TraderMocker这种全本地化的、去中心的仿真模块就应运而生了。github

  为了尽可能的模拟真实的接口调用,TraderMocker在设计上也有一些特色:json

  • 异步执行segmentfault

    异步执行的主要目的是为了还原真实交易的事件发生顺序。如下单为例,生产环境下,调用下单接口遵循如下数据: 下单接口调用-> 下单结果返回-> 订单回报-> 成交回报。若是不采用异步执行的机制,那么就会出现下单接口尚未返回的时候,已经收到订单回报和成交回报了,这样就不符合生产环境的真实场景了。
  • 根据价格撮合session

    TraderMocker天然不多是一个彻底的仿真环境,因此撮合的机制也相对简单。可是为了尽可能模拟实盘环境, TraderMocker会严格按照价格优先的机制进行撮合。这里的撮合,指的是不须要对手盘的撮合,即只要价格条件知足,即直接撮合成交,推送订单回报和成交回报。
  • 支持不一样的品种架构

    TraderMocker做为一个辅助的简化的本地仿真模块,要充分考虑对不一样的品种的支持。这样才能增长 TraderMocker的应用场景。

  基于以上的设计原则,TraderMocker也表现出一些特色:框架

  • 仿真的程度有限异步

    TraderMocker毕竟不是真正的撮合系统,只是利用行情对订单作一个仿真处理。并且接入的行情,就算是期货,也是 500ms一笔的快照。另外,考虑到不一样行情源档位不一样,因此撮合处理的时候只利用了买一卖一的数据。 TraderMocker对订单之间的竞争也不考虑进去,统一按照最新的 tick的委托量进行处理。
  • 不适合大单测试async

    TraderMocker并无处理订单对限价订单簿的冲击。主要考虑到期货行情只有一档,没法进行冲击的处测算,因此就简化了。因此当一个订单的委托价格高于对手价的时候,一次撮合不完会等到下一笔 tick进来再利用对手价进行撮合,这显然不大符合真实场景。所以大单仿真的还原程度会更低,参考性也更低了。
  • 不作验资操做

    TraderMocker由于其特殊性,不会进行资金检查,只要合法的订单都能下单成功。一方面是由于 TraderMocker是为通用性设计的,因此没法兼顾全部的币种,若是增长验资的机制会增长复杂性。另一方面, WonderTrader1+N执行架构,其实是隔绝了策略对资金的关注,即便作验资,也没法将问题传递给策略。
  • 不作结算处理

    TraderMocker为了简化处理,不会进行结算处理。若是引入结算机制,会增长复杂性,并且还会要求仿真器一直在线直到接收到结算价为止。可是在策略的实操中,其实都主要关心的仍是进场价和出厂价,结算的意义对于策略来讲并不大。不过若是不结算,全部的持仓都是今仓,所以对于有些品种来讲,仿真环境中的手续费的设置就须要把平今设置为跟平昨一致。
  • 订单都在内存中

    对于 TraderMocker这样的简易仿真模块, 只会把必要的数据落地。目前 TraderMocker只会保存持仓数据,而 订单数据和成交数据都只在内存中。一单平台重启,订单和成交就都都没有了。
  • 交易指令简化

    TraderMocker为了兼容不一样的品种,因此 只能实现通用的指令,即 买卖和撤单的指令。其余的特殊指令就不支持了,好比 ETF申赎、期权的报价和执行等指令。

  固然TraderMocker只是笔者仓促写出来的一个简易的仿真模块,有不少仿真功能由于使用场景有限,并无彻底实现。若是各位读者有兴趣的话,能够自行根据本身的需求进行完善。到时候若是愿意分享给你们的话,也能够提交一个PR

如何搭建本地仿真环境

  前文介绍了一下TraderMocker模块,下面本文就将介绍如何在利用WonderTrader搭建这样的本地仿真环境。搭建本地仿真环境,须要用到datakit_futhft_fut_mocker两个demo。这两个demo笔者已经提交到wtpy/demos下,有须要的读者能够自行获取,若是master分支没有的话,请到dev分支下载便可。

  • 行情配置
    datakit_fut是经过CTP接口落地行情数据的数据组件demo,基本配置以下:

    {
    "basefiles":{
        "session":"./common/sessions.json",
        "commodity":"./common/commodities.json",
        "contract":"./common/contracts.json",
        "holiday":"./common/holidays.json"
    },
    "writer":{
        "path":"./FUT_Data/",
        "savelog":false,
        "async":false,
        "groupsize":20
    },
    "parsers":[
        {
            "active":true,
            "module":"ParserCTP.dll",
            "front":"tcp://180.168.146.187:10111",
            "broker":"9999",
            "user":"你的SIMNOW帐号",
            "pass":"你的SIMNOW密码",
            "code":"CFFEX.IF2005,SHFE.au2012"
        }
    ],
    "broadcaster":{
        "active":true,
        "bport":3997,
        "broadcast":[
            {
                "host":"255.255.255.255",
                "port":9001,
                "type":2
            }
        ]
    }

在使用的时候,将parsers小节的CTP前置和帐号密码改为生产环境,并将code改为本身须要的合约代码进行订阅,而后启动runDT.py就能够正常运行了。
行情组件运行截图

  • 仿真配置
    hft_fut_mocker则是从UDP广播通道接入行情,并调用TraderMocker进行仿真,配置以下:

    {
    "basefiles":{
        "session":"./common/sessions.json",
        "commodity":"./common/commodities.json",
        "contract":"./common/contracts.json",
        "holiday":"./common/holidays.json",
        "hot":"./common/hots.json"
    },
    "env":{
        "name":"hft",
        "mode": "product",
        "product":{
            "session":"TRADING"
        },
        "filters":"filters.json",
        "fees":"fees.json",
    },
    "data":{
        "store":{
            "path":"./FUT_Data/"
        }
    },
    "traders":[
        {
            "active":true,
            "id":"mocker",
            "module":"TraderMocker.dll",
            "front":"mocker://localhost",
            "mockerid":9999,
            "span":100,
            "newpx":true,
            "maxqty":100,
            "minqty":1,
            "user":"mocker9999",
            "udp_port":9001,
            "savedata":true
        }
    ],
    "parsers":[
        {
            "active":true,
            "id":"parser1",
            "module":"ParserUDP.dll",
            "host":"127.0.0.1",
            "bport":9001,
            "sport":3997,
            "filter":""
        }
    ],
    "bspolicy":"actpolicy.json"
    }

从上面的配置能够看出,TraderMocker仿真器,要从udp广播通道接收最新的行情,才能进行撮合。可能有人会有疑问:为何不从行情通道经过WonderTrader直接向TraderMocker传递行情数据呢?其实也很好解释,由于Trader模块解耦之后,WonderTrader只和Trader交互交易数据,而行情数据,不在接口支持的数据范围内,因此TraderMocker只能本身解决行情接入的问题。所以TraderMocker天然就会依赖数据伺服组件提供的行情广播服务了。

配置修改好了之后,再检查一下策略启动入口:

from wtpy import WtEngine,EngineType
from strategies.HftStraDemo import HftStraDemo

if __name__ == "__main__":
    #建立一个运行环境,并加入策略
    engine = WtEngine(EngineType.ET_HFT)
    engine.init('./common/', "config.json")
    engine.commitConfig()

    straInfo = HftStraDemo(name="hft_IF", code="CFFEX.IF.2104", expsecs=5, offset=100, freq=0)
    engine.add_hft_strategy(straInfo, 'mocker')

    engine.run()

    kw = input('press any key to exit\n')

最后,运行run.py就能够正常进行仿真测试了,如图:
仿真运行截图
若是有须要进行股票仿真的,只须要修改./common目录下相应的基础文件,并修改配置文件中的行情接入模块的配置文件便可。若有不明白的地方,读者也能够私信咨询笔者。

结束语

  如何利用WonderTrader的仿真模块TraderMocker来搭建本地的仿真环境,总结下来就是两个步骤:先运行一个数据伺服,再运行仿真环境。简单的两个步骤,就能够搞定一个仿真环境。相信对于有须要的人来讲,这是一个很轻松的事情。
  对于想用simnow的用户来讲,在simnow缺位的这段时间,只须要一个CTPs实盘帐号便可进行仿真测试。对于那些不知足于券商提供的股票仿真环境的人来讲,本文介绍的这个攻略也许能够提高你仿真测试的效率。
  固然,笔者水平有限,TraderMocker的开发也比较仓促,不免有不少错漏之处,各位读者在使用的时候还须要自行判断一下是否知足本身的需求。另外,仿真毕竟不是实盘,策略的表现是否合理还须要各位仔细辨别。

  最后再安利一下WonderTrader
  WonderTrader旨在给各位量化从业人员提供更好的轮子,将技术相关的东西都封装在平台中,力求给策略研发带来更好的策略开发体验。

WonderTradergithub地址:https://github.com/wondertrad...

WonderTrader官网地址:https://wondertrader.github.io

wtpygithub地址:https://github.com/wondertrad...


市场有风险,投资需谨慎。以上陈述仅做为对于历史事件的回顾,不表明对将来的观点,同时不做为任何投资建议。

相关文章
相关标签/搜索