3655 lines
161 KiB
Go
3655 lines
161 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 bitmex struct {
|
||
|
Exchange
|
||
|
|
||
|
}
|
||
|
|
||
|
func NewBitmexCore() bitmex {
|
||
|
p := bitmex{}
|
||
|
setDefaults(&p)
|
||
|
return p
|
||
|
}
|
||
|
|
||
|
func (this *bitmex) Describe() interface{} {
|
||
|
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
|
||
|
"id": "bitmex",
|
||
|
"name": "BitMEX",
|
||
|
"countries": []interface{}{"SC"},
|
||
|
"version": "v1",
|
||
|
"userAgent": nil,
|
||
|
"rateLimit": 100,
|
||
|
"certified": true,
|
||
|
"pro": true,
|
||
|
"has": map[string]interface{} {
|
||
|
"CORS": nil,
|
||
|
"spot": true,
|
||
|
"margin": false,
|
||
|
"swap": true,
|
||
|
"future": true,
|
||
|
"option": false,
|
||
|
"addMargin": nil,
|
||
|
"cancelAllOrders": true,
|
||
|
"cancelAllOrdersAfter": true,
|
||
|
"cancelOrder": true,
|
||
|
"cancelOrders": true,
|
||
|
"closeAllPositions": false,
|
||
|
"closePosition": true,
|
||
|
"createOrder": true,
|
||
|
"createReduceOnlyOrder": true,
|
||
|
"createStopOrder": true,
|
||
|
"createTrailingAmountOrder": true,
|
||
|
"createTriggerOrder": true,
|
||
|
"editOrder": true,
|
||
|
"fetchBalance": true,
|
||
|
"fetchClosedOrders": true,
|
||
|
"fetchCurrencies": true,
|
||
|
"fetchDepositAddress": true,
|
||
|
"fetchDepositAddresses": false,
|
||
|
"fetchDepositAddressesByNetwork": false,
|
||
|
"fetchDepositsWithdrawals": "emulated",
|
||
|
"fetchDepositWithdrawFee": "emulated",
|
||
|
"fetchDepositWithdrawFees": true,
|
||
|
"fetchFundingHistory": false,
|
||
|
"fetchFundingRate": "emulated",
|
||
|
"fetchFundingRateHistory": true,
|
||
|
"fetchFundingRates": true,
|
||
|
"fetchIndexOHLCV": false,
|
||
|
"fetchLedger": true,
|
||
|
"fetchLeverage": "emulated",
|
||
|
"fetchLeverages": true,
|
||
|
"fetchLeverageTiers": false,
|
||
|
"fetchLiquidations": true,
|
||
|
"fetchMarginAdjustmentHistory": false,
|
||
|
"fetchMarketLeverageTiers": false,
|
||
|
"fetchMarkets": true,
|
||
|
"fetchMarkOHLCV": false,
|
||
|
"fetchMyLiquidations": false,
|
||
|
"fetchMyTrades": true,
|
||
|
"fetchOHLCV": true,
|
||
|
"fetchOpenOrders": true,
|
||
|
"fetchOrder": true,
|
||
|
"fetchOrderBook": true,
|
||
|
"fetchOrders": true,
|
||
|
"fetchPosition": false,
|
||
|
"fetchPositionHistory": false,
|
||
|
"fetchPositions": true,
|
||
|
"fetchPositionsHistory": false,
|
||
|
"fetchPositionsRisk": false,
|
||
|
"fetchPremiumIndexOHLCV": false,
|
||
|
"fetchTicker": true,
|
||
|
"fetchTickers": true,
|
||
|
"fetchTrades": true,
|
||
|
"fetchTransactions": "emulated",
|
||
|
"fetchTransfer": false,
|
||
|
"fetchTransfers": false,
|
||
|
"reduceMargin": nil,
|
||
|
"sandbox": true,
|
||
|
"setLeverage": true,
|
||
|
"setMargin": nil,
|
||
|
"setMarginMode": true,
|
||
|
"setPositionMode": false,
|
||
|
"transfer": false,
|
||
|
"withdraw": true,
|
||
|
},
|
||
|
"timeframes": map[string]interface{} {
|
||
|
"1m": "1m",
|
||
|
"5m": "5m",
|
||
|
"1h": "1h",
|
||
|
"1d": "1d",
|
||
|
},
|
||
|
"urls": map[string]interface{} {
|
||
|
"test": map[string]interface{} {
|
||
|
"public": "https://testnet.bitmex.com",
|
||
|
"private": "https://testnet.bitmex.com",
|
||
|
},
|
||
|
"logo": "https://github.com/user-attachments/assets/c78425ab-78d5-49d6-bd14-db7734798f04",
|
||
|
"api": map[string]interface{} {
|
||
|
"public": "https://www.bitmex.com",
|
||
|
"private": "https://www.bitmex.com",
|
||
|
},
|
||
|
"www": "https://www.bitmex.com",
|
||
|
"doc": []interface{}{"https://www.bitmex.com/app/apiOverview", "https://github.com/BitMEX/api-connectors/tree/master/official-http"},
|
||
|
"fees": "https://www.bitmex.com/app/fees",
|
||
|
"referral": map[string]interface{} {
|
||
|
"url": "https://www.bitmex.com/app/register/NZTR1q",
|
||
|
"discount": 0.1,
|
||
|
},
|
||
|
},
|
||
|
"api": map[string]interface{} {
|
||
|
"public": map[string]interface{} {
|
||
|
"get": map[string]interface{} {
|
||
|
"announcement": 5,
|
||
|
"announcement/urgent": 5,
|
||
|
"chat": 5,
|
||
|
"chat/channels": 5,
|
||
|
"chat/connected": 5,
|
||
|
"chat/pinned": 5,
|
||
|
"funding": 5,
|
||
|
"guild": 5,
|
||
|
"instrument": 5,
|
||
|
"instrument/active": 5,
|
||
|
"instrument/activeAndIndices": 5,
|
||
|
"instrument/activeIntervals": 5,
|
||
|
"instrument/compositeIndex": 5,
|
||
|
"instrument/indices": 5,
|
||
|
"instrument/usdVolume": 5,
|
||
|
"insurance": 5,
|
||
|
"leaderboard": 5,
|
||
|
"liquidation": 5,
|
||
|
"orderBook/L2": 5,
|
||
|
"porl/nonce": 5,
|
||
|
"quote": 5,
|
||
|
"quote/bucketed": 5,
|
||
|
"schema": 5,
|
||
|
"schema/websocketHelp": 5,
|
||
|
"settlement": 5,
|
||
|
"stats": 5,
|
||
|
"stats/history": 5,
|
||
|
"stats/historyUSD": 5,
|
||
|
"trade": 5,
|
||
|
"trade/bucketed": 5,
|
||
|
"wallet/assets": 5,
|
||
|
"wallet/networks": 5,
|
||
|
},
|
||
|
},
|
||
|
"private": map[string]interface{} {
|
||
|
"get": map[string]interface{} {
|
||
|
"address": 5,
|
||
|
"apiKey": 5,
|
||
|
"execution": 5,
|
||
|
"execution/tradeHistory": 5,
|
||
|
"globalNotification": 5,
|
||
|
"leaderboard/name": 5,
|
||
|
"order": 5,
|
||
|
"porl/snapshots": 5,
|
||
|
"position": 5,
|
||
|
"user": 5,
|
||
|
"user/affiliateStatus": 5,
|
||
|
"user/checkReferralCode": 5,
|
||
|
"user/commission": 5,
|
||
|
"user/csa": 5,
|
||
|
"user/depositAddress": 5,
|
||
|
"user/executionHistory": 5,
|
||
|
"user/getWalletTransferAccounts": 5,
|
||
|
"user/margin": 5,
|
||
|
"user/quoteFillRatio": 5,
|
||
|
"user/quoteValueRatio": 5,
|
||
|
"user/staking": 5,
|
||
|
"user/staking/instruments": 5,
|
||
|
"user/staking/tiers": 5,
|
||
|
"user/tradingVolume": 5,
|
||
|
"user/unstakingRequests": 5,
|
||
|
"user/wallet": 5,
|
||
|
"user/walletHistory": 5,
|
||
|
"user/walletSummary": 5,
|
||
|
"userAffiliates": 5,
|
||
|
"userEvent": 5,
|
||
|
},
|
||
|
"post": map[string]interface{} {
|
||
|
"address": 5,
|
||
|
"chat": 5,
|
||
|
"guild": 5,
|
||
|
"guild/archive": 5,
|
||
|
"guild/join": 5,
|
||
|
"guild/kick": 5,
|
||
|
"guild/leave": 5,
|
||
|
"guild/sharesTrades": 5,
|
||
|
"order": 1,
|
||
|
"order/cancelAllAfter": 5,
|
||
|
"order/closePosition": 5,
|
||
|
"position/isolate": 1,
|
||
|
"position/leverage": 1,
|
||
|
"position/riskLimit": 5,
|
||
|
"position/transferMargin": 1,
|
||
|
"user/addSubaccount": 5,
|
||
|
"user/cancelWithdrawal": 5,
|
||
|
"user/communicationToken": 5,
|
||
|
"user/confirmEmail": 5,
|
||
|
"user/confirmWithdrawal": 5,
|
||
|
"user/logout": 5,
|
||
|
"user/preferences": 5,
|
||
|
"user/requestWithdrawal": 5,
|
||
|
"user/unstakingRequests": 5,
|
||
|
"user/updateSubaccount": 5,
|
||
|
"user/walletTransfer": 5,
|
||
|
},
|
||
|
"put": map[string]interface{} {
|
||
|
"guild": 5,
|
||
|
"order": 1,
|
||
|
},
|
||
|
"delete": map[string]interface{} {
|
||
|
"order": 1,
|
||
|
"order/all": 1,
|
||
|
"user/unstakingRequests": 5,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"exceptions": map[string]interface{} {
|
||
|
"exact": map[string]interface{} {
|
||
|
"Invalid API Key.": AuthenticationError,
|
||
|
"This key is disabled.": PermissionDenied,
|
||
|
"Access Denied": PermissionDenied,
|
||
|
"Duplicate clOrdID": InvalidOrder,
|
||
|
"orderQty is invalid": InvalidOrder,
|
||
|
"Invalid price": InvalidOrder,
|
||
|
"Invalid stopPx for ordType": InvalidOrder,
|
||
|
"Account is restricted": PermissionDenied,
|
||
|
},
|
||
|
"broad": map[string]interface{} {
|
||
|
"Signature not valid": AuthenticationError,
|
||
|
"overloaded": ExchangeNotAvailable,
|
||
|
"Account has insufficient Available Balance": InsufficientFunds,
|
||
|
"Service unavailable": ExchangeNotAvailable,
|
||
|
"Server Error": ExchangeError,
|
||
|
"Unable to cancel order due to existing state": InvalidOrder,
|
||
|
"We require all new traders to verify": PermissionDenied,
|
||
|
},
|
||
|
},
|
||
|
"precisionMode": TICK_SIZE,
|
||
|
"options": map[string]interface{} {
|
||
|
"api-expires": 5,
|
||
|
"fetchOHLCVOpenTimestamp": true,
|
||
|
"oldPrecision": false,
|
||
|
"networks": map[string]interface{} {
|
||
|
"BTC": "btc",
|
||
|
"ERC20": "eth",
|
||
|
"BEP20": "bsc",
|
||
|
"TRC20": "tron",
|
||
|
"AVAXC": "avax",
|
||
|
"NEAR": "near",
|
||
|
"XTZ": "xtz",
|
||
|
"DOT": "dot",
|
||
|
"SOL": "sol",
|
||
|
"ADA": "ada",
|
||
|
},
|
||
|
},
|
||
|
"features": map[string]interface{} {
|
||
|
"default": map[string]interface{} {
|
||
|
"sandbox": true,
|
||
|
"createOrder": map[string]interface{} {
|
||
|
"marginMode": true,
|
||
|
"triggerPrice": true,
|
||
|
"triggerPriceType": map[string]interface{} {
|
||
|
"last": true,
|
||
|
"mark": true,
|
||
|
},
|
||
|
"triggerDirection": true,
|
||
|
"stopLossPrice": false,
|
||
|
"takeProfitPrice": false,
|
||
|
"attachedStopLossTakeProfit": nil,
|
||
|
"timeInForce": map[string]interface{} {
|
||
|
"IOC": true,
|
||
|
"FOK": true,
|
||
|
"PO": true,
|
||
|
"GTD": false,
|
||
|
},
|
||
|
"hedged": false,
|
||
|
"trailing": true,
|
||
|
"marketBuyRequiresPrice": false,
|
||
|
"marketBuyByCost": false,
|
||
|
},
|
||
|
"createOrders": nil,
|
||
|
"fetchMyTrades": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"limit": 500,
|
||
|
"daysBack": nil,
|
||
|
"untilDays": 1000000,
|
||
|
"symbolRequired": false,
|
||
|
},
|
||
|
"fetchOrder": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"trigger": false,
|
||
|
"trailing": false,
|
||
|
"symbolRequired": false,
|
||
|
},
|
||
|
"fetchOpenOrders": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"limit": 500,
|
||
|
"trigger": false,
|
||
|
"trailing": false,
|
||
|
"symbolRequired": false,
|
||
|
},
|
||
|
"fetchOrders": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"limit": 500,
|
||
|
"daysBack": nil,
|
||
|
"untilDays": 1000000,
|
||
|
"trigger": false,
|
||
|
"trailing": false,
|
||
|
"symbolRequired": false,
|
||
|
},
|
||
|
"fetchClosedOrders": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"limit": 500,
|
||
|
"daysBack": nil,
|
||
|
"daysBackCanceled": nil,
|
||
|
"untilDays": 1000000,
|
||
|
"trigger": false,
|
||
|
"trailing": false,
|
||
|
"symbolRequired": false,
|
||
|
},
|
||
|
"fetchOHLCV": map[string]interface{} {
|
||
|
"limit": 10000,
|
||
|
},
|
||
|
},
|
||
|
"spot": map[string]interface{} {
|
||
|
"extends": "default",
|
||
|
"createOrder": map[string]interface{} {
|
||
|
"triggerPriceType": map[string]interface{} {
|
||
|
"index": false,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"derivatives": map[string]interface{} {
|
||
|
"extends": "default",
|
||
|
"createOrder": map[string]interface{} {
|
||
|
"triggerPriceType": map[string]interface{} {
|
||
|
"index": true,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"swap": map[string]interface{} {
|
||
|
"linear": map[string]interface{} {
|
||
|
"extends": "derivatives",
|
||
|
},
|
||
|
"inverse": map[string]interface{} {
|
||
|
"extends": "derivatives",
|
||
|
},
|
||
|
},
|
||
|
"future": map[string]interface{} {
|
||
|
"linear": map[string]interface{} {
|
||
|
"extends": "derivatives",
|
||
|
},
|
||
|
"inverse": map[string]interface{} {
|
||
|
"extends": "derivatives",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"commonCurrencies": map[string]interface{} {
|
||
|
"USDt": "USDT",
|
||
|
"XBt": "BTC",
|
||
|
"XBT": "BTC",
|
||
|
"Gwei": "ETH",
|
||
|
"GWEI": "ETH",
|
||
|
"LAMP": "SOL",
|
||
|
"LAMp": "SOL",
|
||
|
},
|
||
|
})
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchCurrencies
|
||
|
* @description fetches all available currencies on an exchange
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Wallet/Wallet_getAssetsConfig
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object} an associative dictionary of currencies
|
||
|
*/
|
||
|
func (this *bitmex) 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.PublicGetWalletAssets(params))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "XBt": {
|
||
|
// "asset": "XBT",
|
||
|
// "currency": "XBt",
|
||
|
// "majorCurrency": "XBT",
|
||
|
// "name": "Bitcoin",
|
||
|
// "currencyType": "Crypto",
|
||
|
// "scale": "8",
|
||
|
// // "mediumPrecision": "8",
|
||
|
// // "shorterPrecision": "4",
|
||
|
// // "symbol": "₿",
|
||
|
// // "weight": "1",
|
||
|
// // "tickLog": "0",
|
||
|
// "enabled": true,
|
||
|
// "isMarginCurrency": true,
|
||
|
// "minDepositAmount": "10000",
|
||
|
// "minWithdrawalAmount": "1000",
|
||
|
// "maxWithdrawalAmount": "100000000000000",
|
||
|
// "networks": [
|
||
|
// {
|
||
|
// "asset": "btc",
|
||
|
// "tokenAddress": "",
|
||
|
// "depositEnabled": true,
|
||
|
// "withdrawalEnabled": true,
|
||
|
// "withdrawalFee": "20000",
|
||
|
// "minFee": "20000",
|
||
|
// "maxFee": "10000000"
|
||
|
// }
|
||
|
// ]
|
||
|
// },
|
||
|
// }
|
||
|
//
|
||
|
var result interface{} = map[string]interface{} {}
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(response)); i++ {
|
||
|
var currency interface{} = GetValue(response, i)
|
||
|
var asset interface{} = this.SafeString(currency, "asset")
|
||
|
var code interface{} = this.SafeCurrencyCode(asset)
|
||
|
var id interface{} = this.SafeString(currency, "currency")
|
||
|
var name interface{} = this.SafeString(currency, "name")
|
||
|
var chains interface{} = this.SafeValue(currency, "networks", []interface{}{})
|
||
|
var depositEnabled interface{} = false
|
||
|
var withdrawEnabled interface{} = false
|
||
|
var networks interface{} = map[string]interface{} {}
|
||
|
var scale interface{} = this.SafeString(currency, "scale")
|
||
|
var precisionString interface{} = this.ParsePrecision(scale)
|
||
|
var precision interface{} = this.ParseNumber(precisionString)
|
||
|
for j := 0; IsLessThan(j, GetArrayLength(chains)); j++ {
|
||
|
var chain interface{} = GetValue(chains, j)
|
||
|
var networkId interface{} = this.SafeString(chain, "asset")
|
||
|
var network interface{} = this.NetworkIdToCode(networkId)
|
||
|
var withdrawalFeeRaw interface{} = this.SafeString(chain, "withdrawalFee")
|
||
|
var withdrawalFee interface{} = this.ParseNumber(Precise.StringMul(withdrawalFeeRaw, precisionString))
|
||
|
var isDepositEnabled interface{} = this.SafeBool(chain, "depositEnabled", false)
|
||
|
var isWithdrawEnabled interface{} = this.SafeBool(chain, "withdrawalEnabled", false)
|
||
|
var active interface{} = (IsTrue(isDepositEnabled) && IsTrue(isWithdrawEnabled))
|
||
|
if IsTrue(isDepositEnabled) {
|
||
|
depositEnabled = true
|
||
|
}
|
||
|
if IsTrue(isWithdrawEnabled) {
|
||
|
withdrawEnabled = true
|
||
|
}
|
||
|
AddElementToObject(networks, network, map[string]interface{} {
|
||
|
"info": chain,
|
||
|
"id": networkId,
|
||
|
"network": network,
|
||
|
"active": active,
|
||
|
"deposit": isDepositEnabled,
|
||
|
"withdraw": isWithdrawEnabled,
|
||
|
"fee": withdrawalFee,
|
||
|
"precision": nil,
|
||
|
"limits": map[string]interface{} {
|
||
|
"withdraw": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": nil,
|
||
|
},
|
||
|
"deposit": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": nil,
|
||
|
},
|
||
|
},
|
||
|
})
|
||
|
}
|
||
|
var currencyEnabled interface{} = this.SafeValue(currency, "enabled")
|
||
|
var currencyActive interface{} = IsTrue(currencyEnabled) || IsTrue((IsTrue(depositEnabled) || IsTrue(withdrawEnabled)))
|
||
|
var minWithdrawalString interface{} = this.SafeString(currency, "minWithdrawalAmount")
|
||
|
var minWithdrawal interface{} = this.ParseNumber(Precise.StringMul(minWithdrawalString, precisionString))
|
||
|
var maxWithdrawalString interface{} = this.SafeString(currency, "maxWithdrawalAmount")
|
||
|
var maxWithdrawal interface{} = this.ParseNumber(Precise.StringMul(maxWithdrawalString, precisionString))
|
||
|
var minDepositString interface{} = this.SafeString(currency, "minDepositAmount")
|
||
|
var minDeposit interface{} = this.ParseNumber(Precise.StringMul(minDepositString, precisionString))
|
||
|
AddElementToObject(result, code, map[string]interface{} {
|
||
|
"id": id,
|
||
|
"code": code,
|
||
|
"info": currency,
|
||
|
"name": name,
|
||
|
"active": currencyActive,
|
||
|
"deposit": depositEnabled,
|
||
|
"withdraw": withdrawEnabled,
|
||
|
"fee": nil,
|
||
|
"precision": precision,
|
||
|
"limits": map[string]interface{} {
|
||
|
"amount": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": nil,
|
||
|
},
|
||
|
"withdraw": map[string]interface{} {
|
||
|
"min": minWithdrawal,
|
||
|
"max": maxWithdrawal,
|
||
|
},
|
||
|
"deposit": map[string]interface{} {
|
||
|
"min": minDeposit,
|
||
|
"max": nil,
|
||
|
},
|
||
|
},
|
||
|
"networks": networks,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
ch <- result
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ConvertFromRealAmount(code interface{}, amount interface{}) interface{} {
|
||
|
var currency interface{} = this.Currency(code)
|
||
|
var precision interface{} = this.SafeString(currency, "precision")
|
||
|
var amountString interface{} = this.NumberToString(amount)
|
||
|
var finalAmount interface{} = Precise.StringDiv(amountString, precision)
|
||
|
return this.ParseNumber(finalAmount)
|
||
|
}
|
||
|
func (this *bitmex) ConvertToRealAmount(code interface{}, amount interface{}) interface{} {
|
||
|
if IsTrue(IsEqual(code, nil)) {
|
||
|
return amount
|
||
|
} else if IsTrue(IsEqual(amount, nil)) {
|
||
|
return nil
|
||
|
}
|
||
|
var currency interface{} = this.Currency(code)
|
||
|
var precision interface{} = this.SafeString(currency, "precision")
|
||
|
return Precise.StringMul(amount, precision)
|
||
|
}
|
||
|
func (this *bitmex) AmountToPrecision(symbol interface{}, amount interface{}) interface{} {
|
||
|
symbol = this.SafeSymbol(symbol)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var oldPrecision interface{} = this.SafeValue(this.Options, "oldPrecision")
|
||
|
if IsTrue(IsTrue(GetValue(market, "spot")) && !IsTrue(oldPrecision)) {
|
||
|
amount = this.ConvertFromRealAmount(GetValue(market, "base"), amount)
|
||
|
}
|
||
|
return this.Exchange.AmountToPrecision(symbol, amount)
|
||
|
}
|
||
|
func (this *bitmex) ConvertFromRawQuantity(symbol interface{}, rawQuantity interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
currencySide := GetArg(optionalArgs, 0, "base")
|
||
|
_ = currencySide
|
||
|
if IsTrue(this.SafeValue(this.Options, "oldPrecision")) {
|
||
|
return this.ParseNumber(rawQuantity)
|
||
|
}
|
||
|
symbol = this.SafeSymbol(symbol)
|
||
|
var marketExists interface{} = this.InArray(symbol, this.Symbols)
|
||
|
if !IsTrue(marketExists) {
|
||
|
return this.ParseNumber(rawQuantity)
|
||
|
}
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
if IsTrue(GetValue(market, "spot")) {
|
||
|
return this.ParseNumber(this.ConvertToRealAmount(GetValue(market, currencySide), rawQuantity))
|
||
|
}
|
||
|
return this.ParseNumber(rawQuantity)
|
||
|
}
|
||
|
func (this *bitmex) ConvertFromRawCost(symbol interface{}, rawQuantity interface{}) interface{} {
|
||
|
return this.ConvertFromRawQuantity(symbol, rawQuantity, "quote")
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchMarkets
|
||
|
* @description retrieves data on all markets for bitmex
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Instrument/Instrument_getActive
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object[]} an array of objects representing market data
|
||
|
*/
|
||
|
func (this *bitmex) 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
|
||
|
|
||
|
response:= (<-this.PublicGetInstrumentActive(params))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// [
|
||
|
// {
|
||
|
// "symbol": "LTCUSDT",
|
||
|
// "rootSymbol": "LTC",
|
||
|
// "state": "Open",
|
||
|
// "typ": "FFWCSX",
|
||
|
// "listing": "2021-11-10T04:00:00.000Z",
|
||
|
// "front": "2021-11-10T04:00:00.000Z",
|
||
|
// "expiry": null,
|
||
|
// "settle": null,
|
||
|
// "listedSettle": null,
|
||
|
// "relistInterval": null,
|
||
|
// "inverseLeg": "",
|
||
|
// "sellLeg": "",
|
||
|
// "buyLeg": "",
|
||
|
// "optionStrikePcnt": null,
|
||
|
// "optionStrikeRound": null,
|
||
|
// "optionStrikePrice": null,
|
||
|
// "optionMultiplier": null,
|
||
|
// "positionCurrency": "LTC", // can be empty for spot markets
|
||
|
// "underlying": "LTC",
|
||
|
// "quoteCurrency": "USDT",
|
||
|
// "underlyingSymbol": "LTCT=", // can be empty for spot markets
|
||
|
// "reference": "BMEX",
|
||
|
// "referenceSymbol": ".BLTCT", // can be empty for spot markets
|
||
|
// "calcInterval": null,
|
||
|
// "publishInterval": null,
|
||
|
// "publishTime": null,
|
||
|
// "maxOrderQty": 1000000000,
|
||
|
// "maxPrice": 1000000,
|
||
|
// "lotSize": 1000,
|
||
|
// "tickSize": 0.01,
|
||
|
// "multiplier": 100,
|
||
|
// "settlCurrency": "USDt", // can be empty for spot markets
|
||
|
// "underlyingToPositionMultiplier": 10000,
|
||
|
// "underlyingToSettleMultiplier": null,
|
||
|
// "quoteToSettleMultiplier": 1000000,
|
||
|
// "isQuanto": false,
|
||
|
// "isInverse": false,
|
||
|
// "initMargin": 0.03,
|
||
|
// "maintMargin": 0.015,
|
||
|
// "riskLimit": 1000000000000, // can be null for spot markets
|
||
|
// "riskStep": 1000000000000, // can be null for spot markets
|
||
|
// "limit": null,
|
||
|
// "capped": false,
|
||
|
// "taxed": true,
|
||
|
// "deleverage": true,
|
||
|
// "makerFee": -0.0001,
|
||
|
// "takerFee": 0.0005,
|
||
|
// "settlementFee": 0,
|
||
|
// "insuranceFee": 0,
|
||
|
// "fundingBaseSymbol": ".LTCBON8H", // can be empty for spot markets
|
||
|
// "fundingQuoteSymbol": ".USDTBON8H", // can be empty for spot markets
|
||
|
// "fundingPremiumSymbol": ".LTCUSDTPI8H", // can be empty for spot markets
|
||
|
// "fundingTimestamp": "2022-01-14T20:00:00.000Z",
|
||
|
// "fundingInterval": "2000-01-01T08:00:00.000Z",
|
||
|
// "fundingRate": 0.0001,
|
||
|
// "indicativeFundingRate": 0.0001,
|
||
|
// "rebalanceTimestamp": null,
|
||
|
// "rebalanceInterval": null,
|
||
|
// "openingTimestamp": "2022-01-14T17:00:00.000Z",
|
||
|
// "closingTimestamp": "2022-01-14T18:00:00.000Z",
|
||
|
// "sessionInterval": "2000-01-01T01:00:00.000Z",
|
||
|
// "prevClosePrice": 138.511,
|
||
|
// "limitDownPrice": null,
|
||
|
// "limitUpPrice": null,
|
||
|
// "bankruptLimitDownPrice": null,
|
||
|
// "bankruptLimitUpPrice": null,
|
||
|
// "prevTotalVolume": 12699024000,
|
||
|
// "totalVolume": 12702160000,
|
||
|
// "volume": 3136000,
|
||
|
// "volume24h": 114251000,
|
||
|
// "prevTotalTurnover": 232418052349000,
|
||
|
// "totalTurnover": 232463353260000,
|
||
|
// "turnover": 45300911000,
|
||
|
// "turnover24h": 1604331340000,
|
||
|
// "homeNotional24h": 11425.1,
|
||
|
// "foreignNotional24h": 1604331.3400000003,
|
||
|
// "prevPrice24h": 135.48,
|
||
|
// "vwap": 140.42165,
|
||
|
// "highPrice": 146.42,
|
||
|
// "lowPrice": 135.08,
|
||
|
// "lastPrice": 144.36,
|
||
|
// "lastPriceProtected": 144.36,
|
||
|
// "lastTickDirection": "MinusTick",
|
||
|
// "lastChangePcnt": 0.0655,
|
||
|
// "bidPrice": 143.75,
|
||
|
// "midPrice": 143.855,
|
||
|
// "askPrice": 143.96,
|
||
|
// "impactBidPrice": 143.75,
|
||
|
// "impactMidPrice": 143.855,
|
||
|
// "impactAskPrice": 143.96,
|
||
|
// "hasLiquidity": true,
|
||
|
// "openInterest": 38103000,
|
||
|
// "openValue": 547963053300,
|
||
|
// "fairMethod": "FundingRate",
|
||
|
// "fairBasisRate": 0.1095,
|
||
|
// "fairBasis": 0.004,
|
||
|
// "fairPrice": 143.811,
|
||
|
// "markMethod": "FairPrice",
|
||
|
// "markPrice": 143.811,
|
||
|
// "indicativeTaxRate": null,
|
||
|
// "indicativeSettlePrice": 143.807,
|
||
|
// "optionUnderlyingPrice": null,
|
||
|
// "settledPriceAdjustmentRate": null,
|
||
|
// "settledPrice": null,
|
||
|
// "timestamp": "2022-01-14T17:49:55.000Z"
|
||
|
// }
|
||
|
// ]
|
||
|
//
|
||
|
ch <- this.ParseMarkets(response)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ParseMarket(market interface{}) interface{} {
|
||
|
var id interface{} = this.SafeString(market, "symbol")
|
||
|
var baseId interface{} = this.SafeString(market, "underlying")
|
||
|
var quoteId interface{} = this.SafeString(market, "quoteCurrency")
|
||
|
var settleId interface{} = this.SafeString(market, "settlCurrency")
|
||
|
var settle interface{} = this.SafeCurrencyCode(settleId)
|
||
|
// 'positionCurrency' may be empty ("", as Bitmex currently returns for ETHUSD)
|
||
|
// so let's take the settlCurrency first and then adjust if needed
|
||
|
var typ interface{} = this.SafeString(market, "typ") // type definitions at: https://www.bitmex.com/api/explorer/#!/Instrument/Instrument_get
|
||
|
var typeVar interface{} = nil
|
||
|
var swap interface{} = false
|
||
|
var spot interface{} = false
|
||
|
var future interface{} = false
|
||
|
if IsTrue(IsEqual(typ, "FFWCSX")) {
|
||
|
typeVar = "swap"
|
||
|
swap = true
|
||
|
} else if IsTrue(IsEqual(typ, "IFXXXP")) {
|
||
|
typeVar = "spot"
|
||
|
spot = true
|
||
|
} else if IsTrue(IsEqual(typ, "FFCCSX")) {
|
||
|
typeVar = "future"
|
||
|
future = true
|
||
|
} else if IsTrue(IsEqual(typ, "FFICSX")) {
|
||
|
// prediction markets (without any volume)
|
||
|
quoteId = baseId
|
||
|
baseId = this.SafeString(market, "rootSymbol")
|
||
|
typeVar = "future"
|
||
|
future = true
|
||
|
}
|
||
|
var base interface{} = this.SafeCurrencyCode(baseId)
|
||
|
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
||
|
var contract interface{} = IsTrue(swap) || IsTrue(future)
|
||
|
var contractSize interface{} = nil
|
||
|
var isInverse interface{} = this.SafeValue(market, "isInverse") // this is true when BASE and SETTLE are same, i.e. BTC/XXX:BTC
|
||
|
var isQuanto interface{} = this.SafeValue(market, "isQuanto") // this is true when BASE and SETTLE are different, i.e. AXS/XXX:BTC
|
||
|
var linear interface{} = Ternary(IsTrue(contract), (!IsTrue(isInverse) && !IsTrue(isQuanto)), nil)
|
||
|
var status interface{} = this.SafeString(market, "state")
|
||
|
var active interface{} = !IsEqual(status, "Unlisted")
|
||
|
var expiry interface{} = nil
|
||
|
var expiryDatetime interface{} = nil
|
||
|
var symbol interface{} = nil
|
||
|
if IsTrue(spot) {
|
||
|
symbol = Add(Add(base, "/"), quote)
|
||
|
} else if IsTrue(contract) {
|
||
|
symbol = Add(Add(Add(Add(base, "/"), quote), ":"), settle)
|
||
|
if IsTrue(linear) {
|
||
|
var multiplierString interface{} = this.SafeString2(market, "underlyingToPositionMultiplier", "underlyingToSettleMultiplier")
|
||
|
contractSize = this.ParseNumber(Precise.StringDiv("1", multiplierString))
|
||
|
} else {
|
||
|
var multiplierString interface{} = Precise.StringAbs(this.SafeString(market, "multiplier"))
|
||
|
contractSize = this.ParseNumber(multiplierString)
|
||
|
}
|
||
|
if IsTrue(future) {
|
||
|
expiryDatetime = this.SafeString(market, "expiry")
|
||
|
expiry = this.Parse8601(expiryDatetime)
|
||
|
symbol = Add(Add(symbol, "-"), this.Yymmdd(expiry))
|
||
|
}
|
||
|
} else {
|
||
|
// for index/exotic markets, default to id
|
||
|
symbol = id
|
||
|
}
|
||
|
var positionId interface{} = this.SafeString2(market, "positionCurrency", "underlying")
|
||
|
var position interface{} = this.SafeCurrencyCode(positionId)
|
||
|
var positionIsQuote interface{} = (IsEqual(position, quote))
|
||
|
var maxOrderQty interface{} = this.SafeNumber(market, "maxOrderQty")
|
||
|
var initMargin interface{} = this.SafeString(market, "initMargin", "1")
|
||
|
var maxLeverage interface{} = this.ParseNumber(Precise.StringDiv("1", initMargin))
|
||
|
return map[string]interface{} {
|
||
|
"id": id,
|
||
|
"symbol": symbol,
|
||
|
"base": base,
|
||
|
"quote": quote,
|
||
|
"settle": settle,
|
||
|
"baseId": baseId,
|
||
|
"quoteId": quoteId,
|
||
|
"settleId": settleId,
|
||
|
"type": typeVar,
|
||
|
"spot": spot,
|
||
|
"margin": false,
|
||
|
"swap": swap,
|
||
|
"future": future,
|
||
|
"option": false,
|
||
|
"active": active,
|
||
|
"contract": contract,
|
||
|
"linear": linear,
|
||
|
"inverse": isInverse,
|
||
|
"quanto": isQuanto,
|
||
|
"taker": this.SafeNumber(market, "takerFee"),
|
||
|
"maker": this.SafeNumber(market, "makerFee"),
|
||
|
"contractSize": contractSize,
|
||
|
"expiry": expiry,
|
||
|
"expiryDatetime": expiryDatetime,
|
||
|
"strike": this.SafeNumber(market, "optionStrikePrice"),
|
||
|
"optionType": nil,
|
||
|
"precision": map[string]interface{} {
|
||
|
"amount": this.SafeNumber(market, "lotSize"),
|
||
|
"price": this.SafeNumber(market, "tickSize"),
|
||
|
},
|
||
|
"limits": map[string]interface{} {
|
||
|
"leverage": map[string]interface{} {
|
||
|
"min": Ternary(IsTrue(contract), this.ParseNumber("1"), nil),
|
||
|
"max": Ternary(IsTrue(contract), maxLeverage, nil),
|
||
|
},
|
||
|
"amount": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": Ternary(IsTrue(positionIsQuote), nil, maxOrderQty),
|
||
|
},
|
||
|
"price": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": this.SafeNumber(market, "maxPrice"),
|
||
|
},
|
||
|
"cost": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": Ternary(IsTrue(positionIsQuote), maxOrderQty, nil),
|
||
|
},
|
||
|
},
|
||
|
"created": this.Parse8601(this.SafeString(market, "listing")),
|
||
|
"info": market,
|
||
|
}
|
||
|
}
|
||
|
func (this *bitmex) ParseBalance(response interface{}) interface{} {
|
||
|
//
|
||
|
// [
|
||
|
// {
|
||
|
// "account":1455728,
|
||
|
// "currency":"XBt",
|
||
|
// "riskLimit":1000000000000,
|
||
|
// "prevState":"",
|
||
|
// "state":"",
|
||
|
// "action":"",
|
||
|
// "amount":263542,
|
||
|
// "pendingCredit":0,
|
||
|
// "pendingDebit":0,
|
||
|
// "confirmedDebit":0,
|
||
|
// "prevRealisedPnl":0,
|
||
|
// "prevUnrealisedPnl":0,
|
||
|
// "grossComm":0,
|
||
|
// "grossOpenCost":0,
|
||
|
// "grossOpenPremium":0,
|
||
|
// "grossExecCost":0,
|
||
|
// "grossMarkValue":0,
|
||
|
// "riskValue":0,
|
||
|
// "taxableMargin":0,
|
||
|
// "initMargin":0,
|
||
|
// "maintMargin":0,
|
||
|
// "sessionMargin":0,
|
||
|
// "targetExcessMargin":0,
|
||
|
// "varMargin":0,
|
||
|
// "realisedPnl":0,
|
||
|
// "unrealisedPnl":0,
|
||
|
// "indicativeTax":0,
|
||
|
// "unrealisedProfit":0,
|
||
|
// "syntheticMargin":null,
|
||
|
// "walletBalance":263542,
|
||
|
// "marginBalance":263542,
|
||
|
// "marginBalancePcnt":1,
|
||
|
// "marginLeverage":0,
|
||
|
// "marginUsedPcnt":0,
|
||
|
// "excessMargin":263542,
|
||
|
// "excessMarginPcnt":1,
|
||
|
// "availableMargin":263542,
|
||
|
// "withdrawableMargin":263542,
|
||
|
// "timestamp":"2020-08-03T12:01:01.246Z",
|
||
|
// "grossLastValue":0,
|
||
|
// "commission":null
|
||
|
// }
|
||
|
// ]
|
||
|
//
|
||
|
var result interface{} = map[string]interface{} {
|
||
|
"info": response,
|
||
|
}
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(response)); i++ {
|
||
|
var balance interface{} = GetValue(response, i)
|
||
|
var currencyId interface{} = this.SafeString(balance, "currency")
|
||
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
||
|
var account interface{} = this.Account()
|
||
|
var free interface{} = this.SafeString(balance, "availableMargin")
|
||
|
var total interface{} = this.SafeString(balance, "marginBalance")
|
||
|
AddElementToObject(account, "free", this.ConvertToRealAmount(code, free))
|
||
|
AddElementToObject(account, "total", this.ConvertToRealAmount(code, total))
|
||
|
AddElementToObject(result, code, account)
|
||
|
}
|
||
|
return this.SafeBalance(result)
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchBalance
|
||
|
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/User/User_getMargin
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
||
|
*/
|
||
|
func (this *bitmex) 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
|
||
|
|
||
|
retRes8968 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes8968)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"currency": "all",
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivateGetUserMargin(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// [
|
||
|
// {
|
||
|
// "account":1455728,
|
||
|
// "currency":"XBt",
|
||
|
// "riskLimit":1000000000000,
|
||
|
// "prevState":"",
|
||
|
// "state":"",
|
||
|
// "action":"",
|
||
|
// "amount":263542,
|
||
|
// "pendingCredit":0,
|
||
|
// "pendingDebit":0,
|
||
|
// "confirmedDebit":0,
|
||
|
// "prevRealisedPnl":0,
|
||
|
// "prevUnrealisedPnl":0,
|
||
|
// "grossComm":0,
|
||
|
// "grossOpenCost":0,
|
||
|
// "grossOpenPremium":0,
|
||
|
// "grossExecCost":0,
|
||
|
// "grossMarkValue":0,
|
||
|
// "riskValue":0,
|
||
|
// "taxableMargin":0,
|
||
|
// "initMargin":0,
|
||
|
// "maintMargin":0,
|
||
|
// "sessionMargin":0,
|
||
|
// "targetExcessMargin":0,
|
||
|
// "varMargin":0,
|
||
|
// "realisedPnl":0,
|
||
|
// "unrealisedPnl":0,
|
||
|
// "indicativeTax":0,
|
||
|
// "unrealisedProfit":0,
|
||
|
// "syntheticMargin":null,
|
||
|
// "walletBalance":263542,
|
||
|
// "marginBalance":263542,
|
||
|
// "marginBalancePcnt":1,
|
||
|
// "marginLeverage":0,
|
||
|
// "marginUsedPcnt":0,
|
||
|
// "excessMargin":263542,
|
||
|
// "excessMarginPcnt":1,
|
||
|
// "availableMargin":263542,
|
||
|
// "withdrawableMargin":263542,
|
||
|
// "timestamp":"2020-08-03T12:01:01.246Z",
|
||
|
// "grossLastValue":0,
|
||
|
// "commission":null
|
||
|
// }
|
||
|
// ]
|
||
|
//
|
||
|
ch <- this.ParseBalance(response)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchOrderBook
|
||
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/OrderBook/OrderBook_getL2
|
||
|
* @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 *bitmex) 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
|
||
|
|
||
|
retRes9628 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes9628)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"symbol": GetValue(market, "id"),
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "depth", limit)
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetOrderBookL2(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
var result interface{} = map[string]interface{} {
|
||
|
"symbol": symbol,
|
||
|
"bids": []interface{}{},
|
||
|
"asks": []interface{}{},
|
||
|
"timestamp": nil,
|
||
|
"datetime": nil,
|
||
|
"nonce": nil,
|
||
|
}
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(response)); i++ {
|
||
|
var order interface{} = GetValue(response, i)
|
||
|
var side interface{} = Ternary(IsTrue((IsEqual(GetValue(order, "side"), "Sell"))), "asks", "bids")
|
||
|
var amount interface{} = this.ConvertFromRawQuantity(symbol, this.SafeString(order, "size"))
|
||
|
var price interface{} = this.SafeNumber(order, "price")
|
||
|
// https://github.com/ccxt/ccxt/issues/4926
|
||
|
// https://github.com/ccxt/ccxt/issues/4927
|
||
|
// the exchange sometimes returns null price in the orderbook
|
||
|
if IsTrue(!IsEqual(price, nil)) {
|
||
|
var resultSide interface{} = GetValue(result, side)
|
||
|
AppendToArray(&resultSide,[]interface{}{price, amount})
|
||
|
}
|
||
|
}
|
||
|
AddElementToObject(result, "bids", this.SortBy(GetValue(result, "bids"), 0, true))
|
||
|
AddElementToObject(result, "asks", this.SortBy(GetValue(result, "asks"), 0))
|
||
|
|
||
|
ch <- result
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchOrder
|
||
|
* @description fetches information on an order made by the user
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Order/Order_getOrders
|
||
|
* @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 *bitmex) 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
|
||
|
var filter interface{} = map[string]interface{} {
|
||
|
"filter": map[string]interface{} {
|
||
|
"orderID": id,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
response:= (<-this.FetchOrders(symbol, nil, nil, this.DeepExtend(filter, params)))
|
||
|
PanicOnError(response)
|
||
|
var numResults interface{} = GetArrayLength(response)
|
||
|
if IsTrue(IsEqual(numResults, 1)) {
|
||
|
|
||
|
ch <- GetValue(response, 0)
|
||
|
return nil
|
||
|
}
|
||
|
panic(OrderNotFound(Add(Add(Add(this.Id, ": The order "), id), " not found.")))
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchOrders
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Order/Order_getOrders
|
||
|
* @description fetches information on multiple orders made by the user
|
||
|
* @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
|
||
|
* @param {int} [params.until] the earliest time in ms to fetch orders for
|
||
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
|
*/
|
||
|
func (this *bitmex) FetchOrders(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
|
||
|
|
||
|
retRes10358 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes10358)
|
||
|
var paginate interface{} = false
|
||
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOrders", "paginate");
|
||
|
paginate = GetValue(paginateparamsVariable,0);
|
||
|
params = GetValue(paginateparamsVariable,1)
|
||
|
if IsTrue(paginate) {
|
||
|
|
||
|
retRes103919 := (<-this.FetchPaginatedCallDynamic("fetchOrders", symbol, since, limit, params, 100))
|
||
|
PanicOnError(retRes103919)
|
||
|
ch <- retRes103919
|
||
|
return nil
|
||
|
}
|
||
|
var market interface{} = nil
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
if IsTrue(!IsEqual(symbol, nil)) {
|
||
|
market = this.Market(symbol)
|
||
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
||
|
}
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "startTime", this.Iso8601(since))
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "count", limit)
|
||
|
}
|
||
|
var until interface{} = this.SafeInteger2(params, "until", "endTime")
|
||
|
if IsTrue(!IsEqual(until, nil)) {
|
||
|
params = this.Omit(params, []interface{}{"until"})
|
||
|
AddElementToObject(request, "endTime", this.Iso8601(until))
|
||
|
}
|
||
|
request = this.DeepExtend(request, params)
|
||
|
// why the hassle? urlencode in python is kinda broken for nested dicts.
|
||
|
// E.g. self.urlencode({"filter": {"open": True}}) will return "filter={'open':+True}"
|
||
|
// Bitmex doesn't like that. Hence resorting to this hack.
|
||
|
if IsTrue(InOp(request, "filter")) {
|
||
|
AddElementToObject(request, "filter", this.Json(GetValue(request, "filter")))
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivateGetOrder(request))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
ch <- this.ParseOrders(response, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchOpenOrders
|
||
|
* @description fetch all unfilled currently open orders
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Order/Order_getOrders
|
||
|
* @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 orders 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 *bitmex) 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
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"filter": map[string]interface{} {
|
||
|
"open": true,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
retRes108615 := (<-this.FetchOrders(symbol, since, limit, this.DeepExtend(request, params)))
|
||
|
PanicOnError(retRes108615)
|
||
|
ch <- retRes108615
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchClosedOrders
|
||
|
* @description fetches information on multiple closed orders made by the user
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Order/Order_getOrders
|
||
|
* @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 *bitmex) FetchClosedOrders(optionalArgs ...interface{}) <- chan interface{} {
|
||
|
ch := make(chan interface{})
|
||
|
go func() interface{} {
|
||
|
defer close(ch)
|
||
|
defer ReturnPanicError(ch)
|
||
|
// Bitmex barfs if you set 'open': false in the filter...
|
||
|
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
|
||
|
|
||
|
orders:= (<-this.FetchOrders(symbol, since, limit, params))
|
||
|
PanicOnError(orders)
|
||
|
|
||
|
ch <- this.FilterByArray(orders, "status", []interface{}{"closed", "canceled"}, false)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchMyTrades
|
||
|
* @description fetch all trades made by the user
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Execution/Execution_getTradeHistory
|
||
|
* @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
|
||
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
||
|
*/
|
||
|
func (this *bitmex) 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
|
||
|
|
||
|
retRes11198 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes11198)
|
||
|
var paginate interface{} = false
|
||
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchMyTrades", "paginate");
|
||
|
paginate = GetValue(paginateparamsVariable,0);
|
||
|
params = GetValue(paginateparamsVariable,1)
|
||
|
if IsTrue(paginate) {
|
||
|
|
||
|
retRes112319 := (<-this.FetchPaginatedCallDynamic("fetchMyTrades", symbol, since, limit, params, 100))
|
||
|
PanicOnError(retRes112319)
|
||
|
ch <- retRes112319
|
||
|
return nil
|
||
|
}
|
||
|
var market interface{} = nil
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
if IsTrue(!IsEqual(symbol, nil)) {
|
||
|
market = this.Market(symbol)
|
||
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
||
|
}
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "startTime", this.Iso8601(since))
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "count", mathMin(500, limit))
|
||
|
}
|
||
|
var until interface{} = this.SafeInteger2(params, "until", "endTime")
|
||
|
if IsTrue(!IsEqual(until, nil)) {
|
||
|
params = this.Omit(params, []interface{}{"until"})
|
||
|
AddElementToObject(request, "endTime", this.Iso8601(until))
|
||
|
}
|
||
|
request = this.DeepExtend(request, params)
|
||
|
// why the hassle? urlencode in python is kinda broken for nested dicts.
|
||
|
// E.g. self.urlencode({"filter": {"open": True}}) will return "filter={'open':+True}"
|
||
|
// Bitmex doesn't like that. Hence resorting to this hack.
|
||
|
if IsTrue(InOp(request, "filter")) {
|
||
|
AddElementToObject(request, "filter", this.Json(GetValue(request, "filter")))
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivateGetExecutionTradeHistory(request))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// [
|
||
|
// {
|
||
|
// "execID": "string",
|
||
|
// "orderID": "string",
|
||
|
// "clOrdID": "string",
|
||
|
// "clOrdLinkID": "string",
|
||
|
// "account": 0,
|
||
|
// "symbol": "string",
|
||
|
// "side": "string",
|
||
|
// "lastQty": 0,
|
||
|
// "lastPx": 0,
|
||
|
// "underlyingLastPx": 0,
|
||
|
// "lastMkt": "string",
|
||
|
// "lastLiquidityInd": "string",
|
||
|
// "simpleOrderQty": 0,
|
||
|
// "orderQty": 0,
|
||
|
// "price": 0,
|
||
|
// "displayQty": 0,
|
||
|
// "stopPx": 0,
|
||
|
// "pegOffsetValue": 0,
|
||
|
// "pegPriceType": "string",
|
||
|
// "currency": "string",
|
||
|
// "settlCurrency": "string",
|
||
|
// "execType": "string",
|
||
|
// "ordType": "string",
|
||
|
// "timeInForce": "string",
|
||
|
// "execInst": "string",
|
||
|
// "contingencyType": "string",
|
||
|
// "exDestination": "string",
|
||
|
// "ordStatus": "string",
|
||
|
// "triggered": "string",
|
||
|
// "workingIndicator": true,
|
||
|
// "ordRejReason": "string",
|
||
|
// "simpleLeavesQty": 0,
|
||
|
// "leavesQty": 0,
|
||
|
// "simpleCumQty": 0,
|
||
|
// "cumQty": 0,
|
||
|
// "avgPx": 0,
|
||
|
// "commission": 0,
|
||
|
// "tradePublishIndicator": "string",
|
||
|
// "multiLegReportingType": "string",
|
||
|
// "text": "string",
|
||
|
// "trdMatchID": "string",
|
||
|
// "execCost": 0,
|
||
|
// "execComm": 0,
|
||
|
// "homeNotional": 0,
|
||
|
// "foreignNotional": 0,
|
||
|
// "transactTime": "2019-03-05T12:47:02.762Z",
|
||
|
// "timestamp": "2019-03-05T12:47:02.762Z"
|
||
|
// }
|
||
|
// ]
|
||
|
//
|
||
|
ch <- this.ParseTrades(response, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ParseLedgerEntryType(typeVar interface{}) interface{} {
|
||
|
var types interface{} = map[string]interface{} {
|
||
|
"Withdrawal": "transaction",
|
||
|
"RealisedPNL": "margin",
|
||
|
"UnrealisedPNL": "margin",
|
||
|
"Deposit": "transaction",
|
||
|
"Transfer": "transfer",
|
||
|
"AffiliatePayout": "referral",
|
||
|
"SpotTrade": "trade",
|
||
|
}
|
||
|
return this.SafeString(types, typeVar, typeVar)
|
||
|
}
|
||
|
func (this *bitmex) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "transactID": "69573da3-7744-5467-3207-89fd6efe7a47",
|
||
|
// "account": 24321,
|
||
|
// "currency": "XBt",
|
||
|
// "transactType": "Withdrawal", // "AffiliatePayout", "Transfer", "Deposit", "RealisedPNL", ...
|
||
|
// "amount": -1000000,
|
||
|
// "fee": 300000,
|
||
|
// "transactStatus": "Completed", // "Canceled", ...
|
||
|
// "address": "1Ex4fkF4NhQaQdRWNoYpqiPbDBbq18Kdd9",
|
||
|
// "tx": "3BMEX91ZhhKoWtsH9QRb5dNXnmnGpiEetA",
|
||
|
// "text": "",
|
||
|
// "transactTime": "2017-03-21T20:05:14.388Z",
|
||
|
// "walletBalance": 0, // balance after
|
||
|
// "marginBalance": null,
|
||
|
// "timestamp": "2017-03-22T13:09:23.514Z"
|
||
|
// }
|
||
|
//
|
||
|
// ButMEX returns the unrealized pnl from the wallet history endpoint.
|
||
|
// The unrealized pnl transaction has an empty timestamp.
|
||
|
// It is not related to historical pnl it has status set to "Pending".
|
||
|
// Therefore it's not a part of the history at all.
|
||
|
// https://github.com/ccxt/ccxt/issues/6047
|
||
|
//
|
||
|
// {
|
||
|
// "transactID":"00000000-0000-0000-0000-000000000000",
|
||
|
// "account":121210,
|
||
|
// "currency":"XBt",
|
||
|
// "transactType":"UnrealisedPNL",
|
||
|
// "amount":-5508,
|
||
|
// "fee":0,
|
||
|
// "transactStatus":"Pending",
|
||
|
// "address":"XBTUSD",
|
||
|
// "tx":"",
|
||
|
// "text":"",
|
||
|
// "transactTime":null, # ←---------------------------- null
|
||
|
// "walletBalance":139198767,
|
||
|
// "marginBalance":139193259,
|
||
|
// "timestamp":null # ←---------------------------- null
|
||
|
// }
|
||
|
//
|
||
|
currency := GetArg(optionalArgs, 0, nil)
|
||
|
_ = currency
|
||
|
var id interface{} = this.SafeString(item, "transactID")
|
||
|
var account interface{} = this.SafeString(item, "account")
|
||
|
var referenceId interface{} = this.SafeString(item, "tx")
|
||
|
var referenceAccount interface{} = nil
|
||
|
var typeVar interface{} = this.ParseLedgerEntryType(this.SafeString(item, "transactType"))
|
||
|
var currencyId interface{} = this.SafeString(item, "currency")
|
||
|
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
|
||
|
currency = this.SafeCurrency(currencyId, currency)
|
||
|
var amountString interface{} = this.SafeString(item, "amount")
|
||
|
var amount interface{} = this.ConvertToRealAmount(code, amountString)
|
||
|
var timestamp interface{} = this.Parse8601(this.SafeString(item, "transactTime"))
|
||
|
if IsTrue(IsEqual(timestamp, nil)) {
|
||
|
// https://github.com/ccxt/ccxt/issues/6047
|
||
|
// set the timestamp to zero, 1970 Jan 1 00:00:00
|
||
|
// for unrealized pnl and other transactions without a timestamp
|
||
|
timestamp = 0 // see comments above
|
||
|
}
|
||
|
var fee interface{} = nil
|
||
|
var feeCost interface{} = this.SafeString(item, "fee")
|
||
|
if IsTrue(!IsEqual(feeCost, nil)) {
|
||
|
feeCost = this.ConvertToRealAmount(code, feeCost)
|
||
|
fee = map[string]interface{} {
|
||
|
"cost": this.ParseNumber(feeCost),
|
||
|
"currency": code,
|
||
|
}
|
||
|
}
|
||
|
var after interface{} = this.SafeString(item, "walletBalance")
|
||
|
if IsTrue(!IsEqual(after, nil)) {
|
||
|
after = this.ConvertToRealAmount(code, after)
|
||
|
}
|
||
|
var before interface{} = this.ParseNumber(Precise.StringSub(this.NumberToString(after), this.NumberToString(amount)))
|
||
|
var direction interface{} = nil
|
||
|
if IsTrue(Precise.StringLt(amountString, "0")) {
|
||
|
direction = "out"
|
||
|
amount = this.ConvertToRealAmount(code, Precise.StringAbs(amountString))
|
||
|
} else {
|
||
|
direction = "in"
|
||
|
}
|
||
|
var status interface{} = this.ParseTransactionStatus(this.SafeString(item, "transactStatus"))
|
||
|
return this.SafeLedgerEntry(map[string]interface{} {
|
||
|
"info": item,
|
||
|
"id": id,
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"direction": direction,
|
||
|
"account": account,
|
||
|
"referenceId": referenceId,
|
||
|
"referenceAccount": referenceAccount,
|
||
|
"type": typeVar,
|
||
|
"currency": code,
|
||
|
"amount": this.ParseNumber(amount),
|
||
|
"before": before,
|
||
|
"after": this.ParseNumber(after),
|
||
|
"status": status,
|
||
|
"fee": fee,
|
||
|
}, currency)
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchLedger
|
||
|
* @description fetch the history of changes, actions done by the user or operations that altered the balance of the user
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/User/User_getWalletHistory
|
||
|
* @param {string} [code] unified currency code, default is undefined
|
||
|
* @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
|
||
|
* @param {int} [limit] max number of ledger entries to return, default is undefined
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger}
|
||
|
*/
|
||
|
func (this *bitmex) FetchLedger(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
|
||
|
|
||
|
retRes13318 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes13318)
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
//
|
||
|
// if (since !== undefined) {
|
||
|
// // date-based pagination not supported
|
||
|
// }
|
||
|
//
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "count", limit)
|
||
|
}
|
||
|
var currency interface{} = nil
|
||
|
if IsTrue(!IsEqual(code, nil)) {
|
||
|
currency = this.Currency(code)
|
||
|
AddElementToObject(request, "currency", GetValue(currency, "id"))
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivateGetUserWalletHistory(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// [
|
||
|
// {
|
||
|
// "transactID": "69573da3-7744-5467-3207-89fd6efe7a47",
|
||
|
// "account": 24321,
|
||
|
// "currency": "XBt",
|
||
|
// "transactType": "Withdrawal", // "AffiliatePayout", "Transfer", "Deposit", "RealisedPNL", ...
|
||
|
// "amount": -1000000,
|
||
|
// "fee": 300000,
|
||
|
// "transactStatus": "Completed", // "Canceled", ...
|
||
|
// "address": "1Ex4fkF4NhQaQdRWNoYpqiPbDBbq18Kdd9",
|
||
|
// "tx": "3BMEX91ZhhKoWtsH9QRb5dNXnmnGpiEetA",
|
||
|
// "text": "",
|
||
|
// "transactTime": "2017-03-21T20:05:14.388Z",
|
||
|
// "walletBalance": 0, // balance after
|
||
|
// "marginBalance": null,
|
||
|
// "timestamp": "2017-03-22T13:09:23.514Z"
|
||
|
// }
|
||
|
// ]
|
||
|
//
|
||
|
ch <- this.ParseLedger(response, currency, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchDepositsWithdrawals
|
||
|
* @description fetch history of deposits and withdrawals
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/User/User_getWalletHistory
|
||
|
* @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined
|
||
|
* @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
|
||
|
* @param {int} [limit] max number of deposit/withdrawals to return, default is undefined
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
||
|
*/
|
||
|
func (this *bitmex) FetchDepositsWithdrawals(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
|
||
|
|
||
|
retRes13848 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes13848)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"currency": "all",
|
||
|
}
|
||
|
//
|
||
|
// if (since !== undefined) {
|
||
|
// // date-based pagination not supported
|
||
|
// }
|
||
|
//
|
||
|
var currency interface{} = nil
|
||
|
if IsTrue(!IsEqual(code, nil)) {
|
||
|
currency = this.Currency(code)
|
||
|
AddElementToObject(request, "currency", GetValue(currency, "id"))
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "count", limit)
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivateGetUserWalletHistory(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
var transactions interface{} = this.FilterByArray(response, "transactType", []interface{}{"Withdrawal", "Deposit"}, false)
|
||
|
|
||
|
ch <- this.ParseTransactions(transactions, currency, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ParseTransactionStatus(status interface{}) interface{} {
|
||
|
var statuses interface{} = map[string]interface{} {
|
||
|
"Confirmed": "pending",
|
||
|
"Canceled": "canceled",
|
||
|
"Completed": "ok",
|
||
|
"Pending": "pending",
|
||
|
}
|
||
|
return this.SafeString(statuses, status, status)
|
||
|
}
|
||
|
func (this *bitmex) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "transactID": "ffe699c2-95ee-4c13-91f9-0faf41daec25",
|
||
|
// "account": 123456,
|
||
|
// "currency": "XBt",
|
||
|
// "network":'', // "tron" for USDt, etc...
|
||
|
// "transactType": "Withdrawal",
|
||
|
// "amount": -100100000,
|
||
|
// "fee": 100000,
|
||
|
// "transactStatus": "Completed",
|
||
|
// "address": "385cR5DM96n1HvBDMzLHPYcw89fZAXULJP",
|
||
|
// "tx": "3BMEXabcdefghijklmnopqrstuvwxyz123",
|
||
|
// "text": '',
|
||
|
// "transactTime": "2019-01-02T01:00:00.000Z",
|
||
|
// "walletBalance": 99900000, // this field might be inexistent
|
||
|
// "marginBalance": None, // this field might be inexistent
|
||
|
// "timestamp": "2019-01-02T13:00:00.000Z"
|
||
|
// }
|
||
|
//
|
||
|
currency := GetArg(optionalArgs, 0, nil)
|
||
|
_ = currency
|
||
|
var currencyId interface{} = this.SafeString(transaction, "currency")
|
||
|
currency = this.SafeCurrency(currencyId, currency)
|
||
|
// For deposits, transactTime == timestamp
|
||
|
// For withdrawals, transactTime is submission, timestamp is processed
|
||
|
var transactTime interface{} = this.Parse8601(this.SafeString(transaction, "transactTime"))
|
||
|
var timestamp interface{} = this.Parse8601(this.SafeString(transaction, "timestamp"))
|
||
|
var typeVar interface{} = this.SafeStringLower(transaction, "transactType")
|
||
|
// Deposits have no from address or to address, withdrawals have both
|
||
|
var address interface{} = nil
|
||
|
var addressFrom interface{} = nil
|
||
|
var addressTo interface{} = nil
|
||
|
if IsTrue(IsEqual(typeVar, "withdrawal")) {
|
||
|
address = this.SafeString(transaction, "address")
|
||
|
addressFrom = this.SafeString(transaction, "tx")
|
||
|
addressTo = address
|
||
|
} else if IsTrue(IsEqual(typeVar, "deposit")) {
|
||
|
addressTo = this.SafeString(transaction, "address")
|
||
|
addressFrom = this.SafeString(transaction, "tx")
|
||
|
}
|
||
|
var amountString interface{} = this.SafeString(transaction, "amount")
|
||
|
var amountStringAbs interface{} = Precise.StringAbs(amountString)
|
||
|
var amount interface{} = this.ConvertToRealAmount(GetValue(currency, "code"), amountStringAbs)
|
||
|
var feeCostString interface{} = this.SafeString(transaction, "fee")
|
||
|
var feeCost interface{} = this.ConvertToRealAmount(GetValue(currency, "code"), feeCostString)
|
||
|
var status interface{} = this.SafeString(transaction, "transactStatus")
|
||
|
if IsTrue(!IsEqual(status, nil)) {
|
||
|
status = this.ParseTransactionStatus(status)
|
||
|
}
|
||
|
return map[string]interface{} {
|
||
|
"info": transaction,
|
||
|
"id": this.SafeString(transaction, "transactID"),
|
||
|
"txid": this.SafeString(transaction, "tx"),
|
||
|
"type": typeVar,
|
||
|
"currency": GetValue(currency, "code"),
|
||
|
"network": this.NetworkIdToCode(this.SafeString(transaction, "network"), GetValue(currency, "code")),
|
||
|
"amount": this.ParseNumber(amount),
|
||
|
"status": status,
|
||
|
"timestamp": transactTime,
|
||
|
"datetime": this.Iso8601(transactTime),
|
||
|
"address": address,
|
||
|
"addressFrom": addressFrom,
|
||
|
"addressTo": addressTo,
|
||
|
"tag": nil,
|
||
|
"tagFrom": nil,
|
||
|
"tagTo": nil,
|
||
|
"updated": timestamp,
|
||
|
"internal": nil,
|
||
|
"comment": nil,
|
||
|
"fee": map[string]interface{} {
|
||
|
"currency": GetValue(currency, "code"),
|
||
|
"cost": this.ParseNumber(feeCost),
|
||
|
"rate": nil,
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchTicker
|
||
|
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Instrument/Instrument_get
|
||
|
* @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 *bitmex) 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
|
||
|
|
||
|
retRes15038 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes15038)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"symbol": GetValue(market, "id"),
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetInstrument(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
var ticker interface{} = this.SafeValue(response, 0)
|
||
|
if IsTrue(IsEqual(ticker, nil)) {
|
||
|
panic(BadSymbol(Add(Add(Add(this.Id, " fetchTicker() symbol "), symbol), " not found")))
|
||
|
}
|
||
|
|
||
|
ch <- this.ParseTicker(ticker, market)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchTickers
|
||
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Instrument/Instrument_getActiveAndIndices
|
||
|
* @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 *bitmex) 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
|
||
|
|
||
|
retRes15268 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes15268)
|
||
|
symbols = this.MarketSymbols(symbols)
|
||
|
|
||
|
response:= (<-this.PublicGetInstrumentActiveAndIndices(params))
|
||
|
PanicOnError(response)
|
||
|
// same response as under "fetchMarkets"
|
||
|
var result interface{} = map[string]interface{} {}
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(response)); i++ {
|
||
|
var ticker interface{} = this.ParseTicker(GetValue(response, i))
|
||
|
var symbol interface{} = this.SafeString(ticker, "symbol")
|
||
|
if IsTrue(!IsEqual(symbol, nil)) {
|
||
|
AddElementToObject(result, symbol, ticker)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ch <- this.FilterByArrayTickers(result, "symbol", symbols)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
// see response sample under "fetchMarkets" because same endpoint is being used here
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var marketId interface{} = this.SafeString(ticker, "symbol")
|
||
|
var symbol interface{} = this.SafeSymbol(marketId, market)
|
||
|
var timestamp interface{} = this.Parse8601(this.SafeString(ticker, "timestamp"))
|
||
|
var open interface{} = this.SafeString(ticker, "prevPrice24h")
|
||
|
var last interface{} = this.SafeString(ticker, "lastPrice")
|
||
|
return this.SafeTicker(map[string]interface{} {
|
||
|
"symbol": symbol,
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"high": this.SafeString(ticker, "highPrice"),
|
||
|
"low": this.SafeString(ticker, "lowPrice"),
|
||
|
"bid": this.SafeString(ticker, "bidPrice"),
|
||
|
"bidVolume": nil,
|
||
|
"ask": this.SafeString(ticker, "askPrice"),
|
||
|
"askVolume": nil,
|
||
|
"vwap": this.SafeString(ticker, "vwap"),
|
||
|
"open": open,
|
||
|
"close": last,
|
||
|
"last": last,
|
||
|
"previousClose": nil,
|
||
|
"change": nil,
|
||
|
"percentage": nil,
|
||
|
"average": nil,
|
||
|
"baseVolume": this.SafeString(ticker, "homeNotional24h"),
|
||
|
"quoteVolume": this.SafeString(ticker, "foreignNotional24h"),
|
||
|
"markPrice": this.SafeString(ticker, "markPrice"),
|
||
|
"info": ticker,
|
||
|
}, market)
|
||
|
}
|
||
|
func (this *bitmex) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "timestamp":"2015-09-25T13:38:00.000Z",
|
||
|
// "symbol":"XBTUSD",
|
||
|
// "open":237.45,
|
||
|
// "high":237.45,
|
||
|
// "low":237.45,
|
||
|
// "close":237.45,
|
||
|
// "trades":0,
|
||
|
// "volume":0,
|
||
|
// "vwap":null,
|
||
|
// "lastSize":null,
|
||
|
// "turnover":0,
|
||
|
// "homeNotional":0,
|
||
|
// "foreignNotional":0
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var marketId interface{} = this.SafeString(ohlcv, "symbol")
|
||
|
market = this.SafeMarket(marketId, market)
|
||
|
var volume interface{} = this.ConvertFromRawQuantity(GetValue(market, "symbol"), this.SafeString(ohlcv, "volume"))
|
||
|
return []interface{}{this.Parse8601(this.SafeString(ohlcv, "timestamp")), this.SafeNumber(ohlcv, "open"), this.SafeNumber(ohlcv, "high"), this.SafeNumber(ohlcv, "low"), this.SafeNumber(ohlcv, "close"), volume}
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchOHLCV
|
||
|
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Trade/Trade_getBucketed
|
||
|
* @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
|
||
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
||
|
*/
|
||
|
func (this *bitmex) 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
|
||
|
|
||
|
retRes16188 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes16188)
|
||
|
var paginate interface{} = false
|
||
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "paginate");
|
||
|
paginate = GetValue(paginateparamsVariable,0);
|
||
|
params = GetValue(paginateparamsVariable,1)
|
||
|
if IsTrue(paginate) {
|
||
|
|
||
|
retRes162219 := (<-this.FetchPaginatedCallDeterministic("fetchOHLCV", symbol, since, limit, timeframe, params))
|
||
|
PanicOnError(retRes162219)
|
||
|
ch <- retRes162219
|
||
|
return nil
|
||
|
}
|
||
|
// send JSON key/value pairs, such as {"key": "value"}
|
||
|
// filter by individual fields and do advanced queries on timestamps
|
||
|
// let filter: Dict = { 'key': 'value' };
|
||
|
// send a bare series (e.g. XBU) to nearest expiring contract in that series
|
||
|
// you can also send a timeframe, e.g. XBU:monthly
|
||
|
// timeframes: daily, weekly, monthly, quarterly, and biquarterly
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"symbol": GetValue(market, "id"),
|
||
|
"binSize": this.SafeString(this.Timeframes, timeframe, timeframe),
|
||
|
"partial": true,
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "count", limit) // default 100, max 500
|
||
|
}
|
||
|
var until interface{} = this.SafeInteger(params, "until")
|
||
|
if IsTrue(!IsEqual(until, nil)) {
|
||
|
params = this.Omit(params, []interface{}{"until"})
|
||
|
AddElementToObject(request, "endTime", this.Iso8601(until))
|
||
|
}
|
||
|
var duration interface{} = Multiply(this.ParseTimeframe(timeframe), 1000)
|
||
|
var fetchOHLCVOpenTimestamp interface{} = this.SafeBool(this.Options, "fetchOHLCVOpenTimestamp", true)
|
||
|
// if since is not set, they will return candles starting from 2017-01-01
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
var timestamp interface{} = since
|
||
|
if IsTrue(fetchOHLCVOpenTimestamp) {
|
||
|
timestamp = this.Sum(timestamp, duration)
|
||
|
}
|
||
|
var startTime interface{} = this.Iso8601(timestamp)
|
||
|
AddElementToObject(request, "startTime", startTime) // starting date filter for results
|
||
|
} else {
|
||
|
AddElementToObject(request, "reverse", true)
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetTradeBucketed(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// [
|
||
|
// {"timestamp":"2015-09-25T13:38:00.000Z","symbol":"XBTUSD","open":237.45,"high":237.45,"low":237.45,"close":237.45,"trades":0,"volume":0,"vwap":null,"lastSize":null,"turnover":0,"homeNotional":0,"foreignNotional":0},
|
||
|
// {"timestamp":"2015-09-25T13:39:00.000Z","symbol":"XBTUSD","open":237.45,"high":237.45,"low":237.45,"close":237.45,"trades":0,"volume":0,"vwap":null,"lastSize":null,"turnover":0,"homeNotional":0,"foreignNotional":0},
|
||
|
// {"timestamp":"2015-09-25T13:40:00.000Z","symbol":"XBTUSD","open":237.45,"high":237.45,"low":237.45,"close":237.45,"trades":0,"volume":0,"vwap":null,"lastSize":null,"turnover":0,"homeNotional":0,"foreignNotional":0}
|
||
|
// ]
|
||
|
//
|
||
|
var result interface{} = this.ParseOHLCVs(response, market, timeframe, since, limit)
|
||
|
if IsTrue(fetchOHLCVOpenTimestamp) {
|
||
|
// bitmex returns the candle's close timestamp - https://github.com/ccxt/ccxt/issues/4446
|
||
|
// we can emulate the open timestamp by shifting all the timestamps one place
|
||
|
// so the previous close becomes the current open, and we drop the first candle
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(result)); i++ {
|
||
|
AddElementToObject(GetValue(result, i), 0, Subtract(GetValue(GetValue(result, i), 0), duration))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ch <- result
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// fetchTrades (public)
|
||
|
//
|
||
|
// {
|
||
|
// "timestamp": "2018-08-28T00:00:02.735Z",
|
||
|
// "symbol": "XBTUSD",
|
||
|
// "side": "Buy",
|
||
|
// "size": 2000,
|
||
|
// "price": 6906.5,
|
||
|
// "tickDirection": "PlusTick",
|
||
|
// "trdMatchID": "b9a42432-0a46-6a2f-5ecc-c32e9ca4baf8",
|
||
|
// "grossValue": 28958000,
|
||
|
// "homeNotional": 0.28958,
|
||
|
// "foreignNotional": 2000
|
||
|
// }
|
||
|
//
|
||
|
// fetchMyTrades (private)
|
||
|
//
|
||
|
// {
|
||
|
// "execID": "string",
|
||
|
// "orderID": "string",
|
||
|
// "clOrdID": "string",
|
||
|
// "clOrdLinkID": "string",
|
||
|
// "account": 0,
|
||
|
// "symbol": "string",
|
||
|
// "side": "string",
|
||
|
// "lastQty": 0,
|
||
|
// "lastPx": 0,
|
||
|
// "underlyingLastPx": 0,
|
||
|
// "lastMkt": "string",
|
||
|
// "lastLiquidityInd": "string",
|
||
|
// "simpleOrderQty": 0,
|
||
|
// "orderQty": 0,
|
||
|
// "price": 0,
|
||
|
// "displayQty": 0,
|
||
|
// "stopPx": 0,
|
||
|
// "pegOffsetValue": 0,
|
||
|
// "pegPriceType": "string",
|
||
|
// "currency": "string",
|
||
|
// "settlCurrency": "string",
|
||
|
// "execType": "string",
|
||
|
// "ordType": "string",
|
||
|
// "timeInForce": "string",
|
||
|
// "execInst": "string",
|
||
|
// "contingencyType": "string",
|
||
|
// "exDestination": "string",
|
||
|
// "ordStatus": "string",
|
||
|
// "triggered": "string",
|
||
|
// "workingIndicator": true,
|
||
|
// "ordRejReason": "string",
|
||
|
// "simpleLeavesQty": 0,
|
||
|
// "leavesQty": 0,
|
||
|
// "simpleCumQty": 0,
|
||
|
// "cumQty": 0,
|
||
|
// "avgPx": 0,
|
||
|
// "commission": 0,
|
||
|
// "tradePublishIndicator": "string",
|
||
|
// "multiLegReportingType": "string",
|
||
|
// "text": "string",
|
||
|
// "trdMatchID": "string",
|
||
|
// "execCost": 0,
|
||
|
// "execComm": 0,
|
||
|
// "homeNotional": 0,
|
||
|
// "foreignNotional": 0,
|
||
|
// "transactTime": "2019-03-05T12:47:02.762Z",
|
||
|
// "timestamp": "2019-03-05T12:47:02.762Z"
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var marketId interface{} = this.SafeString(trade, "symbol")
|
||
|
var symbol interface{} = this.SafeSymbol(marketId, market)
|
||
|
var timestamp interface{} = this.Parse8601(this.SafeString(trade, "timestamp"))
|
||
|
var priceString interface{} = this.SafeString2(trade, "avgPx", "price")
|
||
|
var amountString interface{} = this.ConvertFromRawQuantity(symbol, this.SafeString2(trade, "size", "lastQty"))
|
||
|
var execCost interface{} = this.NumberToString(this.ConvertFromRawCost(symbol, this.SafeString(trade, "execCost")))
|
||
|
var id interface{} = this.SafeString(trade, "trdMatchID")
|
||
|
var order interface{} = this.SafeString(trade, "orderID")
|
||
|
var side interface{} = this.SafeStringLower(trade, "side")
|
||
|
// price * amount doesn't work for all symbols (e.g. XBT, ETH)
|
||
|
var fee interface{} = nil
|
||
|
var feeCostString interface{} = this.NumberToString(this.ConvertFromRawCost(symbol, this.SafeString(trade, "execComm")))
|
||
|
if IsTrue(!IsEqual(feeCostString, nil)) {
|
||
|
var currencyId interface{} = this.SafeString2(trade, "settlCurrency", "currency")
|
||
|
fee = map[string]interface{} {
|
||
|
"cost": feeCostString,
|
||
|
"currency": this.SafeCurrencyCode(currencyId),
|
||
|
"rate": this.SafeString(trade, "commission"),
|
||
|
}
|
||
|
}
|
||
|
// Trade or Funding
|
||
|
var execType interface{} = this.SafeString(trade, "execType")
|
||
|
var takerOrMaker interface{} = nil
|
||
|
if IsTrue(IsTrue(!IsEqual(feeCostString, nil)) && IsTrue(IsEqual(execType, "Trade"))) {
|
||
|
takerOrMaker = Ternary(IsTrue(Precise.StringLt(feeCostString, "0")), "maker", "taker")
|
||
|
}
|
||
|
var typeVar interface{} = this.SafeStringLower(trade, "ordType")
|
||
|
return this.SafeTrade(map[string]interface{} {
|
||
|
"info": trade,
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"symbol": symbol,
|
||
|
"id": id,
|
||
|
"order": order,
|
||
|
"type": typeVar,
|
||
|
"takerOrMaker": takerOrMaker,
|
||
|
"side": side,
|
||
|
"price": priceString,
|
||
|
"cost": Precise.StringAbs(execCost),
|
||
|
"amount": amountString,
|
||
|
"fee": fee,
|
||
|
}, market)
|
||
|
}
|
||
|
func (this *bitmex) ParseOrderStatus(status interface{}) interface{} {
|
||
|
var statuses interface{} = map[string]interface{} {
|
||
|
"New": "open",
|
||
|
"PartiallyFilled": "open",
|
||
|
"Filled": "closed",
|
||
|
"DoneForDay": "open",
|
||
|
"Canceled": "canceled",
|
||
|
"PendingCancel": "open",
|
||
|
"PendingNew": "open",
|
||
|
"Rejected": "rejected",
|
||
|
"Expired": "expired",
|
||
|
"Stopped": "open",
|
||
|
"Untriggered": "open",
|
||
|
"Triggered": "open",
|
||
|
}
|
||
|
return this.SafeString(statuses, status, status)
|
||
|
}
|
||
|
func (this *bitmex) ParseTimeInForce(timeInForce interface{}) interface{} {
|
||
|
var timeInForces interface{} = map[string]interface{} {
|
||
|
"Day": "Day",
|
||
|
"GoodTillCancel": "GTC",
|
||
|
"ImmediateOrCancel": "IOC",
|
||
|
"FillOrKill": "FOK",
|
||
|
}
|
||
|
return this.SafeString(timeInForces, timeInForce, timeInForce)
|
||
|
}
|
||
|
func (this *bitmex) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "orderID":"56222c7a-9956-413a-82cf-99f4812c214b",
|
||
|
// "clOrdID":"",
|
||
|
// "clOrdLinkID":"",
|
||
|
// "account":1455728,
|
||
|
// "symbol":"XBTUSD",
|
||
|
// "side":"Sell",
|
||
|
// "simpleOrderQty":null,
|
||
|
// "orderQty":1,
|
||
|
// "price":40000,
|
||
|
// "displayQty":null,
|
||
|
// "stopPx":null,
|
||
|
// "pegOffsetValue":null,
|
||
|
// "pegPriceType":"",
|
||
|
// "currency":"USD",
|
||
|
// "settlCurrency":"XBt",
|
||
|
// "ordType":"Limit",
|
||
|
// "timeInForce":"GoodTillCancel",
|
||
|
// "execInst":"",
|
||
|
// "contingencyType":"",
|
||
|
// "exDestination":"XBME",
|
||
|
// "ordStatus":"New",
|
||
|
// "triggered":"",
|
||
|
// "workingIndicator":true,
|
||
|
// "ordRejReason":"",
|
||
|
// "simpleLeavesQty":null,
|
||
|
// "leavesQty":1,
|
||
|
// "simpleCumQty":null,
|
||
|
// "cumQty":0,
|
||
|
// "avgPx":null,
|
||
|
// "multiLegReportingType":"SingleSecurity",
|
||
|
// "text":"Submitted via API.",
|
||
|
// "transactTime":"2021-01-02T21:38:49.246Z",
|
||
|
// "timestamp":"2021-01-02T21:38:49.246Z"
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var marketId interface{} = this.SafeString(order, "symbol")
|
||
|
market = this.SafeMarket(marketId, market)
|
||
|
var symbol interface{} = GetValue(market, "symbol")
|
||
|
var qty interface{} = this.SafeString(order, "orderQty")
|
||
|
var cost interface{} = nil
|
||
|
var amount interface{} = nil
|
||
|
var isInverse interface{} = false
|
||
|
if IsTrue(IsEqual(marketId, nil)) {
|
||
|
var defaultSubType interface{} = this.SafeString(this.Options, "defaultSubType", "linear")
|
||
|
isInverse = (IsEqual(defaultSubType, "inverse"))
|
||
|
} else {
|
||
|
isInverse = this.SafeBool(market, "inverse", false)
|
||
|
}
|
||
|
if IsTrue(isInverse) {
|
||
|
cost = this.ConvertFromRawQuantity(symbol, qty)
|
||
|
} else {
|
||
|
amount = this.ConvertFromRawQuantity(symbol, qty)
|
||
|
}
|
||
|
var average interface{} = this.SafeString(order, "avgPx")
|
||
|
var filled interface{} = nil
|
||
|
var cumQty interface{} = this.NumberToString(this.ConvertFromRawQuantity(symbol, this.SafeString(order, "cumQty")))
|
||
|
if IsTrue(isInverse) {
|
||
|
filled = Precise.StringDiv(cumQty, average)
|
||
|
} else {
|
||
|
filled = cumQty
|
||
|
}
|
||
|
var execInst interface{} = this.SafeString(order, "execInst")
|
||
|
var postOnly interface{} = nil
|
||
|
if IsTrue(!IsEqual(execInst, nil)) {
|
||
|
postOnly = (IsEqual(execInst, "ParticipateDoNotInitiate"))
|
||
|
}
|
||
|
var timestamp interface{} = this.Parse8601(this.SafeString(order, "timestamp"))
|
||
|
var triggerPrice interface{} = this.SafeNumber(order, "stopPx")
|
||
|
var remaining interface{} = this.SafeString(order, "leavesQty")
|
||
|
return this.SafeOrder(map[string]interface{} {
|
||
|
"info": order,
|
||
|
"id": this.SafeString(order, "orderID"),
|
||
|
"clientOrderId": this.SafeString(order, "clOrdID"),
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"lastTradeTimestamp": this.Parse8601(this.SafeString(order, "transactTime")),
|
||
|
"symbol": symbol,
|
||
|
"type": this.SafeStringLower(order, "ordType"),
|
||
|
"timeInForce": this.ParseTimeInForce(this.SafeString(order, "timeInForce")),
|
||
|
"postOnly": postOnly,
|
||
|
"side": this.SafeStringLower(order, "side"),
|
||
|
"price": this.SafeString(order, "price"),
|
||
|
"triggerPrice": triggerPrice,
|
||
|
"amount": amount,
|
||
|
"cost": cost,
|
||
|
"average": average,
|
||
|
"filled": filled,
|
||
|
"remaining": this.ConvertFromRawQuantity(symbol, remaining),
|
||
|
"status": this.ParseOrderStatus(this.SafeString(order, "ordStatus")),
|
||
|
"fee": nil,
|
||
|
"trades": nil,
|
||
|
}, market)
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchTrades
|
||
|
* @description get the list of most recent trades for a particular symbol
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Trade/Trade_get
|
||
|
* @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
|
||
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
||
|
*/
|
||
|
func (this *bitmex) 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
|
||
|
|
||
|
retRes19338 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes19338)
|
||
|
var paginate interface{} = false
|
||
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "paginate");
|
||
|
paginate = GetValue(paginateparamsVariable,0);
|
||
|
params = GetValue(paginateparamsVariable,1)
|
||
|
if IsTrue(paginate) {
|
||
|
|
||
|
retRes193719 := (<-this.FetchPaginatedCallDynamic("fetchTrades", symbol, since, limit, params))
|
||
|
PanicOnError(retRes193719)
|
||
|
ch <- retRes193719
|
||
|
return nil
|
||
|
}
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"symbol": GetValue(market, "id"),
|
||
|
}
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "startTime", this.Iso8601(since))
|
||
|
} else {
|
||
|
// by default reverse=false, i.e. trades are fetched since the time of market inception (year 2015 for XBTUSD)
|
||
|
AddElementToObject(request, "reverse", true)
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "count", mathMin(limit, 1000)) // api maximum 1000
|
||
|
}
|
||
|
var until interface{} = this.SafeInteger2(params, "until", "endTime")
|
||
|
if IsTrue(!IsEqual(until, nil)) {
|
||
|
params = this.Omit(params, []interface{}{"until"})
|
||
|
AddElementToObject(request, "endTime", this.Iso8601(until))
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetTrade(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// [
|
||
|
// {
|
||
|
// "timestamp": "2018-08-28T00:00:02.735Z",
|
||
|
// "symbol": "XBTUSD",
|
||
|
// "side": "Buy",
|
||
|
// "size": 2000,
|
||
|
// "price": 6906.5,
|
||
|
// "tickDirection": "PlusTick",
|
||
|
// "trdMatchID": "b9a42432-0a46-6a2f-5ecc-c32e9ca4baf8",
|
||
|
// "grossValue": 28958000,
|
||
|
// "homeNotional": 0.28958,
|
||
|
// "foreignNotional": 2000
|
||
|
// },
|
||
|
// {
|
||
|
// "timestamp": "2018-08-28T00:00:03.778Z",
|
||
|
// "symbol": "XBTUSD",
|
||
|
// "side": "Sell",
|
||
|
// "size": 1000,
|
||
|
// "price": 6906,
|
||
|
// "tickDirection": "MinusTick",
|
||
|
// "trdMatchID": "0d4f1682-5270-a800-569b-4a0eb92db97c",
|
||
|
// "grossValue": 14480000,
|
||
|
// "homeNotional": 0.1448,
|
||
|
// "foreignNotional": 1000
|
||
|
// },
|
||
|
// ]
|
||
|
//
|
||
|
ch <- this.ParseTrades(response, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#createOrder
|
||
|
* @description create a trade order
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Order/Order_new
|
||
|
* @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 {object} [params.triggerPrice] the price at which a trigger order is triggered at
|
||
|
* @param {object} [params.triggerDirection] the direction whenever the trigger happens with relation to price - 'above' or 'below'
|
||
|
* @param {float} [params.trailingAmount] the quote amount to trail away from the current market price
|
||
|
* @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
|
||
|
*/
|
||
|
func (this *bitmex) 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
|
||
|
|
||
|
retRes20068 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes20068)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var orderType interface{} = this.Capitalize(typeVar)
|
||
|
var reduceOnly interface{} = this.SafeValue(params, "reduceOnly")
|
||
|
if IsTrue(!IsEqual(reduceOnly, nil)) {
|
||
|
if IsTrue(IsTrue((!IsTrue(GetValue(market, "swap")))) && IsTrue((!IsTrue(GetValue(market, "future"))))) {
|
||
|
panic(InvalidOrder(Add(Add(Add(this.Id, " createOrder() does not support reduceOnly for "), GetValue(market, "type")), " orders, reduceOnly orders are supported for swap and future markets only")))
|
||
|
}
|
||
|
}
|
||
|
var brokerId interface{} = this.SafeString(this.Options, "brokerId", "CCXT")
|
||
|
var qty interface{} = this.ParseToInt(this.AmountToPrecision(symbol, amount))
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"symbol": GetValue(market, "id"),
|
||
|
"side": this.Capitalize(side),
|
||
|
"orderQty": qty,
|
||
|
"ordType": orderType,
|
||
|
"text": brokerId,
|
||
|
}
|
||
|
// support for unified trigger format
|
||
|
var triggerPrice interface{} = this.SafeNumberN(params, []interface{}{"triggerPrice", "stopPx", "stopPrice"})
|
||
|
var trailingAmount interface{} = this.SafeString2(params, "trailingAmount", "pegOffsetValue")
|
||
|
var isTriggerOrder interface{} = !IsEqual(triggerPrice, nil)
|
||
|
var isTrailingAmountOrder interface{} = !IsEqual(trailingAmount, nil)
|
||
|
if IsTrue(IsTrue(isTriggerOrder) || IsTrue(isTrailingAmountOrder)) {
|
||
|
var triggerDirection interface{} = this.SafeString(params, "triggerDirection")
|
||
|
var triggerAbove interface{} = (IsEqual(triggerDirection, "above"))
|
||
|
if IsTrue(IsTrue((IsEqual(typeVar, "limit"))) || IsTrue((IsEqual(typeVar, "market")))) {
|
||
|
this.CheckRequiredArgument("createOrder", triggerDirection, "triggerDirection", []interface{}{"above", "below"})
|
||
|
}
|
||
|
if IsTrue(IsEqual(typeVar, "limit")) {
|
||
|
if IsTrue(IsEqual(side, "buy")) {
|
||
|
orderType = Ternary(IsTrue(triggerAbove), "StopLimit", "LimitIfTouched")
|
||
|
} else {
|
||
|
orderType = Ternary(IsTrue(triggerAbove), "LimitIfTouched", "StopLimit")
|
||
|
}
|
||
|
} else if IsTrue(IsEqual(typeVar, "market")) {
|
||
|
if IsTrue(IsEqual(side, "buy")) {
|
||
|
orderType = Ternary(IsTrue(triggerAbove), "Stop", "MarketIfTouched")
|
||
|
} else {
|
||
|
orderType = Ternary(IsTrue(triggerAbove), "MarketIfTouched", "Stop")
|
||
|
}
|
||
|
}
|
||
|
if IsTrue(isTrailingAmountOrder) {
|
||
|
var isStopSellOrder interface{} = IsTrue((IsEqual(side, "sell"))) && IsTrue((IsTrue((IsEqual(orderType, "Stop"))) || IsTrue((IsEqual(orderType, "StopLimit")))))
|
||
|
var isBuyIfTouchedOrder interface{} = IsTrue((IsEqual(side, "buy"))) && IsTrue((IsTrue((IsEqual(orderType, "MarketIfTouched"))) || IsTrue((IsEqual(orderType, "LimitIfTouched")))))
|
||
|
if IsTrue(IsTrue(isStopSellOrder) || IsTrue(isBuyIfTouchedOrder)) {
|
||
|
trailingAmount = Add("-", trailingAmount)
|
||
|
}
|
||
|
AddElementToObject(request, "pegOffsetValue", this.ParseToNumeric(trailingAmount))
|
||
|
AddElementToObject(request, "pegPriceType", "TrailingStopPeg")
|
||
|
} else {
|
||
|
if IsTrue(IsEqual(triggerPrice, nil)) {
|
||
|
panic(ArgumentsRequired(Add(Add(Add(this.Id, " createOrder() requires a triggerPrice parameter for the "), orderType), " order type")))
|
||
|
}
|
||
|
AddElementToObject(request, "stopPx", this.ParseToNumeric(this.PriceToPrecision(symbol, triggerPrice)))
|
||
|
}
|
||
|
AddElementToObject(request, "ordType", orderType)
|
||
|
params = this.Omit(params, []interface{}{"triggerPrice", "stopPrice", "stopPx", "triggerDirection", "trailingAmount"})
|
||
|
}
|
||
|
if IsTrue(IsTrue(IsTrue((IsEqual(orderType, "Limit"))) || IsTrue((IsEqual(orderType, "StopLimit")))) || IsTrue((IsEqual(orderType, "LimitIfTouched")))) {
|
||
|
AddElementToObject(request, "price", this.ParseToNumeric(this.PriceToPrecision(symbol, price)))
|
||
|
}
|
||
|
var clientOrderId interface{} = this.SafeString2(params, "clOrdID", "clientOrderId")
|
||
|
if IsTrue(!IsEqual(clientOrderId, nil)) {
|
||
|
AddElementToObject(request, "clOrdID", clientOrderId)
|
||
|
params = this.Omit(params, []interface{}{"clOrdID", "clientOrderId"})
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivatePostOrder(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
ch <- this.ParseOrder(response, market)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) EditOrder(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
|
ch := make(chan interface{})
|
||
|
go func() interface{} {
|
||
|
defer close(ch)
|
||
|
defer ReturnPanicError(ch)
|
||
|
amount := GetArg(optionalArgs, 0, nil)
|
||
|
_ = amount
|
||
|
price := GetArg(optionalArgs, 1, nil)
|
||
|
_ = price
|
||
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
||
|
_ = params
|
||
|
|
||
|
retRes20798 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes20798)
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
var trailingAmount interface{} = this.SafeString2(params, "trailingAmount", "pegOffsetValue")
|
||
|
var isTrailingAmountOrder interface{} = !IsEqual(trailingAmount, nil)
|
||
|
if IsTrue(isTrailingAmountOrder) {
|
||
|
var triggerDirection interface{} = this.SafeString(params, "triggerDirection")
|
||
|
var triggerAbove interface{} = (IsEqual(triggerDirection, "above"))
|
||
|
if IsTrue(IsTrue((IsEqual(typeVar, "limit"))) || IsTrue((IsEqual(typeVar, "market")))) {
|
||
|
this.CheckRequiredArgument("createOrder", triggerDirection, "triggerDirection", []interface{}{"above", "below"})
|
||
|
}
|
||
|
var orderType interface{} = nil
|
||
|
if IsTrue(IsEqual(typeVar, "limit")) {
|
||
|
if IsTrue(IsEqual(side, "buy")) {
|
||
|
orderType = Ternary(IsTrue(triggerAbove), "StopLimit", "LimitIfTouched")
|
||
|
} else {
|
||
|
orderType = Ternary(IsTrue(triggerAbove), "LimitIfTouched", "StopLimit")
|
||
|
}
|
||
|
} else if IsTrue(IsEqual(typeVar, "market")) {
|
||
|
if IsTrue(IsEqual(side, "buy")) {
|
||
|
orderType = Ternary(IsTrue(triggerAbove), "Stop", "MarketIfTouched")
|
||
|
} else {
|
||
|
orderType = Ternary(IsTrue(triggerAbove), "MarketIfTouched", "Stop")
|
||
|
}
|
||
|
}
|
||
|
var isStopSellOrder interface{} = IsTrue((IsEqual(side, "sell"))) && IsTrue((IsTrue((IsEqual(orderType, "Stop"))) || IsTrue((IsEqual(orderType, "StopLimit")))))
|
||
|
var isBuyIfTouchedOrder interface{} = IsTrue((IsEqual(side, "buy"))) && IsTrue((IsTrue((IsEqual(orderType, "MarketIfTouched"))) || IsTrue((IsEqual(orderType, "LimitIfTouched")))))
|
||
|
if IsTrue(IsTrue(isStopSellOrder) || IsTrue(isBuyIfTouchedOrder)) {
|
||
|
trailingAmount = Add("-", trailingAmount)
|
||
|
}
|
||
|
AddElementToObject(request, "pegOffsetValue", this.ParseToNumeric(trailingAmount))
|
||
|
params = this.Omit(params, []interface{}{"triggerDirection", "trailingAmount"})
|
||
|
}
|
||
|
var origClOrdID interface{} = this.SafeString2(params, "origClOrdID", "clientOrderId")
|
||
|
if IsTrue(!IsEqual(origClOrdID, nil)) {
|
||
|
AddElementToObject(request, "origClOrdID", origClOrdID)
|
||
|
var clientOrderId interface{} = this.SafeString(params, "clOrdID", "clientOrderId")
|
||
|
if IsTrue(!IsEqual(clientOrderId, nil)) {
|
||
|
AddElementToObject(request, "clOrdID", clientOrderId)
|
||
|
}
|
||
|
params = this.Omit(params, []interface{}{"origClOrdID", "clOrdID", "clientOrderId"})
|
||
|
} else {
|
||
|
AddElementToObject(request, "orderID", id)
|
||
|
}
|
||
|
if IsTrue(!IsEqual(amount, nil)) {
|
||
|
var qty interface{} = this.ParseToInt(this.AmountToPrecision(symbol, amount))
|
||
|
AddElementToObject(request, "orderQty", qty)
|
||
|
}
|
||
|
if IsTrue(!IsEqual(price, nil)) {
|
||
|
AddElementToObject(request, "price", price)
|
||
|
}
|
||
|
var brokerId interface{} = this.SafeString(this.Options, "brokerId", "CCXT")
|
||
|
AddElementToObject(request, "text", brokerId)
|
||
|
|
||
|
response:= (<-this.PrivatePutOrder(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
ch <- this.ParseOrder(response)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#cancelOrder
|
||
|
* @description cancels an open order
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Order/Order_cancel
|
||
|
* @param {string} id order id
|
||
|
* @param {string} symbol not used by bitmex cancelOrder ()
|
||
|
* @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 *bitmex) 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
|
||
|
|
||
|
retRes21468 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes21468)
|
||
|
// https://github.com/ccxt/ccxt/issues/6507
|
||
|
var clientOrderId interface{} = this.SafeValue2(params, "clOrdID", "clientOrderId")
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
if IsTrue(IsEqual(clientOrderId, nil)) {
|
||
|
AddElementToObject(request, "orderID", id)
|
||
|
} else {
|
||
|
AddElementToObject(request, "clOrdID", clientOrderId)
|
||
|
params = this.Omit(params, []interface{}{"clOrdID", "clientOrderId"})
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivateDeleteOrder(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
var order interface{} = this.SafeValue(response, 0, map[string]interface{} {})
|
||
|
var error interface{} = this.SafeString(order, "error")
|
||
|
if IsTrue(!IsEqual(error, nil)) {
|
||
|
if IsTrue(IsGreaterThanOrEqual(GetIndexOf(error, "Unable to cancel order due to existing state"), 0)) {
|
||
|
panic(OrderNotFound(Add(Add(this.Id, " cancelOrder() failed: "), error)))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ch <- this.ParseOrder(order)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#cancelOrders
|
||
|
* @description cancel multiple orders
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Order/Order_cancel
|
||
|
* @param {string[]} ids order ids
|
||
|
* @param {string} symbol not used by bitmex cancelOrders ()
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
|
*/
|
||
|
func (this *bitmex) CancelOrders(ids interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
|
ch := make(chan interface{})
|
||
|
go func() interface{} {
|
||
|
defer close(ch)
|
||
|
defer ReturnPanicError(ch)
|
||
|
// return await this.cancelOrder (ids, symbol, params);
|
||
|
symbol := GetArg(optionalArgs, 0, nil)
|
||
|
_ = symbol
|
||
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
|
_ = params
|
||
|
|
||
|
retRes21798 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes21798)
|
||
|
// https://github.com/ccxt/ccxt/issues/6507
|
||
|
var clientOrderId interface{} = this.SafeValue2(params, "clOrdID", "clientOrderId")
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
if IsTrue(IsEqual(clientOrderId, nil)) {
|
||
|
AddElementToObject(request, "orderID", ids)
|
||
|
} else {
|
||
|
AddElementToObject(request, "clOrdID", clientOrderId)
|
||
|
params = this.Omit(params, []interface{}{"clOrdID", "clientOrderId"})
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivateDeleteOrder(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
ch <- this.ParseOrders(response)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#cancelAllOrders
|
||
|
* @description cancel all open orders
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Order/Order_cancelAll
|
||
|
* @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
|
*/
|
||
|
func (this *bitmex) 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
|
||
|
|
||
|
retRes22038 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes22038)
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
var market interface{} = nil
|
||
|
if IsTrue(!IsEqual(symbol, nil)) {
|
||
|
market = this.Market(symbol)
|
||
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivateDeleteOrderAll(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// [
|
||
|
// {
|
||
|
// "orderID": "string",
|
||
|
// "clOrdID": "string",
|
||
|
// "clOrdLinkID": "string",
|
||
|
// "account": 0,
|
||
|
// "symbol": "string",
|
||
|
// "side": "string",
|
||
|
// "simpleOrderQty": 0,
|
||
|
// "orderQty": 0,
|
||
|
// "price": 0,
|
||
|
// "displayQty": 0,
|
||
|
// "stopPx": 0,
|
||
|
// "pegOffsetValue": 0,
|
||
|
// "pegPriceType": "string",
|
||
|
// "currency": "string",
|
||
|
// "settlCurrency": "string",
|
||
|
// "ordType": "string",
|
||
|
// "timeInForce": "string",
|
||
|
// "execInst": "string",
|
||
|
// "contingencyType": "string",
|
||
|
// "exDestination": "string",
|
||
|
// "ordStatus": "string",
|
||
|
// "triggered": "string",
|
||
|
// "workingIndicator": true,
|
||
|
// "ordRejReason": "string",
|
||
|
// "simpleLeavesQty": 0,
|
||
|
// "leavesQty": 0,
|
||
|
// "simpleCumQty": 0,
|
||
|
// "cumQty": 0,
|
||
|
// "avgPx": 0,
|
||
|
// "multiLegReportingType": "string",
|
||
|
// "text": "string",
|
||
|
// "transactTime": "2020-06-01T09:36:35.290Z",
|
||
|
// "timestamp": "2020-06-01T09:36:35.290Z"
|
||
|
// }
|
||
|
// ]
|
||
|
//
|
||
|
ch <- this.ParseOrders(response, market)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#cancelAllOrdersAfter
|
||
|
* @description dead man's switch, cancel all orders after the given timeout
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Order/Order_cancelAllAfter
|
||
|
* @param {number} timeout time in milliseconds, 0 represents cancel the timer
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object} the api result
|
||
|
*/
|
||
|
func (this *bitmex) CancelAllOrdersAfter(timeout 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
|
||
|
|
||
|
retRes22638 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes22638)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"timeout": Ternary(IsTrue((IsGreaterThan(timeout, 0))), this.ParseToInt(Divide(timeout, 1000)), 0),
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivatePostOrderCancelAllAfter(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// {
|
||
|
// now: '2024-04-09T09:01:56.560Z',
|
||
|
// cancelTime: '2024-04-09T09:01:56.660Z'
|
||
|
// }
|
||
|
//
|
||
|
ch <- response
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchLeverages
|
||
|
* @description fetch the set leverage for all contract markets
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Position/Position_get
|
||
|
* @param {string[]} [symbols] a list of unified market symbols
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object} a list of [leverage structures]{@link https://docs.ccxt.com/#/?id=leverage-structure}
|
||
|
*/
|
||
|
func (this *bitmex) FetchLeverages(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
|
||
|
|
||
|
retRes22878 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes22878)
|
||
|
|
||
|
leverages:= (<-this.FetchPositions(symbols, params))
|
||
|
PanicOnError(leverages)
|
||
|
|
||
|
ch <- this.ParseLeverages(leverages, symbols, "symbol")
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ParseLeverage(leverage interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var marketId interface{} = this.SafeString(leverage, "symbol")
|
||
|
return map[string]interface{} {
|
||
|
"info": leverage,
|
||
|
"symbol": this.SafeSymbol(marketId, market),
|
||
|
"marginMode": this.SafeStringLower(leverage, "marginMode"),
|
||
|
"longLeverage": this.SafeInteger(leverage, "leverage"),
|
||
|
"shortLeverage": this.SafeInteger(leverage, "leverage"),
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchPositions
|
||
|
* @description fetch all open positions
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Position/Position_get
|
||
|
* @param {string[]|undefined} symbols list of unified market symbols
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
||
|
*/
|
||
|
func (this *bitmex) FetchPositions(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
|
||
|
|
||
|
retRes23138 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes23138)
|
||
|
|
||
|
response:= (<-this.PrivateGetPosition(params))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// [
|
||
|
// {
|
||
|
// "account": 0,
|
||
|
// "symbol": "string",
|
||
|
// "currency": "string",
|
||
|
// "underlying": "string",
|
||
|
// "quoteCurrency": "string",
|
||
|
// "commission": 0,
|
||
|
// "initMarginReq": 0,
|
||
|
// "maintMarginReq": 0,
|
||
|
// "riskLimit": 0,
|
||
|
// "leverage": 0,
|
||
|
// "crossMargin": true,
|
||
|
// "deleveragePercentile": 0,
|
||
|
// "rebalancedPnl": 0,
|
||
|
// "prevRealisedPnl": 0,
|
||
|
// "prevUnrealisedPnl": 0,
|
||
|
// "prevClosePrice": 0,
|
||
|
// "openingTimestamp": "2020-11-09T06:53:59.892Z",
|
||
|
// "openingQty": 0,
|
||
|
// "openingCost": 0,
|
||
|
// "openingComm": 0,
|
||
|
// "openOrderBuyQty": 0,
|
||
|
// "openOrderBuyCost": 0,
|
||
|
// "openOrderBuyPremium": 0,
|
||
|
// "openOrderSellQty": 0,
|
||
|
// "openOrderSellCost": 0,
|
||
|
// "openOrderSellPremium": 0,
|
||
|
// "execBuyQty": 0,
|
||
|
// "execBuyCost": 0,
|
||
|
// "execSellQty": 0,
|
||
|
// "execSellCost": 0,
|
||
|
// "execQty": 0,
|
||
|
// "execCost": 0,
|
||
|
// "execComm": 0,
|
||
|
// "currentTimestamp": "2020-11-09T06:53:59.893Z",
|
||
|
// "currentQty": 0,
|
||
|
// "currentCost": 0,
|
||
|
// "currentComm": 0,
|
||
|
// "realisedCost": 0,
|
||
|
// "unrealisedCost": 0,
|
||
|
// "grossOpenCost": 0,
|
||
|
// "grossOpenPremium": 0,
|
||
|
// "grossExecCost": 0,
|
||
|
// "isOpen": true,
|
||
|
// "markPrice": 0,
|
||
|
// "markValue": 0,
|
||
|
// "riskValue": 0,
|
||
|
// "homeNotional": 0,
|
||
|
// "foreignNotional": 0,
|
||
|
// "posState": "string",
|
||
|
// "posCost": 0,
|
||
|
// "posCost2": 0,
|
||
|
// "posCross": 0,
|
||
|
// "posInit": 0,
|
||
|
// "posComm": 0,
|
||
|
// "posLoss": 0,
|
||
|
// "posMargin": 0,
|
||
|
// "posMaint": 0,
|
||
|
// "posAllowance": 0,
|
||
|
// "taxableMargin": 0,
|
||
|
// "initMargin": 0,
|
||
|
// "maintMargin": 0,
|
||
|
// "sessionMargin": 0,
|
||
|
// "targetExcessMargin": 0,
|
||
|
// "varMargin": 0,
|
||
|
// "realisedGrossPnl": 0,
|
||
|
// "realisedTax": 0,
|
||
|
// "realisedPnl": 0,
|
||
|
// "unrealisedGrossPnl": 0,
|
||
|
// "longBankrupt": 0,
|
||
|
// "shortBankrupt": 0,
|
||
|
// "taxBase": 0,
|
||
|
// "indicativeTaxRate": 0,
|
||
|
// "indicativeTax": 0,
|
||
|
// "unrealisedTax": 0,
|
||
|
// "unrealisedPnl": 0,
|
||
|
// "unrealisedPnlPcnt": 0,
|
||
|
// "unrealisedRoePcnt": 0,
|
||
|
// "simpleQty": 0,
|
||
|
// "simpleCost": 0,
|
||
|
// "simpleValue": 0,
|
||
|
// "simplePnl": 0,
|
||
|
// "simplePnlPcnt": 0,
|
||
|
// "avgCostPrice": 0,
|
||
|
// "avgEntryPrice": 0,
|
||
|
// "breakEvenPrice": 0,
|
||
|
// "marginCallPrice": 0,
|
||
|
// "liquidationPrice": 0,
|
||
|
// "bankruptPrice": 0,
|
||
|
// "timestamp": "2020-11-09T06:53:59.894Z",
|
||
|
// "lastPrice": 0,
|
||
|
// "lastValue": 0
|
||
|
// }
|
||
|
// ]
|
||
|
//
|
||
|
var results interface{} = this.ParsePositions(response, symbols)
|
||
|
|
||
|
ch <- this.FilterByArrayPositions(results, "symbol", symbols, false)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "account": 9371654,
|
||
|
// "symbol": "ETHUSDT",
|
||
|
// "currency": "USDt",
|
||
|
// "underlying": "ETH",
|
||
|
// "quoteCurrency": "USDT",
|
||
|
// "commission": 0.00075,
|
||
|
// "initMarginReq": 0.3333333333333333,
|
||
|
// "maintMarginReq": 0.01,
|
||
|
// "riskLimit": 1000000000000,
|
||
|
// "leverage": 3,
|
||
|
// "crossMargin": false,
|
||
|
// "deleveragePercentile": 1,
|
||
|
// "rebalancedPnl": 0,
|
||
|
// "prevRealisedPnl": 0,
|
||
|
// "prevUnrealisedPnl": 0,
|
||
|
// "prevClosePrice": 2053.738,
|
||
|
// "openingTimestamp": "2022-05-21T04:00:00.000Z",
|
||
|
// "openingQty": 0,
|
||
|
// "openingCost": 0,
|
||
|
// "openingComm": 0,
|
||
|
// "openOrderBuyQty": 0,
|
||
|
// "openOrderBuyCost": 0,
|
||
|
// "openOrderBuyPremium": 0,
|
||
|
// "openOrderSellQty": 0,
|
||
|
// "openOrderSellCost": 0,
|
||
|
// "openOrderSellPremium": 0,
|
||
|
// "execBuyQty": 2000,
|
||
|
// "execBuyCost": 39260000,
|
||
|
// "execSellQty": 0,
|
||
|
// "execSellCost": 0,
|
||
|
// "execQty": 2000,
|
||
|
// "execCost": 39260000,
|
||
|
// "execComm": 26500,
|
||
|
// "currentTimestamp": "2022-05-21T04:35:16.397Z",
|
||
|
// "currentQty": 2000,
|
||
|
// "currentCost": 39260000,
|
||
|
// "currentComm": 26500,
|
||
|
// "realisedCost": 0,
|
||
|
// "unrealisedCost": 39260000,
|
||
|
// "grossOpenCost": 0,
|
||
|
// "grossOpenPremium": 0,
|
||
|
// "grossExecCost": 39260000,
|
||
|
// "isOpen": true,
|
||
|
// "markPrice": 1964.195,
|
||
|
// "markValue": 39283900,
|
||
|
// "riskValue": 39283900,
|
||
|
// "homeNotional": 0.02,
|
||
|
// "foreignNotional": -39.2839,
|
||
|
// "posState": "",
|
||
|
// "posCost": 39260000,
|
||
|
// "posCost2": 39260000,
|
||
|
// "posCross": 0,
|
||
|
// "posInit": 13086667,
|
||
|
// "posComm": 39261,
|
||
|
// "posLoss": 0,
|
||
|
// "posMargin": 13125928,
|
||
|
// "posMaint": 435787,
|
||
|
// "posAllowance": 0,
|
||
|
// "taxableMargin": 0,
|
||
|
// "initMargin": 0,
|
||
|
// "maintMargin": 13149828,
|
||
|
// "sessionMargin": 0,
|
||
|
// "targetExcessMargin": 0,
|
||
|
// "varMargin": 0,
|
||
|
// "realisedGrossPnl": 0,
|
||
|
// "realisedTax": 0,
|
||
|
// "realisedPnl": -26500,
|
||
|
// "unrealisedGrossPnl": 23900,
|
||
|
// "longBankrupt": 0,
|
||
|
// "shortBankrupt": 0,
|
||
|
// "taxBase": 0,
|
||
|
// "indicativeTaxRate": null,
|
||
|
// "indicativeTax": 0,
|
||
|
// "unrealisedTax": 0,
|
||
|
// "unrealisedPnl": 23900,
|
||
|
// "unrealisedPnlPcnt": 0.0006,
|
||
|
// "unrealisedRoePcnt": 0.0018,
|
||
|
// "simpleQty": null,
|
||
|
// "simpleCost": null,
|
||
|
// "simpleValue": null,
|
||
|
// "simplePnl": null,
|
||
|
// "simplePnlPcnt": null,
|
||
|
// "avgCostPrice": 1963,
|
||
|
// "avgEntryPrice": 1963,
|
||
|
// "breakEvenPrice": 1964.35,
|
||
|
// "marginCallPrice": 1328.5,
|
||
|
// "liquidationPrice": 1328.5,
|
||
|
// "bankruptPrice": 1308.7,
|
||
|
// "timestamp": "2022-05-21T04:35:16.397Z",
|
||
|
// "lastPrice": 1964.195,
|
||
|
// "lastValue": 39283900
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
market = this.SafeMarket(this.SafeString(position, "symbol"), market)
|
||
|
var symbol interface{} = GetValue(market, "symbol")
|
||
|
var datetime interface{} = this.SafeString(position, "timestamp")
|
||
|
var crossMargin interface{} = this.SafeValue(position, "crossMargin")
|
||
|
var marginMode interface{} = Ternary(IsTrue((IsEqual(crossMargin, true))), "cross", "isolated")
|
||
|
var notionalString interface{} = Precise.StringAbs(this.SafeString2(position, "foreignNotional", "homeNotional"))
|
||
|
var settleCurrencyCode interface{} = this.SafeString(market, "settle")
|
||
|
var maintenanceMargin interface{} = this.ConvertToRealAmount(settleCurrencyCode, this.SafeString(position, "maintMargin"))
|
||
|
var unrealisedPnl interface{} = this.ConvertToRealAmount(settleCurrencyCode, this.SafeString(position, "unrealisedPnl"))
|
||
|
var contracts interface{} = this.ParseNumber(Precise.StringAbs(this.SafeString(position, "currentQty")))
|
||
|
var contractSize interface{} = this.SafeNumber(market, "contractSize")
|
||
|
var side interface{} = nil
|
||
|
var homeNotional interface{} = this.SafeString(position, "homeNotional")
|
||
|
if IsTrue(!IsEqual(homeNotional, nil)) {
|
||
|
if IsTrue(IsEqual(GetValue(homeNotional, 0), "-")) {
|
||
|
side = "short"
|
||
|
} else {
|
||
|
side = "long"
|
||
|
}
|
||
|
}
|
||
|
return this.SafePosition(map[string]interface{} {
|
||
|
"info": position,
|
||
|
"id": this.SafeString(position, "account"),
|
||
|
"symbol": symbol,
|
||
|
"timestamp": this.Parse8601(datetime),
|
||
|
"datetime": datetime,
|
||
|
"lastUpdateTimestamp": nil,
|
||
|
"hedged": nil,
|
||
|
"side": side,
|
||
|
"contracts": contracts,
|
||
|
"contractSize": contractSize,
|
||
|
"entryPrice": this.SafeNumber(position, "avgEntryPrice"),
|
||
|
"markPrice": this.SafeNumber(position, "markPrice"),
|
||
|
"lastPrice": nil,
|
||
|
"notional": this.ParseNumber(notionalString),
|
||
|
"leverage": this.SafeNumber(position, "leverage"),
|
||
|
"collateral": nil,
|
||
|
"initialMargin": this.SafeNumber(position, "initMargin"),
|
||
|
"initialMarginPercentage": this.SafeNumber(position, "initMarginReq"),
|
||
|
"maintenanceMargin": maintenanceMargin,
|
||
|
"maintenanceMarginPercentage": this.SafeNumber(position, "maintMarginReq"),
|
||
|
"unrealizedPnl": unrealisedPnl,
|
||
|
"liquidationPrice": this.SafeNumber(position, "liquidationPrice"),
|
||
|
"marginMode": marginMode,
|
||
|
"marginRatio": nil,
|
||
|
"percentage": this.SafeNumber(position, "unrealisedPnlPcnt"),
|
||
|
"stopLossPrice": nil,
|
||
|
"takeProfitPrice": nil,
|
||
|
})
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#withdraw
|
||
|
* @description make a withdrawal
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/User/User_requestWithdrawal
|
||
|
* @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 *bitmex) 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)
|
||
|
|
||
|
retRes25788 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes25788)
|
||
|
var currency interface{} = this.Currency(code)
|
||
|
var qty interface{} = this.ConvertFromRealAmount(code, amount)
|
||
|
var networkCode interface{} = nil
|
||
|
networkCodeparamsVariable := this.HandleNetworkCodeAndParams(params);
|
||
|
networkCode = GetValue(networkCodeparamsVariable,0);
|
||
|
params = GetValue(networkCodeparamsVariable,1)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"currency": GetValue(currency, "id"),
|
||
|
"amount": qty,
|
||
|
"address": address,
|
||
|
"network": this.NetworkCodeToId(networkCode, GetValue(currency, "code")),
|
||
|
}
|
||
|
if IsTrue(!IsEqual(this.Twofa, nil)) {
|
||
|
AddElementToObject(request, "otpToken", Totp(this.Twofa))
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivatePostUserRequestWithdrawal(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// {
|
||
|
// "transactID": "3aece414-bb29-76c8-6c6d-16a477a51a1e",
|
||
|
// "account": 1403035,
|
||
|
// "currency": "USDt",
|
||
|
// "network": "tron",
|
||
|
// "transactType": "Withdrawal",
|
||
|
// "amount": -11000000,
|
||
|
// "fee": 1000000,
|
||
|
// "transactStatus": "Pending",
|
||
|
// "address": "TAf5JxcAQQsC2Nm2zu21XE2iDtnisxPo1x",
|
||
|
// "tx": "",
|
||
|
// "text": "",
|
||
|
// "transactTime": "2022-12-16T07:37:06.500Z",
|
||
|
// "timestamp": "2022-12-16T07:37:06.500Z",
|
||
|
// }
|
||
|
//
|
||
|
ch <- this.ParseTransaction(response, currency)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchFundingRates
|
||
|
* @description fetch the funding rate for multiple markets
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Instrument/Instrument_getActiveAndIndices
|
||
|
* @param {string[]|undefined} symbols list of unified market symbols
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rates-structure}, indexed by market symbols
|
||
|
*/
|
||
|
func (this *bitmex) FetchFundingRates(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
|
||
|
|
||
|
retRes26258 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes26258)
|
||
|
|
||
|
response:= (<-this.PublicGetInstrumentActiveAndIndices(params))
|
||
|
PanicOnError(response)
|
||
|
// same response as under "fetchMarkets"
|
||
|
var filteredResponse interface{} = []interface{}{}
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(response)); i++ {
|
||
|
var item interface{} = GetValue(response, i)
|
||
|
var marketId interface{} = this.SafeString(item, "symbol")
|
||
|
var market interface{} = this.SafeMarket(marketId)
|
||
|
var swap interface{} = this.SafeBool(market, "swap", false)
|
||
|
if IsTrue(swap) {
|
||
|
AppendToArray(&filteredResponse,item)
|
||
|
}
|
||
|
}
|
||
|
symbols = this.MarketSymbols(symbols)
|
||
|
var result interface{} = this.ParseFundingRates(filteredResponse)
|
||
|
|
||
|
ch <- this.FilterByArray(result, "symbol", symbols)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ParseFundingRate(contract interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
// see response sample under "fetchMarkets" because same endpoint is being used here
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var datetime interface{} = this.SafeString(contract, "timestamp")
|
||
|
var marketId interface{} = this.SafeString(contract, "symbol")
|
||
|
var fundingDatetime interface{} = this.SafeString(contract, "fundingTimestamp")
|
||
|
return map[string]interface{} {
|
||
|
"info": contract,
|
||
|
"symbol": this.SafeSymbol(marketId, market),
|
||
|
"markPrice": this.SafeNumber(contract, "markPrice"),
|
||
|
"indexPrice": nil,
|
||
|
"interestRate": nil,
|
||
|
"estimatedSettlePrice": this.SafeNumber(contract, "indicativeSettlePrice"),
|
||
|
"timestamp": this.Parse8601(datetime),
|
||
|
"datetime": datetime,
|
||
|
"fundingRate": this.SafeNumber(contract, "fundingRate"),
|
||
|
"fundingTimestamp": this.Parse8601(fundingDatetime),
|
||
|
"fundingDatetime": fundingDatetime,
|
||
|
"nextFundingRate": this.SafeNumber(contract, "indicativeFundingRate"),
|
||
|
"nextFundingTimestamp": nil,
|
||
|
"nextFundingDatetime": nil,
|
||
|
"previousFundingRate": nil,
|
||
|
"previousFundingTimestamp": nil,
|
||
|
"previousFundingDatetime": nil,
|
||
|
"interval": nil,
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchFundingRateHistory
|
||
|
* @description Fetches the history of funding rates
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Funding/Funding_get
|
||
|
* @param {string} symbol unified symbol of the market to fetch the funding rate history for
|
||
|
* @param {int} [since] timestamp in ms of the earliest funding rate to fetch
|
||
|
* @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @param {int} [params.until] timestamp in ms for ending date filter
|
||
|
* @param {bool} [params.reverse] if true, will sort results newest first
|
||
|
* @param {int} [params.start] starting point for results
|
||
|
* @param {string} [params.columns] array of column names to fetch in info, if omitted, will return all columns
|
||
|
* @param {string} [params.filter] generic table filter, send json key/value pairs, such as {"key": "value"}, you can key on individual fields, and do more advanced querying on timestamps, see the [timestamp docs]{@link https://www.bitmex.com/app/restAPI#Timestamp-Filters} for more details
|
||
|
* @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure}
|
||
|
*/
|
||
|
func (this *bitmex) FetchFundingRateHistory(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
|
||
|
|
||
|
retRes26878 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes26878)
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
var market interface{} = nil
|
||
|
if IsTrue(InOp(this.Currencies, symbol)) {
|
||
|
var code interface{} = this.Currency(symbol)
|
||
|
AddElementToObject(request, "symbol", GetValue(code, "id"))
|
||
|
} else if IsTrue(!IsEqual(symbol, nil)) {
|
||
|
var splitSymbol interface{} = Split(symbol, ":")
|
||
|
var splitSymbolLength interface{} = GetArrayLength(splitSymbol)
|
||
|
var timeframes interface{} = []interface{}{"nearest", "daily", "weekly", "monthly", "quarterly", "biquarterly", "perpetual"}
|
||
|
if IsTrue(IsTrue((IsGreaterThan(splitSymbolLength, 1))) && IsTrue(this.InArray(GetValue(splitSymbol, 1), timeframes))) {
|
||
|
var code interface{} = this.Currency(GetValue(splitSymbol, 0))
|
||
|
symbol = Add(Add(GetValue(code, "id"), ":"), GetValue(splitSymbol, 1))
|
||
|
AddElementToObject(request, "symbol", symbol)
|
||
|
} else {
|
||
|
market = this.Market(symbol)
|
||
|
AddElementToObject(request, "symbol", GetValue(market, "id"))
|
||
|
}
|
||
|
}
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "startTime", this.Iso8601(since))
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "count", limit)
|
||
|
}
|
||
|
var until interface{} = this.SafeInteger(params, "until")
|
||
|
params = this.Omit(params, []interface{}{"until"})
|
||
|
if IsTrue(!IsEqual(until, nil)) {
|
||
|
AddElementToObject(request, "endTime", this.Iso8601(until))
|
||
|
}
|
||
|
if IsTrue(IsTrue((IsEqual(since, nil))) && IsTrue((IsEqual(until, nil)))) {
|
||
|
AddElementToObject(request, "reverse", true)
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetFunding(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// [
|
||
|
// {
|
||
|
// "timestamp": "2016-05-07T12:00:00.000Z",
|
||
|
// "symbol": "ETHXBT",
|
||
|
// "fundingInterval": "2000-01-02T00:00:00.000Z",
|
||
|
// "fundingRate": 0.0010890000000000001,
|
||
|
// "fundingRateDaily": 0.0010890000000000001
|
||
|
// }
|
||
|
// ]
|
||
|
//
|
||
|
ch <- this.ParseFundingRateHistories(response, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ParseFundingRateHistory(info interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "timestamp": "2016-05-07T12:00:00.000Z",
|
||
|
// "symbol": "ETHXBT",
|
||
|
// "fundingInterval": "2000-01-02T00:00:00.000Z",
|
||
|
// "fundingRate": 0.0010890000000000001,
|
||
|
// "fundingRateDaily": 0.0010890000000000001
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var marketId interface{} = this.SafeString(info, "symbol")
|
||
|
var datetime interface{} = this.SafeString(info, "timestamp")
|
||
|
return map[string]interface{} {
|
||
|
"info": info,
|
||
|
"symbol": this.SafeSymbol(marketId, market),
|
||
|
"fundingRate": this.SafeNumber(info, "fundingRate"),
|
||
|
"timestamp": this.Parse8601(datetime),
|
||
|
"datetime": datetime,
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#setLeverage
|
||
|
* @description set the level of leverage for a market
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Position/Position_updateLeverage
|
||
|
* @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 *bitmex) 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, 0.01))) || IsTrue((IsGreaterThan(leverage, 100)))) {
|
||
|
panic(BadRequest(Add(this.Id, " leverage should be between 0.01 and 100")))
|
||
|
}
|
||
|
|
||
|
retRes27738 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes27738)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
if IsTrue(IsTrue(!IsEqual(GetValue(market, "type"), "swap")) && IsTrue(!IsEqual(GetValue(market, "type"), "future"))) {
|
||
|
panic(BadSymbol(Add(this.Id, " setLeverage() supports future and swap contracts only")))
|
||
|
}
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"symbol": GetValue(market, "id"),
|
||
|
"leverage": leverage,
|
||
|
}
|
||
|
|
||
|
retRes278215 := (<-this.PrivatePostPositionLeverage(this.Extend(request, params)))
|
||
|
PanicOnError(retRes278215)
|
||
|
ch <- retRes278215
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#setMarginMode
|
||
|
* @description set margin mode to 'cross' or 'isolated'
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Position/Position_isolateMargin
|
||
|
* @param {string} marginMode 'cross' or 'isolated'
|
||
|
* @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 *bitmex) SetMarginMode(marginMode 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, " setMarginMode() requires a symbol argument")))
|
||
|
}
|
||
|
marginMode = ToLower(marginMode)
|
||
|
if IsTrue(IsTrue(!IsEqual(marginMode, "isolated")) && IsTrue(!IsEqual(marginMode, "cross"))) {
|
||
|
panic(BadRequest(Add(this.Id, " setMarginMode() marginMode argument should be isolated or cross")))
|
||
|
}
|
||
|
|
||
|
retRes28038 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes28038)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
if IsTrue(IsTrue((!IsEqual(GetValue(market, "type"), "swap"))) && IsTrue((!IsEqual(GetValue(market, "type"), "future")))) {
|
||
|
panic(BadSymbol(Add(this.Id, " setMarginMode() supports swap and future contracts only")))
|
||
|
}
|
||
|
var enabled interface{} = Ternary(IsTrue((IsEqual(marginMode, "cross"))), false, true)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"symbol": GetValue(market, "id"),
|
||
|
"enabled": enabled,
|
||
|
}
|
||
|
|
||
|
retRes281315 := (<-this.PrivatePostPositionIsolate(this.Extend(request, params)))
|
||
|
PanicOnError(retRes281315)
|
||
|
ch <- retRes281315
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchDepositAddress
|
||
|
* @description fetch the deposit address for a currency associated with this account
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/User/User_getDepositAddress
|
||
|
* @param {string} code unified currency code
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @param {string} [params.network] deposit chain, can view all chains via this.publicGetWalletAssets, default is eth, unless the currency has a default chain within this.options['networks']
|
||
|
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
||
|
*/
|
||
|
func (this *bitmex) FetchDepositAddress(code 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
|
||
|
|
||
|
retRes28278 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes28278)
|
||
|
var networkCode interface{} = nil
|
||
|
networkCodeparamsVariable := this.HandleNetworkCodeAndParams(params);
|
||
|
networkCode = GetValue(networkCodeparamsVariable,0);
|
||
|
params = GetValue(networkCodeparamsVariable,1)
|
||
|
if IsTrue(IsEqual(networkCode, nil)) {
|
||
|
panic(ArgumentsRequired(Add(this.Id, " fetchDepositAddress requires params[\"network\"]")))
|
||
|
}
|
||
|
var currency interface{} = this.Currency(code)
|
||
|
params = this.Omit(params, "network")
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"currency": GetValue(currency, "id"),
|
||
|
"network": this.NetworkCodeToId(networkCode, GetValue(currency, "code")),
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivateGetUserDepositAddress(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// '"bc1qmex3puyrzn2gduqcnlu70c2uscpyaa9nm2l2j9le2lt2wkgmw33sy7ndjg"'
|
||
|
//
|
||
|
ch <- map[string]interface{} {
|
||
|
"info": response,
|
||
|
"currency": code,
|
||
|
"network": networkCode,
|
||
|
"address": Replace(Replace(response, "\"", ""), "\"", ""),
|
||
|
"tag": nil,
|
||
|
}
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ParseDepositWithdrawFee(fee interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "asset": "XBT",
|
||
|
// "currency": "XBt",
|
||
|
// "majorCurrency": "XBT",
|
||
|
// "name": "Bitcoin",
|
||
|
// "currencyType": "Crypto",
|
||
|
// "scale": "8",
|
||
|
// "enabled": true,
|
||
|
// "isMarginCurrency": true,
|
||
|
// "minDepositAmount": "10000",
|
||
|
// "minWithdrawalAmount": "1000",
|
||
|
// "maxWithdrawalAmount": "100000000000000",
|
||
|
// "networks": [
|
||
|
// {
|
||
|
// "asset": "btc",
|
||
|
// "tokenAddress": '',
|
||
|
// "depositEnabled": true,
|
||
|
// "withdrawalEnabled": true,
|
||
|
// "withdrawalFee": "20000",
|
||
|
// "minFee": "20000",
|
||
|
// "maxFee": "10000000"
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
currency := GetArg(optionalArgs, 0, nil)
|
||
|
_ = currency
|
||
|
var networks interface{} = this.SafeValue(fee, "networks", []interface{}{})
|
||
|
var networksLength interface{} = GetArrayLength(networks)
|
||
|
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(networksLength, 0)) {
|
||
|
var scale interface{} = this.SafeString(fee, "scale")
|
||
|
var precision interface{} = this.ParsePrecision(scale)
|
||
|
for i := 0; IsLessThan(i, networksLength); i++ {
|
||
|
var network interface{} = GetValue(networks, i)
|
||
|
var networkId interface{} = this.SafeString(network, "asset")
|
||
|
var currencyCode interface{} = this.SafeString(currency, "code")
|
||
|
var networkCode interface{} = this.NetworkIdToCode(networkId, currencyCode)
|
||
|
var withdrawalFeeId interface{} = this.SafeString(network, "withdrawalFee")
|
||
|
var withdrawalFee interface{} = this.ParseNumber(Precise.StringMul(withdrawalFeeId, precision))
|
||
|
AddElementToObject(GetValue(result, "networks"), networkCode, map[string]interface{} {
|
||
|
"deposit": map[string]interface{} {
|
||
|
"fee": nil,
|
||
|
"percentage": nil,
|
||
|
},
|
||
|
"withdraw": map[string]interface{} {
|
||
|
"fee": withdrawalFee,
|
||
|
"percentage": false,
|
||
|
},
|
||
|
})
|
||
|
if IsTrue(IsEqual(networksLength, 1)) {
|
||
|
AddElementToObject(GetValue(result, "withdraw"), "fee", withdrawalFee)
|
||
|
AddElementToObject(GetValue(result, "withdraw"), "percentage", false)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return result
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchDepositWithdrawFees
|
||
|
* @description fetch deposit and withdraw fees
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Wallet/Wallet_getAssetsConfig
|
||
|
* @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 *bitmex) 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
|
||
|
|
||
|
retRes29268 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes29268)
|
||
|
|
||
|
assets:= (<-this.PublicGetWalletAssets(params))
|
||
|
PanicOnError(assets)
|
||
|
|
||
|
//
|
||
|
// [
|
||
|
// {
|
||
|
// "asset": "XBT",
|
||
|
// "currency": "XBt",
|
||
|
// "majorCurrency": "XBT",
|
||
|
// "name": "Bitcoin",
|
||
|
// "currencyType": "Crypto",
|
||
|
// "scale": "8",
|
||
|
// "enabled": true,
|
||
|
// "isMarginCurrency": true,
|
||
|
// "minDepositAmount": "10000",
|
||
|
// "minWithdrawalAmount": "1000",
|
||
|
// "maxWithdrawalAmount": "100000000000000",
|
||
|
// "networks": [
|
||
|
// {
|
||
|
// "asset": "btc",
|
||
|
// "tokenAddress": '',
|
||
|
// "depositEnabled": true,
|
||
|
// "withdrawalEnabled": true,
|
||
|
// "withdrawalFee": "20000",
|
||
|
// "minFee": "20000",
|
||
|
// "maxFee": "10000000"
|
||
|
// }
|
||
|
// ]
|
||
|
// },
|
||
|
// ...
|
||
|
// ]
|
||
|
//
|
||
|
ch <- this.ParseDepositWithdrawFees(assets, codes, "asset")
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) CalculateRateLimiterCost(api interface{}, method interface{}, path interface{}, params interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
config := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
|
_ = config
|
||
|
var isAuthenticated interface{} = this.CheckRequiredCredentials(false)
|
||
|
var cost interface{} = this.SafeValue(config, "cost", 1)
|
||
|
if IsTrue(!IsEqual(cost, 1)) {
|
||
|
if IsTrue(isAuthenticated) {
|
||
|
return cost
|
||
|
} else {
|
||
|
return 20
|
||
|
}
|
||
|
}
|
||
|
return cost
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name bitmex#fetchLiquidations
|
||
|
* @description retrieves the public liquidations of a trading pair
|
||
|
* @see https://www.bitmex.com/api/explorer/#!/Liquidation/Liquidation_get
|
||
|
* @param {string} symbol unified CCXT market symbol
|
||
|
* @param {int} [since] the earliest time in ms to fetch liquidations for
|
||
|
* @param {int} [limit] the maximum number of liquidation structures to retrieve
|
||
|
* @param {object} [params] exchange specific parameters for the bitmex api endpoint
|
||
|
* @param {int} [params.until] timestamp in ms of the latest liquidation
|
||
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
|
* @returns {object} an array of [liquidation structures]{@link https://docs.ccxt.com/#/?id=liquidation-structure}
|
||
|
*/
|
||
|
func (this *bitmex) FetchLiquidations(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
|
||
|
|
||
|
retRes29878 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes29878)
|
||
|
var paginate interface{} = false
|
||
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchLiquidations", "paginate");
|
||
|
paginate = GetValue(paginateparamsVariable,0);
|
||
|
params = GetValue(paginateparamsVariable,1)
|
||
|
if IsTrue(paginate) {
|
||
|
|
||
|
retRes299119 := (<-this.FetchPaginatedCallDynamic("fetchLiquidations", symbol, since, limit, params))
|
||
|
PanicOnError(retRes299119)
|
||
|
ch <- retRes299119
|
||
|
return nil
|
||
|
}
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
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, "count", limit)
|
||
|
}
|
||
|
requestparamsVariable := this.HandleUntilOption("endTime", request, params);
|
||
|
request = GetValue(requestparamsVariable,0);
|
||
|
params = GetValue(requestparamsVariable,1)
|
||
|
|
||
|
response:= (<-this.PublicGetLiquidation(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// [
|
||
|
// {
|
||
|
// "orderID": "string",
|
||
|
// "symbol": "string",
|
||
|
// "side": "string",
|
||
|
// "price": 0,
|
||
|
// "leavesQty": 0
|
||
|
// }
|
||
|
// ]
|
||
|
//
|
||
|
ch <- this.ParseLiquidations(response, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *bitmex) ParseLiquidation(liquidation interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "orderID": "string",
|
||
|
// "symbol": "string",
|
||
|
// "side": "string",
|
||
|
// "price": 0,
|
||
|
// "leavesQty": 0
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var marketId interface{} = this.SafeString(liquidation, "symbol")
|
||
|
return this.SafeLiquidation(map[string]interface{} {
|
||
|
"info": liquidation,
|
||
|
"symbol": this.SafeSymbol(marketId, market),
|
||
|
"contracts": nil,
|
||
|
"contractSize": this.SafeNumber(market, "contractSize"),
|
||
|
"price": this.SafeNumber(liquidation, "price"),
|
||
|
"baseValue": nil,
|
||
|
"quoteValue": nil,
|
||
|
"timestamp": nil,
|
||
|
"datetime": nil,
|
||
|
})
|
||
|
}
|
||
|
func (this *bitmex) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} {
|
||
|
if IsTrue(IsEqual(response, nil)) {
|
||
|
return nil
|
||
|
}
|
||
|
if IsTrue(IsEqual(code, 429)) {
|
||
|
panic(DDoSProtection(Add(Add(this.Id, " "), body)))
|
||
|
}
|
||
|
if IsTrue(IsGreaterThanOrEqual(code, 400)) {
|
||
|
var error interface{} = this.SafeValue(response, "error", map[string]interface{} {})
|
||
|
var message interface{} = this.SafeString(error, "message")
|
||
|
var feedback interface{} = Add(Add(this.Id, " "), body)
|
||
|
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), message, feedback)
|
||
|
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, feedback)
|
||
|
if IsTrue(IsEqual(code, 400)) {
|
||
|
panic(BadRequest(feedback))
|
||
|
}
|
||
|
panic(ExchangeError(feedback))
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
func (this *bitmex) Nonce() interface{} {
|
||
|
return this.Milliseconds()
|
||
|
}
|
||
|
func (this *bitmex) 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 query interface{} = Add(Add(Add("/api/", this.Version), "/"), path)
|
||
|
if IsTrue(IsEqual(method, "GET")) {
|
||
|
if IsTrue(GetArrayLength(ObjectKeys(params))) {
|
||
|
query = Add(query, Add("?", this.Urlencode(params)))
|
||
|
}
|
||
|
} else {
|
||
|
var format interface{} = this.SafeString(params, "_format")
|
||
|
if IsTrue(!IsEqual(format, nil)) {
|
||
|
query = Add(query, Add("?", this.Urlencode(map[string]interface{} {
|
||
|
"_format": format,
|
||
|
})))
|
||
|
params = this.Omit(params, "_format")
|
||
|
}
|
||
|
}
|
||
|
var url interface{} = Add(GetValue(GetValue(this.Urls, "api"), api), query)
|
||
|
var isAuthenticated interface{} = this.CheckRequiredCredentials(false)
|
||
|
if IsTrue(IsTrue(IsEqual(api, "private")) || IsTrue((IsTrue(IsEqual(api, "public")) && IsTrue(isAuthenticated)))) {
|
||
|
this.CheckRequiredCredentials()
|
||
|
var auth interface{} = Add(method, query)
|
||
|
var expires interface{} = this.SafeInteger(this.Options, "api-expires")
|
||
|
headers = map[string]interface{} {
|
||
|
"Content-Type": "application/json",
|
||
|
"api-key": this.ApiKey,
|
||
|
}
|
||
|
expires = this.Sum(this.Seconds(), expires)
|
||
|
var stringExpires interface{} = ToString(expires)
|
||
|
auth = Add(auth, stringExpires)
|
||
|
AddElementToObject(headers, "api-expires", stringExpires)
|
||
|
if IsTrue(IsTrue(IsTrue(IsEqual(method, "POST")) || IsTrue(IsEqual(method, "PUT"))) || IsTrue(IsEqual(method, "DELETE"))) {
|
||
|
if IsTrue(GetArrayLength(ObjectKeys(params))) {
|
||
|
body = this.Json(params)
|
||
|
auth = Add(auth, body)
|
||
|
}
|
||
|
}
|
||
|
AddElementToObject(headers, "api-signature", this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha256))
|
||
|
}
|
||
|
return map[string]interface{} {
|
||
|
"url": url,
|
||
|
"method": method,
|
||
|
"body": body,
|
||
|
"headers": headers,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
func (this *bitmex) Init(userConfig map[string]interface{}) {
|
||
|
this.Exchange = Exchange{}
|
||
|
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
|
||
|
this.Exchange.DerivedExchange = this
|
||
|
}
|