数字货币量化系统之 CCXT 框架使用 (上)

在前边的学习中,我们是直接通过交易所提供的API接口自己对接来获取行情数据的,如果我们要获取多个平台的数据,那么就要对接多个平台的API,非常麻烦,现在已经有人帮我们把各个交易所的接口做了一个统一的封装,这个就是CCXT 框架,我们只需要使用这个框架就可以轻松的进行行情数据获取及交易。

一、什么是CCXT框架

交易所API

不同的交易所提供不同的接口API

  • 移植性较差
  • 学习成本较高
  • 需要为不同的交易所编写对应的对接方法

CCXT

CCXT - CryptoCurrency eXchange Trading

CCXT框架 是一个Python/Javascript/PHP的一个交易API框架,对接超过130多个交易所。可用于世界各地的加密货币交易所的连接和交易,以及转账支付处理,可用于存储数据,分析,可视化,指标开发,算法交易,是一个非常容易集成的开箱即用的统一API。

CCXT框架Github地址:https://github.com/ccxt/ccxt

二、CCXT框架概述

file

file

CCXT里面的交易所都集成来自Exchange的基类,然后每个交易所实现了一些统一的api接口,另外也实现自己交易所特有的api方法。 统一的api方法分为不需要权限就能访问的,比如load_markets(加载市场的交易对)、 fetch_ticker(获取ticker)等,需要权限访问的方法如fetch_balance(获取张账户资金)、create_order(生成订单)等。CCXT的方法名称有两种实现方式,一种是驼峰法, 另外一种是下划线命名法,在python中,推荐使用下划线方法来调用。

公共API包括

  • 市场数据
  • 交易对
  • 交易手续费
  • 订单薄/深度数据
  • 交易历史
  • 行情/Tickers
  • 用以制图的 OHLC(V)/K线
  • 其他公共接口

私有API包括

  • 管理个人账户信息
  • 查询账户余额
  • 通过市价单和限价单进行交易
  • 存入和提取法币和加密货币
  • 查询个人订单
  • 获取交易明细/历史
  • 在账户之间转移资金
  • 使用商业服务

三、CCXT使用

安装

pip install ccxt

常用接口

# 初始化交易所
binance_exchange = ccxt.binance({
    'timeout': 15000,
    'enableRateLimit': True
})

# 获取单个交易对ticker数据
binance_exchange.fetchTicker(symbol)

# 获取多个交易对ticker数据
tickers_data = binance_exchange.fetchTickers(['BTC/USDT', 'ETH/USDT'])

# 交易委托账本数据获取
binance_exchange.fetch_order_book(symbol)

# K线数据数据获取
binance_exchange.fetch_ohlcv(symbol, timeframe='1d')

外网代理设置

由于GFW的原因,国内可能请求币安的接口api.binance.com 会访问不了,所以,需要科学上网使用代理,这就需要我们对ccxt的源码进行研究,所以,我们可以研究ccxt基类文件exchange.py代理配置,本环境是使用 Conda 进行安装的,文件路径为:/Users/corwien/anaconda3/lib/python3.7/site-packages/ccxt/base/exchange.py,代理的参数为:proxies

这里有两种改法,第一种是直接在基类文件改:
exchange.py

    # proxies = None
    # 这里的代理IP是从showdocsocks软件「复制终端代理命令」找到的[20191208]
    proxies = {'https': "http://127.0.0.1:1087", 'http': "http://127.0.0.1:1087"}

第二种方法,不需要修改ccxt框架源码,在初始化交易所时,直接传入proxies参数即可:

# 初始化交易所(这里使用代理)
binance_exchange = ccxt.binance({
    'timeout':15000,
    'enableRateLimit':True,
    'proxies': {'https': "http://127.0.0.1:1087", 'http': "http://127.0.0.1:1087"}
})

代码实战

# 安装
# pip install ccxt
import ccxt

1. Exhanges

