ZetCode

Python ccxt

最后修改于 2024 年 1 月 29 日

在本文中,我们将介绍如何在 Python 中使用 ccxt 加密货币库。

ccxt 是一个用于加密货币交易和电子商务的 JavaScript/Python/PHP 库。它支持许多加密货币交易所市场和商家 API。

它提供了对市场数据的快速访问,用于存储、分析、可视化、指标开发、算法交易、策略回测和机器人编程。

大多数交易所都提供公共和私有 API。对于私有 API,我们需要提供在交易所账户中生成的 API 密钥。

$ pip install ccxt

我们安装模块。

Python ccxt 交易所

在第一个示例中,我们打印所有可用的交易所。请注意,并非所有交易所都得到完全支持,有些可能无法正常工作。

main.py
#!/usr/bin/python

import ccxt

print(ccxt.exchanges)
print(len(ccxt.exchanges))

我们通过 exchanges 属性获取可用的交易所。

交易所状态

交易所的状态由 fetch_status 确定。

main.py
#!/usr/bin/python

import asyncio
import ccxt.async_support as ccxt

exchanges = [ccxt.__getattribute__(e)() for e in ccxt.exchanges]

async def status(exchange):

    try:

        data = await exchange.fetch_status()

    except Exception as e:

        data = str(e)
        stat = data[:60] + ('..' if len(data) > 60 else '')
        data = {'status': stat}

    finally: 
        await exchange.close()

    return (exchange.name, data)


async def launch():

    resps = await asyncio.gather(*map(status, exchanges))

    for name, e in resps:
        stat = e['status']
        print(f"{name}: {stat}")

asyncio.run(launch())

程序检查所有可用交易所的状态。

import ccxt.async_support as ccxt

由于我们需要发起数十个请求,代码是异步运行的,以避免阻塞。

async def status(exchange):

状态代码是在异步 status 函数中确定的。

exchanges = [ccxt.__getattribute__(e)() for e in ccxt.exchanges]

我们构建了可用交易所对象的列表。由于 ccxt.exchanges 返回交易所属性的列表,我们需要调用它们来获取交易所对象。

try:

    data = await exchange.fetch_status()

我们在 try 块中调用 fetch_status

except Exception as e:

    data = str(e)
    stat = data[:60] + ('..' if len(data) > 60 else '')
    data = {'status': stat}

大多数交易所以 JSON 格式返回错误代码。然而,有些返回 HTML 响应。这会使我们的终端混乱。如果响应数据大于 60 个字符,我们会将其缩短。

finally: 
    await exchange.close()

最后,有必要关闭与交易所的连接。

return (exchange.name, data)

该函数为每次调用返回交易所名称和状态数据。

async def launch():

    resps = await asyncio.gather(*map(status, exchanges))

    for name, e in resps:
        stat = e['status']
        print(f"{name}: {stat}")

我们将状态函数应用于交易所列表。我们在 for 循环中遍历响应,并为每个交易所打印名称和状态。

asyncio.run(launch())

run 函数启动循环并处理异步操作。

获取行情价格

fetch_ticker 函数获取价格行情。它是一个统计计算,包含过去 24 小时内为特定交易对计算的信息。

main.py
#!/usr/bin/python

import asyncio
import ccxt.async_support as ccxt
from pprint import pprint

async def ticker():

    bybit = ccxt.bybit()

    res = await bybit.fetch_ticker('LTC/USDT')
    pprint(res)

    await bybit.close()

asyncio.run(ticker())

该程序在 Bybit 交易所上检索 LTC/USDT 交易对的行情信息。

pprint(res)

pprint 函数美观地打印输出。

$ ./main.py
{'ask': 88.08,
 'askVolume': 10.5,
 'average': 87.37,
 'baseVolume': 57756.04142,
 'bid': 88.07,
 'bidVolume': 58.67049,
 'change': 1.4,
 'close': 88.07,
 'datetime': None,
 'high': 88.48,
 'info': {'ask1Price': '88.08',
          'ask1Size': '10.5',
          'bid1Price': '88.07',
          'bid1Size': '58.67049',
          'highPrice24h': '88.48',
          'lastPrice': '88.07',
          'lowPrice24h': '84.22',
          'prevPrice24h': '86.67',
          'price24hPcnt': '0.0162',
          'symbol': 'LTCUSDT',
          'turnover24h': '5010476.0735012',
          'usdIndexPrice': '88.11038504',
          'volume24h': '57756.04142'},
 'last': 88.07,
 'low': 84.22,
 'open': 86.67,
 'percentage': 1.62,
 'previousClose': None,
 'quoteVolume': 5010476.0735012,
 'symbol': 'LTC/USDT:USDT',
 'timestamp': None,
 'vwap': 86.7524149909303}

