FMZ量化平台策略编写初级教程(必看)

Author: 小草, Created: 2019-08-13 17:47:27, Updated: 2021-08-06 10:29:46

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

FMZ平台回测分模拟级回测和实盘级回测两种。模拟级回测根据底层K线周期生成模拟的tick,每个底层K线周期上将生成14个回测时间点,而实盘级则是真实收集的tick,大约几秒就有一次,目前部分支持了真实的深度(包含20档),真实的逐笔成交。 数据量很大,回测速度慢,因此不能回测特别长的时间。FMZ的回测机制可以使策略在一根K线上交易多次,避免了只能收盘价成交的情况,更加精准又兼顾了回测速度。具体的说明可参考:https://www.fmz.com/digest-topic/4009

回测的策略框架和实盘相同,都是一个死循环。由于回测是在不同回测点上跳跃,此时可以不用Sleep,在一个循环结束会自动跳到下一个时间点。但Python由于程序机制,需要强制一个Sleep(10),以避免卡死。

回测的撮合

回测引擎会根据用户下单价和回测时间点的盘口价格撮合,如果买价高于卖一,以卖一成交。如果无法成交,就会产生挂单。要保证成交需要加滑点。如果回测时发生了开不了仓或平不掉的情况,检查是不是有未成交订单造成的仓位冻结。

回测页面设置

img

  • 1.回测页面的选择,左侧是策略编辑页面。
  • 2.回测起始结束时间,由于数据不完整,回测可能直接从有数据的时间开始。
  • 3.回测GetRecords()函数的默认周期,也可以在代码中指定周期参数。
  • 4.回测机制的选择。
  • 5.展示或隐藏跟多回测设置。
  • 6.最大日志数、收益数据数、图表数据数等,为了防止数据量过大导致浏览器卡死。
  • 6.底层tick生成依据K线周期。
  • 7.交易滑点。
  • 7.容错,会模拟API请求出错情况,检查策略容错能力。
  • 8.是否绘制行情图标,回测中如果使用了TA指标函数,会自展示在图标上,买卖也会标记。
  • 9.手续费设置
  • 10.添加交易所-交易对和资产。
  • 11.回测参数设置,如果参数是数字还支持一键优化参数,自动按照一定范围遍历参数回测。

回测与实盘的不同

  • 1.回测时有效的行情只有GetTicker和GetRecords,其它如获深度、成交历史都不是真实的(因为数据量太大,实盘级回测目前已经支持这些数据,但只有最近数据)。
  • 2.回测添加的交易所都是独立账户,目前不支持切换交易对。因此无法在一个账户里操作两个交易对。
  • 3.回测中无法使用网络请求。
  • 4.回测无法使用IO扩展,只能操作最基础的API。
  • 5.回测只能获取标准的数据,像Info之类的牵扯到实盘的数据不存在。
  • 6.回测中也有可能不成交,注意冻结订单情况。
  • 7.商品期货回测不支持市价单。

策略容错与常见错误

前面说过在实盘中使用API接口都有可能访问失败而返回null,这时在使用其中的数据就会报错并且导致实盘停止,所以策略要做好容错。

常用容错方式

常见错误原因:

  • API访问网络错误,接口访问超时将返回null,此时使用就会报错。
  • 交易所限制错误,如ip限制、下单精度、访问频率、参数错误、资产不足、市场不能交易、撤销已成交订单等等。可具体根据错误代码查询API文档。
  • 交易所返回数据错误,偶有发生,如返回空的深度、延时的账户信息、延时的订单状态等。
  • 程序逻辑错误。

在使用API返回数据之前,都要对其是否为null进行判断,下面将介绍集中常用方法:

//1.判断为null进行处理
var ticker = exchange.GetTicker();
while(ticker == null){
     Log('ticker 获取出错');
     ticker = exchange.GetTicker();
 }
 Log(ticker.Last);
 // 2.判断不为null再进行引用
 var ticker = exchange.GetTicker();
 if(!ticker){
     Log(ticker.Last);
 }
 // 3._C()函数重试
 var ticker = _C(exchange.GetTicker);
 Log(ticker.Last);
 // 4. try catch容错
 try{
     var ticker = exchange.GetTicker();
     Log(ticker.Last);
 }
 catch(err){
     Log('ticker 获取出错');
 } 

如果想要获取错误信息,可以使用GetLastError(),将返回上一次出错信息字符串,可以对错误进行差异处理。

FAQ

论坛置顶帖有许多常见错误汇总: https://www.fmz.com/bbs-topic/1427 。这里将摘要一些,遇到问题可以ctrl+F搜索以下。

如何布置托管者?

在添加托管者一节有详细介绍

能不能找人代写策略?

https://www.fmz.com/markets 上有一些人提供代写服务,或者在群里咨询,需要自己联系,自担风险。

访问所有接口都提示timeout

