我们用fmz做了在线的一个网格交易回测功能

Author: 永赢量化-1, Created: 2020-10-18 23:56:01, Updated:

回到原点

之前一直在找能实时回测的工具,研究一段时间vnpy感觉改成接口还是太麻烦了。 最后还是翻到了fmz的新手指引中的文档 里面发现可以实现我们要的功能,拿出来用了一波,半年了跟大家探讨一下。 顺便吐槽一下fmz的文章真是太少了,这么有用竟然在新手指引里,当时还是通过发帖问了一下才明白。

首先就是用户可以自主选择开始时间和结束时间,所以 img

这个东西就需要进行参数化:

img 感觉很笨的方法,不知道有没有什么函数可以初始化~

self.grid_setting = {
          "min_price": min_price,
          "max_price": max_price,
          "grid_diff": grid_diff,
          "re_diff": grid_diff,
          "total_amount_B": total_amount_B
      }

网格配置参数:最小,最大价格,格子的分布间隔和重新挂单的间隔。

以上都是用户提交的参数。

主要的bus函数为

    def bus(self):
      params = gen_params(self.begin, self.end, self.currency, self.balance, self.stocks)
      task = VCtx(params)
      done = self.train()
      ret = task.Join(True)
      benefit_cal = self.cal_benefit(ret,done)
      result = {}
      result['done'] = done
      result['ret'] = benefit_cal
      return result
  • 通过刚才的gen_params函数获取fmz的回测配置
  • 跑训练函数
  • 根据fmz返回的数据结构,计算收益率和显示交易记录

调用task.Join()将结束回测任务,返回净值数据。Join参数不传True指返回原始未分析的回测结果,结束后不能再调用交易或行情相关函数。

通过文档,我在猜策略结果返回的东西的意思。。

附上fmz返回的收益数据的代码计算的

  def cal_benefit(self,ret,done):
      #计算相隔多少天
      day_begin =  datetime.datetime.strptime(self.begin, '%Y-%m-%d %H:%M:%S')
      day_end =  datetime.datetime.strptime(self.end, '%Y-%m-%d %H:%M:%S')
      days = (day_end - day_begin).days
      begin = ret.iloc[0].net
      end = ret.iloc[-1].net
      fee = ret.iloc[-1].fee
      #计算一共多少次套利
      df = pd.DataFrame(done)
      #如果没有成交记录
      if len(done) == 0:
          benefit_cal = {}
          benefit_cal['benefit'] = 0
          benefit_cal['count'] = 0
          benefit_cal['fee'] = 0
          benefit_cal['benefit_p'] = 0
          return benefit_cal

      buy_count = len(df[df['type'] == 'buy'])
      sell_count = len(df[df['type'] == 'sell'])
      count = min(buy_count , sell_count)
      benefit = count * self.grid_diff * float(done[0]['amount'])
      benefit_cal = {}
      benefit_cal['benefit']= benefit
      benefit_cal['count']= count
      benefit_cal['fee']= fee
      print(benefit_cal)
      per = benefit / self.total_amount_B * 360 / days
      print(per)
      benefit_cal['benefit_p']= round( per , 4)
      return benefit_cal

对了。感觉有点乱,我先讲一下我们的网格的思路:

采用挂单检查的思路进行

  • 首先根据用户的参数初始化网格
  • 初次挂单
  • 定时检查挂单的成交情况,根据买卖单再重新挂单
          while True:
              Sleep(1000 * 60 * 5)
              if 'refreash_data_finish!' != mid.refreash_data():
                  continue
              # 初始化网格
              if not init_flag:
                  cur_price = mid.ticker['Last']
                  grid_list = grid.cal_grid_list(cur_price)
                  init_flag = True

              # 开始挂单
              if not place_flag:
                  grid.place_orders()
                  place_flag = True

              # 开始检查订单状态及时挂单
              grid.check_order_update()
              done = grid.done

大概就是这样了,可能初次看比较懵。

这次想分享的主要是想表达fmz在14天内回测的速度基本可以满足用户在前端等待的时间,长了就有点慢了,是一个量化回测的作为接口的好工具,赞一个!

对了,这次还是回来宣传一波交易比赛的,我们永赢量化团队搞了一个交易比赛,免费参与。只要大家提供查询API即可报名成功,作为一个双周赛,撸点我们的奖金也很好。留个联系方式 fengye607.不知道这样说可以不,小草不要删我,我连平台的地址都不发出来,╭(╯^╰)╮


More

小草 你是需要获取实时行情,然后模拟回测的结果。这样会有一些麻烦,如果只是单交易对可以试试自己写个回测引擎,也不复杂