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 phemex struct { Exchange } func NewPhemexCore() phemex { p := phemex{} setDefaults(&p) return p } func (this *phemex) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "phemex", "name": "Phemex", "countries": []interface{}{"CN"}, "rateLimit": 120.5, "version": "v1", "certified": false, "pro": true, "hostname": "api.phemex.com", "has": map[string]interface{} { "CORS": nil, "spot": true, "margin": false, "swap": true, "future": false, "option": false, "addMargin": false, "cancelAllOrders": true, "cancelOrder": true, "closePosition": false, "createConvertTrade": true, "createOrder": true, "createReduceOnlyOrder": true, "createStopLimitOrder": true, "createStopMarketOrder": true, "createStopOrder": true, "editOrder": true, "fetchBalance": true, "fetchBorrowRateHistories": false, "fetchBorrowRateHistory": false, "fetchClosedOrders": true, "fetchConvertQuote": true, "fetchConvertTrade": false, "fetchConvertTradeHistory": true, "fetchCrossBorrowRate": false, "fetchCrossBorrowRates": false, "fetchCurrencies": true, "fetchDepositAddress": true, "fetchDepositAddresses": false, "fetchDepositAddressesByNetwork": false, "fetchDeposits": true, "fetchFundingHistory": true, "fetchFundingRate": true, "fetchFundingRateHistories": false, "fetchFundingRateHistory": true, "fetchFundingRates": false, "fetchIndexOHLCV": false, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": false, "fetchLeverage": false, "fetchLeverageTiers": true, "fetchMarketLeverageTiers": "emulated", "fetchMarkets": true, "fetchMarkOHLCV": false, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenInterest": true, "fetchOpenOrders": true, "fetchOrder": true, "fetchOrderBook": true, "fetchOrders": true, "fetchPositions": true, "fetchPositionsRisk": false, "fetchPremiumIndexOHLCV": false, "fetchTicker": true, "fetchTickers": true, "fetchTrades": true, "fetchTradingFee": false, "fetchTradingFees": false, "fetchTransfers": true, "fetchWithdrawals": true, "reduceMargin": false, "sandbox": true, "setLeverage": true, "setMargin": true, "setMarginMode": true, "setPositionMode": true, "transfer": true, "withdraw": true, }, "urls": map[string]interface{} { "logo": "https://user-images.githubusercontent.com/1294454/85225056-221eb600-b3d7-11ea-930d-564d2690e3f6.jpg", "test": map[string]interface{} { "v1": "https://testnet-api.phemex.com/v1", "v2": "https://testnet-api.phemex.com", "public": "https://testnet-api.phemex.com/exchange/public", "private": "https://testnet-api.phemex.com", }, "api": map[string]interface{} { "v1": "https://{hostname}/v1", "v2": "https://{hostname}", "public": "https://{hostname}/exchange/public", "private": "https://{hostname}", }, "www": "https://phemex.com", "doc": "https://phemex-docs.github.io/#overview", "fees": "https://phemex.com/fees-conditions", "referral": map[string]interface{} { "url": "https://phemex.com/register?referralCode=EDNVJ", "discount": 0.1, }, }, "timeframes": map[string]interface{} { "1m": "60", "3m": "180", "5m": "300", "15m": "900", "30m": "1800", "1h": "3600", "2h": "7200", "3h": "10800", "4h": "14400", "6h": "21600", "12h": "43200", "1d": "86400", "1w": "604800", "1M": "2592000", "3M": "7776000", "1Y": "31104000", }, "api": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "cfg/v2/products": 5, "cfg/fundingRates": 5, "products": 5, "nomics/trades": 5, "md/kline": 5, "md/v2/kline/list": 5, "md/v2/kline": 5, "md/v2/kline/last": 5, "md/orderbook": 5, "md/trade": 5, "md/spot/ticker/24hr": 5, "exchange/public/cfg/chain-settings": 5, }, }, "v1": map[string]interface{} { "get": map[string]interface{} { "md/fullbook": 5, "md/orderbook": 5, "md/trade": 5, "md/ticker/24hr": 5, "md/ticker/24hr/all": 5, "md/spot/ticker/24hr": 5, "md/spot/ticker/24hr/all": 5, "exchange/public/products": 5, "api-data/public/data/funding-rate-history": 5, }, }, "v2": map[string]interface{} { "get": map[string]interface{} { "public/products": 5, "public/products-plus": 5, "md/v2/orderbook": 5, "md/v2/trade": 5, "md/v2/ticker/24hr": 5, "md/v2/ticker/24hr/all": 5, "api-data/public/data/funding-rate-history": 5, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "spot/orders/active": 1, "spot/orders": 1, "spot/wallets": 5, "exchange/spot/order": 5, "exchange/spot/order/trades": 5, "exchange/order/v2/orderList": 5, "exchange/order/v2/tradingList": 5, "accounts/accountPositions": 1, "g-accounts/accountPositions": 1, "accounts/positions": 25, "api-data/futures/funding-fees": 5, "api-data/g-futures/funding-fees": 5, "api-data/futures/orders": 5, "api-data/g-futures/orders": 5, "api-data/futures/orders/by-order-id": 5, "api-data/g-futures/orders/by-order-id": 5, "api-data/futures/trades": 5, "api-data/g-futures/trades": 5, "api-data/futures/trading-fees": 5, "api-data/g-futures/trading-fees": 5, "api-data/futures/v2/tradeAccountDetail": 5, "g-orders/activeList": 1, "orders/activeList": 1, "exchange/order/list": 5, "exchange/order": 5, "exchange/order/trade": 5, "phemex-user/users/children": 5, "phemex-user/wallets/v2/depositAddress": 5, "phemex-user/wallets/tradeAccountDetail": 5, "phemex-deposit/wallets/api/depositAddress": 5, "phemex-deposit/wallets/api/depositHist": 5, "phemex-deposit/wallets/api/chainCfg": 5, "phemex-withdraw/wallets/api/withdrawHist": 5, "phemex-withdraw/wallets/api/asset/info": 5, "phemex-user/order/closedPositionList": 5, "exchange/margins/transfer": 5, "exchange/wallets/confirm/withdraw": 5, "exchange/wallets/withdrawList": 5, "exchange/wallets/depositList": 5, "exchange/wallets/v2/depositAddress": 5, "api-data/spots/funds": 5, "api-data/spots/orders": 5, "api-data/spots/orders/by-order-id": 5, "api-data/spots/pnls": 5, "api-data/spots/trades": 5, "api-data/spots/trades/by-order-id": 5, "assets/convert": 5, "assets/transfer": 5, "assets/spots/sub-accounts/transfer": 5, "assets/futures/sub-accounts/transfer": 5, "assets/quote": 5, }, "post": map[string]interface{} { "spot/orders": 1, "orders": 1, "g-orders": 1, "positions/assign": 5, "exchange/wallets/transferOut": 5, "exchange/wallets/transferIn": 5, "exchange/margins": 5, "exchange/wallets/createWithdraw": 5, "exchange/wallets/cancelWithdraw": 5, "exchange/wallets/createWithdrawAddress": 5, "assets/transfer": 5, "assets/spots/sub-accounts/transfer": 5, "assets/futures/sub-accounts/transfer": 5, "assets/universal-transfer": 5, "assets/convert": 5, "phemex-withdraw/wallets/api/createWithdraw": 5, "phemex-withdraw/wallets/api/cancelWithdraw": 5, }, "put": map[string]interface{} { "spot/orders/create": 1, "spot/orders": 1, "orders/replace": 1, "g-orders/replace": 1, "positions/leverage": 5, "g-positions/leverage": 5, "g-positions/switch-pos-mode-sync": 5, "positions/riskLimit": 5, }, "delete": map[string]interface{} { "spot/orders": 2, "spot/orders/all": 2, "orders/cancel": 1, "orders": 1, "orders/all": 3, "g-orders/cancel": 1, "g-orders": 1, "g-orders/all": 3, }, }, }, "precisionMode": TICK_SIZE, "fees": map[string]interface{} { "trading": map[string]interface{} { "tierBased": false, "percentage": true, "taker": this.ParseNumber("0.001"), "maker": this.ParseNumber("0.001"), }, }, "features": map[string]interface{} { "default": map[string]interface{} { "sandbox": true, "createOrder": map[string]interface{} { "marginMode": false, "triggerPrice": true, "triggerPriceType": map[string]interface{} { "mark": true, "last": true, "index": true, }, "triggerDirection": false, "stopLossPrice": false, "takeProfitPrice": false, "attachedStopLossTakeProfit": nil, "timeInForce": map[string]interface{} { "IOC": true, "FOK": true, "PO": true, "GTD": false, }, "hedged": false, "leverage": false, "marketBuyByCost": true, "marketBuyRequiresPrice": false, "selfTradePrevention": false, "trailing": false, "iceberg": false, }, "createOrders": nil, "fetchMyTrades": map[string]interface{} { "marginMode": false, "limit": 200, "daysBack": 100000, "untilDays": 2, "symbolRequired": false, }, "fetchOrder": map[string]interface{} { "marginMode": false, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchOpenOrders": map[string]interface{} { "marginMode": false, "limit": nil, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchOrders": map[string]interface{} { "marginMode": false, "limit": nil, "daysBack": nil, "untilDays": nil, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchClosedOrders": map[string]interface{} { "marginMode": false, "limit": 200, "daysBack": 100000, "daysBackCanceled": 100000, "untilDays": 2, "trigger": false, "trailing": false, "symbolRequired": false, }, "fetchOHLCV": map[string]interface{} { "limit": 1000, }, }, "spot": map[string]interface{} { "extends": "default", }, "forDerivatives": map[string]interface{} { "extends": "default", "createOrder": map[string]interface{} { "triggerDirection": true, "attachedStopLossTakeProfit": map[string]interface{} { "triggerPriceType": map[string]interface{} { "mark": true, "last": true, "index": true, }, "price": true, }, "hedged": true, }, "fetchOHLCV": map[string]interface{} { "limit": 2000, }, }, "swap": map[string]interface{} { "linear": map[string]interface{} { "extends": "forDerivatives", }, "inverse": map[string]interface{} { "extends": "forDerivatives", }, }, "future": map[string]interface{} { "linear": nil, "inverse": nil, }, }, "requiredCredentials": map[string]interface{} { "apiKey": true, "secret": true, }, "exceptions": map[string]interface{} { "exact": map[string]interface{} { "401": AuthenticationError, "412": BadRequest, "6001": BadRequest, "19999": BadRequest, "10001": DuplicateOrderId, "10002": OrderNotFound, "10003": CancelPending, "10004": CancelPending, "10005": CancelPending, "11001": InsufficientFunds, "11002": InvalidOrder, "11003": InsufficientFunds, "11004": InvalidOrder, "11005": InsufficientFunds, "11006": ExchangeError, "11007": ExchangeError, "11008": ExchangeError, "11009": ExchangeError, "11010": InsufficientFunds, "11011": InvalidOrder, "11012": InvalidOrder, "11013": InvalidOrder, "11014": InvalidOrder, "11015": InvalidOrder, "11016": BadRequest, "11017": ExchangeError, "11018": ExchangeError, "11019": ExchangeError, "11020": ExchangeError, "11021": ExchangeError, "11022": AccountSuspended, "11023": ExchangeError, "11024": ExchangeError, "11025": BadRequest, "11026": ExchangeError, "11027": BadSymbol, "11028": BadSymbol, "11029": ExchangeError, "11030": ExchangeError, "11031": DDoSProtection, "11032": DDoSProtection, "11033": DuplicateOrderId, "11034": InvalidOrder, "11035": InvalidOrder, "11036": InvalidOrder, "11037": InvalidOrder, "11038": InvalidOrder, "11039": InvalidOrder, "11040": InvalidOrder, "11041": InvalidOrder, "11042": InvalidOrder, "11043": InvalidOrder, "11044": InvalidOrder, "11045": InvalidOrder, "11046": InvalidOrder, "11047": InvalidOrder, "11048": InvalidOrder, "11049": InvalidOrder, "11050": InvalidOrder, "11051": InvalidOrder, "11052": InvalidOrder, "11053": InvalidOrder, "11054": InvalidOrder, "11055": InvalidOrder, "11056": InvalidOrder, "11057": InvalidOrder, "11058": InvalidOrder, "11059": InvalidOrder, "11060": InvalidOrder, "11061": CancelPending, "11062": InvalidOrder, "11063": InvalidOrder, "11064": InvalidOrder, "11065": InvalidOrder, "11066": InvalidOrder, "11067": InvalidOrder, "11068": InvalidOrder, "11069": ExchangeError, "11070": BadSymbol, "11071": InvalidOrder, "11072": InvalidOrder, "11073": InvalidOrder, "11074": InvalidOrder, "11075": InvalidOrder, "11076": InvalidOrder, "11077": InvalidOrder, "11078": InvalidOrder, "11079": InvalidOrder, "11080": InvalidOrder, "11081": InvalidOrder, "11082": InsufficientFunds, "11083": InvalidOrder, "11084": InvalidOrder, "11085": DuplicateOrderId, "11086": InvalidOrder, "11087": InvalidOrder, "11088": InvalidOrder, "11089": InvalidOrder, "11090": InvalidOrder, "11091": InvalidOrder, "11092": InvalidOrder, "11093": InvalidOrder, "11094": InvalidOrder, "11095": InvalidOrder, "11096": InvalidOrder, "11097": BadRequest, "11098": BadRequest, "11099": ExchangeError, "11100": InsufficientFunds, "11101": InsufficientFunds, "11102": BadRequest, "11103": BadRequest, "11104": BadRequest, "11105": InsufficientFunds, "11106": InsufficientFunds, "11107": ExchangeError, "11108": InvalidOrder, "11109": InvalidOrder, "11110": InvalidOrder, "11111": InvalidOrder, "11112": InvalidOrder, "11113": BadRequest, "11114": InvalidOrder, "11115": InvalidOrder, "11116": InvalidOrder, "11117": InvalidOrder, "11118": InvalidOrder, "11119": InvalidOrder, "11120": InvalidOrder, "11121": InvalidOrder, "11122": InvalidOrder, "11123": InvalidOrder, "11124": InvalidOrder, "11125": InvalidOrder, "11126": InvalidOrder, "11128": InvalidOrder, "11129": InvalidOrder, "11130": InvalidOrder, "11131": InvalidOrder, "11132": InvalidOrder, "11133": InvalidOrder, "11134": InvalidOrder, "30000": BadRequest, "30018": BadRequest, "34003": PermissionDenied, "35104": InsufficientFunds, "39995": RateLimitExceeded, "39996": PermissionDenied, "39997": BadSymbol, }, "broad": map[string]interface{} { "401 Insufficient privilege": PermissionDenied, "401 Request IP mismatch": PermissionDenied, "Failed to find api-key": AuthenticationError, "Missing required parameter": BadRequest, "API Signature verification failed": AuthenticationError, "Api key not found": AuthenticationError, }, }, "options": map[string]interface{} { "brokerId": "CCXT123456", "x-phemex-request-expiry": 60, "createOrderByQuoteRequiresPrice": true, "networks": map[string]interface{} { "TRC20": "TRX", "ERC20": "ETH", "BEP20": "BNB", }, "defaultNetworks": map[string]interface{} { "USDT": "ETH", }, "defaultSubType": "linear", "accountsByType": map[string]interface{} { "spot": "spot", "swap": "future", }, "stableCoins": []interface{}{"BUSD", "FEI", "TUSD", "USD", "USDC", "USDD", "USDP", "USDT"}, "transfer": map[string]interface{} { "fillResponseFromRequest": true, }, "triggerPriceTypesMap": map[string]interface{} { "last": "ByLastPrice", "mark": "ByMarkPrice", "index": "ByIndexPrice", "ask": "ByAskPrice", "bid": "ByBidPrice", }, }, }) } func (this *phemex) ParseSafeNumber(optionalArgs ...interface{}) interface{} { value := GetArg(optionalArgs, 0, nil) _ = value if IsTrue(IsEqual(value, nil)) { return value } var parts interface{} = Split(value, ",") value = Join(parts, "") parts = Split(value, " ") return this.SafeNumber(parts, 0) } func (this *phemex) ParseSwapMarket(market interface{}) interface{} { // // { // "symbol":"BTCUSD", // // "code":"1", // "type":"Perpetual", // "displaySymbol":"BTC / USD", // "indexSymbol":".BTC", // "markSymbol":".MBTC", // "fundingRateSymbol":".BTCFR", // "fundingRate8hSymbol":".BTCFR8H", // "contractUnderlyingAssets":"USD", // or eg. `1000 SHIB` // "settleCurrency":"BTC", // "quoteCurrency":"USD", // "contractSize":"1 USD", // "lotSize":1, // "tickSize":0.5, // "priceScale":4, // "ratioScale":8, // "pricePrecision":1, // "minPriceEp":5000, // "maxPriceEp":10000000000, // "maxOrderQty":1000000, // "status":"Listed", // "tipOrderQty":1000000, // "listTime":"1574650800000", // "majorSymbol":true, // "steps":"50", // "riskLimits":[ // {"limit":100,"initialMargin":"1.0%","initialMarginEr":1000000,"maintenanceMargin":"0.5%","maintenanceMarginEr":500000}, // {"limit":150,"initialMargin":"1.5%","initialMarginEr":1500000,"maintenanceMargin":"1.0%","maintenanceMarginEr":1000000}, // {"limit":200,"initialMargin":"2.0%","initialMarginEr":2000000,"maintenanceMargin":"1.5%","maintenanceMarginEr":1500000}, // ], // "underlyingSymbol":".BTC", // "baseCurrency":"BTC", // "settlementCurrency":"BTC", // "valueScale":8, // "defaultLeverage":0, // "maxLeverage":100, // "initMarginEr":"1000000", // "maintMarginEr":"500000", // "defaultRiskLimitEv":10000000000, // "deleverage":true, // "makerFeeRateEr":-250000, // "takerFeeRateEr":750000, // "fundingInterval":8, // "marketUrl":"https://phemex.com/trade/BTCUSD", // "description":"BTCUSD is a BTC/USD perpetual contract priced on the .BTC Index. Each contract is worth 1 USD of Bitcoin. Funding is paid and received every 8 hours. At UTC time: 00:00, 08:00, 16:00.", // } // var id interface{} = this.SafeString(market, "symbol") var contractUnderlyingAssets interface{} = this.SafeString(market, "contractUnderlyingAssets") var baseId interface{} = this.SafeString(market, "baseCurrency", contractUnderlyingAssets) var quoteId interface{} = this.SafeString(market, "quoteCurrency") var settleId interface{} = this.SafeString(market, "settleCurrency") var base interface{} = this.SafeCurrencyCode(baseId) base = Replace(base, " ", "") // replace space for junction codes, eg. `1000 SHIB` var quote interface{} = this.SafeCurrencyCode(quoteId) var settle interface{} = this.SafeCurrencyCode(settleId) var inverse interface{} = false if IsTrue(!IsEqual(settleId, quoteId)) { inverse = true // some unhandled cases if IsTrue(!IsTrue((InOp(market, "baseCurrency"))) && IsTrue(IsEqual(base, quote))) { base = settle } } var priceScale interface{} = this.SafeInteger(market, "priceScale") var ratioScale interface{} = this.SafeInteger(market, "ratioScale") var valueScale interface{} = this.SafeInteger(market, "valueScale") var minPriceEp interface{} = this.SafeString(market, "minPriceEp") var maxPriceEp interface{} = this.SafeString(market, "maxPriceEp") var makerFeeRateEr interface{} = this.SafeString(market, "makerFeeRateEr") var takerFeeRateEr interface{} = this.SafeString(market, "takerFeeRateEr") var status interface{} = this.SafeString(market, "status") var contractSizeString interface{} = this.SafeString(market, "contractSize", " ") var contractSize interface{} = nil if IsTrue(IsEqual(settle, "USDT")) { contractSize = this.ParseNumber("1") } else if IsTrue(GetIndexOf(contractSizeString, " ")) { // "1 USD" // "0.005 ETH" var parts interface{} = Split(contractSizeString, " ") contractSize = this.ParseNumber(GetValue(parts, 0)) } else { // "1.0" contractSize = this.ParseNumber(contractSizeString) } return this.SafeMarketStructure(map[string]interface{} { "id": id, "symbol": Add(Add(Add(Add(base, "/"), quote), ":"), settle), "base": base, "quote": quote, "settle": settle, "baseId": baseId, "quoteId": quoteId, "settleId": settleId, "type": "swap", "spot": false, "margin": false, "swap": true, "future": false, "option": false, "active": IsEqual(status, "Listed"), "contract": true, "linear": !IsTrue(inverse), "inverse": inverse, "taker": this.ParseNumber(this.FromEn(takerFeeRateEr, ratioScale)), "maker": this.ParseNumber(this.FromEn(makerFeeRateEr, ratioScale)), "contractSize": contractSize, "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "priceScale": priceScale, "valueScale": valueScale, "ratioScale": ratioScale, "precision": map[string]interface{} { "amount": this.SafeNumber2(market, "lotSize", "qtyStepSize"), "price": this.SafeNumber(market, "tickSize"), }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": this.ParseNumber("1"), "max": this.SafeNumber(market, "maxLeverage"), }, "amount": map[string]interface{} { "min": nil, "max": nil, }, "price": map[string]interface{} { "min": this.ParseNumber(this.FromEn(minPriceEp, priceScale)), "max": this.ParseNumber(this.FromEn(maxPriceEp, priceScale)), }, "cost": map[string]interface{} { "min": nil, "max": this.ParseNumber(this.SafeString(market, "maxOrderQty")), }, }, "created": nil, "info": market, }) } func (this *phemex) ParseSpotMarket(market interface{}) interface{} { // // { // "symbol":"sBTCUSDT", // "code":1001, // "type":"Spot", // "displaySymbol":"BTC / USDT", // "quoteCurrency":"USDT", // "priceScale":8, // "ratioScale":8, // "pricePrecision":2, // "baseCurrency":"BTC", // "baseTickSize":"0.000001 BTC", // "baseTickSizeEv":100, // "quoteTickSize":"0.01 USDT", // "quoteTickSizeEv":1000000, // "baseQtyPrecision":6, // "quoteQtyPrecision":2, // "minOrderValue":"10 USDT", // "minOrderValueEv":1000000000, // "maxBaseOrderSize":"1000 BTC", // "maxBaseOrderSizeEv":100000000000, // "maxOrderValue":"5,000,000 USDT", // "maxOrderValueEv":500000000000000, // "defaultTakerFee":"0.001", // "defaultTakerFeeEr":100000, // "defaultMakerFee":"0.001", // "defaultMakerFeeEr":100000, // "description":"BTCUSDT is a BTC/USDT spot trading pair. Minimum order value is 1 USDT", // "status":"Listed", // "tipOrderQty":2, // "listTime":1589338800000, // "buyPriceUpperLimitPct":110, // "sellPriceLowerLimitPct":90, // "leverage":5 // }, // var typeVar interface{} = this.SafeStringLower(market, "type") var id interface{} = this.SafeString(market, "symbol") var quoteId interface{} = this.SafeString(market, "quoteCurrency") var baseId interface{} = this.SafeString(market, "baseCurrency") var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) var status interface{} = this.SafeString(market, "status") var precisionAmount interface{} = this.ParseSafeNumber(this.SafeString(market, "baseTickSize")) var precisionPrice interface{} = this.ParseSafeNumber(this.SafeString(market, "quoteTickSize")) return this.SafeMarketStructure(map[string]interface{} { "id": id, "symbol": Add(Add(base, "/"), quote), "base": base, "quote": quote, "settle": nil, "baseId": baseId, "quoteId": quoteId, "settleId": nil, "type": typeVar, "spot": true, "margin": false, "swap": false, "future": false, "option": false, "active": IsEqual(status, "Listed"), "contract": false, "linear": nil, "inverse": nil, "taker": this.SafeNumber(market, "defaultTakerFee"), "maker": this.SafeNumber(market, "defaultMakerFee"), "contractSize": nil, "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "priceScale": this.SafeInteger(market, "priceScale"), "valueScale": this.SafeInteger(market, "valueScale"), "ratioScale": this.SafeInteger(market, "ratioScale"), "precision": map[string]interface{} { "amount": precisionAmount, "price": precisionPrice, }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": nil, "max": nil, }, "amount": map[string]interface{} { "min": precisionAmount, "max": this.ParseSafeNumber(this.SafeString(market, "maxBaseOrderSize")), }, "price": map[string]interface{} { "min": precisionPrice, "max": nil, }, "cost": map[string]interface{} { "min": this.ParseSafeNumber(this.SafeString(market, "minOrderValue")), "max": this.ParseSafeNumber(this.SafeString(market, "maxOrderValue")), }, }, "created": this.SafeInteger(market, "listTime"), "info": market, }) } /** * @method * @name phemex#fetchMarkets * @description retrieves data on all markets for phemex * @see https://phemex-docs.github.io/#query-product-information-3 * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *phemex) FetchMarkets(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var v2ProductsPromise interface{} = this.V2GetPublicProducts(params) // // { // "code":0, // "msg":"", // "data":{ // "currencies":[ // {"currency":"BTC","name":"Bitcoin","code":1,"valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"BTC","inAssetsDisplay":1,"perpetual":0,"stableCoin":0,"assetsPrecision":8}, // {"currency":"USD","name":"USD","code":2,"valueScale":4,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"USD","inAssetsDisplay":1,"perpetual":0,"stableCoin":0,"assetsPrecision":2}, // {"currency":"USDT","name":"TetherUS","code":3,"valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"USDT","inAssetsDisplay":1,"perpetual":2,"stableCoin":1,"assetsPrecision":8}, // ], // "products":[ // { // "symbol":"BTCUSD", // "code":1, // "type":"Perpetual" // "displaySymbol":"BTC / USD", // "indexSymbol":".BTC", // "markSymbol":".MBTC", // "fundingRateSymbol":".BTCFR", // "fundingRate8hSymbol":".BTCFR8H", // "contractUnderlyingAssets":"USD", // "settleCurrency":"BTC", // "quoteCurrency":"USD", // "contractSize":1.0, // "lotSize":1, // "tickSize":0.5, // "priceScale":4, // "ratioScale":8, // "pricePrecision":1, // "minPriceEp":5000, // "maxPriceEp":10000000000, // "maxOrderQty":1000000, // "description":"BTC/USD perpetual contracts are priced on the .BTC Index. Each contract is worth 1 USD. Funding fees are paid and received every 8 hours at UTC time: 00:00, 08:00 and 16:00.", // "status":"Listed", // "tipOrderQty":1000000, // "listTime":1574650800000, // "majorSymbol":true, // "defaultLeverage":"-10", // "fundingInterval":28800, // "maxLeverage":100 // }, // { // "symbol":"sBTCUSDT", // "code":1001, // "type":"Spot", // "displaySymbol":"BTC / USDT", // "quoteCurrency":"USDT", // "priceScale":8, // "ratioScale":8, // "pricePrecision":2, // "baseCurrency":"BTC", // "baseTickSize":"0.000001 BTC", // "baseTickSizeEv":100, // "quoteTickSize":"0.01 USDT", // "quoteTickSizeEv":1000000, // "baseQtyPrecision":6, // "quoteQtyPrecision":2, // "minOrderValue":"10 USDT", // "minOrderValueEv":1000000000, // "maxBaseOrderSize":"1000 BTC", // "maxBaseOrderSizeEv":100000000000, // "maxOrderValue":"5,000,000 USDT", // "maxOrderValueEv":500000000000000, // "defaultTakerFee":"0.001", // "defaultTakerFeeEr":100000, // "defaultMakerFee":"0.001", // "defaultMakerFeeEr":100000, // "description":"BTCUSDT is a BTC/USDT spot trading pair. Minimum order value is 1 USDT", // "status":"Listed", // "tipOrderQty":2, // "listTime":1589338800000, // "buyPriceUpperLimitPct":110, // "sellPriceLowerLimitPct":90, // "leverage":5 // }, // ], // "perpProductsV2":[ // { // "symbol":"BTCUSDT", // "code":41541, // "type":"PerpetualV2", // "displaySymbol":"BTC / USDT", // "indexSymbol":".BTCUSDT", // "markSymbol":".MBTCUSDT", // "fundingRateSymbol":".BTCUSDTFR", // "fundingRate8hSymbol":".BTCUSDTFR8H", // "contractUnderlyingAssets":"BTC", // "settleCurrency":"USDT", // "quoteCurrency":"USDT", // "tickSize":"0.1", // "priceScale":0, // "ratioScale":0, // "pricePrecision":1, // "baseCurrency":"BTC", // "description":"BTC/USDT perpetual contracts are priced on the .BTCUSDT Index. Each contract is worth 1 BTC. Funding fees are paid and received every 8 hours at UTC time: 00:00, 08:00 and 16:00.", // "status":"Listed", // "tipOrderQty":0, // "listTime":1668225600000, // "majorSymbol":true, // "defaultLeverage":"-10", // "fundingInterval":28800, // "maxLeverage":100, // "maxOrderQtyRq":"1000", // "maxPriceRp":"2000000000", // "minOrderValueRv":"1", // "minPriceRp":"1000.0", // "qtyPrecision":3, // "qtyStepSize":"0.001", // "tipOrderQtyRq":"200", // "maxOpenPosLeverage":100.0 // }, // ], // "riskLimits":[ // { // "symbol":"BTCUSD", // "steps":"50", // "riskLimits":[ // {"limit":100,"initialMargin":"1.0%","initialMarginEr":1000000,"maintenanceMargin":"0.5%","maintenanceMarginEr":500000}, // {"limit":150,"initialMargin":"1.5%","initialMarginEr":1500000,"maintenanceMargin":"1.0%","maintenanceMarginEr":1000000}, // {"limit":200,"initialMargin":"2.0%","initialMarginEr":2000000,"maintenanceMargin":"1.5%","maintenanceMarginEr":1500000}, // ] // }, // ], // "leverages":[ // {"initialMargin":"1.0%","initialMarginEr":1000000,"options":[1,2,3,5,10,25,50,100]}, // {"initialMargin":"1.5%","initialMarginEr":1500000,"options":[1,2,3,5,10,25,50,66]}, // {"initialMargin":"2.0%","initialMarginEr":2000000,"options":[1,2,3,5,10,25,33,50]}, // ], // "riskLimitsV2":[ // { // "symbol":"BTCUSDT", // "steps":"2000K", // "riskLimits":[ // {"limit":2000000,"initialMarginRr":"0.01","maintenanceMarginRr":"0.005"},, // {"limit":4000000,"initialMarginRr":"0.015","maintenanceMarginRr":"0.0075"}, // {"limit":6000000,"initialMarginRr":"0.02","maintenanceMarginRr":"0.01"}, // ] // }, // ], // "leveragesV2":[ // {"options":[1.0,2.0,3.0,5.0,10.0,25.0,50.0,100.0],"initialMarginRr":"0.01"}, // {"options":[1.0,2.0,3.0,5.0,10.0,25.0,50.0,66.67],"initialMarginRr":"0.015"}, // {"options":[1.0,2.0,3.0,5.0,10.0,25.0,33.0,50.0],"initialMarginRr":"0.02"}, // ], // "ratioScale":8, // "md5Checksum":"5c6604814d3c1bafbe602c3d11a7e8bf", // } // } // var v1ProductsPromise interface{} = this.V1GetExchangePublicProducts(params) v2Productsv1ProductsVariable := (<-promiseAll([]interface{}{v2ProductsPromise, v1ProductsPromise})); v2Products := GetValue(v2Productsv1ProductsVariable,0); v1Products := GetValue(v2Productsv1ProductsVariable,1) var v1ProductsData interface{} = this.SafeValue(v1Products, "data", []interface{}{}) // // { // "code":0, // "msg":"OK", // "data":[ // { // "symbol":"BTCUSD", // "underlyingSymbol":".BTC", // "quoteCurrency":"USD", // "baseCurrency":"BTC", // "settlementCurrency":"BTC", // "maxOrderQty":1000000, // "maxPriceEp":100000000000000, // "lotSize":1, // "tickSize":"0.5", // "contractSize":"1 USD", // "priceScale":4, // "ratioScale":8, // "valueScale":8, // "defaultLeverage":0, // "maxLeverage":100, // "initMarginEr":"1000000", // "maintMarginEr":"500000", // "defaultRiskLimitEv":10000000000, // "deleverage":true, // "makerFeeRateEr":-250000, // "takerFeeRateEr":750000, // "fundingInterval":8, // "marketUrl":"https://phemex.com/trade/BTCUSD", // "description":"BTCUSD is a BTC/USD perpetual contract priced on the .BTC Index. Each contract is worth 1 USD of Bitcoin. Funding is paid and received every 8 hours. At UTC time: 00:00, 08:00, 16:00.", // "type":"Perpetual" // }, // ] // } // var v2ProductsData interface{} = this.SafeDict(v2Products, "data", map[string]interface{} {}) var products interface{} = this.SafeList(v2ProductsData, "products", []interface{}{}) var perpetualProductsV2 interface{} = this.SafeList(v2ProductsData, "perpProductsV2", []interface{}{}) products = this.ArrayConcat(products, perpetualProductsV2) var riskLimits interface{} = this.SafeList(v2ProductsData, "riskLimits", []interface{}{}) var riskLimitsV2 interface{} = this.SafeList(v2ProductsData, "riskLimitsV2", []interface{}{}) riskLimits = this.ArrayConcat(riskLimits, riskLimitsV2) var currencies interface{} = this.SafeList(v2ProductsData, "currencies", []interface{}{}) var riskLimitsById interface{} = this.IndexBy(riskLimits, "symbol") var v1ProductsById interface{} = this.IndexBy(v1ProductsData, "symbol") var currenciesByCode interface{} = this.IndexBy(currencies, "currency") var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(products)); i++ { var market interface{} = GetValue(products, i) var typeVar interface{} = this.SafeStringLower(market, "type") if IsTrue(IsTrue(IsTrue((IsEqual(typeVar, "perpetual"))) || IsTrue((IsEqual(typeVar, "perpetualv2")))) || IsTrue((IsEqual(typeVar, "perpetualpilot")))) { var id interface{} = this.SafeString(market, "symbol") var riskLimitValues interface{} = this.SafeDict(riskLimitsById, id, map[string]interface{} {}) market = this.Extend(market, riskLimitValues) var v1ProductsValues interface{} = this.SafeDict(v1ProductsById, id, map[string]interface{} {}) market = this.Extend(market, v1ProductsValues) market = this.ParseSwapMarket(market) } else { var baseCurrency interface{} = this.SafeString(market, "baseCurrency") var currencyValues interface{} = this.SafeDict(currenciesByCode, baseCurrency, map[string]interface{} {}) var valueScale interface{} = this.SafeString(currencyValues, "valueScale", "8") market = this.Extend(market, map[string]interface{} { "valueScale": valueScale, }) market = this.ParseSpotMarket(market) } AppendToArray(&result,market) } ch <- result return nil }() return ch } /** * @method * @name phemex#fetchCurrencies * @description fetches all available currencies on an exchange * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ func (this *phemex) 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.V2GetPublicProducts(params)) PanicOnError(response) // // { // "code":0, // "msg":"OK", // "data":{ // ..., // "currencies":[ // {"currency":"BTC","name":"Bitcoin","code":1,"valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"BTC","inAssetsDisplay":1,"perpetual":0,"stableCoin":0,"assetsPrecision":8}, // {"currency":"USD","name":"USD","code":2,"valueScale":4,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"USD","inAssetsDisplay":1,"perpetual":0,"stableCoin":0,"assetsPrecision":2}, // {"currency":"USDT","name":"TetherUS","code":3,"valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"needAddrTag":0,"status":"Listed","displayCurrency":"USDT","inAssetsDisplay":1,"perpetual":2,"stableCoin":1,"assetsPrecision":8}, // ], // ... // } // } var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var currencies interface{} = this.SafeValue(data, "currencies", []interface{}{}) var result interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(currencies)); i++ { var currency interface{} = GetValue(currencies, i) var id interface{} = this.SafeString(currency, "currency") var name interface{} = this.SafeString(currency, "name") var code interface{} = this.SafeCurrencyCode(id) var status interface{} = this.SafeString(currency, "status") var valueScaleString interface{} = this.SafeString(currency, "valueScale") var valueScale interface{} = ParseInt(valueScaleString) var minValueEv interface{} = this.SafeString(currency, "minValueEv") var maxValueEv interface{} = this.SafeString(currency, "maxValueEv") var minAmount interface{} = nil var maxAmount interface{} = nil var precision interface{} = nil if IsTrue(!IsEqual(valueScale, nil)) { var precisionString interface{} = this.ParsePrecision(valueScaleString) precision = this.ParseNumber(precisionString) minAmount = this.ParseNumber(Precise.StringMul(minValueEv, precisionString)) maxAmount = this.ParseNumber(Precise.StringMul(maxValueEv, precisionString)) } AddElementToObject(result, code, map[string]interface{} { "id": id, "info": currency, "code": code, "name": name, "active": IsEqual(status, "Listed"), "deposit": nil, "withdraw": nil, "fee": nil, "precision": precision, "limits": map[string]interface{} { "amount": map[string]interface{} { "min": minAmount, "max": maxAmount, }, "withdraw": map[string]interface{} { "min": nil, "max": nil, }, }, "valueScale": valueScale, "networks": map[string]interface{} {}, }) } ch <- result return nil }() return ch } func (this *phemex) CustomParseBidAsk(bidask interface{}, optionalArgs ...interface{}) interface{} { priceKey := GetArg(optionalArgs, 0, 0) _ = priceKey amountKey := GetArg(optionalArgs, 1, 1) _ = amountKey market := GetArg(optionalArgs, 2, nil) _ = market if IsTrue(IsEqual(market, nil)) { panic(ArgumentsRequired(Add(this.Id, " customParseBidAsk() requires a market argument"))) } var amount interface{} = this.SafeString(bidask, amountKey) if IsTrue(GetValue(market, "spot")) { amount = this.FromEv(amount, market) } return []interface{}{this.ParseNumber(this.FromEp(this.SafeString(bidask, priceKey), market)), this.ParseNumber(amount)} } func (this *phemex) CustomParseOrderBook(orderbook interface{}, symbol interface{}, optionalArgs ...interface{}) interface{} { timestamp := GetArg(optionalArgs, 0, nil) _ = timestamp bidsKey := GetArg(optionalArgs, 1, "bids") _ = bidsKey asksKey := GetArg(optionalArgs, 2, "asks") _ = asksKey priceKey := GetArg(optionalArgs, 3, 0) _ = priceKey amountKey := GetArg(optionalArgs, 4, 1) _ = amountKey market := GetArg(optionalArgs, 5, nil) _ = market var result interface{} = map[string]interface{} { "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "nonce": nil, } var sides interface{} = []interface{}{bidsKey, asksKey} for i := 0; IsLessThan(i, GetArrayLength(sides)); i++ { var side interface{} = GetValue(sides, i) var orders interface{} = []interface{}{} var bidasks interface{} = this.SafeValue(orderbook, side) for k := 0; IsLessThan(k, GetArrayLength(bidasks)); k++ { AppendToArray(&orders,this.CustomParseBidAsk(GetValue(bidasks, k), priceKey, amountKey, market)) } AddElementToObject(result, side, orders) } AddElementToObject(result, bidsKey, this.SortBy(GetValue(result, bidsKey), 0, true)) AddElementToObject(result, asksKey, this.SortBy(GetValue(result, asksKey), 0)) return result } /** * @method * @name phemex#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryorderbook * @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 *phemex) 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 retRes12218 := (<-this.LoadMarkets()) PanicOnError(retRes12218) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } var response interface{} = nil if IsTrue(IsTrue(GetValue(market, "linear")) && IsTrue(IsEqual(GetValue(market, "settle"), "USDT"))) { response = (<-this.V2GetMdV2Orderbook(this.Extend(request, params))) PanicOnError(response) } else { if IsTrue(IsTrue((!IsEqual(limit, nil))) && IsTrue((IsLessThanOrEqual(limit, 30)))) { response = (<-this.V1GetMdOrderbook(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V1GetMdFullbook(this.Extend(request, params))) PanicOnError(response) } } // // { // "error": null, // "id": 0, // "result": { // "book": { // "asks": [ // [ 23415000000, 105262000 ], // [ 23416000000, 147914000 ], // [ 23419000000, 160914000 ], // ], // "bids": [ // [ 23360000000, 32995000 ], // [ 23359000000, 221887000 ], // [ 23356000000, 284599000 ], // ], // }, // "depth": 30, // "sequence": 1592059928, // "symbol": "sETHUSDT", // "timestamp": 1592387340020000955, // "type": "snapshot" // } // } // var result interface{} = this.SafeValue(response, "result", map[string]interface{} {}) var book interface{} = this.SafeValue2(result, "book", "orderbook_p", map[string]interface{} {}) var timestamp interface{} = this.SafeIntegerProduct(result, "timestamp", 0.000001) var orderbook interface{} = this.CustomParseOrderBook(book, symbol, timestamp, "bids", "asks", 0, 1, market) AddElementToObject(orderbook, "nonce", this.SafeInteger(result, "sequence")) ch <- orderbook return nil }() return ch } func (this *phemex) ToEn(n interface{}, scale interface{}) interface{} { var stringN interface{} = this.NumberToString(n) precise := NewPrecise(stringN) precise.Decimals = Subtract(precise.Decimals, scale) precise.Reduce() var preciseString interface{} = precise.ToString() return this.ParseToNumeric(preciseString) } func (this *phemex) ToEv(amount interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market if IsTrue(IsTrue((IsEqual(amount, nil))) || IsTrue((IsEqual(market, nil)))) { return amount } return this.ToEn(amount, GetValue(market, "valueScale")) } func (this *phemex) ToEp(price interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market if IsTrue(IsTrue((IsEqual(price, nil))) || IsTrue((IsEqual(market, nil)))) { return price } return this.ToEn(price, GetValue(market, "priceScale")) } func (this *phemex) FromEn(en interface{}, scale interface{}) interface{} { if IsTrue(IsTrue(IsEqual(en, nil)) || IsTrue(IsEqual(scale, nil))) { return nil } precise := NewPrecise(en) precise.Decimals = this.Sum(precise.Decimals, scale) precise.Reduce() return precise.ToString() } func (this *phemex) FromEp(ep interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market if IsTrue(IsTrue((IsEqual(ep, nil))) || IsTrue((IsEqual(market, nil)))) { return ep } return this.FromEn(ep, this.SafeInteger(market, "priceScale")) } func (this *phemex) FromEv(ev interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market if IsTrue(IsTrue((IsEqual(ev, nil))) || IsTrue((IsEqual(market, nil)))) { return ev } return this.FromEn(ev, this.SafeInteger(market, "valueScale")) } func (this *phemex) FromEr(er interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market if IsTrue(IsTrue((IsEqual(er, nil))) || IsTrue((IsEqual(market, nil)))) { return er } return this.FromEn(er, this.SafeInteger(market, "ratioScale")) } func (this *phemex) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { // // [ // 1592467200, // timestamp // 300, // interval // 23376000000, // last // 23322000000, // open // 23381000000, // high // 23315000000, // low // 23367000000, // close // 208671000, // base volume // 48759063370, // quote volume // ] // market := GetArg(optionalArgs, 0, nil) _ = market var baseVolume interface{} = nil if IsTrue(IsTrue((!IsEqual(market, nil))) && IsTrue(GetValue(market, "spot"))) { baseVolume = this.ParseNumber(this.FromEv(this.SafeString(ohlcv, 7), market)) } else { baseVolume = this.SafeNumber(ohlcv, 7) } return []interface{}{this.SafeTimestamp(ohlcv, 0), this.ParseNumber(this.FromEp(this.SafeString(ohlcv, 3), market)), this.ParseNumber(this.FromEp(this.SafeString(ohlcv, 4), market)), this.ParseNumber(this.FromEp(this.SafeString(ohlcv, 5), market)), this.ParseNumber(this.FromEp(this.SafeString(ohlcv, 6), market)), baseVolume} } /** * @method * @name phemex#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#querykline * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#query-kline * @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] *only used for USDT settled contracts, otherwise is emulated and not supported by the exchange* 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 {int} [params.until] *USDT settled/ linear swaps only* end time in ms * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *phemex) 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 retRes13698 := (<-this.LoadMarkets()) PanicOnError(retRes13698) var market interface{} = this.Market(symbol) var userLimit interface{} = limit var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "resolution": this.SafeString(this.Timeframes, timeframe, timeframe), } var until interface{} = this.SafeInteger2(params, "until", "to") params = this.Omit(params, []interface{}{"until"}) var usesSpecialFromToEndpoint interface{} = IsTrue(((IsTrue(GetValue(market, "linear")) || IsTrue(IsEqual(GetValue(market, "settle"), "USDT"))))) && IsTrue((IsTrue((!IsEqual(since, nil))) || IsTrue((!IsEqual(until, nil))))) var maxLimit interface{} = 1000 if IsTrue(usesSpecialFromToEndpoint) { maxLimit = 2000 } if IsTrue(IsEqual(limit, nil)) { limit = maxLimit } AddElementToObject(request, "limit", mathMin(limit, maxLimit)) var response interface{} = nil if IsTrue(IsTrue(GetValue(market, "linear")) || IsTrue(IsEqual(GetValue(market, "settle"), "USDT"))) { if IsTrue(IsTrue((!IsEqual(until, nil))) || IsTrue((!IsEqual(since, nil)))) { var candleDuration interface{} = this.ParseTimeframe(timeframe) if IsTrue(!IsEqual(since, nil)) { since = MathRound(Divide(since, 1000)) AddElementToObject(request, "from", since) } else { // when 'to' is defined since is mandatory since = Subtract((Divide(until, 100)), (Multiply(maxLimit, candleDuration))) } if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "to", MathRound(Divide(until, 1000))) } else { // when since is defined 'to' is mandatory var to interface{} = Add(since, (Multiply(maxLimit, candleDuration))) var now interface{} = this.Seconds() if IsTrue(IsGreaterThan(to, now)) { to = now } AddElementToObject(request, "to", to) } response = (<-this.PublicGetMdV2KlineList(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PublicGetMdV2KlineLast(this.Extend(request, params))) PanicOnError(response) } } else { if IsTrue(!IsEqual(since, nil)) { // phemex also provides kline query with from/to, however, this interface is NOT recommended and does not work properly. // we do not send since param to the exchange, instead we calculate appropriate limit param var duration interface{} = Multiply(this.ParseTimeframe(timeframe), 1000) var timeDelta interface{} = Subtract(this.Milliseconds(), since) limit = this.ParseToInt(Divide(timeDelta, duration)) // setting limit to the number of candles after since } response = (<-this.PublicGetMdV2Kline(this.Extend(request, params))) PanicOnError(response) } // // { // "code":0, // "msg":"OK", // "data":{ // "total":-1, // "rows":[ // [1592467200,300,23376000000,23322000000,23381000000,23315000000,23367000000,208671000,48759063370], // [1592467500,300,23367000000,23314000000,23390000000,23311000000,23331000000,234820000,54848948710], // [1592467800,300,23331000000,23385000000,23391000000,23326000000,23387000000,152931000,35747882250], // ] // } // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var rows interface{} = this.SafeList(data, "rows", []interface{}{}) ch <- this.ParseOHLCVs(rows, market, timeframe, since, userLimit) return nil }() return ch } func (this *phemex) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // spot // // { // "askEp": 943836000000, // "bidEp": 943601000000, // "highEp": 955946000000, // "lastEp": 943803000000, // "lowEp": 924973000000, // "openEp": 948693000000, // "symbol": "sBTCUSDT", // "timestamp": 1592471203505728630, // "turnoverEv": 111822826123103, // "volumeEv": 11880532281 // } // // swap // // { // "askEp": 2332500, // "bidEp": 2331000, // "fundingRateEr": 10000, // "highEp": 2380000, // "indexEp": 2329057, // "lastEp": 2331500, // "lowEp": 2274000, // "markEp": 2329232, // "openEp": 2337500, // "openInterest": 1298050, // "predFundingRateEr": 19921, // "symbol": "ETHUSD", // "timestamp": 1592474241582701416, // "turnoverEv": 47228362330, // "volume": 4053863 // } // linear swap v2 // // { // "closeRp":"16820.5", // "fundingRateRr":"0.0001", // "highRp":"16962.1", // "indexPriceRp":"16830.15651565", // "lowRp":"16785", // "markPriceRp":"16830.97534951", // "openInterestRv":"1323.596", // "openRp":"16851.7", // "predFundingRateRr":"0.0001", // "symbol":"BTCUSDT", // "timestamp":"1672142789065593096", // "turnoverRv":"124835296.0538", // "volumeRq":"7406.95" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(ticker, "symbol") market = this.SafeMarket(marketId, market) var symbol interface{} = GetValue(market, "symbol") var timestamp interface{} = this.SafeIntegerProduct(ticker, "timestamp", 0.000001) var last interface{} = this.FromEp(this.SafeString2(ticker, "lastEp", "closeRp"), market) var quoteVolume interface{} = this.FromEr(this.SafeString2(ticker, "turnoverEv", "turnoverRv"), market) var baseVolume interface{} = this.SafeString(ticker, "volume") if IsTrue(IsEqual(baseVolume, nil)) { baseVolume = this.FromEv(this.SafeString2(ticker, "volumeEv", "volumeRq"), market) } var open interface{} = this.FromEp(this.SafeString(ticker, "openEp"), market) return this.SafeTicker(map[string]interface{} { "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "high": this.FromEp(this.SafeString2(ticker, "highEp", "highRp"), market), "low": this.FromEp(this.SafeString2(ticker, "lowEp", "lowRp"), market), "bid": this.FromEp(this.SafeString(ticker, "bidEp"), market), "bidVolume": nil, "ask": this.FromEp(this.SafeString(ticker, "askEp"), market), "askVolume": nil, "vwap": nil, "open": open, "close": last, "last": last, "previousClose": nil, "change": nil, "percentage": nil, "average": nil, "baseVolume": baseVolume, "quoteVolume": quoteVolume, "info": ticker, }, market) } /** * @method * @name phemex#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query24hrsticker * @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 *phemex) 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 retRes15418 := (<-this.LoadMarkets()) PanicOnError(retRes15418) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } var response interface{} = nil if IsTrue(GetValue(market, "swap")) { if IsTrue(IsTrue(GetValue(market, "inverse")) || IsTrue(IsEqual(GetValue(market, "settle"), "USD"))) { response = (<-this.V1GetMdTicker24hr(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V2GetMdV2Ticker24hr(this.Extend(request, params))) PanicOnError(response) } } else { response = (<-this.V1GetMdSpotTicker24hr(this.Extend(request, params))) PanicOnError(response) } // // spot // // { // "error": null, // "id": 0, // "result": { // "askEp": 943836000000, // "bidEp": 943601000000, // "highEp": 955946000000, // "lastEp": 943803000000, // "lowEp": 924973000000, // "openEp": 948693000000, // "symbol": "sBTCUSDT", // "timestamp": 1592471203505728630, // "turnoverEv": 111822826123103, // "volumeEv": 11880532281 // } // } // // swap // // { // "error": null, // "id": 0, // "result": { // "askEp": 2332500, // "bidEp": 2331000, // "fundingRateEr": 10000, // "highEp": 2380000, // "indexEp": 2329057, // "lastEp": 2331500, // "lowEp": 2274000, // "markEp": 2329232, // "openEp": 2337500, // "openInterest": 1298050, // "predFundingRateEr": 19921, // "symbol": "ETHUSD", // "timestamp": 1592474241582701416, // "turnoverEv": 47228362330, // "volume": 4053863 // } // } // var result interface{} = this.SafeDict(response, "result", map[string]interface{} {}) ch <- this.ParseTicker(result, market) return nil }() return ch } /** * @method * @name phemex#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://phemex-docs.github.io/#query-24-hours-ticker-for-all-symbols-2 // spot * @see https://phemex-docs.github.io/#query-24-ticker-for-all-symbols // linear * @see https://phemex-docs.github.io/#query-24-hours-ticker-for-all-symbols // inverse * @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 *phemex) 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 retRes16178 := (<-this.LoadMarkets()) PanicOnError(retRes16178) var market interface{} = nil if IsTrue(!IsEqual(symbols, nil)) { var first interface{} = this.SafeValue(symbols, 0) market = this.Market(first) } var typeVar interface{} = nil typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchTickers", market, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) var subType interface{} = nil subTypeparamsVariable := this.HandleSubTypeAndParams("fetchTickers", market, params); subType = GetValue(subTypeparamsVariable,0); params = GetValue(subTypeparamsVariable,1) var query interface{} = this.Omit(params, "type") var response interface{} = nil if IsTrue(IsEqual(typeVar, "spot")) { response = (<-this.V1GetMdSpotTicker24hrAll(query)) PanicOnError(response) } else if IsTrue(IsTrue(IsEqual(subType, "inverse")) || IsTrue(IsEqual(this.SafeString(market, "settle"), "USD"))) { response = (<-this.V1GetMdTicker24hrAll(query)) PanicOnError(response) } else { response = (<-this.V2GetMdV2Ticker24hrAll(query)) PanicOnError(response) } var result interface{} = this.SafeList(response, "result", []interface{}{}) ch <- this.ParseTickers(result, symbols) return nil }() return ch } /** * @method * @name phemex#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#querytrades * @param {string} symbol unified symbol of the market to fetch trades for * @param {int} [since] timestamp in ms of the earliest trade to fetch * @param {int} [limit] the maximum amount of trades to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ func (this *phemex) 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 retRes16528 := (<-this.LoadMarkets()) PanicOnError(retRes16528) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } var response interface{} = nil if IsTrue(IsTrue(GetValue(market, "linear")) && IsTrue(IsEqual(GetValue(market, "settle"), "USDT"))) { response = (<-this.V2GetMdV2Trade(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V1GetMdTrade(this.Extend(request, params))) PanicOnError(response) } // // { // "error": null, // "id": 0, // "result": { // "sequence": 1315644947, // "symbol": "BTCUSD", // "trades": [ // [ 1592541746712239749, 13156448570000, "Buy", 93070000, 40173 ], // [ 1592541740434625085, 13156447110000, "Sell", 93065000, 5000 ], // [ 1592541732958241616, 13156441390000, "Buy", 93070000, 3460 ], // ], // "type": "snapshot" // } // } // var result interface{} = this.SafeValue(response, "result", map[string]interface{} {}) var trades interface{} = this.SafeValue2(result, "trades", "trades_p", []interface{}{}) ch <- this.ParseTrades(trades, market, since, limit) return nil }() return ch } func (this *phemex) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // fetchTrades (public) spot & contract // // [ // 1592541746712239749, // 13156448570000, // "Buy", // 93070000, // 40173 // ] // // fetchTrades (public) perp // // [ // 1675690986063435800, // "Sell", // "22857.4", // "0.269" // ] // // fetchMyTrades (private) // // spot // // { // "qtyType": "ByQuote", // "transactTimeNs": 1589450974800550100, // "clOrdID": "8ba59d40-df25-d4b0-14cf-0703f44e9690", // "orderID": "b2b7018d-f02f-4c59-b4cf-051b9c2d2e83", // "symbol": "sBTCUSDT", // "side": "Buy", // "priceEP": 970056000000, // "baseQtyEv": 0, // "quoteQtyEv": 1000000000, // "action": "New", // "execStatus": "MakerFill", // "ordStatus": "Filled", // "ordType": "Limit", // "execInst": "None", // "timeInForce": "GoodTillCancel", // "stopDirection": "UNSPECIFIED", // "tradeType": "Trade", // "stopPxEp": 0, // "execId": "c6bd8979-07ba-5946-b07e-f8b65135dbb1", // "execPriceEp": 970056000000, // "execBaseQtyEv": 103000, // "execQuoteQtyEv": 999157680, // "leavesBaseQtyEv": 0, // "leavesQuoteQtyEv": 0, // "execFeeEv": 0, // "feeRateEr": 0 // "baseCurrency": "BTC", // "quoteCurrency": "USDT", // "feeCurrency": "BTC" // } // // swap // // { // "transactTimeNs": 1578026629824704800, // "symbol": "BTCUSD", // "currency": "BTC", // "action": "Replace", // "side": "Sell", // "tradeType": "Trade", // "execQty": 700, // "execPriceEp": 71500000, // "orderQty": 700, // "priceEp": 71500000, // "execValueEv": 9790209, // "feeRateEr": -25000, // "execFeeEv": -2447, // "ordType": "Limit", // "execID": "b01671a1-5ddc-5def-b80a-5311522fd4bf", // "orderID": "b63bc982-be3a-45e0-8974-43d6375fb626", // "clOrdID": "uuid-1577463487504", // "execStatus": "MakerFill" // } // perpetual // { // "accountID": 9328670003, // "action": "New", // "actionBy": "ByUser", // "actionTimeNs": 1666858780876924611, // "addedSeq": 77751555, // "apRp": "0", // "bonusChangedAmountRv": "0", // "bpRp": "0", // "clOrdID": "c0327a7d-9064-62a9-28f6-2db9aaaa04e0", // "closedPnlRv": "0", // "closedSize": "0", // "code": 0, // "cumFeeRv": "0", // "cumQty": "0", // "cumValueRv": "0", // "curAccBalanceRv": "1508.489893982237", // "curAssignedPosBalanceRv": "24.62786650928", // "curBonusBalanceRv": "0", // "curLeverageRr": "-10", // "curPosSide": "Buy", // "curPosSize": "0.043", // "curPosTerm": 1, // "curPosValueRv": "894.0689", // "curRiskLimitRv": "1000000", // "currency": "USDT", // "cxlRejReason": 0, // "displayQty": "0.003", // "execFeeRv": "0", // "execID": "00000000-0000-0000-0000-000000000000", // "execPriceRp": "20723.7", // "execQty": "0", // "execSeq": 77751555, // "execStatus": "New", // "execValueRv": "0", // "feeRateRr": "0", // "leavesQty": "0.003", // "leavesValueRv": "63.4503", // "message": "No error", // "ordStatus": "New", // "ordType": "Market", // "orderID": "fa64c6f2-47a4-4929-aab4-b7fa9bbc4323", // "orderQty": "0.003", // "pegOffsetValueRp": "0", // "posSide": "Long", // "priceRp": "21150.1", // "relatedPosTerm": 1, // "relatedReqNum": 11, // "side": "Buy", // "slTrigger": "ByMarkPrice", // "stopLossRp": "0", // "stopPxRp": "0", // "symbol": "BTCUSDT", // "takeProfitRp": "0", // "timeInForce": "ImmediateOrCancel", // "tpTrigger": "ByLastPrice", // "tradeType": "Amend", // "transactTimeNs": 1666858780881545305, // "userID": 932867 // } // // swap - USDT // // { // "createdAt": 1666226932259, // "symbol": "ETHUSDT", // "currency": "USDT", // "action": 1, // "tradeType": 1, // "execQtyRq": "0.01", // "execPriceRp": "1271.9", // "side": 1, // "orderQtyRq": "0.78", // "priceRp": "1271.9", // "execValueRv": "12.719", // "feeRateRr": "0.0001", // "execFeeRv": "0.0012719", // "ordType": 2, // "execId": "8718cae", // "execStatus": 6 // } // spot with fees paid using PT token // "createdAt": "1714990724076", // "symbol": "BTCUSDT", // "currency": "USDT", // "action": "1", // "tradeType": "1", // "execQtyRq": "0.003", // "execPriceRp": "64935", // "side": "2", // "orderQtyRq": "0.003", // "priceRp": "51600", // "execValueRv": "194.805", // "feeRateRr": "0.000495", // "execFeeRv": "0", // "ordType": "3", // "execId": "XXXXXX", // "execStatus": "7", // "posSide": "1", // "ptFeeRv": "0.110012249248", // "ptPriceRp": "0.876524893" // market := GetArg(optionalArgs, 0, nil) _ = market var priceString interface{} = nil var amountString interface{} = nil var timestamp interface{} = nil var id interface{} = nil var side interface{} = nil var costString interface{} = nil var typeVar interface{} = nil var fee interface{} = nil var feeCostString interface{} = nil var feeRateString interface{} = nil var feeCurrencyCode interface{} = nil var marketId interface{} = this.SafeString(trade, "symbol") market = this.SafeMarket(marketId, market) var symbol interface{} = GetValue(market, "symbol") var orderId interface{} = nil var takerOrMaker interface{} = nil if IsTrue(IsArray(trade)) { var tradeLength interface{} = GetArrayLength(trade) timestamp = this.SafeIntegerProduct(trade, 0, 0.000001) if IsTrue(IsGreaterThan(tradeLength, 4)) { id = this.SafeString(trade, Subtract(tradeLength, 4)) } side = this.SafeStringLower(trade, Subtract(tradeLength, 3)) priceString = this.SafeString(trade, Subtract(tradeLength, 2)) amountString = this.SafeString(trade, Subtract(tradeLength, 1)) if IsTrue(IsNumber(GetValue(trade, Subtract(tradeLength, 2)))) { priceString = this.FromEp(priceString, market) amountString = this.FromEv(amountString, market) } } else { timestamp = this.SafeIntegerProduct(trade, "transactTimeNs", 0.000001) if IsTrue(IsEqual(timestamp, nil)) { timestamp = this.SafeInteger(trade, "createdAt") } id = this.SafeString2(trade, "execId", "execID") orderId = this.SafeString(trade, "orderID") if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { var sideId interface{} = this.SafeStringLower(trade, "side") if IsTrue(IsTrue((IsEqual(sideId, "buy"))) || IsTrue((IsEqual(sideId, "sell")))) { side = sideId } else if IsTrue(!IsEqual(sideId, nil)) { side = Ternary(IsTrue((IsEqual(sideId, "1"))), "buy", "sell") } var ordType interface{} = this.SafeString(trade, "ordType") if IsTrue(IsEqual(ordType, "1")) { typeVar = "market" } else if IsTrue(IsEqual(ordType, "2")) { typeVar = "limit" } priceString = this.SafeString(trade, "execPriceRp") amountString = this.SafeString(trade, "execQtyRq") costString = this.SafeString(trade, "execValueRv") feeCostString = this.OmitZero(this.SafeString(trade, "execFeeRv")) feeRateString = this.SafeString(trade, "feeRateRr") if IsTrue(!IsEqual(feeCostString, nil)) { var currencyId interface{} = this.SafeString(trade, "currency") feeCurrencyCode = this.SafeCurrencyCode(currencyId) } else { var ptFeeRv interface{} = this.OmitZero(this.SafeString(trade, "ptFeeRv")) if IsTrue(!IsEqual(ptFeeRv, nil)) { feeCostString = ptFeeRv feeCurrencyCode = "PT" } } } else { side = this.SafeStringLower(trade, "side") typeVar = this.ParseOrderType(this.SafeString(trade, "ordType")) var execStatus interface{} = this.SafeString(trade, "execStatus") if IsTrue(IsEqual(execStatus, "MakerFill")) { takerOrMaker = "maker" } priceString = this.FromEp(this.SafeString(trade, "execPriceEp"), market) amountString = this.FromEv(this.SafeString(trade, "execBaseQtyEv"), market) amountString = this.SafeString(trade, "execQty", amountString) costString = this.FromEr(this.SafeString2(trade, "execQuoteQtyEv", "execValueEv"), market) feeCostString = this.FromEr(this.OmitZero(this.SafeString(trade, "execFeeEv")), market) if IsTrue(!IsEqual(feeCostString, nil)) { feeRateString = this.FromEr(this.SafeString(trade, "feeRateEr"), market) if IsTrue(GetValue(market, "spot")) { feeCurrencyCode = this.SafeCurrencyCode(this.SafeString(trade, "feeCurrency")) } else { var info interface{} = this.SafeValue(market, "info") if IsTrue(!IsEqual(info, nil)) { var settlementCurrencyId interface{} = this.SafeString(info, "settlementCurrency") feeCurrencyCode = this.SafeCurrencyCode(settlementCurrencyId) } } } else { feeCostString = this.SafeString(trade, "ptFeeRv") if IsTrue(!IsEqual(feeCostString, nil)) { feeCurrencyCode = "PT" } } } fee = map[string]interface{} { "cost": feeCostString, "rate": feeRateString, "currency": feeCurrencyCode, } } return this.SafeTrade(map[string]interface{} { "info": trade, "id": id, "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "order": orderId, "type": typeVar, "side": side, "takerOrMaker": takerOrMaker, "price": priceString, "amount": amountString, "cost": costString, "fee": fee, }, market) } func (this *phemex) ParseSpotBalance(response interface{}) interface{} { // // { // "code":0, // "msg":"", // "data":[ // { // "currency":"USDT", // "balanceEv":0, // "lockedTradingBalanceEv":0, // "lockedWithdrawEv":0, // "lastUpdateTimeNs":1592065834511322514, // "walletVid":0 // }, // { // "currency":"ETH", // "balanceEv":0, // "lockedTradingBalanceEv":0, // "lockedWithdrawEv":0, // "lastUpdateTimeNs":1592065834511322514, // "walletVid":0 // } // ] // } // var timestamp interface{} = nil var result interface{} = map[string]interface{} { "info": response, } var data interface{} = this.SafeValue(response, "data", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var balance interface{} = GetValue(data, i) var currencyId interface{} = this.SafeString(balance, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) var currency interface{} = this.SafeValue(this.Currencies, code, map[string]interface{} {}) var scale interface{} = this.SafeInteger(currency, "valueScale", 8) var account interface{} = this.Account() var balanceEv interface{} = this.SafeString(balance, "balanceEv") var lockedTradingBalanceEv interface{} = this.SafeString(balance, "lockedTradingBalanceEv") var lockedWithdrawEv interface{} = this.SafeString(balance, "lockedWithdrawEv") var total interface{} = this.FromEn(balanceEv, scale) var lockedTradingBalance interface{} = this.FromEn(lockedTradingBalanceEv, scale) var lockedWithdraw interface{} = this.FromEn(lockedWithdrawEv, scale) var used interface{} = Precise.StringAdd(lockedTradingBalance, lockedWithdraw) var lastUpdateTimeNs interface{} = this.SafeIntegerProduct(balance, "lastUpdateTimeNs", 0.000001) timestamp = Ternary(IsTrue((IsEqual(timestamp, nil))), lastUpdateTimeNs, mathMax(timestamp, lastUpdateTimeNs)) AddElementToObject(account, "total", total) AddElementToObject(account, "used", used) AddElementToObject(result, code, account) } AddElementToObject(result, "timestamp", timestamp) AddElementToObject(result, "datetime", this.Iso8601(timestamp)) return this.SafeBalance(result) } func (this *phemex) ParseSwapBalance(response interface{}) interface{} { // usdt // { // "info": { // "code": "0", // "msg": '', // "data": { // "account": { // "userID": "940666", // "accountId": "9406660003", // "currency": "USDT", // "accountBalanceRv": "99.93143972", // "totalUsedBalanceRv": "0.40456", // "bonusBalanceRv": "0" // }, // } // // { // "code":0, // "msg":"", // "data":{ // "account":{ // "accountId":6192120001, // "currency":"BTC", // "accountBalanceEv":1254744, // "totalUsedBalanceEv":0, // "bonusBalanceEv":1254744 // } // } // } // var result interface{} = map[string]interface{} { "info": response, } var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var balance interface{} = this.SafeValue(data, "account", map[string]interface{} {}) var currencyId interface{} = this.SafeString(balance, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) var currency interface{} = this.Currency(code) var valueScale interface{} = this.SafeInteger(currency, "valueScale", 8) var account interface{} = this.Account() var accountBalanceEv interface{} = this.SafeString2(balance, "accountBalanceEv", "accountBalanceRv") var totalUsedBalanceEv interface{} = this.SafeString2(balance, "totalUsedBalanceEv", "totalUsedBalanceRv") var needsConversion interface{} = (!IsEqual(code, "USDT")) AddElementToObject(account, "total", Ternary(IsTrue(needsConversion), this.FromEn(accountBalanceEv, valueScale), accountBalanceEv)) AddElementToObject(account, "used", Ternary(IsTrue(needsConversion), this.FromEn(totalUsedBalanceEv, valueScale), totalUsedBalanceEv)) AddElementToObject(result, code, account) return this.SafeBalance(result) } /** * @method * @name phemex#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://phemex-docs.github.io/#query-wallets * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-account-positions * @see https://phemex-docs.github.io/#query-trading-account-and-positions * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.type] spot or swap * @param {string} [params.code] *swap only* currency code of the balance to query (USD, USDT, etc), default is USDT * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure} */ func (this *phemex) 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 retRes20988 := (<-this.LoadMarkets()) PanicOnError(retRes20988) var typeVar interface{} = nil typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchBalance", nil, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) var code interface{} = this.SafeString(params, "code") params = this.Omit(params, []interface{}{"code"}) var response interface{} = nil var request interface{} = map[string]interface{} {} if IsTrue(IsTrue((!IsEqual(typeVar, "spot"))) && IsTrue((!IsEqual(typeVar, "swap")))) { panic(BadRequest(Add(Add(Add(this.Id, " does not support "), typeVar), " markets, only spot and swap"))) } if IsTrue(IsEqual(typeVar, "swap")) { var settle interface{} = nil settleparamsVariable := this.HandleOptionAndParams(params, "fetchBalance", "settle", "USDT"); settle = GetValue(settleparamsVariable,0); params = GetValue(settleparamsVariable,1) if IsTrue(IsTrue(!IsEqual(code, nil)) || IsTrue(!IsEqual(settle, nil))) { var coin interface{} = nil if IsTrue(!IsEqual(code, nil)) { coin = code } else { coin = settle } var currency interface{} = this.Currency(coin) AddElementToObject(request, "currency", GetValue(currency, "id")) if IsTrue(IsEqual(GetValue(currency, "id"), "USDT")) { response = (<-this.PrivateGetGAccountsAccountPositions(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateGetAccountsAccountPositions(this.Extend(request, params))) PanicOnError(response) } } else { var currency interface{} = this.SafeString(params, "currency") if IsTrue(IsEqual(currency, nil)) { panic(ArgumentsRequired(Add(Add(Add(this.Id, " fetchBalance() requires a code parameter or a currency or settle parameter for "), typeVar), " type"))) } response = (<-this.PrivateGetSpotWallets(this.Extend(request, params))) PanicOnError(response) } } else { response = (<-this.PrivateGetSpotWallets(this.Extend(request, params))) PanicOnError(response) } // // usdt // { // "info": { // "code": "0", // "msg": '', // "data": { // "account": { // "userID": "940666", // "accountId": "9406660003", // "currency": "USDT", // "accountBalanceRv": "99.93143972", // "totalUsedBalanceRv": "0.40456", // "bonusBalanceRv": "0" // }, // } // // spot // // { // "code":0, // "msg":"", // "data":[ // { // "currency":"USDT", // "balanceEv":0, // "lockedTradingBalanceEv":0, // "lockedWithdrawEv":0, // "lastUpdateTimeNs":1592065834511322514, // "walletVid":0 // }, // { // "currency":"ETH", // "balanceEv":0, // "lockedTradingBalanceEv":0, // "lockedWithdrawEv":0, // "lastUpdateTimeNs":1592065834511322514, // "walletVid":0 // } // ] // } // // swap // // { // "code":0, // "msg":"", // "data":{ // "account":{ // "accountId":6192120001, // "currency":"BTC", // "accountBalanceEv":1254744, // "totalUsedBalanceEv":0, // "bonusBalanceEv":1254744 // }, // "positions":[ // { // "accountID":6192120001, // "symbol":"BTCUSD", // "currency":"BTC", // "side":"None", // "positionStatus":"Normal", // "crossMargin":false, // "leverageEr":0, // "leverage":0E-8, // "initMarginReqEr":1000000, // "initMarginReq":0.01000000, // "maintMarginReqEr":500000, // "maintMarginReq":0.00500000, // "riskLimitEv":10000000000, // "riskLimit":100.00000000, // "size":0, // "value":0E-8, // "valueEv":0, // "avgEntryPriceEp":0, // "avgEntryPrice":0E-8, // "posCostEv":0, // "posCost":0E-8, // "assignedPosBalanceEv":0, // "assignedPosBalance":0E-8, // "bankruptCommEv":0, // "bankruptComm":0E-8, // "bankruptPriceEp":0, // "bankruptPrice":0E-8, // "positionMarginEv":0, // "positionMargin":0E-8, // "liquidationPriceEp":0, // "liquidationPrice":0E-8, // "deleveragePercentileEr":0, // "deleveragePercentile":0E-8, // "buyValueToCostEr":1150750, // "buyValueToCost":0.01150750, // "sellValueToCostEr":1149250, // "sellValueToCost":0.01149250, // "markPriceEp":96359083, // "markPrice":9635.90830000, // "markValueEv":0, // "markValue":null, // "unRealisedPosLossEv":0, // "unRealisedPosLoss":null, // "estimatedOrdLossEv":0, // "estimatedOrdLoss":0E-8, // "usedBalanceEv":0, // "usedBalance":0E-8, // "takeProfitEp":0, // "takeProfit":null, // "stopLossEp":0, // "stopLoss":null, // "realisedPnlEv":0, // "realisedPnl":null, // "cumRealisedPnlEv":0, // "cumRealisedPnl":null // } // ] // } // } // if IsTrue(IsEqual(typeVar, "swap")) { ch <- this.ParseSwapBalance(response) return nil } ch <- this.ParseSpotBalance(response) return nil }() return ch } func (this *phemex) ParseOrderStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "Created": "open", "Untriggered": "open", "Deactivated": "closed", "Triggered": "open", "Rejected": "rejected", "New": "open", "PartiallyFilled": "open", "Filled": "closed", "Canceled": "canceled", "Suspended": "canceled", "1": "open", "2": "canceled", "3": "closed", "4": "canceled", "5": "open", "6": "open", "7": "closed", "8": "canceled", } return this.SafeString(statuses, status, status) } func (this *phemex) ParseOrderType(typeVar interface{}) interface{} { var types interface{} = map[string]interface{} { "1": "market", "2": "limit", "3": "stop", "4": "stopLimit", "5": "market", "6": "limit", "7": "market", "8": "market", "9": "stopLimit", "10": "market", "Limit": "limit", "Market": "market", } return this.SafeString(types, typeVar, typeVar) } func (this *phemex) ParseTimeInForce(timeInForce interface{}) interface{} { var timeInForces interface{} = map[string]interface{} { "GoodTillCancel": "GTC", "PostOnly": "PO", "ImmediateOrCancel": "IOC", "FillOrKill": "FOK", } return this.SafeString(timeInForces, timeInForce, timeInForce) } func (this *phemex) ParseSpotOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // spot // // { // "orderID": "d1d09454-cabc-4a23-89a7-59d43363f16d", // "clOrdID": "309bcd5c-9f6e-4a68-b775-4494542eb5cb", // "priceEp": 0, // "action": "New", // "trigger": "UNSPECIFIED", // "pegPriceType": "UNSPECIFIED", // "stopDirection": "UNSPECIFIED", // "bizError": 0, // "symbol": "sBTCUSDT", // "side": "Buy", // "baseQtyEv": 0, // "ordType": "Limit", // "timeInForce": "GoodTillCancel", // "ordStatus": "Created", // "cumFeeEv": 0, // "cumBaseQtyEv": 0, // "cumQuoteQtyEv": 0, // "leavesBaseQtyEv": 0, // "leavesQuoteQtyEv": 0, // "avgPriceEp": 0, // "cumBaseAmountEv": 0, // "cumQuoteAmountEv": 0, // "quoteQtyEv": 0, // "qtyType": "ByBase", // "stopPxEp": 0, // "pegOffsetValueEp": 0 // } // // { // "orderID":"99232c3e-3d6a-455f-98cc-2061cdfe91bc", // "stopPxEp":0, // "avgPriceEp":0, // "qtyType":"ByBase", // "leavesBaseQtyEv":0, // "leavesQuoteQtyEv":0, // "baseQtyEv":"1000000000", // "feeCurrency":"4", // "stopDirection":"UNSPECIFIED", // "symbol":"sETHUSDT", // "side":"Buy", // "quoteQtyEv":250000000000, // "priceEp":25000000000, // "ordType":"Limit", // "timeInForce":"GoodTillCancel", // "ordStatus":"Rejected", // "execStatus":"NewRejected", // "createTimeNs":1592675305266037130, // "cumFeeEv":0, // "cumBaseValueEv":0, // "cumQuoteValueEv":0 // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString(order, "orderID") var clientOrderId interface{} = this.SafeString(order, "clOrdID") if IsTrue(IsTrue((!IsEqual(clientOrderId, nil))) && IsTrue((IsLessThan(GetLength(clientOrderId), 1)))) { clientOrderId = nil } var marketId interface{} = this.SafeString(order, "symbol") market = this.SafeMarket(marketId, market) var symbol interface{} = GetValue(market, "symbol") var price interface{} = this.FromEp(this.SafeString(order, "priceEp"), market) var amount interface{} = this.FromEv(this.SafeString(order, "baseQtyEv"), market) var remaining interface{} = this.OmitZero(this.FromEv(this.SafeString(order, "leavesBaseQtyEv"), market)) var filled interface{} = this.FromEv(this.SafeString2(order, "cumBaseQtyEv", "cumBaseValueEv"), market) var cost interface{} = this.FromEr(this.SafeString2(order, "cumQuoteValueEv", "quoteQtyEv"), market) var average interface{} = this.FromEp(this.SafeString(order, "avgPriceEp"), market) var status interface{} = this.ParseOrderStatus(this.SafeString(order, "ordStatus")) var side interface{} = this.SafeStringLower(order, "side") var typeVar interface{} = this.ParseOrderType(this.SafeString(order, "ordType")) var timestamp interface{} = this.SafeIntegerProduct2(order, "actionTimeNs", "createTimeNs", 0.000001) var fee interface{} = nil var feeCost interface{} = this.FromEv(this.SafeString(order, "cumFeeEv"), market) if IsTrue(!IsEqual(feeCost, nil)) { fee = map[string]interface{} { "cost": feeCost, "currency": this.SafeCurrencyCode(this.SafeString(order, "feeCurrency")), } } var timeInForce interface{} = this.ParseTimeInForce(this.SafeString(order, "timeInForce")) var triggerPrice interface{} = this.ParseNumber(this.OmitZero(this.FromEp(this.SafeString(order, "stopPxEp")))) var postOnly interface{} = (IsEqual(timeInForce, "PO")) return this.SafeOrder(map[string]interface{} { "info": order, "id": id, "clientOrderId": clientOrderId, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastTradeTimestamp": nil, "symbol": symbol, "type": typeVar, "timeInForce": timeInForce, "postOnly": postOnly, "side": side, "price": price, "triggerPrice": triggerPrice, "amount": amount, "cost": cost, "average": average, "filled": filled, "remaining": remaining, "status": status, "fee": fee, "trades": nil, }, market) } func (this *phemex) ParseOrderSide(side interface{}) interface{} { var sides interface{} = map[string]interface{} { "1": "buy", "2": "sell", } return this.SafeString(sides, side, side) } func (this *phemex) ParseSwapOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // { // "bizError":0, // "orderID":"7a1ad384-44a3-4e54-a102-de4195a29e32", // "clOrdID":"", // "symbol":"ETHUSD", // "side":"Buy", // "actionTimeNs":1592668973945065381, // "transactTimeNs":0, // "orderType":"Market", // "priceEp":2267500, // "price":226.75000000, // "orderQty":1, // "displayQty":0, // "timeInForce":"ImmediateOrCancel", // "reduceOnly":false, // "closedPnlEv":0, // "closedPnl":0E-8, // "closedSize":0, // "cumQty":0, // "cumValueEv":0, // "cumValue":0E-8, // "leavesQty":1, // "leavesValueEv":11337, // "leavesValue":1.13370000, // "stopDirection":"UNSPECIFIED", // "stopPxEp":0, // "stopPx":0E-8, // "trigger":"UNSPECIFIED", // "pegOffsetValueEp":0, // "execStatus":"PendingNew", // "pegPriceType":"UNSPECIFIED", // "ordStatus":"Created", // "execInst": "ReduceOnly" // } // // usdt // { // "bizError":"0", // "orderID":"bd720dff-5647-4596-aa4e-656bac87aaad", // "clOrdID":"ccxt2022843dffac9477b497", // "symbol":"LTCUSDT", // "side":"Buy", // "actionTimeNs":"1677667878751724052", // "transactTimeNs":"1677667878754017434", // "orderType":"Limit", // "priceRp":"40", // "orderQtyRq":"0.1", // "displayQtyRq":"0.1", // "timeInForce":"GoodTillCancel", // "reduceOnly":false, // "closedPnlRv":"0", // "closedSizeRq":"0", // "cumQtyRq":"0", // "cumValueRv":"0", // "leavesQtyRq":"0.1", // "leavesValueRv":"4", // "stopDirection":"UNSPECIFIED", // "stopPxRp":"0", // "trigger":"UNSPECIFIED", // "pegOffsetValueRp":"0", // "pegOffsetProportionRr":"0", // "execStatus":"New", // "pegPriceType":"UNSPECIFIED", // "ordStatus":"New", // "execInst":"None", // "takeProfitRp":"0", // "stopLossRp":"0" // } // // v2 orderList // { // "createdAt":"1677686231301", // "symbol":"LTCUSDT", // "orderQtyRq":"0.2", // "side":"1", // "posSide":"3", // "priceRp":"50", // "execQtyRq":"0", // "leavesQtyRq":"0.2", // "execPriceRp":"0", // "orderValueRv":"10", // "leavesValueRv":"10", // "cumValueRv":"0", // "stopDirection":"0", // "stopPxRp":"0", // "trigger":"0", // "actionBy":"1", // "execFeeRv":"0", // "ordType":"2", // "ordStatus":"5", // "clOrdId":"4b3b188", // "orderId":"4b3b1884-87cf-4897-b596-6693b7ed84d1", // "execStatus":"5", // "bizError":"0", // "totalPnlRv":null, // "avgTransactPriceRp":null, // "orderDetailsVos":null, // "tradeType":"0" // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString2(order, "orderID", "orderId") var clientOrderId interface{} = this.SafeString2(order, "clOrdID", "clOrdId") if IsTrue(IsTrue((!IsEqual(clientOrderId, nil))) && IsTrue((IsLessThan(GetLength(clientOrderId), 1)))) { clientOrderId = nil } var marketId interface{} = this.SafeString(order, "symbol") var symbol interface{} = this.SafeSymbol(marketId, market) market = this.SafeMarket(marketId, market) var status interface{} = this.ParseOrderStatus(this.SafeString(order, "ordStatus")) var side interface{} = this.ParseOrderSide(this.SafeStringLower(order, "side")) var typeVar interface{} = this.ParseOrderType(this.SafeString(order, "orderType")) var price interface{} = this.SafeString(order, "priceRp") if IsTrue(IsEqual(price, nil)) { price = this.FromEp(this.SafeString(order, "priceEp"), market) } var amount interface{} = this.SafeNumber2(order, "orderQty", "orderQtyRq") var filled interface{} = this.SafeNumber2(order, "cumQty", "cumQtyRq") var remaining interface{} = this.SafeNumber2(order, "leavesQty", "leavesQtyRq") var timestamp interface{} = this.SafeIntegerProduct(order, "actionTimeNs", 0.000001) if IsTrue(IsEqual(timestamp, nil)) { timestamp = this.SafeInteger(order, "createdAt") } var cost interface{} = this.SafeNumber2(order, "cumValue", "cumValueRv") var lastTradeTimestamp interface{} = this.SafeIntegerProduct(order, "transactTimeNs", 0.000001) if IsTrue(IsEqual(lastTradeTimestamp, 0)) { lastTradeTimestamp = nil } var timeInForce interface{} = this.ParseTimeInForce(this.SafeString(order, "timeInForce")) var triggerPrice interface{} = this.OmitZero(this.SafeString2(order, "stopPx", "stopPxRp")) var postOnly interface{} = (IsEqual(timeInForce, "PO")) var reduceOnly interface{} = this.SafeValue(order, "reduceOnly") var execInst interface{} = this.SafeString(order, "execInst") if IsTrue(IsEqual(execInst, "ReduceOnly")) { reduceOnly = true } var takeProfit interface{} = this.SafeString(order, "takeProfitRp") var stopLoss interface{} = this.SafeString(order, "stopLossRp") var feeValue interface{} = this.OmitZero(this.SafeString(order, "execFeeRv")) var ptFeeRv interface{} = this.OmitZero(this.SafeString(order, "ptFeeRv")) var fee interface{} = nil if IsTrue(!IsEqual(feeValue, nil)) { fee = map[string]interface{} { "cost": feeValue, "currency": GetValue(market, "quote"), } } else if IsTrue(!IsEqual(ptFeeRv, nil)) { fee = map[string]interface{} { "cost": ptFeeRv, "currency": "PT", } } return this.SafeOrder(map[string]interface{} { "info": order, "id": id, "clientOrderId": clientOrderId, "datetime": this.Iso8601(timestamp), "timestamp": timestamp, "lastTradeTimestamp": lastTradeTimestamp, "symbol": symbol, "type": typeVar, "timeInForce": timeInForce, "postOnly": postOnly, "reduceOnly": reduceOnly, "side": side, "price": price, "triggerPrice": triggerPrice, "takeProfitPrice": takeProfit, "stopLossPrice": stopLoss, "amount": amount, "filled": filled, "remaining": remaining, "cost": cost, "average": nil, "status": status, "fee": fee, "trades": nil, }) } func (this *phemex) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market var isSwap interface{} = this.SafeBool(market, "swap", false) var hasPnl interface{} = IsTrue(IsTrue((InOp(order, "closedPnl"))) || IsTrue((InOp(order, "closedPnlRv")))) || IsTrue((InOp(order, "totalPnlRv"))) if IsTrue(IsTrue(isSwap) || IsTrue(hasPnl)) { return this.ParseSwapOrder(order, market) } return this.ParseSpotOrder(order, market) } /** * @method * @name phemex#createOrder * @description create a trade order * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#place-order * @see https://phemex-docs.github.io/#place-order-http-put-prefered-3 * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much of currency you want to trade in units of base currency * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {float} [params.trigger] trigger price for conditional orders * @param {object} [params.takeProfit] *swap only* *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered (perpetual swap markets only) * @param {float} [params.takeProfit.triggerPrice] take profit trigger price * @param {object} [params.stopLoss] *swap only* *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered (perpetual swap markets only) * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price * @param {string} [params.posSide] *swap only* "Merged" for one way mode, "Long" for buy side of hedged mode, "Short" for sell side of hedged mode * @param {bool} [params.hedged] *swap only* true for hedged mode, false for one way mode, default is false * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *phemex) 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 retRes26418 := (<-this.LoadMarkets()) PanicOnError(retRes26418) var market interface{} = this.Market(symbol) var requestSide interface{} = this.Capitalize(side) typeVar = this.Capitalize(typeVar) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "side": requestSide, "ordType": typeVar, } var clientOrderId interface{} = this.SafeString2(params, "clOrdID", "clientOrderId") var stopLoss interface{} = this.SafeValue(params, "stopLoss") var stopLossDefined interface{} = (!IsEqual(stopLoss, nil)) var takeProfit interface{} = this.SafeValue(params, "takeProfit") var takeProfitDefined interface{} = (!IsEqual(takeProfit, nil)) if IsTrue(IsEqual(clientOrderId, nil)) { var brokerId interface{} = this.SafeString(this.Options, "brokerId", "CCXT123456") if IsTrue(!IsEqual(brokerId, nil)) { AddElementToObject(request, "clOrdID", Add(brokerId, this.Uuid16())) } } else { AddElementToObject(request, "clOrdID", clientOrderId) params = this.Omit(params, []interface{}{"clOrdID", "clientOrderId"}) } var triggerPrice interface{} = this.SafeStringN(params, []interface{}{"stopPx", "stopPrice", "triggerPrice"}) if IsTrue(!IsEqual(triggerPrice, nil)) { if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { AddElementToObject(request, "stopPxRp", this.PriceToPrecision(symbol, triggerPrice)) } else { AddElementToObject(request, "stopPxEp", this.ToEp(triggerPrice, market)) } } params = this.Omit(params, []interface{}{"stopPx", "stopPrice", "stopLoss", "takeProfit", "triggerPrice"}) if IsTrue(GetValue(market, "spot")) { var qtyType interface{} = this.SafeValue(params, "qtyType", "ByBase") if IsTrue(IsTrue(IsTrue((IsEqual(typeVar, "Market"))) || IsTrue((IsEqual(typeVar, "Stop")))) || IsTrue((IsEqual(typeVar, "MarketIfTouched")))) { if IsTrue(!IsEqual(price, nil)) { qtyType = "ByQuote" } } if IsTrue(!IsEqual(triggerPrice, nil)) { if IsTrue(IsEqual(typeVar, "Limit")) { AddElementToObject(request, "ordType", "StopLimit") } else if IsTrue(IsEqual(typeVar, "Market")) { AddElementToObject(request, "ordType", "Stop") } AddElementToObject(request, "trigger", "ByLastPrice") } AddElementToObject(request, "qtyType", qtyType) if IsTrue(IsEqual(qtyType, "ByQuote")) { var cost interface{} = this.SafeNumber(params, "cost") params = this.Omit(params, "cost") if IsTrue(GetValue(this.Options, "createOrderByQuoteRequiresPrice")) { if IsTrue(!IsEqual(price, nil)) { var amountString interface{} = this.NumberToString(amount) var priceString interface{} = this.NumberToString(price) var quoteAmount interface{} = Precise.StringMul(amountString, priceString) cost = this.ParseNumber(quoteAmount) } else if IsTrue(IsEqual(cost, nil)) { panic(ArgumentsRequired(Add(Add(Add(this.Id, " createOrder() "), qtyType), " requires a price argument or a cost parameter"))) } } cost = Ternary(IsTrue((IsEqual(cost, nil))), amount, cost) var costString interface{} = this.NumberToString(cost) AddElementToObject(request, "quoteQtyEv", this.ToEv(costString, market)) } else { var amountString interface{} = this.NumberToString(amount) AddElementToObject(request, "baseQtyEv", this.ToEv(amountString, market)) } } else if IsTrue(GetValue(market, "swap")) { var hedged interface{} = this.SafeBool(params, "hedged", false) params = this.Omit(params, "hedged") var posSide interface{} = this.SafeStringLower(params, "posSide") if IsTrue(IsEqual(posSide, nil)) { if IsTrue(hedged) { var reduceOnly interface{} = this.SafeBool(params, "reduceOnly") if IsTrue(reduceOnly) { side = Ternary(IsTrue((IsEqual(side, "buy"))), "sell", "buy") params = this.Omit(params, "reduceOnly") } posSide = Ternary(IsTrue((IsEqual(side, "buy"))), "Long", "Short") } else { posSide = "Merged" } } posSide = this.Capitalize(posSide) AddElementToObject(request, "posSide", posSide) if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { AddElementToObject(request, "orderQtyRq", amount) } else { AddElementToObject(request, "orderQty", this.ParseToInt(amount)) } if IsTrue(!IsEqual(triggerPrice, nil)) { var triggerType interface{} = this.SafeString(params, "triggerType", "ByMarkPrice") AddElementToObject(request, "triggerType", triggerType) // set direction & exchange specific order type var triggerDirection interface{} = nil triggerDirectionparamsVariable := this.HandleParamString(params, "triggerDirection"); triggerDirection = GetValue(triggerDirectionparamsVariable,0); params = GetValue(triggerDirectionparamsVariable,1) if IsTrue(IsEqual(triggerDirection, nil)) { panic(ArgumentsRequired(Add(this.Id, " createOrder() also requires a \\'triggerDirection\\' parameter with either \\'up\\' or \\'down\\' value"))) } // the flow defined per https://phemex-docs.github.io/#more-order-type-examples if IsTrue(IsEqual(triggerDirection, "up")) { if IsTrue(IsEqual(side, "sell")) { AddElementToObject(request, "ordType", Ternary(IsTrue((IsEqual(typeVar, "Market"))), "MarketIfTouched", "LimitIfTouched")) } else if IsTrue(IsEqual(side, "buy")) { AddElementToObject(request, "ordType", Ternary(IsTrue((IsEqual(typeVar, "Market"))), "Stop", "StopLimit")) } } else if IsTrue(IsEqual(triggerDirection, "down")) { if IsTrue(IsEqual(side, "sell")) { AddElementToObject(request, "ordType", Ternary(IsTrue((IsEqual(typeVar, "Market"))), "Stop", "StopLimit")) } else if IsTrue(IsEqual(side, "buy")) { AddElementToObject(request, "ordType", Ternary(IsTrue((IsEqual(typeVar, "Market"))), "MarketIfTouched", "LimitIfTouched")) } } } if IsTrue(IsTrue(stopLossDefined) || IsTrue(takeProfitDefined)) { if IsTrue(stopLossDefined) { var stopLossTriggerPrice interface{} = this.SafeValue2(stopLoss, "triggerPrice", "stopPrice") if IsTrue(IsEqual(stopLossTriggerPrice, nil)) { panic(InvalidOrder(Add(this.Id, " createOrder() requires a trigger price in params[\"stopLoss\"][\"triggerPrice\"] for a stop loss order"))) } if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { AddElementToObject(request, "stopLossRp", this.PriceToPrecision(symbol, stopLossTriggerPrice)) } else { AddElementToObject(request, "stopLossEp", this.ToEp(stopLossTriggerPrice, market)) } var stopLossTriggerPriceType interface{} = this.SafeString2(stopLoss, "triggerPriceType", "slTrigger") if IsTrue(!IsEqual(stopLossTriggerPriceType, nil)) { AddElementToObject(request, "slTrigger", this.SafeString(GetValue(this.Options, "triggerPriceTypesMap"), stopLossTriggerPriceType, stopLossTriggerPriceType)) } var slLimitPrice interface{} = this.SafeString(stopLoss, "price") if IsTrue(!IsEqual(slLimitPrice, nil)) { AddElementToObject(request, "slPxRp", this.PriceToPrecision(symbol, slLimitPrice)) } } if IsTrue(takeProfitDefined) { var takeProfitTriggerPrice interface{} = this.SafeValue2(takeProfit, "triggerPrice", "stopPrice") if IsTrue(IsEqual(takeProfitTriggerPrice, nil)) { panic(InvalidOrder(Add(this.Id, " createOrder() requires a trigger price in params[\"takeProfit\"][\"triggerPrice\"] for a take profit order"))) } if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { AddElementToObject(request, "takeProfitRp", this.PriceToPrecision(symbol, takeProfitTriggerPrice)) } else { AddElementToObject(request, "takeProfitEp", this.ToEp(takeProfitTriggerPrice, market)) } var takeProfitTriggerPriceType interface{} = this.SafeString2(takeProfit, "triggerPriceType", "tpTrigger") if IsTrue(!IsEqual(takeProfitTriggerPriceType, nil)) { AddElementToObject(request, "tpTrigger", this.SafeString(GetValue(this.Options, "triggerPriceTypesMap"), takeProfitTriggerPriceType, takeProfitTriggerPriceType)) } var tpLimitPrice interface{} = this.SafeString(takeProfit, "price") if IsTrue(!IsEqual(tpLimitPrice, nil)) { AddElementToObject(request, "tpPxRp", this.PriceToPrecision(symbol, tpLimitPrice)) } } } } if IsTrue(IsTrue(IsTrue((IsEqual(typeVar, "Limit"))) || IsTrue((IsEqual(typeVar, "StopLimit")))) || IsTrue((IsEqual(typeVar, "LimitIfTouched")))) { if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { AddElementToObject(request, "priceRp", this.PriceToPrecision(symbol, price)) } else { var priceString interface{} = this.NumberToString(price) AddElementToObject(request, "priceEp", this.ToEp(priceString, market)) } } var takeProfitPrice interface{} = this.SafeString(params, "takeProfitPrice") if IsTrue(!IsEqual(takeProfitPrice, nil)) { if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { AddElementToObject(request, "takeProfitRp", this.PriceToPrecision(symbol, takeProfitPrice)) } else { AddElementToObject(request, "takeProfitEp", this.ToEp(takeProfitPrice, market)) } params = this.Omit(params, "takeProfitPrice") } var stopLossPrice interface{} = this.SafeString(params, "stopLossPrice") if IsTrue(!IsEqual(stopLossPrice, nil)) { if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { AddElementToObject(request, "stopLossRp", this.PriceToPrecision(symbol, stopLossPrice)) } else { AddElementToObject(request, "stopLossEp", this.ToEp(stopLossPrice, market)) } params = this.Omit(params, "stopLossPrice") } var response interface{} = nil if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { response = (<-this.PrivatePostGOrders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "contract")) { response = (<-this.PrivatePostOrders(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivatePostSpotOrders(this.Extend(request, params))) PanicOnError(response) } // // spot // // { // "code": 0, // "msg": "", // "data": { // "orderID": "d1d09454-cabc-4a23-89a7-59d43363f16d", // "clOrdID": "309bcd5c-9f6e-4a68-b775-4494542eb5cb", // "priceEp": 0, // "action": "New", // "trigger": "UNSPECIFIED", // "pegPriceType": "UNSPECIFIED", // "stopDirection": "UNSPECIFIED", // "bizError": 0, // "symbol": "sBTCUSDT", // "side": "Buy", // "baseQtyEv": 0, // "ordType": "Limit", // "timeInForce": "GoodTillCancel", // "ordStatus": "Created", // "cumFeeEv": 0, // "cumBaseQtyEv": 0, // "cumQuoteQtyEv": 0, // "leavesBaseQtyEv": 0, // "leavesQuoteQtyEv": 0, // "avgPriceEp": 0, // "cumBaseAmountEv": 0, // "cumQuoteAmountEv": 0, // "quoteQtyEv": 0, // "qtyType": "ByBase", // "stopPxEp": 0, // "pegOffsetValueEp": 0 // } // } // // swap // // { // "code":0, // "msg":"", // "data":{ // "bizError":0, // "orderID":"7a1ad384-44a3-4e54-a102-de4195a29e32", // "clOrdID":"", // "symbol":"ETHUSD", // "side":"Buy", // "actionTimeNs":1592668973945065381, // "transactTimeNs":0, // "orderType":"Market", // "priceEp":2267500, // "price":226.75000000, // "orderQty":1, // "displayQty":0, // "timeInForce":"ImmediateOrCancel", // "reduceOnly":false, // "closedPnlEv":0, // "closedPnl":0E-8, // "closedSize":0, // "cumQty":0, // "cumValueEv":0, // "cumValue":0E-8, // "leavesQty":1, // "leavesValueEv":11337, // "leavesValue":1.13370000, // "stopDirection":"UNSPECIFIED", // "stopPxEp":0, // "stopPx":0E-8, // "trigger":"UNSPECIFIED", // "pegOffsetValueEp":0, // "execStatus":"PendingNew", // "pegPriceType":"UNSPECIFIED", // "ordStatus":"Created" // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseOrder(data, market) return nil }() return ch } /** * @method * @name phemex#editOrder * @description edit a trade order * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#amend-order-by-orderid * @param {string} id cancel order id * @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 {string} [params.posSide] either 'Merged' or 'Long' or 'Short' * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *phemex) 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 retRes29508 := (<-this.LoadMarkets()) PanicOnError(retRes29508) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } var clientOrderId interface{} = this.SafeString2(params, "clientOrderId", "clOrdID") params = this.Omit(params, []interface{}{"clientOrderId", "clOrdID"}) var isUSDTSettled interface{} = (IsEqual(GetValue(market, "settle"), "USDT")) if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "clOrdID", clientOrderId) } else { AddElementToObject(request, "orderID", id) } if IsTrue(!IsEqual(price, nil)) { if IsTrue(isUSDTSettled) { AddElementToObject(request, "priceRp", this.PriceToPrecision(GetValue(market, "symbol"), price)) } else { AddElementToObject(request, "priceEp", this.ToEp(price, market)) } } // Note the uppercase 'V' in 'baseQtyEV' request. that is exchange's requirement at this moment. However, to avoid mistakes from user side, let's support lowercased 'baseQtyEv' too var finalQty interface{} = this.SafeString(params, "baseQtyEv") params = this.Omit(params, []interface{}{"baseQtyEv"}) if IsTrue(!IsEqual(finalQty, nil)) { AddElementToObject(request, "baseQtyEV", finalQty) } else if IsTrue(!IsEqual(amount, nil)) { if IsTrue(isUSDTSettled) { AddElementToObject(request, "orderQtyRq", this.AmountToPrecision(GetValue(market, "symbol"), amount)) } else { AddElementToObject(request, "baseQtyEV", this.ToEv(amount, market)) } } var triggerPrice interface{} = this.SafeStringN(params, []interface{}{"triggerPrice", "stopPx", "stopPrice"}) if IsTrue(!IsEqual(triggerPrice, nil)) { if IsTrue(isUSDTSettled) { AddElementToObject(request, "stopPxRp", this.PriceToPrecision(symbol, triggerPrice)) } else { AddElementToObject(request, "stopPxEp", this.ToEp(triggerPrice, market)) } } params = this.Omit(params, []interface{}{"triggerPrice", "stopPx", "stopPrice"}) var response interface{} = nil if IsTrue(isUSDTSettled) { var posSide interface{} = this.SafeString(params, "posSide") if IsTrue(IsEqual(posSide, nil)) { AddElementToObject(request, "posSide", "Merged") } response = (<-this.PrivatePutGOrdersReplace(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "swap")) { response = (<-this.PrivatePutOrdersReplace(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivatePutSpotOrders(this.Extend(request, params))) PanicOnError(response) } var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseOrder(data, market) return nil }() return ch } /** * @method * @name phemex#cancelOrder * @description cancels an open order * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#cancel-single-order-by-orderid * @param {string} id order id * @param {string} symbol unified symbol of the market the order was made in * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.posSide] either 'Merged' or 'Long' or 'Short' * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *phemex) CancelOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrder() requires a symbol argument"))) } retRes30228 := (<-this.LoadMarkets()) PanicOnError(retRes30228) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } var clientOrderId interface{} = this.SafeString2(params, "clientOrderId", "clOrdID") params = this.Omit(params, []interface{}{"clientOrderId", "clOrdID"}) if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "clOrdID", clientOrderId) } else { AddElementToObject(request, "orderID", id) } var response interface{} = nil if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { var posSide interface{} = this.SafeString(params, "posSide") if IsTrue(IsEqual(posSide, nil)) { AddElementToObject(request, "posSide", "Merged") } response = (<-this.PrivateDeleteGOrdersCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "swap")) { response = (<-this.PrivateDeleteOrdersCancel(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateDeleteSpotOrders(this.Extend(request, params))) PanicOnError(response) } var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseOrder(data, market) return nil }() return ch } /** * @method * @name phemex#cancelAllOrders * @description cancel all open orders in a market * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#cancelall * @param {string} symbol unified market symbol of the market to cancel orders in * @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 *phemex) 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelAllOrders() requires a symbol argument"))) } retRes30638 := (<-this.LoadMarkets()) PanicOnError(retRes30638) var market interface{} = this.Market(symbol) var trigger interface{} = this.SafeValue2(params, "stop", "trigger", false) params = this.Omit(params, []interface{}{"stop", "trigger"}) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(trigger) { AddElementToObject(request, "untriggerred", trigger) } var response interface{} = nil if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { response = (<-this.PrivateDeleteGOrdersAll(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "swap")) { response = (<-this.PrivateDeleteOrdersAll(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateDeleteSpotOrdersAll(this.Extend(request, params))) PanicOnError(response) } ch <- []interface{}{this.SafeOrder(map[string]interface{} { "info": response, })} return nil }() return ch } /** * @method * @name phemex#fetchOrder * @see https://phemex-docs.github.io/#query-orders-by-ids * @description fetches information on an order made by the user * @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 *phemex) FetchOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOrder() requires a symbol argument"))) } retRes31278 := (<-this.LoadMarkets()) PanicOnError(retRes31278) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } var clientOrderId interface{} = this.SafeString2(params, "clientOrderId", "clOrdID") params = this.Omit(params, []interface{}{"clientOrderId", "clOrdID"}) if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "clOrdID", clientOrderId) } else { AddElementToObject(request, "orderID", id) } var response interface{} = nil if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { response = (<-this.PrivateGetApiDataGFuturesOrdersByOrderId(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "spot")) { response = (<-this.PrivateGetApiDataSpotsOrdersByOrderId(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateGetExchangeOrder(this.Extend(request, params))) PanicOnError(response) } var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var order interface{} = data if IsTrue(IsArray(data)) { var numOrders interface{} = GetArrayLength(data) if IsTrue(IsLessThan(numOrders, 1)) { if IsTrue(!IsEqual(clientOrderId, nil)) { panic(OrderNotFound(Add(Add(Add(Add(Add(this.Id, " fetchOrder() "), symbol), " order with clientOrderId "), clientOrderId), " not found"))) } else { panic(OrderNotFound(Add(Add(Add(Add(Add(this.Id, " fetchOrder() "), symbol), " order with id "), id), " not found"))) } } order = this.SafeDict(data, 0, map[string]interface{} {}) } else if IsTrue(GetValue(market, "spot")) { var rows interface{} = this.SafeList(data, "rows", []interface{}{}) order = this.SafeDict(rows, 0, map[string]interface{} {}) } ch <- this.ParseOrder(order, market) return nil }() return ch } /** * @method * @name phemex#fetchOrders * @description fetches information on multiple orders made by the user * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryorder * @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 *phemex) 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOrders() requires a symbol argument"))) } retRes31818 := (<-this.LoadMarkets()) PanicOnError(retRes31818) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } var response interface{} = nil if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { AddElementToObject(request, "currency", GetValue(market, "settle")) response = (<-this.PrivateGetExchangeOrderV2OrderList(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "swap")) { response = (<-this.PrivateGetExchangeOrderList(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateGetApiDataSpotsOrders(this.Extend(request, params))) PanicOnError(response) } var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var rows interface{} = this.SafeList(data, "rows", data) ch <- this.ParseOrders(rows, market, since, limit) return nil }() return ch } /** * @method * @name phemex#fetchOpenOrders * @description fetch all unfilled currently open orders * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryopenorder * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Spot-API-en.md#spotListAllOpenOrder * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch open orders for * @param {int} [limit] the maximum number of open order structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *phemex) 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 retRes32208 := (<-this.LoadMarkets()) PanicOnError(retRes32208) if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOpenOrders() requires a symbol argument"))) } retRes32248 := (<-this.LoadMarkets()) PanicOnError(retRes32248) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } var response interface{} = nil { ret__ := func(this *phemex) (ret_ interface{}) { defer func() { if e := recover(); e != nil { if e == "break" { return } ret_ = func(this *phemex) interface{} { // catch block: if IsTrue(IsInstance(e, OrderNotFound)) { ch <- []interface{}{} return nil } panic(e) return nil }(this) } }() // try block: if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { response = (<-this.PrivateGetGOrdersActiveList(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "swap")) { response = (<-this.PrivateGetOrdersActiveList(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateGetSpotOrders(this.Extend(request, params))) PanicOnError(response) } return nil }(this) if ret__ != nil { return ret__ } } var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) if IsTrue(IsArray(data)) { ch <- this.ParseOrders(data, market, since, limit) return nil } else { var rows interface{} = this.SafeList(data, "rows", []interface{}{}) ch <- this.ParseOrders(rows, market, since, limit) return nil } return nil }() return ch } /** * @method * @name phemex#fetchClosedOrders * @description fetches information on multiple closed orders made by the user * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryorder * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#queryorder * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedgedd-Perpetual-API.md#query-closed-orders-by-symbol * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Spot-API-en.md#spotDataOrdersByIds * @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 {string} [params.settle] the settlement currency to fetch orders for * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *phemex) FetchClosedOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes32698 := (<-this.LoadMarkets()) PanicOnError(retRes32698) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(market, nil)) { AddElementToObject(request, "symbol", GetValue(market, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } var response interface{} = nil if IsTrue(IsTrue((IsEqual(symbol, nil))) || IsTrue((IsEqual(this.SafeString(market, "settle"), "USDT")))) { AddElementToObject(request, "currency", this.SafeString(params, "settle", "USDT")) response = (<-this.PrivateGetExchangeOrderV2OrderList(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "swap")) { response = (<-this.PrivateGetExchangeOrderList(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateGetExchangeSpotOrder(this.Extend(request, params))) PanicOnError(response) } // // spot // // { // "code":0, // "msg":"OK", // "data":{ // "total":8, // "rows":[ // { // "orderID":"99232c3e-3d6a-455f-98cc-2061cdfe91bc", // "stopPxEp":0, // "avgPriceEp":0, // "qtyType":"ByBase", // "leavesBaseQtyEv":0, // "leavesQuoteQtyEv":0, // "baseQtyEv":"1000000000", // "feeCurrency":"4", // "stopDirection":"UNSPECIFIED", // "symbol":"sETHUSDT", // "side":"Buy", // "quoteQtyEv":250000000000, // "priceEp":25000000000, // "ordType":"Limit", // "timeInForce":"GoodTillCancel", // "ordStatus":"Rejected", // "execStatus":"NewRejected", // "createTimeNs":1592675305266037130, // "cumFeeEv":0, // "cumBaseValueEv":0, // "cumQuoteValueEv":0 // }, // ] // } // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) if IsTrue(IsArray(data)) { ch <- this.ParseOrders(data, market, since, limit) return nil } else { var rows interface{} = this.SafeList(data, "rows", []interface{}{}) ch <- this.ParseOrders(rows, market, since, limit) return nil } return nil }() return ch } /** * @method * @name phemex#fetchMyTrades * @description fetch all trades made by the user * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#query-user-trade * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-user-trade * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Spot-API-en.md#spotDataTradesHist * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *phemex) 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 retRes33538 := (<-this.LoadMarkets()) PanicOnError(retRes33538) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(limit, nil)) { limit = mathMin(200, limit) AddElementToObject(request, "limit", limit) } var isUSDTSettled interface{} = IsTrue((IsEqual(symbol, nil))) || IsTrue((IsEqual(this.SafeString(market, "settle"), "USDT"))) if IsTrue(isUSDTSettled) { AddElementToObject(request, "currency", "USDT") AddElementToObject(request, "offset", 0) if IsTrue(IsEqual(limit, nil)) { AddElementToObject(request, "limit", 200) } } else { AddElementToObject(request, "symbol", GetValue(market, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } var response interface{} = nil if IsTrue(isUSDTSettled) { response = (<-this.PrivateGetExchangeOrderV2TradingList(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "swap")) { response = (<-this.PrivateGetExchangeOrderTrade(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateGetExchangeSpotOrderTrades(this.Extend(request, params))) PanicOnError(response) } // // spot // // { // "code": 0, // "msg": "OK", // "data": { // "total": 1, // "rows": [ // { // "qtyType": "ByQuote", // "transactTimeNs": 1589450974800550100, // "clOrdID": "8ba59d40-df25-d4b0-14cf-0703f44e9690", // "orderID": "b2b7018d-f02f-4c59-b4cf-051b9c2d2e83", // "symbol": "sBTCUSDT", // "side": "Buy", // "priceEP": 970056000000, // "baseQtyEv": 0, // "quoteQtyEv": 1000000000, // "action": "New", // "execStatus": "MakerFill", // "ordStatus": "Filled", // "ordType": "Limit", // "execInst": "None", // "timeInForce": "GoodTillCancel", // "stopDirection": "UNSPECIFIED", // "tradeType": "Trade", // "stopPxEp": 0, // "execId": "c6bd8979-07ba-5946-b07e-f8b65135dbb1", // "execPriceEp": 970056000000, // "execBaseQtyEv": 103000, // "execQuoteQtyEv": 999157680, // "leavesBaseQtyEv": 0, // "leavesQuoteQtyEv": 0, // "execFeeEv": 0, // "feeRateEr": 0 // } // ] // } // } // // // swap // // { // "code": 0, // "msg": "OK", // "data": { // "total": 79, // "rows": [ // { // "transactTimeNs": 1606054879331565300, // "symbol": "BTCUSD", // "currency": "BTC", // "action": "New", // "side": "Buy", // "tradeType": "Trade", // "execQty": 5, // "execPriceEp": 182990000, // "orderQty": 5, // "priceEp": 183870000, // "execValueEv": 27323, // "feeRateEr": 75000, // "execFeeEv": 21, // "ordType": "Market", // "execID": "5eee56a4-04a9-5677-8eb0-c2fe22ae3645", // "orderID": "ee0acb82-f712-4543-a11d-d23efca73197", // "clOrdID": "", // "execStatus": "TakerFill" // }, // ] // } // } // // swap - usdt // // { // "code": 0, // "msg": "OK", // "data": { // "total": 4, // "rows": [ // { // "createdAt": 1666226932259, // "symbol": "ETHUSDT", // "currency": "USDT", // "action": 1, // "tradeType": 1, // "execQtyRq": "0.01", // "execPriceRp": "1271.9", // "side": 1, // "orderQtyRq": "0.78", // "priceRp": "1271.9", // "execValueRv": "12.719", // "feeRateRr": "0.0001", // "execFeeRv": "0.0012719", // "ordType": 2, // "execId": "8718cae", // "execStatus": 6 // }, // ] // } // } // var data interface{} = nil if IsTrue(isUSDTSettled) { data = this.SafeValue(response, "data", []interface{}{}) } else { data = this.SafeValue(response, "data", map[string]interface{} {}) data = this.SafeValue(data, "rows", []interface{}{}) } ch <- this.ParseTrades(data, market, since, limit) return nil }() return ch } /** * @method * @name phemex#fetchDepositAddress * @description fetch the deposit address for a currency associated with this account * @param {string} code unified currency code * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure} */ func (this *phemex) 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 retRes35078 := (<-this.LoadMarkets()) PanicOnError(retRes35078) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), } var defaultNetworks interface{} = this.SafeDict(this.Options, "defaultNetworks") var defaultNetwork interface{} = this.SafeStringUpper(defaultNetworks, code) var networks interface{} = this.SafeDict(this.Options, "networks", map[string]interface{} {}) var network interface{} = this.SafeStringUpper(params, "network", defaultNetwork) network = this.SafeString(networks, network, network) if IsTrue(IsEqual(network, nil)) { AddElementToObject(request, "chainName", GetValue(currency, "id")) } else { AddElementToObject(request, "chainName", network) params = this.Omit(params, "network") } response:= (<-this.PrivateGetPhemexUserWalletsV2DepositAddress(this.Extend(request, params))) PanicOnError(response) // { // "code":0, // "msg":"OK", // "data":{ // "address":"0x5bfbf60e0fa7f63598e6cfd8a7fd3ffac4ccc6ad", // "tag":null // } // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var address interface{} = this.SafeString(data, "address") var tag interface{} = this.SafeString(data, "tag") this.CheckAddress(address) ch <- map[string]interface{} { "info": response, "currency": code, "network": nil, "address": address, "tag": tag, } return nil }() return ch } /** * @method * @name phemex#fetchDeposits * @description fetch all deposits made to an account * @param {string} code unified currency code * @param {int} [since] the earliest time in ms to fetch deposits for * @param {int} [limit] the maximum number of deposits structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *phemex) FetchDeposits(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes35578 := (<-this.LoadMarkets()) PanicOnError(retRes35578) var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) } response:= (<-this.PrivateGetExchangeWalletsDepositList(params)) PanicOnError(response) // // { // "code":0, // "msg":"OK", // "data":[ // { // "id":29200, // "currency":"USDT", // "currencyCode":3, // "txHash":"0x0bdbdc47807769a03b158d5753f54dfc58b92993d2f5e818db21863e01238e5d", // "address":"0x5bfbf60e0fa7f63598e6cfd8a7fd3ffac4ccc6ad", // "amountEv":3000000000, // "confirmations":13, // "type":"Deposit", // "status":"Success", // "createdAt":1592722565000 // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTransactions(data, currency, since, limit) return nil }() return ch } /** * @method * @name phemex#fetchWithdrawals * @description fetch all withdrawals made from an account * @param {string} code unified currency code * @param {int} [since] the earliest time in ms to fetch withdrawals for * @param {int} [limit] the maximum number of withdrawals structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *phemex) FetchWithdrawals(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes35988 := (<-this.LoadMarkets()) PanicOnError(retRes35988) var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) } response:= (<-this.PrivateGetExchangeWalletsWithdrawList(params)) PanicOnError(response) // // { // "code":0, // "msg":"OK", // "data":[ // { // "address": "1Lxxxxxxxxxxx" // "amountEv": 200000 // "currency": "BTC" // "currencyCode": 1 // "expiredTime": 0 // "feeEv": 50000 // "rejectReason": null // "status": "Succeed" // "txHash": "44exxxxxxxxxxxxxxxxxxxxxx" // "withdrawStatus: "" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTransactions(data, currency, since, limit) return nil }() return ch } func (this *phemex) ParseTransactionStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "Success": "ok", "Succeed": "ok", "Rejected": "failed", "Security check failed": "failed", "SecurityCheckFailed": "failed", "Expired": "failed", "Address Risk": "failed", "Security Checking": "pending", "SecurityChecking": "pending", "Pending Review": "pending", "Pending Transfer": "pending", "AmlCsApporve": "pending", "New": "pending", "Confirmed": "pending", "Cancelled": "canceled", } return this.SafeString(statuses, status, status) } func (this *phemex) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // withdraw // // { // "id": "10000001", // "freezeId": null, // "address": "44exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // "amountRv": "100", // "chainCode": "11", // "chainName": "TRX", // "currency": "USDT", // "currencyCode": 3, // "email": "abc@gmail.com", // "expiredTime": "0", // "feeRv": "1", // "nickName": null, // "phone": null, // "rejectReason": "", // "submitedAt": "1670000000000", // "submittedAt": "1670000000000", // "txHash": null, // "userId": "10000001", // "status": "Success" // // fetchDeposits // // { // "id": "29200", // "currency": "USDT", // "currencyCode": "3", // "chainName": "ETH", // "chainCode": "4", // "txHash": "0x0bdbdc47807769a03b158d5753f54dfc58b92993d2f5e818db21863e01238e5d", // "address": "0x5bfbf60e0fa7f63598e6cfd8a7fd3ffac4ccc6ad", // "amountEv": "3000000000", // "confirmations": "13", // "type": "Deposit", // "status": "Success", // "createdAt": "1592722565000", // } // // fetchWithdrawals // // { // "id": "10000001", // "userId": "10000001", // "freezeId": "10000002", // "phone": null, // "email": "abc@gmail.com", // "nickName": null, // "currency": "USDT", // "currencyCode": "3", // "status": "Succeed", // "withdrawStatus": "Succeed", // "amountEv": "8800000000", // "feeEv": "1200000000", // "address": "0x5xxxad", // "txHash: "0x0xxxx5d", // "submitedAt": "1702571922000", // "submittedAt": "1702571922000", // "expiredTime": "0", // "rejectReason": null, // "chainName": "ETH", // "chainCode": "4", // "proxyAddress": null // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var id interface{} = this.SafeString(transaction, "id") var address interface{} = this.SafeString(transaction, "address") var tag interface{} = nil var txid interface{} = this.SafeString(transaction, "txHash") var currencyId interface{} = this.SafeString(transaction, "currency") currency = this.SafeCurrency(currencyId, currency) var code interface{} = GetValue(currency, "code") var networkId interface{} = this.SafeString(transaction, "chainName") var timestamp interface{} = this.SafeIntegerN(transaction, []interface{}{"createdAt", "submitedAt", "submittedAt"}) var typeVar interface{} = this.SafeStringLower(transaction, "type") var feeCost interface{} = this.ParseNumber(this.FromEn(this.SafeString(transaction, "feeEv"), GetValue(currency, "valueScale"))) if IsTrue(IsEqual(feeCost, nil)) { feeCost = this.SafeNumber(transaction, "feeRv") } var fee interface{} = nil if IsTrue(!IsEqual(feeCost, nil)) { typeVar = "withdrawal" fee = map[string]interface{} { "cost": feeCost, "currency": code, } } var status interface{} = this.ParseTransactionStatus(this.SafeString(transaction, "status")) var amount interface{} = this.ParseNumber(this.FromEn(this.SafeString(transaction, "amountEv"), GetValue(currency, "valueScale"))) if IsTrue(IsEqual(amount, nil)) { amount = this.SafeNumber(transaction, "amountRv") } return map[string]interface{} { "info": transaction, "id": id, "txid": txid, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "network": this.NetworkIdToCode(networkId), "address": address, "addressTo": address, "addressFrom": nil, "tag": tag, "tagTo": tag, "tagFrom": nil, "type": typeVar, "amount": amount, "currency": code, "status": status, "updated": nil, "comment": nil, "internal": nil, "fee": fee, } } /** * @method * @name phemex#fetchPositions * @description fetch all open positions * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#query-trading-account-and-positions * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-account-positions * @see https://phemex-docs.github.io/#query-account-positions-with-unrealized-pnl * @param {string[]} [symbols] list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.code] the currency code to fetch positions for, USD, BTC or USDT, USD is the default * @param {string} [params.method] *USDT contracts only* 'privateGetGAccountsAccountPositions' or 'privateGetAccountsPositions' default is 'privateGetGAccountsAccountPositions' * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *phemex) 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 retRes37828 := (<-this.LoadMarkets()) PanicOnError(retRes37828) symbols = this.MarketSymbols(symbols) var subType interface{} = nil var code interface{} = this.SafeString2(params, "currency", "code", "USD") params = this.Omit(params, []interface{}{"currency", "code"}) var settle interface{} = nil var market interface{} = nil var firstSymbol interface{} = this.SafeString(symbols, 0) if IsTrue(!IsEqual(firstSymbol, nil)) { market = this.Market(firstSymbol) settle = GetValue(market, "settle") code = GetValue(market, "settle") } else { settleparamsVariable := this.HandleOptionAndParams(params, "fetchPositions", "settle", code); settle = GetValue(settleparamsVariable,0); params = GetValue(settleparamsVariable,1) } subTypeparamsVariable := this.HandleSubTypeAndParams("fetchPositions", market, params); subType = GetValue(subTypeparamsVariable,0); params = GetValue(subTypeparamsVariable,1) var isUSDTSettled interface{} = IsEqual(settle, "USDT") if IsTrue(isUSDTSettled) { code = "USDT" } else if IsTrue(IsEqual(settle, "BTC")) { code = "BTC" } else if IsTrue(IsEqual(code, nil)) { code = Ternary(IsTrue((IsEqual(subType, "linear"))), "USD", "BTC") } var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), } var response interface{} = nil if IsTrue(isUSDTSettled) { var method interface{} = nil methodparamsVariable := this.HandleOptionAndParams(params, "fetchPositions", "method", "privateGetGAccountsAccountPositions"); method = GetValue(methodparamsVariable,0); params = GetValue(methodparamsVariable,1) if IsTrue(IsEqual(method, "privateGetGAccountsAccountPositions")) { response = (<-this.PrivateGetGAccountsAccountPositions(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateGetAccountsPositions(this.Extend(request, params))) PanicOnError(response) } } else { response = (<-this.PrivateGetAccountsAccountPositions(this.Extend(request, params))) PanicOnError(response) } // // { // "code":0,"msg":"", // "data":{ // "account":{ // "accountId":6192120001, // "currency":"BTC", // "accountBalanceEv":1254744, // "totalUsedBalanceEv":0, // "bonusBalanceEv":1254744 // }, // "positions":[ // { // "accountID":6192120001, // "symbol":"BTCUSD", // "currency":"BTC", // "side":"None", // "positionStatus":"Normal", // "crossMargin":false, // "leverageEr":100000000, // "leverage":1.00000000, // "initMarginReqEr":100000000, // "initMarginReq":1.00000000, // "maintMarginReqEr":500000, // "maintMarginReq":0.00500000, // "riskLimitEv":10000000000, // "riskLimit":100.00000000, // "size":0, // "value":0E-8, // "valueEv":0, // "avgEntryPriceEp":0, // "avgEntryPrice":0E-8, // "posCostEv":0, // "posCost":0E-8, // "assignedPosBalanceEv":0, // "assignedPosBalance":0E-8, // "bankruptCommEv":0, // "bankruptComm":0E-8, // "bankruptPriceEp":0, // "bankruptPrice":0E-8, // "positionMarginEv":0, // "positionMargin":0E-8, // "liquidationPriceEp":0, // "liquidationPrice":0E-8, // "deleveragePercentileEr":0, // "deleveragePercentile":0E-8, // "buyValueToCostEr":100225000, // "buyValueToCost":1.00225000, // "sellValueToCostEr":100075000, // "sellValueToCost":1.00075000, // "markPriceEp":135736070, // "markPrice":13573.60700000, // "markValueEv":0, // "markValue":null, // "unRealisedPosLossEv":0, // "unRealisedPosLoss":null, // "estimatedOrdLossEv":0, // "estimatedOrdLoss":0E-8, // "usedBalanceEv":0, // "usedBalance":0E-8, // "takeProfitEp":0, // "takeProfit":null, // "stopLossEp":0, // "stopLoss":null, // "cumClosedPnlEv":0, // "cumFundingFeeEv":0, // "cumTransactFeeEv":0, // "realisedPnlEv":0, // "realisedPnl":null, // "cumRealisedPnlEv":0, // "cumRealisedPnl":null // } // ] // } // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var positions interface{} = this.SafeValue(data, "positions", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(positions)); i++ { var position interface{} = GetValue(positions, i) AppendToArray(&result,this.ParsePosition(position)) } ch <- this.FilterByArrayPositions(result, "symbol", symbols, false) return nil }() return ch } func (this *phemex) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} { // // { // "userID": "811370", // "accountID": "8113700002", // "symbol": "ETHUSD", // "currency": "USD", // "side": "Buy", // "positionStatus": "Normal", // "crossMargin": false, // "leverageEr": "200000000", // "leverage": "2.00000000", // "initMarginReqEr": "50000000", // "initMarginReq": "0.50000000", // "maintMarginReqEr": "1000000", // "maintMarginReq": "0.01000000", // "riskLimitEv": "5000000000", // "riskLimit": "500000.00000000", // "size": "1", // "value": "22.22370000", // "valueEv": "222237", // "avgEntryPriceEp": "44447400", // "avgEntryPrice": "4444.74000000", // "posCostEv": "111202", // "posCost": "11.12020000", // "assignedPosBalanceEv": "111202", // "assignedPosBalance": "11.12020000", // "bankruptCommEv": "84", // "bankruptComm": "0.00840000", // "bankruptPriceEp": "22224000", // "bankruptPrice": "2222.40000000", // "positionMarginEv": "111118", // "positionMargin": "11.11180000", // "liquidationPriceEp": "22669000", // "liquidationPrice": "2266.90000000", // "deleveragePercentileEr": "0", // "deleveragePercentile": "0E-8", // "buyValueToCostEr": "50112500", // "buyValueToCost": "0.50112500", // "sellValueToCostEr": "50187500", // "sellValueToCost": "0.50187500", // "markPriceEp": "31332499", // "markPrice": "3133.24990000", // "markValueEv": "0", // "markValue": null, // "unRealisedPosLossEv": "0", // "unRealisedPosLoss": null, // "estimatedOrdLossEv": "0", // "estimatedOrdLoss": "0E-8", // "usedBalanceEv": "111202", // "usedBalance": "11.12020000", // "takeProfitEp": "0", // "takeProfit": null, // "stopLossEp": "0", // "stopLoss": null, // "cumClosedPnlEv": "-1546", // "cumFundingFeeEv": "1605", // "cumTransactFeeEv": "8438", // "realisedPnlEv": "0", // "realisedPnl": null, // "cumRealisedPnlEv": "0", // "cumRealisedPnl": null, // "transactTimeNs": "1641571200001885324", // "takerFeeRateEr": "0", // "makerFeeRateEr": "0", // "term": "6", // "lastTermEndTimeNs": "1607711882505745356", // "lastFundingTimeNs": "1641571200000000000", // "curTermRealisedPnlEv": "-1567", // "execSeq": "12112761561" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(position, "symbol") market = this.SafeMarket(marketId, market) var symbol interface{} = GetValue(market, "symbol") var collateral interface{} = this.SafeString2(position, "positionMargin", "positionMarginRv") var notionalString interface{} = this.SafeString2(position, "value", "valueRv") var maintenanceMarginPercentageString interface{} = this.SafeString2(position, "maintMarginReq", "maintMarginReqRr") var maintenanceMarginString interface{} = Precise.StringMul(notionalString, maintenanceMarginPercentageString) var initialMarginString interface{} = this.SafeString2(position, "assignedPosBalance", "assignedPosBalanceRv") var initialMarginPercentageString interface{} = Precise.StringDiv(initialMarginString, notionalString) var liquidationPrice interface{} = this.SafeNumber2(position, "liquidationPrice", "liquidationPriceRp") var markPriceString interface{} = this.SafeString2(position, "markPrice", "markPriceRp") var contracts interface{} = this.SafeString(position, "size") var contractSize interface{} = this.SafeValue(market, "contractSize") var contractSizeString interface{} = this.NumberToString(contractSize) var leverage interface{} = this.ParseNumber(Precise.StringAbs((this.SafeString2(position, "leverage", "leverageRr")))) var entryPriceString interface{} = this.SafeString2(position, "avgEntryPrice", "avgEntryPriceRp") var rawSide interface{} = this.SafeString(position, "side") var side interface{} = nil if IsTrue(!IsEqual(rawSide, nil)) { side = Ternary(IsTrue((IsEqual(rawSide, "Buy"))), "long", "short") } var priceDiff interface{} = nil var currency interface{} = this.SafeString(position, "currency") if IsTrue(IsEqual(currency, "USD")) { if IsTrue(IsEqual(side, "long")) { priceDiff = Precise.StringSub(markPriceString, entryPriceString) } else { priceDiff = Precise.StringSub(entryPriceString, markPriceString) } } else { // inverse if IsTrue(IsEqual(side, "long")) { priceDiff = Precise.StringSub(Precise.StringDiv("1", entryPriceString), Precise.StringDiv("1", markPriceString)) } else { priceDiff = Precise.StringSub(Precise.StringDiv("1", markPriceString), Precise.StringDiv("1", entryPriceString)) } } var unrealizedPnl interface{} = Precise.StringMul(Precise.StringMul(priceDiff, contracts), contractSizeString) var marginRatio interface{} = Precise.StringDiv(maintenanceMarginString, collateral) var isCross interface{} = this.SafeValue(position, "crossMargin") return this.SafePosition(map[string]interface{} { "info": position, "id": nil, "symbol": symbol, "contracts": this.ParseNumber(contracts), "contractSize": contractSize, "unrealizedPnl": this.ParseNumber(unrealizedPnl), "leverage": leverage, "liquidationPrice": liquidationPrice, "collateral": this.ParseNumber(collateral), "notional": this.ParseNumber(notionalString), "markPrice": this.ParseNumber(markPriceString), "lastPrice": nil, "entryPrice": this.ParseNumber(entryPriceString), "timestamp": nil, "lastUpdateTimestamp": nil, "initialMargin": this.ParseNumber(initialMarginString), "initialMarginPercentage": this.ParseNumber(initialMarginPercentageString), "maintenanceMargin": this.ParseNumber(maintenanceMarginString), "maintenanceMarginPercentage": this.ParseNumber(maintenanceMarginPercentageString), "marginRatio": this.ParseNumber(marginRatio), "datetime": nil, "marginMode": Ternary(IsTrue(isCross), "cross", "isolated"), "side": side, "hedged": false, "percentage": nil, "stopLossPrice": nil, "takeProfitPrice": nil, }) } /** * @method * @name phemex#fetchFundingHistory * @description fetch the history of funding payments paid and received on this account * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#futureDataFundingFeesHist * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch funding history for * @param {int} [limit] the maximum number of funding history structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [funding history structure]{@link https://docs.ccxt.com/#/?id=funding-history-structure} */ func (this *phemex) FetchFundingHistory(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchFundingHistory() requires a symbol argument"))) } retRes40668 := (<-this.LoadMarkets()) PanicOnError(retRes40668) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(!IsEqual(limit, nil)) { if IsTrue(IsGreaterThan(limit, 200)) { panic(BadRequest(Add(this.Id, " fetchFundingHistory() limit argument cannot exceed 200"))) } AddElementToObject(request, "limit", limit) } var response interface{} = nil var isUsdt interface{} = IsEqual(GetValue(market, "settle"), "USDT") if IsTrue(isUsdt) { response = (<-this.PrivateGetApiDataGFuturesFundingFees(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateGetApiDataFuturesFundingFees(this.Extend(request, params))) PanicOnError(response) } // // { // "code": 0, // "msg": "OK", // "data": { // "rows": [ // { // "symbol": "BTCUSD", // "currency": "BTC", // "execQty": 18, // "execQty" regular, but "execQtyRq" in hedge // "side": "Buy", // "execPriceEp": 360086455, // "execPriceEp" regular, but "execPriceRp" in hedge // "execValueEv": 49987, // "execValueEv" regular, but "execValueRv" in hedge // "fundingRateEr": 10000, // "fundingRateEr" regular, but "fundingRateRr" in hedge // "feeRateEr": 10000, // "feeRateEr" regular, but "feeRateRr" in hedge // "execFeeEv": 5, // "execFeeEv" regular, but "execFeeRv" in hedge // "createTime": 1651881600000 // } // ] // } // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var rows interface{} = this.SafeValue(data, "rows", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(rows)); i++ { var entry interface{} = GetValue(rows, i) var timestamp interface{} = this.SafeInteger(entry, "createTime") var execFee interface{} = this.SafeString2(entry, "execFeeEv", "execFeeRv") var currencyCode interface{} = this.SafeCurrencyCode(this.SafeString(entry, "currency")) AppendToArray(&result,map[string]interface{} { "info": entry, "symbol": this.SafeString(entry, "symbol"), "code": currencyCode, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "id": nil, "amount": this.ParseFundingFeeToPrecision(execFee, market, currencyCode), }) } ch <- result return nil }() return ch } func (this *phemex) ParseFundingFeeToPrecision(value interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market currencyCode := GetArg(optionalArgs, 1, nil) _ = currencyCode if IsTrue(IsTrue(IsEqual(value, nil)) || IsTrue(IsEqual(currencyCode, nil))) { return value } // it was confirmed by phemex support, that USDT contracts use direct amounts in funding fees, while USD & INVERSE needs 'valueScale' var isUsdt interface{} = IsEqual(GetValue(market, "settle"), "USDT") if !IsTrue(isUsdt) { var currency interface{} = this.SafeCurrency(currencyCode) var scale interface{} = this.SafeString(GetValue(currency, "info"), "valueScale") var tickPrecision interface{} = this.ParsePrecision(scale) value = Precise.StringMul(value, tickPrecision) } return value } /** * @method * @name phemex#fetchFundingRate * @description fetch the current funding rate * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure} */ func (this *phemex) FetchFundingRate(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 retRes41538 := (<-this.LoadMarkets()) PanicOnError(retRes41538) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "swap")) { panic(BadSymbol(Add(this.Id, " fetchFundingRate() supports swap contracts only"))) } var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } var response interface{} = map[string]interface{} {} if !IsTrue(GetValue(market, "linear")) { response = (<-this.V1GetMdTicker24hr(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V2GetMdV2Ticker24hr(this.Extend(request, params))) PanicOnError(response) } // // { // "error": null, // "id": 0, // "result": { // "askEp": 2332500, // "bidEp": 2331000, // "fundingRateEr": 10000, // "highEp": 2380000, // "indexEp": 2329057, // "lastEp": 2331500, // "lowEp": 2274000, // "markEp": 2329232, // "openEp": 2337500, // "openInterest": 1298050, // "predFundingRateEr": 19921, // "symbol": "ETHUSD", // "timestamp": 1592474241582701416, // "turnoverEv": 47228362330, // "volume": 4053863 // } // } // var result interface{} = this.SafeValue(response, "result", map[string]interface{} {}) ch <- this.ParseFundingRate(result, market) return nil }() return ch } func (this *phemex) ParseFundingRate(contract interface{}, optionalArgs ...interface{}) interface{} { // // { // "askEp": 2332500, // "bidEp": 2331000, // "fundingRateEr": 10000, // "highEp": 2380000, // "indexEp": 2329057, // "lastEp": 2331500, // "lowEp": 2274000, // "markEp": 2329232, // "openEp": 2337500, // "openInterest": 1298050, // "predFundingRateEr": 19921, // "symbol": "ETHUSD", // "timestamp": 1592474241582701416, // "turnoverEv": 47228362330, // "volume": 4053863 // } // // linear swap v2 // // { // "closeRp":"16820.5", // "fundingRateRr":"0.0001", // "highRp":"16962.1", // "indexPriceRp":"16830.15651565", // "lowRp":"16785", // "markPriceRp":"16830.97534951", // "openInterestRv":"1323.596", // "openRp":"16851.7", // "predFundingRateRr":"0.0001", // "symbol":"BTCUSDT", // "timestamp":"1672142789065593096", // "turnoverRv":"124835296.0538", // "volumeRq":"7406.95" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(contract, "symbol") var symbol interface{} = this.SafeSymbol(marketId, market) var timestamp interface{} = this.SafeIntegerProduct(contract, "timestamp", 0.000001) var markEp interface{} = this.FromEp(this.SafeString(contract, "markEp"), market) var indexEp interface{} = this.FromEp(this.SafeString(contract, "indexEp"), market) var fundingRateEr interface{} = this.FromEr(this.SafeString(contract, "fundingRateEr"), market) var nextFundingRateEr interface{} = this.FromEr(this.SafeString(contract, "predFundingRateEr"), market) return map[string]interface{} { "info": contract, "symbol": symbol, "markPrice": this.SafeNumber(contract, "markPriceRp", markEp), "indexPrice": this.SafeNumber(contract, "indexPriceRp", indexEp), "interestRate": nil, "estimatedSettlePrice": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "fundingRate": this.SafeNumber(contract, "fundingRateRr", fundingRateEr), "fundingTimestamp": nil, "fundingDatetime": nil, "nextFundingRate": this.SafeNumber(contract, "predFundingRateRr", nextFundingRateEr), "nextFundingTimestamp": nil, "nextFundingDatetime": nil, "previousFundingRate": nil, "previousFundingTimestamp": nil, "previousFundingDatetime": nil, "interval": nil, } } /** * @method * @name phemex#setMargin * @description Either adds or reduces margin in an isolated position in order to set the margin to a specific value * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#assign-position-balance-in-isolated-marign-mode * @param {string} symbol unified market symbol of the market to set margin in * @param {float} amount the amount to set the margin to * @param {object} [params] parameters specific to the exchange API endpoint * @returns {object} A [margin structure]{@link https://docs.ccxt.com/#/?id=add-margin-structure} */ func (this *phemex) SetMargin(symbol interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes42728 := (<-this.LoadMarkets()) PanicOnError(retRes42728) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "posBalanceEv": this.ToEv(amount, market), } response:= (<-this.PrivatePostPositionsAssign(this.Extend(request, params))) PanicOnError(response) // // { // "code": 0, // "msg": "", // "data": "OK" // } // ch <- this.Extend(this.ParseMarginModification(response, market), map[string]interface{} { "amount": amount, }) return nil }() return ch } func (this *phemex) ParseMarginStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "0": "ok", } return this.SafeString(statuses, status, status) } func (this *phemex) ParseMarginModification(data interface{}, optionalArgs ...interface{}) interface{} { // // { // "code": 0, // "msg": "", // "data": "OK" // } // market := GetArg(optionalArgs, 0, nil) _ = market market = this.SafeMarket(nil, market) var inverse interface{} = this.SafeValue(market, "inverse") var codeCurrency interface{} = Ternary(IsTrue(inverse), "base", "quote") return map[string]interface{} { "info": data, "symbol": this.SafeSymbol(nil, market), "type": "set", "marginMode": "isolated", "amount": nil, "total": nil, "code": GetValue(market, codeCurrency), "status": this.ParseMarginStatus(this.SafeString(data, "code")), "timestamp": nil, "datetime": nil, } } /** * @method * @name phemex#setMarginMode * @description set margin mode to 'cross' or 'isolated' * @see https://phemex-docs.github.io/#set-leverage * @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 *phemex) 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"))) } retRes43378 := (<-this.LoadMarkets()) PanicOnError(retRes43378) var market interface{} = this.Market(symbol) if IsTrue(!IsTrue(GetValue(market, "swap")) || IsTrue(IsEqual(GetValue(market, "settle"), "USDT"))) { panic(BadSymbol(Add(this.Id, " setMarginMode() supports swap (non USDT based) contracts only"))) } 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"))) } var leverage interface{} = this.SafeInteger(params, "leverage") if IsTrue(IsEqual(marginMode, "cross")) { leverage = 0 } if IsTrue(IsEqual(leverage, nil)) { panic(ArgumentsRequired(Add(this.Id, " setMarginMode() requires a leverage parameter"))) } var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "leverage": leverage, } retRes435715 := (<-this.PrivatePutPositionsLeverage(this.Extend(request, params))) PanicOnError(retRes435715) ch <- retRes435715 return nil }() return ch } /** * @method * @name phemex#setPositionMode * @description set hedged to true or false for a market * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#switch-position-mode-synchronously * @param {bool} hedged set to true to use dualSidePosition * @param {string} symbol not used by binance setPositionMode () * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} response from the exchange */ func (this *phemex) SetPositionMode(hedged 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 this.CheckRequiredArgument("setPositionMode", symbol, "symbol") retRes43728 := (<-this.LoadMarkets()) PanicOnError(retRes43728) var market interface{} = this.Market(symbol) if IsTrue(!IsEqual(GetValue(market, "settle"), "USDT")) { panic(BadSymbol(Add(this.Id, " setPositionMode() supports USDT settled markets only"))) } var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(hedged) { AddElementToObject(request, "targetPosMode", "Hedged") } else { AddElementToObject(request, "targetPosMode", "OneWay") } retRes438515 := (<-this.PrivatePutGPositionsSwitchPosModeSync(this.Extend(request, params))) PanicOnError(retRes438515) ch <- retRes438515 return nil }() return ch } /** * @method * @name phemex#fetchLeverageTiers * @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes * @param {string[]|undefined} symbols list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [leverage tiers structures]{@link https://docs.ccxt.com/#/?id=leverage-tiers-structure}, indexed by market symbols */ func (this *phemex) FetchLeverageTiers(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 retRes43978 := (<-this.LoadMarkets()) PanicOnError(retRes43978) if IsTrue(!IsEqual(symbols, nil)) { var first interface{} = this.SafeValue(symbols, 0) var market interface{} = this.Market(first) if IsTrue(!IsEqual(GetValue(market, "settle"), "USD")) { panic(BadSymbol(Add(this.Id, " fetchLeverageTiers() supports USD settled markets only"))) } } response:= (<-this.PublicGetCfgV2Products(params)) PanicOnError(response) // // { // "code":0, // "msg":"OK", // "data":{ // "ratioScale":8, // "currencies":[ // {"currency":"BTC","valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"name":"Bitcoin"}, // {"currency":"USD","valueScale":4,"minValueEv":1,"maxValueEv":500000000000000,"name":"USD"}, // {"currency":"USDT","valueScale":8,"minValueEv":1,"maxValueEv":5000000000000000000,"name":"TetherUS"}, // ], // "products":[ // { // "symbol":"BTCUSD", // "displaySymbol":"BTC / USD", // "indexSymbol":".BTC", // "markSymbol":".MBTC", // "fundingRateSymbol":".BTCFR", // "fundingRate8hSymbol":".BTCFR8H", // "contractUnderlyingAssets":"USD", // "settleCurrency":"BTC", // "quoteCurrency":"USD", // "contractSize":1.0, // "lotSize":1, // "tickSize":0.5, // "priceScale":4, // "ratioScale":8, // "pricePrecision":1, // "minPriceEp":5000, // "maxPriceEp":10000000000, // "maxOrderQty":1000000, // "type":"Perpetual" // }, // { // "symbol":"sBTCUSDT", // "displaySymbol":"BTC / USDT", // "quoteCurrency":"USDT", // "pricePrecision":2, // "type":"Spot", // "baseCurrency":"BTC", // "baseTickSize":"0.000001 BTC", // "baseTickSizeEv":100, // "quoteTickSize":"0.01 USDT", // "quoteTickSizeEv":1000000, // "minOrderValue":"10 USDT", // "minOrderValueEv":1000000000, // "maxBaseOrderSize":"1000 BTC", // "maxBaseOrderSizeEv":100000000000, // "maxOrderValue":"5,000,000 USDT", // "maxOrderValueEv":500000000000000, // "defaultTakerFee":"0.001", // "defaultTakerFeeEr":100000, // "defaultMakerFee":"0.001", // "defaultMakerFeeEr":100000, // "baseQtyPrecision":6, // "quoteQtyPrecision":2 // }, // ], // "riskLimits":[ // { // "symbol":"BTCUSD", // "steps":"50", // "riskLimits":[ // {"limit":100,"initialMargin":"1.0%","initialMarginEr":1000000,"maintenanceMargin":"0.5%","maintenanceMarginEr":500000}, // {"limit":150,"initialMargin":"1.5%","initialMarginEr":1500000,"maintenanceMargin":"1.0%","maintenanceMarginEr":1000000}, // {"limit":200,"initialMargin":"2.0%","initialMarginEr":2000000,"maintenanceMargin":"1.5%","maintenanceMarginEr":1500000}, // ] // }, // ], // "leverages":[ // {"initialMargin":"1.0%","initialMarginEr":1000000,"options":[1,2,3,5,10,25,50,100]}, // {"initialMargin":"1.5%","initialMarginEr":1500000,"options":[1,2,3,5,10,25,50,66]}, // {"initialMargin":"2.0%","initialMarginEr":2000000,"options":[1,2,3,5,10,25,33,50]}, // ] // } // } // // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var riskLimits interface{} = this.SafeList(data, "riskLimits") ch <- this.ParseLeverageTiers(riskLimits, symbols, "symbol") return nil }() return ch } func (this *phemex) ParseMarketLeverageTiers(info interface{}, optionalArgs ...interface{}) interface{} { /** * @param {object} info Exchange market response for 1 market * @param {object} market CCXT market */ // // { // "symbol":"BTCUSD", // "steps":"50", // "riskLimits":[ // {"limit":100,"initialMargin":"1.0%","initialMarginEr":1000000,"maintenanceMargin":"0.5%","maintenanceMarginEr":500000}, // {"limit":150,"initialMargin":"1.5%","initialMarginEr":1500000,"maintenanceMargin":"1.0%","maintenanceMarginEr":1000000}, // {"limit":200,"initialMargin":"2.0%","initialMarginEr":2000000,"maintenanceMargin":"1.5%","maintenanceMarginEr":1500000}, // ] // }, // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(info, "symbol") market = this.SafeMarket(marketId, market) var riskLimits interface{} = (GetValue(GetValue(market, "info"), "riskLimits")) var tiers interface{} = []interface{}{} var minNotional interface{} = 0 for i := 0; IsLessThan(i, GetArrayLength(riskLimits)); i++ { var tier interface{} = GetValue(riskLimits, i) var maxNotional interface{} = this.SafeInteger(tier, "limit") AppendToArray(&tiers,map[string]interface{} { "tier": this.Sum(i, 1), "symbol": this.SafeSymbol(marketId, market), "currency": GetValue(market, "settle"), "minNotional": minNotional, "maxNotional": maxNotional, "maintenanceMarginRate": this.SafeString(tier, "maintenanceMargin"), "maxLeverage": nil, "info": tier, }) minNotional = maxNotional } return tiers } func (this *phemex) 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{} = this.Omit(params, this.ExtractParams(path)) var requestPath interface{} = Add("/", this.ImplodeParams(path, params)) var url interface{} = requestPath var queryString interface{} = "" if IsTrue(IsTrue(IsTrue(IsTrue((IsEqual(method, "GET"))) || IsTrue((IsEqual(method, "DELETE")))) || IsTrue((IsEqual(method, "PUT")))) || IsTrue((IsEqual(url, "/positions/assign")))) { if IsTrue(GetArrayLength(ObjectKeys(query))) { queryString = this.UrlencodeWithArrayRepeat(query) url = Add(url, Add("?", queryString)) } } if IsTrue(IsEqual(api, "private")) { this.CheckRequiredCredentials() var timestamp interface{} = this.Seconds() var xPhemexRequestExpiry interface{} = this.SafeInteger(this.Options, "x-phemex-request-expiry", 60) var expiry interface{} = this.Sum(timestamp, xPhemexRequestExpiry) var expiryString interface{} = ToString(expiry) headers = map[string]interface{} { "x-phemex-access-token": this.ApiKey, "x-phemex-request-expiry": expiryString, } var payload interface{} = "" if IsTrue(IsEqual(method, "POST")) { var isOrderPlacement interface{} = IsTrue(IsTrue((IsEqual(path, "g-orders"))) || IsTrue((IsEqual(path, "spot/orders")))) || IsTrue((IsEqual(path, "orders"))) if IsTrue(isOrderPlacement) { if IsTrue(IsEqual(this.SafeString(params, "clOrdID"), nil)) { var id interface{} = this.SafeString(this.Options, "brokerId", "CCXT123456") AddElementToObject(params, "clOrdID", Add(id, this.Uuid16())) } } payload = this.Json(params) body = payload AddElementToObject(headers, "Content-Type", "application/json") } var auth interface{} = Add(Add(Add(requestPath, queryString), expiryString), payload) AddElementToObject(headers, "x-phemex-request-signature", this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha256)) } url = Add(this.ImplodeHostname(GetValue(GetValue(this.Urls, "api"), api)), url) return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } /** * @method * @name phemex#setLeverage * @description set the level of leverage for a market * @see https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#set-leverage * @param {float} leverage the rate of leverage, 100 > leverage > -100 excluding numbers between -1 to 1 * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {bool} [params.hedged] set to true if hedged position mode is enabled (by default long and short leverage are set to the same value) * @param {float} [params.longLeverageRr] *hedged mode only* set the leverage for long positions * @param {float} [params.shortLeverageRr] *hedged mode only* set the leverage for short positions * @returns {object} response from the exchange */ func (this *phemex) SetLeverage(leverage interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // WARNING: THIS WILL INCREASE LIQUIDATION PRICE FOR OPEN ISOLATED LONG POSITIONS // AND DECREASE LIQUIDATION PRICE FOR OPEN ISOLATED SHORT POSITIONS 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, OpNeg(100)))) || IsTrue((IsGreaterThan(leverage, 100)))) { panic(BadRequest(Add(this.Id, " setLeverage() leverage should be between -100 and 100"))) } retRes45918 := (<-this.LoadMarkets()) PanicOnError(retRes45918) var isHedged interface{} = this.SafeBool(params, "hedged", false) var longLeverageRr interface{} = this.SafeInteger(params, "longLeverageRr") var shortLeverageRr interface{} = this.SafeInteger(params, "shortLeverageRr") var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } var response interface{} = nil if IsTrue(IsEqual(GetValue(market, "settle"), "USDT")) { if IsTrue(IsTrue(!IsTrue(isHedged) && IsTrue(IsEqual(longLeverageRr, nil))) && IsTrue(IsEqual(shortLeverageRr, nil))) { AddElementToObject(request, "leverageRr", leverage) } else { var longVar interface{} = Ternary(IsTrue((!IsEqual(longLeverageRr, nil))), longLeverageRr, leverage) var shortVar interface{} = Ternary(IsTrue((!IsEqual(shortLeverageRr, nil))), shortLeverageRr, leverage) AddElementToObject(request, "longLeverageRr", longVar) AddElementToObject(request, "shortLeverageRr", shortVar) } response = (<-this.PrivatePutGPositionsLeverage(this.Extend(request, params))) PanicOnError(response) } else { AddElementToObject(request, "leverage", leverage) response = (<-this.PrivatePutPositionsLeverage(this.Extend(request, params))) PanicOnError(response) } ch <- response return nil }() return ch } /** * @method * @name phemex#transfer * @description transfer currency internally between wallets on the same account * @see https://phemex-docs.github.io/#transfer-between-spot-and-futures * @see https://phemex-docs.github.io/#universal-transfer-main-account-only-transfer-between-sub-to-main-main-to-sub-or-sub-to-sub * @param {string} code unified currency code * @param {float} amount amount to transfer * @param {string} fromAccount account to transfer from * @param {string} toAccount account to transfer to * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.bizType] for transferring between main and sub-acounts either 'SPOT' or 'PERPETUAL' default is 'SPOT' * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure} */ func (this *phemex) Transfer(code interface{}, amount interface{}, fromAccount interface{}, toAccount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes46328 := (<-this.LoadMarkets()) PanicOnError(retRes46328) var currency interface{} = this.Currency(code) var accountsByType interface{} = this.SafeValue(this.Options, "accountsByType", map[string]interface{} {}) var fromId interface{} = this.SafeString(accountsByType, fromAccount, fromAccount) var toId interface{} = this.SafeString(accountsByType, toAccount, toAccount) var scaledAmmount interface{} = this.ToEv(amount, currency) var direction interface{} = nil var transfer interface{} = nil if IsTrue(IsTrue(IsEqual(fromId, "spot")) && IsTrue(IsEqual(toId, "future"))) { direction = 2 } else if IsTrue(IsTrue(IsEqual(fromId, "future")) && IsTrue(IsEqual(toId, "spot"))) { direction = 1 } if IsTrue(!IsEqual(direction, nil)) { var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), "moveOp": direction, "amountEv": scaledAmmount, } response:= (<-this.PrivatePostAssetsTransfer(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "OK", // "data": { // "linkKey": "8564eba4-c9ec-49d6-9b8c-2ec5001a0fb9", // "userId": "4018340", // "currency": "USD", // "amountEv": "10", // "side": "2", // "status": "10" // } // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) transfer = this.ParseTransfer(data, currency) } else { var request interface{} = map[string]interface{} { "fromUserId": fromId, "toUserId": toId, "amountEv": scaledAmmount, "currency": GetValue(currency, "id"), "bizType": this.SafeString(params, "bizType", "SPOT"), } response:= (<-this.PrivatePostAssetsUniversalTransfer(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "OK", // "data": "API-923db826-aaaa-aaaa-aaaa-4d98c3a7c9fd" // } // transfer = this.ParseTransfer(response) } var transferOptions interface{} = this.SafeValue(this.Options, "transfer", map[string]interface{} {}) var fillResponseFromRequest interface{} = this.SafeBool(transferOptions, "fillResponseFromRequest", true) if IsTrue(fillResponseFromRequest) { if IsTrue(IsEqual(GetValue(transfer, "fromAccount"), nil)) { AddElementToObject(transfer, "fromAccount", fromAccount) } if IsTrue(IsEqual(GetValue(transfer, "toAccount"), nil)) { AddElementToObject(transfer, "toAccount", toAccount) } if IsTrue(IsEqual(GetValue(transfer, "amount"), nil)) { AddElementToObject(transfer, "amount", amount) } if IsTrue(IsEqual(GetValue(transfer, "currency"), nil)) { AddElementToObject(transfer, "currency", code) } } ch <- transfer return nil }() return ch } /** * @method * @name phemex#fetchTransfers * @description fetch a history of internal transfers made on an account * @see https://phemex-docs.github.io/#query-transfer-history * @param {string} code unified currency code of the currency transferred * @param {int} [since] the earliest time in ms to fetch transfers for * @param {int} [limit] the maximum number of transfers structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [transfer structures]{@link https://docs.ccxt.com/#/?id=transfer-structure} */ func (this *phemex) FetchTransfers(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes47178 := (<-this.LoadMarkets()) PanicOnError(retRes47178) if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchTransfers() requires a code argument"))) } var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivateGetAssetsTransfer(this.Extend(request, params))) PanicOnError(response) // // { // "code": 0, // "msg": "OK", // "data": { // "rows": [ // { // "linkKey": "87c071a3-8628-4ac2-aca1-6ce0d1fad66c", // "userId": 4148428, // "currency": "BTC", // "amountEv": 67932, // "side": 2, // "status": 10, // "createTime": 1652832467000, // "bizType": 10 // } // ] // } // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var transfers interface{} = this.SafeList(data, "rows", []interface{}{}) ch <- this.ParseTransfers(transfers, currency, since, limit) return nil }() return ch } func (this *phemex) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} { // // transfer // // { // "linkKey": "8564eba4-c9ec-49d6-9b8c-2ec5001a0fb9", // "userId": "4018340", // "currency": "USD", // "amountEv": "10", // "side": "2", // "status": "10" // } // // fetchTransfers // // { // "linkKey": "87c071a3-8628-4ac2-aca1-6ce0d1fad66c", // "userId": 4148428, // "currency": "BTC", // "amountEv": 67932, // "side": 2, // "status": 10, // "createTime": 1652832467000, // "bizType": 10 // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var id interface{} = this.SafeString(transfer, "linkKey") var status interface{} = this.SafeString(transfer, "status") var amountEv interface{} = this.SafeString(transfer, "amountEv") var amountTransfered interface{} = this.FromEv(amountEv) var currencyId interface{} = this.SafeString(transfer, "currency") var code interface{} = this.SafeCurrencyCode(currencyId, currency) var side interface{} = this.SafeInteger(transfer, "side") var fromId interface{} = nil var toId interface{} = nil if IsTrue(IsEqual(side, 1)) { fromId = "swap" toId = "spot" } else if IsTrue(IsEqual(side, 2)) { fromId = "spot" toId = "swap" } var timestamp interface{} = this.SafeInteger(transfer, "createTime") return map[string]interface{} { "info": transfer, "id": id, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "currency": code, "amount": amountTransfered, "fromAccount": fromId, "toAccount": toId, "status": this.ParseTransferStatus(status), } } func (this *phemex) ParseTransferStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "3": "rejected", "6": "canceled", "10": "ok", "11": "failed", } return this.SafeString(statuses, status, status) } /** * @method * @name phemex#fetchFundingRateHistory * @description fetches historical funding rate prices * @see https://phemex-docs.github.io/#query-funding-rate-history-2 * @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 {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) * @param {int} [params.until] timestamp in ms of the latest funding rate * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} */ func (this *phemex) 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchFundingRateHistory() requires a symbol argument"))) } retRes48408 := (<-this.LoadMarkets()) PanicOnError(retRes48408) var market interface{} = this.Market(symbol) var isUsdtSettled interface{} = IsEqual(GetValue(market, "settle"), "USDT") if !IsTrue(GetValue(market, "swap")) { panic(BadRequest(Add(this.Id, " fetchFundingRateHistory() supports swap contracts only"))) } var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchFundingRateHistory", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes484919 := (<-this.FetchPaginatedCallDeterministic("fetchFundingRateHistory", symbol, since, limit, "8h", params, 100)) PanicOnError(retRes484919) ch <- retRes484919 return nil } var customSymbol interface{} = nil if IsTrue(isUsdtSettled) { customSymbol = Add(Add(".", GetValue(market, "id")), "FR8H") // phemex requires a custom symbol for funding rate history } else { customSymbol = Add(Add(".", GetValue(market, "baseId")), "FR8H") } var request interface{} = map[string]interface{} { "symbol": customSymbol, } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) var response interface{} = nil if IsTrue(isUsdtSettled) { response = (<-this.V2GetApiDataPublicDataFundingRateHistory(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V1GetApiDataPublicDataFundingRateHistory(this.Extend(request, params))) PanicOnError(response) } // // { // "code":"0", // "msg":"OK", // "data":{ // "rows":[ // { // "symbol":".BTCUSDTFR8H", // "fundingRate":"0.0001", // "fundingTime":"1682064000000", // "intervalSeconds":"28800" // } // ] // } // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var rates interface{} = this.SafeValue(data, "rows") var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(rates)); i++ { var item interface{} = GetValue(rates, i) var timestamp interface{} = this.SafeInteger(item, "fundingTime") AppendToArray(&result,map[string]interface{} { "info": item, "symbol": symbol, "fundingRate": this.SafeNumber(item, "fundingRate"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), }) } var sorted interface{} = this.SortBy(result, "timestamp") ch <- this.FilterBySymbolSinceLimit(sorted, symbol, since, limit) return nil }() return ch } /** * @method * @name phemex#withdraw * @description make a withdrawal * @see https://phemex-docs.github.io/#create-withdraw-request * @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 phemex api endpoint * @param {string} [params.network] unified network code * @returns {object} a [transaction structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#transaction-structure} */ func (this *phemex) 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) retRes49228 := (<-this.LoadMarkets()) PanicOnError(retRes49228) this.CheckAddress(address) var currency interface{} = this.Currency(code) var networkCode interface{} = nil networkCodeparamsVariable := this.HandleNetworkCodeAndParams(params); networkCode = GetValue(networkCodeparamsVariable,0); params = GetValue(networkCodeparamsVariable,1) var networkId interface{} = nil if IsTrue(!IsEqual(networkCode, nil)) { networkId = this.NetworkCodeToId(networkCode) } var stableCoins interface{} = this.SafeValue(this.Options, "stableCoins") if IsTrue(IsEqual(networkId, nil)) { if !IsTrue((this.InArray(code, stableCoins))) { networkId = GetValue(currency, "id") } else { panic(ArgumentsRequired(Add(this.Id, " withdraw () requires an extra argument params[\"network\"]"))) } } var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), "address": address, "amount": amount, "chainName": ToUpper(networkId), } if IsTrue(!IsEqual(tag, nil)) { AddElementToObject(request, "addressTag", tag) } response:= (<-this.PrivatePostPhemexWithdrawWalletsApiCreateWithdraw(this.Extend(request, params))) PanicOnError(response) // // { // "code": 0, // "msg": "OK", // "data": { // "id": "10000001", // "freezeId": null, // "address": "44exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // "amountRv": "100", // "chainCode": "11", // "chainName": "TRX", // "currency": "USDT", // "currencyCode": 3, // "email": "abc@gmail.com", // "expiredTime": "0", // "feeRv": "1", // "nickName": null, // "phone": null, // "rejectReason": "", // "submitedAt": "1670000000000", // "submittedAt": "1670000000000", // "txHash": null, // "userId": "10000001", // "status": "Success" // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseTransaction(data, currency) return nil }() return ch } /** * @method * @name phemex#fetchOpenInterest * @description retrieves the open interest of a trading pair * @see https://phemex-docs.github.io/#query-24-hours-ticker * @param {string} symbol unified CCXT market symbol * @param {object} [params] exchange specific parameters * @returns {object} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure} */ func (this *phemex) FetchOpenInterest(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 retRes49908 := (<-this.LoadMarkets()) PanicOnError(retRes49908) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "contract")) { panic(BadRequest(Add(this.Id, " fetchOpenInterest is only supported for contract markets."))) } var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } response:= (<-this.V2GetMdV2Ticker24hr(this.Extend(request, params))) PanicOnError(response) // // { // error: null, // id: '0', // result: { // closeRp: '67550.1', // fundingRateRr: '0.0001', // highRp: '68400', // indexPriceRp: '67567.15389794', // lowRp: '66096.4', // markPriceRp: '67550.1', // openInterestRv: '1848.1144186', // openRp: '66330', // predFundingRateRr: '0.0001', // symbol: 'BTCUSDT', // timestamp: '1729114315443343001', // turnoverRv: '228863389.3237532', // volumeRq: '3388.5600312' // } // } // var result interface{} = this.SafeDict(response, "result") ch <- this.ParseOpenInterest(result, market) return nil }() return ch } func (this *phemex) ParseOpenInterest(interest interface{}, optionalArgs ...interface{}) interface{} { // // { // closeRp: '67550.1', // fundingRateRr: '0.0001', // highRp: '68400', // indexPriceRp: '67567.15389794', // lowRp: '66096.4', // markPriceRp: '67550.1', // openInterestRv: '1848.1144186', // openRp: '66330', // predFundingRateRr: '0.0001', // symbol: 'BTCUSDT', // timestamp: '1729114315443343001', // turnoverRv: '228863389.3237532', // volumeRq: '3388.5600312' // } // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = Divide(this.SafeInteger(interest, "timestamp"), 1000000) var id interface{} = this.SafeString(interest, "symbol") return this.SafeOpenInterest(map[string]interface{} { "info": interest, "symbol": this.SafeSymbol(id, market), "baseVolume": this.SafeString(interest, "volumeRq"), "quoteVolume": nil, "openInterestAmount": this.SafeString(interest, "openInterestRv"), "openInterestValue": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), }, market) } /** * @method * @name phemex#fetchConvertQuote * @description fetch a quote for converting from one currency to another * @see https://phemex-docs.github.io/#rfq-quote * @param {string} fromCode the currency that you want to sell and convert from * @param {string} toCode the currency that you want to buy and convert into * @param {float} amount how much you want to trade in units of the from currency * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure} */ func (this *phemex) FetchConvertQuote(fromCode interface{}, toCode interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) amount := GetArg(optionalArgs, 0, nil) _ = amount params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes50688 := (<-this.LoadMarkets()) PanicOnError(retRes50688) var fromCurrency interface{} = this.Currency(fromCode) var toCurrency interface{} = this.Currency(toCode) var valueScale interface{} = this.SafeInteger(fromCurrency, "valueScale") var request interface{} = map[string]interface{} { "fromCurrency": fromCode, "toCurrency": toCode, "fromAmountEv": this.ToEn(amount, valueScale), } response:= (<-this.PrivateGetAssetsQuote(this.Extend(request, params))) PanicOnError(response) // // { // "code": 0, // "msg": "OK", // "data": { // "code": "GIF...AAA", // "quoteArgs": { // "origin": 10, // "price": "0.00000939", // "proceeds": "0.00000000", // "ttlMs": 7000, // "expireAt": 1739875826009, // "requestAt": 1739875818009, // "quoteAt": 1739875816594 // } // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseConversion(data, fromCurrency, toCurrency) return nil }() return ch } /** * @method * @name phemex#createConvertTrade * @description convert from one currency to another * @see https://phemex-docs.github.io/#convert * @param {string} id the id of the trade that you want to make * @param {string} fromCode the currency that you want to sell and convert from * @param {string} toCode the currency that you want to buy and convert into * @param {float} [amount] how much you want to trade in units of the from currency * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure} */ func (this *phemex) CreateConvertTrade(id interface{}, fromCode interface{}, toCode interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) amount := GetArg(optionalArgs, 0, nil) _ = amount params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes51138 := (<-this.LoadMarkets()) PanicOnError(retRes51138) var fromCurrency interface{} = this.Currency(fromCode) var toCurrency interface{} = this.Currency(toCode) var valueScale interface{} = this.SafeInteger(fromCurrency, "valueScale") var request interface{} = map[string]interface{} { "code": id, "fromCurrency": fromCode, "toCurrency": toCode, } if IsTrue(!IsEqual(amount, nil)) { AddElementToObject(request, "fromAmountEv", this.ToEn(amount, valueScale)) } response:= (<-this.PrivatePostAssetsConvert(this.Extend(request, params))) PanicOnError(response) // // { // "code": 0, // "msg": "OK", // "data": { // "moveOp": 0, // "fromCurrency": "USDT", // "toCurrency": "BTC", // "fromAmountEv": 4000000000, // "toAmountEv": 41511, // "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247", // "status": 10 // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) var fromCurrencyId interface{} = this.SafeString(data, "fromCurrency") var fromResult interface{} = this.SafeCurrency(fromCurrencyId, fromCurrency) var toCurrencyId interface{} = this.SafeString(data, "toCurrency") var to interface{} = this.SafeCurrency(toCurrencyId, toCurrency) ch <- this.ParseConversion(data, fromResult, to) return nil }() return ch } /** * @method * @name phemex#fetchConvertTradeHistory * @description fetch the users history of conversion trades * @see https://phemex-docs.github.io/#query-convert-history * @param {string} [code] the unified currency code * @param {int} [since] the earliest time in ms to fetch conversions for * @param {int} [limit] the maximum number of conversion structures to retrieve, default 20, max 200 * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.until] the end time in ms * @param {string} [params.fromCurrency] the currency that you sold and converted from * @param {string} [params.toCurrency] the currency that you bought and converted into * @returns {object[]} a list of [conversion structures]{@link https://docs.ccxt.com/#/?id=conversion-structure} */ func (this *phemex) FetchConvertTradeHistory(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 retRes51648 := (<-this.LoadMarkets()) PanicOnError(retRes51648) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(code, nil)) { AddElementToObject(request, "fromCurrency", code) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } requestparamsVariable := this.HandleUntilOption("endTime", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.PrivateGetAssetsConvert(this.Extend(request, params))) PanicOnError(response) // // { // "code": 0, // "msg": "OK", // "data": { // "total": 2, // "rows": [ // { // "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247", // "createTime": 1739882294000, // "fromCurrency": "USDT", // "toCurrency": "BTC", // "fromAmountEv": 4000000000, // "toAmountEv": 41511, // "status": 10, // "conversionRate": 1037, // "errorCode": 0 // }, // ] // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) var rows interface{} = this.SafeList(data, "rows", []interface{}{}) ch <- this.ParseConversions(rows, code, "fromCurrency", "toCurrency", since, limit) return nil }() return ch } func (this *phemex) ParseConversion(conversion interface{}, optionalArgs ...interface{}) interface{} { // // fetchConvertQuote // // { // "code": "GIF...AAA", // "quoteArgs": { // "origin": 10, // "price": "0.00000939", // "proceeds": "0.00000000", // "ttlMs": 7000, // "expireAt": 1739875826009, // "requestAt": 1739875818009, // "quoteAt": 1739875816594 // } // } // // createConvertTrade // // { // "moveOp": 0, // "fromCurrency": "USDT", // "toCurrency": "BTC", // "fromAmountEv": 4000000000, // "toAmountEv": 41511, // "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247", // "status": 10 // } // // fetchConvertTradeHistory // // { // "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247", // "createTime": 1739882294000, // "fromCurrency": "USDT", // "toCurrency": "BTC", // "fromAmountEv": 4000000000, // "toAmountEv": 41511, // "status": 10, // "conversionRate": 1037, // "errorCode": 0 // } // fromCurrency := GetArg(optionalArgs, 0, nil) _ = fromCurrency toCurrency := GetArg(optionalArgs, 1, nil) _ = toCurrency var quoteArgs interface{} = this.SafeDict(conversion, "quoteArgs", map[string]interface{} {}) var requestTime interface{} = this.SafeInteger(quoteArgs, "requestAt") var timestamp interface{} = this.SafeInteger(conversion, "createTime", requestTime) var fromCoin interface{} = this.SafeString(conversion, "fromCurrency", this.SafeString(fromCurrency, "code")) var fromCode interface{} = this.SafeCurrencyCode(fromCoin, fromCurrency) var toCoin interface{} = this.SafeString(conversion, "toCurrency", this.SafeString(toCurrency, "code")) var toCode interface{} = this.SafeCurrencyCode(toCoin, toCurrency) var fromValueScale interface{} = this.SafeInteger(fromCurrency, "valueScale") var toValueScale interface{} = this.SafeInteger(toCurrency, "valueScale") var fromAmount interface{} = this.FromEn(this.SafeString(conversion, "fromAmountEv"), fromValueScale) if IsTrue(IsTrue(IsEqual(fromAmount, nil)) && IsTrue(!IsEqual(quoteArgs, nil))) { fromAmount = this.FromEn(this.SafeString(quoteArgs, "origin"), fromValueScale) } var toAmount interface{} = this.FromEn(this.SafeString(conversion, "toAmountEv"), toValueScale) if IsTrue(IsTrue(IsEqual(toAmount, nil)) && IsTrue(!IsEqual(quoteArgs, nil))) { toAmount = this.FromEn(this.SafeString(quoteArgs, "proceeds"), toValueScale) } return map[string]interface{} { "info": conversion, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "id": this.SafeString(conversion, "code"), "fromCurrency": fromCode, "fromAmount": this.ParseNumber(fromAmount), "toCurrency": toCode, "toAmount": this.ParseNumber(toAmount), "price": this.SafeNumber(quoteArgs, "price"), "fee": nil, } } func (this *phemex) HandleErrors(httpCode 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 // fallback to default error handler } // // {"code":30018,"msg":"phemex.data.size.uplimt","data":null} // {"code":412,"msg":"Missing parameter - resolution","data":null} // {"code":412,"msg":"Missing parameter - to","data":null} // {"error":{"code":6001,"message":"invalid argument"},"id":null,"result":null} // var error interface{} = this.SafeValue(response, "error", response) var errorCode interface{} = this.SafeString(error, "code") var message interface{} = this.SafeString(error, "msg") if IsTrue(IsTrue((!IsEqual(errorCode, nil))) && IsTrue((!IsEqual(errorCode, "0")))) { var feedback interface{} = Add(Add(this.Id, " "), body) this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorCode, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, feedback) panic(ExchangeError(feedback)) } return nil } func (this *phemex) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }