准备工作
搭建一套量化系统并非一件容易的事,如果你是一位初出茅庐的程序猿,在下文中如遇到不懂的知识点请自行查阅相关资料,本文也会推荐一些文章和书籍,个人认为作为一名合格的程序猿,最基本的自学能力和探究精神还是需要有的,不要等待别人将答案送到你面前。
本系统采用分布式架构,涉及到的编程语言有:C++、C#、NodeJS,数据库采用MySql,通讯中间件采用ZeroMQ。选择C++的原因有二点,首先考虑到与交易所接口兼容最优化,其次考虑到算法的性能最优化,故所有的后端交易相关应用都采用C++进行编程;选用C#主要原因是为了降低策略开发者的编写难度,毕竟策略开发人员的编程水平没有那么高,并且可快速开发一些可视化回测分析程序;而NodeJS是为了方便开发Web端界面,并且提供一些REST API接口供前端应用调用。最后选用MySql也是为了方便部署,方便使用,并且它的内存数据库还是性能相当不错的,如替换其他数据也可以,如:SqlServer、Oracle、Mongodb等。由于系统采用分布式,为了降低开发难度,应用间数据通讯并非采用原生的tcp/ip协议进行编码,而采用ZeroMQ进行编程,通过几种常用模式,如:REQ/REP、PULL/PUSH、PUB/SUB等,就能轻松进行数据通讯。最后本项目开发工具采用VS2015和VSCode,读者可自行下载。以下所有的项目工程都将基于这两款IDE进行建立。
以上仅仅是编程方面的准备工作,但如果想做好一套量化系统,你必须对业务知识有深刻的了解,不然后面的一些细节你可能无法把控,甚至会引发一些意想不到的灾难。不积跬步,无以至千里;不积小流,无以成江海。让我们一步一个脚印,先把基础打扎实,再正式开始我们的量化系统搭建之行。在此推荐《c++ primer plus》、《C#高级编程》、《代码之美》,交易相关的大家可以参加协会组织的从业人员资格考试,这样能系统的学习基础知识、法律知识等。相信充分做好这些准备后,下文的量化系统搭建会非常轻松、非常有趣。
架构设计
系统架构
本量化系统分为前端和后端,前端主要面向用户,用于策略编写、手工下单、监控、报告分析等;后端将交易和行情进行封装,以及指令路由工作,并提供最简单的接口供前端使用。

以下是行情中心内部架构,考虑到后期接入多家交易所行情,所以将行情接收器独立出来,这样能更好的做到负载均衡,并各自将行情写入内存数据库,供其他应用调用;而行情中心将收集各接收器推送来的行情,封装成统一格式再发布给订阅者。

以下是交易中心与算法工人内部架构,交易中心主要负责接收客户端发送过来的指令,通过风控层后将指令路由至算法工人,由算法工人处理订单逻辑,如:条件单、追单、止损止盈单等,并最终将订单报入交易所场内,同时将回报返回给交易中心,再由交易中心将回报返回给订阅用户。
交易中心还负责路由用户发送的策略指令,并根据指令分发给策略回测工人或者策略仿真工人,对应的去执行回测指令或者启动策略等。

