内容简介:我曾经花了一周时间开发了一个股票模拟交易后台程序,使用Node.js。代码量很少,能完成基本功能。下面给大家介绍一下其实现步骤。其中模拟交易和真实交易最大的不同是,真实交易采用撮合制,逻辑较为复杂。模拟交易采用更简单的即时成交机制,只要符合条件,订单立即成交。这个后台程序一共就两个js文件,一个用于处理成交,即判断成交条件,写数据库。另一个处理其他逻辑。当然这里面没有提到获取股票实时价格的问题,这是另一个系统完成,我们通过消息队列实时获取我们所关心的股票的价格,这是另一个话题了。
我曾经花了一周时间开发了一个股票模拟交易后台程序,使用Node.js。代码量很少,能完成基本功能。下面给大家介绍一下其实现步骤。
基本功能
- 开户
- 搜索股票
- 挂单(多单、空单)
- 撤单(主动、被动)
- 成交(非撮合)
- 除权、除息
- 查询
- 订单状态
- 持仓
- 今日委托
- 今日成交
- 历史委托
- 历史成交
- 挂单列表
- 账户详情(总收益,收益率,总资产)
其中模拟交易和真实交易最大的不同是,真实交易采用撮合制,逻辑较为复杂。模拟交易采用更简单的即时成交机制,只要符合条件,订单立即成交。
这个后台程序一共就两个js文件,一个用于处理成交,即判断成交条件,写数据库。另一个处理其他逻辑。当然这里面没有提到获取股票实时价格的问题,这是另一个系统完成,我们通过消息队列实时获取我们所关心的股票的价格,这是另一个话题了。
这个后台程序以一个node.js进程的方式运行,一个10秒一次的定时器执行成交判断。(真实交易所的撮合器也是10秒钟一次)
此外有一个WebAPI Server接受来自客户端的请求。所以总体架构,可以看成是一个微服务组成的系统。
数据库设计
账户表
Id` int(11) NOT NULL AUTO_INCREMENT COMMENT '模拟账户', `MemberCode` varchar(20) DEFAULT '' COMMENT '用户编号', `AccountNo` varchar(255) DEFAULT NULL COMMENT '账号', `TranAmount` int(11) DEFAULT NULL COMMENT '模拟账户入资金额', `CommissionLimit` decimal(20,4) DEFAULT '2.9900' COMMENT '最低佣金', `CommissionRate` decimal(20,4) DEFAULT '0.0125' COMMENT '佣金比例', `Cash` decimal(20,4) DEFAULT '0.0000' COMMENT '现金', `UsableCash` decimal(20,4) DEFAULT '0.0000' COMMENT '可用资金', `Status` tinyint(4) DEFAULT '1' COMMENT '账号状态:1正常', `AccountType` tinyint(4) DEFAULT '1' COMMENT '账号类型:1现金账号,2保证金账号', `CreateTime` datetime DEFAULT NULL COMMENT '创建时间', PRIMARY KEY (`Id`)
其中一个用户可以对应多个账户,所以有一个AccountNo作为区分。 TranAmount为初始资金,用于重置账户。佣金字段用于模拟交易的手续费和税费。可用资金字段是,当用户挂单的时候有一部分资金处于冻结状态,可用资金就是去除冻结资金的金额。
订单表
Id` int(11) NOT NULL AUTO_INCREMENT COMMENT '模拟交易订单表', `MemberCode` varchar(20) DEFAULT '' COMMENT '用户编号', `AccountNo` varchar(20) DEFAULT '' COMMENT '模拟账号', `SecuritiesType` varchar(10) DEFAULT '' COMMENT '股票类型:us,hk,sh,sz', `SecuritiesNo` varchar(20) DEFAULT '' COMMENT '股票编号', `CPrice` decimal(20,4) DEFAULT '0.0000' COMMENT '委托价', `Price` decimal(20,4) DEFAULT '0.0000' COMMENT '价格', `OrderQty` decimal(20,4) DEFAULT '0.0000' COMMENT '股票数据量', `Side` char(1) DEFAULT '' COMMENT '交易类型:B买、S卖', `OrdType` tinyint(4) DEFAULT '1' COMMENT '订单类型:1市场订单、2限价订单、3止损订单、4做空市场订单、5做空限价订单、6做空止损订单', `execType` tinyint(4) DEFAULT '1' COMMENT '执行类型:0新的,1成交、2取消、3拒绝', `Commission` decimal(20,4) DEFAULT '2.9900' COMMENT '佣金', `Reason` tinyint(4) DEFAULT '0' COMMENT '订单拒绝理由:0正常、1资金不足、2仓位不足、3超时失效', `Amount` decimal(20,4) DEFAULT '0.0000' COMMENT '金额', `EndTime` datetime DEFAULT NULL COMMENT '订单截止时间', `CreateTime` datetime DEFAULT NULL COMMENT '订单时间', `TurnoverTime` datetime DEFAULT NULL COMMENT '成交时间', PRIMARY KEY (`Id`)
这是最重要的两张表,其他几张表就不罗列详细的内容,只做简单说明
- 资产表(记录浮动盈亏,持仓金额,各种时间范围的收益率)
- 额外津贴记录表(记录除权,除息)
- 资金记录表(记录特殊资金变动)
- 仓位表
- 仓位记录表(记录仓位变化)
- 做空仓位记录表
- 排行榜
挂单
挂单的核心就是向数据库插入一条记录,不过即便是简洁的js代码,也差不多写了80行代码。 首先就是一系列的判断,是否可以创建订单。
- 参数是否在取值范围内。
- 市价单类型,判断是否开市,未开盘时间段不能创建订单。
- 账户异常状态不能创建订单。
- 如果是卖多单,或者买空单,则要把仓位数据取出来判断,是否仓位够扣。
- 如果是买多单,或者卖空单,则要计算扣除佣金(手续费)后可用资金够不够。
- 如果是限价单或者是止损单,则判断价格设置是否在有效范围内。 然后执行一个数据库事务,插入一条订单记录,同时修改可交易仓位或者可用资金。
撤单
撤单比挂单简单许多。主要步骤就是先判断订单是否存在,然后修改订单状态,同时修改可交易仓位或者可用资金。
模拟交易主进程
系统每隔10秒执行一次逻辑。
所有订单缓存策略
如果每隔10秒钟从数据库读取所有订单的话,效率会很低,而且过多占用数据库IO资源。所以订单数据都缓存在成交判断的进程内存中。将来也可以升级为使用 redis 等内存数据库来存储。 当有订单创建的时候,通过消息队列通知进程。当进程重启的时候,从数据库读取数据进行初始化。
超时订单处理
有些订单一直没有满足成交条件,但已经超过交易时间,所以要进行处理。(订单状态设置为拒绝)
成交判断
未开盘则跳过。 根据订单类型判断是否达到成交条件
'订单类型:1市场订单、2限价订单、3止损订单、4做空市场订单、5做空限价订单、6做空止损订单' Price:订单设置的价格 price:当前股价 B:买入 S:卖出
let trigge = false switch (OrdType) { case 1: trigge = true; break; case 2: case 3: trigge = Side == "BS" [OrdType - 2] ? (Price >= price) : (Price <= price) break; case 4: trigge = true; break; case 5: case 6: trigge = Side == "BS" [6 - OrdType] ? (Price >= price) : (Price <= price) break; }
执行成交
最初是用程序执行的,后来为了执行效率和数据一致性,采用存储过程。 首先,我们需要查询出账户的现金和可用资金,以及仓位信息。 如果是卖多或者买空(减少持仓,增加现金),我们计算出此时需要增加的金额,当然这个时候可能出现仓位不够的情况,就拒绝订单。 如果是买多或者卖空(增加持仓,减少现金),我们就需要计算此时需要扣除的金额,如果出现可用金额不足,就拒绝订单。 最后,我们修改账户的实际金额和可用金额,写入持仓记录和现金变化记录,修改订单状态为已成交状态。
信息查询
普通数据库查询,这里不多赘述了。
除权、除息
由于模拟交易系统无法第一时间自动得到除权和除息的消息,所以当需要进行除权和除息的操作的时候,可能用户已经发生成交的订单。这时候需要根据持仓记录变更表进行一些计算,恢复正确的持仓,如果是除息就是根据现金记录变更表,进行资金重新计算。最后我们把这次操作的日志记录下来。
以上所述就是小编给大家介绍的《原 荐 Node.js股票模拟交易后台》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 飞特后台管理系统 3.0:不仅仅是后台,还有商城模块
- Linux 后台运行任务 nohup 结合 & 用法以及如何精准查找进程并 kill 后台任务实践
- TIMO 后台管理系统 v2.0 发布,带来全新的项目结构,支持前后台模块分离部署!
- 电商后台设计:系统消息
- APP后台架构设计
- 网站重构-后台服务篇
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
随机密码生成器
多种字符组合密码
Base64 编码/解码
Base64 编码/解码