初级教程

本教程包含策略编写的初级知识,包括API介绍、回测、图表等内容。学习完此基础教程后,用户将能够熟练使用基础的API,编写出稳定的实盘策略。在学习本教程之前,需要先学习FMZ发明者量化平台使用入门 。

旧版教程:发明者量化(FMZ.COM)策略编写完全使用手册2.0(教程), 这个教程列出了很多帖子索引,也推荐浏览看看。

策略编写的初步说明

API的介绍

程序化交易就是用程序通过API和交易所连接,实现按照设计的意图自动进行买卖或实现其他功能。API全称Application Programming Interface,即应用程序编程接口。

目前数字货币交易所主要有两种接口协议:REST和Websocket。REST协议每获取一次数据,需要访问一次。以模拟交易所wex.app的API为例,直接在浏览器中打开 https://api.wex.app/api/v1/public/ticker?market=BTC_USDT ,得到结果:

{"data:{"buy":"11351.73","high":"11595.77","last":"11351.85","low":"11118.45","open":"11358.74","quoteVol":"95995607137.00903936","sell":"11356.02","time":1565593489318,"vol":"3552.5153"}}

这就可以看到交易随BTC_USDT交易对的最新行情,每次刷新还会有变化。其中market=后面接的是具体交易对参数,可以修改以获取其它交易对数据。对于公开接口,如市场行情,所有人都可以获取到,因此不需要验证,而有些接口如下单和获取账户就需要确定用户身份,这时候就需要使用API-KEY进行签名。Websocket是订阅模式,发送需要订阅的内容之后,交易所会将更新的数据发给程序,不需要每次都重新访问,因此更加高效。

FMZ量化交易平台封装了各个交易所的REST接口,使用统一的方式调用和数据格式,使策略编写更加简单通用。在FMZ平台可以很方便的支持Websocket,将在下篇教程中详细介绍。

不同编程语言

FMZ平台API文档大部分以JavaScript为例子,但由于封装,不同语言几乎没有差别,只需要注意语法问题即可。C++稍微特殊,以后的教程会有专门的介绍。由于Js比较简单并且没有兼容性问题,推荐新手使用。FMZ量化平台支持完整的Python,可以自由的安装各种包,推荐有一定编程基础的使用。对于不想学习编程语言,只想快速写出策略的用户,FMZ平台还支持麦语言,基本兼容文华财经策略,有相关经验的推荐使用,缺点是没有编程语言强大灵活。FMZ还支持可视化编程,类似与搭积木的方式实现策略,但不是很推荐,不如代码清晰。由于编程语言相似性很高,不必纠结于选择哪种,都学习一下掌握基础花不了多少精力。

Python由于有不同的版本,可以在程序开头指定,如#!Python2,#!Python3。注意JavaScript最近升级了ES6语法,有兴趣的可以了解。下面展示了同样功能的Python和Javascript代码,可见仅有语法差异,因此API文档仅给出了Javascript的例子,本教程也会兼顾Python的特殊用例。

#python代码
def main():
    while True:
        Log(exchange.GetAccount().Balance)
        Sleep(2000)
#相应的Js代码
function main(){
    while(true){
        Log(exchange.GetAccount().Balance)
        Sleep(2000)
    }
}

资源推荐

调试工具

FMZ量化平台提供了调试工具供调试API接口,https://www.fmz.com/m/debug 。调试工具只支持JavaScript,只能执行一段时间,不用创建机器人就可以调试实盘接口。return的数据将作为结果返回,调试工具的代码不会保存。在学习本教程中,可以同时使用调试工具进行试验。

策略程序架构

策略程序和正常的程序一样,按代码顺序执行,特殊之处是必须有一个main函数。由于策略需要不间断运行,通常情况下,需要一个循环加上休眠时间。因为交易所有API访问频率有限制,需要相应的调整休眠时间。这种架构是典型的固定间隔执行,也可以使用websockt来写事件驱动型策略,如只要深度有变化立即执行,将在进阶教程中介绍。

其它有特殊作用的函数如下:

  • onexit() 为正常退出扫尾函数,最长执行时间为5分钟,可以不声明,如果超时会报错interrupt错误。可用于退出程序时保存一些结果。
  • onerror() 为异常退出函数,最长执行时间为5分钟,可以不声明。
  • init() 为初始化函数,策略程序会在开始运行时自动调用,可不声明。
function onTick(){
   var ticker = exchange.GetTicker()
   var account = exchange.GetAccount()
    //在这里写策略逻辑,将会每6s调用一次
}
function main(){
    while(true){
        onTick()
        Sleep(6000)
    }
}

前面的例子如果网络访问出错可能导致策略直接停止,如果想要一个类似自动重启不会停止的策略,可以再实盘策略用try catch容错主循环(回测不要使用try)。当然只有当策略稳定才建议这样操作,不然会把所有的错误都不报错,难以排查策略的问题。

function onTick(){
   var ticker = exchange.GetTicker()
   var account = exchange.GetAccount()
    //在这里写策略逻辑,将会每6s调用一次
}
function main(){
    try{
        while(true){
           onTick()
           Sleep(6000)
       }
    }catch(err){
        Log(err)
    }
}

交易所API介绍

交易所和交易对设置

在调用任何交易所相关的API时,都需要明确交易所和交易对。如果创建机器人时只添加了一个交易所-交易对,exchange代表这个对象,如exchange.GetTicker()获取的将是这个交易所-交易对的行情ticker。

FMZ平台同时支持添加多个交易所-交易对,如可以同时操作同一个交易所账户的BTC和ETH,也可以同时操作一个交易所的BTC和另一个交易所的ETH。注意同一个交易所不同账户也可以同时添加,它们根据添加到FMZ网站的label区分。当存在多个交易所-交易对时,用exchanges数组来表示,按照创建机器人添加顺序分别为exchanges[0]exchanges[1]...以此类推。交易对的格式如BTC_USDT,前者BTC是交易货币,USDT是计价货币。

显然,如果我们操作的交易对很多,这种方式将会很麻烦,此时可以用SetCurrency来切换交易对,如exchange.SetCurrency("BTC_USDT"),此时exchange所绑定的交易对就变为了BTC_USDT,在下次调用改变交易对之前将会一直有效。注意回测最新支持了切换交易对。下面是一个具体的例子。

var symbols = ["BTC_USDT", "LTC_USDT", "EOS_USDT", "ETH_USDT"]
var buyValue = 1000
function main(){
  for(var i=0;i<symbols.length;i++){
      exchange.SetCurrency(symbols[i])
      var ticker = exchange.GetTicker()
      var amount = _N(buyValue/ticker.Sell, 3)
      exchange.Buy(ticker.Sell, amount)
      Sleep(1000)
  }
}

获取行情等公开接口

正如前面举得例子,行情接口一般都是公开接口,所有人都能获取。通常的行情接口有:获取行情ticker、获取深度depth、获取K线records、获取成交记录trades。行情是策略进行交易判断的基础,下面将一一介绍,最好能够在调试工具中自己尝试,需要详细的解释可以查看API文档。

各个接口一般都有Info字段,表示交易所返回的原始数据字符串,可用于补充额外的信息,用之前需要解析,JavaScript使用JSON.parse(),Python使用json库。Time字段表示请求的时间戳,可用于判断延时。

在实盘中使用API接口都有可能访问失败而返回null,Python返回None,这时在使用其中的数据就会报错并且导致机器人停止,所以容错非常重要。本教程将单独介绍。

GetTicker

获取市场当前行情,大概是最常用的接口,可以查到上一次成交价,买一卖一价,最近成交量等信息。再下单之前可以根据ticker信息来确定交易价格。一个实盘返回的例子{"Info:{}, "High":5226.69, "Low":5086.37,"Sell":5210.63, "Buy":5208.5, "Last":5208.51, "Volume":1703.1245, "OpenInterest":0, "Time":1554884195976}

function main() {
    var ticker = exchange.GetTicker()
    Log(ticker) //在调试工具中 return ticker 。可以看到具体的结果。
    Log('上次成交价: ',ticker.Last, '买一价: ', ticker.Buy)
}

GetDepth

获取挂单深度信息。虽然GetTicker中包含了买一卖一,但如果要查询更深的挂单,可以用这个接口,一般可以查到上下200个挂单。可以使用这个接口计算冲击价格。下面是一个真实的返回结果。其中Asks表示卖单挂单,数组中分别是“卖一”、“卖二”...所以价格也依次上升。Bids表示买单挂单,数组中分别是“买一”、“买二”...价格依次下降。

{
    "Info":null,
    "Asks":[
        {"Price":5866.38,"Amount":0.068644},
        {"Price":5866.39,"Amount":0.263985},
        ......
        ]
    "Bids":[
        {"Price":5865.13,"Amount":0.001898},
        {"Price":5865,"Amount":0.085575},
        ......
        ],
    "Time":1530241857399
}

使用深度获取买单卖单例子:

function main() {
    var depth = exchange.GetDepth()
    Log('买一价个: ', depth.Bids[0].Price, '卖一价格: ', depth.Asks[0].Price)
}

GetRecords

获取K线,最常用的接口之一,可一次返回较长时间的价格信息,计算各种指标的基础。K线周期如果不指定表示将使用添加机器人时的默认周期。K线长度不能指定,随着时间积累会不断增加,最大2000根,第一次调用大概200根(不同的交易所返回不同)。最后一根K线是最新的K线,所以数据会随着行情不断变化,第一根K线是最旧的数据。

exchange.SetMaxBarLen(Len)可以设置第一次获取K线的数量(部分交易所支持),并且设置了最大的K线数量。 如:exchange.SetMaxBarLen(500)

GetRecords可以指定周期:PERIOD_M1:1分钟,PERIOD_M5:5分钟,PERIOD_M15:15分钟,PERIOD_M30:30分钟,PERIOD_H1:1小时,PERIOD_D1:1天。具体使用为exchange.GetRecords(PERIOD_M1)。升级最新的托管者后,会支持自定义周期,直接传周期秒数作为参数就行,分钟级别的自定义会根据1分钟K线合成,1分钟以下K线通过GetTrades()合成,

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值