CCXT-02-交易所模型
1. 交易所数据结构
每个交易所都有一组属性和方法,其中绝大部分都可以在创建交易所对象时, 使用一个关联数组类型的参数来覆盖默认的设置。也可以定义一个继承类 任意覆盖父类的逻辑。 下面是交易所基类的属性概览,其中的值用于演示:
{
'id': 'exchange' // lowercase string exchange id
'name': 'Exchange' // human-readable string
'countries': [ 'US', 'CN', 'EU' ], // array of ISO country codes
'urls': {
'api': 'https://api.example.com/data', // string or dictionary of base API URLs
'www': 'https://www.example.com' // string website URL
'doc': 'https://docs.example.com/api', // string URL or array of URLs
},
'version': 'v1', // string ending with digits
'api': { ... }, // dictionary of api endpoints
'has': { // exchange capabilities
'CORS': false,
'publicAPI': true,
'privateAPI': true,
'cancelOrder': true,
'createDepositAddress': false,
'createOrder': true,
'deposit': false,
'fetchBalance': true,
'fetchClosedOrders': false,
'fetchCurrencies': false,
'fetchDepositAddress': false,
'fetchMarkets': true,
'fetchMyTrades': false,
'fetchOHLCV': false,
'fetchOpenOrders': false,
'fetchOrder': false,
'fetchOrderBook': true,
'fetchOrders': false,
'fetchStatus': 'emulated',
'fetchTicker': true,
'fetchTickers': false,
'fetchBidsAsks': false,
'fetchTrades': true,
'withdraw': false,
},
'timeframes': { // empty if the exchange !has.fetchOHLCV
'1m': '1minute',
'1h': '1hour',
'1d': '1day',
'1M': '1month',
'1y': '1year',
},
'timeout': 10000, // number in milliseconds
'rateLimit': 2000, // number in milliseconds
'userAgent': 'ccxt/1.1.1 ...' // string, HTTP User-Agent header
'verbose': false, // boolean, output error details
'markets': { ... } // dictionary of markets/pairs by symbol
'symbols': [ ... ] // sorted list of string symbols (traded pairs)
'currencies': { ... } // dictionary of currencies by currency code
'markets_by_id': { ... }, // dictionary of dictionaries (markets) by id
'proxy': 'https://crossorigin.me/', // string URL
'apiKey': '92560ffae9b8a0421...', // string public apiKey (ASCII, hex, Base64, ...)
'secret': '9aHjPmW+EtRRKN/Oi...' // string private secret key
'password': '6kszf4aci8r', // string password
'uid': '123456', // string user id
}
下面是属性的详细说明:
- id: 每个交易所都有一个默认id,它是一个字符串常量,用于在ccxt中唯一的标识一个特定的交易所实例。 你可以有多个接入同一个交易所的ccxt交易所实例,可以使用id进行区分。默认的交易所id是全小写字符, 对应交易所的名称。
- name:方便人类查看的交易所名称,字符串常量。
- countries: 国别代码字符串数组,每个成员都是2个字符长的ISO国别代码,表示交易所的运营所在地。
- urls[‘api’]: 用于ccxt调用的交易所API url字符串,或者是包含了公开和私有API url的关联数组。
- urls[‘www’]: 交易所的官网URL
- urls[‘doc’]: 交易所API文档的官方URL,可以是单个url或url数组。
- version: 当前使用的交易所API的版本号,CCXT在调用交易所API时将在每个请求的URL中添加这个版本号。 除非你要实现一个新的交易所API,否则你不需要修改这个字段。
- api: 一个包含了交易所的所有API访问端结点的关联数组。ccxt使用这个API定义为每个可用访问端结点 自动构造交易所实例方法。
- has: 描述交易所特性支持能力的关联数组,例如 fetchTickers、fetchOHLCV 或CORS。
- timeframes: 交易所的fetchOHLCV方法支持的时间尺度,关联数组,键为时间尺度缩写。只有当 [‘fetchOHLCV’]属性为真时,ccxt才会填充这个字段的内容。
- timeout: ccxt访问交易所API时,请求-响应的超时设置,单位:毫秒,默认值:10000,即10秒。你 应当根据自己的网络情况进行适当的设置。
- rateLimit: 交易所API的请求限流,单位:毫秒,表示向同一交易所发出的两次请求之间需要的最小延迟间隔。 默认情况下ccxt禁用内置的限流功能,可以通过设置
enableRateLimit
来启用API访问限流。 - enableRateLimit: 是否启用内置的限流机制,布尔值,默认值:false。调用者需要开启内置的限流机制 或者自己实现限流,以避免被交易所禁止访问。
- userAgent: 用于设置HTTP请求头中的User-Agent。ccxt默认会设置自己的User-Aget,有些交易所可能 不允许ccxt访问,你可以将这个值设置为false、undefined或空字符串。
- verbose: 是否记录HTTP请求信息到标准输出设备,布尔值,默认:false。Python开发者可以使用提单的 日志调试方法,方法时在代码开头添加以下代码:
import logging
logging.basicConfig(level=logging.DEBUG)
-
markets: 市场描述关联数组,键为交易对或交易符号。在访问这个属性之前需要先调用
loadMarkets()
或load_markets()
载入市场数据。 -
symbols: 交易所的有效符号的数组,以字母表顺序排列。这些符号是市场对象的键,可以用来方便地 访问指定的市场。
-
currencies: 交易所的有效数字货币的关联数组,键为数字货币的代码(3~4字母)。数字货币从市场 载入。
-
markets_by_id: 按交易所列举的市场关联数值。在访问此属性之前需要先载入市场。
-
proxy: 用来访问交易所的http(s)代理的URL字符串,例如’http://crossorigin.me/',默认值:''。
-
apiKey: 用来访问交易所的API Key。大部分交易所需要API Key才能访问其API。
-
secret: 用来访问交易所的密文。大部分交易所需要同时提供api key和密文。
-
password: 交易所要求的交易密码。有些交易所在交易时要求提供这个密码,但是大多数交易所不需要。
-
uid: 你的交易所账户的唯一ID。可以是字符串或数。有些交易所在交易时也需要提供这个信息,但是大多数交易所不需要。
-
requiredCredentials: 统一的身份信息关联数组,定义需要哪些身份信息才能访问交易所的私有API。
-
options: 一个针对特定交易所的关联数组,定义该交易所支持的特定的选项。
-
precisionMode: 交易所的小数精度模式。
-
has: 描述交易所支持特性的关联数组,例如:
'has': {
'CORS': false, // has Cross-Origin Resource Sharing enabled (works from browser) or not
'publicAPI': true, // has public API available and implemented, true/false
'privateAPI': true, // has private API available and implemented, true/false
// unified methods availability flags (can be true, false, or 'emulated'):
'cancelOrder': true,
'createDepositAddress': false,
'createOrder': true,
'deposit': false,
'fetchBalance': true,
'fetchClosedOrders': false,
'fetchCurrencies': false,
'fetchDepositAddress': false,
'fetchMarkets': true,
'fetchMyTrades': false,
'fetchOHLCV': false,
'fetchOpenOrders': false,
'fetchOrder': false,
'fetchOrderBook': true,
'fetchOrders': false,
'fetchStatus': 'emulated',
'fetchTicker': true,
'fetchTickers': false,
'fetchBidsAsks': false,
'fetchTrades': true,
'withdraw': false,
...
}
特性的值为true
、false
或emulated
,其含义如下:
- true表示该特性是交易所API原生支持的,并且在cctx库中通过统一API提供访问接口
- false表示该特性不是交易所API原生支持的,并且在cctx库中没有访问该特性的统一API
- emulated表示该特性不是交易所API原生支持的,但是cctx库通过统一API提供了该特性
2. 交易所API限流
交易所通常都有限流机制。交易所会记录、跟踪你的身份和IP地址, 不允许你过于频繁的访问其API。通过限流措施,交易所可以对访问流量 进行负载均衡,以此保护其API服务被DDOS攻击或被滥用。
大多数交易所允许每秒1到2个请求。如果你的访问过于有攻击性,交易所可能 会临时限制你访问其API或者封掉你的IP一段时间。
exchange.rateLimit
属性被设置为一个安全的默认值,这是次优的选择。 有些交易所可能针对不同的访问端结点有不同的限流规则。ccxt的用户需要根据 应用的特定目的来修改rateLimit属性。
CCXT库有内置的实验性质的限流器,可以在后台实现访问节流,这一过程 对调用者是透明的。警告:CCXT的用户应当至少启用一种限流机制:要么 实现自己的自定义限流算法,要么使用内置的限流器。
使用.enableRateLimit
属性启用内置的限流器,例如: 下面的Python代码在创建交易所实例时启用内置的限流器:
# enable built-in rate limiting upon instantiation of the exchange
exchange = ccxt.bitfinex({
'enableRateLimit': True,
})
# or switch the built-in rate-limiter on or off later after instantiation
exchange.enableRateLimit = True # enable
exchange.enableRateLimit = False # disable
如果你的调用达到了限流门槛或者返回nonce错误,ccxt库将抛出以下异常之一:
- DDoSProtectionError:DDOS保护错误
- ExchangeNotAvailable:交易所不可用
- ExchangeError:交易所错误
- InvalidNonce:无效的Nonce值
通常在稍晚时候再重试访问即可解决问题。
3. Cloudflare / Incapsula 的DDoS保护
有些交易所使用Cloudflare或Incapsula的DDoS保护,在交易所处于高负载时 你的IP会被临时阻断,有时他们甚至限制你所在的整个国家和地区的访问。 在这种情况下他们的服务器通常会返回一个页面声明HTTP 40x错误或者 返回一个AJAX测试或验证码,然后推迟几秒钟才载入页面得到临时的访问 许可或者被添加到一个白名单中。 触发DDoS保护、限流或位置过滤的最常见表现有:
- 调用交易所对象的各种方法都返回RequestTimeout异常
- 捕捉到的
ExchangeError
或ExchangeNotAvailable
异常,其HTTP错误码为400, 403, 404, 429, 500, 501, 503, 等等。 - 出现DNS解析问题、SSL证书问题和底层连接问题
- 从交易所API返回HTML页面而非JSON对象
如果你遇到DDoS保护错误,并且无法访问特定的交易所,那么可以尝试如下方法:
- 尝试使用cloudscraper:
- 使用一个代理服务器(不过会导致响应变慢)
- 要求交易所的技术支持人员将你加入白名单
- 在临近交易所的地方(同国、同城、同数据中心、同机架、同服务器)运行你的软件
- 尝试不同地理位置的其他IP
- 在一组分布网络服务器上运行你的软件