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,
    ...
}

特性的值为truefalseemulated,其含义如下:

  • 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异常
  • 捕捉到的ExchangeErrorExchangeNotAvailable异常,其HTTP错误码为400, 403, 404, 429, 500, 501, 503, 等等。
  • 出现DNS解析问题、SSL证书问题和底层连接问题
  • 从交易所API返回HTML页面而非JSON对象

如果你遇到DDoS保护错误,并且无法访问特定的交易所,那么可以尝试如下方法: