如何利用CCXT交易数字货币合约

如何利用CCXT交易数字货币合约

更多精彩内容,欢迎关注公众号:数量技术宅,欢迎加入量化学院,与180位来自各行各业优秀的同学一同交流量化观点。

对于币圈量化老司机来说,相信或多或少都有接触过ccxt这个接口,ccxt为我们提供了多交易所统一的标准格式API,方便我们做两件事:第一,跨市场的策略,可以轻松对接不同交易所;第二,同一个策略,可以在几乎不修改代码的前提下,移植到不同的交易所。

大多数情况下,我们使用ccxt接口连接行情、交易,默认接入的都是币币交易(spot)。其实,ccxt还有一个强大的隐藏功能,它也能用来交易数字货币期货,也就是我们通常说的合约,包括交割合约、永续合约、币本位合约、U本位合约,只要ccxt封装了交易所的相关API,我们就可以实现对应的交易。有了这个利器,我们甚至可以用ccxt做一些期现套利,以及跨交易所的期货策略。

ccxt的官方帮助文档中,并没有详细介绍如何用ccxt交易合约,我们通过这篇文章为大家总结。

01

CCXT的显调用与隐式调用

介绍如何使用ccxt调用期货方法之前,我们先来看两个重要的概念:显式调用与隐式调用。

显式调用很好理解,就算用ccxt封装的统一接口,来完成行情获取、交易等相关的操作。对于ccxt所支持的每一个交易所,我们都可以用同样的方式,只需更改交易所的名称,即可用同样的代码,在不同交易所,完成同样的操作。我们来看以下代码示例:

import ccxtbinance = ccxt.binance()okex = ccxt.okex()spot_symbol = “BTC/USDT”# fetch_order_bookspot_depth = binance.fetch_order_book(spot_symbol)spot_depth = okex.fetch_order_book(spot_symbol)# limit_buy_order binance.create_limit_buy_order(spot_symbol, amount, price)okex.create_limit_buy_order(spot_symbol, amount, price)

关于显式调用,ccxt的帮助文档中已经介绍的比较详细了,大家有不清楚的可以参照github上ccxt的manual,我们在这里不在赘述。我们重点来看ccxt的隐式调用。隐式调用在ccxt的官方文档中,几乎是一笔带过,仅仅告诉我们,使用dir()命令,我们可以获取该交易所ccxt支持的隐式方法。

我们根据上述的说明,以币安交易所为例,通过dir(ccxt.binance()),查看币安交易所的隐式方法,由于隐式的方法实在太多,我们只能截取部分方法来显示。

在这些方法中,我们看到了一些共同的抬头,比如dapi、fapi、sapi,其实,这些抬头的API,就分别是币安某个合约接口(比如u本位永续、币本位交割、币本位永续)的特有类别的API。如此多的方法,让我们看的眼花缭乱,那么我们如何知道,每个方法该如何使用,参数又该如何传入、传入哪些。

这就需要我们对照币安交易所的API,来为大家解释了。我们以u本位合约获取所有交易对的api为例,我们先看币安api说明对于这个方法的描述,仔细看这个api的地址GET /fapi/v1/exchangeInfo。

我们再在dir(ccxt.binance())的显示结果中搜索“exchangeInfo”。我们看到fapi开头的方法中,有如下几个,这些方法,其实是一个方法(ccxt分为驼峰和下划线,两种命名方式)

fapiPublicGetExchangeInfo,这个方法,是将GET /fapi/v1/exchangeInfo这个原始api的关键词,按照一定的顺序排列组合起来,并且在里面加上了Public。因为这是一个所有人都可以查询得到的公有方法。如果方法中包含Private字样,说明该方法是原始api中的私有方法。所以说,我们对于每个原始api,都可以用他的关键词,在ccxt的隐式方法列表中查询,如果能够查询到该关键词的方法,而且方法的其他字段,也与该方法的原始请求地址一致,那么说明该方法,极有可能就是原始api封装的隐式方法。

我们通过实例来验证,由于fapiPublicGetExchangeInfo是不需要传入参数的。我们直接调用:

symbols = binance.fapiPublicGetExchangeInfo(),这个方法,并看一下这个方法返回的symbols 结果。通过比较ccxt隐式方法返回的结果,与api说明中的返回一致,取到了u本位所有的交易币种信息,的确和api中的描述一样。由此可以判断,我们调用隐式方法的思路是正确的。

02

隐式调用:接收行情

刚才调用binance.fapiPublicGetExchangeInfo(),已经给我们列出了所有在币安能够交易的U本位合约,并且每个symbols list里的symbol字段,就是币安交易所的u本位合约标准字段。我们以BTCUSDT字段为例,调用U本位合约的隐式api,来获取深度行情。

首先,还是来看一下币安u本位合约行情的api说明。与exchangeInfo不同的是,深度行情的获取,需要传入参数,参数列表有两个,分别是symbol和limit,大家需要特别注意后面这个是否必需的字段,Yes代表该参数必须传,No代表该参数可以传,也可以按系统指定的默认值来。

我们再按照刚才的规则,找到ccxt对于币安u本位合约获取深度行情的隐式方法:fapiPublicGetDepth。该函数,同样符合我们之前所推断的命名规则。我们调用该函数,按照格式要求传入symbol函数,执行深度数据的获取。

