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 }