3716 lines
160 KiB
Go
3716 lines
160 KiB
Go
package ccxt
|
|
|
|
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
|
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
|
|
|
type bitrue struct {
|
|
Exchange
|
|
|
|
}
|
|
|
|
func NewBitrueCore() bitrue {
|
|
p := bitrue{}
|
|
setDefaults(&p)
|
|
return p
|
|
}
|
|
|
|
func (this *bitrue) Describe() interface{} {
|
|
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
|
|
"id": "bitrue",
|
|
"name": "Bitrue",
|
|
"countries": []interface{}{"SG"},
|
|
"rateLimit": 1000,
|
|
"certified": false,
|
|
"version": "v1",
|
|
"pro": true,
|
|
"has": map[string]interface{} {
|
|
"CORS": nil,
|
|
"spot": true,
|
|
"margin": false,
|
|
"swap": true,
|
|
"future": false,
|
|
"option": false,
|
|
"cancelAllOrders": true,
|
|
"cancelOrder": true,
|
|
"createMarketBuyOrderWithCost": true,
|
|
"createMarketOrderWithCost": false,
|
|
"createMarketSellOrderWithCost": false,
|
|
"createOrder": true,
|
|
"createStopLimitOrder": true,
|
|
"createStopMarketOrder": true,
|
|
"createStopOrder": true,
|
|
"fetchBalance": true,
|
|
"fetchBidsAsks": true,
|
|
"fetchBorrowRateHistories": false,
|
|
"fetchBorrowRateHistory": false,
|
|
"fetchClosedOrders": true,
|
|
"fetchCrossBorrowRate": false,
|
|
"fetchCrossBorrowRates": false,
|
|
"fetchCurrencies": true,
|
|
"fetchDepositAddress": false,
|
|
"fetchDeposits": true,
|
|
"fetchDepositsWithdrawals": false,
|
|
"fetchDepositWithdrawFee": "emulated",
|
|
"fetchDepositWithdrawFees": true,
|
|
"fetchFundingHistory": false,
|
|
"fetchFundingRate": false,
|
|
"fetchFundingRateHistory": false,
|
|
"fetchFundingRates": false,
|
|
"fetchIsolatedBorrowRate": false,
|
|
"fetchIsolatedBorrowRates": false,
|
|
"fetchMarginMode": false,
|
|
"fetchMarkets": true,
|
|
"fetchMyTrades": true,
|
|
"fetchOHLCV": true,
|
|
"fetchOpenOrders": true,
|
|
"fetchOrder": true,
|
|
"fetchOrderBook": true,
|
|
"fetchOrders": false,
|
|
"fetchPositionMode": false,
|
|
"fetchStatus": true,
|
|
"fetchTicker": true,
|
|
"fetchTickers": true,
|
|
"fetchTime": true,
|
|
"fetchTrades": true,
|
|
"fetchTradingFee": false,
|
|
"fetchTradingFees": false,
|
|
"fetchTransactionFees": false,
|
|
"fetchTransactions": false,
|
|
"fetchTransfers": true,
|
|
"fetchWithdrawals": true,
|
|
"setLeverage": true,
|
|
"setMargin": true,
|
|
"transfer": true,
|
|
"withdraw": true,
|
|
},
|
|
"timeframes": map[string]interface{} {
|
|
"1m": "1m",
|
|
"5m": "5m",
|
|
"15m": "15m",
|
|
"30m": "30m",
|
|
"1h": "1H",
|
|
"2h": "2H",
|
|
"4h": "4H",
|
|
"1d": "1D",
|
|
"1w": "1W",
|
|
},
|
|
"urls": map[string]interface{} {
|
|
"logo": "https://github.com/user-attachments/assets/67abe346-1273-461a-bd7c-42fa32907c8e",
|
|
"api": map[string]interface{} {
|
|
"spot": "https://www.bitrue.com/api",
|
|
"fapi": "https://fapi.bitrue.com/fapi",
|
|
"dapi": "https://fapi.bitrue.com/dapi",
|
|
"kline": "https://www.bitrue.com/kline-api",
|
|
},
|
|
"www": "https://www.bitrue.com",
|
|
"referral": "https://www.bitrue.com/affiliate/landing?cn=600000&inviteCode=EZWETQE",
|
|
"doc": []interface{}{"https://github.com/Bitrue-exchange/bitrue-official-api-docs", "https://www.bitrue.com/api-docs"},
|
|
"fees": "https://bitrue.zendesk.com/hc/en-001/articles/4405479952537",
|
|
},
|
|
"api": map[string]interface{} {
|
|
"spot": map[string]interface{} {
|
|
"kline": map[string]interface{} {
|
|
"public": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"public.json": 1,
|
|
"public{currency}.json": 1,
|
|
},
|
|
},
|
|
},
|
|
"v1": map[string]interface{} {
|
|
"public": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"ping": 1,
|
|
"time": 1,
|
|
"exchangeInfo": 1,
|
|
"depth": map[string]interface{} {
|
|
"cost": 1,
|
|
"byLimit": []interface{}{[]interface{}{100, 1}, []interface{}{500, 5}, []interface{}{1000, 10}},
|
|
},
|
|
"trades": 1,
|
|
"historicalTrades": 5,
|
|
"aggTrades": 1,
|
|
"ticker/24hr": map[string]interface{} {
|
|
"cost": 1,
|
|
"noSymbol": 40,
|
|
},
|
|
"ticker/price": map[string]interface{} {
|
|
"cost": 1,
|
|
"noSymbol": 2,
|
|
},
|
|
"ticker/bookTicker": map[string]interface{} {
|
|
"cost": 1,
|
|
"noSymbol": 2,
|
|
},
|
|
"market/kline": 1,
|
|
},
|
|
},
|
|
"private": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"order": 1,
|
|
"openOrders": 1,
|
|
"allOrders": 5,
|
|
"account": 5,
|
|
"myTrades": map[string]interface{} {
|
|
"cost": 5,
|
|
"noSymbol": 40,
|
|
},
|
|
"etf/net-value/{symbol}": 1,
|
|
"withdraw/history": 1,
|
|
"deposit/history": 1,
|
|
},
|
|
"post": map[string]interface{} {
|
|
"order": 4,
|
|
"withdraw/commit": 1,
|
|
},
|
|
"delete": map[string]interface{} {
|
|
"order": 1,
|
|
},
|
|
},
|
|
},
|
|
"v2": map[string]interface{} {
|
|
"private": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"myTrades": 5,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"fapi": map[string]interface{} {
|
|
"v1": map[string]interface{} {
|
|
"public": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"ping": 1,
|
|
"time": 1,
|
|
"contracts": 1,
|
|
"depth": 1,
|
|
"ticker": 1,
|
|
"klines": 1,
|
|
},
|
|
},
|
|
},
|
|
"v2": map[string]interface{} {
|
|
"private": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"myTrades": 1,
|
|
"openOrders": 1,
|
|
"order": 1,
|
|
"account": 1,
|
|
"leverageBracket": 1,
|
|
"commissionRate": 1,
|
|
"futures_transfer_history": 1,
|
|
"forceOrdersHistory": 1,
|
|
},
|
|
"post": map[string]interface{} {
|
|
"positionMargin": 1,
|
|
"level_edit": 1,
|
|
"cancel": 1,
|
|
"order": 1,
|
|
"allOpenOrders": 1,
|
|
"futures_transfer": 1,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"dapi": map[string]interface{} {
|
|
"v1": map[string]interface{} {
|
|
"public": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"ping": 1,
|
|
"time": 1,
|
|
"contracts": 1,
|
|
"depth": 1,
|
|
"ticker": 1,
|
|
"klines": 1,
|
|
},
|
|
},
|
|
},
|
|
"v2": map[string]interface{} {
|
|
"private": map[string]interface{} {
|
|
"get": map[string]interface{} {
|
|
"myTrades": 1,
|
|
"openOrders": 1,
|
|
"order": 1,
|
|
"account": 1,
|
|
"leverageBracket": 1,
|
|
"commissionRate": 1,
|
|
"futures_transfer_history": 1,
|
|
"forceOrdersHistory": 1,
|
|
},
|
|
"post": map[string]interface{} {
|
|
"positionMargin": 1,
|
|
"level_edit": 1,
|
|
"cancel": 1,
|
|
"order": 1,
|
|
"allOpenOrders": 1,
|
|
"futures_transfer": 1,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"fees": map[string]interface{} {
|
|
"trading": map[string]interface{} {
|
|
"feeSide": "get",
|
|
"tierBased": false,
|
|
"percentage": true,
|
|
"taker": this.ParseNumber("0.00098"),
|
|
"maker": this.ParseNumber("0.00098"),
|
|
},
|
|
"future": map[string]interface{} {
|
|
"trading": map[string]interface{} {
|
|
"feeSide": "quote",
|
|
"tierBased": true,
|
|
"percentage": true,
|
|
"taker": this.ParseNumber("0.000400"),
|
|
"maker": this.ParseNumber("0.000200"),
|
|
"tiers": map[string]interface{} {
|
|
"taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.000400")}, []interface{}{this.ParseNumber("250"), this.ParseNumber("0.000400")}, []interface{}{this.ParseNumber("2500"), this.ParseNumber("0.000350")}, []interface{}{this.ParseNumber("7500"), this.ParseNumber("0.000320")}, []interface{}{this.ParseNumber("22500"), this.ParseNumber("0.000300")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.000270")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.000250")}, []interface{}{this.ParseNumber("200000"), this.ParseNumber("0.000220")}, []interface{}{this.ParseNumber("400000"), this.ParseNumber("0.000200")}, []interface{}{this.ParseNumber("750000"), this.ParseNumber("0.000170")}},
|
|
"maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.000200")}, []interface{}{this.ParseNumber("250"), this.ParseNumber("0.000160")}, []interface{}{this.ParseNumber("2500"), this.ParseNumber("0.000140")}, []interface{}{this.ParseNumber("7500"), this.ParseNumber("0.000120")}, []interface{}{this.ParseNumber("22500"), this.ParseNumber("0.000100")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.000080")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.000060")}, []interface{}{this.ParseNumber("200000"), this.ParseNumber("0.000040")}, []interface{}{this.ParseNumber("400000"), this.ParseNumber("0.000020")}, []interface{}{this.ParseNumber("750000"), this.ParseNumber("0")}},
|
|
},
|
|
},
|
|
},
|
|
"delivery": map[string]interface{} {
|
|
"trading": map[string]interface{} {
|
|
"feeSide": "base",
|
|
"tierBased": true,
|
|
"percentage": true,
|
|
"taker": this.ParseNumber("0.000500"),
|
|
"maker": this.ParseNumber("0.000100"),
|
|
"tiers": map[string]interface{} {
|
|
"taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.000500")}, []interface{}{this.ParseNumber("250"), this.ParseNumber("0.000450")}, []interface{}{this.ParseNumber("2500"), this.ParseNumber("0.000400")}, []interface{}{this.ParseNumber("7500"), this.ParseNumber("0.000300")}, []interface{}{this.ParseNumber("22500"), this.ParseNumber("0.000250")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.000240")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.000240")}, []interface{}{this.ParseNumber("200000"), this.ParseNumber("0.000240")}, []interface{}{this.ParseNumber("400000"), this.ParseNumber("0.000240")}, []interface{}{this.ParseNumber("750000"), this.ParseNumber("0.000240")}},
|
|
"maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.000100")}, []interface{}{this.ParseNumber("250"), this.ParseNumber("0.000080")}, []interface{}{this.ParseNumber("2500"), this.ParseNumber("0.000050")}, []interface{}{this.ParseNumber("7500"), this.ParseNumber("0.0000030")}, []interface{}{this.ParseNumber("22500"), this.ParseNumber("0")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("-0.000050")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("-0.000060")}, []interface{}{this.ParseNumber("200000"), this.ParseNumber("-0.000070")}, []interface{}{this.ParseNumber("400000"), this.ParseNumber("-0.000080")}, []interface{}{this.ParseNumber("750000"), this.ParseNumber("-0.000090")}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"options": map[string]interface{} {
|
|
"createMarketBuyOrderRequiresPrice": true,
|
|
"fetchMarkets": []interface{}{"spot", "linear", "inverse"},
|
|
"fetchMyTradesMethod": "v2PrivateGetMyTrades",
|
|
"hasAlreadyAuthenticatedSuccessfully": false,
|
|
"currencyToPrecisionRoundingMode": TRUNCATE,
|
|
"recvWindow": Multiply(5, 1000),
|
|
"timeDifference": 0,
|
|
"adjustForTimeDifference": false,
|
|
"parseOrderToPrecision": false,
|
|
"newOrderRespType": map[string]interface{} {
|
|
"market": "FULL",
|
|
"limit": "FULL",
|
|
},
|
|
"networks": map[string]interface{} {
|
|
"ERC20": "ETH",
|
|
"TRC20": "TRX",
|
|
"AETERNITY": "Aeternity",
|
|
"AION": "AION",
|
|
"ALGO": "Algorand",
|
|
"ASK": "ASK",
|
|
"ATOM": "ATOM",
|
|
"AVAXC": "AVAX C-Chain",
|
|
"BCH": "BCH",
|
|
"BEP2": "BEP2",
|
|
"BEP20": "BEP20",
|
|
"Bitcoin": "Bitcoin",
|
|
"BRP20": "BRP20",
|
|
"ADA": "Cardano",
|
|
"CASINOCOIN": "CasinoCoin",
|
|
"CASINOCOIN-XRPL": "CasinoCoin XRPL",
|
|
"CONTENTOS": "Contentos",
|
|
"DASH": "Dash",
|
|
"DECOIN": "Decoin",
|
|
"DFI": "DeFiChain",
|
|
"DGB": "DGB",
|
|
"DIVI": "Divi",
|
|
"DOGE": "dogecoin",
|
|
"EOS": "EOS",
|
|
"ETC": "ETC",
|
|
"FILECOIN": "Filecoin",
|
|
"FREETON": "FREETON",
|
|
"HBAR": "HBAR",
|
|
"HEDERA": "Hedera Hashgraph",
|
|
"HRC20": "HRC20",
|
|
"ICON": "ICON",
|
|
"ICP": "ICP",
|
|
"IGNIS": "Ignis",
|
|
"INTERNETCOMPUTER": "Internet Computer",
|
|
"IOTA": "IOTA",
|
|
"KAVA": "KAVA",
|
|
"KSM": "KSM",
|
|
"LTC": "LiteCoin",
|
|
"LUNA": "Luna",
|
|
"MATIC": "MATIC",
|
|
"MOBILECOIN": "Mobile Coin",
|
|
"MONACOIN": "MonaCoin",
|
|
"XMR": "Monero",
|
|
"NEM": "NEM",
|
|
"NEP5": "NEP5",
|
|
"OMNI": "OMNI",
|
|
"PAC": "PAC",
|
|
"DOT": "Polkadot",
|
|
"RAVEN": "Ravencoin",
|
|
"SAFEX": "Safex",
|
|
"SOL": "SOLANA",
|
|
"SGB": "Songbird",
|
|
"XML": "Stellar Lumens",
|
|
"XYM": "Symbol",
|
|
"XTZ": "Tezos",
|
|
"theta": "theta",
|
|
"THETA": "THETA",
|
|
"VECHAIN": "VeChain",
|
|
"WANCHAIN": "Wanchain",
|
|
"XINFIN": "XinFin Network",
|
|
"XRP": "XRP",
|
|
"XRPL": "XRPL",
|
|
"ZIL": "ZIL",
|
|
},
|
|
"defaultType": "spot",
|
|
"timeframes": map[string]interface{} {
|
|
"spot": map[string]interface{} {
|
|
"1m": "1m",
|
|
"5m": "5m",
|
|
"15m": "15m",
|
|
"30m": "30m",
|
|
"1h": "1H",
|
|
"2h": "2H",
|
|
"4h": "4H",
|
|
"12h": "12H",
|
|
"1d": "1D",
|
|
"1w": "1W",
|
|
},
|
|
"future": map[string]interface{} {
|
|
"1m": "1min",
|
|
"5m": "5min",
|
|
"15m": "15min",
|
|
"30m": "30min",
|
|
"1h": "1h",
|
|
"1d": "1day",
|
|
"1w": "1week",
|
|
"1M": "1month",
|
|
},
|
|
},
|
|
"accountsByType": map[string]interface{} {
|
|
"spot": "wallet",
|
|
"future": "contract",
|
|
"swap": "contract",
|
|
"funding": "wallet",
|
|
"fund": "wallet",
|
|
"contract": "contract",
|
|
},
|
|
},
|
|
"commonCurrencies": map[string]interface{} {
|
|
"MIM": "MIM Swarm",
|
|
},
|
|
"precisionMode": TICK_SIZE,
|
|
"features": map[string]interface{} {
|
|
"default": map[string]interface{} {
|
|
"sandbox": false,
|
|
"createOrder": map[string]interface{} {
|
|
"marginMode": false,
|
|
"triggerPrice": true,
|
|
"triggerPriceType": nil,
|
|
"triggerDirection": nil,
|
|
"stopLossPrice": false,
|
|
"takeProfitPrice": false,
|
|
"attachedStopLossTakeProfit": nil,
|
|
"timeInForce": map[string]interface{} {
|
|
"IOC": true,
|
|
"FOK": true,
|
|
"PO": true,
|
|
"GTD": false,
|
|
},
|
|
"hedged": false,
|
|
"trailing": false,
|
|
"leverage": false,
|
|
"marketBuyRequiresPrice": true,
|
|
"marketBuyByCost": true,
|
|
"selfTradePrevention": false,
|
|
"iceberg": true,
|
|
},
|
|
"createOrders": nil,
|
|
"fetchMyTrades": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 1000,
|
|
"daysBack": 100000,
|
|
"untilDays": 100000,
|
|
"symbolRequired": true,
|
|
},
|
|
"fetchOrder": map[string]interface{} {
|
|
"marginMode": false,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": true,
|
|
},
|
|
"fetchOpenOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": nil,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": true,
|
|
},
|
|
"fetchOrders": nil,
|
|
"fetchClosedOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 1000,
|
|
"daysBack": 90,
|
|
"daysBackCanceled": 1,
|
|
"untilDays": 90,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": true,
|
|
},
|
|
"fetchOHLCV": map[string]interface{} {
|
|
"limit": 1440,
|
|
},
|
|
},
|
|
"spot": map[string]interface{} {
|
|
"extends": "default",
|
|
},
|
|
"forDerivatives": map[string]interface{} {
|
|
"extends": "default",
|
|
"createOrder": map[string]interface{} {
|
|
"marginMode": true,
|
|
"leverage": true,
|
|
"marketBuyRequiresPrice": false,
|
|
"marketBuyByCost": false,
|
|
},
|
|
"fetchOHLCV": map[string]interface{} {
|
|
"limit": 300,
|
|
},
|
|
"fetchClosedOrders": nil,
|
|
},
|
|
"swap": map[string]interface{} {
|
|
"linear": map[string]interface{} {
|
|
"extends": "forDerivatives",
|
|
},
|
|
"inverse": map[string]interface{} {
|
|
"extends": "forDerivatives",
|
|
},
|
|
},
|
|
"future": map[string]interface{} {
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
},
|
|
},
|
|
"exceptions": map[string]interface{} {
|
|
"exact": map[string]interface{} {
|
|
"System is under maintenance.": OnMaintenance,
|
|
"System abnormality": ExchangeError,
|
|
"You are not authorized to execute this request.": PermissionDenied,
|
|
"API key does not exist": AuthenticationError,
|
|
"Order would trigger immediately.": OrderImmediatelyFillable,
|
|
"Stop price would trigger immediately.": OrderImmediatelyFillable,
|
|
"Order would immediately match and take.": OrderImmediatelyFillable,
|
|
"Account has insufficient balance for requested action.": InsufficientFunds,
|
|
"Rest API trading is not enabled.": ExchangeNotAvailable,
|
|
"You don\\'t have permission.": PermissionDenied,
|
|
"Market is closed.": ExchangeNotAvailable,
|
|
"Too many requests. Please try again later.": DDoSProtection,
|
|
"-1000": ExchangeNotAvailable,
|
|
"-1001": ExchangeNotAvailable,
|
|
"-1002": AuthenticationError,
|
|
"-1003": RateLimitExceeded,
|
|
"-1013": InvalidOrder,
|
|
"-1015": RateLimitExceeded,
|
|
"-1016": ExchangeNotAvailable,
|
|
"-1020": BadRequest,
|
|
"-1021": InvalidNonce,
|
|
"-1022": AuthenticationError,
|
|
"-1100": BadRequest,
|
|
"-1101": BadRequest,
|
|
"-1102": BadRequest,
|
|
"-1103": BadRequest,
|
|
"-1104": BadRequest,
|
|
"-1105": BadRequest,
|
|
"-1106": BadRequest,
|
|
"-1111": BadRequest,
|
|
"-1112": InvalidOrder,
|
|
"-1114": BadRequest,
|
|
"-1115": BadRequest,
|
|
"-1116": BadRequest,
|
|
"-1117": BadRequest,
|
|
"-1166": InvalidOrder,
|
|
"-1118": BadRequest,
|
|
"-1119": BadRequest,
|
|
"-1120": BadRequest,
|
|
"-1121": BadSymbol,
|
|
"-1125": AuthenticationError,
|
|
"-1127": BadRequest,
|
|
"-1128": BadRequest,
|
|
"-1130": BadRequest,
|
|
"-1131": BadRequest,
|
|
"-1160": InvalidOrder,
|
|
"-1156": InvalidOrder,
|
|
"-2008": AuthenticationError,
|
|
"-2010": ExchangeError,
|
|
"-2011": OrderNotFound,
|
|
"-2013": OrderNotFound,
|
|
"-2014": AuthenticationError,
|
|
"-2015": AuthenticationError,
|
|
"-2017": InsufficientFunds,
|
|
"-2019": InsufficientFunds,
|
|
"-3005": InsufficientFunds,
|
|
"-3006": InsufficientFunds,
|
|
"-3008": InsufficientFunds,
|
|
"-3010": ExchangeError,
|
|
"-3015": ExchangeError,
|
|
"-3022": AccountSuspended,
|
|
"-4028": BadRequest,
|
|
"-3020": InsufficientFunds,
|
|
"-3041": InsufficientFunds,
|
|
"-5013": InsufficientFunds,
|
|
"-11008": InsufficientFunds,
|
|
"-4051": InsufficientFunds,
|
|
},
|
|
"broad": map[string]interface{} {
|
|
"Insufficient account balance": InsufficientFunds,
|
|
"has no operation privilege": PermissionDenied,
|
|
"MAX_POSITION": InvalidOrder,
|
|
},
|
|
},
|
|
})
|
|
}
|
|
func (this *bitrue) Nonce() interface{} {
|
|
return Subtract(this.Milliseconds(), GetValue(this.Options, "timeDifference"))
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchStatus
|
|
* @description the latest known information on the availability of the exchange API
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#test-connectivity
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
|
|
*/
|
|
func (this *bitrue) FetchStatus(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
response:= (<-this.SpotV1PublicGetPing(params))
|
|
PanicOnError(response)
|
|
//
|
|
// empty means working status.
|
|
//
|
|
// {}
|
|
//
|
|
var keys interface{} = ObjectKeys(response)
|
|
var keysLength interface{} = GetArrayLength(keys)
|
|
var formattedStatus interface{} = Ternary(IsTrue(keysLength), "maintenance", "ok")
|
|
|
|
ch <- map[string]interface{} {
|
|
"status": formattedStatus,
|
|
"updated": nil,
|
|
"eta": nil,
|
|
"url": nil,
|
|
"info": response,
|
|
}
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchTime
|
|
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#check-server-time
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
*/
|
|
func (this *bitrue) FetchTime(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
response:= (<-this.SpotV1PublicGetTime(params))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// {
|
|
// "serverTime":1635467280514
|
|
// }
|
|
//
|
|
ch <- this.SafeInteger(response, "serverTime")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchCurrencies
|
|
* @description fetches all available currencies on an exchange
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} an associative dictionary of currencies
|
|
*/
|
|
func (this *bitrue) FetchCurrencies(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
response:= (<-this.SpotV1PublicGetExchangeInfo(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "timezone":"CTT",
|
|
// "serverTime":1635464889117,
|
|
// "rateLimits":[
|
|
// {"rateLimitType":"REQUESTS_WEIGHT","interval":"MINUTES","limit":6000},
|
|
// {"rateLimitType":"ORDERS","interval":"SECONDS","limit":150},
|
|
// {"rateLimitType":"ORDERS","interval":"DAYS","limit":288000},
|
|
// ],
|
|
// "exchangeFilters":[],
|
|
// "symbols":[
|
|
// {
|
|
// "symbol":"SHABTC",
|
|
// "status":"TRADING",
|
|
// "baseAsset":"sha",
|
|
// "baseAssetPrecision":0,
|
|
// "quoteAsset":"btc",
|
|
// "quotePrecision":10,
|
|
// "orderTypes":["MARKET","LIMIT"],
|
|
// "icebergAllowed":false,
|
|
// "filters":[
|
|
// {"filterType":"PRICE_FILTER","minPrice":"0.00000001349","maxPrice":"0.00000017537","priceScale":10},
|
|
// {"filterType":"LOT_SIZE","minQty":"1.0","minVal":"0.00020","maxQty":"1000000000","volumeScale":0},
|
|
// ],
|
|
// "defaultPrice":"0.0000006100",
|
|
// },
|
|
// ],
|
|
// "coins":[
|
|
// {
|
|
// "coin": "near",
|
|
// "coinFulName": "NEAR Protocol",
|
|
// "chains": [ "BEP20", ],
|
|
// "chainDetail": [
|
|
// {
|
|
// "chain": "BEP20",
|
|
// "enableWithdraw": true,
|
|
// "enableDeposit": true,
|
|
// "withdrawFee": "0.2000",
|
|
// "minWithdraw": "5.0000",
|
|
// "maxWithdraw": "1000000000000000.0000",
|
|
// },
|
|
// ],
|
|
// },
|
|
// ],
|
|
// }
|
|
//
|
|
var result interface{} = map[string]interface{} {}
|
|
var coins interface{} = this.SafeList(response, "coins", []interface{}{})
|
|
for i := 0; IsLessThan(i, GetArrayLength(coins)); i++ {
|
|
var currency interface{} = GetValue(coins, i)
|
|
var id interface{} = this.SafeString(currency, "coin")
|
|
var name interface{} = this.SafeString(currency, "coinFulName")
|
|
var code interface{} = this.SafeCurrencyCode(id)
|
|
var deposit interface{} = nil
|
|
var withdraw interface{} = nil
|
|
var minWithdrawString interface{} = nil
|
|
var maxWithdrawString interface{} = nil
|
|
var minWithdrawFeeString interface{} = nil
|
|
var networkDetails interface{} = this.SafeList(currency, "chainDetail", []interface{}{})
|
|
var networks interface{} = map[string]interface{} {}
|
|
for j := 0; IsLessThan(j, GetArrayLength(networkDetails)); j++ {
|
|
var entry interface{} = GetValue(networkDetails, j)
|
|
var networkId interface{} = this.SafeString(entry, "chain")
|
|
var network interface{} = this.NetworkIdToCode(networkId, code)
|
|
var enableDeposit interface{} = this.SafeBool(entry, "enableDeposit")
|
|
deposit = Ternary(IsTrue((enableDeposit)), enableDeposit, deposit)
|
|
var enableWithdraw interface{} = this.SafeBool(entry, "enableWithdraw")
|
|
withdraw = Ternary(IsTrue((enableWithdraw)), enableWithdraw, withdraw)
|
|
var networkWithdrawFeeString interface{} = this.SafeString(entry, "withdrawFee")
|
|
if IsTrue(!IsEqual(networkWithdrawFeeString, nil)) {
|
|
minWithdrawFeeString = Ternary(IsTrue((IsEqual(minWithdrawFeeString, nil))), networkWithdrawFeeString, Precise.StringMin(networkWithdrawFeeString, minWithdrawFeeString))
|
|
}
|
|
var networkMinWithdrawString interface{} = this.SafeString(entry, "minWithdraw")
|
|
if IsTrue(!IsEqual(networkMinWithdrawString, nil)) {
|
|
minWithdrawString = Ternary(IsTrue((IsEqual(minWithdrawString, nil))), networkMinWithdrawString, Precise.StringMin(networkMinWithdrawString, minWithdrawString))
|
|
}
|
|
var networkMaxWithdrawString interface{} = this.SafeString(entry, "maxWithdraw")
|
|
if IsTrue(!IsEqual(networkMaxWithdrawString, nil)) {
|
|
maxWithdrawString = Ternary(IsTrue((IsEqual(maxWithdrawString, nil))), networkMaxWithdrawString, Precise.StringMax(networkMaxWithdrawString, maxWithdrawString))
|
|
}
|
|
AddElementToObject(networks, network, map[string]interface{} {
|
|
"info": entry,
|
|
"id": networkId,
|
|
"network": network,
|
|
"deposit": enableDeposit,
|
|
"withdraw": enableWithdraw,
|
|
"active": IsTrue(enableDeposit) && IsTrue(enableWithdraw),
|
|
"fee": this.ParseNumber(networkWithdrawFeeString),
|
|
"precision": nil,
|
|
"limits": map[string]interface{} {
|
|
"withdraw": map[string]interface{} {
|
|
"min": this.ParseNumber(networkMinWithdrawString),
|
|
"max": this.ParseNumber(networkMaxWithdrawString),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
AddElementToObject(result, code, map[string]interface{} {
|
|
"id": id,
|
|
"name": name,
|
|
"code": code,
|
|
"precision": nil,
|
|
"info": currency,
|
|
"active": IsTrue(deposit) && IsTrue(withdraw),
|
|
"deposit": deposit,
|
|
"withdraw": withdraw,
|
|
"networks": networks,
|
|
"fee": this.ParseNumber(minWithdrawFeeString),
|
|
"limits": map[string]interface{} {
|
|
"withdraw": map[string]interface{} {
|
|
"min": this.ParseNumber(minWithdrawString),
|
|
"max": this.ParseNumber(maxWithdrawString),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchMarkets
|
|
* @description retrieves data on all markets for bitrue
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#exchangeInfo_endpoint
|
|
* @see https://www.bitrue.com/api-docs#current-open-contract
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#current-open-contract
|
|
* @param {object} [params] extra parameters specific to the exchange api endpoint
|
|
* @returns {object[]} an array of objects representing market data
|
|
*/
|
|
func (this *bitrue) FetchMarkets(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
var promisesRaw interface{} = []interface{}{}
|
|
var fetchMarkets interface{} = this.SafeValue(this.Options, "fetchMarkets", []interface{}{"spot", "linear", "inverse"})
|
|
for i := 0; IsLessThan(i, GetArrayLength(fetchMarkets)); i++ {
|
|
var marketType interface{} = GetValue(fetchMarkets, i)
|
|
if IsTrue(IsEqual(marketType, "spot")) {
|
|
AppendToArray(&promisesRaw,this.SpotV1PublicGetExchangeInfo(params))
|
|
} else if IsTrue(IsEqual(marketType, "linear")) {
|
|
AppendToArray(&promisesRaw,this.FapiV1PublicGetContracts(params))
|
|
} else if IsTrue(IsEqual(marketType, "inverse")) {
|
|
AppendToArray(&promisesRaw,this.DapiV1PublicGetContracts(params))
|
|
} else {
|
|
panic(ExchangeError(Add(Add(Add(this.Id, " fetchMarkets() this.options fetchMarkets \""), marketType), "\" is not a supported market type")))
|
|
}
|
|
}
|
|
|
|
promises:= (<-promiseAll(promisesRaw))
|
|
PanicOnError(promises)
|
|
var spotMarkets interface{} = this.SafeValue(this.SafeValue(promises, 0), "symbols", []interface{}{})
|
|
var futureMarkets interface{} = this.SafeValue(promises, 1)
|
|
var deliveryMarkets interface{} = this.SafeValue(promises, 2)
|
|
var markets interface{} = spotMarkets
|
|
markets = this.ArrayConcat(markets, futureMarkets)
|
|
markets = this.ArrayConcat(markets, deliveryMarkets)
|
|
//
|
|
// spot
|
|
//
|
|
// {
|
|
// "timezone":"CTT",
|
|
// "serverTime":1635464889117,
|
|
// "rateLimits":[
|
|
// {"rateLimitType":"REQUESTS_WEIGHT","interval":"MINUTES","limit":6000},
|
|
// {"rateLimitType":"ORDERS","interval":"SECONDS","limit":150},
|
|
// {"rateLimitType":"ORDERS","interval":"DAYS","limit":288000},
|
|
// ],
|
|
// "exchangeFilters":[],
|
|
// "symbols":[
|
|
// {
|
|
// "symbol":"SHABTC",
|
|
// "status":"TRADING",
|
|
// "baseAsset":"sha",
|
|
// "baseAssetPrecision":0,
|
|
// "quoteAsset":"btc",
|
|
// "quotePrecision":10,
|
|
// "orderTypes":["MARKET","LIMIT"],
|
|
// "icebergAllowed":false,
|
|
// "filters":[
|
|
// {"filterType":"PRICE_FILTER","minPrice":"0.00000001349","maxPrice":"0.00000017537","priceScale":10},
|
|
// {"filterType":"LOT_SIZE","minQty":"1.0","minVal":"0.00020","maxQty":"1000000000","volumeScale":0},
|
|
// ],
|
|
// "defaultPrice":"0.0000006100",
|
|
// },
|
|
// ],
|
|
// "coins":[
|
|
// {
|
|
// "coin":"sbr",
|
|
// "coinFulName":"Saber",
|
|
// "enableWithdraw":true,
|
|
// "enableDeposit":true,
|
|
// "chains":["SOLANA"],
|
|
// "withdrawFee":"2.0",
|
|
// "minWithdraw":"5.0",
|
|
// "maxWithdraw":"1000000000000000",
|
|
// },
|
|
// ],
|
|
// }
|
|
//
|
|
// swap / delivery
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol": "H-HT-USDT",
|
|
// "pricePrecision": 8,
|
|
// "side": 1,
|
|
// "maxMarketVolume": 100000,
|
|
// "multiplier": 6,
|
|
// "minOrderVolume": 1,
|
|
// "maxMarketMoney": 10000000,
|
|
// "type": "H", // E: perpetual contract, S: test contract, others are mixed contract
|
|
// "maxLimitVolume": 1000000,
|
|
// "maxValidOrder": 20,
|
|
// "multiplierCoin": "HT",
|
|
// "minOrderMoney": 0.001,
|
|
// "maxLimitMoney": 1000000,
|
|
// "status": 1
|
|
// }
|
|
// ]
|
|
//
|
|
if IsTrue(GetValue(this.Options, "adjustForTimeDifference")) {
|
|
|
|
retRes88712 := (<-this.LoadTimeDifference())
|
|
PanicOnError(retRes88712)
|
|
}
|
|
|
|
ch <- this.ParseMarkets(markets)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitrue) ParseMarket(market interface{}) interface{} {
|
|
var id interface{} = this.SafeString(market, "symbol")
|
|
var lowercaseId interface{} = this.SafeStringLower(market, "symbol")
|
|
var side interface{} = this.SafeInteger(market, "side") // 1 linear, 0 inverse, undefined spot
|
|
var typeVar interface{} = nil
|
|
var isLinear interface{} = nil
|
|
var isInverse interface{} = nil
|
|
if IsTrue(IsEqual(side, nil)) {
|
|
typeVar = "spot"
|
|
} else {
|
|
typeVar = "swap"
|
|
isLinear = (IsEqual(side, 1))
|
|
isInverse = (IsEqual(side, 0))
|
|
}
|
|
var isContract interface{} = (!IsEqual(typeVar, "spot"))
|
|
var baseId interface{} = this.SafeString(market, "baseAsset")
|
|
var quoteId interface{} = this.SafeString(market, "quoteAsset")
|
|
var settleId interface{} = nil
|
|
var settle interface{} = nil
|
|
if IsTrue(isContract) {
|
|
var symbolSplit interface{} = Split(id, "-")
|
|
baseId = this.SafeString(symbolSplit, 1)
|
|
quoteId = this.SafeString(symbolSplit, 2)
|
|
if IsTrue(isLinear) {
|
|
settleId = quoteId
|
|
} else {
|
|
settleId = baseId
|
|
}
|
|
settle = this.SafeCurrencyCode(settleId)
|
|
}
|
|
var base interface{} = this.SafeCurrencyCode(baseId)
|
|
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
|
var symbol interface{} = Add(Add(base, "/"), quote)
|
|
if IsTrue(!IsEqual(settle, nil)) {
|
|
symbol = Add(symbol, Add(":", settle))
|
|
}
|
|
var filters interface{} = this.SafeList(market, "filters", []interface{}{})
|
|
var filtersByType interface{} = this.IndexBy(filters, "filterType")
|
|
var status interface{} = this.SafeString(market, "status")
|
|
var priceFilter interface{} = this.SafeDict(filtersByType, "PRICE_FILTER", map[string]interface{} {})
|
|
var amountFilter interface{} = this.SafeDict(filtersByType, "LOT_SIZE", map[string]interface{} {})
|
|
var defaultPricePrecision interface{} = this.SafeString(market, "pricePrecision")
|
|
var defaultAmountPrecision interface{} = this.SafeString(market, "quantityPrecision")
|
|
var pricePrecision interface{} = this.SafeString(priceFilter, "priceScale", defaultPricePrecision)
|
|
var amountPrecision interface{} = this.SafeString(amountFilter, "volumeScale", defaultAmountPrecision)
|
|
var multiplier interface{} = this.SafeString(market, "multiplier")
|
|
var maxQuantity interface{} = this.SafeNumber(amountFilter, "maxQty")
|
|
if IsTrue(IsEqual(maxQuantity, nil)) {
|
|
maxQuantity = this.SafeNumber(market, "maxValidOrder")
|
|
}
|
|
var minCost interface{} = this.SafeNumber(amountFilter, "minVal")
|
|
if IsTrue(IsEqual(minCost, nil)) {
|
|
minCost = this.SafeNumber(market, "minOrderMoney")
|
|
}
|
|
return map[string]interface{} {
|
|
"id": id,
|
|
"lowercaseId": lowercaseId,
|
|
"symbol": symbol,
|
|
"base": base,
|
|
"quote": quote,
|
|
"settle": settle,
|
|
"baseId": baseId,
|
|
"quoteId": quoteId,
|
|
"settleId": settleId,
|
|
"type": typeVar,
|
|
"spot": (IsEqual(typeVar, "spot")),
|
|
"margin": false,
|
|
"swap": isContract,
|
|
"future": false,
|
|
"option": false,
|
|
"active": (IsEqual(status, "TRADING")),
|
|
"contract": isContract,
|
|
"linear": isLinear,
|
|
"inverse": isInverse,
|
|
"contractSize": this.ParseNumber(Precise.StringAbs(multiplier)),
|
|
"expiry": nil,
|
|
"expiryDatetime": nil,
|
|
"strike": nil,
|
|
"optionType": nil,
|
|
"precision": map[string]interface{} {
|
|
"amount": this.ParseNumber(this.ParsePrecision(amountPrecision)),
|
|
"price": this.ParseNumber(this.ParsePrecision(pricePrecision)),
|
|
},
|
|
"limits": map[string]interface{} {
|
|
"leverage": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"amount": map[string]interface{} {
|
|
"min": this.SafeNumber(amountFilter, "minQty"),
|
|
"max": maxQuantity,
|
|
},
|
|
"price": map[string]interface{} {
|
|
"min": this.SafeNumber(priceFilter, "minPrice"),
|
|
"max": this.SafeNumber(priceFilter, "maxPrice"),
|
|
},
|
|
"cost": map[string]interface{} {
|
|
"min": minCost,
|
|
"max": nil,
|
|
},
|
|
},
|
|
"created": nil,
|
|
"info": market,
|
|
}
|
|
}
|
|
func (this *bitrue) ParseBalance(response interface{}) interface{} {
|
|
//
|
|
// spot
|
|
//
|
|
// {
|
|
// "makerCommission":0,
|
|
// "takerCommission":0,
|
|
// "buyerCommission":0,
|
|
// "sellerCommission":0,
|
|
// "updateTime":null,
|
|
// "balances":[
|
|
// {"asset":"sbr","free":"0","locked":"0"},
|
|
// {"asset":"ksm","free":"0","locked":"0"},
|
|
// {"asset":"neo3s","free":"0","locked":"0"},
|
|
// ],
|
|
// "canTrade":false,
|
|
// "canWithdraw":false,
|
|
// "canDeposit":false
|
|
// }
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// "account":[
|
|
// {
|
|
// "marginCoin":"USDT",
|
|
// "coinPrecious":4,
|
|
// "accountNormal":1010.4043400372839856,
|
|
// "accountLock":2.9827889600000006,
|
|
// "partPositionNormal":0,
|
|
// "totalPositionNormal":0,
|
|
// "achievedAmount":0,
|
|
// "unrealizedAmount":0,
|
|
// "totalMarginRate":0,
|
|
// "totalEquity":1010.4043400372839856,
|
|
// "partEquity":0,
|
|
// "totalCost":0,
|
|
// "sumMarginRate":0,
|
|
// "sumOpenRealizedAmount":0,
|
|
// "canUseTrialFund":0,
|
|
// "sumMaintenanceMargin":null,
|
|
// "futureModel":null,
|
|
// "positionVos":[]
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
var result interface{} = map[string]interface{} {
|
|
"info": response,
|
|
}
|
|
var timestamp interface{} = this.SafeInteger(response, "updateTime")
|
|
var balances interface{} = this.SafeValue2(response, "balances", "account", []interface{}{})
|
|
for i := 0; IsLessThan(i, GetArrayLength(balances)); i++ {
|
|
var balance interface{} = GetValue(balances, i)
|
|
var currencyId interface{} = this.SafeString2(balance, "asset", "marginCoin")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
|
var account interface{} = this.Account()
|
|
AddElementToObject(account, "free", this.SafeString2(balance, "free", "accountNormal"))
|
|
AddElementToObject(account, "used", this.SafeString2(balance, "locked", "accountLock"))
|
|
AddElementToObject(result, code, account)
|
|
}
|
|
AddElementToObject(result, "timestamp", timestamp)
|
|
AddElementToObject(result, "datetime", this.Iso8601(timestamp))
|
|
return this.SafeBalance(result)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchBalance
|
|
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#account-information-user_data
|
|
* @see https://www.bitrue.com/api-docs#account-information-v2-user_data-hmac-sha256
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#account-information-v2-user_data-hmac-sha256
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.type] 'future', 'delivery', 'spot', 'swap'
|
|
* @param {string} [params.subType] 'linear', 'inverse'
|
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
*/
|
|
func (this *bitrue) FetchBalance(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes10778 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes10778)
|
|
var typeVar interface{} = nil
|
|
typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchBalance", nil, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
var subType interface{} = nil
|
|
subTypeparamsVariable := this.HandleSubTypeAndParams("fetchBalance", nil, params);
|
|
subType = GetValue(subTypeparamsVariable,0);
|
|
params = GetValue(subTypeparamsVariable,1)
|
|
var response interface{} = nil
|
|
var result interface{} = nil
|
|
if IsTrue(IsEqual(typeVar, "swap")) {
|
|
if IsTrue(IsTrue(!IsEqual(subType, nil)) && IsTrue(IsEqual(subType, "inverse"))) {
|
|
|
|
response = (<-this.DapiV2PrivateGetAccount(params))
|
|
PanicOnError(response)
|
|
result = this.SafeDict(response, "data", map[string]interface{} {})
|
|
} else {
|
|
|
|
response = (<-this.FapiV2PrivateGetAccount(params))
|
|
PanicOnError(response)
|
|
result = this.SafeDict(response, "data", map[string]interface{} {})
|
|
}
|
|
} else {
|
|
|
|
response = (<-this.SpotV1PrivateGetAccount(params))
|
|
PanicOnError(response)
|
|
result = response
|
|
}
|
|
|
|
ch <- this.ParseBalance(result)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchOrderBook
|
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#order-book
|
|
* @see https://www.bitrue.com/api-docs#order-book
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#order-book
|
|
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
* @param {int} [limit] the maximum amount of order book entries to return
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
*/
|
|
func (this *bitrue) FetchOrderBook(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
limit := GetArg(optionalArgs, 0, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes11898 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes11898)
|
|
var market interface{} = this.Market(symbol)
|
|
var response interface{} = nil
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
var request interface{} = map[string]interface{} {
|
|
"contractName": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
if IsTrue(IsGreaterThan(limit, 100)) {
|
|
limit = 100
|
|
}
|
|
AddElementToObject(request, "limit", limit) // default 100, max 100, see https://www.bitrue.com/api-docs#order-book
|
|
}
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV1PublicGetDepth(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV1PublicGetDepth(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
} else if IsTrue(GetValue(market, "spot")) {
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
if IsTrue(IsGreaterThan(limit, 1000)) {
|
|
limit = 1000
|
|
}
|
|
AddElementToObject(request, "limit", limit) // default 100, max 1000, see https://github.com/Bitrue-exchange/bitrue-official-api-docs#order-book
|
|
}
|
|
|
|
response = (<-this.SpotV1PublicGetDepth(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " fetchOrderBook only support spot & swap markets")))
|
|
}
|
|
//
|
|
// spot
|
|
//
|
|
// {
|
|
// "lastUpdateId":1635474910177,
|
|
// "bids":[
|
|
// ["61436.84","0.05",[]],
|
|
// ["61435.77","0.0124",[]],
|
|
// ["61434.88","0.012",[]],
|
|
// ],
|
|
// "asks":[
|
|
// ["61452.46","0.0001",[]],
|
|
// ["61452.47","0.0597",[]],
|
|
// ["61452.76","0.0713",[]],
|
|
// ]
|
|
// }
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// "asks": [[34916.5, 2582], [34916.6, 2193], [34916.7, 2629], [34916.8, 3478], [34916.9, 2718]],
|
|
// "bids": [[34916.4, 92065], [34916.3, 25703], [34916.2, 37259], [34916.1, 26446], [34916, 44456]],
|
|
// "time": 1699338305000
|
|
// }
|
|
//
|
|
var timestamp interface{} = this.SafeInteger(response, "time")
|
|
var orderbook interface{} = this.ParseOrderBook(response, symbol, timestamp)
|
|
AddElementToObject(orderbook, "nonce", this.SafeInteger(response, "lastUpdateId"))
|
|
|
|
ch <- orderbook
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitrue) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchBidsAsks
|
|
//
|
|
// {
|
|
// "symbol": "LTCBTC",
|
|
// "bidPrice": "4.00000000",
|
|
// "bidQty": "431.00000000",
|
|
// "askPrice": "4.00000200",
|
|
// "askQty": "9.00000000"
|
|
// }
|
|
//
|
|
// fetchTicker
|
|
//
|
|
// {
|
|
// "symbol": "BNBBTC",
|
|
// "priceChange": "0.000248",
|
|
// "priceChangePercent": "3.5500",
|
|
// "weightedAvgPrice": null,
|
|
// "prevClosePrice": null,
|
|
// "lastPrice": "0.007226",
|
|
// "lastQty": null,
|
|
// "bidPrice": "0.007208",
|
|
// "askPrice": "0.007240",
|
|
// "openPrice": "0.006978",
|
|
// "highPrice": "0.007295",
|
|
// "lowPrice": "0.006935",
|
|
// "volume": "11749.86",
|
|
// "quoteVolume": "84.1066211",
|
|
// "openTime": 0,
|
|
// "closeTime": 0,
|
|
// "firstId": 0,
|
|
// "lastId": 0,
|
|
// "count": 0
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var symbol interface{} = this.SafeSymbol(nil, market)
|
|
var last interface{} = this.SafeString2(ticker, "lastPrice", "last")
|
|
var timestamp interface{} = this.SafeInteger(ticker, "time")
|
|
var percentage interface{} = nil
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
percentage = Precise.StringMul(this.SafeString(ticker, "rose"), "100")
|
|
} else {
|
|
percentage = this.SafeString(ticker, "priceChangePercent")
|
|
}
|
|
return this.SafeTicker(map[string]interface{} {
|
|
"symbol": symbol,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"high": this.SafeString2(ticker, "highPrice", "high"),
|
|
"low": this.SafeString2(ticker, "lowPrice", "low"),
|
|
"bid": this.SafeString2(ticker, "bidPrice", "buy"),
|
|
"bidVolume": this.SafeString(ticker, "bidQty"),
|
|
"ask": this.SafeString2(ticker, "askPrice", "sell"),
|
|
"askVolume": this.SafeString(ticker, "askQty"),
|
|
"vwap": this.SafeString(ticker, "weightedAvgPrice"),
|
|
"open": this.SafeString(ticker, "openPrice"),
|
|
"close": last,
|
|
"last": last,
|
|
"previousClose": nil,
|
|
"change": this.SafeString(ticker, "priceChange"),
|
|
"percentage": percentage,
|
|
"average": nil,
|
|
"baseVolume": this.SafeString2(ticker, "volume", "vol"),
|
|
"quoteVolume": this.SafeString(ticker, "quoteVolume"),
|
|
"info": ticker,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchTicker
|
|
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#24hr-ticker-price-change-statistics
|
|
* @see https://www.bitrue.com/api-docs#ticker
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#ticker
|
|
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
*/
|
|
func (this *bitrue) FetchTicker(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes13338 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes13338)
|
|
var market interface{} = this.Market(symbol)
|
|
var response interface{} = nil
|
|
var data interface{} = nil
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
var request interface{} = map[string]interface{} {
|
|
"contractName": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV1PublicGetTicker(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV1PublicGetTicker(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
data = response
|
|
} else if IsTrue(GetValue(market, "spot")) {
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
|
|
response = (<-this.SpotV1PublicGetTicker24hr(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
data = this.SafeDict(response, 0, map[string]interface{} {})
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " fetchTicker only support spot & swap markets")))
|
|
}
|
|
|
|
//
|
|
// spot
|
|
//
|
|
// [{
|
|
// symbol: 'BTCUSDT',
|
|
// priceChange: '105.20',
|
|
// priceChangePercent: '0.3000',
|
|
// weightedAvgPrice: null,
|
|
// prevClosePrice: null,
|
|
// lastPrice: '34905.21',
|
|
// lastQty: null,
|
|
// bidPrice: '34905.21',
|
|
// askPrice: '34905.22',
|
|
// openPrice: '34800.01',
|
|
// highPrice: '35276.33',
|
|
// lowPrice: '34787.51',
|
|
// volume: '12549.6481',
|
|
// quoteVolume: '439390492.917',
|
|
// openTime: '0',
|
|
// closeTime: '0',
|
|
// firstId: '0',
|
|
// lastId: '0',
|
|
// count: '0'
|
|
// }]
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// "high": "35296",
|
|
// "vol": "779308354",
|
|
// "last": "34884.1",
|
|
// "low": "34806.7",
|
|
// "buy": 34883.9,
|
|
// "sell": 34884,
|
|
// "rose": "-0.0027957315",
|
|
// "time": 1699348013000
|
|
// }
|
|
//
|
|
ch <- this.ParseTicker(data, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchOHLCV
|
|
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
* @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#kline-data
|
|
* @see https://www.bitrue.com/api_docs_includes_file/futures/index.html#kline-candlestick-data
|
|
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
* @param {string} timeframe the length of time each candle represents
|
|
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
* @param {int} [limit] the maximum amount of candles to fetch
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
*/
|
|
func (this *bitrue) FetchOHLCV(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
timeframe := GetArg(optionalArgs, 0, "1m")
|
|
_ = timeframe
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes14118 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes14118)
|
|
var market interface{} = this.Market(symbol)
|
|
var timeframes interface{} = this.SafeDict(this.Options, "timeframes", map[string]interface{} {})
|
|
var response interface{} = nil
|
|
var data interface{} = nil
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
var timeframesFuture interface{} = this.SafeDict(timeframes, "future", map[string]interface{} {})
|
|
var request interface{} = map[string]interface{} {
|
|
"contractName": GetValue(market, "id"),
|
|
"interval": this.SafeString(timeframesFuture, timeframe, "1min"),
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV1PublicGetKlines(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV1PublicGetKlines(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
data = response
|
|
} else if IsTrue(GetValue(market, "spot")) {
|
|
var timeframesSpot interface{} = this.SafeDict(timeframes, "spot", map[string]interface{} {})
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
"scale": this.SafeString(timeframesSpot, timeframe, "1m"),
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "fromIdx", since)
|
|
}
|
|
|
|
response = (<-this.SpotV1PublicGetMarketKline(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
data = this.SafeList(response, "data", []interface{}{})
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " fetchOHLCV only support spot & swap markets")))
|
|
}
|
|
|
|
//
|
|
// spot
|
|
//
|
|
// {
|
|
// "symbol":"BTCUSDT",
|
|
// "scale":"KLINE_1MIN",
|
|
// "data":[
|
|
// {
|
|
// "i":"1660825020",
|
|
// "a":"93458.778",
|
|
// "v":"3.9774",
|
|
// "c":"23494.99",
|
|
// "h":"23509.63",
|
|
// "l":"23491.93",
|
|
// "o":"23508.34"
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
// swap
|
|
//
|
|
// [
|
|
// {
|
|
// "high": "35360.7",
|
|
// "vol": "110288",
|
|
// "low": "35347.9",
|
|
// "idx": 1699411680000,
|
|
// "close": "35347.9",
|
|
// "open": "35349.4"
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseOHLCVs(data, market, timeframe, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitrue) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// spot
|
|
//
|
|
// {
|
|
// "i":"1660825020",
|
|
// "a":"93458.778",
|
|
// "v":"3.9774",
|
|
// "c":"23494.99",
|
|
// "h":"23509.63",
|
|
// "l":"23491.93",
|
|
// "o":"23508.34"
|
|
// }
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// "high": "35360.7",
|
|
// "vol": "110288",
|
|
// "low": "35347.9",
|
|
// "idx": 1699411680000,
|
|
// "close": "35347.9",
|
|
// "open": "35349.4"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var timestamp interface{} = this.SafeTimestamp(ohlcv, "i")
|
|
if IsTrue(IsEqual(timestamp, nil)) {
|
|
timestamp = this.SafeInteger(ohlcv, "idx")
|
|
}
|
|
return []interface{}{timestamp, this.SafeNumber2(ohlcv, "o", "open"), this.SafeNumber2(ohlcv, "h", "high"), this.SafeNumber2(ohlcv, "l", "low"), this.SafeNumber2(ohlcv, "c", "close"), this.SafeNumber2(ohlcv, "v", "vol")}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchBidsAsks
|
|
* @description fetches the bid and ask price and volume for multiple markets
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#symbol-order-book-ticker
|
|
* @see https://www.bitrue.com/api-docs#ticker
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#ticker
|
|
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
*/
|
|
func (this *bitrue) FetchBidsAsks(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbols := GetArg(optionalArgs, 0, nil)
|
|
_ = symbols
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes15368 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes15368)
|
|
symbols = this.MarketSymbols(symbols, nil, false)
|
|
var first interface{} = this.SafeString(symbols, 0)
|
|
var market interface{} = this.Market(first)
|
|
var response interface{} = nil
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
var request interface{} = map[string]interface{} {
|
|
"contractName": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV1PublicGetTicker(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV1PublicGetTicker(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
} else if IsTrue(GetValue(market, "spot")) {
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
|
|
response = (<-this.SpotV1PublicGetTickerBookTicker(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " fetchBidsAsks only support spot & swap markets")))
|
|
}
|
|
//
|
|
// spot
|
|
//
|
|
// {
|
|
// "symbol": "LTCBTC",
|
|
// "bidPrice": "4.00000000",
|
|
// "bidQty": "431.00000000",
|
|
// "askPrice": "4.00000200",
|
|
// "askQty": "9.00000000"
|
|
// }
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// "high": "35296",
|
|
// "vol": "779308354",
|
|
// "last": "34884.1",
|
|
// "low": "34806.7",
|
|
// "buy": 34883.9,
|
|
// "sell": 34884,
|
|
// "rose": "-0.0027957315",
|
|
// "time": 1699348013000
|
|
// }
|
|
//
|
|
var data interface{} = map[string]interface{} {}
|
|
AddElementToObject(data, GetValue(market, "id"), response)
|
|
|
|
ch <- this.ParseTickers(data, symbols)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchTickers
|
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#24hr-ticker-price-change-statistics
|
|
* @see https://www.bitrue.com/api-docs#ticker
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#ticker
|
|
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
*/
|
|
func (this *bitrue) FetchTickers(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbols := GetArg(optionalArgs, 0, nil)
|
|
_ = symbols
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes15998 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes15998)
|
|
symbols = this.MarketSymbols(symbols)
|
|
var response interface{} = nil
|
|
var data interface{} = nil
|
|
var request interface{} = map[string]interface{} {}
|
|
var typeVar interface{} = nil
|
|
if IsTrue(!IsEqual(symbols, nil)) {
|
|
var first interface{} = this.SafeString(symbols, 0)
|
|
var market interface{} = this.Market(first)
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
panic(NotSupported(Add(this.Id, " fetchTickers does not support swap markets, please use fetchTicker instead")))
|
|
} else if IsTrue(GetValue(market, "spot")) {
|
|
|
|
response = (<-this.SpotV1PublicGetTicker24hr(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
data = response
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " fetchTickers only support spot & swap markets")))
|
|
}
|
|
} else {
|
|
typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchTickers", nil, params);
|
|
typeVar = GetValue(typeVarparamsVariable,0);
|
|
params = GetValue(typeVarparamsVariable,1)
|
|
if IsTrue(!IsEqual(typeVar, "spot")) {
|
|
panic(NotSupported(Add(this.Id, " fetchTickers only support spot when symbols are not proved")))
|
|
}
|
|
|
|
response = (<-this.SpotV1PublicGetTicker24hr(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
data = response
|
|
}
|
|
//
|
|
// spot
|
|
//
|
|
// [{
|
|
// symbol: 'BTCUSDT',
|
|
// priceChange: '105.20',
|
|
// priceChangePercent: '0.3000',
|
|
// weightedAvgPrice: null,
|
|
// prevClosePrice: null,
|
|
// lastPrice: '34905.21',
|
|
// lastQty: null,
|
|
// bidPrice: '34905.21',
|
|
// askPrice: '34905.22',
|
|
// openPrice: '34800.01',
|
|
// highPrice: '35276.33',
|
|
// lowPrice: '34787.51',
|
|
// volume: '12549.6481',
|
|
// quoteVolume: '439390492.917',
|
|
// openTime: '0',
|
|
// closeTime: '0',
|
|
// firstId: '0',
|
|
// lastId: '0',
|
|
// count: '0'
|
|
// }]
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// "high": "35296",
|
|
// "vol": "779308354",
|
|
// "last": "34884.1",
|
|
// "low": "34806.7",
|
|
// "buy": 34883.9,
|
|
// "sell": 34884,
|
|
// "rose": "-0.0027957315",
|
|
// "time": 1699348013000
|
|
// }
|
|
//
|
|
// the exchange returns market ids with an underscore from the tickers endpoint
|
|
// the market ids do not have an underscore, so it has to be removed
|
|
// https://github.com/ccxt/ccxt/issues/13856
|
|
var tickers interface{} = map[string]interface{} {}
|
|
for i := 0; IsLessThan(i, GetArrayLength(data)); i++ {
|
|
var ticker interface{} = this.SafeDict(data, i, map[string]interface{} {})
|
|
var market interface{} = this.Market(this.SafeValue(ticker, "symbol"))
|
|
AddElementToObject(tickers, GetValue(market, "id"), ticker)
|
|
}
|
|
|
|
ch <- this.ParseTickers(tickers, symbols)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitrue) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchTrades
|
|
//
|
|
// {
|
|
// "id": 28457,
|
|
// "price": "4.00000100",
|
|
// "qty": "12.00000000",
|
|
// "time": 1499865549590, // Actual timestamp of trade
|
|
// "isBuyerMaker": true,
|
|
// "isBestMatch": true
|
|
// }
|
|
//
|
|
// fetchTrades - spot
|
|
//
|
|
// {
|
|
// "symbol":"USDCUSDT",
|
|
// "id":20725156,
|
|
// "orderId":2880918576,
|
|
// "origClientOrderId":null,
|
|
// "price":"0.9996000000000000",
|
|
// "qty":"100.0000000000000000",
|
|
// "commission":null,
|
|
// "commissionAssert":null,
|
|
// "time":1635558511000,
|
|
// "isBuyer":false,
|
|
// "isMaker":false,
|
|
// "isBestMatch":true
|
|
// }
|
|
//
|
|
// fetchTrades - future
|
|
//
|
|
// {
|
|
// "tradeId":12,
|
|
// "price":0.9,
|
|
// "qty":1,
|
|
// "amount":9,
|
|
// "contractName":"E-SAND-USDT",
|
|
// "side":"BUY",
|
|
// "fee":"0.0018",
|
|
// "bidId":1558124009467904992,
|
|
// "askId":1558124043827644908,
|
|
// "bidUserId":10294,
|
|
// "askUserId":10467,
|
|
// "isBuyer":true,
|
|
// "isMaker":true,
|
|
// "ctime":1678426306000
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var timestamp interface{} = this.SafeInteger2(trade, "ctime", "time")
|
|
var priceString interface{} = this.SafeString(trade, "price")
|
|
var amountString interface{} = this.SafeString(trade, "qty")
|
|
var marketId interface{} = this.SafeString2(trade, "symbol", "contractName")
|
|
var symbol interface{} = this.SafeSymbol(marketId, market)
|
|
var orderId interface{} = this.SafeString(trade, "orderId")
|
|
var id interface{} = this.SafeString2(trade, "id", "tradeId")
|
|
var side interface{} = nil
|
|
var buyerMaker interface{} = this.SafeBool(trade, "isBuyerMaker") // ignore "m" until Bitrue fixes api
|
|
var isBuyer interface{} = this.SafeBool(trade, "isBuyer")
|
|
if IsTrue(!IsEqual(buyerMaker, nil)) {
|
|
side = Ternary(IsTrue(buyerMaker), "sell", "buy")
|
|
}
|
|
if IsTrue(!IsEqual(isBuyer, nil)) {
|
|
side = Ternary(IsTrue(isBuyer), "buy", "sell") // this is a true side
|
|
}
|
|
var fee interface{} = nil
|
|
if IsTrue(InOp(trade, "commission")) {
|
|
fee = map[string]interface{} {
|
|
"cost": this.SafeString2(trade, "commission", "fee"),
|
|
"currency": this.SafeCurrencyCode(this.SafeString(trade, "commissionAssert")),
|
|
}
|
|
}
|
|
var takerOrMaker interface{} = nil
|
|
var isMaker interface{} = this.SafeBool(trade, "isMaker")
|
|
if IsTrue(!IsEqual(isMaker, nil)) {
|
|
takerOrMaker = Ternary(IsTrue(isMaker), "maker", "taker")
|
|
}
|
|
return this.SafeTrade(map[string]interface{} {
|
|
"info": trade,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"symbol": symbol,
|
|
"id": id,
|
|
"order": orderId,
|
|
"type": nil,
|
|
"side": side,
|
|
"takerOrMaker": takerOrMaker,
|
|
"price": priceString,
|
|
"amount": amountString,
|
|
"cost": nil,
|
|
"fee": fee,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchTrades
|
|
* @description get the list of most recent trades for a particular symbol
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#recent-trades-list
|
|
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
* @param {int} [limit] the maximum amount of trades to fetch
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
*/
|
|
func (this *bitrue) FetchTrades(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
since := GetArg(optionalArgs, 0, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 1, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes17808 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes17808)
|
|
var market interface{} = this.Market(symbol)
|
|
var response interface{} = nil
|
|
if IsTrue(GetValue(market, "spot")) {
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit) // default 100, max 1000
|
|
}
|
|
|
|
response = (<-this.SpotV1PublicGetTrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " fetchTrades only support spot markets")))
|
|
}
|
|
|
|
//
|
|
// spot
|
|
//
|
|
// [
|
|
// {
|
|
// "id": 28457,
|
|
// "price": "4.00000100",
|
|
// "qty": "12.00000000",
|
|
// "time": 1499865549590,
|
|
// "isBuyerMaker": true,
|
|
// "isBestMatch": true
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseTrades(response, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitrue) ParseOrderStatus(status interface{}) interface{} {
|
|
var statuses interface{} = map[string]interface{} {
|
|
"INIT": "open",
|
|
"PENDING_CREATE": "open",
|
|
"NEW": "open",
|
|
"PARTIALLY_FILLED": "open",
|
|
"FILLED": "closed",
|
|
"CANCELED": "canceled",
|
|
"PENDING_CANCEL": "canceling",
|
|
"REJECTED": "rejected",
|
|
"EXPIRED": "expired",
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *bitrue) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// createOrder - spot
|
|
//
|
|
// {
|
|
// "symbol":"USDCUSDT",
|
|
// "orderId":2878854881,
|
|
// "clientOrderId":"",
|
|
// "transactTime":1635551031276
|
|
// }
|
|
//
|
|
// createOrder - future
|
|
//
|
|
// {
|
|
// "orderId":1690615676032452985,
|
|
// }
|
|
//
|
|
// fetchOrders - spot
|
|
//
|
|
// {
|
|
// "symbol":"USDCUSDT",
|
|
// "orderId":"2878854881",
|
|
// "clientOrderId":"",
|
|
// "price":"1.1000000000000000",
|
|
// "origQty":"100.0000000000000000",
|
|
// "executedQty":"0.0000000000000000",
|
|
// "cummulativeQuoteQty":"0.0000000000000000",
|
|
// "status":"NEW",
|
|
// "timeInForce":"",
|
|
// "type":"LIMIT",
|
|
// "side":"SELL",
|
|
// "stopPrice":"",
|
|
// "icebergQty":"",
|
|
// "time":1635551031000,
|
|
// "updateTime":1635551031000,
|
|
// "isWorking":false
|
|
// }
|
|
//
|
|
// fetchOrders - future
|
|
//
|
|
// {
|
|
// "orderId":1917641,
|
|
// "price":100,
|
|
// "origQty":10,
|
|
// "origAmount":10,
|
|
// "executedQty":1,
|
|
// "avgPrice":10000,
|
|
// "status":"INIT",
|
|
// "type":"LIMIT",
|
|
// "side":"BUY",
|
|
// "action":"OPEN",
|
|
// "transactTime":1686716571425
|
|
// "clientOrderId":4949299210
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var status interface{} = this.ParseOrderStatus(this.SafeString2(order, "status", "orderStatus"))
|
|
var marketId interface{} = this.SafeString(order, "symbol")
|
|
var symbol interface{} = this.SafeSymbol(marketId, market)
|
|
var filled interface{} = this.SafeString(order, "executedQty")
|
|
var timestamp interface{} = nil
|
|
var lastTradeTimestamp interface{} = nil
|
|
if IsTrue(InOp(order, "time")) {
|
|
timestamp = this.SafeInteger(order, "time")
|
|
} else if IsTrue(InOp(order, "transactTime")) {
|
|
timestamp = this.SafeInteger(order, "transactTime")
|
|
} else if IsTrue(InOp(order, "updateTime")) {
|
|
if IsTrue(IsEqual(status, "open")) {
|
|
if IsTrue(Precise.StringGt(filled, "0")) {
|
|
lastTradeTimestamp = this.SafeInteger(order, "updateTime")
|
|
} else {
|
|
timestamp = this.SafeInteger(order, "updateTime")
|
|
}
|
|
}
|
|
}
|
|
var average interface{} = this.SafeString(order, "avgPrice")
|
|
var price interface{} = this.SafeString(order, "price")
|
|
var amount interface{} = this.SafeString(order, "origQty")
|
|
// - Spot/Margin market: cummulativeQuoteQty
|
|
// - Futures market: cumQuote.
|
|
// Note this is not the actual cost, since Binance futures uses leverage to calculate margins.
|
|
var cost interface{} = this.SafeString2(order, "cummulativeQuoteQty", "cumQuote")
|
|
var id interface{} = this.SafeString(order, "orderId")
|
|
var typeVar interface{} = this.SafeStringLower(order, "type")
|
|
var side interface{} = this.SafeStringLower(order, "side")
|
|
var fills interface{} = this.SafeList(order, "fills", []interface{}{})
|
|
var clientOrderId interface{} = this.SafeString(order, "clientOrderId")
|
|
var timeInForce interface{} = this.SafeString(order, "timeInForce")
|
|
var postOnly interface{} = IsTrue(IsTrue((IsEqual(typeVar, "limit_maker"))) || IsTrue((IsEqual(timeInForce, "GTX")))) || IsTrue((IsEqual(typeVar, "post_only")))
|
|
if IsTrue(IsEqual(typeVar, "limit_maker")) {
|
|
typeVar = "limit"
|
|
}
|
|
var triggerPrice interface{} = this.ParseNumber(this.OmitZero(this.SafeString(order, "stopPrice")))
|
|
return this.SafeOrder(map[string]interface{} {
|
|
"info": order,
|
|
"id": id,
|
|
"clientOrderId": clientOrderId,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"lastTradeTimestamp": lastTradeTimestamp,
|
|
"symbol": symbol,
|
|
"type": typeVar,
|
|
"timeInForce": timeInForce,
|
|
"postOnly": postOnly,
|
|
"side": side,
|
|
"price": price,
|
|
"triggerPrice": triggerPrice,
|
|
"amount": amount,
|
|
"cost": cost,
|
|
"average": average,
|
|
"filled": filled,
|
|
"remaining": nil,
|
|
"status": status,
|
|
"fee": nil,
|
|
"trades": fills,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#createMarketBuyOrderWithCost
|
|
* @description create a market buy order by providing the symbol and cost
|
|
* @see https://www.bitrue.com/api-docs#new-order-trade-hmac-sha256
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#new-order-trade-hmac-sha256
|
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
* @param {float} cost how much you want to trade in units of the quote currency
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitrue) CreateMarketBuyOrderWithCost(symbol interface{}, cost interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes19568 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes19568)
|
|
var market interface{} = this.Market(symbol)
|
|
if !IsTrue(GetValue(market, "swap")) {
|
|
panic(NotSupported(Add(this.Id, " createMarketBuyOrderWithCost() supports swap orders only")))
|
|
}
|
|
AddElementToObject(params, "createMarketBuyOrderRequiresPrice", false)
|
|
|
|
retRes196215 := (<-this.CreateOrder(symbol, "market", "buy", cost, nil, params))
|
|
PanicOnError(retRes196215)
|
|
ch <- retRes196215
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#createOrder
|
|
* @description create a trade order
|
|
* @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#new-order-trade
|
|
* @see https://www.bitrue.com/api_docs_includes_file/futures/index.html#new-order-trade-hmac-sha256
|
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
* @param {string} type 'market' or 'limit'
|
|
* @param {string} side 'buy' or 'sell'
|
|
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
* @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {float} [params.triggerPrice] *spot only* the price at which a trigger order is triggered at
|
|
* @param {string} [params.clientOrderId] a unique id for the order, automatically generated if not sent
|
|
* @param {decimal} [params.leverage] in future order, the leverage value of the order should consistent with the user contract configuration, default is 1
|
|
* @param {string} [params.timeInForce] 'fok', 'ioc' or 'po'
|
|
* @param {bool} [params.postOnly] default false
|
|
* @param {bool} [params.reduceOnly] default false
|
|
* EXCHANGE SPECIFIC PARAMETERS
|
|
* @param {decimal} [params.icebergQty]
|
|
* @param {long} [params.recvWindow]
|
|
* @param {float} [params.cost] *swap market buy only* the quote quantity that can be used as an alternative for the amount
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitrue) CreateOrder(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
price := GetArg(optionalArgs, 0, nil)
|
|
_ = price
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes19908 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes19908)
|
|
var market interface{} = this.Market(symbol)
|
|
var response interface{} = nil
|
|
var data interface{} = nil
|
|
var uppercaseType interface{} = ToUpper(typeVar)
|
|
var request interface{} = map[string]interface{} {
|
|
"side": ToUpper(side),
|
|
"type": uppercaseType,
|
|
}
|
|
if IsTrue(IsEqual(uppercaseType, "LIMIT")) {
|
|
if IsTrue(IsEqual(price, nil)) {
|
|
panic(InvalidOrder(Add(this.Id, " createOrder() requires a price argument")))
|
|
}
|
|
AddElementToObject(request, "price", this.PriceToPrecision(symbol, price))
|
|
}
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
var isMarket interface{} = IsEqual(uppercaseType, "MARKET")
|
|
var timeInForce interface{} = this.SafeStringLower(params, "timeInForce")
|
|
var postOnly interface{} = this.IsPostOnly(isMarket, nil, params)
|
|
if IsTrue(postOnly) {
|
|
AddElementToObject(request, "type", "POST_ONLY")
|
|
} else if IsTrue(IsEqual(timeInForce, "fok")) {
|
|
AddElementToObject(request, "type", "FOK")
|
|
} else if IsTrue(IsEqual(timeInForce, "ioc")) {
|
|
AddElementToObject(request, "type", "IOC")
|
|
}
|
|
AddElementToObject(request, "contractName", GetValue(market, "id"))
|
|
var createMarketBuyOrderRequiresPrice interface{} = true
|
|
createMarketBuyOrderRequiresPriceparamsVariable := this.HandleOptionAndParams(params, "createOrder", "createMarketBuyOrderRequiresPrice", true);
|
|
createMarketBuyOrderRequiresPrice = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,0);
|
|
params = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,1)
|
|
if IsTrue(IsTrue(IsTrue(isMarket) && IsTrue((IsEqual(side, "buy")))) && IsTrue(createMarketBuyOrderRequiresPrice)) {
|
|
var cost interface{} = this.SafeString(params, "cost")
|
|
params = this.Omit(params, "cost")
|
|
if IsTrue(IsTrue(IsEqual(price, nil)) && IsTrue(IsEqual(cost, nil))) {
|
|
panic(InvalidOrder(Add(this.Id, " createOrder() requires the price argument with swap market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options[\"createMarketBuyOrderRequiresPrice\"] = false to supply the cost in the amount argument (the exchange-specific behaviour)")))
|
|
} else {
|
|
var amountString interface{} = this.NumberToString(amount)
|
|
var priceString interface{} = this.NumberToString(price)
|
|
var quoteAmount interface{} = Precise.StringMul(amountString, priceString)
|
|
var requestAmount interface{} = Ternary(IsTrue((!IsEqual(cost, nil))), cost, quoteAmount)
|
|
AddElementToObject(request, "amount", this.CostToPrecision(symbol, requestAmount))
|
|
AddElementToObject(request, "volume", this.CostToPrecision(symbol, requestAmount))
|
|
}
|
|
} else {
|
|
AddElementToObject(request, "amount", this.ParseToNumeric(amount))
|
|
AddElementToObject(request, "volume", this.ParseToNumeric(amount))
|
|
}
|
|
AddElementToObject(request, "positionType", 1)
|
|
var reduceOnly interface{} = this.SafeValue2(params, "reduceOnly", "reduce_only")
|
|
AddElementToObject(request, "open", Ternary(IsTrue(reduceOnly), "CLOSE", "OPEN"))
|
|
var leverage interface{} = this.SafeString(params, "leverage", "1")
|
|
AddElementToObject(request, "leverage", this.ParseToNumeric(leverage))
|
|
params = this.Omit(params, []interface{}{"leverage", "reduceOnly", "reduce_only", "timeInForce"})
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV2PrivatePostOrder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV2PrivatePostOrder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
data = this.SafeDict(response, "data", map[string]interface{} {})
|
|
} else if IsTrue(GetValue(market, "spot")) {
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
AddElementToObject(request, "quantity", this.AmountToPrecision(symbol, amount))
|
|
var validOrderTypes interface{} = this.SafeValue(GetValue(market, "info"), "orderTypes")
|
|
if !IsTrue(this.InArray(uppercaseType, validOrderTypes)) {
|
|
panic(InvalidOrder(Add(Add(Add(Add(this.Id, " "), typeVar), " is not a valid order type in market "), symbol)))
|
|
}
|
|
var clientOrderId interface{} = this.SafeString2(params, "newClientOrderId", "clientOrderId")
|
|
if IsTrue(!IsEqual(clientOrderId, nil)) {
|
|
params = this.Omit(params, []interface{}{"newClientOrderId", "clientOrderId"})
|
|
AddElementToObject(request, "newClientOrderId", clientOrderId)
|
|
}
|
|
var triggerPrice interface{} = this.SafeValue2(params, "triggerPrice", "stopPrice")
|
|
if IsTrue(!IsEqual(triggerPrice, nil)) {
|
|
params = this.Omit(params, []interface{}{"triggerPrice", "stopPrice"})
|
|
AddElementToObject(request, "stopPrice", this.PriceToPrecision(symbol, triggerPrice))
|
|
}
|
|
|
|
response = (<-this.SpotV1PrivatePostOrder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
data = response
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " createOrder only support spot & swap markets")))
|
|
}
|
|
|
|
//
|
|
// spot
|
|
//
|
|
// {
|
|
// "symbol": "BTCUSDT",
|
|
// "orderId": 307650651173648896,
|
|
// "orderIdStr": "307650651173648896",
|
|
// "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
|
|
// "transactTime": 1507725176595
|
|
// }
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// "code": "0",
|
|
// "msg": "Success",
|
|
// "data": {
|
|
// "orderId": 1690615676032452985
|
|
// }
|
|
// }
|
|
//
|
|
ch <- this.ParseOrder(data, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchOrder
|
|
* @description fetches information on an order made by the user
|
|
* @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#query-order-user_data
|
|
* @see https://www.bitrue.com/api_docs_includes_file/futures/index.html#query-order-user_data-hmac-sha256
|
|
* @param {string} id the order id
|
|
* @param {string} symbol unified symbol of the market the order was made in
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitrue) FetchOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOrder() requires a symbol argument")))
|
|
}
|
|
|
|
retRes21148 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes21148)
|
|
var market interface{} = this.Market(symbol)
|
|
var origClientOrderId interface{} = this.SafeValue2(params, "origClientOrderId", "clientOrderId")
|
|
params = this.Omit(params, []interface{}{"origClientOrderId", "clientOrderId"})
|
|
var response interface{} = nil
|
|
var data interface{} = nil
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(IsEqual(origClientOrderId, nil)) {
|
|
AddElementToObject(request, "orderId", id)
|
|
} else {
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
AddElementToObject(request, "clientOrderId", origClientOrderId)
|
|
} else {
|
|
AddElementToObject(request, "origClientOrderId", origClientOrderId)
|
|
}
|
|
}
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
AddElementToObject(request, "contractName", GetValue(market, "id"))
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV2PrivateGetOrder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV2PrivateGetOrder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
data = this.SafeDict(response, "data", map[string]interface{} {})
|
|
} else if IsTrue(GetValue(market, "spot")) {
|
|
AddElementToObject(request, "orderId", id) // spot market id is mandatory
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
|
|
response = (<-this.SpotV1PrivateGetOrder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
data = response
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " fetchOrder only support spot & swap markets")))
|
|
}
|
|
|
|
//
|
|
// spot
|
|
//
|
|
// {
|
|
// "symbol": "LTCBTC",
|
|
// "orderId": 1,
|
|
// "clientOrderId": "myOrder1",
|
|
// "price": "0.1",
|
|
// "origQty": "1.0",
|
|
// "executedQty": "0.0",
|
|
// "cummulativeQuoteQty": "0.0",
|
|
// "status": "NEW",
|
|
// "timeInForce": "GTC",
|
|
// "type": "LIMIT",
|
|
// "side": "BUY",
|
|
// "stopPrice": "0.0",
|
|
// "icebergQty": "0.0",
|
|
// "time": 1499827319559,
|
|
// "updateTime": 1499827319559,
|
|
// "isWorking": true
|
|
// }
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// "code":0,
|
|
// "msg":"success",
|
|
// "data":{
|
|
// "orderId":1917641,
|
|
// "price":100,
|
|
// "origQty":10,
|
|
// "origAmount":10,
|
|
// "executedQty":1,
|
|
// "avgPrice":10000,
|
|
// "status":"INIT",
|
|
// "type":"LIMIT",
|
|
// "side":"BUY",
|
|
// "action":"OPEN",
|
|
// "transactTime":1686716571425
|
|
// "clientOrderId":4949299210
|
|
// }
|
|
// }
|
|
//
|
|
ch <- this.ParseOrder(data, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchClosedOrders
|
|
* @description fetches information on multiple closed orders made by the user
|
|
* @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#all-orders-user_data
|
|
* @param {string} symbol unified market symbol of the market orders were made in
|
|
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitrue) FetchClosedOrders(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchClosedOrders() requires a symbol argument")))
|
|
}
|
|
|
|
retRes22078 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes22078)
|
|
var market interface{} = this.Market(symbol)
|
|
if !IsTrue(GetValue(market, "spot")) {
|
|
panic(NotSupported(Add(this.Id, " fetchClosedOrders only support spot markets")))
|
|
}
|
|
var request interface{} = map[string]interface{} {
|
|
"symbol": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit) // default 100, max 1000
|
|
}
|
|
|
|
response:= (<-this.SpotV1PrivateGetAllOrders(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol": "LTCBTC",
|
|
// "orderId": 1,
|
|
// "clientOrderId": "myOrder1",
|
|
// "price": "0.1",
|
|
// "origQty": "1.0",
|
|
// "executedQty": "0.0",
|
|
// "cummulativeQuoteQty": "0.0",
|
|
// "status": "NEW",
|
|
// "timeInForce": "GTC",
|
|
// "type": "LIMIT",
|
|
// "side": "BUY",
|
|
// "stopPrice": "0.0",
|
|
// "icebergQty": "0.0",
|
|
// "time": 1499827319559,
|
|
// "updateTime": 1499827319559,
|
|
// "isWorking": true
|
|
// }
|
|
// ]
|
|
//
|
|
ch <- this.ParseOrders(response, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchOpenOrders
|
|
* @description fetch all unfilled currently open orders
|
|
* @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#current-open-orders-user_data
|
|
* @see https://www.bitrue.com/api_docs_includes_file/futures/index.html#cancel-all-open-orders-trade-hmac-sha256
|
|
* @param {string} symbol unified market symbol
|
|
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
* @param {int} [limit] the maximum number of open order structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitrue) FetchOpenOrders(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOpenOrders() requires a symbol argument")))
|
|
}
|
|
|
|
retRes22678 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes22678)
|
|
var market interface{} = this.Market(symbol)
|
|
var response interface{} = nil
|
|
var data interface{} = nil
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
AddElementToObject(request, "contractName", GetValue(market, "id"))
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV2PrivateGetOpenOrders(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV2PrivateGetOpenOrders(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
data = this.SafeList(response, "data", []interface{}{})
|
|
} else if IsTrue(GetValue(market, "spot")) {
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
|
|
response = (<-this.SpotV1PrivateGetOpenOrders(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
data = response
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " fetchOpenOrders only support spot & swap markets")))
|
|
}
|
|
|
|
//
|
|
// spot
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol":"USDCUSDT",
|
|
// "orderId":"2878854881",
|
|
// "clientOrderId":"",
|
|
// "price":"1.1000000000000000",
|
|
// "origQty":"100.0000000000000000",
|
|
// "executedQty":"0.0000000000000000",
|
|
// "cummulativeQuoteQty":"0.0000000000000000",
|
|
// "status":"NEW",
|
|
// "timeInForce":"",
|
|
// "type":"LIMIT",
|
|
// "side":"SELL",
|
|
// "stopPrice":"",
|
|
// "icebergQty":"",
|
|
// "time":1635551031000,
|
|
// "updateTime":1635551031000,
|
|
// "isWorking":false
|
|
// }
|
|
// ]
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// "code": "0",
|
|
// "msg": "Success",
|
|
// "data": [{
|
|
// "orderId": 1917641,
|
|
// "clientOrderId": "2488514315",
|
|
// "price": 100,
|
|
// "origQty": 10,
|
|
// "origAmount": 10,
|
|
// "executedQty": 1,
|
|
// "avgPrice": 12451,
|
|
// "status": "INIT",
|
|
// "type": "LIMIT",
|
|
// "side": "BUY",
|
|
// "action": "OPEN",
|
|
// "transactTime": 1686717303975
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
ch <- this.ParseOrders(data, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#cancelOrder
|
|
* @description cancels an open order
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#cancel-order-trade
|
|
* @see https://www.bitrue.com/api-docs#cancel-order-trade-hmac-sha256
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#cancel-order-trade-hmac-sha256
|
|
* @param {string} id order id
|
|
* @param {string} symbol unified symbol of the market the order was made in
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *bitrue) CancelOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " cancelOrder() requires a symbol argument")))
|
|
}
|
|
|
|
retRes23528 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes23528)
|
|
var market interface{} = this.Market(symbol)
|
|
var origClientOrderId interface{} = this.SafeValue2(params, "origClientOrderId", "clientOrderId")
|
|
params = this.Omit(params, []interface{}{"origClientOrderId", "clientOrderId"})
|
|
var response interface{} = nil
|
|
var data interface{} = nil
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(IsEqual(origClientOrderId, nil)) {
|
|
AddElementToObject(request, "orderId", id)
|
|
} else {
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
AddElementToObject(request, "clientOrderId", origClientOrderId)
|
|
} else {
|
|
AddElementToObject(request, "origClientOrderId", origClientOrderId)
|
|
}
|
|
}
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
AddElementToObject(request, "contractName", GetValue(market, "id"))
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV2PrivatePostCancel(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV2PrivatePostCancel(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
data = this.SafeDict(response, "data", map[string]interface{} {})
|
|
} else if IsTrue(GetValue(market, "spot")) {
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
|
|
response = (<-this.SpotV1PrivateDeleteOrder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
data = response
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " cancelOrder only support spot & swap markets")))
|
|
}
|
|
|
|
//
|
|
// spot
|
|
//
|
|
// {
|
|
// "symbol": "LTCBTC",
|
|
// "origClientOrderId": "myOrder1",
|
|
// "orderId": 1,
|
|
// "clientOrderId": "cancelMyOrder1"
|
|
// }
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// "code": "0",
|
|
// "msg": "Success",
|
|
// "data": {
|
|
// "orderId": 1690615847831143159
|
|
// }
|
|
// }
|
|
//
|
|
ch <- this.ParseOrder(data, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#cancelAllOrders
|
|
* @description cancel all open orders in a market
|
|
* @see https://www.bitrue.com/api-docs#cancel-all-open-orders-trade-hmac-sha256
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#cancel-all-open-orders-trade-hmac-sha256
|
|
* @param {string} symbol unified market symbol of the market to cancel orders in
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.marginMode] 'cross' or 'isolated', for spot margin trading
|
|
* @returns {object[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
|
|
*/
|
|
func (this *bitrue) CancelAllOrders(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes24188 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes24188)
|
|
var market interface{} = this.Market(symbol)
|
|
var response interface{} = nil
|
|
var data interface{} = nil
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
var request interface{} = map[string]interface{} {
|
|
"contractName": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV2PrivatePostAllOpenOrders(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV2PrivatePostAllOpenOrders(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
data = this.SafeList(response, "data", []interface{}{})
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " cancelAllOrders only support future markets")))
|
|
}
|
|
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// 'code': '0',
|
|
// 'msg': 'Success',
|
|
// 'data': null
|
|
// }
|
|
//
|
|
ch <- this.ParseOrders(data, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchMyTrades
|
|
* @description fetch all trades made by the user
|
|
* @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#account-trade-list-user_data
|
|
* @see https://www.bitrue.com/api_docs_includes_file/futures/index.html#account-trade-list-user_data-hmac-sha256
|
|
* @param {string} symbol unified market symbol
|
|
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
*/
|
|
func (this *bitrue) FetchMyTrades(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes24608 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes24608)
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchMyTrades() requires a symbol argument")))
|
|
}
|
|
var market interface{} = this.Market(symbol)
|
|
var response interface{} = nil
|
|
var data interface{} = nil
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
if IsTrue(IsGreaterThan(limit, 1000)) {
|
|
limit = 1000
|
|
}
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
if IsTrue(GetValue(market, "swap")) {
|
|
AddElementToObject(request, "contractName", GetValue(market, "id"))
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV2PrivateGetMyTrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV2PrivateGetMyTrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
data = this.SafeList(response, "data", []interface{}{})
|
|
} else if IsTrue(GetValue(market, "spot")) {
|
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
|
|
|
response = (<-this.SpotV2PrivateGetMyTrades(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
data = response
|
|
} else {
|
|
panic(NotSupported(Add(this.Id, " fetchMyTrades only support spot & swap markets")))
|
|
}
|
|
|
|
//
|
|
// spot
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol":"USDCUSDT",
|
|
// "id":20725156,
|
|
// "orderId":2880918576,
|
|
// "origClientOrderId":null,
|
|
// "price":"0.9996000000000000",
|
|
// "qty":"100.0000000000000000",
|
|
// "commission":null,
|
|
// "commissionAssert":null,
|
|
// "time":1635558511000,
|
|
// "isBuyer":false,
|
|
// "isMaker":false,
|
|
// "isBestMatch":true
|
|
// }
|
|
// ]
|
|
//
|
|
// swap
|
|
//
|
|
// {
|
|
// "code":"0",
|
|
// "msg":"Success",
|
|
// "data":[
|
|
// {
|
|
// "tradeId":12,
|
|
// "price":0.9,
|
|
// "qty":1,
|
|
// "amount":9,
|
|
// "contractName":"E-SAND-USDT",
|
|
// "side":"BUY",
|
|
// "fee":"0.0018",
|
|
// "bidId":1558124009467904992,
|
|
// "askId":1558124043827644908,
|
|
// "bidUserId":10294,
|
|
// "askUserId":10467,
|
|
// "isBuyer":true,
|
|
// "isMaker":true,
|
|
// "ctime":1678426306000
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
ch <- this.ParseTrades(data, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchDeposits
|
|
* @description fetch all deposits made to an account
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#deposit-history--withdraw_data
|
|
* @param {string} code unified currency code
|
|
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *bitrue) FetchDeposits(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(code, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchDeposits() requires a code argument")))
|
|
}
|
|
|
|
retRes25558 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes25558)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"coin": GetValue(currency, "id"),
|
|
"status": 1,
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.SpotV1PrivateGetDepositHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "code":200,
|
|
// "msg":"succ",
|
|
// "data":[
|
|
// {
|
|
// "id":2659137,
|
|
// "symbol":"USDC",
|
|
// "amount":"200.0000000000000000",
|
|
// "fee":"0.0E-15",
|
|
// "createdAt":1635503169000,
|
|
// "updatedAt":1635503202000,
|
|
// "addressFrom":"0x2faf487a4414fe77e2327f0bf4ae2a264a776ad2",
|
|
// "addressTo":"0x190ceccb1f8bfbec1749180f0ba8922b488d865b",
|
|
// "txid":"0x9970aec41099ac385568859517308707bc7d716df8dabae7b52f5b17351c3ed0",
|
|
// "confirmations":5,
|
|
// "status":0,
|
|
// "tagType":null,
|
|
// },
|
|
// {
|
|
// "id":2659137,
|
|
// "symbol": "XRP",
|
|
// "amount": "20.0000000000000000",
|
|
// "fee": "0.0E-15",
|
|
// "createdAt": 1544669393000,
|
|
// "updatedAt": 1544669413000,
|
|
// "addressFrom": "",
|
|
// "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641",
|
|
// "txid": "515B23E1F9864D3AF7F5B4C4FCBED784BAE861854FAB95F4031922B6AAEFC7AC",
|
|
// "confirmations": 7,
|
|
// "status": 1,
|
|
// "tagType": "Tag"
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
|
|
|
ch <- this.ParseTransactions(data, currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchWithdrawals
|
|
* @description fetch all withdrawals made from an account
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#withdraw-history--withdraw_data
|
|
* @param {string} code unified currency code
|
|
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *bitrue) FetchWithdrawals(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(code, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchWithdrawals() requires a code argument")))
|
|
}
|
|
|
|
retRes26288 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes26288)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"coin": GetValue(currency, "id"),
|
|
"status": 5,
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "startTime", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.SpotV1PrivateGetWithdrawHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "code": 200,
|
|
// "msg": "succ",
|
|
// "data": [
|
|
// {
|
|
// "id": 183745,
|
|
// "symbol": "usdt_erc20",
|
|
// "amount": "8.4000000000000000",
|
|
// "fee": "1.6000000000000000",
|
|
// "payAmount": "0.0000000000000000",
|
|
// "createdAt": 1595336441000,
|
|
// "updatedAt": 1595336576000,
|
|
// "addressFrom": "",
|
|
// "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83",
|
|
// "txid": "",
|
|
// "confirmations": 0,
|
|
// "status": 6,
|
|
// "tagType": null
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
|
|
|
ch <- this.ParseTransactions(data, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitrue) ParseTransactionStatusByType(status interface{}, optionalArgs ...interface{}) interface{} {
|
|
typeVar := GetArg(optionalArgs, 0, nil)
|
|
_ = typeVar
|
|
var statusesByType interface{} = map[string]interface{} {
|
|
"deposit": map[string]interface{} {
|
|
"0": "pending",
|
|
"1": "ok",
|
|
},
|
|
"withdrawal": map[string]interface{} {
|
|
"0": "pending",
|
|
"5": "ok",
|
|
"6": "canceled",
|
|
},
|
|
}
|
|
var statuses interface{} = this.SafeDict(statusesByType, typeVar, map[string]interface{} {})
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *bitrue) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchDeposits
|
|
//
|
|
// {
|
|
// "symbol": "XRP",
|
|
// "amount": "261.3361000000000000",
|
|
// "fee": "0.0E-15",
|
|
// "createdAt": 1548816979000,
|
|
// "updatedAt": 1548816999000,
|
|
// "addressFrom": "",
|
|
// "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641",
|
|
// "txid": "86D6EB68A7A28938BCE06BD348F8C07DEF500C5F7FE92069EF8C0551CE0F2C7D",
|
|
// "confirmations": 8,
|
|
// "status": 1,
|
|
// "tagType": "Tag"
|
|
// },
|
|
// {
|
|
// "symbol": "XRP",
|
|
// "amount": "20.0000000000000000",
|
|
// "fee": "0.0E-15",
|
|
// "createdAt": 1544669393000,
|
|
// "updatedAt": 1544669413000,
|
|
// "addressFrom": "",
|
|
// "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641",
|
|
// "txid": "515B23E1F9864D3AF7F5B4C4FCBED784BAE861854FAB95F4031922B6AAEFC7AC",
|
|
// "confirmations": 7,
|
|
// "status": 1,
|
|
// "tagType": "Tag"
|
|
// }
|
|
//
|
|
// fetchWithdrawals
|
|
//
|
|
// {
|
|
// "id": 183745,
|
|
// "symbol": "usdt_erc20",
|
|
// "amount": "8.4000000000000000",
|
|
// "fee": "1.6000000000000000",
|
|
// "payAmount": "0.0000000000000000",
|
|
// "createdAt": 1595336441000,
|
|
// "updatedAt": 1595336576000,
|
|
// "addressFrom": "",
|
|
// "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83",
|
|
// "txid": "",
|
|
// "confirmations": 0,
|
|
// "status": 6,
|
|
// "tagType": null
|
|
// }
|
|
//
|
|
// withdraw
|
|
//
|
|
// {
|
|
// "msg": null,
|
|
// "amount": 1000,
|
|
// "fee": 1,
|
|
// "ctime": null,
|
|
// "coin": "usdt_erc20",
|
|
// "withdrawId": 1156423,
|
|
// "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83"
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var id interface{} = this.SafeString2(transaction, "id", "withdrawId")
|
|
var tagType interface{} = this.SafeString(transaction, "tagType")
|
|
var addressTo interface{} = this.SafeString(transaction, "addressTo")
|
|
var addressFrom interface{} = this.SafeString(transaction, "addressFrom")
|
|
var tagTo interface{} = nil
|
|
var tagFrom interface{} = nil
|
|
if IsTrue(!IsEqual(tagType, nil)) {
|
|
if IsTrue(!IsEqual(addressTo, nil)) {
|
|
var parts interface{} = Split(addressTo, "_")
|
|
addressTo = this.SafeString(parts, 0)
|
|
tagTo = this.SafeString(parts, 1)
|
|
}
|
|
if IsTrue(!IsEqual(addressFrom, nil)) {
|
|
var parts interface{} = Split(addressFrom, "_")
|
|
addressFrom = this.SafeString(parts, 0)
|
|
tagFrom = this.SafeString(parts, 1)
|
|
}
|
|
}
|
|
var txid interface{} = this.SafeString(transaction, "txid")
|
|
var timestamp interface{} = this.SafeInteger(transaction, "createdAt")
|
|
var updated interface{} = this.SafeInteger(transaction, "updatedAt")
|
|
var payAmount interface{} = (InOp(transaction, "payAmount"))
|
|
var ctime interface{} = (InOp(transaction, "ctime"))
|
|
var typeVar interface{} = Ternary(IsTrue((IsTrue(payAmount) || IsTrue(ctime))), "withdrawal", "deposit")
|
|
var status interface{} = this.ParseTransactionStatusByType(this.SafeString(transaction, "status"), typeVar)
|
|
var amount interface{} = this.SafeNumber(transaction, "amount")
|
|
var network interface{} = nil
|
|
var currencyId interface{} = this.SafeString2(transaction, "symbol", "coin")
|
|
if IsTrue(!IsEqual(currencyId, nil)) {
|
|
var parts interface{} = Split(currencyId, "_")
|
|
currencyId = this.SafeString(parts, 0)
|
|
var networkId interface{} = this.SafeString(parts, 1)
|
|
if IsTrue(!IsEqual(networkId, nil)) {
|
|
network = ToUpper(networkId)
|
|
}
|
|
}
|
|
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
|
|
var feeCost interface{} = this.SafeNumber(transaction, "fee")
|
|
var fee interface{} = nil
|
|
if IsTrue(!IsEqual(feeCost, nil)) {
|
|
fee = map[string]interface{} {
|
|
"currency": code,
|
|
"cost": feeCost,
|
|
}
|
|
}
|
|
return map[string]interface{} {
|
|
"info": transaction,
|
|
"id": id,
|
|
"txid": txid,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"network": network,
|
|
"address": addressTo,
|
|
"addressTo": addressTo,
|
|
"addressFrom": addressFrom,
|
|
"tag": tagTo,
|
|
"tagTo": tagTo,
|
|
"tagFrom": tagFrom,
|
|
"type": typeVar,
|
|
"amount": amount,
|
|
"currency": code,
|
|
"status": status,
|
|
"updated": updated,
|
|
"internal": false,
|
|
"comment": nil,
|
|
"fee": fee,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#withdraw
|
|
* @description make a withdrawal
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#withdraw-commit--withdraw_data
|
|
* @param {string} code unified currency code
|
|
* @param {float} amount the amount to withdraw
|
|
* @param {string} address the address to withdraw to
|
|
* @param {string} tag
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *bitrue) Withdraw(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
tag := GetArg(optionalArgs, 0, nil)
|
|
_ = tag
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
tagparamsVariable := this.HandleWithdrawTagAndParams(tag, params);
|
|
tag = GetValue(tagparamsVariable,0);
|
|
params = GetValue(tagparamsVariable,1)
|
|
this.CheckAddress(address)
|
|
|
|
retRes28318 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes28318)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"coin": GetValue(currency, "id"),
|
|
"amount": amount,
|
|
"addressTo": address,
|
|
}
|
|
var networkCode interface{} = nil
|
|
networkCodeparamsVariable := this.HandleNetworkCodeAndParams(params);
|
|
networkCode = GetValue(networkCodeparamsVariable,0);
|
|
params = GetValue(networkCodeparamsVariable,1)
|
|
if IsTrue(!IsEqual(networkCode, nil)) {
|
|
AddElementToObject(request, "chainName", this.NetworkCodeToId(networkCode))
|
|
}
|
|
if IsTrue(!IsEqual(tag, nil)) {
|
|
AddElementToObject(request, "tag", tag)
|
|
}
|
|
|
|
response:= (<-this.SpotV1PrivatePostWithdrawCommit(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "code": 200,
|
|
// "msg": "succ",
|
|
// "data": {
|
|
// "msg": null,
|
|
// "amount": 1000,
|
|
// "fee": 1,
|
|
// "ctime": null,
|
|
// "coin": "usdt_erc20",
|
|
// "withdrawId": 1156423,
|
|
// "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83"
|
|
// }
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
|
|
ch <- this.ParseTransaction(data, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitrue) ParseDepositWithdrawFee(fee interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "coin": "adx",
|
|
// "coinFulName": "Ambire AdEx",
|
|
// "chains": [ "BSC" ],
|
|
// "chainDetail": [ [Object] ]
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var chainDetails interface{} = this.SafeList(fee, "chainDetail", []interface{}{})
|
|
var chainDetailLength interface{} = GetArrayLength(chainDetails)
|
|
var result interface{} = map[string]interface{} {
|
|
"info": fee,
|
|
"withdraw": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
"deposit": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
"networks": map[string]interface{} {},
|
|
}
|
|
if IsTrue(!IsEqual(chainDetailLength, 0)) {
|
|
for i := 0; IsLessThan(i, chainDetailLength); i++ {
|
|
var chainDetail interface{} = GetValue(chainDetails, i)
|
|
var networkId interface{} = this.SafeString(chainDetail, "chain")
|
|
var currencyCode interface{} = this.SafeString(currency, "code")
|
|
var networkCode interface{} = this.NetworkIdToCode(networkId, currencyCode)
|
|
AddElementToObject(GetValue(result, "networks"), networkCode, map[string]interface{} {
|
|
"deposit": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
"withdraw": map[string]interface{} {
|
|
"fee": this.SafeNumber(chainDetail, "withdrawFee"),
|
|
"percentage": false,
|
|
},
|
|
})
|
|
if IsTrue(IsEqual(chainDetailLength, 1)) {
|
|
AddElementToObject(GetValue(result, "withdraw"), "fee", this.SafeNumber(chainDetail, "withdrawFee"))
|
|
AddElementToObject(GetValue(result, "withdraw"), "percentage", false)
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchDepositWithdrawFees
|
|
* @description fetch deposit and withdraw fees
|
|
* @see https://github.com/Bitrue-exchange/Spot-official-api-docs#exchangeInfo_endpoint
|
|
* @param {string[]|undefined} codes list of unified currency codes
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
*/
|
|
func (this *bitrue) FetchDepositWithdrawFees(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
codes := GetArg(optionalArgs, 0, nil)
|
|
_ = codes
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes29228 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes29228)
|
|
|
|
response:= (<-this.SpotV1PublicGetExchangeInfo(params))
|
|
PanicOnError(response)
|
|
var coins interface{} = this.SafeList(response, "coins")
|
|
|
|
ch <- this.ParseDepositWithdrawFees(coins, codes, "coin")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitrue) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// fetchTransfers
|
|
//
|
|
// {
|
|
// 'transferType': 'wallet_to_contract',
|
|
// 'symbol': 'USDT',
|
|
// 'amount': 1.0,
|
|
// 'status': 1,
|
|
// 'ctime': 1685404575000
|
|
// }
|
|
//
|
|
// transfer
|
|
//
|
|
// {}
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var transferType interface{} = this.SafeString(transfer, "transferType")
|
|
var fromAccount interface{} = nil
|
|
var toAccount interface{} = nil
|
|
if IsTrue(!IsEqual(transferType, nil)) {
|
|
var accountSplit interface{} = Split(transferType, "_to_")
|
|
fromAccount = this.SafeString(accountSplit, 0)
|
|
toAccount = this.SafeString(accountSplit, 1)
|
|
}
|
|
var timestamp interface{} = this.SafeInteger(transfer, "ctime")
|
|
return map[string]interface{} {
|
|
"info": transfer,
|
|
"id": nil,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"currency": this.SafeString(currency, "code"),
|
|
"amount": this.SafeNumber(transfer, "amount"),
|
|
"fromAccount": fromAccount,
|
|
"toAccount": toAccount,
|
|
"status": "ok",
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#fetchTransfers
|
|
* @description fetch a history of internal transfers made on an account
|
|
* @see https://www.bitrue.com/api-docs#get-future-account-transfer-history-list-user_data-hmac-sha256
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#get-future-account-transfer-history-list-user_data-hmac-sha256
|
|
* @param {string} code unified currency code of the currency transferred
|
|
* @param {int} [since] the earliest time in ms to fetch transfers for
|
|
* @param {int} [limit] the maximum number of transfers structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] the latest time in ms to fetch transfers for
|
|
* @param {string} [params.type] transfer type wallet_to_contract or contract_to_wallet
|
|
* @returns {object[]} a list of [transfer structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#transfer-structure}
|
|
*/
|
|
func (this *bitrue) FetchTransfers(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
code := GetArg(optionalArgs, 0, nil)
|
|
_ = code
|
|
since := GetArg(optionalArgs, 1, nil)
|
|
_ = since
|
|
limit := GetArg(optionalArgs, 2, nil)
|
|
_ = limit
|
|
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes29818 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes29818)
|
|
var typeVar interface{} = this.SafeString2(params, "type", "transferType")
|
|
var request interface{} = map[string]interface{} {
|
|
"transferType": typeVar,
|
|
}
|
|
var currency interface{} = nil
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
AddElementToObject(request, "coinSymbol", GetValue(currency, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "beginTime", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
if IsTrue(IsGreaterThan(limit, 200)) {
|
|
limit = 200
|
|
}
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
var until interface{} = this.SafeInteger(params, "until")
|
|
if IsTrue(!IsEqual(until, nil)) {
|
|
params = this.Omit(params, "until")
|
|
AddElementToObject(request, "endTime", until)
|
|
}
|
|
|
|
response:= (<-this.FapiV2PrivateGetFuturesTransferHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// 'code': '0',
|
|
// 'msg': 'Success',
|
|
// 'data': [{
|
|
// 'transferType': 'wallet_to_contract',
|
|
// 'symbol': 'USDT',
|
|
// 'amount': 1.0,
|
|
// 'status': 1,
|
|
// 'ctime': 1685404575000
|
|
// }]
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
|
|
|
ch <- this.ParseTransfers(data, currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#transfer
|
|
* @description transfer currency internally between wallets on the same account
|
|
* @see https://www.bitrue.com/api-docs#new-future-account-transfer-user_data-hmac-sha256
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#user-commission-rate-user_data-hmac-sha256
|
|
* @param {string} code unified currency code
|
|
* @param {float} amount amount to transfer
|
|
* @param {string} fromAccount account to transfer from
|
|
* @param {string} toAccount account to transfer to
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [transfer structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#transfer-structure}
|
|
*/
|
|
func (this *bitrue) Transfer(code interface{}, amount interface{}, fromAccount interface{}, toAccount interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes30378 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes30378)
|
|
var currency interface{} = this.Currency(code)
|
|
var accountTypes interface{} = this.SafeDict(this.Options, "accountsByType", map[string]interface{} {})
|
|
var fromId interface{} = this.SafeString(accountTypes, fromAccount, fromAccount)
|
|
var toId interface{} = this.SafeString(accountTypes, toAccount, toAccount)
|
|
var request interface{} = map[string]interface{} {
|
|
"coinSymbol": GetValue(currency, "id"),
|
|
"amount": this.CurrencyToPrecision(code, amount),
|
|
"transferType": Add(Add(fromId, "_to_"), toId),
|
|
}
|
|
|
|
response:= (<-this.FapiV2PrivatePostFuturesTransfer(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// 'code': '0',
|
|
// 'msg': 'Success',
|
|
// 'data': null
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
|
|
ch <- this.ParseTransfer(data, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#setLeverage
|
|
* @description set the level of leverage for a market
|
|
* @see https://www.bitrue.com/api-docs#change-initial-leverage-trade-hmac-sha256
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#change-initial-leverage-trade-hmac-sha256
|
|
* @param {float} leverage the rate of leverage
|
|
* @param {string} symbol unified market symbol
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} response from the exchange
|
|
*/
|
|
func (this *bitrue) SetLeverage(leverage interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
symbol := GetArg(optionalArgs, 0, nil)
|
|
_ = symbol
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " setLeverage() requires a symbol argument")))
|
|
}
|
|
if IsTrue(IsTrue((IsLessThan(leverage, 1))) || IsTrue((IsGreaterThan(leverage, 125)))) {
|
|
panic(BadRequest(Add(this.Id, " leverage should be between 1 and 125")))
|
|
}
|
|
|
|
retRes30778 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes30778)
|
|
var market interface{} = this.Market(symbol)
|
|
var response interface{} = nil
|
|
var request interface{} = map[string]interface{} {
|
|
"contractName": GetValue(market, "id"),
|
|
"leverage": leverage,
|
|
}
|
|
if !IsTrue(GetValue(market, "swap")) {
|
|
panic(NotSupported(Add(this.Id, " setLeverage only support swap markets")))
|
|
}
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV2PrivatePostLevelEdit(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV2PrivatePostLevelEdit(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
|
|
ch <- response
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitrue) ParseMarginModification(data interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// setMargin
|
|
//
|
|
// {
|
|
// "code": 0,
|
|
// "msg": "success"
|
|
// "data": null
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
return map[string]interface{} {
|
|
"info": data,
|
|
"symbol": GetValue(market, "symbol"),
|
|
"type": nil,
|
|
"marginMode": "isolated",
|
|
"amount": nil,
|
|
"total": nil,
|
|
"code": nil,
|
|
"status": nil,
|
|
"timestamp": nil,
|
|
"datetime": nil,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name bitrue#setMargin
|
|
* @description Either adds or reduces margin in an isolated position in order to set the margin to a specific value
|
|
* @see https://www.bitrue.com/api-docs#modify-isolated-position-margin-trade-hmac-sha256
|
|
* @see https://www.bitrue.com/api_docs_includes_file/delivery.html#modify-isolated-position-margin-trade-hmac-sha256
|
|
* @param {string} symbol unified market symbol of the market to set margin in
|
|
* @param {float} amount the amount to set the margin to
|
|
* @param {object} [params] parameters specific to the exchange API endpoint
|
|
* @returns {object} A [margin structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#add-margin-structure}
|
|
*/
|
|
func (this *bitrue) SetMargin(symbol interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes31318 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes31318)
|
|
var market interface{} = this.Market(symbol)
|
|
if !IsTrue(GetValue(market, "swap")) {
|
|
panic(NotSupported(Add(this.Id, " setMargin only support swap markets")))
|
|
}
|
|
var response interface{} = nil
|
|
var request interface{} = map[string]interface{} {
|
|
"contractName": GetValue(market, "id"),
|
|
"amount": this.ParseToNumeric(amount),
|
|
}
|
|
if IsTrue(GetValue(market, "linear")) {
|
|
|
|
response = (<-this.FapiV2PrivatePostPositionMargin(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else if IsTrue(GetValue(market, "inverse")) {
|
|
|
|
response = (<-this.DapiV2PrivatePostPositionMargin(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
|
|
//
|
|
// {
|
|
// "code": 0,
|
|
// "msg": "success"
|
|
// "data": null
|
|
// }
|
|
//
|
|
ch <- this.ParseMarginModification(response, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *bitrue) Sign(path interface{}, optionalArgs ...interface{}) interface{} {
|
|
api := GetArg(optionalArgs, 0, "public")
|
|
_ = api
|
|
method := GetArg(optionalArgs, 1, "GET")
|
|
_ = method
|
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
|
_ = params
|
|
headers := GetArg(optionalArgs, 3, nil)
|
|
_ = headers
|
|
body := GetArg(optionalArgs, 4, nil)
|
|
_ = body
|
|
var typeVar interface{} = this.SafeString(api, 0)
|
|
var version interface{} = this.SafeString(api, 1)
|
|
var access interface{} = this.SafeString(api, 2)
|
|
var url interface{} = nil
|
|
if IsTrue(IsTrue((IsTrue(IsEqual(typeVar, "api")) && IsTrue(IsEqual(version, "kline")))) || IsTrue((IsTrue(IsEqual(typeVar, "open")) && IsTrue(IsGreaterThanOrEqual(GetIndexOf(path, "listenKey"), 0))))) {
|
|
url = GetValue(GetValue(this.Urls, "api"), typeVar)
|
|
} else {
|
|
url = Add(Add(GetValue(GetValue(this.Urls, "api"), typeVar), "/"), version)
|
|
}
|
|
url = Add(Add(url, "/"), this.ImplodeParams(path, params))
|
|
params = this.Omit(params, this.ExtractParams(path))
|
|
if IsTrue(IsEqual(access, "private")) {
|
|
this.CheckRequiredCredentials()
|
|
var recvWindow interface{} = this.SafeInteger(this.Options, "recvWindow", 5000)
|
|
if IsTrue(IsTrue(IsEqual(typeVar, "spot")) || IsTrue(IsEqual(typeVar, "open"))) {
|
|
var query interface{} = this.Urlencode(this.Extend(map[string]interface{} {
|
|
"timestamp": this.Nonce(),
|
|
"recvWindow": recvWindow,
|
|
}, params))
|
|
var signature interface{} = this.Hmac(this.Encode(query), this.Encode(this.Secret), sha256)
|
|
query = Add(query, Add(Add("&", "signature="), signature))
|
|
headers = map[string]interface{} {
|
|
"X-MBX-APIKEY": this.ApiKey,
|
|
}
|
|
if IsTrue(IsTrue((IsEqual(method, "GET"))) || IsTrue((IsEqual(method, "DELETE")))) {
|
|
url = Add(url, Add("?", query))
|
|
} else {
|
|
body = query
|
|
AddElementToObject(headers, "Content-Type", "application/x-www-form-urlencoded")
|
|
}
|
|
} else {
|
|
var timestamp interface{} = ToString(this.Nonce())
|
|
var signPath interface{} = nil
|
|
if IsTrue(IsEqual(typeVar, "fapi")) {
|
|
signPath = "/fapi"
|
|
} else if IsTrue(IsEqual(typeVar, "dapi")) {
|
|
signPath = "/dapi"
|
|
}
|
|
signPath = Add(Add(Add(Add(signPath, "/"), version), "/"), path)
|
|
var signMessage interface{} = Add(Add(timestamp, method), signPath)
|
|
if IsTrue(IsEqual(method, "GET")) {
|
|
var keys interface{} = ObjectKeys(params)
|
|
var keysLength interface{} = GetArrayLength(keys)
|
|
if IsTrue(IsGreaterThan(keysLength, 0)) {
|
|
signMessage = Add(signMessage, Add("?", this.Urlencode(params)))
|
|
}
|
|
var signature interface{} = this.Hmac(this.Encode(signMessage), this.Encode(this.Secret), sha256)
|
|
headers = map[string]interface{} {
|
|
"X-CH-APIKEY": this.ApiKey,
|
|
"X-CH-SIGN": signature,
|
|
"X-CH-TS": timestamp,
|
|
}
|
|
url = Add(url, Add("?", this.Urlencode(params)))
|
|
} else {
|
|
var query interface{} = this.Extend(map[string]interface{} {
|
|
"recvWindow": recvWindow,
|
|
}, params)
|
|
body = this.Json(query)
|
|
signMessage = Add(signMessage, body)
|
|
var signature interface{} = this.Hmac(this.Encode(signMessage), this.Encode(this.Secret), sha256)
|
|
headers = map[string]interface{} {
|
|
"Content-Type": "application/json",
|
|
"X-CH-APIKEY": this.ApiKey,
|
|
"X-CH-SIGN": signature,
|
|
"X-CH-TS": timestamp,
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if IsTrue(GetArrayLength(ObjectKeys(params))) {
|
|
url = Add(url, Add("?", this.Urlencode(params)))
|
|
}
|
|
}
|
|
return map[string]interface{} {
|
|
"url": url,
|
|
"method": method,
|
|
"body": body,
|
|
"headers": headers,
|
|
}
|
|
}
|
|
func (this *bitrue) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} {
|
|
if IsTrue(IsTrue((IsEqual(code, 418))) || IsTrue((IsEqual(code, 429)))) {
|
|
panic(DDoSProtection(Add(Add(Add(Add(Add(Add(this.Id, " "), ToString(code)), " "), reason), " "), body)))
|
|
}
|
|
// error response in a form: { "code": -1013, "msg": "Invalid quantity." }
|
|
// following block cointains legacy checks against message patterns in "msg" property
|
|
// will switch "code" checks eventually, when we know all of them
|
|
if IsTrue(IsGreaterThanOrEqual(code, 400)) {
|
|
if IsTrue(IsGreaterThanOrEqual(GetIndexOf(body, "Price * QTY is zero or less"), 0)) {
|
|
panic(InvalidOrder(Add(Add(this.Id, " order cost = amount * price is zero or less "), body)))
|
|
}
|
|
if IsTrue(IsGreaterThanOrEqual(GetIndexOf(body, "LOT_SIZE"), 0)) {
|
|
panic(InvalidOrder(Add(Add(this.Id, " order amount should be evenly divisible by lot size "), body)))
|
|
}
|
|
if IsTrue(IsGreaterThanOrEqual(GetIndexOf(body, "PRICE_FILTER"), 0)) {
|
|
panic(InvalidOrder(Add(Add(this.Id, " order price is invalid, i.e. exceeds allowed price precision, exceeds min price or max price limits or is invalid float value in general, use this.priceToPrecision (symbol, amount) "), body)))
|
|
}
|
|
}
|
|
if IsTrue(IsEqual(response, nil)) {
|
|
return nil // fallback to default error handler
|
|
}
|
|
// check success value for wapi endpoints
|
|
// response in format {'msg': 'The coin does not exist.', 'success': true/false}
|
|
var success interface{} = this.SafeBool(response, "success", true)
|
|
if !IsTrue(success) {
|
|
var messageInner interface{} = this.SafeString(response, "msg")
|
|
var parsedMessage interface{} = nil
|
|
if IsTrue(!IsEqual(messageInner, nil)) {
|
|
|
|
{ ret__ := func(this *bitrue) (ret_ interface{}) {
|
|
defer func() {
|
|
if e := recover(); e != nil {
|
|
if e == "break" {
|
|
return
|
|
}
|
|
ret_ = func(this *bitrue) interface{} {
|
|
// catch block:
|
|
// do nothing
|
|
parsedMessage = nil
|
|
return nil
|
|
}(this)
|
|
}
|
|
}()
|
|
// try block:
|
|
parsedMessage = JsonParse(messageInner)
|
|
return nil
|
|
}(this)
|
|
if ret__ != nil {
|
|
return ret__
|
|
}
|
|
}
|
|
if IsTrue(!IsEqual(parsedMessage, nil)) {
|
|
response = parsedMessage
|
|
}
|
|
}
|
|
}
|
|
var message interface{} = this.SafeString(response, "msg")
|
|
if IsTrue(!IsEqual(message, nil)) {
|
|
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), message, Add(Add(this.Id, " "), message))
|
|
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, Add(Add(this.Id, " "), message))
|
|
}
|
|
// checks against error codes
|
|
var error interface{} = this.SafeString(response, "code")
|
|
if IsTrue(!IsEqual(error, nil)) {
|
|
// https://github.com/ccxt/ccxt/issues/6501
|
|
// https://github.com/ccxt/ccxt/issues/7742
|
|
if IsTrue(IsTrue((IsEqual(error, "200"))) || IsTrue(Precise.StringEquals(error, "0"))) {
|
|
return nil
|
|
}
|
|
// a workaround for {"code":-2015,"msg":"Invalid API-key, IP, or permissions for action."}
|
|
// despite that their message is very confusing, it is raised by Binance
|
|
// on a temporary ban, the API key is valid, but disabled for a while
|
|
if IsTrue(IsTrue((IsEqual(error, "-2015"))) && IsTrue(GetValue(this.Options, "hasAlreadyAuthenticatedSuccessfully"))) {
|
|
panic(DDoSProtection(Add(Add(this.Id, " temporary banned: "), body)))
|
|
}
|
|
var feedback interface{} = Add(Add(this.Id, " "), body)
|
|
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), error, feedback)
|
|
panic(ExchangeError(feedback))
|
|
}
|
|
if !IsTrue(success) {
|
|
panic(ExchangeError(Add(Add(this.Id, " "), body)))
|
|
}
|
|
return nil
|
|
}
|
|
func (this *bitrue) CalculateRateLimiterCost(api interface{}, method interface{}, path interface{}, params interface{}, optionalArgs ...interface{}) interface{} {
|
|
config := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = config
|
|
if IsTrue(IsTrue((InOp(config, "noSymbol"))) && !IsTrue((InOp(params, "symbol")))) {
|
|
return GetValue(config, "noSymbol")
|
|
} else if IsTrue(IsTrue((InOp(config, "byLimit"))) && IsTrue((InOp(params, "limit")))) {
|
|
var limit interface{} = GetValue(params, "limit")
|
|
var byLimit interface{} = GetValue(config, "byLimit")
|
|
for i := 0; IsLessThan(i, GetArrayLength(byLimit)); i++ {
|
|
var entry interface{} = GetValue(byLimit, i)
|
|
if IsTrue(IsLessThanOrEqual(limit, GetValue(entry, 0))) {
|
|
return GetValue(entry, 1)
|
|
}
|
|
}
|
|
}
|
|
return this.SafeValue(config, "cost", 1)
|
|
}
|
|
|
|
|
|
func (this *bitrue) Init(userConfig map[string]interface{}) {
|
|
this.Exchange = Exchange{}
|
|
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
|
|
this.Exchange.DerivedExchange = this
|
|
}
|