行情信息包括当前(最新)、开盘、最高、最低、收盘价、交易量等值。

Binance 交易对

交易对是交易品种。它由基础资产和报价资产组成。给定交易对 BTCBUSD,BTC 代表基础资产,BUSD 代表报价资产。

main.py
#!/usr/bin/python

from datetime import datetime

import ccxt
from rich import box
from rich.console import Console
from rich.table import Table

binance = ccxt.binance()

markets = binance.load_markets()

print(f'Binance has {len(binance.symbols)} symbols')

data = list(ccxt.Exchange.keysort(markets).items())

now = f'{datetime.today()}'
table = Table(title='Binance symbols', box=box.ASCII,
              caption=now, caption_justify='left')

table.add_column('id', style='steel_blue')
table.add_column('symbol')
table.add_column('base', style='cadet_blue')
table.add_column('quote', style='cadet_blue')

for (_, v) in data:
    table.add_row(v['id'], v['symbol'], v['base'], v['quote'])

console = Console()
console.print(table)

该程序列出了 Binance 交易所上所有可用的交易对。我们使用 richTable 以整洁的表格显示所有数据。

binance = ccxt.binance()

我们获取 Binance 交易所。

markets = binance.load_markets()

使用 load_markets,我们获取 Binance 上的所有市场。不同的市场(现货、期货)有不同的交易对。

data = list(ccxt.Exchange.keysort(markets).items())

我们对数据进行排序。

now = f'{datetime.today()}'
table = Table(title='Binance symbols', box=box.ASCII,
                caption=now, caption_justify='left')

table.add_column('id', style='steel_blue')
table.add_column('symbol')
table.add_column('base', style='cadet_blue')
table.add_column('quote', style='cadet_blue')

数据在表格中显示。表格有四列。

for (_, v) in data:
    table.add_row(v['id'], v['symbol'], v['base'], v['quote'])

我们将数据添加到表格中。

console = Console()
console.print(table)

表格被打印到控制台。

获取余额

fetch_balance 函数查询余额,获取可用于交易的资金数量或锁定在订单中的资金。由于这是私有信息,我们需要提供密钥。

main.py
#!/usr/bin/python

import asyncio
import os
import ccxt.async_support as ccxt

async def balance():

    binance = ccxt.binance({
        'apiKey': os.getenv('BINANCE_API_KEY'),
        'secret': os.getenv('BINANCE_SECRET_KEY'),
    })

    res = await binance.fetch_balance()
    data = [(coin, balance) for coin, balance in res['total'].items() if balance > 0]

    for name, amount in data:
        print(f'{name:<4} {amount:>18.8f}')

    await binance.close()


asyncio.run(balance())

我们从 Binance 获取所有大于零的余额。

binance = ccxt.binance({
    'apiKey': os.getenv('BINANCE_API_KEY'),
    'secret': os.getenv('BINANCE_SECRET_KEY'),
})

我们提供 API 密钥和秘密密钥。密钥从环境变量加载。

res = await binance.fetch_balance()

我们获取所有余额。

data = [(coin, balance) for coin, balance in res['total'].items() if balance > 0]

使用 Python 列表推导式,我们仅获取余额大于零的余额。

for name, amount in data:
    print(f'{name:<4} {amount:>18.8f}')

我们使用 Python 的格式化选项来整洁地显示数据。交易品种左对齐。金额右对齐。值显示为 8 位小数。

订单簿

订单簿是特定资产当前买单(买入价)和卖单(卖出价)的列表。订单簿列出了买/卖订单的价格以及要买卖的代币单位数量。

买入价由绿色数字表示,卖出价由红色数字表示。

main.py
#!/usr/bin/python

import asyncio
import ccxt.async_support as ccxt
from pprint import pprint

green = '\033[92m'
red = '\033[91m'
term = '\033[0m'

async def order_book():

    bitrue = ccxt.bitrue()

    order_book = await bitrue.fetch_order_book('ETH/USDT', limit=20)
    bids = order_book['bids']
    asks = order_book['asks']

    for p, a in bids:
        print(f'{green}{p:.2f} {a:>12.5f}{term}')

    print('----------------------')

    for p, a in asks:
        print(f'{red}{p:.2f} {a:>12.5f}{term}')

    await bitrue.close()