# 获取所有交易所列表
exchange_list = ccxt.exchanges
exchange_list
['_1btcxe',
 'acx',
 'adara',
 'allcoin',
 'anxpro',
 'bcex',
 'bequant',
 'bibox',
 'bigone',
 'binance',
 'binanceje',
 'binanceus',
 'bit2c',
 'bitbank',
 'bitbay',
 'bitfinex',
 'bitfinex2',
 'bitflyer',
 'bitforex',
 'bithumb',
 'bitkk',
 'bitlish',
 'bitmart',
 'bitmax',
 'bitmex',
 'bitso',
 'bitstamp',
 'bitstamp1',
 'bittrex',
 'bitz',
 'bl3p',
 'bleutrade',
 'braziliex',
 'btcalpha',
 'btcbox',
 'btcchina',
 'btcmarkets',
 'btctradeim',
 'btctradeua',
 'btcturk',
 'buda',
 'bw',
 'bytetrade',
 'cex',
 'chilebit',
 'cobinhood',
 'coinbase',
 'coinbaseprime',
 'coinbasepro',
 'coincheck',
 'coinegg',
 'coinex',
 'coinfalcon',
 'coinfloor',
 'coingi',
 'coinmarketcap',
 'coinmate',
 'coinone',
 'coinspot',
 'coolcoin',
 'coss',
 'crex24',
 'deribit',
 'digifinex',
 'dsx',
 'exmo',
 'exx',
 'fcoin',
 'fcoinjp',
 'flowbtc',
 'foxbit',
 'ftx',
 'fybse',
 'gateio',
 'gemini',
 'hitbtc',
 'hitbtc2',
 'huobipro',
 'huobiru',
 'ice3x',
 'idex',
 'independentreserve',
 'indodax',
 'itbit',
 'kkex',
 'kraken',
 'kucoin',
 'kuna',
 'lakebtc',
 'latoken',
 'lbank',
 'liquid',
 'livecoin',
 'luno',
 'lykke',
 'mandala',
 'mercado',
 'mixcoins',
 'negociecoins',
 'oceanex',
 'okcoincny',
 'okcoinusd',
 'okex',
 'okex3',
 'paymium',
 'poloniex',
 'rightbtc',
 'southxchange',
 'stex',
 'stronghold',
 'surbitcoin',
 'theocean',
 'therock',
 'tidebit',
 'tidex',
 'upbit',
 'vaultoro',
 'vbtc',
 'virwox',
 'whitebit',
 'xbtce',
 'yobit',
 'zaif',
 'zb']
# 初始化交易所
binance_exchange = ccxt.binance({
    'timeout': 15000,
    'enableRateLimit': True,
         'proxies': {'https': "http://127.0.0.1:1087", 'http': "http://127.0.0.1:1087"}
})
# 交易所数据结构
print('交易所id:', binance_exchange.id)
print('交易所名称:', binance_exchange.name)
print('是否支持共有API:', binance_exchange.has['publicAPI'])
print('是否支持私有API:', binance_exchange.has['privateAPI'])
print('支持的时间频率:', binance_exchange.timeframes)
print('最长等待时间(s):', binance_exchange.timeout / 1000)
print('访问频率(s):', binance_exchange.rateLimit / 1000)
# print('交易所当前时间:', binance_exchange.iso8601(binance_exchange.milliseconds()))
交易所id: binance
交易所名称: Binance
是否支持共有API: True
是否支持私有API: True
支持的时间频率: {'1m': '1m', '3m': '3m', '5m': '5m', '15m': '15m', '30m': '30m', '1h': '1h', '2h': '2h', '4h': '4h', '6h': '6h', '8h': '8h', '12h': '12h', '1d': '1d', '3d': '3d', '1w': '1w', '1M': '1M'}
最长等待时间(s): 15.0
访问频率(s): 0.5
print('交易所当前时间:', binance_exchange.iso8601(binance_exchange.milliseconds()))
交易所当前时间: 2019-12-08T15:27:31.951Z

2. Markets