是指访问交易所接口超时,如果偶尔出现不是问题,如果一直提示做说明所在网络无法访问,需要使用海外服务器。

ERR_INVALID_POSITION 错误

回测系统报错,一般为策略编写错误,在没有持仓或者持仓数量不足时,尝试下单平仓,会引起该报错。

symbol not set

期货交易所回测,代码中没有设置合约, 参看 exchange.SetContractType 函数

BITMEX 429错误,{“error”:{“message”:“Rate limit exceeded retry in 1 seconds ……”}}

访问交易所接口频率过高。

{“status”:6004,“msg”:“timestamp is out of range”}

服务器时间戳超出范围需要更新服务器时间,不能偏差过大

GetOrder(455284455): Error: invalid order id or order cancelled.

些交易所订单取消,交易所就不在维护这个订单信息,无法获取。

GetOrders: 400: {“code”:-1121,“msg”:“Invalid symbol.”}

无效的交易对,检查下是不是交易对设置错误。

Secret key decrypt failed

API KEY 解析失败,如果配置了APIKEY后修改过FMZ密码,尝试在FMZ添加交易所页面,重新配置交易所APIKEY。

Signature not valid: Invalid submission time or incorrect time format [无效的提交时间,或时间格式错误]

建议使用Linux服务器,或者在这些出现该问题的windows系统安装时间同步软件。

为什么设置了全局代理,托管者任然无法访问交易所API?

全局代理并没有代理托管者网络端口,由于延迟问题,最好部署海外服务器的托管者

策略如何保存在本地,而不是上传的FMZ上?

使用Python可以导入本地的文件,把正常根据FMZ的API写的策略保存成文件放在自己的服务器上的执行路径下,直接读取执行就可以了。

#!python2.7

def run(runfile):
      with open(runfile,"r") as f:
            exec(f.read())
            
def main():
    run('my.py')

如何使用交易所的测试网或者更改API基地址

使用exchange.SetBase()直接切换到相应的API基地址即可。如:

exchange.SetBase("https://www.okex.me")

More

gaoencheer api

Science 如何在本地实现策略运行呢?我写了一个简单的Log输出语句,并且按照文末的操作。 第一步,先用一台笔记本作为服务器,运行托管者程序; 第二步,写一个简单的Log输出信息的test.py程序(FMZ 的API接口函数); 第三步,按文末那样,写个runfile,通过run.py调用test.py运行。 /upload/asset/1add39483ef82d45b3ce3.png

gyp9 我买的网易云量化交易课程怎么没了,现在去哪里看

MonuRajak many

MonuRajak hi

伯仲 学习ing

wqy 有一个小的文字错误,GetAccount 获取账户 介绍中,FrozenStocks应该是冻结余额而不是可用余额吧

谭雅少尉 getorder outtime 获取订单超时,okex的交易所,怎么办

乌木十二造高招 担保资产率获取不到吗,到0%会被强制平仓的担保资产率

shifeng2020 我是看1分钟k线图操作的,所以Python死循环的sleep time 可以设置为0.1s,也就是sleep(100)吗,我看你其中写过一个sleep(10),也就是0.1s不会超过huobi HM的API限制吗?

东风化宇 exchange.SetDirection("closebuy"); //如果是永续合约,直接设置exchange.SetDirection("sell") 这儿我试了OKex的永续合约,如果设置成 sell,直接开空了,平不是平多

东风化宇 exchange.SetDirection("closebuy"); //如果是永续合约,直接设置exchange.SetDirection("sell") 这儿我试了OKex的永续合约,如果设置成 sell,直接开空了,平不是平多

东风化宇 GetOrders 的代码里面有两个拼写错误。。。一个是 function写成了 fuction,另一个是for循环的条件里 ; 打成了 ,

东风化宇 是我错了。。。 exchange.Buy(-1, 0.5),交易对是ETH_BTC,市价单代表买入0.5BTC的ETH exchange.Buy(price, 0.5),如果是这种限价单,则代表用price的价格买入 0.5ETH

东风化宇 exchange.Buy(-1, 0.5),交易对是ETH_BTC,则代表市价买入0.5BTC的ETH 这里应该是【代表市价买入0.5ETH】

gyp9 谢谢

小草 一直在网易 https://study.163.com/course/courseMain.htm?share=2&shareId=400000000602076&courseId=1006074239&_trace_c_p_k2_=c3f5d238efc3457d93c8b92c0398d2b2

小草 加首页微信,拉你入群

wqy 大佬麻烦问下咱们有官方交流群吗?有时候遇到问题不知道该在哪提问

小草 改了

小草 再次获取

小草 原始信息里有,可以用GetRawJSON或者查看字段里的info信息

东风化宇 不错不错,还有管理回复。。我发现代码里好多拼写错误,哈哈

小草 嗯嗯,已改正,感谢指出错误

小草 有些永续合约允许双向持仓的,需要设置平仓。我更新一下,原来只有bitmex