ccxt-go/bitmex.go

3655 lines
161 KiB
Go
Raw Permalink Normal View History

2025-02-28 10:33:20 +08:00
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
}