# 加载市场数据
binance_markets = binance_exchange.load_markets()
# 支持的交易对
list(binance_markets.keys())
['ETH/BTC',
 'LTC/BTC',
 'BNB/BTC',
 'NEO/BTC',
 'QTUM/ETH',
 'EOS/ETH',
 'SNT/ETH',
 'BNT/ETH',
 'BCC/BTC',
 'GAS/BTC',
 'BNB/ETH',
 'BTC/USDT',
 'ETH/USDT',
 'HSR/BTC',
 'OAX/ETH',
 'DNT/ETH',
 'MCO/ETH',
 'ICN/ETH',
 'MCO/BTC',
 'WTC/BTC',
 'WTC/ETH',
 'LRC/BTC',
 'LRC/ETH',
 'QTUM/BTC',
 'YOYOW/BTC',
 'OMG/BTC',
 'OMG/ETH',
 'ZRX/BTC',
 'ZRX/ETH',
 'STRAT/BTC',
 'STRAT/ETH',
 'SNGLS/BTC',
 'SNGLS/ETH',
 'BQX/BTC',
 'BQX/ETH',
 'KNC/BTC',
 'KNC/ETH',
 'FUN/BTC',
 'FUN/ETH',
 'SNM/BTC',
 'SNM/ETH',
 'NEO/ETH',
  ...
 'VET/BUSD']
symbol = 'BTC/USDT'
# 获取指定交易对市场信息
btc_usdt_market = binance_markets[symbol]
btc_usdt_market
{'percentage': True,
 'tierBased': False,
 'taker': 0.001,
 'maker': 0.001,
 'precision': {'base': 8, 'quote': 8, 'amount': 6, 'price': 2},
 'limits': {'amount': {'min': 1e-06, 'max': 9000.0},
  'price': {'min': 0.01, 'max': 1000000.0},
  'cost': {'min': 10.0, 'max': None}},
 'id': 'BTCUSDT',
 'symbol': 'BTC/USDT',
 'base': 'BTC',
 'quote': 'USDT',
 'baseId': 'BTC',
 'quoteId': 'USDT',
 'info': {'symbol': 'BTCUSDT',
  'status': 'TRADING',
  'baseAsset': 'BTC',
  'baseAssetPrecision': 8,
  'quoteAsset': 'USDT',
  'quotePrecision': 8,
  'baseCommissionPrecision': 8,
  'quoteCommissionPrecision': 8,
  'orderTypes': ['LIMIT',
   'LIMIT_MAKER',
   'MARKET',
   'STOP_LOSS_LIMIT',
   'TAKE_PROFIT_LIMIT'],
  'icebergAllowed': True,
  'ocoAllowed': True,
  'quoteOrderQtyMarketAllowed': True,
  'isSpotTradingAllowed': True,
  'isMarginTradingAllowed': True,
  'filters': [{'filterType': 'PRICE_FILTER',
    'minPrice': '0.01000000',
    'maxPrice': '1000000.00000000',
    'tickSize': '0.01000000'},
   {'filterType': 'PERCENT_PRICE',
    'multiplierUp': '5',
    'multiplierDown': '0.2',
    'avgPriceMins': 5},
   {'filterType': 'LOT_SIZE',
    'minQty': '0.00000100',
    'maxQty': '9000.00000000',
    'stepSize': '0.00000100'},
   {'filterType': 'MIN_NOTIONAL',
    'minNotional': '10.00000000',
    'applyToMarket': True,
    'avgPriceMins': 5},
   {'filterType': 'ICEBERG_PARTS', 'limit': 10},
   {'filterType': 'MARKET_LOT_SIZE',
    'minQty': '0.00000000',
    'maxQty': '3200.00000000',
    'stepSize': '0.00000000'},
   {'filterType': 'MAX_NUM_ALGO_ORDERS', 'maxNumAlgoOrders': 5}]},
 'type': 'spot',
 'spot': True,
 'future': False,
 'active': True}

3. 交易对行情获取

3.1 Ticker数据获取