整个量化系统的总架构由以上三个流程图作为核心,后面我们会针对每一个模块进行剖析,最终一步步的去实现出整套量化系统。
数据库结构
- 用户表Users
字段名 |
类型 |
描述 |
UserId |
String |
用户编号 |
UserName |
String |
用户名 |
UserPwd |
String |
密码 |
… |
|
|
- 日志表Logs
字段名 |
类型 |
描述 |
Id |
String |
编号 |
Category |
String |
类别 |
Message |
String |
消息 |
CreateTime |
DateTime |
创建时间 |
… |
|
|
- 合约表Contracts
字段名 |
类型 |
描述 |
Code |
String |
编码 |
ExCode |
String |
交易所编码 |
Name |
String |
合约名 |
Category |
String |
类别 |
Exchange |
String |
交易所 |
Status |
Bool |
状态 |
… |
|
|
- 账户表Accounts
字段名 |
类型 |
描述 |
UserId |
String |
用户编号 |
StaticRight |
Double |
静态权益 |
Fee |
Double |
手续费 |
UsedMargin |
Double |
占用保证金 |
FrozenMargin |
Double |
冻结保证金 |
FrozenFee |
Double |
冻结手续费 |
… |
|
|
- 持仓表Positions
字段名 |
类型 |
描述 |
Id |
String |
编号 |
UserId |
String |
用户编号 |
StrategyId |
String |
策略编号 |
Contract |
String |
合约 |
LongVolume |
Int |
多头数量 |
LongPrice |
Double |
多头均价 |
ShortVolume |
Int |
空头数量 |
ShortPrice |
Double |
空头均价 |
… |
|
|
- 订单表Orders
字段名 |
类型 |
描述 |
OrderId |
String |
订单编号 |
UserId |
String |
用户编号 |
StrategyId |
String |
策略编号 |
OrderType |
String |
订单类型 |
Contract |
String |
合约 |
Side |
String |
买卖 |
InsertPrice |
Double |
报单价格 |
InsertVolume |
Int |
报单数量 |
InsertTime |
DateTime |
报单时间 |
TradedPrice |
Double |
成交价格 |
TradedVolume |
Int |
成交数量 |
TradedTime |
DateTime |
成交时间 |
RealAccount |
String |
真实账号 |
… |
|
|
- 成交表Trades
字段名 |
类型 |
描述 |
TradeId |
String |
成交编号 |
OrderId |
String |
订单编号 |
UserId |
String |
用户编号 |
StrategyId |
String |
策略编号 |
Contract |
String |
合约 |
Side |
String |
买卖 |
TradedPrice |
Double |
成交价格 |
TradedVolume |
Int |
成交数量 |
TradedTime |
DateTime |
成交时间 |
Fee |
Double |
手续费 |
RealAccount |
String |
真实账号 |
… |
|
|
- 结算表Settles
字段名 |
类型 |
描述 |
Id |
String |
编号 |
UserId |
String |
用户编号 |
StrategyId |
String |
策略编号 |
Contract |
String |
合约 |
SettlePrice |
Double |
结算价格 |
LeftVolume |
Int |
剩余数量 |
Profit |
Double |
盈亏 |
Fee |
Double |
手续费 |
CreateTime |
DateTime |
创建时间 |
… |
|
|
- 报告表Reports
字段名 |
类型 |
描述 |
Id |
String |
编号 |
UserId |
String |
用户编号 |
StrategyId |
String |
策略编号 |
InitRight |
Double |
初始权益 |
TotalProfit |
Double |
总盈亏 |
TotalFee |
Double |
总手续费 |
MaxRight |
Double |
最大权益 |
MaxUsedMargin |
Double |
最大占保 |
MaxBack |
Double |
最大回撤 |
TradedDays |
Int |
交易天数 |
LongWinMoney |
Double |
多头盈利 |
LongWinCount |
Int |
多头盈利次数 |
ShortWinMoney |
Double |
空头盈利 |
ShortWinCount |
Int |
空头盈利次数 |
LongLossMoney |
Double |
多头亏损 |
LongLossCount |
Int |
多头亏损次数 |
ShortLossMoney |
Double |
空头亏损 |
ShortLossCount |
Int |
空头亏损次数 |
… |
|
|
- 策略表Strategies
字段名 |
类型 |
描述 |
StrategyId |
String |
策略编号 |
UserId |
String |
用户编号 |
Name |
String |
策略名称 |
Category |
String |
类别 |
Code |
String |
策略代码 |
StrategyParams |
String |
策略参数 |
StrategySettings |
String |
策略配置 |
StrategyWroker |
String |
策略工人 |
RealAccount |
String |
真实账号 |
IsAuto |
Bool |
自动运行 |
CreateTime |
DateTime |
创建时间 |
… |
|
|
- 每日资金表DailyMoneys
字段名 |
类型 |
描述 |
Id |
String |
编号 |
UserId |
String |
用户编号 |
StrategyId |
String |
策略编号 |
Right |
Double |
当日权益 |
Profit |
Double |
当日盈亏 |
Fee |
Double |
当日手续费 |
CreateTime |
DateTime |
创建时间 |
… |
|
|
本量化系统的历史行情数据采用调用第三方接口的方式,因为数据整理也是一项很庞大的工作,一时半会完善不好整个行情数据库。在此毛遂自荐一下我们自己的 EPI金融数据接口,该行情库的数据已经过多次清洗和检验了,准确率能达到95%以上。
以上是整个量化系统的架构设计,后面将详细介绍每个模块的内部设计并进行编码,所有的源码将会发布至Github上,并将本项目命名为Quant。