ba_futures_symbol = “BTCUSDT”future_depth = binance.fapiPublicGetDepth({“symbol”:ba_futures_symbol})

通过返回结果可以看到,我们成功的使用隐式方法,调取到了币安u本位BTCUSDT合约的深度数据。

而对于OKEX交易所来说,我们也可以遵循同样的步骤,来获取OK我们需要币种(合约)的深度数据。我们还是通过print(dir(ccxt.okex())),打印ccxt支持的okex交易所的所有隐式方法。

我们再来看OKEX交易所的API,以交割合约为例,我们同样找到API关于获取深度行情的方法,以及需要传入的参数,这个方法的关键词包括”futures”、”instruments“、”book”等。

我们用上述关键词,在ccxt okex的所有隐式方法中寻找,可以找到对应的方法:

futuresGetInstrumentsInstrumentIdBook,他的命名结构、命名逻辑,与ok的api传入地址很相似。

我们调用这个方法来进行测试,这里需要注意的是,对于okex交易所,我们传入的合约ID(instrument_id)需要是具体的交割合约,比如我们以BTC-USD-0625举例,与此同时,再传入一个辅助的size参数。由于我们的size选择的是50档的盘口,返回的也是50档的深度数据。

ok_futures_symbol = “BTC-USD-0625”future_depth = okex.futuresGetInstrumentsInstrumentIdBook({“instrument_id”:ok_futures_symbol, “size”:50})

通过这个例子,可以看到ok交易所,我们也可以用同样的逻辑+方法,获取到ccxt隐式方法封装的合约深度。对于其他交易所的隐式行情调用,我们都可以以此类推,在这里就不一一详述了,大家对哪个交易所有兴趣,都可以print(交易所.dir()),并且与该交易所的官方api文档进行比对,调用相应命名规则的ccxt隐式方法。

03

隐式调用:交易

我们知道,交易api一般来说都比行情api更加复杂一些,但我们调用api的基本流程,应该来说不会发生变化,依然是先找到交易所api文档中,对应方法的地址,再根据地址中的关键词、传入参数,调用ccxt隐式交易api。

先看币安交易所,还是以u本位api举例,来看用的最多的下单函数的说明。下单函数请求地址:POST /fapi/v1/order。所以我们必须要找到包含这些关键词的ccxt隐式api对应方法,并且,按照binance的参数传入规则,将对应的下单参数传入。

ccxt中对应的交易方法的名称叫做fapiPrivatePostOrder,我们将该方法名称拆分:fapi、Private、Post、Order,除了Private,其余正好对应了原始api的关键词字段。Private是ccxt为每个隐式的私有方法,都会添加的前缀。找到了隐式方法,再根据api文档的说明,我们就可以传入合法参数进行下单了。以下,就是一个利用隐式api下市价单的例子,在下完单的同时,我们在返回值中提取出orderId,为后续的查询订单、撤单方法使用。

order_res = binance.fapiPrivatePostOrder({ “symbol”: _symbol, “side”: _direction, “positionSide”: _positionside, “type”: “MARKET”, “quantity”: _amount, “timestamp”: severtime})orderid = order_res[orderId]

对于OK交易所来说,也是同理,我们先查看OK交易所的原始api,同样以下单函数为例。OK交易所的下单api,有两个重要的特征,大家需要特别注意:第一,传入的参数类型都是string,哪怕背后对应的是整数类型,传入时也要转换为string,不然就会报错。第二,下单的数量,必须转换为合约的张数,其他交易所,例如币安,在u本位合约下单时,允许传入例如下单0.01btc这样的合约单位,但OK交易所不行,必须转换为整数,不然订单就无法提交成功。

此外,instrument_id、type等参数,也需要严格的按照交易所api的要求来传递,我们来看下方的例子。

order_res = okex.futures_post_order({ “client_oid”: “test”, instrument_id: _futsymbol, type: str(1), size: str(1), order_type: 0, match_price: 1})orderid = order_res[“order_id”]

04

写在最后

写到这里,相信大家对ccxt如何调用交易所隐式api,已经有了很清楚的认识了。ccxt的隐式调用,虽然不如显式的方便(对于不同交易所,我们还是需要修改对应代码的,无法统一定制)。

我们这里以ok、币安举例,是因为币安的现货、u本位合约、币本位合约,okex的现货、交割合约、永续合约,再到期权,ccxt都封装在了隐式方法中,对于这两个交易所,理论上所有的api功能,我们都可以通过调用隐式的方法实现,免去了我们自己去对接交易所底层api,处理那些鉴权、现货期货api合并等麻烦的问题。

但是对于其他交易所来说,就没有那么幸运了,比如火币交易所,ccxt隐式提供的api就不包括hbdm,也就是火币合约相关的隐式方法,再比如gateio交易所,也只有现货的api提供。

但是,ccxt起码是给大家在开发数字货币实盘系统提供了另外一个途径,在开发某个交易所的交易系统前,我们可以先通过dir方法,看一下ccxt的隐式接口是否齐全,如果齐全,我们借道ccxt就能够开发出一个完整功能的系统,如果该交易所隐式接口不齐全,我们再考虑自行对接交易所的api,由此,我们的开发效率也能够进一步的提高。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注