# 获取单个交易对ticker数据
ticker_data = binance_exchange.fetchTicker(symbol)
ticker_data
{'symbol': 'BTC/USDT',
 'timestamp': 1575818853630,
 'datetime': '2019-12-08T15:27:33.630Z',
 'high': 7564.0,
 'low': 7374.86,
 'bid': 7535.63,
 'bidVolume': 0.005553,
 'ask': 7536.61,
 'askVolume': 0.176018,
 'vwap': 7473.20969548,
 'open': 7520.32,
 'close': 7536.64,
 'last': 7536.64,
 'previousClose': 7520.32,
 'change': 16.32,
 'percentage': 0.217,
 'average': None,
 'baseVolume': 28714.717963,
 'quoteVolume': 214591108.6841426,
 'info': {'symbol': 'BTCUSDT',
  'priceChange': '16.32000000',
  'priceChangePercent': '0.217',
  'weightedAvgPrice': '7473.20969548',
  'prevClosePrice': '7520.32000000',
  'lastPrice': '7536.64000000',
  'lastQty': '0.00265400',
  'bidPrice': '7535.63000000',
  'bidQty': '0.00555300',
  'askPrice': '7536.61000000',
  'askQty': '0.17601800',
  'openPrice': '7520.32000000',
  'highPrice': '7564.00000000',
  'lowPrice': '7374.86000000',
  'volume': '28714.71796300',
  'quoteVolume': '214591108.68414260',
  'openTime': 1575732453630,
  'closeTime': 1575818853630,
  'firstId': 214160415,
  'lastId': 214414245,
  'count': 253831}}
print('Ticker时刻:', ticker_data['datetime'])
print('Ticker价格:', ticker_data['last'])
Ticker时刻: 2019-12-08T15:27:33.630Z
Ticker价格: 7536.64
# 时间操作
# 转换UTC时间
print('Ticker数据开始时间:', binance_exchange.iso8601(ticker_data['info']['openTime']))
print('Ticker数据结束时间:', binance_exchange.iso8601(ticker_data['info']['closeTime']))
Ticker数据开始时间: 2019-12-07T15:27:33.630Z
Ticker数据结束时间: 2019-12-08T15:27:33.630Z
# 获取多个交易对ticker数据
tickers_data = binance_exchange.fetchTickers(['BTC/USDT', 'ETH/USDT'])
tickers_data
{'BTC/USDT': {'symbol': 'BTC/USDT',
  'timestamp': 1575818853630,
  'datetime': '2019-12-08T15:27:33.630Z',
  'high': 7564.0,
  'low': 7374.86,
  'bid': 7535.63,
  'bidVolume': 0.005553,
  'ask': 7536.61,
  'askVolume': 0.176018,
  'vwap': 7473.20969548,
  'open': 7520.32,
  'close': 7536.64,
  'last': 7536.64,
  'previousClose': 7520.32,
  'change': 16.32,
  'percentage': 0.217,
  'average': None,
  'baseVolume': 28714.717963,
  'quoteVolume': 214591108.6841426,
  'info': {'symbol': 'BTCUSDT',
   'priceChange': '16.32000000',
   'priceChangePercent': '0.217',
   'weightedAvgPrice': '7473.20969548',
   'prevClosePrice': '7520.32000000',
   'lastPrice': '7536.64000000',
   'lastQty': '0.00265400',
   'bidPrice': '7535.63000000',
   'bidQty': '0.00555300',
   'askPrice': '7536.61000000',
   'askQty': '0.17601800',
   'openPrice': '7520.32000000',
   'highPrice': '7564.00000000',
   'lowPrice': '7374.86000000',
   'volume': '28714.71796300',
   'quoteVolume': '214591108.68414260',
   'openTime': 1575732453630,
   'closeTime': 1575818853630,
   'firstId': 214160415,
   'lastId': 214414245,
   'count': 253831}},
 'ETH/USDT': {'symbol': 'ETH/USDT',
  'timestamp': 1575818854124,
  'datetime': '2019-12-08T15:27:34.124Z',
  'high': 151.5,
  'low': 146.11,
  'bid': 150.35,
  'bidVolume': 69.5885,
  'ask': 150.36,
  'askVolume': 19.47036,
  'vwap': 148.08120506,
  'open': 148.1,
  'close': 150.35,
  'last': 150.35,
  'previousClose': 148.12,
  'change': 2.25,
  'percentage': 1.519,
  'average': None,
  'baseVolume': 163075.16884,
  'quoteVolume': 24148367.5166566,
  'info': {'symbol': 'ETHUSDT',
   'priceChange': '2.25000000',
   'priceChangePercent': '1.519',
   'weightedAvgPrice': '148.08120506',
   'prevClosePrice': '148.12000000',
   'lastPrice': '150.35000000',
   'lastQty': '0.79890000',
   'bidPrice': '150.35000000',
   'bidQty': '69.58850000',
   'askPrice': '150.36000000',
   'askQty': '19.47036000',
   'openPrice': '148.10000000',
   'highPrice': '151.50000000',
   'lowPrice': '146.11000000',
   'volume': '163075.16884000',
   'quoteVolume': '24148367.51665660',
   'openTime': 1575732454124,
   'closeTime': 1575818854124,
   'firstId': 108282329,
   'lastId': 108353527,
   'count': 71199}}}

