经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 其他 » 区块链 » 查看文章
使用JavaScript实现量化策略并发执行
来源:cnblogs  作者:fmzcom  时间:2019/6/29 11:58:37  对本文有异议

本文代码和文章发在FMZ发明者比特币量化交易平台上:

使用JavaScript实现量化策略并发执行--封装Go函数 - 发明者量化?www.fmz.com

在实现量化策略时,很多情况下,并发执行可以降低延时提升效率。以对冲机器人为例,需要获取两个币的深度,顺序执行的代码如下:

  1. var depthA = exchanges[0].GetDepth()
  2. var depthB = exchanges[1].GetDepth()

  

请求一次rest API存在延时,假设是100ms,那么两次获取深度的时间实际上不一样,如果需要更多的访问,延时问题将会更突出,影响策略的执行。

JavaScript由于没有多线程,因此底层封装了Go函数解决这个问题,但由于设计机制,实现起来较为繁琐。

  1. var a = exchanges[0].Go("GetDepth")
  2. var b = exchanges[1].Go("GetDepth")
  3. var depthA = a.wait() //调用wait方法等待返回异步获取depth结果
  4. var depthB = b.wait()

  

在大多数简单情况下,这样写策略并无问题。但注意到每次策略循环都要重复这个过程,中间变量a,b实际上只是临时辅助。如果我们的并发任务非常多,就要另外纪录a和depthA,b和depthB之间的对应关系,当我们的并发任务不确定时,情况就更加复杂。因此,我们希望实现一个函数:当写Go并发时,同时绑定一个变量,当并发运行结果返回时,结果自动赋值给变量,这样就省去了中间变量,使程序更加简洁。具体实现如下:

  1. function G(t, ctx, f) {
  2. return {run:function(){
  3. f(t.wait(1000), ctx)
  4. }}
  5. }

  

我们定义了一个G函数,其中参数t是将要执行的Go函数,ctx是记录程序上下文,f为具体赋值的函数。等会就会看到这个函数的作用。

这时,整体的程序框架可以写为类似于“生产者-消费者”模型(有一些区别),生产者不断发出任务,消费者将它们并发执行,一下代码仅为演示,不涉及到程序的执行逻辑。

  1. var Info = [{depth:null, account:null}, {depth:null, account:null}] //加入我们需要获取两个交易所的深度和账户,跟多的信息也可以放入,如订单Id,状态等。
  2. var tasks = [ ] //全局的任务列表
  3.  
  4. function produce(){ //下发各种并发任务
  5. //这里省略了任务产生的逻辑,仅为演示
  6. tasks.push({exchange:0, ret:'depth', param:['GetDepth']})
  7. tasks.push({exchange:1, ret:'depth', param:['GetDepth']})
  8. tasks.push({exchange:0, ret:'sellID', param:['Buy', Info[0].depth.Asks[0].Price, 10]})
  9. tasks.push({exchange:1, ret:'buyID', param:['Sell', Info[1].depth.Bids[0].Price, 10]})
  10. }
  11. function worker(){
  12. var jobs = []
  13. for(var i=0;i<tasks.length;i++){
  14. var task = tasks[i]
  15. tasks.splice(i,1) //删掉已执行的任务
  16. jobs.push(G(exchanges[task.exchange].Go.apply(this, task.param), task, function(v, task) {
  17. Info[task.exchange][task.ret] = v //这里的v就是并发Go函数wait()的返回值,可以仔细体会下
  18. }))
  19. }
  20. _.each(jobs, function(t){
  21. t.run() //在这里并发执行所有任务
  22. })
  23. }
  24. function main() {
  25. while(true){
  26. produce() // 发出交易指令
  27. worker() // 并发执行
  28. Sleep(1000)
  29. }
  30. }

  

看上去兜了一圈只实现了一个简单功能,实际上大大简化了代码复杂程度,我们只需关心程序需要产生什么任务,由worker()程序自动将他们并发执行,并返回相应的结果。灵活性提升了很多。

原文链接:http://www.cnblogs.com/botvsing/p/11106147.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号