Loading ...

FMZ发明者量化平台回测说明

Author: 小草, Created: 2019-07-06 12:15:50, Updated: 2020-05-06 09:11:06

大部分策略在实盘之前都需要回测进行验证,FMZ支持部分品种数字货币现货、期货和永续合约,以及商品期货所有品种。但发明者量化平台的回测机制和常见的onbar回测有所区别,造成了很多新手的困惑。本文将详细说明并解答一些常见的回测问题。

回测系统是如何运作的?

img

如上图所示,回测开始时间到结束时间可以当作一个时间轴,回测时,回测时间点沿轴从左到右移动开始回测,在这个时间点上,只能获取到此点之前的历史数据,策略根据这些数据做出买卖,最终形成盈亏。显然,回测的时间点的分布是离散的,分布的密集程度代表了回测的精度。 当然考虑到回测时间点越密集,所需的时间越长,实际的回测系统需要在精度和效率之间做出取舍。

传统onBar回测机制

onbar回测机制是基于K线的,即每一个K线产生一个回测时间点,在此时间点上可以获取到当前K线的高开低收价格、交易量等信息,以及此时间点之前的历史K线信息。 这种机制的弊端很明显:在一根K线上,只能产生一次买卖,通常依据的价格是K线的收盘价。并且一根K线只能获取到高开低收四个价格,至于在一根K线内价格如何变化的,是最高价先发生、还是最低价先发生等等信息都无从获取。以1小时K线为例,实盘时肯定每隔几秒获取一次行情信息,交易指令也会在盘中发出而不是等待K线结束。onbar回测机制的好处是易于理解,回测速度极快。

FMZ发明者量化平台onTick回测机制

img

上图为FMZ回测设置界面。回测模式分为两种模拟级回测和实盘级回测,下面将分别介绍:

什么是tick

和K线数据不同,tick是具体某个时间点的价格。根据K线数据,我们实际上只知道开盘价和收盘价的发生时间,K线周期内什么时间价格达到最高,是不清楚的。实际上,K线数据也是根据tick生成的。而根据K线数据,也可以模拟出一个K线周期具体tick的变动, 虽然不是真实的tick,但可以让我们的回测精度高一些。并且模拟依据的K线周期可以比回测所用的周期小很多,这样精度就更高了。

模拟级回测

模拟级回测要选择回测所使用的K线周期和底层K线周期。比如策略使用小时线回测,底层K线选择5分钟,那么回测时间点的间隔将以5分钟K线模拟生成的tick为基础,具体表现为最新1小时K线的收盘价不断变动。具体根据K线生成K线内tick的机制和MT4类似,这个帖子里有详细的说明:https://www.fmz.com/bbs-topic/662

img
我们使用一个简单的策略来演示一下这个机制,策略代码:

function main() {
  while(true){
      var records = exchange.GetRecords() //GetRecords可以填参数,获取不同周期K线。
      var ticker = exchange.GetTicker()
      Log('K线收盘价: ', records[records.length-1].Close, 'ticker买一卖一价: ', ticker.Buy, ticker.Sell)
      //js回测不用Sleep,会自动跳到下一个tick。Python需要一个小的休眠时间
  }
}

回测结果: img 每根K线只有开盘和收盘的tick是固定的,中间加上模拟的12个tick,这样一根K线将会形成14个回测时间点。如果回测一天,底层K线周期用5分钟,共有24×12×14 = 4032 时间点,而传统的onBar回测只有24个,精度大幅提高。在一个K线周期内也能完成开仓平仓操作。虽然中间生成的tick是模拟的,但影响不大。回测中,只要买单价大于卖一,卖单价小于买一,就会撮合成交。这种回测方式兼顾了回测速度和精度,推荐大家使用。

实盘级回测

实盘级回测用到了真实的tick,每个时间点的间隔最短只有1s,这种回测的精度到每一秒的变化,但由于数据量大,回测速度慢、回测时间也不能很长。下图为真实的tick。实盘级回测可用于精确的验证策略。 img

回测和实盘的差距

即使实盘级回测和实盘还是有明显的数据不足,如不能获取到成交历史trades、不能获取到实际的深度变化、真实的网络延时等等。即使这样FMZ目前的回测系统也相对完善,还有很多小功能,如模拟网络错误,可以用于测试策略的容错能力,模拟网络延时、绘制行情图标等。

常见问题

为什么只支持几个交易对和交易所能回测?

目前只有几个常见交易对数据,其实策略和品种关系不是很大,已经足够验证策略了。

能模拟BitMEX收取资金费率吗?

可以,选取BitMEX回测可以打开事件记录。 img

回测在那里进行?

JavaScript策略的回测在浏览器中进行,Python可以选择FMZ的服务器或者自己的托管者。

回测日志可以下载吗?

可以,日志右上角有下载按钮

能本地回测吗?

FMZ开源了Python回测引擎。参考: https://www.fmz.com/bbs-topic/1687


More

Linghan 一个小时周期的K线, 每跟K线模拟出12个tick, 共14个tick, 一天总共24*14个数据, 怎么有24*12*14?

Linghan 还是有点不明白. 假设GetRecords设置为5分钟, 返回的数据不应该是每五分钟的一根K线么? 怎么中间有那么多tick级别数据? 不是说只有12个tick么?

Linghan 我看了 草哥... 教程不是很详细... 在本地回测出来的json结果, 没说明是什么东西... 另外啊, 本地能起一个类似在FMZ这样的web界面么? 方便画策略信号和各种图的

小草 可以自定义数据,先把教程看一遍吧

Linghan 果然, 判断小于2000就不计算, 然后就直接从2019年9月开始计算了...我其实自己有数据, 能不能用我自己的数据?

Linghan 我一开始就设置就取最大2000. 那要是长度不够的话, 是不是就gg了

小草 文章里说明了,回测K线是累计的,从1到2000,先判断下长度

小草 文章里说明了,回测信号是累计的,从1到2000,先判断下长度

Linghan ''' def BOLL(): global records, Midline, Band, Upline, Downline Midline = ta.MA(np.array(records.Close), paraA)[-2] Band = ta.STDDEV(np.array(records.Close), paraB)[-2] Upline = Midline + 2 * Band Downline = Midline - 2 * Band ''' IndexError: index -2 is out of bounds for axis 0 with size 1. 我想回测2018~2020年的数据, 就两年, 5分钟K线做信号的, 结果那个计算信号的函数抛出这个... 这是拉数据拉不到啊... HUOBI/OKEx都拉不到

Linghan ''' def BOLL(): global records, Midline, Band, Upline, Downline Midline = ta.MA(np.array(records.Close), paraA)[-2] Band = ta.STDDEV(np.array(records.Close), paraB)[-2] Upline = Midline + 2 * Band Downline = Midline - 2 * Band ''' IndexError: index -2 is out of bounds for axis 0 with size 1. 我想回测2018~2020年的数据, 就两年, 5分钟K线做信号的, 结果那个计算信号的函数抛出这个... 这是拉数据拉不到啊...

小草 一般够了,那个交易所?

Linghan 我看BTCUSD季度合约期货的五分钟K线, 能回测的时间实在是太短了.. 这个有办法解决么?

Linghan 终于搞明白了... 确实有点容易懵逼

小草 K线和tick是不同的,我在文章里说了以下,模拟tick并不是模拟K线

小草 自己打印以下K线就知道了

小草 这是回测啊,你仔细看文章,返回的就是每五分钟的一根K线,只不过最后一根的收盘价会模拟变动。

Linghan emm..可能我表达不是很清楚. 我用GetRecords设置为5分钟, 返回的数据不应该是每五分钟的一根K线么? 获取一天就是288根数据, 我不需要中间那些tick数据来计算信号, 实盘的时候从websocket也拿不到tick数据的, 我怎么把中间这些tick去掉?

小草 什么都不需要做,正常写策略就行。

Linghan 假设我需要用BOLL做突破, 我用288根5分钟K线计算轨道, 我计算信号的时候不需要模拟的tick, 这个应该怎么做?

小草 回测点和K线周期不一样,1根K线内也可以有行情,根据底层K线周期模拟的