3.2 交易委托账本数据获取

binance_exchange.fetch_order_book(symbol)
{'bids': [[7535.07, 2.0],
  [7535.02, 2.2],
  [7535.01, 1.862624],
  [7535.0, 1.343753],
  [7534.73, 0.03],
  [7534.68, 0.04601],
  [7534.65, 0.080972],
  [7534.52, 0.741444],
  [7534.2, 0.5],
  [7534.1, 0.863648],
  [7534.09, 0.5],
  [7533.77, 0.05],
  [7533.39, 0.667],
  [7533.34, 0.482002],
  [7533.0, 0.0015],
  [7532.99, 0.160791],
  [7532.94, 2.026584],
  [7532.73, 2.2],
  [7532.34, 2.5],
  [7532.26, 2.2],
  [7532.16, 0.003462],
  [7532.14, 2.2],
  [7532.05, 0.274675],
  [7532.04, 2.2],
  [7531.87, 2.82],
  [7531.64, 0.033193],
  [7531.63, 0.026555],
  [7531.48, 0.00987],
  [7531.15, 0.011069],
  [7530.32, 0.3],
  [7530.31, 0.226657],
  [7530.22, 0.31701],
  [7530.21, 0.294178],
  [7530.14, 0.460023],
  [7530.13, 0.397404],
  [7530.01, 0.018965],
  [7530.0, 2.28075],
  [7529.95, 0.184238],
  [7529.94, 0.820655],
  [7529.77, 0.3],
  [7529.76, 0.480499],
  [7529.74, 0.79616],
  [7529.44, 0.011232],
  [7529.4, 0.7939],
  [7528.87, 0.477672],
  [7528.52, 0.072711],
  [7527.99, 0.001329],
  [7527.72, 0.00991],
  [7527.31, 0.265699],
 ...
  [7524.23, 0.224019],
  [7524.2, 0.327293],
  [7524.14, 0.4198],
  [7524.0, 0.399029],
  [7523.94, 0.01016],
  [7523.57, 0.016614],
  [7523.21, 0.398751],
  [7523.16, 0.01068],
  [7522.95, 0.004075],
  [7522.29, 2.933],
  [7521.73, 0.398816],
  [7521.61, 0.023834],
  [7521.55, 0.053502],
  [7521.45, 0.134884],
  [7521.34, 0.001861],
  [7520.64, 0.061339],
  [7520.46, 0.001594],
  [7520.26, 0.430983],
  [7520.21, 0.003888],
  [7520.05, 0.0102],
  [7520.02, 0.153064],
  ...
  [7518.28, 1.0028],
  [7518.18, 0.1],
  [7518.12, 0.01]],
 'asks': [[7535.98, 0.173007],
  [7535.99, 2.0],
  [7536.0, 0.107593],
  [7536.01, 0.205962],
  [7536.03, 0.120477],
  [7536.89, 0.230145],
  [7546.82, 0.397523],
  [7546.86, 0.287908],
  [7547.08, 0.0103],
  [7547.5, 0.001326],
  [7547.51, 0.001415],
  [7548.0, 0.09495],
 ...
  [7550.31, 0.538136]],
 'timestamp': None,
 'datetime': None,
 'nonce': 1503889978}
# 获取上一次访问交易所的时间
binance_exchange.last_response_headers['Date']
'Sun, 08 Dec 2019 15:27:48 GMT'
orderbook = binance_exchange.fetch_order_book(symbol)

# 最高买价
bid = orderbook['bids'][0][0] if len (orderbook['bids']) > 0 else None

# 最低卖价
ask = orderbook['asks'][0][0] if len (orderbook['asks']) > 0 else None

