| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- const BinanceKit = require('./binance-kit')
- const HttpKit = require('../../kit/http-kit')
- const TimeKit = require("../../kit/time-kit");
- const HTTPRequest = require('request')
- const assert = require("assert");
- const isDev = process.env.USER === 'skyfffire'
- const proxy = 'http://localhost:9080'
- class BinanceSpot {
- static BASE_URL = 'https://api.binance.com'
- static TRADE_TYPE = {
- MARKET: 'MARKET'
- }
- static TRADE_SIDE = {
- BUY: 'buy',
- SELL: 'sell'
- }
- static PRICE = {
- MARKET: -1
- }
- static NETWORK = {
- BSC: 'BSC'
- }
- static BASE_TOKEN = {
- BUSD: 'BUSD'
- }
-
- constructor(apiKey, secretKey) {
- this.apiKey = apiKey
- this.secretKey = secretKey
- }
- static async realPrice(symbol='BNBBUSD', side=BinanceSpot.TRADE_SIDE.BUY) {
- const url = `${BinanceSpot.BASE_URL}/api/v3/depth?symbol=${symbol}&limit=${5}`
- const { data: rst } = await HttpKit.get(url)
- if (!rst || !rst.bids || !rst.asks || !rst.bids[0] || !rst.asks[0]) {
- return 0
- }
- if (side === BinanceSpot.TRADE_SIDE.SELL) {
- return parseFloat(rst.bids[0][0])
- } else {
- return parseFloat(rst.asks[0][0])
- }
- }
- static async exchangeInfo(symbols=['BNBBUSD', 'BTCBUSD']) {
- const url = `${BinanceSpot.BASE_URL}/api/v3/exchangeInfo?symbols=${BinanceKit.buildExchangeInfoSymbols(symbols)}`
- const { data: rst } = await HttpKit.get(url)
- return rst
- }
- async accountInfo() {
- const url = `${BinanceSpot.BASE_URL}/api/v3/account`
- let timestamp = new Date().getTime()
- let data = {
- timestamp: timestamp
- }
- let signature = BinanceKit.createSignature(this.secretKey, data)
- let finalQueryURL = BinanceKit.toFinalQueryURL(url, data, signature)
- let headers = {
- 'X-MBX-APIKEY': this.apiKey
- }
- const { data: rst } = await HttpKit.get(finalQueryURL, headers)
- return rst
- }
- async withdraw(amount, coin=BinanceSpot.BASE_TOKEN.BUSD,
- address='0xCfB3Cb29EeAE464ABD44E35d53e12c555705e824', network=BinanceSpot.NETWORK.BSC) {
- const url = `${BinanceSpot.BASE_URL}/sapi/v1/capital/withdraw/apply`
- let timestamp = new Date().getTime()
- let data = {
- timestamp: timestamp,
- coin: coin,
- address: address,
- amount: amount,
- network: network
- }
- let signature = BinanceKit.createSignature(this.secretKey, data)
- let finalQueryURL = BinanceKit.toFinalQueryURL(url, data, signature)
- let headers = {
- 'X-MBX-APIKEY': this.apiKey
- }
- const { data: rst } = await HttpKit.post(finalQueryURL, data, headers)
- return rst
- }
- async takeOrder(symbol='BTCUSDT', price, side, quantity, quoteOrderQty, type=BinanceSpot.TRADE_TYPE.MARKET) {
- const url = `${BinanceSpot.BASE_URL}/api/v3/order`
- let timestamp = new Date().getTime()
- let data = {
- timestamp: timestamp,
- symbol: symbol,
- side: side,
- type: type,
- recvWindow: 60 * 1000
- }
- // 区分买卖情况应该分别传入什么数量
- if (side === BinanceSpot.TRADE_SIDE.BUY) data['quoteOrderQty'] = quoteOrderQty
- else if (side === BinanceSpot.TRADE_SIDE.SELL) data['quantity'] = quantity
- // MARKET状态不传入price
- if (type !== 'MARKET') data['price'] = price
- let signature = BinanceKit.createSignature(this.secretKey, data)
- let finalQueryURL = BinanceKit.toFinalQueryURL(url, data, signature)
- let headers = {
- 'X-MBX-APIKEY': this.apiKey
- }
- const params = {
- url: finalQueryURL,
- method: 'POST',
- headers: headers,
- proxy: isDev ? proxy : undefined
- }
- let finish = false
- let rst = undefined
- HTTPRequest(params, function (error, response) {
- // 请求成功的处理逻辑
- if (!error) {
- rst = JSON.parse(response.body)
- } else {
- rst = error
- }
- finish = true
- })
- while (!finish) {
- await TimeKit.sleep(10)
- }
- return rst
- }
- async buy(pair, price, quoteOrderQty, type=BinanceSpot.TRADE_TYPE.MARKET) {
- return await this.takeOrder(
- pair,
- price,
- BinanceSpot.TRADE_SIDE.BUY,
- 0,
- quoteOrderQty,
- type)
- }
- async sell(pair, price, quantity, type=BinanceSpot.TRADE_TYPE.MARKET) {
- return await this.takeOrder(
- pair,
- price,
- BinanceSpot.TRADE_SIDE.SELL,
- quantity,
- 0,
- type)
- }
- async buyMarket(pair, quoteOrderQty) {
- const buyRst = await this.buy(pair, -1, quoteOrderQty)
- assert.notEqual(buyRst.executedQty, undefined, JSON.stringify(buyRst))
- const cummulativeQuoteQty = parseFloat(buyRst.cummulativeQuoteQty)
- // 计算扣除手续费后的实际成交数量
- let executedQty = 0
- for (const fill of buyRst.fills) {
- executedQty += parseFloat(fill.qty)
- // 扣除支付的手续费
- if (fill.commissionAsset !== 'BNB') executedQty -= parseFloat(fill.commission)
- }
- return {
- cummulativeQuoteQty: cummulativeQuoteQty,
- executedQty: executedQty,
- avgPrice: cummulativeQuoteQty / executedQty
- }
- }
- async sellMarket(pair, quantity) {
- const sellRst = await this.sell(pair, -1, quantity)
- assert.notEqual(sellRst.executedQty, undefined, JSON.stringify(sellRst))
- let cummulativeQuoteQty = parseFloat(sellRst.cummulativeQuoteQty)
- // 计算扣除手续费后的实际成交数量
- let executedQty = 0
- for (const fill of sellRst.fills) {
- executedQty += parseFloat(fill.qty)
- // 扣除支付的手续费
- if (fill.commissionAsset !== 'BNB') cummulativeQuoteQty -= parseFloat(fill.commission)
- }
- return {
- cummulativeQuoteQty: cummulativeQuoteQty,
- executedQty: executedQty,
- avgPrice: cummulativeQuoteQty / executedQty
- }
- }
- }
- module.exports = BinanceSpot
|