5992 lines
268 KiB
Go
5992 lines
268 KiB
Go
package ccxt
|
|
|
|
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
|
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
|
|
|
type 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
|
|
}
|