# 价差
spread = (ask - bid) if (bid and ask) else None

# 市场行情
print ('买价:{:.2f}, 卖价:{:.2f}, 价差:{:.2f}'.format(bid, ask, spread))
买价:7535.07, 卖价:7535.94, 价差:0.87

3.3 K线数据数据获取

if binance_exchange.has['fetchOHLCV']:
    print(binance_exchange.fetch_ohlcv(symbol, timeframe='1d'))
[[1532649600000, 7920.0, 8285.0, 7805.0, 8188.57, 43671.005891], [1532736000000, 8188.57, 8246.54, 8067.0, 8225.04, 26215.173839], [1532822400000, 8225.04, 8294.51, 8115.0, 8211.0, 25531.226185], [1532908800000, 8210.99, 8273.0, 7866.0, 8173.92, 39692.416542], [1532995200000, 8171.4, 8180.0, 7633.0, 7730.93, 48296.915587], [1533081600000, 7735.67, 7750.0, 7430.0, 7604.58, 42582.312932], [1533168000000, 7600.08, 7709.46, 7455.72, 7525.71, 37665.696684], [1533254400000, 7525.71, 7540.0, 7282.44, 7418.78, 44669.486047], [1533340800000, 7412.27, 7494.81, 6926.0, 7009.84, 36288.42601], [1533427200000, 7009.84, 7089.87, 6882.29, 7024.19, 32894.849782], [1533513600000, 7024.19, 7160.0, 6821.0, 6934.82, 32760.191643], [1533600000000, 6935.0, 7150.46, 6670.0, 6720.06, 45438.473501], [1533686400000, 6720.63, 6721.54, 6123.0, 6285.0, 59550.536319], [1533772800000, 6283.27, 6622.81, 6178.6, 6529.79, 51941.185111], [1533859200000, 6529.79, 6575.88, 6026.39, 6144.01, 59034.974902], [1533945600000, 6148.13, 6488.0, 5971.0, 6232.35, 47133.418555], [1534032000000, 6222.55, 6472.3, 6130.0, 6308.33, 38567.770712], [1534118400000, 6308.56, 6545.0, 6145.04, 6246.35, 53895.828783], [1534204800000, 6248.25, 6250.33, 5880.0, 6188.08, 50186.745091], [1534291200000, 6188.08, 6609.0, 6172.11, 6267.16, 68806.687026], [1534377600000, 6265.27, 6480.0, 6205.6, 6311.75, 48515.254618], [1534464000000, 6316.0, 6585.0, 6285.4, 6584.49, 57851.610803], [1534550400000, 6579.04, 6620.0, 6288.0, 6387.96, 53742.322172], [1545609600000, 3929.71, 4198.0, 3924.83, 4008.01, 64647.809129], [1575331200000, 7294.42, 7400.0, 7241.35, 7292.71, 33149.477487]]
import pandas as pd

if binance_exchange.has['fetchOHLCV']:
    kline_data = pd.DataFrame(binance_exchange.fetch_ohlcv(symbol, timeframe='1m'))
    kline_data.columns = ['Datetime', 'Open', 'High', 'Low', 'Close', 'Vol']
    kline_data['Datetime'] = kline_data['Datetime'].apply(binance_exchange.iso8601)
kline_data.head()
Datetime Open High Low Close Vol
0 2019-12-08T07:08:00.000Z 7443.96 7443.96 7438.94 7440.73 30.998419
1 2019-12-08T07:09:00.000Z 7440.84 7441.69 7438.97 7440.72 6.239697
2 2019-12-08T07:10:00.000Z 7440.85 7443.48 7440.43 7443.12 4.752409
3 2019-12-08T07:11:00.000Z 7443.12 7443.12 7440.92 7441.85 4.286640
4 2019-12-08T07:12:00.000Z 7441.84 7443.04 7437.90 7438.85 9.714785
kline_data.tail()
Datetime Open High Low Close Vol
495 2019-12-08T15:23:00.000Z 7531.89 7536.31 7531.01 7535.93 11.761618
496 2019-12-08T15:24:00.000Z 7535.98 7538.00 7531.56 7533.81 17.987021
497 2019-12-08T15:25:00.000Z 7533.26 7539.38 7532.25 7535.97 41.508465
498 2019-12-08T15:26:00.000Z 7536.84 7540.55 7536.01 7538.69 42.706338
499 2019-12-08T15:27:00.000Z 7536.89 7538.54 7534.97 7535.04 27.286387
kline_data.shape
(500, 6)
if binance_exchange.has['fetchOrders']:
    since = binance_exchange.parse8601('2019-12-06T00:00:00Z')
    end = binance_exchange.milliseconds() - 60 * 1000  # 前一分钟
    all_kline_data = []
    while since < end:
        symbol = 'BTC/USDT'
        kline_data = binance_exchange.fetch_ohlcv(symbol, since=since, timeframe='1m')
        print(binance_exchange.iso8601(since))
        if len(kline_data):
            # 更新获取时间
            since = kline_data[len(kline_data) - 1][0]
            all_kline_data += kline_data
        else:
            break
