2718 lines
114 KiB
Go
2718 lines
114 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 paradex struct {
|
||
|
Exchange
|
||
|
|
||
|
}
|
||
|
|
||
|
func NewParadexCore() paradex {
|
||
|
p := paradex{}
|
||
|
setDefaults(&p)
|
||
|
return p
|
||
|
}
|
||
|
|
||
|
func (this *paradex) Describe() interface{} {
|
||
|
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
|
||
|
"id": "paradex",
|
||
|
"name": "Paradex",
|
||
|
"countries": []interface{}{},
|
||
|
"version": "v1",
|
||
|
"rateLimit": 50,
|
||
|
"certified": false,
|
||
|
"pro": true,
|
||
|
"dex": true,
|
||
|
"has": map[string]interface{} {
|
||
|
"CORS": nil,
|
||
|
"spot": false,
|
||
|
"margin": false,
|
||
|
"swap": true,
|
||
|
"future": false,
|
||
|
"option": false,
|
||
|
"addMargin": false,
|
||
|
"borrowCrossMargin": false,
|
||
|
"borrowIsolatedMargin": false,
|
||
|
"cancelAllOrders": true,
|
||
|
"cancelAllOrdersAfter": false,
|
||
|
"cancelOrder": false,
|
||
|
"cancelOrders": false,
|
||
|
"cancelOrdersForSymbols": false,
|
||
|
"closeAllPositions": false,
|
||
|
"closePosition": false,
|
||
|
"createMarketBuyOrderWithCost": false,
|
||
|
"createMarketOrderWithCost": false,
|
||
|
"createMarketSellOrderWithCost": false,
|
||
|
"createOrder": true,
|
||
|
"createOrders": false,
|
||
|
"createReduceOnlyOrder": false,
|
||
|
"createStopOrder": true,
|
||
|
"createTriggerOrder": true,
|
||
|
"editOrder": false,
|
||
|
"fetchAccounts": false,
|
||
|
"fetchBalance": true,
|
||
|
"fetchBorrowInterest": false,
|
||
|
"fetchBorrowRateHistories": false,
|
||
|
"fetchBorrowRateHistory": false,
|
||
|
"fetchCanceledOrders": false,
|
||
|
"fetchClosedOrders": false,
|
||
|
"fetchCrossBorrowRate": false,
|
||
|
"fetchCrossBorrowRates": false,
|
||
|
"fetchCurrencies": false,
|
||
|
"fetchDepositAddress": false,
|
||
|
"fetchDepositAddresses": false,
|
||
|
"fetchDeposits": true,
|
||
|
"fetchDepositWithdrawFee": false,
|
||
|
"fetchDepositWithdrawFees": false,
|
||
|
"fetchFundingHistory": false,
|
||
|
"fetchFundingRate": false,
|
||
|
"fetchFundingRateHistory": false,
|
||
|
"fetchFundingRates": false,
|
||
|
"fetchIndexOHLCV": false,
|
||
|
"fetchIsolatedBorrowRate": false,
|
||
|
"fetchIsolatedBorrowRates": false,
|
||
|
"fetchLedger": false,
|
||
|
"fetchLeverage": false,
|
||
|
"fetchLeverageTiers": false,
|
||
|
"fetchLiquidations": true,
|
||
|
"fetchMarginMode": nil,
|
||
|
"fetchMarketLeverageTiers": false,
|
||
|
"fetchMarkets": true,
|
||
|
"fetchMarkOHLCV": false,
|
||
|
"fetchMyLiquidations": false,
|
||
|
"fetchMyTrades": true,
|
||
|
"fetchOHLCV": true,
|
||
|
"fetchOpenInterest": true,
|
||
|
"fetchOpenInterestHistory": false,
|
||
|
"fetchOpenOrders": true,
|
||
|
"fetchOrder": true,
|
||
|
"fetchOrderBook": true,
|
||
|
"fetchOrders": true,
|
||
|
"fetchOrderTrades": false,
|
||
|
"fetchPosition": true,
|
||
|
"fetchPositionMode": false,
|
||
|
"fetchPositions": true,
|
||
|
"fetchPositionsRisk": false,
|
||
|
"fetchPremiumIndexOHLCV": false,
|
||
|
"fetchStatus": true,
|
||
|
"fetchTicker": true,
|
||
|
"fetchTickers": true,
|
||
|
"fetchTime": true,
|
||
|
"fetchTrades": true,
|
||
|
"fetchTradingFee": false,
|
||
|
"fetchTradingFees": false,
|
||
|
"fetchTransfer": false,
|
||
|
"fetchTransfers": false,
|
||
|
"fetchWithdrawal": false,
|
||
|
"fetchWithdrawals": true,
|
||
|
"reduceMargin": false,
|
||
|
"repayCrossMargin": false,
|
||
|
"repayIsolatedMargin": false,
|
||
|
"sandbox": true,
|
||
|
"setLeverage": false,
|
||
|
"setMarginMode": false,
|
||
|
"setPositionMode": false,
|
||
|
"transfer": false,
|
||
|
"withdraw": false,
|
||
|
},
|
||
|
"timeframes": map[string]interface{} {
|
||
|
"1m": 1,
|
||
|
"3m": 3,
|
||
|
"5m": 5,
|
||
|
"15m": 15,
|
||
|
"30m": 30,
|
||
|
"1h": 60,
|
||
|
},
|
||
|
"hostname": "paradex.trade",
|
||
|
"urls": map[string]interface{} {
|
||
|
"logo": "https://github.com/user-attachments/assets/84628770-784e-4ec4-a759-ec2fbb2244ea",
|
||
|
"api": map[string]interface{} {
|
||
|
"v1": "https://api.prod.{hostname}/v1",
|
||
|
},
|
||
|
"test": map[string]interface{} {
|
||
|
"v1": "https://api.testnet.{hostname}/v1",
|
||
|
},
|
||
|
"www": "https://www.paradex.trade/",
|
||
|
"doc": "https://docs.api.testnet.paradex.trade/",
|
||
|
"fees": "https://docs.paradex.trade/getting-started/trading-fees",
|
||
|
"referral": "https://app.paradex.trade/r/ccxt24",
|
||
|
},
|
||
|
"api": map[string]interface{} {
|
||
|
"public": map[string]interface{} {
|
||
|
"get": map[string]interface{} {
|
||
|
"bbo/{market}": 1,
|
||
|
"funding/data": 1,
|
||
|
"markets": 1,
|
||
|
"markets/klines": 1,
|
||
|
"markets/summary": 1,
|
||
|
"orderbook/{market}": 1,
|
||
|
"insurance": 1,
|
||
|
"referrals/config": 1,
|
||
|
"system/config": 1,
|
||
|
"system/state": 1,
|
||
|
"system/time": 1,
|
||
|
"trades": 1,
|
||
|
},
|
||
|
},
|
||
|
"private": map[string]interface{} {
|
||
|
"get": map[string]interface{} {
|
||
|
"account": 1,
|
||
|
"account/profile": 1,
|
||
|
"balance": 1,
|
||
|
"fills": 1,
|
||
|
"funding/payments": 1,
|
||
|
"positions": 1,
|
||
|
"tradebusts": 1,
|
||
|
"transactions": 1,
|
||
|
"liquidations": 1,
|
||
|
"orders": 1,
|
||
|
"orders-history": 1,
|
||
|
"orders/by_client_id/{client_id}": 1,
|
||
|
"orders/{order_id}": 1,
|
||
|
"points_data/{market}/{program}": 1,
|
||
|
"referrals/summary": 1,
|
||
|
"transfers": 1,
|
||
|
},
|
||
|
"post": map[string]interface{} {
|
||
|
"account/profile/referral_code": 1,
|
||
|
"account/profile/username": 1,
|
||
|
"auth": 1,
|
||
|
"onboarding": 1,
|
||
|
"orders": 1,
|
||
|
},
|
||
|
"delete": map[string]interface{} {
|
||
|
"orders": 1,
|
||
|
"orders/by_client_id/{client_id}": 1,
|
||
|
"orders/{order_id}": 1,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"fees": map[string]interface{} {
|
||
|
"swap": map[string]interface{} {
|
||
|
"taker": this.ParseNumber("0.0002"),
|
||
|
"maker": this.ParseNumber("0.0002"),
|
||
|
},
|
||
|
"spot": map[string]interface{} {
|
||
|
"taker": this.ParseNumber("0.0002"),
|
||
|
"maker": this.ParseNumber("0.0002"),
|
||
|
},
|
||
|
},
|
||
|
"requiredCredentials": map[string]interface{} {
|
||
|
"apiKey": false,
|
||
|
"secret": false,
|
||
|
"walletAddress": true,
|
||
|
"privateKey": true,
|
||
|
},
|
||
|
"exceptions": map[string]interface{} {
|
||
|
"exact": map[string]interface{} {
|
||
|
"VALIDATION_ERROR": AuthenticationError,
|
||
|
"BINDING_ERROR": OperationRejected,
|
||
|
"INTERNAL_ERROR": ExchangeError,
|
||
|
"NOT_FOUND": BadRequest,
|
||
|
"SERVICE_UNAVAILABLE": ExchangeError,
|
||
|
"INVALID_REQUEST_PARAMETER": BadRequest,
|
||
|
"ORDER_ID_NOT_FOUND": InvalidOrder,
|
||
|
"ORDER_IS_CLOSED": InvalidOrder,
|
||
|
"ORDER_IS_NOT_OPEN_YET": InvalidOrder,
|
||
|
"CLIENT_ORDER_ID_NOT_FOUND": InvalidOrder,
|
||
|
"DUPLICATED_CLIENT_ID": InvalidOrder,
|
||
|
"INVALID_PRICE_PRECISION": OperationRejected,
|
||
|
"INVALID_SYMBOL": OperationRejected,
|
||
|
"INVALID_TOKEN": OperationRejected,
|
||
|
"INVALID_ETHEREUM_ADDRESS": OperationRejected,
|
||
|
"INVALID_ETHEREUM_SIGNATURE": OperationRejected,
|
||
|
"INVALID_STARKNET_ADDRESS": OperationRejected,
|
||
|
"INVALID_STARKNET_SIGNATURE": OperationRejected,
|
||
|
"STARKNET_SIGNATURE_VERIFICATION_FAILED": AuthenticationError,
|
||
|
"BAD_STARKNET_REQUEST": BadRequest,
|
||
|
"ETHEREUM_SIGNER_MISMATCH": BadRequest,
|
||
|
"ETHEREUM_HASH_MISMATCH": BadRequest,
|
||
|
"NOT_ONBOARDED": BadRequest,
|
||
|
"INVALID_TIMESTAMP": BadRequest,
|
||
|
"INVALID_SIGNATURE_EXPIRATION": AuthenticationError,
|
||
|
"ACCOUNT_NOT_FOUND": AuthenticationError,
|
||
|
"INVALID_ORDER_SIGNATURE": AuthenticationError,
|
||
|
"PUBLIC_KEY_INVALID": BadRequest,
|
||
|
"UNAUTHORIZED_ETHEREUM_ADDRESS": BadRequest,
|
||
|
"ETHEREUM_ADDRESS_ALREADY_ONBOARDED": BadRequest,
|
||
|
"MARKET_NOT_FOUND": BadRequest,
|
||
|
"ALLOWLIST_ENTRY_NOT_FOUND": BadRequest,
|
||
|
"USERNAME_IN_USE": AuthenticationError,
|
||
|
"GEO_IP_BLOCK": PermissionDenied,
|
||
|
"ETHEREUM_ADDRESS_BLOCKED": PermissionDenied,
|
||
|
"PROGRAM_NOT_FOUND": BadRequest,
|
||
|
"INVALID_DASHBOARD": OperationRejected,
|
||
|
"MARKET_NOT_OPEN": BadRequest,
|
||
|
"INVALID_REFERRAL_CODE": OperationRejected,
|
||
|
"PARENT_ADDRESS_ALREADY_ONBOARDED": BadRequest,
|
||
|
"INVALID_PARENT_ACCOUNT": OperationRejected,
|
||
|
"INVALID_VAULT_OPERATOR_CHAIN": OperationRejected,
|
||
|
"VAULT_OPERATOR_ALREADY_ONBOARDED": OperationRejected,
|
||
|
"VAULT_NAME_IN_USE": OperationRejected,
|
||
|
"BATCH_SIZE_OUT_OF_RANGE": OperationRejected,
|
||
|
"ISOLATED_MARKET_ACCOUNT_MISMATCH": OperationRejected,
|
||
|
"POINTS_SUMMARY_NOT_FOUND": OperationRejected,
|
||
|
"-32700": BadRequest,
|
||
|
"-32600": BadRequest,
|
||
|
"-32601": BadRequest,
|
||
|
"-32602": BadRequest,
|
||
|
"-32603": ExchangeError,
|
||
|
"100": BadRequest,
|
||
|
"40110": AuthenticationError,
|
||
|
"40111": AuthenticationError,
|
||
|
"40112": PermissionDenied,
|
||
|
},
|
||
|
"broad": map[string]interface{} {
|
||
|
"missing or malformed jwt": AuthenticationError,
|
||
|
},
|
||
|
},
|
||
|
"precisionMode": TICK_SIZE,
|
||
|
"commonCurrencies": map[string]interface{} {},
|
||
|
"options": map[string]interface{} {
|
||
|
"paradexAccount": nil,
|
||
|
"broker": "CCXT",
|
||
|
},
|
||
|
"features": map[string]interface{} {
|
||
|
"spot": nil,
|
||
|
"forSwap": map[string]interface{} {
|
||
|
"sandbox": true,
|
||
|
"createOrder": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"triggerPrice": true,
|
||
|
"triggerDirection": true,
|
||
|
"triggerPriceType": nil,
|
||
|
"stopLossPrice": false,
|
||
|
"takeProfitPrice": false,
|
||
|
"attachedStopLossTakeProfit": nil,
|
||
|
"timeInForce": map[string]interface{} {
|
||
|
"IOC": true,
|
||
|
"FOK": false,
|
||
|
"PO": true,
|
||
|
"GTD": false,
|
||
|
},
|
||
|
"hedged": false,
|
||
|
"trailing": false,
|
||
|
"leverage": false,
|
||
|
"marketBuyByCost": false,
|
||
|
"marketBuyRequiresPrice": false,
|
||
|
"selfTradePrevention": true,
|
||
|
"iceberg": false,
|
||
|
},
|
||
|
"createOrders": nil,
|
||
|
"fetchMyTrades": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"limit": 100,
|
||
|
"daysBack": 100000,
|
||
|
"untilDays": 100000,
|
||
|
"symbolRequired": false,
|
||
|
},
|
||
|
"fetchOrder": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"trigger": false,
|
||
|
"trailing": false,
|
||
|
"symbolRequired": false,
|
||
|
},
|
||
|
"fetchOpenOrders": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"limit": 100,
|
||
|
"trigger": false,
|
||
|
"trailing": false,
|
||
|
"symbolRequired": false,
|
||
|
},
|
||
|
"fetchOrders": map[string]interface{} {
|
||
|
"marginMode": false,
|
||
|
"limit": 100,
|
||
|
"daysBack": 100000,
|
||
|
"untilDays": 100000,
|
||
|
"trigger": false,
|
||
|
"trailing": false,
|
||
|
"symbolRequired": false,
|
||
|
},
|
||
|
"fetchClosedOrders": nil,
|
||
|
"fetchOHLCV": map[string]interface{} {
|
||
|
"limit": nil,
|
||
|
},
|
||
|
},
|
||
|
"swap": map[string]interface{} {
|
||
|
"linear": map[string]interface{} {
|
||
|
"extends": "forSwap",
|
||
|
},
|
||
|
"inverse": nil,
|
||
|
},
|
||
|
"future": map[string]interface{} {
|
||
|
"linear": nil,
|
||
|
"inverse": nil,
|
||
|
},
|
||
|
},
|
||
|
})
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchTime
|
||
|
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
||
|
* @see https://docs.api.testnet.paradex.trade/#get-system-time-unix-milliseconds
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
||
|
*/
|
||
|
func (this *paradex) FetchTime(optionalArgs ...interface{}) <- chan interface{} {
|
||
|
ch := make(chan interface{})
|
||
|
go func() interface{} {
|
||
|
defer close(ch)
|
||
|
defer ReturnPanicError(ch)
|
||
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
|
_ = params
|
||
|
|
||
|
response:= (<-this.PublicGetSystemTime(params))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// {
|
||
|
// "server_time": "1681493415023"
|
||
|
// }
|
||
|
//
|
||
|
ch <- this.SafeInteger(response, "server_time")
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchStatus
|
||
|
* @description the latest known information on the availability of the exchange API
|
||
|
* @see https://docs.api.testnet.paradex.trade/#get-system-state
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
|
||
|
*/
|
||
|
func (this *paradex) FetchStatus(optionalArgs ...interface{}) <- chan interface{} {
|
||
|
ch := make(chan interface{})
|
||
|
go func() interface{} {
|
||
|
defer close(ch)
|
||
|
defer ReturnPanicError(ch)
|
||
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
|
_ = params
|
||
|
|
||
|
response:= (<-this.PublicGetSystemState(params))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "status": "ok"
|
||
|
// }
|
||
|
//
|
||
|
var status interface{} = this.SafeString(response, "status")
|
||
|
|
||
|
ch <- map[string]interface{} {
|
||
|
"status": Ternary(IsTrue((IsEqual(status, "ok"))), "ok", "maintenance"),
|
||
|
"updated": nil,
|
||
|
"eta": nil,
|
||
|
"url": nil,
|
||
|
"info": response,
|
||
|
}
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchMarkets
|
||
|
* @description retrieves data on all markets for bitget
|
||
|
* @see https://docs.api.testnet.paradex.trade/#list-available-markets
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object[]} an array of objects representing market data
|
||
|
*/
|
||
|
func (this *paradex) FetchMarkets(optionalArgs ...interface{}) <- chan interface{} {
|
||
|
ch := make(chan interface{})
|
||
|
go func() interface{} {
|
||
|
defer close(ch)
|
||
|
defer ReturnPanicError(ch)
|
||
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
|
_ = params
|
||
|
|
||
|
response:= (<-this.PublicGetMarkets(params))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "symbol": "BODEN-USD-PERP",
|
||
|
// "base_currency": "BODEN",
|
||
|
// "quote_currency": "USD",
|
||
|
// "settlement_currency": "USDC",
|
||
|
// "order_size_increment": "1",
|
||
|
// "price_tick_size": "0.00001",
|
||
|
// "min_notional": "200",
|
||
|
// "open_at": 1717065600000,
|
||
|
// "expiry_at": 0,
|
||
|
// "asset_kind": "PERP",
|
||
|
// "position_limit": "2000000",
|
||
|
// "price_bands_width": "0.2",
|
||
|
// "max_open_orders": 50,
|
||
|
// "max_funding_rate": "0.05",
|
||
|
// "delta1_cross_margin_params": {
|
||
|
// "imf_base": "0.2",
|
||
|
// "imf_shift": "180000",
|
||
|
// "imf_factor": "0.00071",
|
||
|
// "mmf_factor": "0.5"
|
||
|
// },
|
||
|
// "price_feed_id": "9LScEHse1ioZt2rUuhwiN6bmYnqpMqvZkQJDNUpxVHN5",
|
||
|
// "oracle_ewma_factor": "0.14999987905913592",
|
||
|
// "max_order_size": "520000",
|
||
|
// "max_funding_rate_change": "0.0005",
|
||
|
// "max_tob_spread": "0.2"
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeList(response, "results")
|
||
|
|
||
|
ch <- this.ParseMarkets(data)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) ParseMarket(market interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "symbol": "BODEN-USD-PERP",
|
||
|
// "base_currency": "BODEN",
|
||
|
// "quote_currency": "USD",
|
||
|
// "settlement_currency": "USDC",
|
||
|
// "order_size_increment": "1",
|
||
|
// "price_tick_size": "0.00001",
|
||
|
// "min_notional": "200",
|
||
|
// "open_at": 1717065600000,
|
||
|
// "expiry_at": 0,
|
||
|
// "asset_kind": "PERP",
|
||
|
// "position_limit": "2000000",
|
||
|
// "price_bands_width": "0.2",
|
||
|
// "max_open_orders": 50,
|
||
|
// "max_funding_rate": "0.05",
|
||
|
// "delta1_cross_margin_params": {
|
||
|
// "imf_base": "0.2",
|
||
|
// "imf_shift": "180000",
|
||
|
// "imf_factor": "0.00071",
|
||
|
// "mmf_factor": "0.5"
|
||
|
// },
|
||
|
// "price_feed_id": "9LScEHse1ioZt2rUuhwiN6bmYnqpMqvZkQJDNUpxVHN5",
|
||
|
// "oracle_ewma_factor": "0.14999987905913592",
|
||
|
// "max_order_size": "520000",
|
||
|
// "max_funding_rate_change": "0.0005",
|
||
|
// "max_tob_spread": "0.2"
|
||
|
// }
|
||
|
//
|
||
|
var marketId interface{} = this.SafeString(market, "symbol")
|
||
|
var quoteId interface{} = this.SafeString(market, "quote_currency")
|
||
|
var baseId interface{} = this.SafeString(market, "base_currency")
|
||
|
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
||
|
var base interface{} = this.SafeCurrencyCode(baseId)
|
||
|
var settleId interface{} = this.SafeString(market, "settlement_currency")
|
||
|
var settle interface{} = this.SafeCurrencyCode(settleId)
|
||
|
var symbol interface{} = Add(Add(Add(Add(base, "/"), quote), ":"), settle)
|
||
|
var expiry interface{} = this.SafeInteger(market, "expiry_at")
|
||
|
var takerFee interface{} = this.ParseNumber("0.0003")
|
||
|
var makerFee interface{} = this.ParseNumber("-0.00005")
|
||
|
return this.SafeMarketStructure(map[string]interface{} {
|
||
|
"id": marketId,
|
||
|
"symbol": symbol,
|
||
|
"base": base,
|
||
|
"quote": quote,
|
||
|
"settle": settle,
|
||
|
"baseId": baseId,
|
||
|
"quoteId": quoteId,
|
||
|
"settleId": settleId,
|
||
|
"type": "swap",
|
||
|
"spot": false,
|
||
|
"margin": nil,
|
||
|
"swap": true,
|
||
|
"future": false,
|
||
|
"option": false,
|
||
|
"active": this.SafeBool(market, "enableTrading"),
|
||
|
"contract": true,
|
||
|
"linear": true,
|
||
|
"inverse": nil,
|
||
|
"taker": takerFee,
|
||
|
"maker": makerFee,
|
||
|
"contractSize": this.ParseNumber("1"),
|
||
|
"expiry": Ternary(IsTrue((IsEqual(expiry, 0))), nil, expiry),
|
||
|
"expiryDatetime": Ternary(IsTrue((IsEqual(expiry, 0))), nil, this.Iso8601(expiry)),
|
||
|
"strike": nil,
|
||
|
"optionType": nil,
|
||
|
"precision": map[string]interface{} {
|
||
|
"amount": this.SafeNumber(market, "order_size_increment"),
|
||
|
"price": this.SafeNumber(market, "price_tick_size"),
|
||
|
},
|
||
|
"limits": map[string]interface{} {
|
||
|
"leverage": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": nil,
|
||
|
},
|
||
|
"amount": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": this.SafeNumber(market, "max_order_size"),
|
||
|
},
|
||
|
"price": map[string]interface{} {
|
||
|
"min": nil,
|
||
|
"max": nil,
|
||
|
},
|
||
|
"cost": map[string]interface{} {
|
||
|
"min": this.SafeNumber(market, "min_notional"),
|
||
|
"max": nil,
|
||
|
},
|
||
|
},
|
||
|
"created": nil,
|
||
|
"info": market,
|
||
|
})
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchOHLCV
|
||
|
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
||
|
* @see https://docs.api.testnet.paradex.trade/#ohlcv-for-a-symbol
|
||
|
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
||
|
* @param {string} timeframe the length of time each candle represents
|
||
|
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
||
|
* @param {int} [limit] the maximum amount of candles to fetch
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @param {int} [params.until] timestamp in ms of the latest candle to fetch
|
||
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
||
|
*/
|
||
|
func (this *paradex) 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
|
||
|
|
||
|
retRes5538 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes5538)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"resolution": this.SafeString(this.Timeframes, timeframe, timeframe),
|
||
|
"symbol": GetValue(market, "id"),
|
||
|
}
|
||
|
var now interface{} = this.Milliseconds()
|
||
|
var duration interface{} = this.ParseTimeframe(timeframe)
|
||
|
var until interface{} = this.SafeInteger2(params, "until", "till", now)
|
||
|
params = this.Omit(params, []interface{}{"until", "till"})
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "start_at", since)
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "end_at", Subtract(this.Sum(since, Multiply(Multiply(duration, (Add(limit, 1))), 1000)), 1))
|
||
|
} else {
|
||
|
AddElementToObject(request, "end_at", until)
|
||
|
}
|
||
|
} else {
|
||
|
AddElementToObject(request, "end_at", until)
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "start_at", Add(Subtract(until, Multiply(Multiply(duration, (Add(limit, 1))), 1000)), 1))
|
||
|
} else {
|
||
|
AddElementToObject(request, "start_at", Add(Subtract(until, Multiply(Multiply(duration, 101), 1000)), 1))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetMarketsKlines(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "results": [
|
||
|
// [
|
||
|
// 1720071900000,
|
||
|
// 58961.3,
|
||
|
// 58961.3,
|
||
|
// 58961.3,
|
||
|
// 58961.3,
|
||
|
// 1591
|
||
|
// ]
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
|
||
|
ch <- this.ParseOHLCVs(data, market, timeframe, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// [
|
||
|
// 1720071900000,
|
||
|
// 58961.3,
|
||
|
// 58961.3,
|
||
|
// 58961.3,
|
||
|
// 58961.3,
|
||
|
// 1591
|
||
|
// ]
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
return []interface{}{this.SafeInteger(ohlcv, 0), this.SafeNumber(ohlcv, 1), this.SafeNumber(ohlcv, 2), this.SafeNumber(ohlcv, 3), this.SafeNumber(ohlcv, 4), this.SafeNumber(ohlcv, 5)}
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchTickers
|
||
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
||
|
* @see https://docs.api.testnet.paradex.trade/#list-available-markets-summary
|
||
|
* @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 *paradex) 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
|
||
|
|
||
|
retRes6288 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes6288)
|
||
|
symbols = this.MarketSymbols(symbols)
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
if IsTrue(!IsEqual(symbols, nil)) {
|
||
|
if IsTrue(IsArray(symbols)) {
|
||
|
AddElementToObject(request, "market", this.MarketId(GetValue(symbols, 0)))
|
||
|
} else {
|
||
|
AddElementToObject(request, "market", this.MarketId(symbols))
|
||
|
}
|
||
|
} else {
|
||
|
AddElementToObject(request, "market", "ALL")
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetMarketsSummary(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "symbol": "BTC-USD-PERP",
|
||
|
// "oracle_price": "68465.17449906",
|
||
|
// "mark_price": "68465.17449906",
|
||
|
// "last_traded_price": "68495.1",
|
||
|
// "bid": "68477.6",
|
||
|
// "ask": "69578.2",
|
||
|
// "volume_24h": "5815541.397939004",
|
||
|
// "total_volume": "584031465.525259686",
|
||
|
// "created_at": 1718170156580,
|
||
|
// "underlying_price": "67367.37268422",
|
||
|
// "open_interest": "162.272",
|
||
|
// "funding_rate": "0.01629574927887",
|
||
|
// "price_change_rate_24h": "0.009032"
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
|
||
|
ch <- this.ParseTickers(data, symbols)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchTicker
|
||
|
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
||
|
* @see https://docs.api.testnet.paradex.trade/#list-available-markets-summary
|
||
|
* @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 *paradex) 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
|
||
|
|
||
|
retRes6768 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes6768)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"market": GetValue(market, "id"),
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetMarketsSummary(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "symbol": "BTC-USD-PERP",
|
||
|
// "oracle_price": "68465.17449906",
|
||
|
// "mark_price": "68465.17449906",
|
||
|
// "last_traded_price": "68495.1",
|
||
|
// "bid": "68477.6",
|
||
|
// "ask": "69578.2",
|
||
|
// "volume_24h": "5815541.397939004",
|
||
|
// "total_volume": "584031465.525259686",
|
||
|
// "created_at": 1718170156580,
|
||
|
// "underlying_price": "67367.37268422",
|
||
|
// "open_interest": "162.272",
|
||
|
// "funding_rate": "0.01629574927887",
|
||
|
// "price_change_rate_24h": "0.009032"
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
var ticker interface{} = this.SafeDict(data, 0, map[string]interface{} {})
|
||
|
|
||
|
ch <- this.ParseTicker(ticker, market)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "symbol": "BTC-USD-PERP",
|
||
|
// "oracle_price": "68465.17449906",
|
||
|
// "mark_price": "68465.17449906",
|
||
|
// "last_traded_price": "68495.1",
|
||
|
// "bid": "68477.6",
|
||
|
// "ask": "69578.2",
|
||
|
// "volume_24h": "5815541.397939004",
|
||
|
// "total_volume": "584031465.525259686",
|
||
|
// "created_at": 1718170156580,
|
||
|
// "underlying_price": "67367.37268422",
|
||
|
// "open_interest": "162.272",
|
||
|
// "funding_rate": "0.01629574927887",
|
||
|
// "price_change_rate_24h": "0.009032"
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var percentage interface{} = this.SafeString(ticker, "price_change_rate_24h")
|
||
|
if IsTrue(!IsEqual(percentage, nil)) {
|
||
|
percentage = Precise.StringMul(percentage, "100")
|
||
|
}
|
||
|
var last interface{} = this.SafeString(ticker, "last_traded_price")
|
||
|
var marketId interface{} = this.SafeString(ticker, "symbol")
|
||
|
market = this.SafeMarket(marketId, market)
|
||
|
var symbol interface{} = GetValue(market, "symbol")
|
||
|
var timestamp interface{} = this.SafeInteger(ticker, "created_at")
|
||
|
return this.SafeTicker(map[string]interface{} {
|
||
|
"symbol": symbol,
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"high": nil,
|
||
|
"low": nil,
|
||
|
"bid": this.SafeString(ticker, "bid"),
|
||
|
"bidVolume": nil,
|
||
|
"ask": this.SafeString(ticker, "ask"),
|
||
|
"askVolume": nil,
|
||
|
"vwap": nil,
|
||
|
"open": nil,
|
||
|
"close": last,
|
||
|
"last": last,
|
||
|
"previousClose": nil,
|
||
|
"change": nil,
|
||
|
"percentage": percentage,
|
||
|
"average": nil,
|
||
|
"baseVolume": nil,
|
||
|
"quoteVolume": this.SafeString(ticker, "volume_24h"),
|
||
|
"markPrice": this.SafeString(ticker, "mark_price"),
|
||
|
"info": ticker,
|
||
|
}, market)
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchOrderBook
|
||
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
||
|
* @see https://docs.api.testnet.paradex.trade/#get-market-orderbook
|
||
|
* @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 *paradex) 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
|
||
|
|
||
|
retRes7718 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes7718)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"market": GetValue(market, "id"),
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetOrderbookMarket(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "seq_no": 14115975,
|
||
|
// "last_updated_at": 1718172538340,
|
||
|
// "asks": [
|
||
|
// [
|
||
|
// "69578.2",
|
||
|
// "3.019"
|
||
|
// ]
|
||
|
// ],
|
||
|
// "bids": [
|
||
|
// [
|
||
|
// "68477.6",
|
||
|
// "0.1"
|
||
|
// ]
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "depth", limit)
|
||
|
}
|
||
|
var timestamp interface{} = this.SafeInteger(response, "last_updated_at")
|
||
|
var orderbook interface{} = this.ParseOrderBook(response, GetValue(market, "symbol"), timestamp)
|
||
|
AddElementToObject(orderbook, "nonce", this.SafeInteger(response, "seq_no"))
|
||
|
|
||
|
ch <- orderbook
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchTrades
|
||
|
* @description get the list of most recent trades for a particular symbol
|
||
|
* @see https://docs.api.testnet.paradex.trade/#trade-tape
|
||
|
* @param {string} symbol unified symbol of the market to fetch trades for
|
||
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
||
|
* @param {int} [limit] the maximum amount of trades to fetch
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @param {int} [params.until] the latest time in ms to fetch trades for
|
||
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times
|
||
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
||
|
*/
|
||
|
func (this *paradex) 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
|
||
|
|
||
|
retRes8178 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes8178)
|
||
|
var paginate interface{} = false
|
||
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "paginate");
|
||
|
paginate = GetValue(paginateparamsVariable,0);
|
||
|
params = GetValue(paginateparamsVariable,1)
|
||
|
if IsTrue(paginate) {
|
||
|
|
||
|
retRes82119 := (<-this.FetchPaginatedCallCursor("fetchTrades", symbol, since, limit, params, "next", "cursor", nil, 100))
|
||
|
PanicOnError(retRes82119)
|
||
|
ch <- retRes82119
|
||
|
return nil
|
||
|
}
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"market": GetValue(market, "id"),
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "page_size", limit)
|
||
|
}
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "start_at", since)
|
||
|
}
|
||
|
requestparamsVariable := this.HandleUntilOption("end_at", request, params);
|
||
|
request = GetValue(requestparamsVariable,0);
|
||
|
params = GetValue(requestparamsVariable,1)
|
||
|
|
||
|
response:= (<-this.PublicGetTrades(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "next": "...",
|
||
|
// "prev": "...",
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "id": "1718154353750201703989430001",
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "side": "BUY",
|
||
|
// "size": "0.026",
|
||
|
// "price": "69578.2",
|
||
|
// "created_at": 1718154353750,
|
||
|
// "trade_type": "FILL"
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var trades interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(trades)); i++ {
|
||
|
AddElementToObject(GetValue(trades, i), "next", this.SafeString(response, "next"))
|
||
|
}
|
||
|
|
||
|
ch <- this.ParseTrades(trades, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// fetchTrades (public)
|
||
|
//
|
||
|
// {
|
||
|
// "id": "1718154353750201703989430001",
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "side": "BUY",
|
||
|
// "size": "0.026",
|
||
|
// "price": "69578.2",
|
||
|
// "created_at": 1718154353750,
|
||
|
// "trade_type": "FILL"
|
||
|
// }
|
||
|
//
|
||
|
// fetchMyTrades (private)
|
||
|
//
|
||
|
// {
|
||
|
// "id": "1718947571560201703986670001",
|
||
|
// "side": "BUY",
|
||
|
// "liquidity": "TAKER",
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "order_id": "1718947571540201703992340000",
|
||
|
// "price": "64852.9",
|
||
|
// "size": "0.01",
|
||
|
// "fee": "0.1945587",
|
||
|
// "fee_currency": "USDC",
|
||
|
// "created_at": 1718947571569,
|
||
|
// "remaining_size": "0",
|
||
|
// "client_id": "",
|
||
|
// "fill_type": "FILL"
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var marketId interface{} = this.SafeString(trade, "market")
|
||
|
market = this.SafeMarket(marketId, market)
|
||
|
var id interface{} = this.SafeString(trade, "id")
|
||
|
var timestamp interface{} = this.SafeInteger(trade, "created_at")
|
||
|
var priceString interface{} = this.SafeString(trade, "price")
|
||
|
var amountString interface{} = this.SafeString(trade, "size")
|
||
|
var side interface{} = this.SafeStringLower(trade, "side")
|
||
|
var liability interface{} = this.SafeStringLower(trade, "liquidity", "taker")
|
||
|
var isTaker interface{} = IsEqual(liability, "taker")
|
||
|
var takerOrMaker interface{} = Ternary(IsTrue((isTaker)), "taker", "maker")
|
||
|
var currencyId interface{} = this.SafeString(trade, "fee_currency")
|
||
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
||
|
return this.SafeTrade(map[string]interface{} {
|
||
|
"info": trade,
|
||
|
"id": id,
|
||
|
"order": this.SafeString(trade, "order_id"),
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"symbol": GetValue(market, "symbol"),
|
||
|
"type": nil,
|
||
|
"takerOrMaker": takerOrMaker,
|
||
|
"side": side,
|
||
|
"price": priceString,
|
||
|
"amount": amountString,
|
||
|
"cost": nil,
|
||
|
"fee": map[string]interface{} {
|
||
|
"cost": this.SafeString(trade, "fee"),
|
||
|
"currency": code,
|
||
|
"rate": nil,
|
||
|
},
|
||
|
}, market)
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchOpenInterest
|
||
|
* @description retrieves the open interest of a contract trading pair
|
||
|
* @see https://docs.api.testnet.paradex.trade/#list-available-markets-summary
|
||
|
* @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 *paradex) 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
|
||
|
|
||
|
retRes9348 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes9348)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
if !IsTrue(GetValue(market, "contract")) {
|
||
|
panic(BadRequest(Add(this.Id, " fetchOpenInterest() supports contract markets only")))
|
||
|
}
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"market": GetValue(market, "id"),
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetMarketsSummary(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "symbol": "BTC-USD-PERP",
|
||
|
// "oracle_price": "68465.17449906",
|
||
|
// "mark_price": "68465.17449906",
|
||
|
// "last_traded_price": "68495.1",
|
||
|
// "bid": "68477.6",
|
||
|
// "ask": "69578.2",
|
||
|
// "volume_24h": "5815541.397939004",
|
||
|
// "total_volume": "584031465.525259686",
|
||
|
// "created_at": 1718170156580,
|
||
|
// "underlying_price": "67367.37268422",
|
||
|
// "open_interest": "162.272",
|
||
|
// "funding_rate": "0.01629574927887",
|
||
|
// "price_change_rate_24h": "0.009032"
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
var interest interface{} = this.SafeDict(data, 0, map[string]interface{} {})
|
||
|
|
||
|
ch <- this.ParseOpenInterest(interest, market)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) ParseOpenInterest(interest interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "symbol": "BTC-USD-PERP",
|
||
|
// "oracle_price": "68465.17449904",
|
||
|
// "mark_price": "68465.17449906",
|
||
|
// "last_traded_price": "68495.1",
|
||
|
// "bid": "68477.6",
|
||
|
// "ask": "69578.2",
|
||
|
// "volume_24h": "5815541.397939004",
|
||
|
// "total_volume": "584031465.525259686",
|
||
|
// "created_at": 1718170156580,
|
||
|
// "underlying_price": "67367.37268422",
|
||
|
// "open_interest": "162.272",
|
||
|
// "funding_rate": "0.01629574927887",
|
||
|
// "price_change_rate_24h": "0.009032"
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var timestamp interface{} = this.SafeInteger(interest, "created_at")
|
||
|
var marketId interface{} = this.SafeString(interest, "symbol")
|
||
|
market = this.SafeMarket(marketId, market)
|
||
|
var symbol interface{} = GetValue(market, "symbol")
|
||
|
return this.SafeOpenInterest(map[string]interface{} {
|
||
|
"symbol": symbol,
|
||
|
"openInterestAmount": this.SafeString(interest, "open_interest"),
|
||
|
"openInterestValue": nil,
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"info": interest,
|
||
|
}, market)
|
||
|
}
|
||
|
func (this *paradex) HashMessage(message interface{}) interface{} {
|
||
|
return Add("0x", this.Hash(message, keccak, "hex"))
|
||
|
}
|
||
|
func (this *paradex) SignHash(hash interface{}, privateKey interface{}) interface{} {
|
||
|
var signature interface{} = Ecdsa(Slice(hash, OpNeg(64), nil), Slice(privateKey, OpNeg(64), nil), secp256k1, nil)
|
||
|
var r interface{} = GetValue(signature, "r")
|
||
|
var s interface{} = GetValue(signature, "s")
|
||
|
var v interface{} = this.IntToBase16(this.Sum(27, GetValue(signature, "v")))
|
||
|
return Add(Add(Add("0x", PadStart(r, 64, "0")), PadStart(s, 64, "0")), v)
|
||
|
}
|
||
|
func (this *paradex) SignMessage(message interface{}, privateKey interface{}) interface{} {
|
||
|
return this.SignHash(this.HashMessage(message), Slice(privateKey, OpNeg(64), nil))
|
||
|
}
|
||
|
func (this *paradex) GetSystemConfig() <- chan interface{} {
|
||
|
ch := make(chan interface{})
|
||
|
go func() interface{} {
|
||
|
defer close(ch)
|
||
|
defer ReturnPanicError(ch)
|
||
|
var cachedConfig interface{} = this.SafeDict(this.Options, "systemConfig")
|
||
|
if IsTrue(!IsEqual(cachedConfig, nil)) {
|
||
|
|
||
|
ch <- cachedConfig
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PublicGetSystemConfig())
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "starknet_gateway_url": "https://potc-testnet-sepolia.starknet.io",
|
||
|
// "starknet_fullnode_rpc_url": "https://pathfinder.api.testnet.paradex.trade/rpc/v0_7",
|
||
|
// "starknet_chain_id": "PRIVATE_SN_POTC_SEPOLIA",
|
||
|
// "block_explorer_url": "https://voyager.testnet.paradex.trade/",
|
||
|
// "paraclear_address": "0x286003f7c7bfc3f94e8f0af48b48302e7aee2fb13c23b141479ba00832ef2c6",
|
||
|
// "paraclear_decimals": 8,
|
||
|
// "paraclear_account_proxy_hash": "0x3530cc4759d78042f1b543bf797f5f3d647cde0388c33734cf91b7f7b9314a9",
|
||
|
// "paraclear_account_hash": "0x41cb0280ebadaa75f996d8d92c6f265f6d040bb3ba442e5f86a554f1765244e",
|
||
|
// "oracle_address": "0x2c6a867917ef858d6b193a0ff9e62b46d0dc760366920d631715d58baeaca1f",
|
||
|
// "bridged_tokens": [
|
||
|
// {
|
||
|
// "name": "TEST USDC",
|
||
|
// "symbol": "USDC",
|
||
|
// "decimals": 6,
|
||
|
// "l1_token_address": "0x29A873159D5e14AcBd63913D4A7E2df04570c666",
|
||
|
// "l1_bridge_address": "0x8586e05adc0C35aa11609023d4Ae6075Cb813b4C",
|
||
|
// "l2_token_address": "0x6f373b346561036d98ea10fb3e60d2f459c872b1933b50b21fe6ef4fda3b75e",
|
||
|
// "l2_bridge_address": "0x46e9237f5408b5f899e72125dd69bd55485a287aaf24663d3ebe00d237fc7ef"
|
||
|
// }
|
||
|
// ],
|
||
|
// "l1_core_contract_address": "0x582CC5d9b509391232cd544cDF9da036e55833Af",
|
||
|
// "l1_operator_address": "0x11bACdFbBcd3Febe5e8CEAa75E0Ef6444d9B45FB",
|
||
|
// "l1_chain_id": "11155111",
|
||
|
// "liquidation_fee": "0.2"
|
||
|
// }
|
||
|
//
|
||
|
AddElementToObject(this.Options, "systemConfig", response)
|
||
|
|
||
|
ch <- response
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) PrepareParadexDomain(optionalArgs ...interface{}) <- chan interface{} {
|
||
|
ch := make(chan interface{})
|
||
|
go func() interface{} {
|
||
|
defer close(ch)
|
||
|
defer ReturnPanicError(ch)
|
||
|
l1 := GetArg(optionalArgs, 0, false)
|
||
|
_ = l1
|
||
|
|
||
|
systemConfig:= (<-this.GetSystemConfig())
|
||
|
PanicOnError(systemConfig)
|
||
|
if IsTrue(IsEqual(l1, true)) {
|
||
|
var l1D interface{} = map[string]interface{} {
|
||
|
"name": "Paradex",
|
||
|
"chainId": GetValue(systemConfig, "l1_chain_id"),
|
||
|
"version": "1",
|
||
|
}
|
||
|
|
||
|
ch <- l1D
|
||
|
return nil
|
||
|
}
|
||
|
var domain interface{} = map[string]interface{} {
|
||
|
"name": "Paradex",
|
||
|
"chainId": GetValue(systemConfig, "starknet_chain_id"),
|
||
|
"version": 1,
|
||
|
}
|
||
|
|
||
|
ch <- domain
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) RetrieveAccount() <- chan interface{} {
|
||
|
ch := make(chan interface{})
|
||
|
go func() interface{} {
|
||
|
defer close(ch)
|
||
|
defer ReturnPanicError(ch)
|
||
|
var cachedAccount interface{} = this.SafeDict(this.Options, "paradexAccount")
|
||
|
if IsTrue(!IsEqual(cachedAccount, nil)) {
|
||
|
|
||
|
ch <- cachedAccount
|
||
|
return nil
|
||
|
}
|
||
|
this.CheckRequiredCredentials()
|
||
|
|
||
|
systemConfig:= (<-this.GetSystemConfig())
|
||
|
PanicOnError(systemConfig)
|
||
|
|
||
|
domain:= (<-this.PrepareParadexDomain(true))
|
||
|
PanicOnError(domain)
|
||
|
var messageTypes interface{} = map[string]interface{} {
|
||
|
"Constant": []interface{}{map[string]interface{} {
|
||
|
"name": "action",
|
||
|
"type": "string",
|
||
|
}},
|
||
|
}
|
||
|
var message interface{} = map[string]interface{} {
|
||
|
"action": "STARK Key",
|
||
|
}
|
||
|
var msg interface{} = this.EthEncodeStructuredData(domain, messageTypes, message)
|
||
|
var signature interface{} = this.SignMessage(msg, this.PrivateKey)
|
||
|
var account interface{} = this.RetrieveStarkAccount(signature, GetValue(systemConfig, "paraclear_account_hash"), GetValue(systemConfig, "paraclear_account_proxy_hash"))
|
||
|
AddElementToObject(this.Options, "paradexAccount", account)
|
||
|
|
||
|
ch <- account
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) Onboarding(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
|
||
|
|
||
|
account:= (<-this.RetrieveAccount())
|
||
|
PanicOnError(account)
|
||
|
var req interface{} = map[string]interface{} {
|
||
|
"action": "Onboarding",
|
||
|
}
|
||
|
|
||
|
domain:= (<-this.PrepareParadexDomain())
|
||
|
PanicOnError(domain)
|
||
|
var messageTypes interface{} = map[string]interface{} {
|
||
|
"Constant": []interface{}{map[string]interface{} {
|
||
|
"name": "action",
|
||
|
"type": "felt",
|
||
|
}},
|
||
|
}
|
||
|
var msg interface{} = this.StarknetEncodeStructuredData(domain, messageTypes, req, GetValue(account, "address"))
|
||
|
var signature interface{} = this.StarknetSign(msg, GetValue(account, "privateKey"))
|
||
|
AddElementToObject(params, "signature", signature)
|
||
|
AddElementToObject(params, "account", GetValue(account, "address"))
|
||
|
AddElementToObject(params, "public_key", GetValue(account, "publicKey"))
|
||
|
|
||
|
response:= (<-this.PrivatePostOnboarding(params))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
ch <- response
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) AuthenticateRest(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 cachedToken interface{} = this.SafeString(this.Options, "authToken")
|
||
|
var now interface{} = this.Nonce()
|
||
|
if IsTrue(!IsEqual(cachedToken, nil)) {
|
||
|
var cachedExpires interface{} = this.SafeInteger(this.Options, "expires")
|
||
|
if IsTrue(IsLessThan(now, cachedExpires)) {
|
||
|
|
||
|
ch <- cachedToken
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
account:= (<-this.RetrieveAccount())
|
||
|
PanicOnError(account)
|
||
|
// https://docs.paradex.trade/api-reference/general-information/authentication
|
||
|
var expires interface{} = Add(now, 180)
|
||
|
var req interface{} = map[string]interface{} {
|
||
|
"method": "POST",
|
||
|
"path": "/v1/auth",
|
||
|
"body": "",
|
||
|
"timestamp": now,
|
||
|
"expiration": expires,
|
||
|
}
|
||
|
|
||
|
domain:= (<-this.PrepareParadexDomain())
|
||
|
PanicOnError(domain)
|
||
|
var messageTypes interface{} = map[string]interface{} {
|
||
|
"Request": []interface{}{map[string]interface{} {
|
||
|
"name": "method",
|
||
|
"type": "felt",
|
||
|
}, map[string]interface{} {
|
||
|
"name": "path",
|
||
|
"type": "felt",
|
||
|
}, map[string]interface{} {
|
||
|
"name": "body",
|
||
|
"type": "felt",
|
||
|
}, map[string]interface{} {
|
||
|
"name": "timestamp",
|
||
|
"type": "felt",
|
||
|
}, map[string]interface{} {
|
||
|
"name": "expiration",
|
||
|
"type": "felt",
|
||
|
}},
|
||
|
}
|
||
|
var msg interface{} = this.StarknetEncodeStructuredData(domain, messageTypes, req, GetValue(account, "address"))
|
||
|
var signature interface{} = this.StarknetSign(msg, GetValue(account, "privateKey"))
|
||
|
AddElementToObject(params, "signature", signature)
|
||
|
AddElementToObject(params, "account", GetValue(account, "address"))
|
||
|
AddElementToObject(params, "timestamp", GetValue(req, "timestamp"))
|
||
|
AddElementToObject(params, "expiration", GetValue(req, "expiration"))
|
||
|
|
||
|
response:= (<-this.PrivatePostAuth(params))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// jwt_token: "ooooccxtooootoooootheoooomoonooooo"
|
||
|
// }
|
||
|
//
|
||
|
var token interface{} = this.SafeString(response, "jwt_token")
|
||
|
AddElementToObject(this.Options, "authToken", token)
|
||
|
AddElementToObject(this.Options, "expires", expires)
|
||
|
|
||
|
ch <- token
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "account": "0x4638e3041366aa71720be63e32e53e1223316c7f0d56f7aa617542ed1e7512x",
|
||
|
// "avg_fill_price": "26000",
|
||
|
// "client_id": "x1234",
|
||
|
// "cancel_reason": "NOT_ENOUGH_MARGIN",
|
||
|
// "created_at": 1681493746016,
|
||
|
// "flags": [
|
||
|
// "REDUCE_ONLY"
|
||
|
// ],
|
||
|
// "id": "123456",
|
||
|
// "instruction": "GTC",
|
||
|
// "last_updated_at": 1681493746016,
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "price": "26000",
|
||
|
// "published_at": 1681493746016,
|
||
|
// "received_at": 1681493746016,
|
||
|
// "remaining_size": "0",
|
||
|
// "seq_no": 1681471234972000000,
|
||
|
// "side": "BUY",
|
||
|
// "size": "0.05",
|
||
|
// "status": "NEW",
|
||
|
// "stp": "EXPIRE_MAKER",
|
||
|
// "timestamp": 1681493746016,
|
||
|
// "trigger_price": "26000",
|
||
|
// "type": "MARKET"
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var timestamp interface{} = this.SafeInteger(order, "created_at")
|
||
|
var orderId interface{} = this.SafeString(order, "id")
|
||
|
var clientOrderId interface{} = this.OmitZero(this.SafeString(order, "client_id"))
|
||
|
var marketId interface{} = this.SafeString(order, "market")
|
||
|
market = this.SafeMarket(marketId, market)
|
||
|
var symbol interface{} = GetValue(market, "symbol")
|
||
|
var price interface{} = this.SafeString(order, "price")
|
||
|
var amount interface{} = this.SafeString(order, "size")
|
||
|
var orderType interface{} = this.SafeString(order, "type")
|
||
|
var status interface{} = this.SafeString(order, "status")
|
||
|
var side interface{} = this.SafeStringLower(order, "side")
|
||
|
var average interface{} = this.OmitZero(this.SafeString(order, "avg_fill_price"))
|
||
|
var remaining interface{} = this.OmitZero(this.SafeString(order, "remaining_size"))
|
||
|
var lastUpdateTimestamp interface{} = this.SafeInteger(order, "last_updated_at")
|
||
|
return this.SafeOrder(map[string]interface{} {
|
||
|
"id": orderId,
|
||
|
"clientOrderId": clientOrderId,
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"lastTradeTimestamp": nil,
|
||
|
"lastUpdateTimestamp": lastUpdateTimestamp,
|
||
|
"status": this.ParseOrderStatus(status),
|
||
|
"symbol": symbol,
|
||
|
"type": this.ParseOrderType(orderType),
|
||
|
"timeInForce": this.ParseTimeInForce(this.SafeString(order, "instrunction")),
|
||
|
"postOnly": nil,
|
||
|
"reduceOnly": nil,
|
||
|
"side": side,
|
||
|
"price": price,
|
||
|
"triggerPrice": this.SafeString(order, "trigger_price"),
|
||
|
"takeProfitPrice": nil,
|
||
|
"stopLossPrice": nil,
|
||
|
"average": average,
|
||
|
"amount": amount,
|
||
|
"filled": nil,
|
||
|
"remaining": remaining,
|
||
|
"cost": nil,
|
||
|
"trades": nil,
|
||
|
"fee": map[string]interface{} {
|
||
|
"cost": nil,
|
||
|
"currency": nil,
|
||
|
},
|
||
|
"info": order,
|
||
|
}, market)
|
||
|
}
|
||
|
func (this *paradex) ParseTimeInForce(timeInForce interface{}) interface{} {
|
||
|
var timeInForces interface{} = map[string]interface{} {
|
||
|
"IOC": "IOC",
|
||
|
"GTC": "GTC",
|
||
|
"POST_ONLY": "PO",
|
||
|
}
|
||
|
return this.SafeString(timeInForces, timeInForce, nil)
|
||
|
}
|
||
|
func (this *paradex) ParseOrderStatus(status interface{}) interface{} {
|
||
|
if IsTrue(!IsEqual(status, nil)) {
|
||
|
var statuses interface{} = map[string]interface{} {
|
||
|
"NEW": "open",
|
||
|
"UNTRIGGERED": "open",
|
||
|
"OPEN": "open",
|
||
|
"CLOSED": "closed",
|
||
|
}
|
||
|
return this.SafeString(statuses, status, status)
|
||
|
}
|
||
|
return status
|
||
|
}
|
||
|
func (this *paradex) ParseOrderType(typeVar interface{}) interface{} {
|
||
|
var types interface{} = map[string]interface{} {
|
||
|
"LIMIT": "limit",
|
||
|
"MARKET": "market",
|
||
|
"STOP_LIMIT": "limit",
|
||
|
"STOP_MARKET": "market",
|
||
|
}
|
||
|
return this.SafeStringLower(types, typeVar, typeVar)
|
||
|
}
|
||
|
func (this *paradex) ConvertShortString(str interface{}) interface{} {
|
||
|
// TODO: add stringToBase16 in exchange
|
||
|
return Add("0x", this.BinaryToBase16(this.Base64ToBinary(this.StringToBase64(str))))
|
||
|
}
|
||
|
func (this *paradex) ScaleNumber(num interface{}) interface{} {
|
||
|
return Precise.StringMul(num, "100000000")
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#createOrder
|
||
|
* @description create a trade order
|
||
|
* @see https://docs.api.prod.paradex.trade/#create-order
|
||
|
* @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 fullfilled, in units of the quote currency, ignored in market orders
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @param {float} [params.stopPrice] alias for triggerPrice
|
||
|
* @param {float} [params.triggerPrice] The price a trigger order is triggered at
|
||
|
* @param {string} [params.timeInForce] "GTC", "IOC", or "POST_ONLY"
|
||
|
* @param {bool} [params.postOnly] true or false
|
||
|
* @param {bool} [params.reduceOnly] Ensures that the executed order does not flip the opened position.
|
||
|
* @param {string} [params.clientOrderId] a unique id for the order
|
||
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
|
*/
|
||
|
func (this *paradex) 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
|
||
|
|
||
|
retRes13038 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes13038)
|
||
|
|
||
|
retRes13048 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes13048)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var reduceOnly interface{} = this.SafeBool2(params, "reduceOnly", "reduce_only")
|
||
|
var orderType interface{} = ToUpper(typeVar)
|
||
|
var orderSide interface{} = ToUpper(side)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"market": GetValue(market, "id"),
|
||
|
"side": orderSide,
|
||
|
"type": orderType,
|
||
|
"size": this.AmountToPrecision(symbol, amount),
|
||
|
}
|
||
|
var triggerPrice interface{} = this.SafeString2(params, "triggerPrice", "stopPrice")
|
||
|
var isMarket interface{} = IsEqual(orderType, "MARKET")
|
||
|
var timeInForce interface{} = this.SafeStringUpper(params, "timeInForce")
|
||
|
var postOnly interface{} = this.IsPostOnly(isMarket, nil, params)
|
||
|
if !IsTrue(isMarket) {
|
||
|
if IsTrue(postOnly) {
|
||
|
AddElementToObject(request, "instruction", "POST_ONLY")
|
||
|
} else if IsTrue(IsEqual(timeInForce, "ioc")) {
|
||
|
AddElementToObject(request, "instruction", "IOC")
|
||
|
}
|
||
|
}
|
||
|
if IsTrue(reduceOnly) {
|
||
|
AddElementToObject(request, "flags", []interface{}{"REDUCE_ONLY"})
|
||
|
}
|
||
|
if IsTrue(!IsEqual(price, nil)) {
|
||
|
AddElementToObject(request, "price", this.PriceToPrecision(symbol, price))
|
||
|
}
|
||
|
var clientOrderId interface{} = this.SafeStringN(params, []interface{}{"clOrdID", "clientOrderId", "client_order_id"})
|
||
|
if IsTrue(!IsEqual(clientOrderId, nil)) {
|
||
|
AddElementToObject(request, "client_id", clientOrderId)
|
||
|
}
|
||
|
if IsTrue(!IsEqual(triggerPrice, nil)) {
|
||
|
if IsTrue(isMarket) {
|
||
|
AddElementToObject(request, "type", "STOP_MARKET")
|
||
|
} else {
|
||
|
AddElementToObject(request, "type", "STOP_LIMIT")
|
||
|
}
|
||
|
AddElementToObject(request, "trigger_price", this.PriceToPrecision(symbol, triggerPrice))
|
||
|
}
|
||
|
params = this.Omit(params, []interface{}{"reduceOnly", "reduce_only", "clOrdID", "clientOrderId", "client_order_id", "postOnly", "timeInForce", "stopPrice", "triggerPrice"})
|
||
|
|
||
|
account:= (<-this.RetrieveAccount())
|
||
|
PanicOnError(account)
|
||
|
var now interface{} = this.Nonce()
|
||
|
var orderReq interface{} = map[string]interface{} {
|
||
|
"timestamp": Multiply(now, 1000),
|
||
|
"market": this.ConvertShortString(GetValue(request, "market")),
|
||
|
"side": Ternary(IsTrue((IsEqual(orderSide, "BUY"))), "1", "2"),
|
||
|
"orderType": this.ConvertShortString(GetValue(request, "type")),
|
||
|
"size": this.ScaleNumber(GetValue(request, "size")),
|
||
|
"price": Ternary(IsTrue((isMarket)), "0", this.ScaleNumber(GetValue(request, "price"))),
|
||
|
}
|
||
|
|
||
|
domain:= (<-this.PrepareParadexDomain())
|
||
|
PanicOnError(domain)
|
||
|
var messageTypes interface{} = map[string]interface{} {
|
||
|
"Order": []interface{}{map[string]interface{} {
|
||
|
"name": "timestamp",
|
||
|
"type": "felt",
|
||
|
}, map[string]interface{} {
|
||
|
"name": "market",
|
||
|
"type": "felt",
|
||
|
}, map[string]interface{} {
|
||
|
"name": "side",
|
||
|
"type": "felt",
|
||
|
}, map[string]interface{} {
|
||
|
"name": "orderType",
|
||
|
"type": "felt",
|
||
|
}, map[string]interface{} {
|
||
|
"name": "size",
|
||
|
"type": "felt",
|
||
|
}, map[string]interface{} {
|
||
|
"name": "price",
|
||
|
"type": "felt",
|
||
|
}},
|
||
|
}
|
||
|
var msg interface{} = this.StarknetEncodeStructuredData(domain, messageTypes, orderReq, GetValue(account, "address"))
|
||
|
var signature interface{} = this.StarknetSign(msg, GetValue(account, "privateKey"))
|
||
|
AddElementToObject(request, "signature", signature)
|
||
|
AddElementToObject(request, "signature_timestamp", GetValue(orderReq, "timestamp"))
|
||
|
|
||
|
response:= (<-this.PrivatePostOrders(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "account": "0x4638e3041366aa71720be63e32e53e1223316c7f0d56f7aa617542ed1e7512x",
|
||
|
// "avg_fill_price": "26000",
|
||
|
// "cancel_reason": "NOT_ENOUGH_MARGIN",
|
||
|
// "client_id": "x1234",
|
||
|
// "created_at": 1681493746016,
|
||
|
// "flags": [
|
||
|
// "REDUCE_ONLY"
|
||
|
// ],
|
||
|
// "id": "123456",
|
||
|
// "instruction": "GTC",
|
||
|
// "last_updated_at": 1681493746016,
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "price": "26000",
|
||
|
// "published_at": 1681493746016,
|
||
|
// "received_at": 1681493746016,
|
||
|
// "remaining_size": "0",
|
||
|
// "seq_no": 1681471234972000000,
|
||
|
// "side": "BUY",
|
||
|
// "size": "0.05",
|
||
|
// "status": "NEW",
|
||
|
// "stp": "EXPIRE_MAKER",
|
||
|
// "timestamp": 1681493746016,
|
||
|
// "trigger_price": "26000",
|
||
|
// "type": "MARKET"
|
||
|
// }
|
||
|
//
|
||
|
var order interface{} = this.ParseOrder(response, market)
|
||
|
|
||
|
ch <- order
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#cancelOrder
|
||
|
* @description cancels an open order
|
||
|
* @see https://docs.api.prod.paradex.trade/#cancel-order
|
||
|
* @see https://docs.api.prod.paradex.trade/#cancel-open-order-by-client-order-id
|
||
|
* @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.clientOrderId] a unique id for the order
|
||
|
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
|
*/
|
||
|
func (this *paradex) 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
|
||
|
|
||
|
retRes14188 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes14188)
|
||
|
|
||
|
retRes14198 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes14198)
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
var clientOrderId interface{} = this.SafeStringN(params, []interface{}{"clOrdID", "clientOrderId", "client_order_id"})
|
||
|
var response interface{} = nil
|
||
|
if IsTrue(!IsEqual(clientOrderId, nil)) {
|
||
|
AddElementToObject(request, "client_id", clientOrderId)
|
||
|
|
||
|
response = (<-this.PrivateDeleteOrdersByClientIdClientId(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
} else {
|
||
|
AddElementToObject(request, "order_id", id)
|
||
|
|
||
|
response = (<-this.PrivateDeleteOrdersOrderId(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// if success, no response...
|
||
|
//
|
||
|
ch <- this.ParseOrder(response)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#cancelAllOrders
|
||
|
* @description cancel all open orders in a market
|
||
|
* @see https://docs.api.prod.paradex.trade/#cancel-all-open-orders
|
||
|
* @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 *paradex) 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")))
|
||
|
}
|
||
|
|
||
|
retRes14498 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes14498)
|
||
|
|
||
|
retRes14508 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes14508)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
var request interface{} = map[string]interface{} {
|
||
|
"market": GetValue(market, "id"),
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivateDeleteOrders(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
|
||
|
//
|
||
|
// if success, no response...
|
||
|
//
|
||
|
ch <- response
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchOrder
|
||
|
* @description fetches information on an order made by the user
|
||
|
* @see https://docs.api.prod.paradex.trade/#get-order
|
||
|
* @see https://docs.api.prod.paradex.trade/#get-order-by-client-id
|
||
|
* @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
|
||
|
* @param {string} [params.clientOrderId] a unique id for the order
|
||
|
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
|
*/
|
||
|
func (this *paradex) 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
|
||
|
|
||
|
retRes14758 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes14758)
|
||
|
|
||
|
retRes14768 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes14768)
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
var clientOrderId interface{} = this.SafeStringN(params, []interface{}{"clOrdID", "clientOrderId", "client_order_id"})
|
||
|
params = this.Omit(params, []interface{}{"clOrdID", "clientOrderId", "client_order_id"})
|
||
|
var response interface{} = nil
|
||
|
if IsTrue(!IsEqual(clientOrderId, nil)) {
|
||
|
AddElementToObject(request, "client_id", clientOrderId)
|
||
|
|
||
|
response = (<-this.PrivateGetOrdersByClientIdClientId(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
} else {
|
||
|
AddElementToObject(request, "order_id", id)
|
||
|
|
||
|
response = (<-this.PrivateGetOrdersOrderId(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// {
|
||
|
// "id": "1718941725080201704028870000",
|
||
|
// "account": "0x49ddd7a564c978f6e4089ff8355b56a42b7e2d48ba282cb5aad60f04bea0ec3",
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "side": "SELL",
|
||
|
// "type": "LIMIT",
|
||
|
// "size": "10.153",
|
||
|
// "remaining_size": "10.153",
|
||
|
// "price": "70784.5",
|
||
|
// "status": "CLOSED",
|
||
|
// "created_at": 1718941725082,
|
||
|
// "last_updated_at": 1718958002991,
|
||
|
// "timestamp": 1718941724678,
|
||
|
// "cancel_reason": "USER_CANCELED",
|
||
|
// "client_id": "",
|
||
|
// "seq_no": 1718958002991595738,
|
||
|
// "instruction": "GTC",
|
||
|
// "avg_fill_price": "",
|
||
|
// "stp": "EXPIRE_TAKER",
|
||
|
// "received_at": 1718958510959,
|
||
|
// "published_at": 1718958510960,
|
||
|
// "flags": [],
|
||
|
// "trigger_price": "0"
|
||
|
// }
|
||
|
//
|
||
|
ch <- this.ParseOrder(response)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchOrders
|
||
|
* @description fetches information on multiple orders made by the user
|
||
|
* @see https://docs.api.prod.paradex.trade/#get-orders
|
||
|
* @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.side] 'buy' or 'sell'
|
||
|
* @param {boolean} [params.paginate] set to true if you want to fetch orders with pagination
|
||
|
* @param {int} params.until timestamp in ms of the latest order to fetch
|
||
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
|
*/
|
||
|
func (this *paradex) 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
|
||
|
|
||
|
retRes15328 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes15328)
|
||
|
|
||
|
retRes15338 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes15338)
|
||
|
var paginate interface{} = false
|
||
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOrders", "paginate");
|
||
|
paginate = GetValue(paginateparamsVariable,0);
|
||
|
params = GetValue(paginateparamsVariable,1)
|
||
|
if IsTrue(paginate) {
|
||
|
|
||
|
retRes153719 := (<-this.FetchPaginatedCallCursor("fetchOrders", symbol, since, limit, params, "next", "cursor", nil, 50))
|
||
|
PanicOnError(retRes153719)
|
||
|
ch <- retRes153719
|
||
|
return nil
|
||
|
}
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
var market interface{} = nil
|
||
|
if IsTrue(!IsEqual(symbol, nil)) {
|
||
|
market = this.Market(symbol)
|
||
|
AddElementToObject(request, "market", GetValue(market, "id"))
|
||
|
}
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "start_at", since)
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "page_size", limit)
|
||
|
}
|
||
|
requestparamsVariable := this.HandleUntilOption("end_at", request, params);
|
||
|
request = GetValue(requestparamsVariable,0);
|
||
|
params = GetValue(requestparamsVariable,1)
|
||
|
|
||
|
response:= (<-this.PrivateGetOrdersHistory(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "next": "eyJmaWx0ZXIiMsIm1hcmtlciI6eyJtYXJrZXIiOiIxNjc1NjUwMDE3NDMxMTAxNjk5N=",
|
||
|
// "prev": "eyJmaWx0ZXIiOnsiTGltaXQiOjkwfSwidGltZSI6MTY4MTY3OTgzNzk3MTMwOTk1MywibWFya2VyIjp7Im1zMjExMD==",
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "account": "0x4638e3041366aa71720be63e32e53e1223316c7f0d56f7aa617542ed1e7512x",
|
||
|
// "avg_fill_price": "26000",
|
||
|
// "cancel_reason": "NOT_ENOUGH_MARGIN",
|
||
|
// "client_id": "x1234",
|
||
|
// "created_at": 1681493746016,
|
||
|
// "flags": [
|
||
|
// "REDUCE_ONLY"
|
||
|
// ],
|
||
|
// "id": "123456",
|
||
|
// "instruction": "GTC",
|
||
|
// "last_updated_at": 1681493746016,
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "price": "26000",
|
||
|
// "published_at": 1681493746016,
|
||
|
// "received_at": 1681493746016,
|
||
|
// "remaining_size": "0",
|
||
|
// "seq_no": 1681471234972000000,
|
||
|
// "side": "BUY",
|
||
|
// "size": "0.05",
|
||
|
// "status": "NEW",
|
||
|
// "stp": "EXPIRE_MAKER",
|
||
|
// "timestamp": 1681493746016,
|
||
|
// "trigger_price": "26000",
|
||
|
// "type": "MARKET"
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var orders interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
var paginationCursor interface{} = this.SafeString(response, "next")
|
||
|
var ordersLength interface{} = GetArrayLength(orders)
|
||
|
if IsTrue(IsTrue((!IsEqual(paginationCursor, nil))) && IsTrue((IsGreaterThan(ordersLength, 0)))) {
|
||
|
var first interface{} = GetValue(orders, 0)
|
||
|
AddElementToObject(first, "next", paginationCursor)
|
||
|
AddElementToObject(orders, 0, first)
|
||
|
}
|
||
|
|
||
|
ch <- this.ParseOrders(orders, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchOpenOrders
|
||
|
* @description fetches information on multiple orders made by the user
|
||
|
* @see https://docs.api.prod.paradex.trade/#paradex-rest-api-orders
|
||
|
* @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 *paradex) 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
|
||
|
|
||
|
retRes16108 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes16108)
|
||
|
|
||
|
retRes16118 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes16118)
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
var market interface{} = nil
|
||
|
if IsTrue(!IsEqual(symbol, nil)) {
|
||
|
market = this.Market(symbol)
|
||
|
AddElementToObject(request, "market", GetValue(market, "id"))
|
||
|
}
|
||
|
|
||
|
response:= (<-this.PrivateGetOrders(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "account": "0x4638e3041366aa71720be63e32e53e1223316c7f0d56f7aa617542ed1e7512x",
|
||
|
// "avg_fill_price": "26000",
|
||
|
// "client_id": "x1234",
|
||
|
// "cancel_reason": "NOT_ENOUGH_MARGIN",
|
||
|
// "created_at": 1681493746016,
|
||
|
// "flags": [
|
||
|
// "REDUCE_ONLY"
|
||
|
// ],
|
||
|
// "id": "123456",
|
||
|
// "instruction": "GTC",
|
||
|
// "last_updated_at": 1681493746016,
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "price": "26000",
|
||
|
// "published_at": 1681493746016,
|
||
|
// "received_at": 1681493746016,
|
||
|
// "remaining_size": "0",
|
||
|
// "seq_no": 1681471234972000000,
|
||
|
// "side": "BUY",
|
||
|
// "size": "0.05",
|
||
|
// "status": "NEW",
|
||
|
// "stp": "EXPIRE_MAKER",
|
||
|
// "timestamp": 1681493746016,
|
||
|
// "trigger_price": "26000",
|
||
|
// "type": "MARKET"
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var orders interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
|
||
|
ch <- this.ParseOrders(orders, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchBalance
|
||
|
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
||
|
* @see https://docs.api.prod.paradex.trade/#list-balances
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
||
|
*/
|
||
|
func (this *paradex) 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
|
||
|
|
||
|
retRes16648 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes16648)
|
||
|
|
||
|
retRes16658 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes16658)
|
||
|
|
||
|
response:= (<-this.PrivateGetBalance())
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "token": "USDC",
|
||
|
// "size": "99980.2382266290601",
|
||
|
// "last_updated_at": 1718529757240
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
|
||
|
ch <- this.ParseBalance(data)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) ParseBalance(response interface{}) interface{} {
|
||
|
var result interface{} = map[string]interface{} {
|
||
|
"info": response,
|
||
|
}
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(response)); i++ {
|
||
|
var balance interface{} = this.SafeDict(response, i, map[string]interface{} {})
|
||
|
var currencyId interface{} = this.SafeString(balance, "token")
|
||
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
||
|
var account interface{} = this.Account()
|
||
|
AddElementToObject(account, "total", this.SafeString(balance, "size"))
|
||
|
AddElementToObject(result, code, account)
|
||
|
}
|
||
|
return this.SafeBalance(result)
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchMyTrades
|
||
|
* @description fetch all trades made by the user
|
||
|
* @see https://docs.api.prod.paradex.trade/#list-fills
|
||
|
* @param {string} symbol unified market symbol
|
||
|
* @param {int} [since] the earliest time in ms to fetch trades for
|
||
|
* @param {int} [limit] the maximum number of trades structures to retrieve
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
|
* @param {int} [params.until] the latest time in ms to fetch entries for
|
||
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
||
|
*/
|
||
|
func (this *paradex) 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
|
||
|
|
||
|
retRes17098 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes17098)
|
||
|
|
||
|
retRes17108 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes17108)
|
||
|
var paginate interface{} = false
|
||
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchMyTrades", "paginate");
|
||
|
paginate = GetValue(paginateparamsVariable,0);
|
||
|
params = GetValue(paginateparamsVariable,1)
|
||
|
if IsTrue(paginate) {
|
||
|
|
||
|
retRes171419 := (<-this.FetchPaginatedCallCursor("fetchMyTrades", symbol, since, limit, params, "next", "cursor", nil, 100))
|
||
|
PanicOnError(retRes171419)
|
||
|
ch <- retRes171419
|
||
|
return nil
|
||
|
}
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
var market interface{} = nil
|
||
|
if IsTrue(!IsEqual(symbol, nil)) {
|
||
|
market = this.Market(symbol)
|
||
|
AddElementToObject(request, "market", GetValue(market, "id"))
|
||
|
}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "page_size", limit)
|
||
|
}
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "start_at", since)
|
||
|
}
|
||
|
requestparamsVariable := this.HandleUntilOption("end_at", request, params);
|
||
|
request = GetValue(requestparamsVariable,0);
|
||
|
params = GetValue(requestparamsVariable,1)
|
||
|
|
||
|
response:= (<-this.PrivateGetFills(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "next": null,
|
||
|
// "prev": null,
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "id": "1718947571560201703986670001",
|
||
|
// "side": "BUY",
|
||
|
// "liquidity": "TAKER",
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "order_id": "1718947571540201703992340000",
|
||
|
// "price": "64852.9",
|
||
|
// "size": "0.01",
|
||
|
// "fee": "0.1945587",
|
||
|
// "fee_currency": "USDC",
|
||
|
// "created_at": 1718947571569,
|
||
|
// "remaining_size": "0",
|
||
|
// "client_id": "",
|
||
|
// "fill_type": "FILL"
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var trades interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(trades)); i++ {
|
||
|
AddElementToObject(GetValue(trades, i), "next", this.SafeString(response, "next"))
|
||
|
}
|
||
|
|
||
|
ch <- this.ParseTrades(trades, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchPosition
|
||
|
* @description fetch data on an open position
|
||
|
* @see https://docs.api.prod.paradex.trade/#list-open-positions
|
||
|
* @param {string} symbol unified market symbol of the market the position is held in
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
||
|
*/
|
||
|
func (this *paradex) FetchPosition(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
|
||
|
|
||
|
retRes17708 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes17708)
|
||
|
|
||
|
retRes17718 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes17718)
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
|
||
|
positions:= (<-this.FetchPositions([]interface{}{GetValue(market, "symbol")}, params))
|
||
|
PanicOnError(positions)
|
||
|
|
||
|
ch <- this.SafeDict(positions, 0, map[string]interface{} {})
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchPositions
|
||
|
* @description fetch all open positions
|
||
|
* @see https://docs.api.prod.paradex.trade/#list-open-positions
|
||
|
* @param {string[]} [symbols] list of unified market symbols
|
||
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
|
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
||
|
*/
|
||
|
func (this *paradex) 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
|
||
|
|
||
|
retRes17878 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes17878)
|
||
|
|
||
|
retRes17888 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes17888)
|
||
|
symbols = this.MarketSymbols(symbols)
|
||
|
|
||
|
response:= (<-this.PrivateGetPositions())
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "id": "0x49ddd7a564c978f6e4089ff8355b56a42b7e2d48ba282cb5aad60f04bea0ec3-BTC-USD-PERP",
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "status": "OPEN",
|
||
|
// "side": "LONG",
|
||
|
// "size": "0.01",
|
||
|
// "average_entry_price": "64839.96053748",
|
||
|
// "average_entry_price_usd": "64852.9",
|
||
|
// "realized_pnl": "0",
|
||
|
// "unrealized_pnl": "-2.39677214",
|
||
|
// "unrealized_funding_pnl": "-0.11214013",
|
||
|
// "cost": "648.39960537",
|
||
|
// "cost_usd": "648.529",
|
||
|
// "cached_funding_index": "35202.1002351",
|
||
|
// "last_updated_at": 1718950074249,
|
||
|
// "last_fill_id": "1718947571560201703986670001",
|
||
|
// "seq_no": 1718950074249176253,
|
||
|
// "liquidation_price": ""
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
|
||
|
ch <- this.ParsePositions(data, symbols)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "id": "0x49ddd7a564c978f6e4089ff8355b56a42b7e2d48ba282cb5aad60f04bea0ec3-BTC-USD-PERP",
|
||
|
// "market": "BTC-USD-PERP",
|
||
|
// "status": "OPEN",
|
||
|
// "side": "LONG",
|
||
|
// "size": "0.01",
|
||
|
// "average_entry_price": "64839.96053748",
|
||
|
// "average_entry_price_usd": "64852.9",
|
||
|
// "realized_pnl": "0",
|
||
|
// "unrealized_pnl": "-2.39677214",
|
||
|
// "unrealized_funding_pnl": "-0.11214013",
|
||
|
// "cost": "648.39960537",
|
||
|
// "cost_usd": "648.529",
|
||
|
// "cached_funding_index": "35202.1002351",
|
||
|
// "last_updated_at": 1718950074249,
|
||
|
// "last_fill_id": "1718947571560201703986670001",
|
||
|
// "seq_no": 1718950074249176253,
|
||
|
// "liquidation_price": ""
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var marketId interface{} = this.SafeString(position, "market")
|
||
|
market = this.SafeMarket(marketId, market)
|
||
|
var symbol interface{} = GetValue(market, "symbol")
|
||
|
var side interface{} = this.SafeStringLower(position, "side")
|
||
|
var quantity interface{} = this.SafeString(position, "size")
|
||
|
if IsTrue(!IsEqual(side, "long")) {
|
||
|
quantity = Precise.StringMul("-1", quantity)
|
||
|
}
|
||
|
var timestamp interface{} = this.SafeInteger(position, "time")
|
||
|
return this.SafePosition(map[string]interface{} {
|
||
|
"info": position,
|
||
|
"id": this.SafeString(position, "id"),
|
||
|
"symbol": symbol,
|
||
|
"entryPrice": this.SafeString(position, "average_entry_price"),
|
||
|
"markPrice": nil,
|
||
|
"notional": nil,
|
||
|
"collateral": this.SafeString(position, "cost"),
|
||
|
"unrealizedPnl": this.SafeString(position, "unrealized_pnl"),
|
||
|
"side": side,
|
||
|
"contracts": this.ParseNumber(quantity),
|
||
|
"contractSize": nil,
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"hedged": nil,
|
||
|
"maintenanceMargin": nil,
|
||
|
"maintenanceMarginPercentage": nil,
|
||
|
"initialMargin": nil,
|
||
|
"initialMarginPercentage": nil,
|
||
|
"leverage": nil,
|
||
|
"liquidationPrice": nil,
|
||
|
"marginRatio": nil,
|
||
|
"marginMode": nil,
|
||
|
"percentage": nil,
|
||
|
})
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchLiquidations
|
||
|
* @description retrieves the public liquidations of a trading pair
|
||
|
* @see https://docs.api.prod.paradex.trade/#list-liquidations
|
||
|
* @param {string} symbol unified CCXT market symbol
|
||
|
* @param {int} [since] the earliest time in ms to fetch liquidations for
|
||
|
* @param {int} [limit] the maximum number of liquidation structures to retrieve
|
||
|
* @param {object} [params] exchange specific parameters for the huobi api endpoint
|
||
|
* @param {int} [params.until] timestamp in ms of the latest liquidation
|
||
|
* @returns {object} an array of [liquidation structures]{@link https://docs.ccxt.com/#/?id=liquidation-structure}
|
||
|
*/
|
||
|
func (this *paradex) FetchLiquidations(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
|
ch := make(chan interface{})
|
||
|
go func() interface{} {
|
||
|
defer close(ch)
|
||
|
defer ReturnPanicError(ch)
|
||
|
since := GetArg(optionalArgs, 0, nil)
|
||
|
_ = since
|
||
|
limit := GetArg(optionalArgs, 1, nil)
|
||
|
_ = limit
|
||
|
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
||
|
_ = params
|
||
|
|
||
|
retRes18918 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes18918)
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "from", since)
|
||
|
} else {
|
||
|
AddElementToObject(request, "from", 1)
|
||
|
}
|
||
|
var market interface{} = this.Market(symbol)
|
||
|
requestparamsVariable := this.HandleUntilOption("to", request, params);
|
||
|
request = GetValue(requestparamsVariable,0);
|
||
|
params = GetValue(requestparamsVariable,1)
|
||
|
|
||
|
response:= (<-this.PrivateGetLiquidations(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "created_at": 1697213130097,
|
||
|
// "id": "0x123456789"
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var data interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
|
||
|
ch <- this.ParseLiquidations(data, market, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) ParseLiquidation(liquidation interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// {
|
||
|
// "created_at": 1697213130097,
|
||
|
// "id": "0x123456789"
|
||
|
// }
|
||
|
//
|
||
|
market := GetArg(optionalArgs, 0, nil)
|
||
|
_ = market
|
||
|
var timestamp interface{} = this.SafeInteger(liquidation, "created_at")
|
||
|
return this.SafeLiquidation(map[string]interface{} {
|
||
|
"info": liquidation,
|
||
|
"symbol": nil,
|
||
|
"contracts": nil,
|
||
|
"contractSize": nil,
|
||
|
"price": nil,
|
||
|
"baseValue": nil,
|
||
|
"quoteValue": nil,
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
})
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchTransfers
|
||
|
* @description fetch all deposits made to an account
|
||
|
* @see https://docs.api.prod.paradex.trade/#paradex-rest-api-transfers
|
||
|
* @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
|
||
|
* @param {int} [params.until] the latest time in ms to fetch entries for
|
||
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
|
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
||
|
*/
|
||
|
func (this *paradex) 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
|
||
|
|
||
|
retRes19508 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes19508)
|
||
|
|
||
|
retRes19518 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes19518)
|
||
|
var paginate interface{} = false
|
||
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchDeposits", "paginate");
|
||
|
paginate = GetValue(paginateparamsVariable,0);
|
||
|
params = GetValue(paginateparamsVariable,1)
|
||
|
if IsTrue(paginate) {
|
||
|
|
||
|
retRes195519 := (<-this.FetchPaginatedCallCursor("fetchDeposits", code, since, limit, params, "next", "cursor", nil, 100))
|
||
|
PanicOnError(retRes195519)
|
||
|
ch <- retRes195519
|
||
|
return nil
|
||
|
}
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "page_size", limit)
|
||
|
}
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "start_at", since)
|
||
|
}
|
||
|
requestparamsVariable := this.HandleUntilOption("end_at", request, params);
|
||
|
request = GetValue(requestparamsVariable,0);
|
||
|
params = GetValue(requestparamsVariable,1)
|
||
|
|
||
|
response:= (<-this.PrivateGetTransfers(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "next": null,
|
||
|
// "prev": null,
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "id": "1718940471200201703989430000",
|
||
|
// "account": "0x49ddd7a564c978f6e4089ff8355b56a42b7e2d48ba282cb5aad60f04bea0ec3",
|
||
|
// "kind": "DEPOSIT",
|
||
|
// "status": "COMPLETED",
|
||
|
// "amount": "100000",
|
||
|
// "token": "USDC",
|
||
|
// "created_at": 1718940471208,
|
||
|
// "last_updated_at": 1718941455546,
|
||
|
// "txn_hash": "0x73a415ca558a97bbdcd1c43e52b45f1e0486a0a84b3bb4958035ad6c59cb866",
|
||
|
// "external_txn_hash": "",
|
||
|
// "socialized_loss_factor": ""
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var rows interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
var deposits interface{} = []interface{}{}
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(rows)); i++ {
|
||
|
var row interface{} = GetValue(rows, i)
|
||
|
if IsTrue(IsEqual(GetValue(row, "kind"), "DEPOSIT")) {
|
||
|
AppendToArray(&deposits,row)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ch <- this.ParseTransactions(deposits, nil, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
/**
|
||
|
* @method
|
||
|
* @name paradex#fetchWithdrawals
|
||
|
* @description fetch all withdrawals made from an account
|
||
|
* @see https://docs.api.prod.paradex.trade/#paradex-rest-api-transfers
|
||
|
* @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
|
||
|
* @param {int} [params.until] the latest time in ms to fetch withdrawals for
|
||
|
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
|
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
||
|
*/
|
||
|
func (this *paradex) 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
|
||
|
|
||
|
retRes20128 := (<-this.AuthenticateRest())
|
||
|
PanicOnError(retRes20128)
|
||
|
|
||
|
retRes20138 := (<-this.LoadMarkets())
|
||
|
PanicOnError(retRes20138)
|
||
|
var paginate interface{} = false
|
||
|
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchWithdrawals", "paginate");
|
||
|
paginate = GetValue(paginateparamsVariable,0);
|
||
|
params = GetValue(paginateparamsVariable,1)
|
||
|
if IsTrue(paginate) {
|
||
|
|
||
|
retRes201719 := (<-this.FetchPaginatedCallCursor("fetchWithdrawals", code, since, limit, params, "next", "cursor", nil, 100))
|
||
|
PanicOnError(retRes201719)
|
||
|
ch <- retRes201719
|
||
|
return nil
|
||
|
}
|
||
|
var request interface{} = map[string]interface{} {}
|
||
|
if IsTrue(!IsEqual(limit, nil)) {
|
||
|
AddElementToObject(request, "page_size", limit)
|
||
|
}
|
||
|
if IsTrue(!IsEqual(since, nil)) {
|
||
|
AddElementToObject(request, "start_at", since)
|
||
|
}
|
||
|
requestparamsVariable := this.HandleUntilOption("end_at", request, params);
|
||
|
request = GetValue(requestparamsVariable,0);
|
||
|
params = GetValue(requestparamsVariable,1)
|
||
|
|
||
|
response:= (<-this.PrivateGetTransfers(this.Extend(request, params)))
|
||
|
PanicOnError(response)
|
||
|
//
|
||
|
// {
|
||
|
// "next": null,
|
||
|
// "prev": null,
|
||
|
// "results": [
|
||
|
// {
|
||
|
// "id": "1718940471200201703989430000",
|
||
|
// "account": "0x49ddd7a564c978f6e4089ff8355b56a42b7e2d48ba282cb5aad60f04bea0ec3",
|
||
|
// "kind": "DEPOSIT",
|
||
|
// "status": "COMPLETED",
|
||
|
// "amount": "100000",
|
||
|
// "token": "USDC",
|
||
|
// "created_at": 1718940471208,
|
||
|
// "last_updated_at": 1718941455546,
|
||
|
// "txn_hash": "0x73a415ca558a97bbdcd1c43e52b45f1e0486a0a84b3bb4958035ad6c59cb866",
|
||
|
// "external_txn_hash": "",
|
||
|
// "socialized_loss_factor": ""
|
||
|
// }
|
||
|
// ]
|
||
|
// }
|
||
|
//
|
||
|
var rows interface{} = this.SafeList(response, "results", []interface{}{})
|
||
|
var deposits interface{} = []interface{}{}
|
||
|
for i := 0; IsLessThan(i, GetArrayLength(rows)); i++ {
|
||
|
var row interface{} = GetValue(rows, i)
|
||
|
if IsTrue(IsEqual(GetValue(row, "kind"), "WITHDRAWAL")) {
|
||
|
AppendToArray(&deposits,row)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ch <- this.ParseTransactions(deposits, nil, since, limit)
|
||
|
return nil
|
||
|
|
||
|
}()
|
||
|
return ch
|
||
|
}
|
||
|
func (this *paradex) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} {
|
||
|
//
|
||
|
// fetchDeposits & fetchWithdrawals
|
||
|
//
|
||
|
// {
|
||
|
// "id": "1718940471200201703989430000",
|
||
|
// "account": "0x49ddd7a564c978f6e4089ff8355b56a42b7e2d48ba282cb5aad60f04bea0ec3",
|
||
|
// "kind": "DEPOSIT",
|
||
|
// "status": "COMPLETED",
|
||
|
// "amount": "100000",
|
||
|
// "token": "USDC",
|
||
|
// "created_at": 1718940471208,
|
||
|
// "last_updated_at": 1718941455546,
|
||
|
// "txn_hash": "0x73a415ca558a97bbdcd1c43e52b45f1e0486a0a84b3bb4958035ad6c59cb866",
|
||
|
// "external_txn_hash": "",
|
||
|
// "socialized_loss_factor": ""
|
||
|
// }
|
||
|
//
|
||
|
currency := GetArg(optionalArgs, 0, nil)
|
||
|
_ = currency
|
||
|
var id interface{} = this.SafeString(transaction, "id")
|
||
|
var address interface{} = this.SafeString(transaction, "account")
|
||
|
var txid interface{} = this.SafeString(transaction, "txn_hash")
|
||
|
var currencyId interface{} = this.SafeString(transaction, "token")
|
||
|
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
|
||
|
var timestamp interface{} = this.SafeInteger(transaction, "created_at")
|
||
|
var updated interface{} = this.SafeInteger(transaction, "last_updated_at")
|
||
|
var typeVar interface{} = this.SafeString(transaction, "kind")
|
||
|
typeVar = Ternary(IsTrue((IsEqual(typeVar, "DEPOSIT"))), "deposit", "withdrawal")
|
||
|
var status interface{} = this.ParseTransactionStatus(this.SafeString(transaction, "status"))
|
||
|
var amount interface{} = this.SafeNumber(transaction, "amount")
|
||
|
return map[string]interface{} {
|
||
|
"info": transaction,
|
||
|
"id": id,
|
||
|
"txid": txid,
|
||
|
"timestamp": timestamp,
|
||
|
"datetime": this.Iso8601(timestamp),
|
||
|
"network": nil,
|
||
|
"address": address,
|
||
|
"addressTo": address,
|
||
|
"addressFrom": nil,
|
||
|
"tag": nil,
|
||
|
"tagTo": nil,
|
||
|
"tagFrom": nil,
|
||
|
"type": typeVar,
|
||
|
"amount": amount,
|
||
|
"currency": code,
|
||
|
"status": status,
|
||
|
"updated": updated,
|
||
|
"internal": nil,
|
||
|
"comment": nil,
|
||
|
"fee": nil,
|
||
|
}
|
||
|
}
|
||
|
func (this *paradex) ParseTransactionStatus(status interface{}) interface{} {
|
||
|
var statuses interface{} = map[string]interface{} {
|
||
|
"PENDING": "pending",
|
||
|
"AVAILABLE": "pending",
|
||
|
"COMPLETED": "ok",
|
||
|
"FAILED": "failed",
|
||
|
}
|
||
|
return this.SafeString(statuses, status, status)
|
||
|
}
|
||
|
func (this *paradex) 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 url interface{} = Add(Add(this.ImplodeHostname(GetValue(GetValue(this.Urls, "api"), this.Version)), "/"), this.ImplodeParams(path, params))
|
||
|
var query interface{} = this.Omit(params, this.ExtractParams(path))
|
||
|
if IsTrue(IsEqual(api, "public")) {
|
||
|
if IsTrue(GetArrayLength(ObjectKeys(query))) {
|
||
|
url = Add(url, Add("?", this.Urlencode(query)))
|
||
|
}
|
||
|
} else if IsTrue(IsEqual(api, "private")) {
|
||
|
headers = map[string]interface{} {
|
||
|
"Accept": "application/json",
|
||
|
"PARADEX-PARTNER": this.SafeString(this.Options, "broker", "CCXT"),
|
||
|
}
|
||
|
// TODO: optimize
|
||
|
if IsTrue(IsEqual(path, "auth")) {
|
||
|
AddElementToObject(headers, "PARADEX-STARKNET-ACCOUNT", GetValue(query, "account"))
|
||
|
AddElementToObject(headers, "PARADEX-STARKNET-SIGNATURE", GetValue(query, "signature"))
|
||
|
AddElementToObject(headers, "PARADEX-TIMESTAMP", ToString(GetValue(query, "timestamp")))
|
||
|
AddElementToObject(headers, "PARADEX-SIGNATURE-EXPIRATION", ToString(GetValue(query, "expiration")))
|
||
|
} else if IsTrue(IsEqual(path, "onboarding")) {
|
||
|
AddElementToObject(headers, "PARADEX-ETHEREUM-ACCOUNT", this.WalletAddress)
|
||
|
AddElementToObject(headers, "PARADEX-STARKNET-ACCOUNT", GetValue(query, "account"))
|
||
|
AddElementToObject(headers, "PARADEX-STARKNET-SIGNATURE", GetValue(query, "signature"))
|
||
|
AddElementToObject(headers, "PARADEX-TIMESTAMP", ToString(this.Nonce()))
|
||
|
AddElementToObject(headers, "Content-Type", "application/json")
|
||
|
body = this.Json(map[string]interface{} {
|
||
|
"public_key": GetValue(query, "public_key"),
|
||
|
})
|
||
|
} else {
|
||
|
var token interface{} = GetValue(this.Options, "authToken")
|
||
|
AddElementToObject(headers, "Authorization", Add("Bearer ", token))
|
||
|
if IsTrue(IsEqual(method, "POST")) {
|
||
|
AddElementToObject(headers, "Content-Type", "application/json")
|
||
|
body = this.Json(query)
|
||
|
} else {
|
||
|
url = Add(Add(url, "?"), this.Urlencode(query))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return map[string]interface{} {
|
||
|
"url": url,
|
||
|
"method": method,
|
||
|
"body": body,
|
||
|
"headers": headers,
|
||
|
}
|
||
|
}
|
||
|
func (this *paradex) HandleErrors(httpCode interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} {
|
||
|
if !IsTrue(response) {
|
||
|
return nil // fallback to default error handler
|
||
|
}
|
||
|
//
|
||
|
// {
|
||
|
// "data": null,
|
||
|
// "error": "NOT_ONBOARDED",
|
||
|
// "message": "User has never called /onboarding endpoint"
|
||
|
// }
|
||
|
//
|
||
|
var errorCode interface{} = this.SafeString(response, "error")
|
||
|
if IsTrue(!IsEqual(errorCode, nil)) {
|
||
|
var feedback interface{} = Add(Add(this.Id, " "), body)
|
||
|
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), body, feedback)
|
||
|
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorCode, feedback)
|
||
|
panic(ExchangeError(feedback))
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
|
||
|
func (this *paradex) Init(userConfig map[string]interface{}) {
|
||
|
this.Exchange = Exchange{}
|
||
|
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
|
||
|
this.Exchange.DerivedExchange = this
|
||
|
}
|