asyncio.run(order_book())

该程序显示 Bitrue 交易所上 ETH/USDT 交易对的订单簿。

green = '\033[92m'
red = '\033[91m'
term = '\033[0m'

我们将值显示为彩色。这些是绿色、红色和颜色终止的代码。

order_book = await bitrue.fetch_order_book('ETH/USDT', limit=20)

我们使用 fetch_order_book 检索订单簿。我们获取最后 20 个值。

bids = order_book['bids']
asks = order_book['asks']

从订单簿数据中,我们获取买入价和卖出价。

for p, a in bids:
    print(f'{green}{p:.2f} {a:>12.5f}{term}')

print('----------------------')

for p, a in asks:
    print(f'{red}{p:.2f} {a:>12.5f}{term}')

首先,我们以绿色显示买入价,然后以红色显示卖出价。

我的交易

fetch_my_trades 检索用户进行的所有交易。

main.py
#!/usr/bin/python

import os
import asyncio
import ccxt.async_support as ccxt
from datetime import datetime


async def trades():

    binance = ccxt.binance({
        'apiKey': os.getenv('BINANCE_API_KEY'),
        'secret': os.getenv('BINANCE_SECRET_KEY'),
    })

    symbol = 'LTC/BUSD'
    date = '2023-03-20T00:00:00'
    start_time = binance.parse8601(date)

    print(f'Fetching {symbol} trades since {binance.iso8601(start_time)}')
    trades = await binance.fetch_my_trades(symbol, start_time)

    await binance.close()

    print(f'Fetched {len(trades)} trades')

    for trade in trades:

        d = datetime.fromisoformat(trade['datetime'])
        print(f"{d:%m/%d/%Y} {trade['amount']} {trade['side']}")


asyncio.run(trades())

该示例检索所有 LTC/BUSD 交易。

symbol = 'LTC/BUSD'

交易对是 LTC/BUSD。

date = '2023-03-20T00:00:00'
start_time = binance.parse8601(date)

我们显示自指定日期以来的所有交易。binance.parse8601 是一个辅助函数,它将字符串日期时间转换为 Unix 时间。

trades = await binance.fetch_my_trades(symbol, start_time)

我们使用 fetch_my_trades 获取自指定日期以来的所有 LTC/BUSD 交易。

for trade in trades:

    d = datetime.fromisoformat(trade['datetime'])
    print(f"{d:%m/%d/%Y} {trade['amount']} {trade['side']}")

我们将检索到的数据打印到控制台。我们显示日期、数量和方向(买入或卖出)。

K 线数据

fetch_ohlcv 获取历史 K 线数据,其中包含开盘价、最高价、最低价、收盘价和市场交易量。

main.py
#!/usr/bin/python

import asyncio
import ccxt.async_support as ccxt

from rich import box
from rich.console import Console
from rich.table import Table
from datetime import datetime


async def ohlc():

    binance = ccxt.binance()
    data = await binance.fetch_ohlcv('BTC/USDT', '1d', limit=20)
    await binance.close()

    now = f'{datetime.today()}'
    table = Table(title='Binance - BTC/USDT', box=box.ASCII,
                  caption=now, caption_justify='left')

    table.add_column('Date', justify='center', style='steel_blue')
    table.add_column('Open')
    table.add_column('High')
    table.add_column('Low')
    table.add_column('Close')
    table.add_column('Volume', justify='right', style='cadet_blue')

    for e in data:

        d = datetime.utcfromtimestamp(e[0]/1000.0)
        table.add_row(f'{d:%m/%d/%Y}', f'{e[1]:.2f}', f'{e[2]:.2f}',
                      f'{e[3]:.2f}', f'{e[4]:.2f}', f'{e[5]:.5f}')

    console = Console()
    console.print(table)

asyncio.run(ohlc())

该示例在 Binance 上检索 BTC/USDT 过去 20 天的 K 线数据。

data = await binance.fetch_ohlcv('BTC/USDT', '1d', limit=20)

我们获取数据。时间范围是 1 天,限制是 20 个值。

来源

ccxt 文档

在本文中,我们介绍了如何使用 ccxt 加密货币库。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在教学编程方面拥有十多年的经验。

列出所有 Python 教程