数字货币量化系统之 CCXT 框架使用委托下单 (下)
我们这里使用CCXT提供的私有API来委托下单,撤销订单,查询交易记录等操作。
一、交易所API申请
我们这里以 Binance.com 交易所为例,申请开放的API来下单、撤单等操作,不过需要科学上网。申请账号之后,我们给账户里边转入 12 USDT 进行测试。
二、实际操作
import ccxt
4. 交易
4.1 身份验证
# 初始化交易所
binance_exchange = ccxt.binance({
'apiKey': 'NNG6XatvBmznJIeNMXXXXXXXXXXXXXXXXeLuniAGCl8ZDKSb',
'secret': '8gU3JCAF4oKcxXXXXXXXXXXXXXXXX53TU04XA',
'timeout': 15000,
'enableRateLimit': True,
'proxies': {'https': "http://127.0.0.1:1087", 'http': "http://127.0.0.1:1087"}
})
#说明: apiKey:交易所key,secret:交易所密钥
4.2 查询账余额
binance_exchange.fetch_balance ()
{'info': {'makerCommission': 10,
'takerCommission': 10,
'buyerCommission': 0,
'sellerCommission': 0,
'canTrade': True,
'canWithdraw': True,
'canDeposit': True,
'updateTime': 1575903607695,
'accountType': 'SPOT',
'balances': [{'asset': 'BTC', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'LTC', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'ETH', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'NEO', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'BNB', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'QTUM', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'EOS', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'SNT', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'BNT', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'GAS', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'BCC', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'USDT', 'free': '12.64066000', 'locked': '0.00000000'},
...
{'asset': 'BCH', 'free': '0.00000000', 'locked': '0.00000000'},
{'asset': 'TROY', 'free': '0.00000000', 'locked': '0.00000000'}]},
'BTC': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'LTC': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'ETH': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'NEO': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'BNB': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'QTUM': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'EOS': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'SNT': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'BNT': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'GAS': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'BCC': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'USDT': {'free': 12.64066, 'used': 0.0, 'total': 12.64066},
'HSR': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'OAX': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'DNT': {'free': 0.0, 'used': 0.0, 'total': 0.0},
...
'DCR': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'USDC': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'MITH': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'BCH': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'ARPA': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'CTXC': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'TROY': {'free': 0.0, 'used': 0.0, 'total': 0.0},
'free': {'BTC': 0.0,
'LTC': 0.0,
'ETH': 0.0,
'NEO': 0.0,
'BNB': 0.0,
'QTUM': 0.0,
'EOS': 0.0,
'SNT': 0.0,
'BNT': 0.0,
'GAS': 0.0,
'BCC': 0.0,
'USDT': 12.64066,
'HSR': 0.0,
'OAX': 0.0,
...
'CTXC': 0.0,
'TROY': 0.0}}
print('BTC一共:', binance_exchange.fetch_balance ()['BTC']['total'])
print('BTC可用:', binance_exchange.fetch_balance ()['BTC']['free'])
print('BTC冻结:', binance_exchange.fetch_balance ()['BTC']['used'])
print()
print('USDT一共:', binance_exchange.fetch_balance ()['USDT']['total'])
print('USDT可用:', binance_exchange.fetch_balance ()['USDT']['free'])
print('USDT冻结:', binance_exchange.fetch_balance ()['USDT']['used'])
BTC一共: 0.0
BTC可用: 0.0
BTC冻结: 0.0
USDT一共: 12.64066
USDT可用: 12.64066
USDT冻结: 0.0
我给Binance 充了12.64刀做测试
4.3 订单
- 下单
# 以很低的价格买入波场,当然这个只会挂单,永远也不会成交(限价单)
if binance_exchange.has['createLimitOrder']:
binance_exchange.create_order(symbol='TRX/USDT', side='buy', type='limit', price=0.0100, amount=1000)
print('USDT一共:', binance_exchange.fetch_balance ()['USDT']['total'])
print('USDT可用:', binance_exchange.fetch_balance ()['USDT']['free'])
print('USDT冻结:', binance_exchange.fetch_balance ()['USDT']['used'])
USDT一共: 12.64066
USDT可用: 2.64066
USDT冻结: 10.0
我们也可以在Binance APP 上看到刚才下的委托单:
- 查询未成交订单
open_orders = binance_exchange.fetch_open_orders('TRX/USDT')
open_orders
[{'info': {'symbol': 'TRXUSDT',
'orderId': 159165583,
'orderListId': -1,
'clientOrderId': '7iGqXRlvmxo7iSueGN9kkU',
'price': '0.01000000',
'origQty': '1000.00000000',
'executedQty': '0.00000000',
'cummulativeQuoteQty': '0.00000000',
'status': 'NEW',
'timeInForce': 'GTC',
'type': 'LIMIT',
'side': 'BUY',
'stopPrice': '0.00000000',
'icebergQty': '0.00000000',
'time': 1575904473056,
'updateTime': 1575904473056,
'isWorking': True,
'origQuoteOrderQty': '0.00000000'},
'id': '159165583',
'timestamp': 1575904473056,
'datetime': '2019-12-09T15:14:33.056Z',
'lastTradeTimestamp': None,
'symbol': 'TRX/USDT',
'type': 'limit',
'side': 'buy',
'price': 0.01,
'amount': 1000.0,
'cost': 0.0,
'average': None,
'filled': 0.0,
'remaining': 1000.0,
'status': 'open',
'fee': None,
'trades': None}]
- 取消订单
open_orders[0]['info']['orderId']
159165583
# 取消订单
if binance_exchange.has['cancelOrder']:
for order in open_orders:
order_id = order['info']['orderId']
binance_exchange.cancel_order(order_id, 'TRX/USDT')
# 再次查询是否还有委托的订单
if binance_exchange.has['fetchOpenOrders']:
print(binance_exchange.fetch_open_orders('TRX/USDT'))
[]
- 查询交易完成的订单
if binance_exchange.has['fetchClosedOrders']:
closed_orders = binance_exchange.fetch_closed_orders('TRX/USDT')
for close_order in closed_orders:
print(close_order)
4.4 最佳价格下单
在下单时,为了保证成交,可以使用买卖的价差的一般来成交单
market_symbol = 'EOS/USDT'
ticker = binance_exchange.fetch_ticker(market_symbol) # fetching 24h stats on market, heavy call
print(ticker)
print()
price_precision = 4
amnt_precision = 4
# 计算差价
price_diff = ticker['ask'] - ticker['bid']
price_diff_half = float(round(((price_diff) / 2), price_precision))
print("price_diff_half:", price_diff_half)
# 买价(保证成交,原bid+一半价差)
best_buy_price = float(round((ticker['bid'] + price_diff_half), price_precision))
print("bid:", ticker['bid'])
print("best_buy_price:", best_buy_price)
# 卖价(也要保证成交)
best_sale_price = float(round((ticker['ask'] - price_diff_half), price_precision))
print("ask:", ticker['ask'])
print("best_sale_price:", best_sale_price)
# 买入操作
symbol = market_symbol
amount = 5
side = 'buy'
type = 'limit'
price = best_buy_price
# 买入测试
# The minimum quantity is equivalent of 10 USDT,如果少于10刀会报MIN_NOTIONAL这样的错误
res = binance_exchange.create_order(symbol=symbol, side=side, type=type, price=price, amount=amount)
print(res)
打印:
{'symbol': 'EOS/USDT', 'timestamp': 1591265112365, 'datetime': '2020-06-04T10:05:12.365Z', 'high': 2.7483, 'low': 2.6536, 'bid': 2.6945, 'bidVolume': 52.88, 'ask': 2.6954, 'askVolume': 22.17, 'vwap': 2.69660904, 'open': 2.6818, 'close': 2.6951, 'last': 2.6951, 'previousClose': 2.6817, 'change': 0.0133, 'percentage': 0.496, 'average': None, 'baseVolume': 6658621.98, 'quoteVolume': 17955700.205303, 'info': {'symbol': 'EOSUSDT', 'priceChange': '0.01330000', 'priceChangePercent': '0.496', 'weightedAvgPrice': '2.69660904', 'prevClosePrice': '2.68170000', 'lastPrice': '2.69510000', 'lastQty': '4.26000000', 'bidPrice': '2.69450000', 'bidQty': '52.88000000', 'askPrice': '2.69540000', 'askQty': '22.17000000', 'openPrice': '2.68180000', 'highPrice': '2.74830000', 'lowPrice': '2.65360000', 'volume': '6658621.98000000', 'quoteVolume': '17955700.20530300', 'openTime': 1591178712365, 'closeTime': 1591265112365, 'firstId': 51924000, 'lastId': 51983608, 'count': 59609}}
price_diff_half: 0.0004
bid: 2.6945
best_buy_price: 2.6949
ask: 2.6954
best_sale_price: 2.695
{'info': {'symbol': 'EOSUSDT', 'orderId': 739196471, 'orderListId': -1, 'clientOrderId': 'qWjl9yMp2GjYjmUt2q9HVR', 'transactTime': 1591265112949, 'price': '2.69490000', 'origQty': '5.00000000', 'executedQty': '0.00000000', 'cummulativeQuoteQty': '0.00000000', 'status': 'NEW', 'timeInForce': 'GTC', 'type': 'LIMIT', 'side': 'BUY'}, 'id': '739196471', 'clientOrderId': 'qWjl9yMp2GjYjmUt2q9HVR', 'timestamp': 1591265112949, 'datetime': '2020-06-04T10:05:12.949Z', 'lastTradeTimestamp': None, 'symbol': 'EOS/USDT', 'type': 'limit', 'side': 'buy', 'price': 2.6949, 'amount': 5.0, 'cost': 0.0, 'average': None, 'filled': 0.0, 'remaining': 5.0, 'status': 'open', 'fee': None, 'trades': None}
低于市场价挂委托单:
当前市场价为2.695,低于市场价 2.234 买入,看返回的结果:
2.234
{'info': {'symbol': 'EOSUSDT', 'orderId': 739214495, 'orderListId': -1, 'clientOrderId': 'GvK8Hd2RsUlFb1jLhmUbHY', 'transactTime': 1591265573673, 'price': '2.23400000', 'origQty': '5.00000000', 'executedQty': '0.00000000', 'cummulativeQuoteQty': '0.00000000', 'status': 'NEW', 'timeInForce': 'GTC', 'type': 'LIMIT', 'side': 'BUY'}, 'id': '739214495', 'clientOrderId': 'GvK8Hd2RsUlFb1jLhmUbHY', 'timestamp': 1591265573673, 'datetime': '2020-06-04T10:12:53.673Z', 'lastTradeTimestamp': None, 'symbol': 'EOS/USDT', 'type': 'limit', 'side': 'buy', 'price': 2.234, 'amount': 5.0, 'cost': 0.0, 'average': None, 'filled': 0.0, 'remaining': 5.0, 'status': 'open', 'fee': None, 'trades': None}
卖出:
# 卖出操作
symbol = market_symbol
amount = 4
side = 'sell'
type = 'limit'
price = best_sale_price
# 在卖出的时候也需要判断卖出交易额是否大于最小成交额,即必须 price * amount > cost_min
res = binance_exchange.create_order(symbol=symbol, side=side, type=type, price=price, amount=amount)
print(res)
结果打印:
{'info': {'symbol': 'EOSUSDT', 'orderId': 739862035, 'orderListId': -1, 'clientOrderId': 'aWMAuaIJjEzM51Evlhv5js', 'transactTime': 1591284841786, 'price': '2.72430000', 'origQty': '4.00000000', 'executedQty': '4.00000000', 'cummulativeQuoteQty': '10.90100200', 'status': 'FILLED', 'timeInForce': 'GTC', 'type': 'LIMIT', 'side': 'SELL'}, 'id': '739862035', 'clientOrderId': 'aWMAuaIJjEzM51Evlhv5js', 'timestamp': 1591284841786, 'datetime': '2020-06-04T15:34:01.786Z', 'lastTradeTimestamp': None, 'symbol': 'EOS/USDT', 'type': 'limit', 'side': 'sell', 'price': 2.7243, 'amount': 4.0, 'cost': 10.901002, 'average': 2.7252505, 'filled': 4.0, 'remaining': 0.0, 'status': 'closed', 'fee': None, 'trades': None}
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)