2019-12-06T00:00:00.000Z
2019-12-06T08:19:00.000Z
2019-12-06T16:38:00.000Z
2019-12-07T00:57:00.000Z
2019-12-07T09:16:00.000Z
2019-12-07T17:35:00.000Z
2019-12-08T01:54:00.000Z
2019-12-08T10:13:00.000Z
all_kline_data_df = pd.DataFrame(all_kline_data)
all_kline_data_df.columns = ['Datetime', 'Open', 'High', 'Low', 'Close', 'Vol']
all_kline_data_df['Datetime'] = all_kline_data_df['Datetime'].apply(binance_exchange.iso8601)
all_kline_data_df.shape
(3816, 6)
all_kline_data_df.head()
Datetime Open High Low Close Vol
0 2019-12-06T00:00:00.000Z 7389.00 7389.14 7378.36 7380.06 32.287087
1 2019-12-06T00:01:00.000Z 7379.52 7381.09 7374.56 7380.31 25.726149
2 2019-12-06T00:02:00.000Z 7380.32 7381.54 7361.51 7362.00 34.931360
3 2019-12-06T00:03:00.000Z 7362.90 7376.47 7362.49 7371.72 57.385524
4 2019-12-06T00:04:00.000Z 7372.25 7372.68 7361.67 7367.89 20.704690
all_kline_data_df.tail()
Datetime Open High Low Close Vol
3811 2019-12-08T15:24:00.000Z 7535.98 7538.00 7531.56 7533.81 17.987021
3812 2019-12-08T15:25:00.000Z 7533.26 7539.38 7532.25 7535.97 41.508465
3813 2019-12-08T15:26:00.000Z 7536.84 7540.55 7536.01 7538.69 42.706338
3814 2019-12-08T15:27:00.000Z 7536.89 7538.54 7534.97 7535.03 27.320591
3815 2019-12-08T15:28:00.000Z 7535.04 7536.90 7535.03 7536.89 0.717543
all_kline_data_df[all_kline_data_df['Datetime'].duplicated()]
Datetime Open High Low Close Vol
500 2019-12-06T08:19:00.000Z 7358.52 7358.70 7355.00 7355.00 28.169124
1000 2019-12-06T16:38:00.000Z 7403.20 7404.92 7396.73 7397.33 28.956847
1500 2019-12-07T00:57:00.000Z 7511.73 7516.53 7510.47 7516.46 29.754072
2000 2019-12-07T09:16:00.000Z 7497.48 7497.99 7494.18 7497.56 17.171503
2500 2019-12-07T17:35:00.000Z 7505.69 7507.04 7503.36 7504.79 7.136617
3000 2019-12-08T01:54:00.000Z 7438.74 7439.14 7432.64 7439.08 17.463862
3500 2019-12-08T10:13:00.000Z 7474.25 7474.65 7466.29 7469.32 27.449734
all_kline_data_df.drop_duplicates(subset=['Datetime'], inplace=True)
all_kline_data_df['Datetime'] = pd.to_datetime(all_kline_data_df['Datetime'] )
all_kline_data_df.set_index('Datetime', inplace=True)
import matplotlib.pyplot as plt
%matplotlib inline

all_kline_data_df['Open'].plot(figsize=(15, 8))

file

为者常成,行者常至