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 okx struct { Exchange } func NewOkxCore() okx { p := okx{} setDefaults(&p) return p } func (this *okx) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "okx", "name": "OKX", "countries": []interface{}{"CN", "US"}, "version": "v5", "rateLimit": Multiply(100, 1.03), "pro": true, "certified": true, "has": map[string]interface{} { "CORS": nil, "spot": true, "margin": true, "swap": true, "future": true, "option": true, "addMargin": true, "cancelAllOrders": false, "cancelAllOrdersAfter": true, "cancelOrder": true, "cancelOrders": true, "cancelOrdersForSymbols": true, "closeAllPositions": false, "closePosition": true, "createConvertTrade": true, "createDepositAddress": false, "createMarketBuyOrderWithCost": true, "createMarketSellOrderWithCost": true, "createOrder": true, "createOrders": true, "createOrderWithTakeProfitAndStopLoss": true, "createPostOnlyOrder": true, "createReduceOnlyOrder": true, "createStopLimitOrder": true, "createStopLossOrder": true, "createStopMarketOrder": true, "createStopOrder": true, "createTakeProfitOrder": true, "createTrailingPercentOrder": true, "createTriggerOrder": true, "editOrder": true, "fetchAccounts": true, "fetchBalance": true, "fetchBidsAsks": nil, "fetchBorrowInterest": true, "fetchBorrowRateHistories": true, "fetchBorrowRateHistory": true, "fetchCanceledOrders": true, "fetchClosedOrder": nil, "fetchClosedOrders": true, "fetchConvertCurrencies": true, "fetchConvertQuote": true, "fetchConvertTrade": true, "fetchConvertTradeHistory": true, "fetchCrossBorrowRate": true, "fetchCrossBorrowRates": true, "fetchCurrencies": true, "fetchDeposit": true, "fetchDepositAddress": true, "fetchDepositAddresses": false, "fetchDepositAddressesByNetwork": true, "fetchDeposits": true, "fetchDepositsWithdrawals": false, "fetchDepositWithdrawFee": "emulated", "fetchDepositWithdrawFees": true, "fetchFundingHistory": true, "fetchFundingInterval": true, "fetchFundingIntervals": false, "fetchFundingRate": true, "fetchFundingRateHistory": true, "fetchFundingRates": false, "fetchGreeks": true, "fetchIndexOHLCV": true, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": false, "fetchL3OrderBook": false, "fetchLedger": true, "fetchLedgerEntry": nil, "fetchLeverage": true, "fetchLeverageTiers": false, "fetchLongShortRatio": false, "fetchLongShortRatioHistory": true, "fetchMarginAdjustmentHistory": true, "fetchMarketLeverageTiers": true, "fetchMarkets": true, "fetchMarkOHLCV": true, "fetchMarkPrice": true, "fetchMarkPrices": true, "fetchMySettlementHistory": false, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenInterest": true, "fetchOpenInterestHistory": true, "fetchOpenOrder": nil, "fetchOpenOrders": true, "fetchOption": true, "fetchOptionChain": true, "fetchOrder": true, "fetchOrderBook": true, "fetchOrderBooks": false, "fetchOrders": false, "fetchOrderTrades": true, "fetchPosition": true, "fetchPositionHistory": "emulated", "fetchPositions": true, "fetchPositionsForSymbol": true, "fetchPositionsHistory": true, "fetchPositionsRisk": false, "fetchPremiumIndexOHLCV": false, "fetchSettlementHistory": true, "fetchStatus": true, "fetchTicker": true, "fetchTickers": true, "fetchTime": true, "fetchTrades": true, "fetchTradingFee": true, "fetchTradingFees": false, "fetchTradingLimits": false, "fetchTransactionFee": false, "fetchTransactionFees": false, "fetchTransactions": false, "fetchTransfer": true, "fetchTransfers": true, "fetchUnderlyingAssets": true, "fetchVolatilityHistory": false, "fetchWithdrawal": true, "fetchWithdrawals": true, "fetchWithdrawalWhitelist": false, "reduceMargin": true, "repayCrossMargin": true, "sandbox": true, "setLeverage": true, "setMargin": false, "setMarginMode": true, "setPositionMode": true, "signIn": false, "transfer": true, "withdraw": true, }, "timeframes": map[string]interface{} { "1m": "1m", "3m": "3m", "5m": "5m", "15m": "15m", "30m": "30m", "1h": "1H", "2h": "2H", "4h": "4H", "6h": "6H", "12h": "12H", "1d": "1D", "1w": "1W", "1M": "1M", "3M": "3M", }, "hostname": "www.okx.com", "urls": map[string]interface{} { "logo": "https://user-images.githubusercontent.com/1294454/152485636-38b19e4a-bece-4dec-979a-5982859ffc04.jpg", "api": map[string]interface{} { "rest": "https://{hostname}", }, "www": "https://www.okx.com", "doc": "https://www.okx.com/docs-v5/en/", "fees": "https://www.okx.com/pages/products/fees.html", "referral": map[string]interface{} { "url": "https://www.okx.com/join/CCXT2023", "discount": 0.2, }, "test": map[string]interface{} { "rest": "https://{hostname}", }, }, "api": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "market/books-full": 2, "market/tickers": 1, "market/ticker": 1, "market/index-tickers": 1, "market/books": Divide(1, 2), "market/books-lite": Divide(5, 3), "market/candles": Divide(1, 2), "market/history-candles": 1, "market/index-candles": 1, "market/history-index-candles": 2, "market/mark-price-candles": 1, "market/history-mark-price-candles": 2, "market/trades": Divide(1, 5), "market/history-trades": 2, "market/option/instrument-family-trades": 1, "market/platform-24-volume": 10, "market/open-oracle": 50, "market/exchange-rate": 20, "market/index-components": 1, "public/economic-calendar": 50, "market/block-tickers": 1, "market/block-ticker": 1, "public/block-trades": 1, "public/instruments": 1, "public/delivery-exercise-history": Divide(1, 2), "public/open-interest": 1, "public/funding-rate": 1, "public/funding-rate-history": 1, "public/price-limit": 1, "public/opt-summary": 1, "public/estimated-price": 2, "public/discount-rate-interest-free-quota": 10, "public/time": 2, "public/mark-price": 2, "public/position-tiers": 2, "public/interest-rate-loan-quota": 10, "public/vip-interest-rate-loan-quota": 10, "public/underlying": 1, "public/insurance-fund": 2, "public/convert-contract-coin": 2, "public/option-trades": 1, "public/instrument-tick-bands": 4, "rubik/stat/trading-data/support-coin": 4, "rubik/stat/taker-volume": 4, "rubik/stat/margin/loan-ratio": 4, "rubik/stat/contracts/long-short-account-ratio": 4, "rubik/stat/contracts/long-short-account-ratio-contract": 4, "rubik/stat/contracts/open-interest-volume": 4, "rubik/stat/option/open-interest-volume": 4, "rubik/stat/option/open-interest-volume-ratio": 4, "rubik/stat/option/open-interest-volume-expiry": 4, "rubik/stat/option/open-interest-volume-strike": 4, "rubik/stat/option/taker-block-volume": 4, "system/status": 50, "sprd/spreads": 1, "sprd/books": Divide(1, 2), "sprd/ticker": 1, "sprd/public-trades": Divide(1, 5), "market/sprd-ticker": 2, "market/sprd-candles": 2, "market/sprd-history-candles": 2, "tradingBot/grid/ai-param": 1, "tradingBot/grid/min-investment": 1, "tradingBot/public/rsi-back-testing": 1, "asset/exchange-list": Divide(5, 3), "finance/staking-defi/eth/apy-history": Divide(5, 3), "finance/staking-defi/sol/apy-history": Divide(5, 3), "finance/savings/lending-rate-summary": Divide(5, 3), "finance/savings/lending-rate-history": Divide(5, 3), "finance/fixed-loan/lending-offers": Divide(10, 3), "finance/fixed-loan/lending-apy-history": Divide(10, 3), "finance/fixed-loan/pending-lending-volume": Divide(10, 3), "finance/sfp/dcd/products": Divide(2, 3), "copytrading/public-lead-traders": 4, "copytrading/public-weekly-pnl": 4, "copytrading/public-stats": 4, "copytrading/public-preference-currency": 4, "copytrading/public-current-subpositions": 4, "copytrading/public-subpositions-history": 4, "support/announcements-types": 20, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "rfq/counterparties": 4, "rfq/maker-instrument-settings": 4, "rfq/mmp-config": 4, "rfq/rfqs": 10, "rfq/quotes": 10, "rfq/trades": 4, "rfq/public-trades": 4, "sprd/order": Divide(1, 3), "sprd/orders-pending": Divide(1, 3), "sprd/orders-history": Divide(1, 2), "sprd/orders-history-archive": Divide(1, 2), "sprd/trades": Divide(1, 3), "trade/order": Divide(1, 3), "trade/orders-pending": Divide(1, 3), "trade/orders-history": Divide(1, 2), "trade/orders-history-archive": 1, "trade/fills": Divide(1, 3), "trade/fills-history": 2.2, "trade/fills-archive": 2, "trade/order-algo": 1, "trade/orders-algo-pending": 1, "trade/orders-algo-history": 1, "trade/easy-convert-currency-list": 20, "trade/easy-convert-history": 20, "trade/one-click-repay-currency-list": 20, "trade/one-click-repay-history": 20, "trade/account-rate-limit": 1, "asset/currencies": Divide(5, 3), "asset/balances": Divide(5, 3), "asset/non-tradable-assets": Divide(5, 3), "asset/asset-valuation": 10, "asset/transfer-state": 10, "asset/bills": Divide(5, 3), "asset/deposit-lightning": 5, "asset/deposit-address": Divide(5, 3), "asset/deposit-history": Divide(5, 3), "asset/withdrawal-history": Divide(5, 3), "asset/deposit-withdraw-status": 20, "asset/convert/currencies": Divide(5, 3), "asset/convert/currency-pair": Divide(5, 3), "asset/convert/history": Divide(5, 3), "asset/monthly-statement": 2, "account/instruments": 1, "account/balance": 2, "account/positions": 2, "account/positions-history": 100, "account/account-position-risk": 2, "account/bills": Divide(5, 3), "account/bills-archive": Divide(5, 3), "account/bills-history-archive": 2, "account/config": 4, "account/max-size": 1, "account/max-avail-size": 1, "account/leverage-info": 1, "account/adjust-leverage-info": 4, "account/max-loan": 1, "account/trade-fee": 4, "account/interest-accrued": 4, "account/interest-rate": 4, "account/max-withdrawal": 1, "account/risk-state": 2, "account/quick-margin-borrow-repay-history": 4, "account/borrow-repay-history": 4, "account/vip-interest-accrued": 4, "account/vip-interest-deducted": 4, "account/vip-loan-order-list": 4, "account/vip-loan-order-detail": 4, "account/interest-limits": 4, "account/greeks": 2, "account/position-tiers": 2, "account/mmp-config": 4, "account/fixed-loan/borrowing-limit": 4, "account/fixed-loan/borrowing-quote": 5, "account/fixed-loan/borrowing-orders-list": 5, "account/spot-manual-borrow-repay": 10, "account/set-auto-repay": 4, "account/spot-borrow-repay-history": 4, "users/subaccount/list": 10, "account/subaccount/balances": Divide(10, 3), "asset/subaccount/balances": Divide(10, 3), "account/subaccount/max-withdrawal": 1, "asset/subaccount/bills": Divide(5, 3), "asset/subaccount/managed-subaccount-bills": Divide(5, 3), "users/entrust-subaccount-list": 10, "account/subaccount/interest-limits": 4, "tradingBot/grid/orders-algo-pending": 1, "tradingBot/grid/orders-algo-history": 1, "tradingBot/grid/orders-algo-details": 1, "tradingBot/grid/sub-orders": 1, "tradingBot/grid/positions": 1, "tradingBot/grid/ai-param": 1, "tradingBot/signal/signals": 1, "tradingBot/signal/orders-algo-details": 1, "tradingBot/signal/orders-algo-history": 1, "tradingBot/signal/positions": 1, "tradingBot/signal/positions-history": 1, "tradingBot/signal/sub-orders": 1, "tradingBot/signal/event-history": 1, "tradingBot/recurring/orders-algo-pending": 1, "tradingBot/recurring/orders-algo-history": 1, "tradingBot/recurring/orders-algo-details": 1, "tradingBot/recurring/sub-orders": 1, "finance/savings/balance": Divide(5, 3), "finance/savings/lending-history": Divide(5, 3), "finance/staking-defi/offers": Divide(10, 3), "finance/staking-defi/orders-active": Divide(10, 3), "finance/staking-defi/orders-history": Divide(10, 3), "finance/staking-defi/eth/balance": Divide(5, 3), "finance/staking-defi/eth/purchase-redeem-history": Divide(5, 3), "finance/staking-defi/eth/product-info": 3, "finance/staking-defi/sol/balance": Divide(5, 3), "finance/staking-defi/sol/purchase-redeem-history": Divide(5, 3), "copytrading/current-subpositions": 1, "copytrading/subpositions-history": 1, "copytrading/instruments": 4, "copytrading/profit-sharing-details": 4, "copytrading/total-profit-sharing": 4, "copytrading/unrealized-profit-sharing-details": 4, "copytrading/copy-settings": 4, "copytrading/batch-leverage-info": 4, "copytrading/current-lead-traders": 4, "copytrading/lead-traders-history": 4, "broker/nd/info": 10, "broker/nd/subaccount-info": 10, "broker/nd/subaccount/apikey": 10, "asset/broker/nd/subaccount-deposit-address": Divide(5, 3), "asset/broker/nd/subaccount-deposit-history": 4, "asset/broker/nd/subaccount-withdrawal-history": 4, "broker/nd/rebate-daily": 100, "broker/nd/rebate-per-orders": 300, "finance/sfp/dcd/order": 2, "finance/sfp/dcd/orders": 2, "broker/fd/rebate-per-orders": 300, "broker/fd/if-rebate": 5, "affiliate/invitee/detail": 1, "users/partner/if-rebate": 1, "support/announcements": 4, }, "post": map[string]interface{} { "rfq/create-rfq": 4, "rfq/cancel-rfq": 4, "rfq/cancel-batch-rfqs": 10, "rfq/cancel-all-rfqs": 10, "rfq/execute-quote": 15, "rfq/maker-instrument-settings": 4, "rfq/mmp-reset": 4, "rfq/mmp-config": 100, "rfq/create-quote": 0.4, "rfq/cancel-quote": 0.4, "rfq/cancel-batch-quotes": 10, "rfq/cancel-all-quotes": 10, "sprd/order": 1, "sprd/cancel-order": 1, "sprd/mass-cancel": 1, "sprd/amend-order": 1, "sprd/cancel-all-after": 10, "trade/order": Divide(1, 3), "trade/batch-orders": Divide(1, 15), "trade/cancel-order": Divide(1, 3), "trade/cancel-batch-orders": Divide(1, 15), "trade/amend-order": Divide(1, 3), "trade/amend-batch-orders": Divide(1, 150), "trade/close-position": 1, "trade/fills-archive": 172800, "trade/order-algo": 1, "trade/cancel-algos": 1, "trade/amend-algos": 1, "trade/cancel-advance-algos": 1, "trade/easy-convert": 20, "trade/one-click-repay": 20, "trade/mass-cancel": 4, "trade/cancel-all-after": 10, "asset/transfer": 10, "asset/withdrawal": Divide(5, 3), "asset/withdrawal-lightning": 5, "asset/cancel-withdrawal": Divide(5, 3), "asset/convert-dust-assets": 10, "asset/convert/estimate-quote": 1, "asset/convert/trade": 1, "asset/monthly-statement": 1, "account/set-position-mode": 4, "account/set-leverage": 1, "account/position/margin-balance": 1, "account/set-greeks": 4, "account/set-isolated-mode": 4, "account/quick-margin-borrow-repay": 4, "account/borrow-repay": Divide(5, 3), "account/simulated_margin": 10, "account/position-builder": 10, "account/set-riskOffset-type": 2, "account/activate-option": 4, "account/set-auto-loan": 4, "account/set-account-level": 4, "account/mmp-reset": 4, "account/mmp-config": 100, "account/fixed-loan/borrowing-order": 5, "account/fixed-loan/amend-borrowing-order": 5, "account/fixed-loan/manual-reborrow": 5, "account/fixed-loan/repay-borrowing-order": 5, "account/bills-history-archive": 72000, "users/subaccount/modify-apikey": 10, "asset/subaccount/transfer": 10, "users/subaccount/set-transfer-out": 10, "account/subaccount/set-loan-allocation": 4, "tradingBot/grid/order-algo": 1, "tradingBot/grid/amend-order-algo": 1, "tradingBot/grid/stop-order-algo": 1, "tradingBot/grid/close-position": 1, "tradingBot/grid/cancel-close-order": 1, "tradingBot/grid/order-instant-trigger": 1, "tradingBot/grid/withdraw-income": 1, "tradingBot/grid/compute-margin-balance": 1, "tradingBot/grid/margin-balance": 1, "tradingBot/grid/min-investment": 1, "tradingBot/grid/adjust-investment": 1, "tradingBot/signal/create-signal": 1, "tradingBot/signal/order-algo": 1, "tradingBot/signal/stop-order-algo": 1, "tradingBot/signal/margin-balance": 1, "tradingBot/signal/amendTPSL": 1, "tradingBot/signal/set-instruments": 1, "tradingBot/signal/close-position": 1, "tradingBot/signal/sub-order": 1, "tradingBot/signal/cancel-sub-order": 1, "tradingBot/recurring/order-algo": 1, "tradingBot/recurring/amend-order-algo": 1, "tradingBot/recurring/stop-order-algo": 1, "finance/savings/purchase-redempt": Divide(5, 3), "finance/savings/set-lending-rate": Divide(5, 3), "finance/staking-defi/purchase": 3, "finance/staking-defi/redeem": 3, "finance/staking-defi/cancel": 3, "finance/staking-defi/eth/purchase": 5, "finance/staking-defi/eth/redeem": 5, "finance/staking-defi/sol/purchase": 5, "finance/staking-defi/sol/redeem": 5, "copytrading/algo-order": 1, "copytrading/close-subposition": 1, "copytrading/set-instruments": 4, "copytrading/first-copy-settings": 4, "copytrading/amend-copy-settings": 4, "copytrading/stop-copy-trading": 4, "copytrading/batch-set-leverage": 4, "broker/nd/create-subaccount": 0.25, "broker/nd/delete-subaccount": 1, "broker/nd/subaccount/apikey": 0.25, "broker/nd/subaccount/modify-apikey": 1, "broker/nd/subaccount/delete-apikey": 1, "broker/nd/set-subaccount-level": 4, "broker/nd/set-subaccount-fee-rate": 4, "broker/nd/set-subaccount-assets": 0.25, "asset/broker/nd/subaccount-deposit-address": 1, "asset/broker/nd/modify-subaccount-deposit-address": Divide(5, 3), "broker/nd/rebate-per-orders": 36000, "finance/sfp/dcd/quote": 10, "finance/sfp/dcd/order": 10, "broker/nd/report-subaccount-ip": 0.25, "broker/fd/rebate-per-orders": 36000, }, }, }, "fees": map[string]interface{} { "trading": map[string]interface{} { "taker": this.ParseNumber("0.0015"), "maker": this.ParseNumber("0.0010"), }, "spot": map[string]interface{} { "taker": this.ParseNumber("0.0015"), "maker": this.ParseNumber("0.0010"), }, "future": map[string]interface{} { "taker": this.ParseNumber("0.0005"), "maker": this.ParseNumber("0.0002"), }, "swap": map[string]interface{} { "taker": this.ParseNumber("0.00050"), "maker": this.ParseNumber("0.00020"), }, }, "requiredCredentials": map[string]interface{} { "apiKey": true, "secret": true, "password": true, }, "exceptions": map[string]interface{} { "exact": map[string]interface{} { "1": ExchangeError, "2": ExchangeError, "4088": ManualInteractionNeeded, "50000": BadRequest, "50001": OnMaintenance, "50002": BadRequest, "50004": RequestTimeout, "50005": ExchangeNotAvailable, "50006": BadRequest, "50007": AccountSuspended, "50008": AuthenticationError, "50009": AccountSuspended, "50010": ExchangeError, "50011": RateLimitExceeded, "50012": ExchangeError, "50013": ExchangeNotAvailable, "50014": BadRequest, "50015": ExchangeError, "50016": ExchangeError, "50017": ExchangeError, "50018": ExchangeError, "50019": ExchangeError, "50020": ExchangeError, "50021": ExchangeError, "50022": ExchangeError, "50023": ExchangeError, "50024": BadRequest, "50025": ExchangeError, "50026": ExchangeNotAvailable, "50027": PermissionDenied, "50028": ExchangeError, "50044": BadRequest, "50061": ExchangeError, "50062": ExchangeError, "50100": ExchangeError, "50101": AuthenticationError, "50102": InvalidNonce, "50103": AuthenticationError, "50104": AuthenticationError, "50105": AuthenticationError, "50106": AuthenticationError, "50107": AuthenticationError, "50108": ExchangeError, "50109": ExchangeError, "50110": PermissionDenied, "50111": AuthenticationError, "50112": AuthenticationError, "50113": AuthenticationError, "50114": AuthenticationError, "50115": BadRequest, "51000": BadRequest, "51001": BadSymbol, "51002": BadSymbol, "51003": BadRequest, "51004": InvalidOrder, "51005": InvalidOrder, "51006": InvalidOrder, "51007": InvalidOrder, "51008": InsufficientFunds, "51009": AccountSuspended, "51010": AccountNotEnabled, "51011": InvalidOrder, "51012": BadSymbol, "51014": BadSymbol, "51015": BadSymbol, "51016": InvalidOrder, "51017": ExchangeError, "51018": ExchangeError, "51019": ExchangeError, "51020": InvalidOrder, "51021": ContractUnavailable, "51022": ContractUnavailable, "51023": ExchangeError, "51024": AccountSuspended, "51025": ExchangeError, "51026": BadSymbol, "51027": ContractUnavailable, "51028": ContractUnavailable, "51029": ContractUnavailable, "51030": ContractUnavailable, "51031": InvalidOrder, "51046": InvalidOrder, "51047": InvalidOrder, "51072": InvalidOrder, "51073": InvalidOrder, "51074": InvalidOrder, "51090": InvalidOrder, "51091": InvalidOrder, "51092": InvalidOrder, "51093": InvalidOrder, "51094": InvalidOrder, "51095": InvalidOrder, "51096": InvalidOrder, "51098": InvalidOrder, "51099": InvalidOrder, "51100": InvalidOrder, "51101": InvalidOrder, "51102": InvalidOrder, "51103": InvalidOrder, "51104": InvalidOrder, "51105": InvalidOrder, "51106": InvalidOrder, "51107": InvalidOrder, "51108": InvalidOrder, "51109": InvalidOrder, "51110": InvalidOrder, "51111": BadRequest, "51112": InvalidOrder, "51113": RateLimitExceeded, "51115": InvalidOrder, "51116": InvalidOrder, "51117": InvalidOrder, "51118": InvalidOrder, "51119": InsufficientFunds, "51120": InvalidOrder, "51121": InvalidOrder, "51122": InvalidOrder, "51124": InvalidOrder, "51125": InvalidOrder, "51126": InvalidOrder, "51127": InsufficientFunds, "51128": InvalidOrder, "51129": InvalidOrder, "51130": BadSymbol, "51131": InsufficientFunds, "51132": InvalidOrder, "51133": InvalidOrder, "51134": InvalidOrder, "51135": InvalidOrder, "51136": InvalidOrder, "51137": InvalidOrder, "51138": InvalidOrder, "51139": InvalidOrder, "51156": BadRequest, "51159": BadRequest, "51162": InvalidOrder, "51163": InvalidOrder, "51166": InvalidOrder, "51174": InvalidOrder, "51185": InvalidOrder, "51201": InvalidOrder, "51202": InvalidOrder, "51203": InvalidOrder, "51204": InvalidOrder, "51205": InvalidOrder, "51250": InvalidOrder, "51251": InvalidOrder, "51252": InvalidOrder, "51253": InvalidOrder, "51254": InvalidOrder, "51255": InvalidOrder, "51256": InvalidOrder, "51257": InvalidOrder, "51258": InvalidOrder, "51259": InvalidOrder, "51260": InvalidOrder, "51261": InvalidOrder, "51262": InvalidOrder, "51263": InvalidOrder, "51264": InvalidOrder, "51265": InvalidOrder, "51267": InvalidOrder, "51268": InvalidOrder, "51269": InvalidOrder, "51270": InvalidOrder, "51271": InvalidOrder, "51272": InvalidOrder, "51273": InvalidOrder, "51274": InvalidOrder, "51275": InvalidOrder, "51276": InvalidOrder, "51277": InvalidOrder, "51278": InvalidOrder, "51279": InvalidOrder, "51280": InvalidOrder, "51321": InvalidOrder, "51322": InvalidOrder, "51323": BadRequest, "51324": BadRequest, "51325": InvalidOrder, "51327": InvalidOrder, "51328": InvalidOrder, "51329": InvalidOrder, "51330": InvalidOrder, "51400": OrderNotFound, "51401": OrderNotFound, "51402": OrderNotFound, "51403": InvalidOrder, "51404": InvalidOrder, "51405": ExchangeError, "51406": ExchangeError, "51407": BadRequest, "51408": ExchangeError, "51409": ExchangeError, "51410": CancelPending, "51500": ExchangeError, "51501": ExchangeError, "51502": InsufficientFunds, "51503": ExchangeError, "51506": ExchangeError, "51508": ExchangeError, "51509": ExchangeError, "51510": ExchangeError, "51511": ExchangeError, "51600": ExchangeError, "51601": ExchangeError, "51602": ExchangeError, "51603": OrderNotFound, "51732": AuthenticationError, "51733": AuthenticationError, "51734": AuthenticationError, "51735": ExchangeError, "51736": InsufficientFunds, "52000": ExchangeError, "54000": ExchangeError, "54001": ExchangeError, "54008": InvalidOrder, "54009": InvalidOrder, "54011": InvalidOrder, "55100": InvalidOrder, "55101": InvalidOrder, "55102": InvalidOrder, "55103": InvalidOrder, "55104": InvalidOrder, "55111": InvalidOrder, "55112": InvalidOrder, "55113": InvalidOrder, "58000": ExchangeError, "58001": AuthenticationError, "58002": PermissionDenied, "58003": ExchangeError, "58004": AccountSuspended, "58005": ExchangeError, "58006": ExchangeError, "58007": ExchangeError, "58100": ExchangeError, "58101": AccountSuspended, "58102": RateLimitExceeded, "58103": ExchangeError, "58104": ExchangeError, "58105": ExchangeError, "58106": ExchangeError, "58107": ExchangeError, "58108": ExchangeError, "58109": ExchangeError, "58110": ExchangeError, "58111": ExchangeError, "58112": ExchangeError, "58114": ExchangeError, "58115": ExchangeError, "58116": ExchangeError, "58117": ExchangeError, "58125": BadRequest, "58126": BadRequest, "58127": BadRequest, "58128": BadRequest, "58200": ExchangeError, "58201": ExchangeError, "58202": ExchangeError, "58203": InvalidAddress, "58204": AccountSuspended, "58205": ExchangeError, "58206": ExchangeError, "58207": InvalidAddress, "58208": ExchangeError, "58209": ExchangeError, "58210": ExchangeError, "58211": ExchangeError, "58212": ExchangeError, "58213": AuthenticationError, "58221": BadRequest, "58222": BadRequest, "58224": BadRequest, "58227": BadRequest, "58228": BadRequest, "58229": InsufficientFunds, "58300": ExchangeError, "58350": InsufficientFunds, "59000": ExchangeError, "59001": ExchangeError, "59100": ExchangeError, "59101": ExchangeError, "59102": ExchangeError, "59103": InsufficientFunds, "59104": ExchangeError, "59105": ExchangeError, "59106": ExchangeError, "59107": ExchangeError, "59108": InsufficientFunds, "59109": ExchangeError, "59128": InvalidOrder, "59200": InsufficientFunds, "59201": InsufficientFunds, "59216": BadRequest, "59260": PermissionDenied, "59262": PermissionDenied, "59300": ExchangeError, "59301": ExchangeError, "59313": ExchangeError, "59401": ExchangeError, "59410": OperationRejected, "59411": InsufficientFunds, "59412": OperationRejected, "59413": OperationRejected, "59414": BadRequest, "59500": ExchangeError, "59501": ExchangeError, "59502": ExchangeError, "59503": ExchangeError, "59504": ExchangeError, "59505": ExchangeError, "59506": ExchangeError, "59507": ExchangeError, "59508": AccountSuspended, "59642": BadRequest, "59643": ExchangeError, "60001": AuthenticationError, "60002": AuthenticationError, "60003": AuthenticationError, "60004": AuthenticationError, "60005": AuthenticationError, "60006": InvalidNonce, "60007": AuthenticationError, "60008": AuthenticationError, "60009": AuthenticationError, "60010": AuthenticationError, "60011": AuthenticationError, "60012": BadRequest, "60013": BadRequest, "60014": RateLimitExceeded, "60015": NetworkError, "60016": ExchangeNotAvailable, "60017": BadRequest, "60018": BadRequest, "60019": BadRequest, "60020": ExchangeError, "60021": AccountNotEnabled, "60022": AuthenticationError, "60023": DDoSProtection, "60024": AuthenticationError, "60025": ExchangeError, "60026": AuthenticationError, "60027": ArgumentsRequired, "60028": NotSupported, "60029": AccountNotEnabled, "60030": AccountNotEnabled, "60031": AuthenticationError, "60032": AuthenticationError, "63999": ExchangeError, "64000": BadRequest, "64001": BadRequest, "64002": BadRequest, "64003": AccountNotEnabled, "70010": BadRequest, "70013": BadRequest, "70016": BadRequest, "1009": BadRequest, "4001": AuthenticationError, "4002": BadRequest, "4003": RateLimitExceeded, "4004": NetworkError, "4005": ExchangeNotAvailable, "4006": BadRequest, "4007": AuthenticationError, "4008": RateLimitExceeded, }, "broad": map[string]interface{} { "Internal Server Error": ExchangeNotAvailable, "server error": ExchangeNotAvailable, }, }, "httpExceptions": map[string]interface{} { "429": ExchangeNotAvailable, }, "precisionMode": TICK_SIZE, "options": map[string]interface{} { "sandboxMode": false, "defaultNetwork": "ERC20", "defaultNetworks": map[string]interface{} { "ETH": "ERC20", "BTC": "BTC", "USDT": "TRC20", }, "networks": map[string]interface{} { "BTC": "Bitcoin", "BTCLN": "Lightning", "BEP20": "BSC", "ERC20": "ERC20", "TRC20": "TRC20", "CRC20": "Crypto", "ACA": "Acala", "ALGO": "Algorand", "BHP": "BHP", "APT": "Aptos", "ARBONE": "Arbitrum One", "AVAXC": "Avalanche C-Chain", "AVAXX": "Avalanche X-Chain", "ARK": "ARK", "AR": "Arweave", "ASTR": "Astar", "BCH": "BitcoinCash", "BSV": "Bitcoin SV", "BTM": "Bytom", "ADA": "Cardano", "CSPR": "Casper", "CELO": "CELO", "XCH": "Chia", "CHZ": "Chiliz", "ATOM": "Cosmos", "TRUE": "TrueChain", "DCR": "Decred", "DGB": "Digibyte", "DOGE": "Dogecoin", "XEC": "XEC", "EGLD": "Elrond", "EOS": "EOS", "ETC": "Ethereum Classic", "ETHW": "EthereumPow", "FTM": "Fantom", "FIL": "Filecoin", "FLOW": "FLOW", "FSN": "Fusion", "ONE": "Harmony", "HBAR": "Hedera", "HNT": "Helium", "ZEN": "Horizen", "ICX": "ICON", "ICP": "Dfinity", "IOST": "IOST", "IOTA": "MIOTA", "KDA": "Kadena", "KAR": "KAR", "KLAY": "Klaytn", "KSM": "Kusama", "LSK": "Lisk", "LTC": "Litecoin", "METIS": "Metis", "MINA": "Mina", "XMR": "Monero", "GLRM": "Moonbeam", "MOVR": "Moonriver", "NANO": "Nano", "NEAR": "NEAR", "NAS": "Nebulas", "NEM": "New Economy Movement", "NULS": "NULS", "OASYS": "OASYS", "OKC": "OKC", "ONT": "Ontology", "OPTIMISM": "Optimism", "LAT": "PlatON", "DOT": "Polkadot", "MATIC": "Polygon", "RVN": "Ravencoin", "XRP": "Ripple", "SC": "Siacoin", "SOL": "Solana", "STX": "l-Stacks", "XLM": "Stellar Lumens", "XTZ": "Tezos", "TON": "TON", "THETA": "Theta", "VSYS": "VSYSTEMS", "WAVES": "WAVES", "WAX": "Wax", "ZEC": "Zcash", "ZIL": "Zilliqa", "ZKSYNC": "ZKSYNC", "OMNI": "Omni", }, "fetchOpenInterestHistory": map[string]interface{} { "timeframes": map[string]interface{} { "5m": "5m", "1h": "1H", "8h": "8H", "1d": "1D", "5M": "5m", "1H": "1H", "8H": "8H", "1D": "1D", }, }, "fetchOHLCV": map[string]interface{} { "timezone": "UTC", }, "fetchPositions": map[string]interface{} { "method": "privateGetAccountPositions", }, "createOrder": "privatePostTradeBatchOrders", "createMarketBuyOrderRequiresPrice": false, "fetchMarkets": []interface{}{"spot", "future", "swap", "option"}, "timeDifference": 0, "adjustForTimeDifference": false, "defaultType": "spot", "fetchLedger": map[string]interface{} { "method": "privateGetAccountBills", }, "fetchOrder": map[string]interface{} { "method": "privateGetTradeOrder", }, "fetchOpenOrders": map[string]interface{} { "method": "privateGetTradeOrdersPending", }, "cancelOrders": map[string]interface{} { "method": "privatePostTradeCancelBatchOrders", }, "fetchCanceledOrders": map[string]interface{} { "method": "privateGetTradeOrdersHistory", }, "fetchClosedOrders": map[string]interface{} { "method": "privateGetTradeOrdersHistory", }, "withdraw": map[string]interface{} { "password": nil, "pwd": nil, }, "algoOrderTypes": map[string]interface{} { "conditional": true, "trigger": true, "oco": true, "move_order_stop": true, "iceberg": true, "twap": true, }, "accountsByType": map[string]interface{} { "funding": "6", "trading": "18", "spot": "18", "future": "18", "futures": "18", "margin": "18", "swap": "18", "option": "18", }, "accountsById": map[string]interface{} { "6": "funding", "18": "trading", }, "exchangeType": map[string]interface{} { "spot": "SPOT", "margin": "MARGIN", "swap": "SWAP", "future": "FUTURES", "futures": "FUTURES", "option": "OPTION", "SPOT": "SPOT", "MARGIN": "MARGIN", "SWAP": "SWAP", "FUTURES": "FUTURES", "OPTION": "OPTION", }, "brokerId": "e847386590ce4dBC", }, "features": map[string]interface{} { "default": map[string]interface{} { "sandbox": true, "createOrder": map[string]interface{} { "marginMode": true, "triggerPrice": true, "triggerPriceType": map[string]interface{} { "last": true, "mark": true, "index": true, }, "triggerDirection": false, "stopLossPrice": true, "takeProfitPrice": true, "attachedStopLossTakeProfit": map[string]interface{} { "triggerPriceType": map[string]interface{} { "last": true, "mark": true, "index": true, }, "price": true, }, "timeInForce": map[string]interface{} { "IOC": true, "FOK": true, "PO": true, "GTD": false, }, "hedged": true, "trailing": true, "iceberg": true, "leverage": false, "selfTradePrevention": true, "marketBuyByCost": true, "marketBuyRequiresPrice": false, }, "createOrders": map[string]interface{} { "max": 20, }, "fetchMyTrades": map[string]interface{} { "marginMode": false, "daysBack": 90, "limit": 100, "untilDays": 10000, "symbolRequired": false, }, "fetchOrder": map[string]interface{} { "marginMode": false, "trigger": true, "trailing": true, "symbolRequired": true, }, "fetchOpenOrders": map[string]interface{} { "marginMode": false, "limit": 100, "trigger": true, "trailing": true, "symbolRequired": false, }, "fetchOrders": nil, "fetchClosedOrders": map[string]interface{} { "marginMode": false, "limit": 100, "daysBack": 90, "daysBackCanceled": Divide(1, 12), "untilDays": nil, "trigger": true, "trailing": true, "symbolRequired": false, }, "fetchOHLCV": map[string]interface{} { "limit": 300, }, }, "spot": map[string]interface{} { "extends": "default", }, "swap": map[string]interface{} { "linear": map[string]interface{} { "extends": "default", }, "inverse": map[string]interface{} { "extends": "default", }, }, "future": map[string]interface{} { "linear": map[string]interface{} { "extends": "default", }, "inverse": map[string]interface{} { "extends": "default", }, }, }, "commonCurrencies": map[string]interface{} { "AE": "AET", "WIN": "WINTOKEN", }, }) } func (this *okx) HandleMarketTypeAndParams(methodName interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params defaultValue := GetArg(optionalArgs, 2, nil) _ = defaultValue var instType interface{} = this.SafeString(params, "instType") params = this.Omit(params, "instType") var typeVar interface{} = this.SafeString(params, "type") if IsTrue(IsTrue((IsEqual(typeVar, nil))) && IsTrue((!IsEqual(instType, nil)))) { AddElementToObject(params, "type", instType) } return this.Exchange.HandleMarketTypeAndParams(methodName, market, params, defaultValue) } func (this *okx) ConvertToInstrumentType(typeVar interface{}) interface{} { var exchangeTypes interface{} = this.SafeDict(this.Options, "exchangeType", map[string]interface{} {}) return this.SafeString(exchangeTypes, typeVar, typeVar) } func (this *okx) CreateExpiredOptionMarket(symbol interface{}) interface{} { // support expired option contracts var quote interface{} = "USD" var optionParts interface{} = Split(symbol, "-") var symbolBase interface{} = Split(symbol, "/") var base interface{} = nil if IsTrue(IsGreaterThan(GetIndexOf(symbol, "/"), OpNeg(1))) { base = this.SafeString(symbolBase, 0) } else { base = this.SafeString(optionParts, 0) } var settle interface{} = base var expiry interface{} = this.SafeString(optionParts, 2) var strike interface{} = this.SafeString(optionParts, 3) var optionType interface{} = this.SafeString(optionParts, 4) var datetime interface{} = this.ConvertExpireDate(expiry) var timestamp interface{} = this.Parse8601(datetime) return map[string]interface{} { "id": Add(Add(Add(Add(Add(Add(Add(Add(base, "-"), quote), "-"), expiry), "-"), strike), "-"), optionType), "symbol": Add(Add(Add(Add(Add(Add(Add(Add(Add(Add(base, "/"), quote), ":"), settle), "-"), expiry), "-"), strike), "-"), optionType), "base": base, "quote": quote, "settle": settle, "baseId": base, "quoteId": quote, "settleId": settle, "active": false, "type": "option", "linear": nil, "inverse": nil, "spot": false, "swap": false, "future": false, "option": true, "margin": false, "contract": true, "contractSize": this.ParseNumber("1"), "expiry": timestamp, "expiryDatetime": datetime, "optionType": Ternary(IsTrue((IsEqual(optionType, "C"))), "call", "put"), "strike": this.ParseNumber(strike), "precision": map[string]interface{} { "amount": nil, "price": nil, }, "limits": map[string]interface{} { "amount": map[string]interface{} { "min": nil, "max": nil, }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": nil, "max": nil, }, }, "info": nil, } } func (this *okx) SafeMarket(optionalArgs ...interface{}) interface{} { marketId := GetArg(optionalArgs, 0, nil) _ = marketId market := GetArg(optionalArgs, 1, nil) _ = market delimiter := GetArg(optionalArgs, 2, nil) _ = delimiter marketType := GetArg(optionalArgs, 3, nil) _ = marketType var isOption interface{} = IsTrue((!IsEqual(marketId, nil))) && IsTrue((IsTrue((IsGreaterThan(GetIndexOf(marketId, "-C"), OpNeg(1)))) || IsTrue((IsGreaterThan(GetIndexOf(marketId, "-P"), OpNeg(1)))))) if IsTrue(IsTrue(isOption) && !IsTrue((InOp(this.Markets_by_id, marketId)))) { // handle expired option contracts return this.CreateExpiredOptionMarket(marketId) } return this.Exchange.SafeMarket(marketId, market, delimiter, marketType) } /** * @method * @name okx#fetchStatus * @description the latest known information on the availability of the exchange API * @see https://www.okx.com/docs-v5/en/#status-get-status * @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 *okx) 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.PublicGetSystemStatus(params)) PanicOnError(response) // // Note, if there is no maintenance around, the 'data' array is empty // // { // "code": "0", // "msg": "", // "data": [ // { // "begin": "1621328400000", // "end": "1621329000000", // "href": "https://www.okx.com/support/hc/en-us/articles/360060882172", // "scheDesc": "", // "serviceType": "1", // 0 WebSocket, 1 Spot/Margin, 2 Futures, 3 Perpetual, 4 Options, 5 Trading service // "state": "scheduled", // ongoing, completed, canceled // "system": "classic", // classic, unified // "title": "Classic Spot System Upgrade" // }, // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var dataLength interface{} = GetArrayLength(data) var update interface{} = map[string]interface{} { "updated": nil, "status": Ternary(IsTrue((IsEqual(dataLength, 0))), "ok", "maintenance"), "eta": nil, "url": nil, "info": response, } for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var event interface{} = GetValue(data, i) var state interface{} = this.SafeString(event, "state") AddElementToObject(update, "eta", this.SafeInteger(event, "end")) AddElementToObject(update, "url", this.SafeString(event, "href")) if IsTrue(IsEqual(state, "ongoing")) { AddElementToObject(update, "status", "maintenance") } else if IsTrue(IsEqual(state, "scheduled")) { AddElementToObject(update, "status", "ok") } else if IsTrue(IsEqual(state, "completed")) { AddElementToObject(update, "status", "ok") } else if IsTrue(IsEqual(state, "canceled")) { AddElementToObject(update, "status", "ok") } } ch <- update return nil }() return ch } /** * @method * @name okx#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @see https://www.okx.com/docs-v5/en/#public-data-rest-api-get-system-time * @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 *okx) 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.PublicGetPublicTime(params)) PanicOnError(response) // // { // "code": "0", // "data": [ // {"ts": "1621247923668"} // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var first interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.SafeInteger(first, "ts") return nil }() return ch } /** * @method * @name okx#fetchAccounts * @description fetch all the accounts associated with a profile * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-account-configuration * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type */ func (this *okx) FetchAccounts(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.PrivateGetAccountConfig(params)) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "acctLv": "2", // "autoLoan": false, // "ctIsoMode": "automatic", // "greeksType": "PA", // "level": "Lv1", // "levelTmp": "", // "mgnIsoMode": "automatic", // "posMode": "long_short_mode", // "uid": "88018754289672195" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var account interface{} = GetValue(data, i) var accountId interface{} = this.SafeString(account, "uid") var typeVar interface{} = this.SafeString(account, "acctLv") AppendToArray(&result,map[string]interface{} { "id": accountId, "type": typeVar, "currency": nil, "info": account, "code": nil, }) } ch <- result return nil }() return ch } func (this *okx) Nonce() interface{} { return Subtract(this.Milliseconds(), GetValue(this.Options, "timeDifference")) } /** * @method * @name okx#fetchMarkets * @description retrieves data on all markets for okx * @see https://www.okx.com/docs-v5/en/#rest-api-public-data-get-instruments * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *okx) 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 if IsTrue(GetValue(this.Options, "adjustForTimeDifference")) { retRes151512 := (<-this.LoadTimeDifference()) PanicOnError(retRes151512) } var types interface{} = this.SafeList(this.Options, "fetchMarkets", []interface{}{}) var promises interface{} = []interface{}{} var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(types)); i++ { AppendToArray(&promises,this.FetchMarketsByType(GetValue(types, i), params)) } promises = (<-promiseAll(promises)) PanicOnError(promises) for i := 0; IsLessThan(i, GetArrayLength(promises)); i++ { result = this.ArrayConcat(result, GetValue(promises, i)) } ch <- result return nil }() return ch } func (this *okx) ParseMarket(market interface{}) interface{} { // // { // "alias": "", // this_week, next_week, quarter, next_quarter // "baseCcy": "BTC", // "category": "1", // "ctMult": "", // "ctType": "", // inverse, linear // "ctVal": "", // "ctValCcy": "", // "expTime": "", // "instId": "BTC-USDT", // BTC-USD-210521, CSPR-USDT-SWAP, BTC-USD-210517-44000-C // "instType": "SPOT", // SPOT, FUTURES, SWAP, OPTION // "lever": "10", // "listTime": "1548133413000", // "lotSz": "0.00000001", // "minSz": "0.00001", // "optType": "", // "quoteCcy": "USDT", // "settleCcy": "", // "state": "live", // "stk": "", // "tickSz": "0.1", // "uly": "" // } // // { // "alias": "", // "baseCcy": "", // "category": "1", // "ctMult": "0.1", // "ctType": "", // "ctVal": "1", // "ctValCcy": "BTC", // "expTime": "1648195200000", // "instId": "BTC-USD-220325-194000-P", // "instType": "OPTION", // "lever": "", // "listTime": "1631262612280", // "lotSz": "1", // "minSz": "1", // "optType": "P", // "quoteCcy": "", // "settleCcy": "BTC", // "state": "live", // "stk": "194000", // "tickSz": "0.0005", // "uly": "BTC-USD" // } // var id interface{} = this.SafeString(market, "instId") var typeVar interface{} = this.SafeStringLower(market, "instType") if IsTrue(IsEqual(typeVar, "futures")) { typeVar = "future" } var spot interface{} = (IsEqual(typeVar, "spot")) var future interface{} = (IsEqual(typeVar, "future")) var swap interface{} = (IsEqual(typeVar, "swap")) var option interface{} = (IsEqual(typeVar, "option")) var contract interface{} = IsTrue(IsTrue(swap) || IsTrue(future)) || IsTrue(option) var baseId interface{} = this.SafeString(market, "baseCcy") var quoteId interface{} = this.SafeString(market, "quoteCcy") var settleId interface{} = this.SafeString(market, "settleCcy") var settle interface{} = this.SafeCurrencyCode(settleId) var underlying interface{} = this.SafeString(market, "uly") if IsTrue(IsTrue((!IsEqual(underlying, nil))) && !IsTrue(spot)) { var parts interface{} = Split(underlying, "-") baseId = this.SafeString(parts, 0) quoteId = this.SafeString(parts, 1) } var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) var symbol interface{} = Add(Add(base, "/"), quote) var expiry interface{} = nil var strikePrice interface{} = nil var optionType interface{} = nil if IsTrue(contract) { symbol = Add(Add(symbol, ":"), settle) expiry = this.SafeInteger(market, "expTime") if IsTrue(future) { var ymd interface{} = this.Yymmdd(expiry) symbol = Add(Add(symbol, "-"), ymd) } else if IsTrue(option) { strikePrice = this.SafeString(market, "stk") optionType = this.SafeString(market, "optType") var ymd interface{} = this.Yymmdd(expiry) symbol = Add(Add(Add(Add(Add(Add(symbol, "-"), ymd), "-"), strikePrice), "-"), optionType) optionType = Ternary(IsTrue((IsEqual(optionType, "P"))), "put", "call") } } var tickSize interface{} = this.SafeString(market, "tickSz") var fees interface{} = this.SafeDict2(this.Fees, typeVar, "trading", map[string]interface{} {}) var maxLeverage interface{} = this.SafeString(market, "lever", "1") maxLeverage = Precise.StringMax(maxLeverage, "1") var maxSpotCost interface{} = this.SafeNumber(market, "maxMktSz") return this.Extend(fees, map[string]interface{} { "id": id, "symbol": symbol, "base": base, "quote": quote, "settle": settle, "baseId": baseId, "quoteId": quoteId, "settleId": settleId, "type": typeVar, "spot": spot, "margin": IsTrue(spot) && IsTrue((Precise.StringGt(maxLeverage, "1"))), "swap": swap, "future": future, "option": option, "active": true, "contract": contract, "linear": Ternary(IsTrue(contract), (IsEqual(quoteId, settleId)), nil), "inverse": Ternary(IsTrue(contract), (IsEqual(baseId, settleId)), nil), "contractSize": Ternary(IsTrue(contract), this.SafeNumber(market, "ctVal"), nil), "expiry": expiry, "expiryDatetime": this.Iso8601(expiry), "strike": this.ParseNumber(strikePrice), "optionType": optionType, "created": this.SafeInteger(market, "listTime"), "precision": map[string]interface{} { "amount": this.SafeNumber(market, "lotSz"), "price": this.ParseNumber(tickSize), }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": this.ParseNumber("1"), "max": this.ParseNumber(maxLeverage), }, "amount": map[string]interface{} { "min": this.SafeNumber(market, "minSz"), "max": nil, }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": nil, "max": Ternary(IsTrue(contract), nil, maxSpotCost), }, }, "info": market, }) } func (this *okx) FetchMarketsByType(typeVar 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 var request interface{} = map[string]interface{} { "instType": this.ConvertToInstrumentType(typeVar), } if IsTrue(IsEqual(typeVar, "option")) { var optionsUnderlying interface{} = this.SafeList(this.Options, "defaultUnderlying", []interface{}{"BTC-USD", "ETH-USD"}) var promises interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(optionsUnderlying)); i++ { var underlying interface{} = GetValue(optionsUnderlying, i) AddElementToObject(request, "uly", underlying) AppendToArray(&promises,this.PublicGetPublicInstruments(this.Extend(request, params))) } promisesResult:= (<-promiseAll(promises)) PanicOnError(promisesResult) var markets interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(promisesResult)); i++ { var res interface{} = this.SafeDict(promisesResult, i, map[string]interface{} {}) var options interface{} = this.SafeList(res, "data", []interface{}{}) markets = this.ArrayConcat(markets, options) } ch <- this.ParseMarkets(markets) return nil } response:= (<-this.PublicGetPublicInstruments(this.Extend(request, params))) PanicOnError(response) // // spot, future, swap, option // // { // "code": "0", // "data": [ // { // "alias": "", // this_week, next_week, quarter, next_quarter // "baseCcy": "BTC", // "category": "1", // "ctMult": "", // "ctType": "", // inverse, linear // "ctVal": "", // "ctValCcy": "", // "expTime": "", // "instId": "BTC-USDT", // BTC-USD-210521, CSPR-USDT-SWAP, BTC-USD-210517-44000-C // "instType": "SPOT", // SPOT, FUTURES, SWAP, OPTION // "lever": "10", // "listTime": "1548133413000", // "lotSz": "0.00000001", // "minSz": "0.00001", // "optType": "", // "quoteCcy": "USDT", // "settleCcy": "", // "state": "live", // "stk": "", // "tickSz": "0.1", // "uly": "" // } // ], // "msg": "" // } // var dataResponse interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseMarkets(dataResponse) return nil }() return ch } /** * @method * @name okx#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://www.okx.com/docs-v5/en/#rest-api-funding-get-currencies * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ func (this *okx) FetchCurrencies(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // this endpoint requires authentication // while fetchCurrencies is a public API method by design // therefore we check the keys here // and fallback to generating the currencies from the markets params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var isSandboxMode interface{} = this.SafeBool(this.Options, "sandboxMode", false) if IsTrue(!IsTrue(this.CheckRequiredCredentials(false)) || IsTrue(isSandboxMode)) { return nil } // // has['fetchCurrencies'] is currently set to true, but an unauthorized request returns // // {"msg":"Request header “OK_ACCESS_KEY“ can't be empty.","code":"50103"} // response:= (<-this.PrivateGetAssetCurrencies(params)) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "canDep": true, // "canInternal": false, // "canWd": true, // "ccy": "USDT", // "chain": "USDT-TRC20", // "logoLink": "https://static.coinall.ltd/cdn/assets/imgs/221/5F74EB20302D7761.png", // "mainNet": false, // "maxFee": "1.6", // "maxWd": "8852150", // "minFee": "0.8", // "minWd": "2", // "name": "Tether", // "usedWdQuota": "0", // "wdQuota": "500", // "wdTickSz": "3" // }, // { // "canDep": true, // "canInternal": false, // "canWd": true, // "ccy": "USDT", // "chain": "USDT-ERC20", // "logoLink": "https://static.coinall.ltd/cdn/assets/imgs/221/5F74EB20302D7761.png", // "mainNet": false, // "maxFee": "16", // "maxWd": "8852150", // "minFee": "8", // "minWd": "2", // "name": "Tether", // "usedWdQuota": "0", // "wdQuota": "500", // "wdTickSz": "3" // }, // ... // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var result interface{} = map[string]interface{} {} var dataByCurrencyId interface{} = this.GroupBy(data, "ccy") var currencyIds interface{} = ObjectKeys(dataByCurrencyId) for i := 0; IsLessThan(i, GetArrayLength(currencyIds)); i++ { var currencyId interface{} = GetValue(currencyIds, i) var currency interface{} = this.SafeCurrency(currencyId) var code interface{} = GetValue(currency, "code") var chains interface{} = GetValue(dataByCurrencyId, currencyId) var networks interface{} = map[string]interface{} {} var currencyActive interface{} = false var depositEnabled interface{} = false var withdrawEnabled interface{} = false var maxPrecision interface{} = nil for j := 0; IsLessThan(j, GetArrayLength(chains)); j++ { var chain interface{} = GetValue(chains, j) var canDeposit interface{} = this.SafeBool(chain, "canDep") depositEnabled = Ternary(IsTrue((canDeposit)), canDeposit, depositEnabled) var canWithdraw interface{} = this.SafeBool(chain, "canWd") withdrawEnabled = Ternary(IsTrue((canWithdraw)), canWithdraw, withdrawEnabled) var canInternal interface{} = this.SafeBool(chain, "canInternal") var active interface{} = Ternary(IsTrue((IsTrue(IsTrue(canDeposit) && IsTrue(canWithdraw)) && IsTrue(canInternal))), true, false) currencyActive = Ternary(IsTrue((active)), active, currencyActive) var networkId interface{} = this.SafeString(chain, "chain") if IsTrue(IsTrue((!IsEqual(networkId, nil))) && IsTrue((IsGreaterThanOrEqual(GetIndexOf(networkId, "-"), 0)))) { var idParts interface{} = Split(networkId, "-") var parts interface{} = this.ArraySlice(idParts, 1) var chainPart interface{} = Join(parts, "-") var networkCode interface{} = this.NetworkIdToCode(chainPart, GetValue(currency, "code")) var precision interface{} = this.ParsePrecision(this.SafeString(chain, "wdTickSz")) if IsTrue(IsEqual(maxPrecision, nil)) { maxPrecision = precision } else { maxPrecision = Precise.StringMin(maxPrecision, precision) } AddElementToObject(networks, networkCode, map[string]interface{} { "id": networkId, "network": networkCode, "active": active, "deposit": canDeposit, "withdraw": canWithdraw, "fee": this.SafeNumber(chain, "fee"), "precision": this.ParseNumber(precision), "limits": map[string]interface{} { "withdraw": map[string]interface{} { "min": this.SafeNumber(chain, "minWd"), "max": this.SafeNumber(chain, "maxWd"), }, }, "info": chain, }) } } var firstChain interface{} = this.SafeDict(chains, 0, map[string]interface{} {}) AddElementToObject(result, code, map[string]interface{} { "info": chains, "code": code, "id": currencyId, "name": this.SafeString(firstChain, "name"), "active": currencyActive, "deposit": depositEnabled, "withdraw": withdrawEnabled, "fee": nil, "precision": this.ParseNumber(maxPrecision), "limits": map[string]interface{} { "amount": map[string]interface{} { "min": nil, "max": nil, }, }, "networks": networks, }) } ch <- result return nil }() return ch } /** * @method * @name okx#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-order-book * @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 * @param {string} [params.method] 'publicGetMarketBooksFull' or 'publicGetMarketBooks' default is 'publicGetMarketBooks' * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ func (this *okx) 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 retRes18898 := (<-this.LoadMarkets()) PanicOnError(retRes18898) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } var method interface{} = nil methodparamsVariable := this.HandleOptionAndParams(params, "fetchOrderBook", "method", "publicGetMarketBooks"); method = GetValue(methodparamsVariable,0); params = GetValue(methodparamsVariable,1) if IsTrue(IsTrue(IsEqual(method, "publicGetMarketBooksFull")) && IsTrue(IsEqual(limit, nil))) { limit = 5000 } limit = Ternary(IsTrue((IsEqual(limit, nil))), 100, limit) if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "sz", limit) // max 400 } var response interface{} = nil if IsTrue(IsTrue((IsEqual(method, "publicGetMarketBooksFull"))) || IsTrue((IsGreaterThan(limit, 400)))) { response = (<-this.PublicGetMarketBooksFull(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PublicGetMarketBooks(this.Extend(request, params))) PanicOnError(response) } // // { // "code": "0", // "msg": "", // "data": [ // { // "asks": [ // ["0.07228","4.211619","0","2"], // price, amount, liquidated orders, total open orders // ["0.0723","299.880364","0","2"], // ["0.07231","3.72832","0","1"], // ], // "bids": [ // ["0.07221","18.5","0","1"], // ["0.0722","18.5","0","1"], // ["0.07219","0.505407","0","1"], // ], // "ts": "1621438475342" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var first interface{} = this.SafeDict(data, 0, map[string]interface{} {}) var timestamp interface{} = this.SafeInteger(first, "ts") ch <- this.ParseOrderBook(first, symbol, timestamp) return nil }() return ch } func (this *okx) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // { // "instType":"SWAP", // "instId":"BTC-USDT-SWAP", // "markPx":"200", // "ts":"1597026383085" // } // // { // "instType": "SPOT", // "instId": "ETH-BTC", // "last": "0.07319", // "lastSz": "0.044378", // "askPx": "0.07322", // "askSz": "4.2", // "bidPx": "0.0732", // "bidSz": "6.050058", // "open24h": "0.07801", // "high24h": "0.07975", // "low24h": "0.06019", // "volCcy24h": "11788.887619", // "vol24h": "167493.829229", // "ts": "1621440583784", // "sodUtc0": "0.07872", // "sodUtc8": "0.07345" // } // { // instId: 'LTC-USDT', // idxPx: '65.74', // open24h: '65.37', // high24h: '66.15', // low24h: '64.97', // sodUtc0: '65.68', // sodUtc8: '65.54', // ts: '1728467346900' // }, // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeInteger(ticker, "ts") var marketId interface{} = this.SafeString(ticker, "instId") market = this.SafeMarket(marketId, market, "-") var symbol interface{} = GetValue(market, "symbol") var last interface{} = this.SafeString(ticker, "last") var open interface{} = this.SafeString(ticker, "open24h") var spot interface{} = this.SafeBool(market, "spot", false) var quoteVolume interface{} = Ternary(IsTrue(spot), this.SafeString(ticker, "volCcy24h"), nil) var baseVolume interface{} = this.SafeString(ticker, "vol24h") var high interface{} = this.SafeString(ticker, "high24h") var low interface{} = this.SafeString(ticker, "low24h") return this.SafeTicker(map[string]interface{} { "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "high": high, "low": low, "bid": this.SafeString(ticker, "bidPx"), "bidVolume": this.SafeString(ticker, "bidSz"), "ask": this.SafeString(ticker, "askPx"), "askVolume": this.SafeString(ticker, "askSz"), "vwap": nil, "open": open, "close": last, "last": last, "previousClose": nil, "change": nil, "percentage": nil, "average": nil, "baseVolume": baseVolume, "quoteVolume": quoteVolume, "markPrice": this.SafeString(ticker, "markPx"), "indexPrice": this.SafeString(ticker, "idxPx"), "info": ticker, }, market) } /** * @method * @name okx#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-ticker * @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 *okx) 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 retRes20218 := (<-this.LoadMarkets()) PanicOnError(retRes20218) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } response:= (<-this.PublicGetMarketTicker(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "", // "data": [ // { // "instType": "SPOT", // "instId": "ETH-BTC", // "last": "0.07319", // "lastSz": "0.044378", // "askPx": "0.07322", // "askSz": "4.2", // "bidPx": "0.0732", // "bidSz": "6.050058", // "open24h": "0.07801", // "high24h": "0.07975", // "low24h": "0.06019", // "volCcy24h": "11788.887619", // "vol24h": "167493.829229", // "ts": "1621440583784", // "sodUtc0": "0.07872", // "sodUtc8": "0.07345" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var first interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseTicker(first, market) return nil }() return ch } /** * @method * @name okx#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers * @param {string[]} [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 *okx) 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 retRes20688 := (<-this.LoadMarkets()) PanicOnError(retRes20688) symbols = this.MarketSymbols(symbols) var market interface{} = this.GetMarketFromSymbols(symbols) var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchTickers", market, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var request interface{} = map[string]interface{} { "instType": this.ConvertToInstrumentType(marketType), } if IsTrue(IsEqual(marketType, "option")) { var defaultUnderlying interface{} = this.SafeString(this.Options, "defaultUnderlying", "BTC-USD") var currencyId interface{} = this.SafeString2(params, "uly", "marketId", defaultUnderlying) if IsTrue(IsEqual(currencyId, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchTickers() requires an underlying uly or marketId parameter for options markets"))) } else { AddElementToObject(request, "uly", currencyId) } } response:= (<-this.PublicGetMarketTickers(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "", // "data": [ // { // "instType": "SPOT", // "instId": "BCD-BTC", // "last": "0.0000769", // "lastSz": "5.4788", // "askPx": "0.0000777", // "askSz": "3.2197", // "bidPx": "0.0000757", // "bidSz": "4.7509", // "open24h": "0.0000885", // "high24h": "0.0000917", // "low24h": "0.0000596", // "volCcy24h": "9.2877", // "vol24h": "124824.1985", // "ts": "1621441741434", // "sodUtc0": "0.0000905", // "sodUtc8": "0.0000729" // }, // ] // } // var tickers interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTickers(tickers, symbols) return nil }() return ch } /** * @method * @name okx#fetchMarkPrice * @description fetches mark price for the market * @see https://www.okx.com/docs-v5/en/#public-data-rest-api-get-mark-price * @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 dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ func (this *okx) FetchMarkPrice(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 retRes21268 := (<-this.LoadMarkets()) PanicOnError(retRes21268) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } response:= (<-this.PublicGetPublicMarkPrice(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "instId": "ETH-USDT", // "instType": "MARGIN", // "markPx": "2403.98", // "ts": "1728578500703" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data") ch <- this.ParseTicker(this.SafeDict(data, 0), market) return nil }() return ch } /** * @method * @name okx#fetchMarkPrices * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://www.okx.com/docs-v5/en/#public-data-rest-api-get-mark-price * @param {string[]} [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 *okx) FetchMarkPrices(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 retRes21608 := (<-this.LoadMarkets()) PanicOnError(retRes21608) symbols = this.MarketSymbols(symbols) var market interface{} = this.GetMarketFromSymbols(symbols) var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchTickers", market, params, "swap"); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var request interface{} = map[string]interface{} { "instType": this.ConvertToInstrumentType(marketType), } if IsTrue(IsEqual(marketType, "option")) { var defaultUnderlying interface{} = this.SafeString(this.Options, "defaultUnderlying", "BTC-USD") var currencyId interface{} = this.SafeString2(params, "uly", "marketId", defaultUnderlying) if IsTrue(IsEqual(currencyId, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchMarkPrices() requires an underlying uly or marketId parameter for options markets"))) } else { AddElementToObject(request, "uly", currencyId) } } response:= (<-this.PublicGetPublicMarkPrice(this.Extend(request, params))) PanicOnError(response) var tickers interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTickers(tickers, symbols) return nil }() return ch } func (this *okx) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // public fetchTrades // // { // "instId": "ETH-BTC", // "side": "sell", // "sz": "0.119501", // "px": "0.07065", // "tradeId": "15826757", // "ts": "1621446178316" // } // // option: fetchTrades // // { // "fillVol": "0.46387625976562497", // "fwdPx": "26299.754935451125", // "indexPx": "26309.7", // "instFamily": "BTC-USD", // "instId": "BTC-USD-230526-26000-C", // "markPx": "0.042386283557554236", // "optType": "C", // "px": "0.0415", // "side": "sell", // "sz": "90", // "tradeId": "112", // "ts": "1683907480154" // } // // private fetchMyTrades // // { // "side": "buy", // "fillSz": "0.007533", // "fillPx": "2654.98", // "fee": "-0.000007533", // "ordId": "317321390244397056", // "instType": "SPOT", // "instId": "ETH-USDT", // "clOrdId": "", // "posSide": "net", // "billId": "317321390265368576", // "tag": "0", // "execType": "T", // "tradeId": "107601752", // "feeCcy": "ETH", // "ts": "1621927314985" // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString(trade, "tradeId") var marketId interface{} = this.SafeString(trade, "instId") market = this.SafeMarket(marketId, market, "-") var symbol interface{} = GetValue(market, "symbol") var timestamp interface{} = this.SafeInteger(trade, "ts") var price interface{} = this.SafeString2(trade, "fillPx", "px") var amount interface{} = this.SafeString2(trade, "fillSz", "sz") var side interface{} = this.SafeString(trade, "side") var orderId interface{} = this.SafeString(trade, "ordId") var feeCostString interface{} = this.SafeString(trade, "fee") var fee interface{} = nil if IsTrue(!IsEqual(feeCostString, nil)) { var feeCostSigned interface{} = Precise.StringNeg(feeCostString) var feeCurrencyId interface{} = this.SafeString(trade, "feeCcy") var feeCurrencyCode interface{} = this.SafeCurrencyCode(feeCurrencyId) fee = map[string]interface{} { "cost": feeCostSigned, "currency": feeCurrencyCode, } } var takerOrMaker interface{} = this.SafeString(trade, "execType") if IsTrue(IsEqual(takerOrMaker, "T")) { takerOrMaker = "taker" } else if IsTrue(IsEqual(takerOrMaker, "M")) { takerOrMaker = "maker" } return this.SafeTrade(map[string]interface{} { "info": trade, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "symbol": symbol, "id": id, "order": orderId, "type": nil, "takerOrMaker": takerOrMaker, "side": side, "price": price, "amount": amount, "cost": nil, "fee": fee, }, market) } /** * @method * @name okx#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://www.okx.com/docs-v5/en/#rest-api-market-data-get-trades * @see https://www.okx.com/docs-v5/en/#rest-api-public-data-get-option-trades * @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 {string} [params.method] 'publicGetMarketTrades' or 'publicGetMarketHistoryTrades' default is 'publicGetMarketTrades' * @param {boolean} [params.paginate] *only applies to publicGetMarketHistoryTrades* 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 *okx) 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 retRes22908 := (<-this.LoadMarkets()) PanicOnError(retRes22908) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes229419 := (<-this.FetchPaginatedCallCursor("fetchTrades", symbol, since, limit, params, "tradeId", "after", nil, 100)) PanicOnError(retRes229419) ch <- retRes229419 return nil } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } var response interface{} = nil if IsTrue(GetValue(market, "option")) { response = (<-this.PublicGetPublicOptionTrades(this.Extend(request, params))) PanicOnError(response) } else { if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100 } var method interface{} = nil methodparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "method", "publicGetMarketTrades"); method = GetValue(methodparamsVariable,0); params = GetValue(methodparamsVariable,1) if IsTrue(IsEqual(method, "publicGetMarketTrades")) { response = (<-this.PublicGetMarketTrades(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(method, "publicGetMarketHistoryTrades")) { response = (<-this.PublicGetMarketHistoryTrades(this.Extend(request, params))) PanicOnError(response) } } // // { // "code": "0", // "msg": "", // "data": [ // {"instId":"ETH-BTC","side":"sell","sz":"0.119501","px":"0.07065","tradeId":"15826757","ts":"1621446178316"}, // {"instId":"ETH-BTC","side":"sell","sz":"0.03","px":"0.07068","tradeId":"15826756","ts":"1621446178066"}, // {"instId":"ETH-BTC","side":"buy","sz":"0.507","px":"0.07069","tradeId":"15826755","ts":"1621446175085"}, // ] // } // // option // // { // "code": "0", // "data": [ // { // "fillVol": "0.46387625976562497", // "fwdPx": "26299.754935451125", // "indexPx": "26309.7", // "instFamily": "BTC-USD", // "instId": "BTC-USD-230526-26000-C", // "markPx": "0.042386283557554236", // "optType": "C", // "px": "0.0415", // "side": "sell", // "sz": "90", // "tradeId": "112", // "ts": "1683907480154" // }, // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTrades(data, market, since, limit) return nil }() return ch } func (this *okx) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { // // [ // "1678928760000", // timestamp // "24341.4", // open // "24344", // high // "24313.2", // low // "24323", // close // "628", // contract volume // "2.5819", // base volume // "62800", // quote volume // "0" // candlestick state // ] // market := GetArg(optionalArgs, 0, nil) _ = market var res interface{} = this.HandleMarketTypeAndParams("fetchOHLCV", market, nil) var typeVar interface{} = GetValue(res, 0) var volumeIndex interface{} = Ternary(IsTrue((IsEqual(typeVar, "spot"))), 5, 6) 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, volumeIndex)} } /** * @method * @name okx#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://www.okx.com/docs-v5/en/#rest-api-market-data-get-candlesticks * @see https://www.okx.com/docs-v5/en/#rest-api-market-data-get-candlesticks-history * @see https://www.okx.com/docs-v5/en/#rest-api-market-data-get-mark-price-candlesticks * @see https://www.okx.com/docs-v5/en/#rest-api-market-data-get-mark-price-candlesticks-history * @see https://www.okx.com/docs-v5/en/#rest-api-market-data-get-index-candlesticks * @see https://www.okx.com/docs-v5/en/#rest-api-market-data-get-index-candlesticks-history * @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 {string} [params.price] "mark" or "index" for mark price and index price candles * @param {int} [params.until] timestamp in ms of the latest candle to fetch * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *okx) 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 retRes24018 := (<-this.LoadMarkets()) PanicOnError(retRes24018) var market interface{} = this.Market(symbol) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes240619 := (<-this.FetchPaginatedCallDeterministic("fetchOHLCV", symbol, since, limit, timeframe, params, 200)) PanicOnError(retRes240619) ch <- retRes240619 return nil } var price interface{} = this.SafeString(params, "price") params = this.Omit(params, "price") var options interface{} = this.SafeDict(this.Options, "fetchOHLCV", map[string]interface{} {}) var timezone interface{} = this.SafeString(options, "timezone", "UTC") if IsTrue(IsEqual(limit, nil)) { limit = 100 // default 100, max 100 } var duration interface{} = this.ParseTimeframe(timeframe) var bar interface{} = this.SafeString(this.Timeframes, timeframe, timeframe) if IsTrue(IsTrue((IsEqual(timezone, "UTC"))) && IsTrue((IsGreaterThanOrEqual(duration, 21600)))) { bar = Add(bar, ToLower(timezone)) } var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), "bar": bar, "limit": limit, } var defaultType interface{} = "Candles" if IsTrue(!IsEqual(since, nil)) { var now interface{} = this.Milliseconds() var durationInMilliseconds interface{} = Multiply(duration, 1000) // switch to history candles if since is past the cutoff for current candles var historyBorder interface{} = Subtract(now, (Multiply((Subtract(1440, 1)), durationInMilliseconds))) if IsTrue(IsLessThan(since, historyBorder)) { defaultType = "HistoryCandles" } var startTime interface{} = mathMax(Subtract(since, 1), 0) AddElementToObject(request, "before", startTime) AddElementToObject(request, "after", this.Sum(since, Multiply(durationInMilliseconds, limit))) } var until interface{} = this.SafeInteger(params, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "after", until) params = this.Omit(params, "until") } defaultType = this.SafeString(options, "type", defaultType) // Candles or HistoryCandles var typeVar interface{} = this.SafeString(params, "type", defaultType) params = this.Omit(params, "type") var isHistoryCandles interface{} = (IsEqual(typeVar, "HistoryCandles")) var response interface{} = nil if IsTrue(IsEqual(price, "mark")) { if IsTrue(isHistoryCandles) { response = (<-this.PublicGetMarketHistoryMarkPriceCandles(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PublicGetMarketMarkPriceCandles(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(IsEqual(price, "index")) { AddElementToObject(request, "instId", GetValue(GetValue(market, "info"), "instFamily")) // okx index candles require instFamily instead of instId if IsTrue(isHistoryCandles) { response = (<-this.PublicGetMarketHistoryIndexCandles(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PublicGetMarketIndexCandles(this.Extend(request, params))) PanicOnError(response) } } else { if IsTrue(isHistoryCandles) { response = (<-this.PublicGetMarketHistoryCandles(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PublicGetMarketCandles(this.Extend(request, params))) PanicOnError(response) } } // // { // "code": "0", // "msg": "", // "data": [ // ["1678928760000","24341.4","24344","24313.2","24323","628","2.5819","62800","0"], // ["1678928700000","24324.1","24347.6","24321.7","24341.4","2565","10.5401","256500","1"], // ["1678928640000","24300.2","24324.1","24288","24324.1","3304","13.5937","330400","1"], // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOHLCVs(data, market, timeframe, since, limit) return nil }() return ch } /** * @method * @name okx#fetchFundingRateHistory * @description fetches historical funding rate prices * @see https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate-history * @param {string} symbol unified symbol of the market to fetch the funding rate history for * @param {int} [since] timestamp in ms of the earliest funding rate to fetch * @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} */ func (this *okx) FetchFundingRateHistory(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchFundingRateHistory() requires a symbol argument"))) } retRes24998 := (<-this.LoadMarkets()) PanicOnError(retRes24998) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchFundingRateHistory", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes250319 := (<-this.FetchPaginatedCallDeterministic("fetchFundingRateHistory", symbol, since, limit, "8h", params, 100)) PanicOnError(retRes250319) ch <- retRes250319 return nil } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "before", mathMax(Subtract(since, 1), 0)) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PublicGetPublicFundingRateHistory(this.Extend(request, params))) PanicOnError(response) // // { // "code":"0", // "msg":"", // "data":[ // { // "instType":"SWAP", // "instId":"BTC-USDT-SWAP", // "fundingRate":"0.018", // "realizedRate":"0.017", // "fundingTime":"1597026383085" // }, // { // "instType":"SWAP", // "instId":"BTC-USDT-SWAP", // "fundingRate":"0.018", // "realizedRate":"0.017", // "fundingTime":"1597026383085" // } // ] // } // var rates interface{} = []interface{}{} var data interface{} = this.SafeList(response, "data", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var rate interface{} = GetValue(data, i) var timestamp interface{} = this.SafeInteger(rate, "fundingTime") AppendToArray(&rates,map[string]interface{} { "info": rate, "symbol": this.SafeSymbol(this.SafeString(rate, "instId")), "fundingRate": this.SafeNumber(rate, "realizedRate"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), }) } var sorted interface{} = this.SortBy(rates, "timestamp") ch <- this.FilterBySymbolSinceLimit(sorted, GetValue(market, "symbol"), since, limit) return nil }() return ch } func (this *okx) ParseBalanceByType(typeVar interface{}, response interface{}) interface{} { if IsTrue(IsEqual(typeVar, "funding")) { return this.ParseFundingBalance(response) } else { return this.ParseTradingBalance(response) } } func (this *okx) ParseTradingBalance(response interface{}) interface{} { var result interface{} = map[string]interface{} { "info": response, } var data interface{} = this.SafeList(response, "data", []interface{}{}) var first interface{} = this.SafeDict(data, 0, map[string]interface{} {}) var timestamp interface{} = this.SafeInteger(first, "uTime") var details interface{} = this.SafeList(first, "details", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(details)); i++ { var balance interface{} = GetValue(details, i) var currencyId interface{} = this.SafeString(balance, "ccy") var code interface{} = this.SafeCurrencyCode(currencyId) var account interface{} = this.Account() // it may be incorrect to use total, free and used for swap accounts var eq interface{} = this.SafeString(balance, "eq") var availEq interface{} = this.SafeString(balance, "availEq") if IsTrue(IsTrue((IsEqual(eq, nil))) || IsTrue((IsEqual(availEq, nil)))) { AddElementToObject(account, "free", this.SafeString(balance, "availBal")) AddElementToObject(account, "used", this.SafeString(balance, "frozenBal")) } else { AddElementToObject(account, "total", eq) AddElementToObject(account, "free", availEq) } AddElementToObject(result, code, account) } AddElementToObject(result, "timestamp", timestamp) AddElementToObject(result, "datetime", this.Iso8601(timestamp)) return this.SafeBalance(result) } func (this *okx) ParseFundingBalance(response interface{}) interface{} { var result interface{} = map[string]interface{} { "info": response, } var data interface{} = this.SafeList(response, "data", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var balance interface{} = GetValue(data, i) var currencyId interface{} = this.SafeString(balance, "ccy") var code interface{} = this.SafeCurrencyCode(currencyId) var account interface{} = this.Account() // it may be incorrect to use total, free and used for swap accounts AddElementToObject(account, "total", this.SafeString(balance, "bal")) AddElementToObject(account, "free", this.SafeString(balance, "availBal")) AddElementToObject(account, "used", this.SafeString(balance, "frozenBal")) AddElementToObject(result, code, account) } return this.SafeBalance(result) } func (this *okx) ParseTradingFee(fee interface{}, optionalArgs ...interface{}) interface{} { // https://www.okx.com/docs-v5/en/#rest-api-account-get-fee-rates // // { // "category": "1", // "delivery": "", // "exercise": "", // "instType": "SPOT", // "level": "Lv1", // "maker": "-0.0008", // "taker": "-0.001", // "ts": "1639043138472" // } // market := GetArg(optionalArgs, 0, nil) _ = market return map[string]interface{} { "info": fee, "symbol": this.SafeSymbol(nil, market), "maker": this.ParseNumber(Precise.StringNeg(this.SafeString2(fee, "maker", "makerU"))), "taker": this.ParseNumber(Precise.StringNeg(this.SafeString2(fee, "taker", "takerU"))), "percentage": nil, "tierBased": nil, } } /** * @method * @name okx#fetchTradingFee * @description fetch the trading fees for a market * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-fee-rates * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure} */ func (this *okx) FetchTradingFee(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 retRes26438 := (<-this.LoadMarkets()) PanicOnError(retRes26438) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instType": this.ConvertToInstrumentType(GetValue(market, "type")), } if IsTrue(GetValue(market, "spot")) { AddElementToObject(request, "instId", GetValue(market, "id")) } else if IsTrue(IsTrue(IsTrue(GetValue(market, "swap")) || IsTrue(GetValue(market, "future"))) || IsTrue(GetValue(market, "option"))) { AddElementToObject(request, "uly", Add(Add(GetValue(market, "baseId"), "-"), GetValue(market, "quoteId"))) } else { panic(NotSupported(Add(this.Id, " fetchTradingFee() supports spot, swap, future or option markets only"))) } response:= (<-this.PrivateGetAccountTradeFee(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "category": "1", // "delivery": "", // "exercise": "", // "instType": "SPOT", // "level": "Lv1", // "maker": "-0.0008", // "taker": "-0.001", // "ts": "1639043138472" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var first interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseTradingFee(first, market) return nil }() return ch } /** * @method * @name okx#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-balance * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-balance * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.type] wallet type, ['funding' or 'trading'] default is 'trading' * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure} */ func (this *okx) 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 retRes26938 := (<-this.LoadMarkets()) PanicOnError(retRes26938) marketTypequeryVariable := this.HandleMarketTypeAndParams("fetchBalance", nil, params); marketType := GetValue(marketTypequeryVariable,0); query := GetValue(marketTypequeryVariable,1) var request interface{} = map[string]interface{} {} var response interface{} = nil if IsTrue(IsEqual(marketType, "funding")) { response = (<-this.PrivateGetAssetBalances(this.Extend(request, query))) PanicOnError(response) } else { response = (<-this.PrivateGetAccountBalance(this.Extend(request, query))) PanicOnError(response) } // // { // "code": "0", // "data": [ // { // "adjEq": "", // "details": [ // { // "availBal": "", // "availEq": "28.21006347", // "cashBal": "28.21006347", // "ccy": "USDT", // "crossLiab": "", // "disEq": "28.2687404020176", // "eq":"28 .21006347", // "eqUsd": "28.2687404020176", // "frozenBal": "0", // "interest": "", // "isoEq": "0", // "isoLiab": "", // "liab": "", // "maxLoan": "", // "mgnRatio": "", // "notionalLever": "0", // "ordFrozen": "0", // "twap": "0", // "uTime": "1621556539861", // "upl": "0", // "uplLiab": "" // } // ], // "imr": "", // "isoEq": "0", // "mgnRatio": "", // "mmr": "", // "notionalUsd": "", // "ordFroz": "", // "totalEq": "28.2687404020176", // "uTime": "1621556553510" // } // ], // "msg": "" // } // // { // "code": "0", // "data": [ // { // "adjEq": "", // "details": [ // { // "availBal": "0.049", // "availEq": "", // "cashBal": "0.049", // "ccy": "BTC", // "crossLiab": "", // "disEq": "1918.55678", // "eq": "0.049", // "eqUsd": "1918.55678", // "frozenBal": "0", // "interest": "", // "isoEq": "", // "isoLiab": "", // "liab": "", // "maxLoan": "", // "mgnRatio": "", // "notionalLever": "", // "ordFrozen": "0", // "twap": "0", // "uTime": "1621973128591", // "upl": "", // "uplLiab": "" // } // ], // "imr": "", // "isoEq": "", // "mgnRatio": "", // "mmr": "", // "notionalUsd": "", // "ordFroz": "", // "totalEq": "1918.55678", // "uTime": "1622045126908" // } // ], // "msg": "" // } // // funding // // { // "code": "0", // "data": [ // { // "availBal": "0.00005426", // "bal": 0.0000542600000000, // "ccy": "BTC", // "frozenBal": "0" // } // ], // "msg": "" // } // ch <- this.ParseBalanceByType(marketType, response) return nil }() return ch } /** * @method * @name okx#createMarketBuyOrderWithCost * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order * @description create a market buy order by providing the symbol and cost * @param {string} symbol unified symbol of the market to create an order in * @param {float} cost how much you want to trade in units of the quote currency * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) CreateMarketBuyOrderWithCost(symbol interface{}, cost 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 retRes28208 := (<-this.LoadMarkets()) PanicOnError(retRes28208) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "spot")) { panic(NotSupported(Add(this.Id, " createMarketBuyOrderWithCost() supports spot markets only"))) } var req interface{} = map[string]interface{} { "createMarketBuyOrderRequiresPrice": false, "tgtCcy": "quote_ccy", } retRes282915 := (<-this.CreateOrder(symbol, "market", "buy", cost, nil, this.Extend(req, params))) PanicOnError(retRes282915) ch <- retRes282915 return nil }() return ch } /** * @method * @name okx#createMarketSellOrderWithCost * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order * @description create a market buy order by providing the symbol and cost * @param {string} symbol unified symbol of the market to create an order in * @param {float} cost how much you want to trade in units of the quote currency * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) CreateMarketSellOrderWithCost(symbol interface{}, cost 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 retRes28438 := (<-this.LoadMarkets()) PanicOnError(retRes28438) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "spot")) { panic(NotSupported(Add(this.Id, " createMarketSellOrderWithCost() supports spot markets only"))) } var req interface{} = map[string]interface{} { "createMarketBuyOrderRequiresPrice": false, "tgtCcy": "quote_ccy", } retRes285215 := (<-this.CreateOrder(symbol, "market", "sell", cost, nil, this.Extend(req, params))) PanicOnError(retRes285215) ch <- retRes285215 return nil }() return ch } func (this *okx) CreateOrderRequest(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) interface{} { price := GetArg(optionalArgs, 0, nil) _ = price params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), "side": side, "ordType": typeVar, "sz": this.AmountToPrecision(symbol, amount), } var spot interface{} = GetValue(market, "spot") var contract interface{} = GetValue(market, "contract") var triggerPrice interface{} = this.SafeValueN(params, []interface{}{"triggerPrice", "stopPrice", "triggerPx"}) var timeInForce interface{} = this.SafeString(params, "timeInForce", "GTC") var takeProfitPrice interface{} = this.SafeValue2(params, "takeProfitPrice", "tpTriggerPx") var tpOrdPx interface{} = this.SafeValue(params, "tpOrdPx", price) var tpTriggerPxType interface{} = this.SafeString(params, "tpTriggerPxType", "last") var stopLossPrice interface{} = this.SafeValue2(params, "stopLossPrice", "slTriggerPx") var slOrdPx interface{} = this.SafeValue(params, "slOrdPx", price) var slTriggerPxType interface{} = this.SafeString(params, "slTriggerPxType", "last") var clientOrderId interface{} = this.SafeString2(params, "clOrdId", "clientOrderId") var stopLoss interface{} = this.SafeValue(params, "stopLoss") var stopLossDefined interface{} = (!IsEqual(stopLoss, nil)) var takeProfit interface{} = this.SafeValue(params, "takeProfit") var takeProfitDefined interface{} = (!IsEqual(takeProfit, nil)) var trailingPercent interface{} = this.SafeString2(params, "trailingPercent", "callbackRatio") var isTrailingPercentOrder interface{} = !IsEqual(trailingPercent, nil) var trigger interface{} = IsTrue((!IsEqual(triggerPrice, nil))) || IsTrue((IsEqual(typeVar, "trigger"))) var isReduceOnly interface{} = this.SafeValue(params, "reduceOnly", false) var defaultMarginMode interface{} = this.SafeString2(this.Options, "defaultMarginMode", "marginMode", "cross") var marginMode interface{} = this.SafeString2(params, "marginMode", "tdMode") // cross or isolated, tdMode not ommited so as to be extended into the request var margin interface{} = false if IsTrue(IsTrue((!IsEqual(marginMode, nil))) && IsTrue((!IsEqual(marginMode, "cash")))) { margin = true } else { marginMode = defaultMarginMode margin = this.SafeBool(params, "margin", false) } if IsTrue(spot) { if IsTrue(margin) { var defaultCurrency interface{} = Ternary(IsTrue((IsEqual(side, "buy"))), GetValue(market, "quote"), GetValue(market, "base")) var currency interface{} = this.SafeString(params, "ccy", defaultCurrency) AddElementToObject(request, "ccy", this.SafeCurrencyCode(currency)) } var tradeMode interface{} = Ternary(IsTrue(margin), marginMode, "cash") AddElementToObject(request, "tdMode", tradeMode) } else if IsTrue(contract) { if IsTrue(IsTrue(GetValue(market, "swap")) || IsTrue(GetValue(market, "future"))) { var positionSide interface{} = nil positionSideparamsVariable := this.HandleOptionAndParams(params, "createOrder", "positionSide"); positionSide = GetValue(positionSideparamsVariable,0); params = GetValue(positionSideparamsVariable,1) if IsTrue(!IsEqual(positionSide, nil)) { AddElementToObject(request, "posSide", positionSide) } else { var hedged interface{} = nil hedgedparamsVariable := this.HandleOptionAndParams(params, "createOrder", "hedged"); hedged = GetValue(hedgedparamsVariable,0); params = GetValue(hedgedparamsVariable,1) if IsTrue(hedged) { var isBuy interface{} = (IsEqual(side, "buy")) var isProtective interface{} = IsTrue(IsTrue((!IsEqual(takeProfitPrice, nil))) || IsTrue((!IsEqual(stopLossPrice, nil)))) || IsTrue(isReduceOnly) if IsTrue(isProtective) { // in case of protective orders, the posSide should be opposite of position side // reduceOnly is emulated and not natively supported by the exchange AddElementToObject(request, "posSide", Ternary(IsTrue(isBuy), "short", "long")) if IsTrue(isReduceOnly) { params = this.Omit(params, "reduceOnly") } } else { AddElementToObject(request, "posSide", Ternary(IsTrue(isBuy), "long", "short")) } } } } AddElementToObject(request, "tdMode", marginMode) } var isMarketOrder interface{} = IsEqual(typeVar, "market") var postOnly interface{} = false postOnlyparamsVariable := this.HandlePostOnly(isMarketOrder, IsEqual(typeVar, "post_only"), params); postOnly = GetValue(postOnlyparamsVariable,0); params = GetValue(postOnlyparamsVariable,1) params = this.Omit(params, []interface{}{"currency", "ccy", "marginMode", "timeInForce", "stopPrice", "triggerPrice", "clientOrderId", "stopLossPrice", "takeProfitPrice", "slOrdPx", "tpOrdPx", "margin", "stopLoss", "takeProfit", "trailingPercent"}) var ioc interface{} = IsTrue((IsEqual(timeInForce, "IOC"))) || IsTrue((IsEqual(typeVar, "ioc"))) var fok interface{} = IsTrue((IsEqual(timeInForce, "FOK"))) || IsTrue((IsEqual(typeVar, "fok"))) var conditional interface{} = IsTrue(IsTrue((!IsEqual(stopLossPrice, nil))) || IsTrue((!IsEqual(takeProfitPrice, nil)))) || IsTrue((IsEqual(typeVar, "conditional"))) var marketIOC interface{} = IsTrue((IsTrue(isMarketOrder) && IsTrue(ioc))) || IsTrue((IsEqual(typeVar, "optimal_limit_ioc"))) var defaultTgtCcy interface{} = this.SafeString(this.Options, "tgtCcy", "base_ccy") var tgtCcy interface{} = this.SafeString(params, "tgtCcy", defaultTgtCcy) if IsTrue(IsTrue((!IsTrue(contract))) && IsTrue((!IsTrue(margin)))) { AddElementToObject(request, "tgtCcy", tgtCcy) } if IsTrue(IsTrue(isMarketOrder) || IsTrue(marketIOC)) { AddElementToObject(request, "ordType", "market") if IsTrue(IsTrue(spot) && IsTrue((IsEqual(side, "buy")))) { // spot market buy: "sz" can refer either to base currency units or to quote currency units // see documentation: https://www.okx.com/docs-v5/en/#rest-api-trade-place-order if IsTrue(IsEqual(tgtCcy, "quote_ccy")) { // quote_ccy: sz refers to units of quote currency var createMarketBuyOrderRequiresPrice interface{} = true createMarketBuyOrderRequiresPriceparamsVariable := this.HandleOptionAndParams(params, "createOrder", "createMarketBuyOrderRequiresPrice", true); createMarketBuyOrderRequiresPrice = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,0); params = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,1) var notional interface{} = this.SafeNumber2(params, "cost", "sz") params = this.Omit(params, []interface{}{"cost", "sz"}) if IsTrue(createMarketBuyOrderRequiresPrice) { if IsTrue(!IsEqual(price, nil)) { if IsTrue(IsEqual(notional, nil)) { var amountString interface{} = this.NumberToString(amount) var priceString interface{} = this.NumberToString(price) var quoteAmount interface{} = Precise.StringMul(amountString, priceString) notional = this.ParseNumber(quoteAmount) } } else if IsTrue(IsEqual(notional, nil)) { panic(InvalidOrder(Add(this.Id, " createOrder() requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options[\\'createMarketBuyOrderRequiresPrice\\'] = false and supply the total cost value in the \\'amount\\' argument or in the \\'cost\\' unified extra parameter or in exchange-specific \\'sz\\' extra parameter (the exchange-specific behaviour)"))) } } else { notional = Ternary(IsTrue((IsEqual(notional, nil))), amount, notional) } AddElementToObject(request, "sz", this.CostToPrecision(symbol, notional)) } } if IsTrue(IsTrue(marketIOC) && IsTrue(contract)) { AddElementToObject(request, "ordType", "optimal_limit_ioc") } } else { if IsTrue(IsTrue((!IsTrue(trigger))) && IsTrue((!IsTrue(conditional)))) { AddElementToObject(request, "px", this.PriceToPrecision(symbol, price)) } } if IsTrue(postOnly) { AddElementToObject(request, "ordType", "post_only") } else if IsTrue(IsTrue(ioc) && !IsTrue(marketIOC)) { AddElementToObject(request, "ordType", "ioc") } else if IsTrue(fok) { AddElementToObject(request, "ordType", "fok") } if IsTrue(isTrailingPercentOrder) { var convertedTrailingPercent interface{} = Precise.StringDiv(trailingPercent, "100") AddElementToObject(request, "callbackRatio", convertedTrailingPercent) AddElementToObject(request, "ordType", "move_order_stop") } else if IsTrue(IsTrue(stopLossDefined) || IsTrue(takeProfitDefined)) { if IsTrue(stopLossDefined) { var stopLossTriggerPrice interface{} = this.SafeValueN(stopLoss, []interface{}{"triggerPrice", "stopPrice", "slTriggerPx"}) if IsTrue(IsEqual(stopLossTriggerPrice, nil)) { panic(InvalidOrder(Add(this.Id, " createOrder() requires a trigger price in params[\"stopLoss\"][\"triggerPrice\"], or params[\"stopLoss\"][\"stopPrice\"], or params[\"stopLoss\"][\"slTriggerPx\"] for a stop loss order"))) } AddElementToObject(request, "slTriggerPx", this.PriceToPrecision(symbol, stopLossTriggerPrice)) var stopLossLimitPrice interface{} = this.SafeValueN(stopLoss, []interface{}{"price", "stopLossPrice", "slOrdPx"}) var stopLossOrderType interface{} = this.SafeString(stopLoss, "type") if IsTrue(!IsEqual(stopLossOrderType, nil)) { var stopLossLimitOrderType interface{} = (IsEqual(stopLossOrderType, "limit")) var stopLossMarketOrderType interface{} = (IsEqual(stopLossOrderType, "market")) if IsTrue(IsTrue((!IsTrue(stopLossLimitOrderType))) && IsTrue((!IsTrue(stopLossMarketOrderType)))) { panic(InvalidOrder(Add(this.Id, " createOrder() params[\"stopLoss\"][\"type\"] must be either \"limit\" or \"market\""))) } else if IsTrue(stopLossLimitOrderType) { if IsTrue(IsEqual(stopLossLimitPrice, nil)) { panic(InvalidOrder(Add(this.Id, " createOrder() requires a limit price in params[\"stopLoss\"][\"price\"] or params[\"stopLoss\"][\"slOrdPx\"] for a stop loss limit order"))) } else { AddElementToObject(request, "slOrdPx", this.PriceToPrecision(symbol, stopLossLimitPrice)) } } else if IsTrue(IsEqual(stopLossOrderType, "market")) { AddElementToObject(request, "slOrdPx", "-1") } } else if IsTrue(!IsEqual(stopLossLimitPrice, nil)) { AddElementToObject(request, "slOrdPx", this.PriceToPrecision(symbol, stopLossLimitPrice)) // limit sl order } else { AddElementToObject(request, "slOrdPx", "-1") // market sl order } var stopLossTriggerPriceType interface{} = this.SafeString2(stopLoss, "triggerPriceType", "slTriggerPxType", "last") if IsTrue(!IsEqual(stopLossTriggerPriceType, nil)) { if IsTrue(IsTrue(IsTrue((!IsEqual(stopLossTriggerPriceType, "last"))) && IsTrue((!IsEqual(stopLossTriggerPriceType, "index")))) && IsTrue((!IsEqual(stopLossTriggerPriceType, "mark")))) { panic(InvalidOrder(Add(this.Id, " createOrder() stop loss trigger price type must be one of \"last\", \"index\" or \"mark\""))) } AddElementToObject(request, "slTriggerPxType", stopLossTriggerPriceType) } } if IsTrue(takeProfitDefined) { var takeProfitTriggerPrice interface{} = this.SafeValueN(takeProfit, []interface{}{"triggerPrice", "stopPrice", "tpTriggerPx"}) if IsTrue(IsEqual(takeProfitTriggerPrice, nil)) { panic(InvalidOrder(Add(this.Id, " createOrder() requires a trigger price in params[\"takeProfit\"][\"triggerPrice\"], or params[\"takeProfit\"][\"stopPrice\"], or params[\"takeProfit\"][\"tpTriggerPx\"] for a take profit order"))) } AddElementToObject(request, "tpTriggerPx", this.PriceToPrecision(symbol, takeProfitTriggerPrice)) var takeProfitLimitPrice interface{} = this.SafeValueN(takeProfit, []interface{}{"price", "takeProfitPrice", "tpOrdPx"}) var takeProfitOrderType interface{} = this.SafeString2(takeProfit, "type", "tpOrdKind") if IsTrue(!IsEqual(takeProfitOrderType, nil)) { var takeProfitLimitOrderType interface{} = (IsEqual(takeProfitOrderType, "limit")) var takeProfitMarketOrderType interface{} = (IsEqual(takeProfitOrderType, "market")) if IsTrue(IsTrue((!IsTrue(takeProfitLimitOrderType))) && IsTrue((!IsTrue(takeProfitMarketOrderType)))) { panic(InvalidOrder(Add(this.Id, " createOrder() params[\"takeProfit\"][\"type\"] must be either \"limit\" or \"market\""))) } else if IsTrue(takeProfitLimitOrderType) { if IsTrue(IsEqual(takeProfitLimitPrice, nil)) { panic(InvalidOrder(Add(this.Id, " createOrder() requires a limit price in params[\"takeProfit\"][\"price\"] or params[\"takeProfit\"][\"tpOrdPx\"] for a take profit limit order"))) } else { AddElementToObject(request, "tpOrdKind", takeProfitOrderType) AddElementToObject(request, "tpOrdPx", this.PriceToPrecision(symbol, takeProfitLimitPrice)) } } else if IsTrue(IsEqual(takeProfitOrderType, "market")) { AddElementToObject(request, "tpOrdPx", "-1") } } else if IsTrue(!IsEqual(takeProfitLimitPrice, nil)) { AddElementToObject(request, "tpOrdKind", "limit") AddElementToObject(request, "tpOrdPx", this.PriceToPrecision(symbol, takeProfitLimitPrice)) // limit tp order } else { AddElementToObject(request, "tpOrdPx", "-1") // market tp order } var takeProfitTriggerPriceType interface{} = this.SafeString2(takeProfit, "triggerPriceType", "tpTriggerPxType", "last") if IsTrue(!IsEqual(takeProfitTriggerPriceType, nil)) { if IsTrue(IsTrue(IsTrue((!IsEqual(takeProfitTriggerPriceType, "last"))) && IsTrue((!IsEqual(takeProfitTriggerPriceType, "index")))) && IsTrue((!IsEqual(takeProfitTriggerPriceType, "mark")))) { panic(InvalidOrder(Add(this.Id, " createOrder() take profit trigger price type must be one of \"last\", \"index\" or \"mark\""))) } AddElementToObject(request, "tpTriggerPxType", takeProfitTriggerPriceType) } } } else if IsTrue(trigger) { AddElementToObject(request, "ordType", "trigger") AddElementToObject(request, "triggerPx", this.PriceToPrecision(symbol, triggerPrice)) AddElementToObject(request, "orderPx", Ternary(IsTrue(isMarketOrder), "-1", this.PriceToPrecision(symbol, price))) } else if IsTrue(conditional) { AddElementToObject(request, "ordType", "conditional") var twoWayCondition interface{} = (IsTrue((!IsEqual(takeProfitPrice, nil))) && IsTrue((!IsEqual(stopLossPrice, nil)))) // if TP and SL are sent together // as ordType 'conditional' only stop-loss order will be applied // tpOrdKind is 'condition' which is the default if IsTrue(twoWayCondition) { AddElementToObject(request, "ordType", "oco") } if IsTrue(!IsEqual(takeProfitPrice, nil)) { AddElementToObject(request, "tpTriggerPx", this.PriceToPrecision(symbol, takeProfitPrice)) var tpOrdPxReq interface{} = "-1" if IsTrue(!IsEqual(tpOrdPx, nil)) { tpOrdPxReq = this.PriceToPrecision(symbol, tpOrdPx) } AddElementToObject(request, "tpOrdPx", tpOrdPxReq) AddElementToObject(request, "tpTriggerPxType", tpTriggerPxType) } if IsTrue(!IsEqual(stopLossPrice, nil)) { AddElementToObject(request, "slTriggerPx", this.PriceToPrecision(symbol, stopLossPrice)) var slOrdPxReq interface{} = "-1" if IsTrue(!IsEqual(slOrdPx, nil)) { slOrdPxReq = this.PriceToPrecision(symbol, slOrdPx) } AddElementToObject(request, "slOrdPx", slOrdPxReq) AddElementToObject(request, "slTriggerPxType", slTriggerPxType) } } if IsTrue(IsEqual(clientOrderId, nil)) { var brokerId interface{} = this.SafeString(this.Options, "brokerId") if IsTrue(!IsEqual(brokerId, nil)) { AddElementToObject(request, "clOrdId", Add(brokerId, this.Uuid16())) AddElementToObject(request, "tag", brokerId) } } else { AddElementToObject(request, "clOrdId", clientOrderId) params = this.Omit(params, []interface{}{"clOrdId", "clientOrderId"}) } return this.Extend(request, params) } /** * @method * @name okx#createOrder * @description create a trade order * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-multiple-orders * @see https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-place-algo-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 fulfilled, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {bool} [params.reduceOnly] a mark to reduce the position size for margin, swap and future orders * @param {bool} [params.postOnly] true to place a post only order * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered (perpetual swap markets only) * @param {float} [params.takeProfit.triggerPrice] take profit trigger price * @param {float} [params.takeProfit.price] used for take profit limit orders, not used for take profit market price orders * @param {string} [params.takeProfit.type] 'market' or 'limit' used to specify the take profit price type * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered (perpetual swap markets only) * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price * @param {float} [params.stopLoss.price] used for stop loss limit orders, not used for stop loss market price orders * @param {string} [params.stopLoss.type] 'market' or 'limit' used to specify the stop loss price type * @param {string} [params.positionSide] if position mode is one-way: set to 'net', if position mode is hedge-mode: set to 'long' or 'short' * @param {string} [params.trailingPercent] the percent to trail away from the current market price * @param {string} [params.tpOrdKind] 'condition' or 'limit', the default is 'condition' * @param {bool} [params.hedged] *swap and future only* true for hedged mode, false for one way mode * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) 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 retRes31548 := (<-this.LoadMarkets()) PanicOnError(retRes31548) var market interface{} = this.Market(symbol) var request interface{} = this.CreateOrderRequest(symbol, typeVar, side, amount, price, params) var method interface{} = this.SafeString(this.Options, "createOrder", "privatePostTradeBatchOrders") var requestOrdType interface{} = this.SafeString(request, "ordType") if IsTrue(IsTrue(IsTrue(IsTrue(IsTrue(IsTrue(IsTrue((IsEqual(requestOrdType, "trigger"))) || IsTrue((IsEqual(requestOrdType, "conditional")))) || IsTrue((IsEqual(requestOrdType, "move_order_stop")))) || IsTrue((IsEqual(typeVar, "move_order_stop")))) || IsTrue((IsEqual(typeVar, "oco")))) || IsTrue((IsEqual(typeVar, "iceberg")))) || IsTrue((IsEqual(typeVar, "twap")))) { method = "privatePostTradeOrderAlgo" } if IsTrue(IsTrue(IsTrue((!IsEqual(method, "privatePostTradeOrder"))) && IsTrue((!IsEqual(method, "privatePostTradeOrderAlgo")))) && IsTrue((!IsEqual(method, "privatePostTradeBatchOrders")))) { panic(ExchangeError(Add(this.Id, " createOrder() this.options[\"createOrder\"] must be either privatePostTradeBatchOrders or privatePostTradeOrder or privatePostTradeOrderAlgo"))) } if IsTrue(IsEqual(method, "privatePostTradeBatchOrders")) { // keep the request body the same // submit a single order in an array to the batch order endpoint // because it has a lower ratelimit request = []interface{}{request} } var response interface{} = nil if IsTrue(IsEqual(method, "privatePostTradeOrder")) { response = (<-this.PrivatePostTradeOrder(request)) PanicOnError(response) } else if IsTrue(IsEqual(method, "privatePostTradeOrderAlgo")) { response = (<-this.PrivatePostTradeOrderAlgo(request)) PanicOnError(response) } else { response = (<-this.PrivatePostTradeBatchOrders(request)) PanicOnError(response) } var data interface{} = this.SafeList(response, "data", []interface{}{}) var first interface{} = this.SafeDict(data, 0, map[string]interface{} {}) var order interface{} = this.ParseOrder(first, market) AddElementToObject(order, "type", typeVar) AddElementToObject(order, "side", side) ch <- order return nil }() return ch } /** * @method * @name okx#createOrders * @description create a list of trade orders * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-multiple-orders * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) CreateOrders(orders 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 retRes31978 := (<-this.LoadMarkets()) PanicOnError(retRes31978) var ordersRequests interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { var rawOrder interface{} = GetValue(orders, i) var marketId interface{} = this.SafeString(rawOrder, "symbol") var typeVar interface{} = this.SafeString(rawOrder, "type") var side interface{} = this.SafeString(rawOrder, "side") var amount interface{} = this.SafeValue(rawOrder, "amount") var price interface{} = this.SafeValue(rawOrder, "price") var orderParams interface{} = this.SafeDict(rawOrder, "params", map[string]interface{} {}) var extendedParams interface{} = this.Extend(orderParams, params) // the request does not accept extra params since it's a list, so we're extending each order with the common params var orderRequest interface{} = this.CreateOrderRequest(marketId, typeVar, side, amount, price, extendedParams) AppendToArray(&ordersRequests,orderRequest) } response:= (<-this.PrivatePostTradeBatchOrders(ordersRequests)) PanicOnError(response) // { // "code": "0", // "data": [ // { // "clOrdId": "e847386590ce4dBCc7f2a1b4c4509f82", // "ordId": "636305438765568000", // "sCode": "0", // "sMsg": "Order placed", // "tag": "e847386590ce4dBC" // }, // { // "clOrdId": "e847386590ce4dBC0b9993fe642d8f62", // "ordId": "636305438765568001", // "sCode": "0", // "sMsg": "Order placed", // "tag": "e847386590ce4dBC" // } // ], // "inTime": "1697979038584486", // "msg": "", // "outTime": "1697979038586493" // } var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(data) return nil }() return ch } func (this *okx) EditOrderRequest(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) interface{} { amount := GetArg(optionalArgs, 0, nil) _ = amount price := GetArg(optionalArgs, 1, nil) _ = price params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } var isAlgoOrder interface{} = nil if IsTrue(IsTrue(IsTrue(IsTrue(IsTrue(IsTrue((IsEqual(typeVar, "trigger"))) || IsTrue((IsEqual(typeVar, "conditional")))) || IsTrue((IsEqual(typeVar, "move_order_stop")))) || IsTrue((IsEqual(typeVar, "oco")))) || IsTrue((IsEqual(typeVar, "iceberg")))) || IsTrue((IsEqual(typeVar, "twap")))) { isAlgoOrder = true } var clientOrderId interface{} = this.SafeString2(params, "clOrdId", "clientOrderId") if IsTrue(!IsEqual(clientOrderId, nil)) { if IsTrue(isAlgoOrder) { AddElementToObject(request, "algoClOrdId", clientOrderId) } else { AddElementToObject(request, "clOrdId", clientOrderId) } } else { if IsTrue(isAlgoOrder) { AddElementToObject(request, "algoId", id) } else { AddElementToObject(request, "ordId", id) } } var stopLossTriggerPrice interface{} = this.SafeValue2(params, "stopLossPrice", "newSlTriggerPx") var stopLossPrice interface{} = this.SafeValue(params, "newSlOrdPx") var stopLossTriggerPriceType interface{} = this.SafeString(params, "newSlTriggerPxType", "last") var takeProfitTriggerPrice interface{} = this.SafeValue2(params, "takeProfitPrice", "newTpTriggerPx") var takeProfitPrice interface{} = this.SafeValue(params, "newTpOrdPx") var takeProfitTriggerPriceType interface{} = this.SafeString(params, "newTpTriggerPxType", "last") var stopLoss interface{} = this.SafeValue(params, "stopLoss") var takeProfit interface{} = this.SafeValue(params, "takeProfit") var stopLossDefined interface{} = (!IsEqual(stopLoss, nil)) var takeProfitDefined interface{} = (!IsEqual(takeProfit, nil)) if IsTrue(isAlgoOrder) { if IsTrue(IsTrue((IsEqual(stopLossTriggerPrice, nil))) && IsTrue((IsEqual(takeProfitTriggerPrice, nil)))) { panic(BadRequest(Add(this.Id, " editOrder() requires a stopLossPrice or takeProfitPrice parameter for editing an algo order"))) } if IsTrue(!IsEqual(stopLossTriggerPrice, nil)) { if IsTrue(IsEqual(stopLossPrice, nil)) { panic(BadRequest(Add(this.Id, " editOrder() requires a newSlOrdPx parameter for editing an algo order"))) } AddElementToObject(request, "newSlTriggerPx", this.PriceToPrecision(symbol, stopLossTriggerPrice)) AddElementToObject(request, "newSlOrdPx", Ternary(IsTrue((IsEqual(typeVar, "market"))), "-1", this.PriceToPrecision(symbol, stopLossPrice))) AddElementToObject(request, "newSlTriggerPxType", stopLossTriggerPriceType) } if IsTrue(!IsEqual(takeProfitTriggerPrice, nil)) { if IsTrue(IsEqual(takeProfitPrice, nil)) { panic(BadRequest(Add(this.Id, " editOrder() requires a newTpOrdPx parameter for editing an algo order"))) } AddElementToObject(request, "newTpTriggerPx", this.PriceToPrecision(symbol, takeProfitTriggerPrice)) AddElementToObject(request, "newTpOrdPx", Ternary(IsTrue((IsEqual(typeVar, "market"))), "-1", this.PriceToPrecision(symbol, takeProfitPrice))) AddElementToObject(request, "newTpTriggerPxType", takeProfitTriggerPriceType) } } else { if IsTrue(!IsEqual(stopLossTriggerPrice, nil)) { AddElementToObject(request, "newSlTriggerPx", this.PriceToPrecision(symbol, stopLossTriggerPrice)) AddElementToObject(request, "newSlOrdPx", Ternary(IsTrue((IsEqual(typeVar, "market"))), "-1", this.PriceToPrecision(symbol, stopLossPrice))) AddElementToObject(request, "newSlTriggerPxType", stopLossTriggerPriceType) } if IsTrue(!IsEqual(takeProfitTriggerPrice, nil)) { AddElementToObject(request, "newTpTriggerPx", this.PriceToPrecision(symbol, takeProfitTriggerPrice)) AddElementToObject(request, "newTpOrdPx", Ternary(IsTrue((IsEqual(typeVar, "market"))), "-1", this.PriceToPrecision(symbol, takeProfitPrice))) AddElementToObject(request, "newTpTriggerPxType", takeProfitTriggerPriceType) } if IsTrue(stopLossDefined) { stopLossTriggerPrice = this.SafeValue(stopLoss, "triggerPrice") stopLossPrice = this.SafeValue(stopLoss, "price") var stopLossType interface{} = this.SafeString(stopLoss, "type") AddElementToObject(request, "newSlTriggerPx", this.PriceToPrecision(symbol, stopLossTriggerPrice)) AddElementToObject(request, "newSlOrdPx", Ternary(IsTrue((IsEqual(stopLossType, "market"))), "-1", this.PriceToPrecision(symbol, stopLossPrice))) AddElementToObject(request, "newSlTriggerPxType", stopLossTriggerPriceType) } if IsTrue(takeProfitDefined) { takeProfitTriggerPrice = this.SafeValue(takeProfit, "triggerPrice") takeProfitPrice = this.SafeValue(takeProfit, "price") var takeProfitType interface{} = this.SafeString(takeProfit, "type") AddElementToObject(request, "newTpOrdKind", Ternary(IsTrue((IsEqual(takeProfitType, "limit"))), takeProfitType, "condition")) AddElementToObject(request, "newTpTriggerPx", this.PriceToPrecision(symbol, takeProfitTriggerPrice)) AddElementToObject(request, "newTpOrdPx", Ternary(IsTrue((IsEqual(takeProfitType, "market"))), "-1", this.PriceToPrecision(symbol, takeProfitPrice))) AddElementToObject(request, "newTpTriggerPxType", takeProfitTriggerPriceType) } } if IsTrue(!IsEqual(amount, nil)) { AddElementToObject(request, "newSz", this.AmountToPrecision(symbol, amount)) } if !IsTrue(isAlgoOrder) { if IsTrue(!IsEqual(price, nil)) { AddElementToObject(request, "newPx", this.PriceToPrecision(symbol, price)) } } params = this.Omit(params, []interface{}{"clOrdId", "clientOrderId", "takeProfitPrice", "stopLossPrice", "stopLoss", "takeProfit", "postOnly"}) return this.Extend(request, params) } /** * @method * @name okx#editOrder * @description edit a trade order * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-amend-order * @see https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-amend-algo-order * @param {string} id order id * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much of the currency you want to trade in units of the base currency * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.clientOrderId] client order id, uses id if not passed * @param {float} [params.stopLossPrice] stop loss trigger price * @param {float} [params.newSlOrdPx] the stop loss order price, set to stopLossPrice if the type is market * @param {string} [params.newSlTriggerPxType] 'last', 'index' or 'mark' used to specify the stop loss trigger price type, default is 'last' * @param {float} [params.takeProfitPrice] take profit trigger price * @param {float} [params.newTpOrdPx] the take profit order price, set to takeProfitPrice if the type is market * @param {string} [params.newTpTriggerPxType] 'last', 'index' or 'mark' used to specify the take profit trigger price type, default is 'last' * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price * @param {float} [params.stopLoss.price] used for stop loss limit orders, not used for stop loss market price orders * @param {string} [params.stopLoss.type] 'market' or 'limit' used to specify the stop loss price type * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered * @param {float} [params.takeProfit.triggerPrice] take profit trigger price * @param {float} [params.takeProfit.price] used for take profit limit orders, not used for take profit market price orders * @param {string} [params.takeProfit.type] 'market' or 'limit' used to specify the take profit price type * @param {string} [params.newTpOrdKind] 'condition' or 'limit', the default is 'condition' * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) EditOrder(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) amount := GetArg(optionalArgs, 0, nil) _ = amount price := GetArg(optionalArgs, 1, nil) _ = price params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params retRes33648 := (<-this.LoadMarkets()) PanicOnError(retRes33648) var market interface{} = this.Market(symbol) var request interface{} = this.EditOrderRequest(id, symbol, typeVar, side, amount, price, params) var isAlgoOrder interface{} = nil if IsTrue(IsTrue(IsTrue(IsTrue(IsTrue(IsTrue((IsEqual(typeVar, "trigger"))) || IsTrue((IsEqual(typeVar, "conditional")))) || IsTrue((IsEqual(typeVar, "move_order_stop")))) || IsTrue((IsEqual(typeVar, "oco")))) || IsTrue((IsEqual(typeVar, "iceberg")))) || IsTrue((IsEqual(typeVar, "twap")))) { isAlgoOrder = true } var response interface{} = nil if IsTrue(isAlgoOrder) { response = (<-this.PrivatePostTradeAmendAlgos(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivatePostTradeAmendOrder(this.Extend(request, params))) PanicOnError(response) } // // { // "code": "0", // "data": [ // { // "clOrdId": "e847386590ce4dBCc1a045253497a547", // "ordId": "559176536793178112", // "reqId": "", // "sCode": "0", // "sMsg": "" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var first interface{} = this.SafeDict(data, 0, map[string]interface{} {}) var order interface{} = this.ParseOrder(first, market) AddElementToObject(order, "type", typeVar) AddElementToObject(order, "side", side) ch <- order return nil }() return ch } /** * @method * @name okx#cancelOrder * @description cancels an open order * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-order * @see https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order * @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 {boolean} [params.trigger] true if trigger orders * @param {boolean} [params.trailing] set to true if you want to cancel a trailing order * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) CancelOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrder() requires a symbol argument"))) } var trigger interface{} = this.SafeValue2(params, "stop", "trigger") var trailing interface{} = this.SafeBool(params, "trailing", false) if IsTrue(IsTrue(trigger) || IsTrue(trailing)) { orderInner:= (<-this.CancelOrders([]interface{}{id}, symbol, params)) PanicOnError(orderInner) ch <- this.SafeValue(orderInner, 0) return nil } retRes34238 := (<-this.LoadMarkets()) PanicOnError(retRes34238) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } var clientOrderId interface{} = this.SafeString2(params, "clOrdId", "clientOrderId") if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "clOrdId", clientOrderId) } else { AddElementToObject(request, "ordId", id) } var query interface{} = this.Omit(params, []interface{}{"clOrdId", "clientOrderId"}) response:= (<-this.PrivatePostTradeCancelOrder(this.Extend(request, query))) PanicOnError(response) // {"code":"0","data":[{"clOrdId":"","ordId":"317251910906576896","sCode":"0","sMsg":""}],"msg":""} var data interface{} = this.SafeValue(response, "data", []interface{}{}) var order interface{} = this.SafeDict(data, 0) ch <- this.ParseOrder(order, market) return nil }() return ch } func (this *okx) ParseIds(ids interface{}) interface{} { /** * @ignore * @method * @name okx#parseIds * @param {string[]|string} ids order ids * @returns {string[]} list of order ids */ if IsTrue(IsTrue((!IsEqual(ids, nil))) && IsTrue(IsString(ids))) { return Split(ids, ",") } else { return ids } } /** * @method * @name okx#cancelOrders * @description cancel multiple orders * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-multiple-orders * @see https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order * @param {string[]} ids order ids * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.trigger] whether the order is a stop/trigger order * @param {boolean} [params.trailing] set to true if you want to cancel trailing orders * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) CancelOrders(ids interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // TODO : the original endpoint signature differs, according to that you can skip individual symbol and assign ids in batch. At this moment, `params` is not being used too. symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrders() requires a symbol argument"))) } retRes34778 := (<-this.LoadMarkets()) PanicOnError(retRes34778) var market interface{} = this.Market(symbol) var request interface{} = []interface{}{} var options interface{} = this.SafeValue(this.Options, "cancelOrders", map[string]interface{} {}) var defaultMethod interface{} = this.SafeString(options, "method", "privatePostTradeCancelBatchOrders") var method interface{} = this.SafeString(params, "method", defaultMethod) var clientOrderIds interface{} = this.ParseIds(this.SafeValue2(params, "clOrdId", "clientOrderId")) var algoIds interface{} = this.ParseIds(this.SafeValue(params, "algoId")) var trigger interface{} = this.SafeValue2(params, "stop", "trigger") var trailing interface{} = this.SafeBool(params, "trailing", false) if IsTrue(IsTrue(trigger) || IsTrue(trailing)) { method = "privatePostTradeCancelAlgos" } if IsTrue(IsEqual(clientOrderIds, nil)) { ids = this.ParseIds(ids) if IsTrue(!IsEqual(algoIds, nil)) { for i := 0; IsLessThan(i, GetArrayLength(algoIds)); i++ { AppendToArray(&request,map[string]interface{} { "algoId": GetValue(algoIds, i), "instId": GetValue(market, "id"), }) } } for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ { if IsTrue(IsTrue(trailing) || IsTrue(trigger)) { AppendToArray(&request,map[string]interface{} { "algoId": GetValue(ids, i), "instId": GetValue(market, "id"), }) } else { AppendToArray(&request,map[string]interface{} { "ordId": GetValue(ids, i), "instId": GetValue(market, "id"), }) } } } else { for i := 0; IsLessThan(i, GetArrayLength(clientOrderIds)); i++ { AppendToArray(&request,map[string]interface{} { "instId": GetValue(market, "id"), "clOrdId": GetValue(clientOrderIds, i), }) } } var response interface{} = nil if IsTrue(IsEqual(method, "privatePostTradeCancelAlgos")) { response = (<-this.PrivatePostTradeCancelAlgos(request)) PanicOnError(response) // * dont extend with params, otherwise ARRAY will be turned into OBJECT } else { response = (<-this.PrivatePostTradeCancelBatchOrders(request)) PanicOnError(response) // * dont extend with params, otherwise ARRAY will be turned into OBJECT } // // { // "code": "0", // "data": [ // { // "clOrdId": "e123456789ec4dBC1123456ba123b45e", // "ordId": "405071912345641543", // "sCode": "0", // "sMsg": "" // }, // ... // ], // "msg": "" // } // // Algo order // // { // "code": "0", // "data": [ // { // "algoId": "431375349042380800", // "sCode": "0", // "sMsg": "" // } // ], // "msg": "" // } // var ordersData interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(ordersData, market, nil, nil, params) return nil }() return ch } /** * @method * @name okx#cancelOrdersForSymbols * @description cancel multiple orders for multiple symbols * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-multiple-orders * @see https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order * @param {CancellationRequest[]} orders each order should contain the parameters required by cancelOrder namely id and symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}] * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.trigger] whether the order is a stop/trigger order * @param {boolean} [params.trailing] set to true if you want to cancel trailing orders * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) CancelOrdersForSymbols(orders 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 retRes35738 := (<-this.LoadMarkets()) PanicOnError(retRes35738) var request interface{} = []interface{}{} var options interface{} = this.SafeDict(this.Options, "cancelOrders", map[string]interface{} {}) var defaultMethod interface{} = this.SafeString(options, "method", "privatePostTradeCancelBatchOrders") var method interface{} = this.SafeString(params, "method", defaultMethod) var trigger interface{} = this.SafeBool2(params, "stop", "trigger") var trailing interface{} = this.SafeBool(params, "trailing", false) var isStopOrTrailing interface{} = IsTrue(trigger) || IsTrue(trailing) if IsTrue(isStopOrTrailing) { method = "privatePostTradeCancelAlgos" } for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { var order interface{} = GetValue(orders, i) var id interface{} = this.SafeString(order, "id") var clientOrderId interface{} = this.SafeString2(order, "clOrdId", "clientOrderId") var symbol interface{} = this.SafeString(order, "symbol") var market interface{} = this.Market(symbol) var idKey interface{} = "ordId" if IsTrue(isStopOrTrailing) { idKey = "algoId" } else if IsTrue(!IsEqual(clientOrderId, nil)) { idKey = "clOrdId" } var requestItem interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } AddElementToObject(requestItem, idKey, Ternary(IsTrue((!IsEqual(clientOrderId, nil))), clientOrderId, id)) AppendToArray(&request,requestItem) } var response interface{} = nil if IsTrue(IsEqual(method, "privatePostTradeCancelAlgos")) { response = (<-this.PrivatePostTradeCancelAlgos(request)) PanicOnError(response) // * dont extend with params, otherwise ARRAY will be turned into OBJECT } else { response = (<-this.PrivatePostTradeCancelBatchOrders(request)) PanicOnError(response) // * dont extend with params, otherwise ARRAY will be turned into OBJECT } // // { // "code": "0", // "data": [ // { // "clOrdId": "e123456789ec4dBC1123456ba123b45e", // "ordId": "405071912345641543", // "sCode": "0", // "sMsg": "" // }, // ... // ], // "msg": "" // } // // Algo order // // { // "code": "0", // "data": [ // { // "algoId": "431375349042380800", // "sCode": "0", // "sMsg": "" // } // ], // "msg": "" // } // var ordersData interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(ordersData, nil, nil, nil, params) return nil }() return ch } /** * @method * @name okx#cancelAllOrdersAfter * @description dead man's switch, cancel all orders after the given timeout * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-all-after * @param {number} timeout time in milliseconds, 0 represents cancel the timer * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} the api result */ func (this *okx) CancelAllOrdersAfter(timeout interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes36518 := (<-this.LoadMarkets()) PanicOnError(retRes36518) var request interface{} = map[string]interface{} { "timeOut": Ternary(IsTrue((IsGreaterThan(timeout, 0))), this.ParseToInt(Divide(timeout, 1000)), 0), } response:= (<-this.PrivatePostTradeCancelAllAfter(this.Extend(request, params))) PanicOnError(response) // // { // "code":"0", // "msg":"", // "data":[ // { // "triggerTime":"1587971460", // "ts":"1587971400" // } // ] // } // ch <- response return nil }() return ch } func (this *okx) ParseOrderStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "canceled": "canceled", "order_failed": "canceled", "live": "open", "partially_filled": "open", "filled": "closed", "effective": "closed", } return this.SafeString(statuses, status, status) } func (this *okx) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // createOrder // // { // "clOrdId": "oktswap6", // "ordId": "312269865356374016", // "tag": "", // "sCode": "0", // "sMsg": "" // } // // editOrder // // { // "clOrdId": "e847386590ce4dBCc1a045253497a547", // "ordId": "559176536793178112", // "reqId": "", // "sCode": "0", // "sMsg": "" // } // // Spot and Swap fetchOrder, fetchOpenOrders // // { // "accFillSz": "0", // "avgPx": "", // "cTime": "1621910749815", // "category": "normal", // "ccy": "", // "clOrdId": "", // "fee": "0", // "feeCcy": "ETH", // "fillPx": "", // "fillSz": "0", // "fillTime": "", // "instId": "ETH-USDT", // "instType": "SPOT", // "lever": "", // "ordId": "317251910906576896", // "ordType": "limit", // "pnl": "0", // "posSide": "net", // "px": "2000", // "rebate": "0", // "rebateCcy": "USDT", // "side": "buy", // "slOrdPx": "", // "slTriggerPx": "", // "state": "live", // "sz": "0.001", // "tag": "", // "tdMode": "cash", // "tpOrdPx": "", // "tpTriggerPx": "", // "tradeId": "", // "uTime": "1621910749815" // } // // Algo Order fetchOpenOrders, fetchCanceledOrders, fetchClosedOrders // // { // "activePx": "", // "activePxType": "", // "actualPx": "", // "actualSide": "buy", // "actualSz": "0", // "algoId": "431375349042380800", // "cTime": "1649119897778", // "callbackRatio": "", // "callbackSpread": "", // "ccy": "", // "ctVal": "0.01", // "instId": "BTC-USDT-SWAP", // "instType": "SWAP", // "last": "46538.9", // "lever": "125", // "moveTriggerPx": "", // "notionalUsd": "467.059", // "ordId": "", // "ordPx": "50000", // "ordType": "trigger", // "posSide": "long", // "pxLimit": "", // "pxSpread": "", // "pxVar": "", // "side": "buy", // "slOrdPx": "", // "slTriggerPx": "", // "slTriggerPxType": "", // "state": "live", // "sz": "1", // "szLimit": "", // "tag": "", // "tdMode": "isolated", // "tgtCcy": "", // "timeInterval": "", // "tpOrdPx": "", // "tpTriggerPx": "", // "tpTriggerPxType": "", // "triggerPx": "50000", // "triggerPxType": "last", // "triggerTime": "", // "uly": "BTC-USDT" // } // market := GetArg(optionalArgs, 0, nil) _ = market var scode interface{} = this.SafeString(order, "sCode") if IsTrue(IsTrue((!IsEqual(scode, nil))) && IsTrue((!IsEqual(scode, "0")))) { return this.SafeOrder(map[string]interface{} { "id": this.SafeString(order, "ordId"), "clientOrderId": this.SafeString(order, "clOrdId"), "status": "rejected", "info": order, }) } var id interface{} = this.SafeString2(order, "algoId", "ordId") var timestamp interface{} = this.SafeInteger(order, "cTime") var lastUpdateTimestamp interface{} = this.SafeInteger(order, "uTime") var lastTradeTimestamp interface{} = this.SafeInteger(order, "fillTime") var side interface{} = this.SafeString(order, "side") var typeVar interface{} = this.SafeString(order, "ordType") var postOnly interface{} = nil var timeInForce interface{} = nil if IsTrue(IsEqual(typeVar, "post_only")) { postOnly = true typeVar = "limit" } else if IsTrue(IsEqual(typeVar, "fok")) { timeInForce = "FOK" typeVar = "limit" } else if IsTrue(IsEqual(typeVar, "ioc")) { timeInForce = "IOC" typeVar = "limit" } var marketId interface{} = this.SafeString(order, "instId") market = this.SafeMarket(marketId, market) var symbol interface{} = this.SafeSymbol(marketId, market, "-") var filled interface{} = this.SafeString(order, "accFillSz") var price interface{} = this.SafeString2(order, "px", "ordPx") var average interface{} = this.SafeString(order, "avgPx") var status interface{} = this.ParseOrderStatus(this.SafeString(order, "state")) var feeCostString interface{} = this.SafeString(order, "fee") var amount interface{} = nil var cost interface{} = nil // spot market buy: "sz" can refer either to base currency units or to quote currency units // see documentation: https://www.okx.com/docs-v5/en/#rest-api-trade-place-order var defaultTgtCcy interface{} = this.SafeString(this.Options, "tgtCcy", "base_ccy") var tgtCcy interface{} = this.SafeString(order, "tgtCcy", defaultTgtCcy) var instType interface{} = this.SafeString(order, "instType") if IsTrue(IsTrue(IsTrue(IsTrue((IsEqual(side, "buy"))) && IsTrue((IsEqual(typeVar, "market")))) && IsTrue((IsEqual(instType, "SPOT")))) && IsTrue((IsEqual(tgtCcy, "quote_ccy")))) { // "sz" refers to the cost cost = this.SafeString(order, "sz") } else { // "sz" refers to the trade currency amount amount = this.SafeString(order, "sz") } var fee interface{} = nil if IsTrue(!IsEqual(feeCostString, nil)) { var feeCostSigned interface{} = Precise.StringNeg(feeCostString) var feeCurrencyId interface{} = this.SafeString(order, "feeCcy") var feeCurrencyCode interface{} = this.SafeCurrencyCode(feeCurrencyId) fee = map[string]interface{} { "cost": this.ParseNumber(feeCostSigned), "currency": feeCurrencyCode, } } var clientOrderId interface{} = this.SafeString(order, "clOrdId") if IsTrue(IsTrue((!IsEqual(clientOrderId, nil))) && IsTrue((IsLessThan(GetLength(clientOrderId), 1)))) { clientOrderId = nil // fix empty clientOrderId string } var stopLossPrice interface{} = this.SafeNumber2(order, "slTriggerPx", "slOrdPx") var takeProfitPrice interface{} = this.SafeNumber2(order, "tpTriggerPx", "tpOrdPx") var reduceOnlyRaw interface{} = this.SafeString(order, "reduceOnly") var reduceOnly interface{} = false if IsTrue(!IsEqual(reduceOnly, nil)) { reduceOnly = (IsEqual(reduceOnlyRaw, "true")) } return this.SafeOrder(map[string]interface{} { "info": order, "id": id, "clientOrderId": clientOrderId, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastTradeTimestamp": lastTradeTimestamp, "lastUpdateTimestamp": lastUpdateTimestamp, "symbol": symbol, "type": typeVar, "timeInForce": timeInForce, "postOnly": postOnly, "side": side, "price": price, "stopLossPrice": stopLossPrice, "takeProfitPrice": takeProfitPrice, "triggerPrice": this.SafeNumberN(order, []interface{}{"triggerPx", "moveTriggerPx"}), "average": average, "cost": cost, "amount": amount, "filled": filled, "remaining": nil, "status": status, "fee": fee, "trades": nil, "reduceOnly": reduceOnly, }, market) } /** * @method * @name okx#fetchOrder * @description fetch an order by the id * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-details * @see https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-details * @param {string} id the order id * @param {string} symbol unified market symbol * @param {object} [params] extra and exchange specific parameters * @param {boolean} [params.trigger] true if fetching trigger orders * @returns [an order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) FetchOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOrder() requires a symbol argument"))) } retRes39048 := (<-this.LoadMarkets()) PanicOnError(retRes39048) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } var clientOrderId interface{} = this.SafeString2(params, "clOrdId", "clientOrderId") var options interface{} = this.SafeValue(this.Options, "fetchOrder", map[string]interface{} {}) var defaultMethod interface{} = this.SafeString(options, "method", "privateGetTradeOrder") var method interface{} = this.SafeString(params, "method", defaultMethod) var trigger interface{} = this.SafeValue2(params, "stop", "trigger") if IsTrue(trigger) { method = "privateGetTradeOrderAlgo" if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "algoClOrdId", clientOrderId) } else { AddElementToObject(request, "algoId", id) } } else { if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "clOrdId", clientOrderId) } else { AddElementToObject(request, "ordId", id) } } var query interface{} = this.Omit(params, []interface{}{"method", "clOrdId", "clientOrderId", "stop", "trigger"}) var response interface{} = nil if IsTrue(IsEqual(method, "privateGetTradeOrderAlgo")) { response = (<-this.PrivateGetTradeOrderAlgo(this.Extend(request, query))) PanicOnError(response) } else { response = (<-this.PrivateGetTradeOrder(this.Extend(request, query))) PanicOnError(response) } // // Spot and Swap // // { // "code": "0", // "data": [ // { // "accFillSz": "0", // "avgPx": "", // "cTime": "1621910749815", // "category": "normal", // "ccy": "", // "clOrdId": "", // "fee": "0", // "feeCcy": "ETH", // "fillPx": "", // "fillSz": "0", // "fillTime": "", // "instId": "ETH-USDT", // "instType": "SPOT", // "lever": "", // "ordId": "317251910906576896", // "ordType": "limit", // "pnl": "0", // "posSide": "net", // "px":"20 00", // "rebate": "0", // "rebateCcy": "USDT", // "side": "buy", // "slOrdPx": "", // "slTriggerPx": "", // "state": "live", // "sz":"0. 001", // "tag": "", // "tdMode": "cash", // "tpOrdPx": "", // "tpTriggerPx": "", // "tradeId": "", // "uTime": "1621910749815" // } // ], // "msg": "" // } // // Algo order // { // "code":"0", // "msg":"", // "data":[ // { // "instType":"FUTURES", // "instId":"BTC-USD-200329", // "ordId":"123445", // "ccy":"BTC", // "clOrdId":"", // "algoId":"1234", // "sz":"999", // "closeFraction":"", // "ordType":"oco", // "side":"buy", // "posSide":"long", // "tdMode":"cross", // "tgtCcy": "", // "state":"effective", // "lever":"20", // "tpTriggerPx":"", // "tpTriggerPxType":"", // "tpOrdPx":"", // "slTriggerPx":"", // "slTriggerPxType":"", // "triggerPx":"99", // "triggerPxType":"last", // "ordPx":"12", // "actualSz":"", // "actualPx":"", // "actualSide":"", // "pxVar":"", // "pxSpread":"", // "pxLimit":"", // "szLimit":"", // "tag": "adadadadad", // "timeInterval":"", // "callbackRatio":"", // "callbackSpread":"", // "activePx":"", // "moveTriggerPx":"", // "reduceOnly": "false", // "triggerTime":"1597026383085", // "last": "16012", // "failCode": "", // "algoClOrdId": "", // "cTime":"1597026383000" // } // ] // } // var data interface{} = this.SafeValue(response, "data", []interface{}{}) var order interface{} = this.SafeDict(data, 0) ch <- this.ParseOrder(order, market) return nil }() return ch } /** * @method * @name okx#fetchOpenOrders * @description fetch all unfilled currently open orders * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-list * @see https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-list * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch open orders for * @param {int} [limit] the maximum number of open orders structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {bool} [params.trigger] True if fetching trigger or conditional orders * @param {string} [params.ordType] "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap" * @param {string} [params.algoId] Algo ID "'433845797218942976'" * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @param {boolean} [params.trailing] set to true if you want to fetch trailing orders * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) 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 retRes40578 := (<-this.LoadMarkets()) PanicOnError(retRes40578) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOpenOrders", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes406119 := (<-this.FetchPaginatedCallDynamic("fetchOpenOrders", symbol, since, limit, params)) PanicOnError(retRes406119) ch <- retRes406119 return nil } var request interface{} = map[string]interface{} {} var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "instId", GetValue(market, "id")) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 100 } var options interface{} = this.SafeValue(this.Options, "fetchOpenOrders", map[string]interface{} {}) var algoOrderTypes interface{} = this.SafeValue(this.Options, "algoOrderTypes", map[string]interface{} {}) var defaultMethod interface{} = this.SafeString(options, "method", "privateGetTradeOrdersPending") var method interface{} = this.SafeString(params, "method", defaultMethod) var ordType interface{} = this.SafeString(params, "ordType") var trigger interface{} = this.SafeValue2(params, "stop", "trigger") var trailing interface{} = this.SafeBool(params, "trailing", false) if IsTrue(IsTrue(IsTrue(trailing) || IsTrue(trigger)) || IsTrue((InOp(algoOrderTypes, ordType)))) { method = "privateGetTradeOrdersAlgoPending" } if IsTrue(trailing) { AddElementToObject(request, "ordType", "move_order_stop") } else if IsTrue(IsTrue(trigger) && IsTrue((IsEqual(ordType, nil)))) { AddElementToObject(request, "ordType", "trigger") } var query interface{} = this.Omit(params, []interface{}{"method", "stop", "trigger", "trailing"}) var response interface{} = nil if IsTrue(IsEqual(method, "privateGetTradeOrdersAlgoPending")) { response = (<-this.PrivateGetTradeOrdersAlgoPending(this.Extend(request, query))) PanicOnError(response) } else { response = (<-this.PrivateGetTradeOrdersPending(this.Extend(request, query))) PanicOnError(response) } // // { // "code": "0", // "data": [ // { // "accFillSz": "0", // "avgPx": "", // "cTime": "1621910749815", // "category": "normal", // "ccy": "", // "clOrdId": "", // "fee": "0", // "feeCcy": "ETH", // "fillPx": "", // "fillSz": "0", // "fillTime": "", // "instId": "ETH-USDT", // "instType": "SPOT", // "lever": "", // "ordId": "317251910906576896", // "ordType": "limit", // "pnl": "0", // "posSide": "net", // "px":"20 00", // "rebate": "0", // "rebateCcy": "USDT", // "side": "buy", // "slOrdPx": "", // "slTriggerPx": "", // "state": "live", // "sz":"0. 001", // "tag": "", // "tdMode": "cash", // "tpOrdPx": "", // "tpTriggerPx": "", // "tradeId": "", // "uTime": "1621910749815" // } // ], // "msg":"" // } // // Algo order // // { // "code": "0", // "data": [ // { // "activePx": "", // "activePxType": "", // "actualPx": "", // "actualSide": "buy", // "actualSz": "0", // "algoId": "431375349042380800", // "cTime": "1649119897778", // "callbackRatio": "", // "callbackSpread": "", // "ccy": "", // "ctVal": "0.01", // "instId": "BTC-USDT-SWAP", // "instType": "SWAP", // "last": "46538.9", // "lever": "125", // "moveTriggerPx": "", // "notionalUsd": "467.059", // "ordId": "", // "ordPx": "50000", // "ordType": "trigger", // "posSide": "long", // "pxLimit": "", // "pxSpread": "", // "pxVar": "", // "side": "buy", // "slOrdPx": "", // "slTriggerPx": "", // "slTriggerPxType": "", // "state": "live", // "sz": "1", // "szLimit": "", // "tag": "", // "tdMode": "isolated", // "tgtCcy": "", // "timeInterval": "", // "tpOrdPx": "", // "tpTriggerPx": "", // "tpTriggerPxType": "", // "triggerPx": "50000", // "triggerPxType": "last", // "triggerTime": "", // "uly": "BTC-USDT" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(data, market, since, limit) return nil }() return ch } /** * @method * @name okx#fetchCanceledOrders * @description fetches information on multiple canceled orders made by the user * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-7-days * @see https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-history * @param {string} symbol unified market symbol of the market orders were made in * @param {int} [since] timestamp in ms of the earliest order, default is undefined * @param {int} [limit] max number of orders to return, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {bool} [params.trigger] True if fetching trigger or conditional orders * @param {string} [params.ordType] "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap" * @param {string} [params.algoId] Algo ID "'433845797218942976'" * @param {int} [params.until] timestamp in ms to fetch orders for * @param {boolean} [params.trailing] set to true if you want to fetch trailing orders * @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) FetchCanceledOrders(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 retRes42208 := (<-this.LoadMarkets()) PanicOnError(retRes42208) var request interface{} = map[string]interface{} {} var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "instId", GetValue(market, "id")) } var typeVar interface{} = nil var query interface{} = nil typeVarqueryVariable := this.HandleMarketTypeAndParams("fetchCanceledOrders", market, params); typeVar = GetValue(typeVarqueryVariable,0); query = GetValue(typeVarqueryVariable,1) AddElementToObject(request, "instType", this.ConvertToInstrumentType(typeVar)) if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 100 } AddElementToObject(request, "state", "canceled") var options interface{} = this.SafeValue(this.Options, "fetchCanceledOrders", map[string]interface{} {}) var algoOrderTypes interface{} = this.SafeValue(this.Options, "algoOrderTypes", map[string]interface{} {}) var defaultMethod interface{} = this.SafeString(options, "method", "privateGetTradeOrdersHistory") var method interface{} = this.SafeString(params, "method", defaultMethod) var ordType interface{} = this.SafeString(params, "ordType") var trigger interface{} = this.SafeValue2(params, "stop", "trigger") var trailing interface{} = this.SafeBool(params, "trailing", false) if IsTrue(trailing) { method = "privateGetTradeOrdersAlgoHistory" AddElementToObject(request, "ordType", "move_order_stop") } else if IsTrue(IsTrue(trigger) || IsTrue((InOp(algoOrderTypes, ordType)))) { method = "privateGetTradeOrdersAlgoHistory" var algoId interface{} = this.SafeString(params, "algoId") if IsTrue(!IsEqual(algoId, nil)) { AddElementToObject(request, "algoId", algoId) params = this.Omit(params, "algoId") } if IsTrue(trigger) { if IsTrue(IsEqual(ordType, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchCanceledOrders() requires an \"ordType\" string parameter, \"conditional\", \"oco\", \"trigger\", \"move_order_stop\", \"iceberg\", or \"twap\""))) } } } else { if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "begin", since) } var until interface{} = this.SafeInteger(query, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "end", until) query = this.Omit(query, []interface{}{"until"}) } } var send interface{} = this.Omit(query, []interface{}{"method", "stop", "trigger", "trailing"}) var response interface{} = nil if IsTrue(IsEqual(method, "privateGetTradeOrdersAlgoHistory")) { response = (<-this.PrivateGetTradeOrdersAlgoHistory(this.Extend(request, send))) PanicOnError(response) } else { response = (<-this.PrivateGetTradeOrdersHistory(this.Extend(request, send))) PanicOnError(response) } // // { // "code": "0", // "data": [ // { // "accFillSz": "0", // "avgPx": "", // "cTime": "1644037822494", // "category": "normal", // "ccy": "", // "clOrdId": "", // "fee": "0", // "feeCcy": "BTC", // "fillPx": "", // "fillSz": "0", // "fillTime": "", // "instId": "BTC-USDT", // "instType": "SPOT", // "lever": "", // "ordId": "410059580352409602", // "ordType": "limit", // "pnl": "0", // "posSide": "net", // "px": "30000", // "rebate": "0", // "rebateCcy": "USDT", // "side": "buy", // "slOrdPx": "", // "slTriggerPx": "", // "slTriggerPxType": "", // "source": "", // "state": "canceled", // "sz": "0.0005452", // "tag": "", // "tdMode": "cash", // "tgtCcy": "", // "tpOrdPx": "", // "tpTriggerPx": "", // "tpTriggerPxType": "", // "tradeId": "", // "uTime": "1644038165667" // } // ], // "msg": "" // } // // Algo order // // { // "code": "0", // "data": [ // { // "activePx": "", // "activePxType": "", // "actualPx": "", // "actualSide": "buy", // "actualSz": "0", // "algoId": "433845797218942976", // "cTime": "1649708898523", // "callbackRatio": "", // "callbackSpread": "", // "ccy": "", // "ctVal": "0.01", // "instId": "BTC-USDT-SWAP", // "instType": "SWAP", // "last": "39950.4", // "lever": "125", // "moveTriggerPx": "", // "notionalUsd": "1592.1760000000002", // "ordId": "", // "ordPx": "29000", // "ordType": "trigger", // "posSide": "long", // "pxLimit": "", // "pxSpread": "", // "pxVar": "", // "side": "buy", // "slOrdPx": "", // "slTriggerPx": "", // "slTriggerPxType": "", // "state": "canceled", // "sz": "4", // "szLimit": "", // "tag": "", // "tdMode": "isolated", // "tgtCcy": "", // "timeInterval": "", // "tpOrdPx": "", // "tpTriggerPx": "", // "tpTriggerPxType": "", // "triggerPx": "30000", // "triggerPxType": "last", // "triggerTime": "", // "uly": "BTC-USDT" // }, // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(data, market, since, limit) return nil }() return ch } /** * @method * @name okx#fetchClosedOrders * @description fetches information on multiple closed orders made by the user * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-7-days * @see https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-history * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-3-months * @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 {bool} [params.trigger] True if fetching trigger or conditional orders * @param {string} [params.ordType] "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap" * @param {string} [params.algoId] Algo ID "'433845797218942976'" * @param {int} [params.until] timestamp in ms to fetch orders for * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @param {string} [params.method] method to be used, either 'privateGetTradeOrdersHistory', 'privateGetTradeOrdersHistoryArchive' or 'privateGetTradeOrdersAlgoHistory' default is 'privateGetTradeOrdersHistory' * @param {boolean} [params.trailing] set to true if you want to fetch trailing orders * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *okx) FetchClosedOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes44088 := (<-this.LoadMarkets()) PanicOnError(retRes44088) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchClosedOrders", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes441219 := (<-this.FetchPaginatedCallDynamic("fetchClosedOrders", symbol, since, limit, params)) PanicOnError(retRes441219) ch <- retRes441219 return nil } var request interface{} = map[string]interface{} {} var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "instId", GetValue(market, "id")) } var typeVar interface{} = nil var query interface{} = nil typeVarqueryVariable := this.HandleMarketTypeAndParams("fetchClosedOrders", market, params); typeVar = GetValue(typeVarqueryVariable,0); query = GetValue(typeVarqueryVariable,1) AddElementToObject(request, "instType", this.ConvertToInstrumentType(typeVar)) if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 100 } var options interface{} = this.SafeDict(this.Options, "fetchClosedOrders", map[string]interface{} {}) var algoOrderTypes interface{} = this.SafeDict(this.Options, "algoOrderTypes", map[string]interface{} {}) var defaultMethod interface{} = this.SafeString(options, "method", "privateGetTradeOrdersHistory") var method interface{} = this.SafeString(params, "method", defaultMethod) var ordType interface{} = this.SafeString(params, "ordType") var trigger interface{} = this.SafeBool2(params, "stop", "trigger") var trailing interface{} = this.SafeBool(params, "trailing", false) if IsTrue(IsTrue(IsTrue(trailing) || IsTrue(trigger)) || IsTrue((InOp(algoOrderTypes, ordType)))) { method = "privateGetTradeOrdersAlgoHistory" AddElementToObject(request, "state", "effective") } if IsTrue(trailing) { AddElementToObject(request, "ordType", "move_order_stop") } else if IsTrue(trigger) { if IsTrue(IsEqual(ordType, nil)) { AddElementToObject(request, "ordType", "trigger") } } else { if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "begin", since) } var until interface{} = this.SafeInteger(query, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "end", until) query = this.Omit(query, []interface{}{"until"}) } AddElementToObject(request, "state", "filled") } var send interface{} = this.Omit(query, []interface{}{"method", "stop", "trigger", "trailing"}) var response interface{} = nil if IsTrue(IsEqual(method, "privateGetTradeOrdersAlgoHistory")) { response = (<-this.PrivateGetTradeOrdersAlgoHistory(this.Extend(request, send))) PanicOnError(response) } else if IsTrue(IsEqual(method, "privateGetTradeOrdersHistoryArchive")) { response = (<-this.PrivateGetTradeOrdersHistoryArchive(this.Extend(request, send))) PanicOnError(response) } else { response = (<-this.PrivateGetTradeOrdersHistory(this.Extend(request, send))) PanicOnError(response) } // // { // "code": "0", // "data": [ // { // "accFillSz": "0", // "avgPx": "", // "cTime": "1621910749815", // "category": "normal", // "ccy": "", // "clOrdId": "", // "fee": "0", // "feeCcy": "ETH", // "fillPx": "", // "fillSz": "0", // "fillTime": "", // "instId": "ETH-USDT", // "instType": "SPOT", // "lever": "", // "ordId": "317251910906576896", // "ordType": "limit", // "pnl": "0", // "posSide": "net", // "px": "2000", // "rebate": "0", // "rebateCcy": "USDT", // "side": "buy", // "slOrdPx": "", // "slTriggerPx": "", // "state": "live", // "sz": "0.001", // "tag": "", // "tdMode": "cash", // "tpOrdPx": "", // "tpTriggerPx": "", // "tradeId": "", // "uTime": "1621910749815" // } // ], // "msg": "" // } // // Algo order // // { // "code": "0", // "data": [ // { // "activePx": "", // "activePxType": "", // "actualPx": "", // "actualSide": "buy", // "actualSz": "0", // "algoId": "433845797218942976", // "cTime": "1649708898523", // "callbackRatio": "", // "callbackSpread": "", // "ccy": "", // "ctVal": "0.01", // "instId": "BTC-USDT-SWAP", // "instType": "SWAP", // "last": "39950.4", // "lever": "125", // "moveTriggerPx": "", // "notionalUsd": "1592.1760000000002", // "ordId": "", // "ordPx": "29000", // "ordType": "trigger", // "posSide": "long", // "pxLimit": "", // "pxSpread": "", // "pxVar": "", // "side": "buy", // "slOrdPx": "", // "slTriggerPx": "", // "slTriggerPxType": "", // "state": "effective", // "sz": "4", // "szLimit": "", // "tag": "", // "tdMode": "isolated", // "tgtCcy": "", // "timeInterval": "", // "tpOrdPx": "", // "tpTriggerPx": "", // "tpTriggerPxType": "", // "triggerPx": "30000", // "triggerPxType": "last", // "triggerTime": "", // "uly": "BTC-USDT" // }, // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(data, market, since, limit) return nil }() return ch } /** * @method * @name okx#fetchMyTrades * @description fetch all trades made by the user * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-transaction-details-last-3-months * @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 {int} [params.until] Timestamp in ms of the latest time to retrieve trades 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 {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *okx) 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 retRes45878 := (<-this.LoadMarkets()) PanicOnError(retRes45878) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchMyTrades", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes459119 := (<-this.FetchPaginatedCallDynamic("fetchMyTrades", symbol, since, limit, params)) PanicOnError(retRes459119) ch <- retRes459119 return nil } var request interface{} = map[string]interface{} {} var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "instId", GetValue(market, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "begin", since) } requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) typeVarqueryVariable := this.HandleMarketTypeAndParams("fetchMyTrades", market, params); typeVar := GetValue(typeVarqueryVariable,0); query := GetValue(typeVarqueryVariable,1) AddElementToObject(request, "instType", this.ConvertToInstrumentType(typeVar)) if IsTrue(IsTrue((!IsEqual(limit, nil))) && IsTrue((IsEqual(since, nil)))) { AddElementToObject(request, "limit", limit) // default 100, max 100 } response:= (<-this.PrivateGetTradeFillsHistory(this.Extend(request, query))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "side": "buy", // "fillSz": "0.007533", // "fillPx": "2654.98", // "fee": "-0.000007533", // "ordId": "317321390244397056", // "instType": "SPOT", // "instId": "ETH-USDT", // "clOrdId": "", // "posSide": "net", // "billId": "317321390265368576", // "tag": "0", // "execType": "T", // "tradeId": "107601752", // "feeCcy": "ETH", // "ts": "1621927314985" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTrades(data, market, since, limit, query) return nil }() return ch } /** * @method * @name okx#fetchOrderTrades * @description fetch all the trades made from a single order * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-transaction-details-last-3-months * @param {string} id order id * @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 to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *okx) FetchOrderTrades(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 since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params var request interface{} = map[string]interface{} { "ordId": id, } retRes466615 := (<-this.FetchMyTrades(symbol, since, limit, this.Extend(request, params))) PanicOnError(retRes466615) ch <- retRes466615 return nil }() return ch } /** * @method * @name okx#fetchLedger * @description fetch the history of changes, actions done by the user or operations that altered balance of the user * @see https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days * @see https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months * @see https://www.okx.com/docs-v5/en/#rest-api-funding-asset-bills-details * @param {string} [code] unified currency code, default is undefined * @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined * @param {int} [limit] max number of ledger entries to return, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.marginMode] 'cross' or 'isolated' * @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 [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger} */ func (this *okx) FetchLedger(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes46868 := (<-this.LoadMarkets()) PanicOnError(retRes46868) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchLedger", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes469019 := (<-this.FetchPaginatedCallDynamic("fetchLedger", code, since, limit, params)) PanicOnError(retRes469019) ch <- retRes469019 return nil } var options interface{} = this.SafeDict(this.Options, "fetchLedger", map[string]interface{} {}) var method interface{} = this.SafeString(options, "method") method = this.SafeString(params, "method", method) params = this.Omit(params, "method") var request interface{} = map[string]interface{} {} var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchLedger", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) if IsTrue(IsEqual(marginMode, nil)) { marginMode = this.SafeString(params, "mgnMode") } if IsTrue(!IsEqual(method, "privateGetAssetBills")) { if IsTrue(!IsEqual(marginMode, nil)) { AddElementToObject(request, "mgnMode", marginMode) } } typeVarqueryVariable := this.HandleMarketTypeAndParams("fetchLedger", nil, params); typeVar := GetValue(typeVarqueryVariable,0); query := GetValue(typeVarqueryVariable,1) if IsTrue(!IsEqual(typeVar, nil)) { AddElementToObject(request, "instType", this.ConvertToInstrumentType(typeVar)) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "ccy", GetValue(currency, "id")) } requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) var response interface{} = nil if IsTrue(IsEqual(method, "privateGetAccountBillsArchive")) { response = (<-this.PrivateGetAccountBillsArchive(this.Extend(request, query))) PanicOnError(response) } else if IsTrue(IsEqual(method, "privateGetAssetBills")) { response = (<-this.PrivateGetAssetBills(this.Extend(request, query))) PanicOnError(response) } else { response = (<-this.PrivateGetAccountBills(this.Extend(request, query))) PanicOnError(response) } // // privateGetAccountBills, privateGetAccountBillsArchive // // { // "code": "0", // "msg": "", // "data": [ // { // "bal": "0.0000819307998198", // "balChg": "-664.2679586599999802", // "billId": "310394313544966151", // "ccy": "USDT", // "fee": "0", // "from": "", // "instId": "LTC-USDT", // "instType": "SPOT", // "mgnMode": "cross", // "notes": "", // "ordId": "310394313519800320", // "pnl": "0", // "posBal": "0", // "posBalChg": "0", // "subType": "2", // "sz": "664.26795866", // "to": "", // "ts": "1620275771196", // "type": "2" // } // ] // } // // privateGetAssetBills // // { // "code": "0", // "msg": "", // "data": [ // { // "billId": "12344", // "ccy": "BTC", // "balChg": "2", // "bal": "12", // "type": "1", // "ts": "1597026383085" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseLedger(data, currency, since, limit) return nil }() return ch } func (this *okx) ParseLedgerEntryType(typeVar interface{}) interface{} { var types interface{} = map[string]interface{} { "1": "transfer", "2": "trade", "3": "trade", "4": "rebate", "5": "trade", "6": "transfer", "7": "trade", "8": "fee", "9": "trade", "10": "trade", "11": "trade", } return this.SafeString(types, typeVar, typeVar) } func (this *okx) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} { // // privateGetAccountBills, privateGetAccountBillsArchive // // { // "bal": "0.0000819307998198", // "balChg": "-664.2679586599999802", // "billId": "310394313544966151", // "ccy": "USDT", // "fee": "0", // "from": "", // "instId": "LTC-USDT", // "instType": "SPOT", // "mgnMode": "cross", // "notes": "", // "ordId": "310394313519800320", // "pnl": "0", // "posBal": "0", // "posBalChg": "0", // "subType": "2", // "sz": "664.26795866", // "to": "", // "ts": "1620275771196", // "type": "2" // } // // privateGetAssetBills // // { // "billId": "12344", // "ccy": "BTC", // "balChg": "2", // "bal": "12", // "type": "1", // "ts": "1597026383085" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var currencyId interface{} = this.SafeString(item, "ccy") var code interface{} = this.SafeCurrencyCode(currencyId, currency) currency = this.SafeCurrency(currencyId, currency) var timestamp interface{} = this.SafeInteger(item, "ts") var feeCostString interface{} = this.SafeString(item, "fee") var fee interface{} = nil if IsTrue(!IsEqual(feeCostString, nil)) { fee = map[string]interface{} { "cost": this.ParseNumber(Precise.StringNeg(feeCostString)), "currency": code, } } var marketId interface{} = this.SafeString(item, "instId") var symbol interface{} = this.SafeSymbol(marketId, nil, "-") return this.SafeLedgerEntry(map[string]interface{} { "info": item, "id": this.SafeString(item, "billId"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "account": nil, "referenceId": this.SafeString(item, "ordId"), "referenceAccount": nil, "type": this.ParseLedgerEntryType(this.SafeString(item, "type")), "currency": code, "symbol": symbol, "amount": this.SafeNumber(item, "balChg"), "before": nil, "after": this.SafeNumber(item, "bal"), "status": "ok", "fee": fee, }, currency) } func (this *okx) ParseDepositAddress(depositAddress interface{}, optionalArgs ...interface{}) interface{} { // // { // "addr": "okbtothemoon", // "memo": "971668", // may be missing // "tag":"52055", // may be missing // "pmtId": "", // may be missing // "ccy": "BTC", // "to": "6", // 1 SPOT, 3 FUTURES, 6 FUNDING, 9 SWAP, 12 OPTION, 18 Unified account // "selected": true // } // // { // "ccy":"usdt-erc20", // "to":"6", // "addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa", // "selected":true // } // // { // "chain": "ETH-OKExChain", // "addrEx": { "comment": "6040348" }, // some currencies like TON may have this field, // "ctAddr": "72315c", // "ccy": "ETH", // "to": "6", // "addr": "0x1c9f2244d1ccaa060bd536827c18925db10db102", // "selected": true // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var address interface{} = this.SafeString(depositAddress, "addr") var tag interface{} = this.SafeStringN(depositAddress, []interface{}{"tag", "pmtId", "memo"}) if IsTrue(IsEqual(tag, nil)) { var addrEx interface{} = this.SafeValue(depositAddress, "addrEx", map[string]interface{} {}) tag = this.SafeString(addrEx, "comment") } var currencyId interface{} = this.SafeString(depositAddress, "ccy") currency = this.SafeCurrency(currencyId, currency) var code interface{} = GetValue(currency, "code") var chain interface{} = this.SafeString(depositAddress, "chain") var networks interface{} = this.SafeValue(currency, "networks", map[string]interface{} {}) var networksById interface{} = this.IndexBy(networks, "id") var networkData interface{} = this.SafeValue(networksById, chain) // inconsistent naming responses from exchange // with respect to network naming provided in currency info vs address chain-names and ids // // response from address endpoint: // { // "chain": "USDT-Polygon", // "ctAddr": "", // "ccy": "USDT", // "to":"6" , // "addr": "0x1903441e386cc49d937f6302955b5feb4286dcfa", // "selected": true // } // network information from currency['networks'] field: // Polygon: { // info: { // canDep: false, // canInternal: false, // canWd: false, // ccy: 'USDT', // chain: 'USDT-Polygon-Bridge', // mainNet: false, // maxFee: '26.879528', // minFee: '13.439764', // minWd: '0.001', // name: '' // }, // id: 'USDT-Polygon-Bridge', // network: 'Polygon', // active: false, // deposit: false, // withdraw: false, // fee: 13.439764, // precision: undefined, // limits: { // withdraw: { // min: 0.001, // max: undefined // } // } // }, // if IsTrue(IsEqual(chain, "USDT-Polygon")) { networkData = this.SafeValue2(networksById, "USDT-Polygon-Bridge", "USDT-Polygon") } var network interface{} = this.SafeString(networkData, "network") var networkCode interface{} = this.NetworkIdToCode(network, code) this.CheckAddress(address) return map[string]interface{} { "info": depositAddress, "currency": code, "network": networkCode, "address": address, "tag": tag, } } /** * @method * @name okx#fetchDepositAddressesByNetwork * @description fetch a dictionary of addresses for a currency, indexed by network * @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address * @param {string} code unified currency code of the currency for the deposit address * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [address structures]{@link https://docs.ccxt.com/#/?id=address-structure} indexed by the network */ func (this *okx) FetchDepositAddressesByNetwork(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes49878 := (<-this.LoadMarkets()) PanicOnError(retRes49878) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "ccy": GetValue(currency, "id"), } response:= (<-this.PrivateGetAssetDepositAddress(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "", // "data": [ // { // "addr": "okbtothemoon", // "memo": "971668", // may be missing // "tag":"52055", // may be missing // "pmtId": "", // may be missing // "ccy": "BTC", // "to": "6", // 1 SPOT, 3 FUTURES, 6 FUNDING, 9 SWAP, 12 OPTION, 18 Unified account // "selected": true // }, // // {"ccy":"usdt-erc20","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true}, // // {"ccy":"usdt-trc20","to":"6","addr":"TRrd5SiSZrfQVRKm4e9SRSbn2LNTYqCjqx","selected":true}, // // {"ccy":"usdt_okexchain","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true}, // // {"ccy":"usdt_kip20","to":"6","addr":"0x696abb81974a8793352cbd33aadcf78eda3cfdfa","selected":true}, // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var filtered interface{} = this.FilterBy(data, "selected", true) var parsed interface{} = this.ParseDepositAddresses(filtered, []interface{}{GetValue(currency, "code")}, false) ch <- this.IndexBy(parsed, "network") return nil }() return ch } /** * @method * @name okx#fetchDepositAddress * @description fetch the deposit address for a currency associated with this account * @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address * @param {string} code unified currency code * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.network] the network name for the deposit address * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure} */ func (this *okx) FetchDepositAddress(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes50318 := (<-this.LoadMarkets()) PanicOnError(retRes50318) var rawNetwork interface{} = this.SafeStringUpper(params, "network") params = this.Omit(params, "network") code = this.SafeCurrencyCode(code) var network interface{} = this.NetworkIdToCode(rawNetwork, code) response:= (<-this.FetchDepositAddressesByNetwork(code, params)) PanicOnError(response) if IsTrue(!IsEqual(network, nil)) { var result interface{} = this.SafeDict(response, network) if IsTrue(IsEqual(result, nil)) { panic(InvalidAddress(Add(Add(Add(Add(this.Id, " fetchDepositAddress() cannot find "), network), " deposit address for "), code))) } ch <- result return nil } var codeNetwork interface{} = this.NetworkIdToCode(code, code) if IsTrue(InOp(response, codeNetwork)) { ch <- GetValue(response, codeNetwork) return nil } // if the network is not specified, return the first address var keys interface{} = ObjectKeys(response) var first interface{} = this.SafeString(keys, 0) ch <- this.SafeDict(response, first) return nil }() return ch } /** * @method * @name okx#withdraw * @description make a withdrawal * @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-withdrawal * @param {string} code unified currency code * @param {float} amount the amount to withdraw * @param {string} address the address to withdraw to * @param {string} tag * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *okx) Withdraw(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) tag := GetArg(optionalArgs, 0, nil) _ = tag params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params tagparamsVariable := this.HandleWithdrawTagAndParams(tag, params); tag = GetValue(tagparamsVariable,0); params = GetValue(tagparamsVariable,1) this.CheckAddress(address) retRes50698 := (<-this.LoadMarkets()) PanicOnError(retRes50698) var currency interface{} = this.Currency(code) if IsTrue(IsTrue((!IsEqual(tag, nil))) && IsTrue((IsGreaterThan(GetArrayLength(tag), 0)))) { address = Add(Add(address, ":"), tag) } var request interface{} = map[string]interface{} { "ccy": GetValue(currency, "id"), "toAddr": address, "dest": "4", "amt": this.NumberToString(amount), } var network interface{} = this.SafeString(params, "network") // this line allows the user to specify either ERC20 or ETH if IsTrue(!IsEqual(network, nil)) { var networks interface{} = this.SafeDict(this.Options, "networks", map[string]interface{} {}) network = this.SafeString(networks, ToUpper(network), network) // handle ETH>ERC20 alias AddElementToObject(request, "chain", Add(Add(GetValue(currency, "id"), "-"), network)) params = this.Omit(params, "network") } var fee interface{} = this.SafeString(params, "fee") if IsTrue(IsEqual(fee, nil)) { currencies:= (<-this.FetchCurrencies()) PanicOnError(currencies) this.Currencies = this.DeepExtend(this.Currencies, currencies) var targetNetwork interface{} = this.SafeDict(GetValue(currency, "networks"), this.NetworkIdToCode(network), map[string]interface{} {}) fee = this.SafeString(targetNetwork, "fee") if IsTrue(IsEqual(fee, nil)) { panic(ArgumentsRequired(Add(this.Id, " withdraw() requires a \"fee\" string parameter, network transaction fee must be ≥ 0. Withdrawals to OKCoin or OKX are fee-free, please set \"0\". Withdrawing to external digital asset address requires network transaction fee."))) } } AddElementToObject(request, "fee", this.NumberToString(fee)) // withdrawals to OKCoin or OKX are fee-free, please set 0 var query interface{} = this.Omit(params, []interface{}{"fee"}) response:= (<-this.PrivatePostAssetWithdrawal(this.Extend(request, query))) PanicOnError(response) // // { // "code": "0", // "msg": "", // "data": [ // { // "amt": "0.1", // "wdId": "67485", // "ccy": "BTC" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var transaction interface{} = this.SafeDict(data, 0) ch <- this.ParseTransaction(transaction, currency) return nil }() return ch } /** * @method * @name okx#fetchDeposits * @description fetch all deposits made to an account * @see https://www.okx.com/docs-v5/en/#rest-api-funding-get-deposit-history * @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 *okx) 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 retRes51328 := (<-this.LoadMarkets()) PanicOnError(retRes51328) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchDeposits", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes513619 := (<-this.FetchPaginatedCallDynamic("fetchDeposits", code, since, limit, params)) PanicOnError(retRes513619) ch <- retRes513619 return nil } var request interface{} = map[string]interface{} {} var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "ccy", GetValue(currency, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "before", mathMax(Subtract(since, 1), 0)) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 100 } requestparamsVariable := this.HandleUntilOption("after", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.PrivateGetAssetDepositHistory(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "", // "data": [ // { // "amt": "0.01044408", // "txId": "1915737_3_0_0_asset", // "ccy": "BTC", // "from": "13801825426", // "to": "", // "ts": "1597026383085", // "state": "2", // "depId": "4703879" // }, // { // "amt": "491.6784211", // "txId": "1744594_3_184_0_asset", // "ccy": "OKB", // "from": "", // "to": "", // "ts": "1597026383085", // "state": "2", // "depId": "4703809" // }, // { // "amt": "223.18782496", // "txId": "6d892c669225b1092c780bf0da0c6f912fc7dc8f6b8cc53b003288624c", // "ccy": "USDT", // "from": "", // "to": "39kK4XvgEuM7rX9frgyHoZkWqx4iKu1spD", // "ts": "1597026383085", // "state": "2", // "depId": "4703779" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTransactions(data, currency, since, limit, params) return nil }() return ch } /** * @method * @name okx#fetchDeposit * @description fetch data on a currency deposit via the deposit id * @see https://www.okx.com/docs-v5/en/#rest-api-funding-get-deposit-history * @param {string} id deposit id * @param {string} code filter by currency code * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *okx) FetchDeposit(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes52118 := (<-this.LoadMarkets()) PanicOnError(retRes52118) var request interface{} = map[string]interface{} { "depId": id, } var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "ccy", GetValue(currency, "id")) } response:= (<-this.PrivateGetAssetDepositHistory(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeValue(response, "data") var deposit interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseTransaction(deposit, currency) return nil }() return ch } /** * @method * @name okx#fetchWithdrawals * @description fetch all withdrawals made from an account * @see https://www.okx.com/docs-v5/en/#rest-api-funding-get-withdrawal-history * @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 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 *okx) 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 retRes52408 := (<-this.LoadMarkets()) PanicOnError(retRes52408) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchWithdrawals", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes524419 := (<-this.FetchPaginatedCallDynamic("fetchWithdrawals", code, since, limit, params)) PanicOnError(retRes524419) ch <- retRes524419 return nil } var request interface{} = map[string]interface{} {} var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "ccy", GetValue(currency, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "before", mathMax(Subtract(since, 1), 0)) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 100 } requestparamsVariable := this.HandleUntilOption("after", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.PrivateGetAssetWithdrawalHistory(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "", // "data": [ // { // "amt": "0.094", // "wdId": "4703879", // "fee": "0.01000000eth", // "txId": "0x62477bac6509a04512819bb1455e923a60dea5966c7caeaa0b24eb8fb0432b85", // "ccy": "ETH", // "from": "13426335357", // "to": "0xA41446125D0B5b6785f6898c9D67874D763A1519", // "ts": "1597026383085", // "state": "2" // }, // { // "amt": "0.01", // "wdId": "4703879", // "fee": "0.00000000btc", // "txId": "", // "ccy": "BTC", // "from": "13426335357", // "to": "13426335357", // "ts": "1597026383085", // "state": "2" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTransactions(data, currency, since, limit, params) return nil }() return ch } /** * @method * @name okx#fetchWithdrawal * @description fetch data on a currency withdrawal via the withdrawal id * @see https://www.okx.com/docs-v5/en/#rest-api-funding-get-withdrawal-history * @param {string} id withdrawal id * @param {string} code unified currency code of the currency withdrawn, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *okx) FetchWithdrawal(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes53118 := (<-this.LoadMarkets()) PanicOnError(retRes53118) var request interface{} = map[string]interface{} { "wdId": id, } var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "ccy", GetValue(currency, "id")) } response:= (<-this.PrivateGetAssetWithdrawalHistory(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "chain": "USDT-TRC20", // "clientId": '', // "fee": "0.8", // "ccy": "USDT", // "amt": "54.561", // "txId": "00cff6ec7fa7c7d7d184bd84e82b9ff36863f07c0421188607f87dfa94e06b70", // "from": "example@email.com", // "to": "TEY6qjnKDyyq5jDc3DJizWLCdUySrpQ4yp", // "state": "2", // "ts": "1641376485000", // "wdId": "25147041" // } // ], // "msg": '' // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var withdrawal interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseTransaction(withdrawal) return nil }() return ch } func (this *okx) ParseTransactionStatus(status interface{}) interface{} { // // deposit statuses // // { // "0": "waiting for confirmation", // "1": "deposit credited", // "2": "deposit successful" // } // // withdrawal statuses // // { // '-3': "pending cancel", // "-2": "canceled", // "-1": "failed", // "0": "pending", // "1": "sending", // "2": "sent", // "3": "awaiting email verification", // "4": "awaiting manual verification", // "5": "awaiting identity verification" // } // var statuses interface{} = map[string]interface{} { "-3": "pending", "-2": "canceled", "-1": "failed", "0": "pending", "1": "pending", "2": "ok", "3": "pending", "4": "pending", "5": "pending", "6": "pending", "7": "pending", "8": "pending", "9": "pending", "10": "pending", "12": "pending", "15": "pending", "16": "pending", } return this.SafeString(statuses, status, status) } func (this *okx) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // withdraw // // { // "amt": "0.1", // "wdId": "67485", // "ccy": "BTC" // } // // fetchWithdrawals // // { // "amt": "0.094", // "wdId": "4703879", // "fee": "0.01000000eth", // "txId": "0x62477bac6509a04512819bb1455e923a60dea5966c7caeaa0b24eb8fb0432b85", // "ccy": "ETH", // "from": "13426335357", // "to": "0xA41446125D0B5b6785f6898c9D67874D763A1519", // "tag", // "pmtId", // "memo", // "ts": "1597026383085", // "state": "2" // } // // fetchDeposits // // { // "amt": "0.01044408", // "txId": "1915737_3_0_0_asset", // "ccy": "BTC", // "from": "13801825426", // "to": "", // "ts": "1597026383085", // "state": "2", // "depId": "4703879" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var typeVar interface{} = nil var id interface{} = nil var withdrawalId interface{} = this.SafeString(transaction, "wdId") var addressFrom interface{} = this.SafeString(transaction, "from") var addressTo interface{} = this.SafeString(transaction, "to") var address interface{} = addressTo var tagTo interface{} = this.SafeString2(transaction, "tag", "memo") tagTo = this.SafeString2(transaction, "pmtId", tagTo) if IsTrue(!IsEqual(withdrawalId, nil)) { typeVar = "withdrawal" id = withdrawalId } else { // the payment_id will appear on new deposits but appears to be removed from the response after 2 months id = this.SafeString(transaction, "depId") typeVar = "deposit" } var currencyId interface{} = this.SafeString(transaction, "ccy") var code interface{} = this.SafeCurrencyCode(currencyId) var amount interface{} = this.SafeNumber(transaction, "amt") var status interface{} = this.ParseTransactionStatus(this.SafeString(transaction, "state")) var txid interface{} = this.SafeString(transaction, "txId") var timestamp interface{} = this.SafeInteger(transaction, "ts") var feeCost interface{} = nil if IsTrue(IsEqual(typeVar, "deposit")) { feeCost = 0 } else { feeCost = this.SafeNumber(transaction, "fee") } // todo parse tags return map[string]interface{} { "info": transaction, "id": id, "currency": code, "amount": amount, "network": nil, "addressFrom": addressFrom, "addressTo": addressTo, "address": address, "tagFrom": nil, "tagTo": tagTo, "tag": tagTo, "status": status, "type": typeVar, "updated": nil, "txid": txid, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "internal": nil, "comment": nil, "fee": map[string]interface{} { "currency": code, "cost": feeCost, }, } } /** * @method * @name okx#fetchLeverage * @description fetch the set leverage for a market * @see https://www.okx.com/docs-v5/en/#rest-api-account-get-leverage * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.marginMode] 'cross' or 'isolated' * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure} */ func (this *okx) FetchLeverage(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 retRes55008 := (<-this.LoadMarkets()) PanicOnError(retRes55008) var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchLeverage", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) if IsTrue(IsEqual(marginMode, nil)) { marginMode = this.SafeString(params, "mgnMode", "cross") // cross as default marginMode } if IsTrue(IsTrue((!IsEqual(marginMode, "cross"))) && IsTrue((!IsEqual(marginMode, "isolated")))) { panic(BadRequest(Add(this.Id, " fetchLeverage() requires a marginMode parameter that must be either cross or isolated"))) } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), "mgnMode": marginMode, } response:= (<-this.PrivateGetAccountLeverageInfo(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "instId": "BTC-USDT-SWAP", // "lever": "5.00000000", // "mgnMode": "isolated", // "posSide": "net" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseLeverage(data, market) return nil }() return ch } func (this *okx) ParseLeverage(leverage interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = nil var marginMode interface{} = nil var longLeverage interface{} = nil var shortLeverage interface{} = nil for i := 0; IsLessThan(i, GetArrayLength(leverage)); i++ { var entry interface{} = GetValue(leverage, i) marginMode = this.SafeStringLower(entry, "mgnMode") marketId = this.SafeString(entry, "instId") var positionSide interface{} = this.SafeStringLower(entry, "posSide") if IsTrue(IsEqual(positionSide, "long")) { longLeverage = this.SafeInteger(entry, "lever") } else if IsTrue(IsEqual(positionSide, "short")) { shortLeverage = this.SafeInteger(entry, "lever") } else { longLeverage = this.SafeInteger(entry, "lever") shortLeverage = this.SafeInteger(entry, "lever") } } return map[string]interface{} { "info": leverage, "symbol": this.SafeSymbol(marketId, market), "marginMode": marginMode, "longLeverage": longLeverage, "shortLeverage": shortLeverage, } } /** * @method * @name okx#fetchPosition * @description fetch data on a single open contract trade position * @see https://www.okx.com/docs-v5/en/#rest-api-account-get-positions * @param {string} symbol unified market symbol of the market the position is held in, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.instType] MARGIN, SWAP, FUTURES, OPTION * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *okx) 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 retRes55728 := (<-this.LoadMarkets()) PanicOnError(retRes55728) var market interface{} = this.Market(symbol) typeVarqueryVariable := this.HandleMarketTypeAndParams("fetchPosition", market, params); typeVar := GetValue(typeVarqueryVariable,0); query := GetValue(typeVarqueryVariable,1) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } if IsTrue(!IsEqual(typeVar, nil)) { AddElementToObject(request, "instType", this.ConvertToInstrumentType(typeVar)) } response:= (<-this.PrivateGetAccountPositions(this.Extend(request, query))) PanicOnError(response) // // { // "code": "0", // "msg": "", // "data": [ // { // "adl": "1", // "availPos": "1", // "avgPx": "2566.31", // "cTime": "1619507758793", // "ccy": "ETH", // "deltaBS": "", // "deltaPA": "", // "gammaBS": "", // "gammaPA": "", // "imr": "", // "instId": "ETH-USD-210430", // "instType": "FUTURES", // "interest": "0", // "last": "2566.22", // "lever": "10", // "liab": "", // "liabCcy": "", // "liqPx": "2352.8496681818233", // "margin": "0.0003896645377994", // "mgnMode": "isolated", // "mgnRatio": "11.731726509588816", // "mmr": "0.0000311811092368", // "optVal": "", // "pTime": "1619507761462", // "pos": "1", // "posCcy": "", // "posId": "307173036051017730", // "posSide": "long", // "thetaBS": "", // "thetaPA": "", // "tradeId": "109844", // "uTime": "1619507761462", // "upl": "-0.0000009932766034", // "uplRatio": "-0.0025490556801078", // "vegaBS": "", // "vegaPA": "" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var position interface{} = this.SafeDict(data, 0) if IsTrue(IsEqual(position, nil)) { return nil } ch <- this.ParsePosition(position, market) return nil }() return ch } /** * @method * @name okx#fetchPositions * @see https://www.okx.com/docs-v5/en/#rest-api-account-get-positions * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-positions-history history * @description fetch all open positions * @param {string[]|undefined} symbols list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.instType] MARGIN, SWAP, FUTURES, OPTION * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *okx) 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 retRes56508 := (<-this.LoadMarkets()) PanicOnError(retRes56508) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(symbols, nil)) { var marketIds interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(symbols)); i++ { var entry interface{} = GetValue(symbols, i) var market interface{} = this.Market(entry) AppendToArray(&marketIds,GetValue(market, "id")) } var marketIdsLength interface{} = GetArrayLength(marketIds) if IsTrue(IsGreaterThan(marketIdsLength, 0)) { AddElementToObject(request, "instId", Join(marketIds, ",")) } } var fetchPositionsOptions interface{} = this.SafeDict(this.Options, "fetchPositions", map[string]interface{} {}) var method interface{} = this.SafeString(fetchPositionsOptions, "method", "privateGetAccountPositions") var response interface{} = nil if IsTrue(IsEqual(method, "privateGetAccountPositionsHistory")) { response = (<-this.PrivateGetAccountPositionsHistory(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateGetAccountPositions(this.Extend(request, params))) PanicOnError(response) } // // { // "code": "0", // "msg": "", // "data": [ // { // "adl": "1", // "availPos": "1", // "avgPx": "2566.31", // "cTime": "1619507758793", // "ccy": "ETH", // "deltaBS": "", // "deltaPA": "", // "gammaBS": "", // "gammaPA": "", // "imr": "", // "instId": "ETH-USD-210430", // "instType": "FUTURES", // "interest": "0", // "last": "2566.22", // "lever": "10", // "liab": "", // "liabCcy": "", // "liqPx": "2352.8496681818233", // "margin": "0.0003896645377994", // "mgnMode": "isolated", // "mgnRatio": "11.731726509588816", // "mmr": "0.0000311811092368", // "optVal": "", // "pTime": "1619507761462", // "pos": "1", // "posCcy": "", // "posId": "307173036051017730", // "posSide": "long", // "thetaBS": "", // "thetaPA": "", // "tradeId": "109844", // "uTime": "1619507761462", // "upl": "-0.0000009932766034", // "uplRatio": "-0.0025490556801078", // "vegaBS": "", // "vegaPA": "" // } // ] // } // var positions interface{} = this.SafeList(response, "data", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(positions)); i++ { AppendToArray(&result,this.ParsePosition(GetValue(positions, i))) } ch <- this.FilterByArrayPositions(result, "symbol", this.MarketSymbols(symbols), false) return nil }() return ch } /** * @method * @name okx#fetchPositionsForSymbol * @see https://www.okx.com/docs-v5/en/#rest-api-account-get-positions * @description fetch all open positions for specific symbol * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.instType] MARGIN (if needed) * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *okx) FetchPositionsForSymbol(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 retRes574115 := (<-this.FetchPositions([]interface{}{symbol}, params)) PanicOnError(retRes574115) ch <- retRes574115 return nil }() return ch } func (this *okx) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} { // // { // "adl": "3", // "availPos": "1", // "avgPx": "34131.1", // "cTime": "1627227626502", // "ccy": "USDT", // "deltaBS": "", // "deltaPA": "", // "gammaBS": "", // "gammaPA": "", // "imr": "170.66093041794787", // "instId": "BTC-USDT-SWAP", // "instType": "SWAP", // "interest": "0", // "last": "34134.4", // "lever": "2", // "liab": "", // "liabCcy": "", // "liqPx": "12608.959083877446", // "markPx": "4786.459271773621", // "margin": "", // "mgnMode": "cross", // "mgnRatio": "140.49930117599155", // "mmr": "1.3652874433435829", // "notionalUsd": "341.5130010779638", // "optVal": "", // "pos": "1", // "posCcy": "", // "posId": "339552508062380036", // "posSide": "long", // "thetaBS": "", // "thetaPA": "", // "tradeId": "98617799", // "uTime": "1627227626502", // "upl": "0.0108608358957281", // "uplRatio": "0.0000636418743944", // "vegaBS": "", // "vegaPA": "" // } // history // { // "cTime":"1708351230102", // "ccy":"USDT", // "closeAvgPx":"1.2567", // "closeTotalPos":"40", // "direction":"short", // "fee":"-0.0351036", // "fundingFee":"0", // "instId":"SUSHI-USDT-SWAP", // "instType":"SWAP", // "lever":"10.0", // "liqPenalty":"0", // "mgnMode":"isolated", // "openAvgPx":"1.2462", // "openMaxPos":"40", // "pnl":"-0.42", // "pnlRatio":"-0.0912982667308618", // "posId":"666159086676836352", // "realizedPnl":"-0.4551036", // "triggerPx":"", // "type":"2", // "uTime":"1708354805699", // "uly":"SUSHI-USDT" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(position, "instId") market = this.SafeMarket(marketId, market, nil, "contract") var symbol interface{} = GetValue(market, "symbol") var pos interface{} = this.SafeString(position, "pos") // 'pos' field: One way mode: 0 if position is not open, 1 if open | Two way (hedge) mode: -1 if short, 1 if long, 0 if position is not open var contractsAbs interface{} = Precise.StringAbs(pos) var side interface{} = this.SafeString2(position, "posSide", "direction") var hedged interface{} = !IsEqual(side, "net") var contracts interface{} = this.ParseNumber(contractsAbs) if IsTrue(GetValue(market, "margin")) { // margin position if IsTrue(IsEqual(side, "net")) { var posCcy interface{} = this.SafeString(position, "posCcy") var parsedCurrency interface{} = this.SafeCurrencyCode(posCcy) if IsTrue(!IsEqual(parsedCurrency, nil)) { side = Ternary(IsTrue((IsEqual(GetValue(market, "base"), parsedCurrency))), "long", "short") } } if IsTrue(IsEqual(side, nil)) { side = this.SafeString(position, "direction") } } else { if IsTrue(!IsEqual(pos, nil)) { if IsTrue(IsEqual(side, "net")) { if IsTrue(Precise.StringGt(pos, "0")) { side = "long" } else if IsTrue(Precise.StringLt(pos, "0")) { side = "short" } else { side = nil } } } } var contractSize interface{} = this.SafeNumber(market, "contractSize") var contractSizeString interface{} = this.NumberToString(contractSize) var markPriceString interface{} = this.SafeString(position, "markPx") var notionalString interface{} = this.SafeString(position, "notionalUsd") if IsTrue(GetValue(market, "inverse")) { notionalString = Precise.StringDiv(Precise.StringMul(contractsAbs, contractSizeString), markPriceString) } var notional interface{} = this.ParseNumber(notionalString) var marginMode interface{} = this.SafeString(position, "mgnMode") var initialMarginString interface{} = nil var entryPriceString interface{} = this.SafeString2(position, "avgPx", "openAvgPx") var unrealizedPnlString interface{} = this.SafeString(position, "upl") var leverageString interface{} = this.SafeString(position, "lever") var initialMarginPercentage interface{} = nil var collateralString interface{} = nil if IsTrue(IsEqual(marginMode, "cross")) { initialMarginString = this.SafeString(position, "imr") collateralString = Precise.StringAdd(initialMarginString, unrealizedPnlString) } else if IsTrue(IsEqual(marginMode, "isolated")) { initialMarginPercentage = Precise.StringDiv("1", leverageString) collateralString = this.SafeString(position, "margin") } var maintenanceMarginString interface{} = this.SafeString(position, "mmr") var maintenanceMargin interface{} = this.ParseNumber(maintenanceMarginString) var maintenanceMarginPercentageString interface{} = Precise.StringDiv(maintenanceMarginString, notionalString) if IsTrue(IsEqual(initialMarginPercentage, nil)) { initialMarginPercentage = this.ParseNumber(Precise.StringDiv(initialMarginString, notionalString, 4)) } else if IsTrue(IsEqual(initialMarginString, nil)) { initialMarginString = Precise.StringMul(initialMarginPercentage, notionalString) } var rounder interface{} = "0.00005" // round to closest 0.01% var maintenanceMarginPercentage interface{} = this.ParseNumber(Precise.StringDiv(Precise.StringAdd(maintenanceMarginPercentageString, rounder), "1", 4)) var liquidationPrice interface{} = this.SafeNumber(position, "liqPx") var percentageString interface{} = this.SafeString(position, "uplRatio") var percentage interface{} = this.ParseNumber(Precise.StringMul(percentageString, "100")) var timestamp interface{} = this.SafeInteger(position, "cTime") var marginRatio interface{} = this.ParseNumber(Precise.StringDiv(maintenanceMarginString, collateralString, 4)) return this.SafePosition(map[string]interface{} { "info": position, "id": this.SafeString(position, "posId"), "symbol": symbol, "notional": notional, "marginMode": marginMode, "liquidationPrice": liquidationPrice, "entryPrice": this.ParseNumber(entryPriceString), "unrealizedPnl": this.ParseNumber(unrealizedPnlString), "realizedPnl": this.SafeNumber(position, "realizedPnl"), "percentage": percentage, "contracts": contracts, "contractSize": contractSize, "markPrice": this.ParseNumber(markPriceString), "lastPrice": this.SafeNumber(position, "closeAvgPx"), "side": side, "hedged": hedged, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastUpdateTimestamp": this.SafeInteger(position, "uTime"), "maintenanceMargin": maintenanceMargin, "maintenanceMarginPercentage": maintenanceMarginPercentage, "collateral": this.ParseNumber(collateralString), "initialMargin": this.ParseNumber(initialMarginString), "initialMarginPercentage": this.ParseNumber(initialMarginPercentage), "leverage": this.ParseNumber(leverageString), "marginRatio": marginRatio, "stopLossPrice": nil, "takeProfitPrice": nil, }) } /** * @method * @name okx#transfer * @description transfer currency internally between wallets on the same account * @see https://www.okx.com/docs-v5/en/#rest-api-funding-funds-transfer * @param {string} code unified currency code * @param {float} amount amount to transfer * @param {string} fromAccount account to transfer from * @param {string} toAccount account to transfer to * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure} */ func (this *okx) Transfer(code interface{}, amount interface{}, fromAccount interface{}, toAccount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes59268 := (<-this.LoadMarkets()) PanicOnError(retRes59268) var currency interface{} = this.Currency(code) var accountsByType interface{} = this.SafeDict(this.Options, "accountsByType", map[string]interface{} {}) var fromId interface{} = this.SafeString(accountsByType, fromAccount, fromAccount) var toId interface{} = this.SafeString(accountsByType, toAccount, toAccount) var request interface{} = map[string]interface{} { "ccy": GetValue(currency, "id"), "amt": this.CurrencyToPrecision(code, amount), "type": "0", "from": fromId, "to": toId, } if IsTrue(IsEqual(fromId, "master")) { AddElementToObject(request, "type", "1") AddElementToObject(request, "subAcct", toId) AddElementToObject(request, "from", this.SafeString(params, "from", "6")) AddElementToObject(request, "to", this.SafeString(params, "to", "6")) } else if IsTrue(IsEqual(toId, "master")) { AddElementToObject(request, "type", "2") AddElementToObject(request, "subAcct", fromId) AddElementToObject(request, "from", this.SafeString(params, "from", "6")) AddElementToObject(request, "to", this.SafeString(params, "to", "6")) } response:= (<-this.PrivatePostAssetTransfer(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "", // "data": [ // { // "transId": "754147", // "ccy": "USDT", // "from": "6", // "amt": "0.1", // "to": "18" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var rawTransfer interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseTransfer(rawTransfer, currency) return nil }() return ch } func (this *okx) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} { // // transfer // // { // "transId": "754147", // "ccy": "USDT", // "from": "6", // "amt": "0.1", // "to": "18" // } // // fetchTransfer // // { // "amt": "5", // "ccy": "USDT", // "from": "18", // "instId": "", // "state": "success", // "subAcct": "", // "to": "6", // "toInstId": "", // "transId": "464424732", // "type": "0" // } // // fetchTransfers // // { // "bal": "70.6874353780312913", // "balChg": "-4.0000000000000000", // negative means "to funding", positive meand "from funding" // "billId": "588900695232225299", // "ccy": "USDT", // "execType": "", // "fee": "", // "from": "18", // "instId": "", // "instType": "", // "mgnMode": "", // "notes": "To Funding Account", // "ordId": "", // "pnl": "", // "posBal": "", // "posBalChg": "", // "price": "0", // "subType": "12", // "sz": "-4", // "to": "6", // "ts": "1686676866989", // "type": "1" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var id interface{} = this.SafeString2(transfer, "transId", "billId") var currencyId interface{} = this.SafeString(transfer, "ccy") var code interface{} = this.SafeCurrencyCode(currencyId, currency) var amount interface{} = this.SafeNumber(transfer, "amt") var fromAccountId interface{} = this.SafeString(transfer, "from") var toAccountId interface{} = this.SafeString(transfer, "to") var accountsById interface{} = this.SafeDict(this.Options, "accountsById", map[string]interface{} {}) var timestamp interface{} = this.SafeInteger(transfer, "ts") var balanceChange interface{} = this.SafeString(transfer, "sz") if IsTrue(!IsEqual(balanceChange, nil)) { amount = this.ParseNumber(Precise.StringAbs(balanceChange)) } return map[string]interface{} { "info": transfer, "id": id, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "currency": code, "amount": amount, "fromAccount": this.SafeString(accountsById, fromAccountId), "toAccount": this.SafeString(accountsById, toAccountId), "status": this.ParseTransferStatus(this.SafeString(transfer, "state")), } } func (this *okx) ParseTransferStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "success": "ok", } return this.SafeString(statuses, status, status) } func (this *okx) FetchTransfer(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes60608 := (<-this.LoadMarkets()) PanicOnError(retRes60608) var request interface{} = map[string]interface{} { "transId": id, } response:= (<-this.PrivateGetAssetTransferState(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "amt": "5", // "ccy": "USDT", // "from": "18", // "instId": "", // "state": "success", // "subAcct": "", // "to": "6", // "toInstId": "", // "transId": "464424732", // "type": "0" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var transfer interface{} = this.SafeDict(data, 0) ch <- this.ParseTransfer(transfer) return nil }() return ch } /** * @method * @name okx#fetchTransfers * @description fetch a history of internal transfers made on an account * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months * @param {string} code unified currency code of the currency transferred * @param {int} [since] the earliest time in ms to fetch transfers for * @param {int} [limit] the maximum number of transfers structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [transfer structures]{@link https://docs.ccxt.com/#/?id=transfer-structure} */ func (this *okx) FetchTransfers(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes61038 := (<-this.LoadMarkets()) PanicOnError(retRes61038) var currency interface{} = nil var request interface{} = map[string]interface{} { "type": "1", } if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "ccy", GetValue(currency, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "begin", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivateGetAccountBillsArchive(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "bal": "70.6874353780312913", // "balChg": "-4.0000000000000000", // "billId": "588900695232225299", // "ccy": "USDT", // "execType": "", // "fee": "", // "from": "18", // "instId": "", // "instType": "", // "mgnMode": "", // "notes": "To Funding Account", // "ordId": "", // "pnl": "", // "posBal": "", // "posBalChg": "", // "price": "0", // "subType": "12", // "sz": "-4", // "to": "6", // "ts": "1686676866989", // "type": "1" // }, // ... // ], // "msg": "" // } // var transfers interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTransfers(transfers, currency, since, limit, params) return nil }() return ch } func (this *okx) 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 isArray interface{} = IsArray(params) var request interface{} = Add(Add(Add("/api/", this.Version), "/"), this.ImplodeParams(path, params)) var query interface{} = this.Omit(params, this.ExtractParams(path)) var url interface{} = Add(this.ImplodeHostname(GetValue(GetValue(this.Urls, "api"), "rest")), request) // const type = this.getPathAuthenticationType (path); if IsTrue(IsEqual(api, "public")) { if IsTrue(GetArrayLength(ObjectKeys(query))) { url = Add(url, Add("?", this.Urlencode(query))) } } else if IsTrue(IsEqual(api, "private")) { this.CheckRequiredCredentials() // inject id in implicit api call if IsTrue(IsTrue(IsEqual(method, "POST")) && IsTrue((IsTrue(IsTrue(IsEqual(path, "trade/batch-orders")) || IsTrue(IsEqual(path, "trade/order-algo"))) || IsTrue(IsEqual(path, "trade/order"))))) { var brokerId interface{} = this.SafeString(this.Options, "brokerId", "e847386590ce4dBC") if IsTrue(IsArray(params)) { for i := 0; IsLessThan(i, GetArrayLength(params)); i++ { var entry interface{} = GetValue(params, i) var clientOrderId interface{} = this.SafeString(entry, "clOrdId") if IsTrue(IsEqual(clientOrderId, nil)) { AddElementToObject(entry, "clOrdId", Add(brokerId, this.Uuid16())) AddElementToObject(entry, "tag", brokerId) AddElementToObject(params, i, entry) } } } else { var clientOrderId interface{} = this.SafeString(params, "clOrdId") if IsTrue(IsEqual(clientOrderId, nil)) { AddElementToObject(params, "clOrdId", Add(brokerId, this.Uuid16())) AddElementToObject(params, "tag", brokerId) } } } var timestamp interface{} = this.Iso8601(this.Nonce()) headers = map[string]interface{} { "OK-ACCESS-KEY": this.ApiKey, "OK-ACCESS-PASSPHRASE": this.Password, "OK-ACCESS-TIMESTAMP": timestamp, } var auth interface{} = Add(Add(timestamp, method), request) if IsTrue(IsEqual(method, "GET")) { if IsTrue(GetArrayLength(ObjectKeys(query))) { var urlencodedQuery interface{} = Add("?", this.Urlencode(query)) url = Add(url, urlencodedQuery) auth = Add(auth, urlencodedQuery) } } else { if IsTrue(IsTrue(isArray) || IsTrue(GetArrayLength(ObjectKeys(query)))) { body = this.Json(query) auth = Add(auth, body) } AddElementToObject(headers, "Content-Type", "application/json") } var signature interface{} = this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha256, "base64") AddElementToObject(headers, "OK-ACCESS-SIGN", signature) } return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } func (this *okx) ParseFundingRate(contract interface{}, optionalArgs ...interface{}) interface{} { // // { // "fundingRate": "0.00027815", // "fundingTime": "1634256000000", // "instId": "BTC-USD-SWAP", // "instType": "SWAP", // "nextFundingRate": "0.00017", // "nextFundingTime": "1634284800000" // } // ws // { // "fundingRate":"0.0001875391284828", // "fundingTime":"1700726400000", // "instId":"BTC-USD-SWAP", // "instType":"SWAP", // "method": "next_period", // "maxFundingRate":"0.00375", // "minFundingRate":"-0.00375", // "nextFundingRate":"0.0002608059239328", // "nextFundingTime":"1700755200000", // "premium": "0.0001233824646391", // "settFundingRate":"0.0001699799259033", // "settState":"settled", // "ts":"1700724675402" // } // // in the response above nextFundingRate is actually two funding rates from now // market := GetArg(optionalArgs, 0, nil) _ = market var nextFundingRateTimestamp interface{} = this.SafeInteger(contract, "nextFundingTime") var marketId interface{} = this.SafeString(contract, "instId") var symbol interface{} = this.SafeSymbol(marketId, market) var nextFundingRate interface{} = this.SafeNumber(contract, "nextFundingRate") var fundingTime interface{} = this.SafeInteger(contract, "fundingTime") var fundingTimeString interface{} = this.SafeString(contract, "fundingTime") var nextFundingTimeString interface{} = this.SafeString(contract, "nextFundingRate") var millisecondsInterval interface{} = Precise.StringSub(nextFundingTimeString, fundingTimeString) // https://www.okx.com/support/hc/en-us/articles/360053909272-Ⅸ-Introduction-to-perpetual-swap-funding-fee // > The current interest is 0. return map[string]interface{} { "info": contract, "symbol": symbol, "markPrice": nil, "indexPrice": nil, "interestRate": this.ParseNumber("0"), "estimatedSettlePrice": nil, "timestamp": nil, "datetime": nil, "fundingRate": this.SafeNumber(contract, "fundingRate"), "fundingTimestamp": fundingTime, "fundingDatetime": this.Iso8601(fundingTime), "nextFundingRate": nextFundingRate, "nextFundingTimestamp": nextFundingRateTimestamp, "nextFundingDatetime": this.Iso8601(nextFundingRateTimestamp), "previousFundingRate": nil, "previousFundingTimestamp": nil, "previousFundingDatetime": nil, "interval": this.ParseFundingInterval(millisecondsInterval), } } func (this *okx) ParseFundingInterval(interval interface{}) interface{} { var intervals interface{} = map[string]interface{} { "3600000": "1h", "14400000": "4h", "28800000": "8h", "57600000": "16h", "86400000": "24h", } return this.SafeString(intervals, interval, interval) } /** * @method * @name okx#fetchFundingInterval * @description fetch the current funding rate interval * @see https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure} */ func (this *okx) FetchFundingInterval(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 retRes629915 := (<-this.FetchFundingRate(symbol, params)) PanicOnError(retRes629915) ch <- retRes629915 return nil }() return ch } /** * @method * @name okx#fetchFundingRate * @description fetch the current funding rate * @see https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure} */ func (this *okx) FetchFundingRate(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes63128 := (<-this.LoadMarkets()) PanicOnError(retRes63128) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "swap")) { panic(ExchangeError(Add(this.Id, " fetchFundingRate() is only valid for swap markets"))) } var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } response:= (<-this.PublicGetPublicFundingRate(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "fundingRate": "0.00027815", // "fundingTime": "1634256000000", // "instId": "BTC-USD-SWAP", // "instType": "SWAP", // "nextFundingRate": "0.00017", // "nextFundingTime": "1634284800000" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var entry interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseFundingRate(entry, market) return nil }() return ch } /** * @method * @name okx#fetchFundingHistory * @description fetch the history of funding payments paid and received on this account * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch funding history for * @param {int} [limit] the maximum number of funding history structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [funding history structure]{@link https://docs.ccxt.com/#/?id=funding-history-structure} */ func (this *okx) FetchFundingHistory(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes63548 := (<-this.LoadMarkets()) PanicOnError(retRes63548) var request interface{} = map[string]interface{} { "type": "8", } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", ToString(limit)) // default 100, max 100 } var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) symbol = GetValue(market, "symbol") if IsTrue(GetValue(market, "contract")) { if IsTrue(GetValue(market, "linear")) { AddElementToObject(request, "ctType", "linear") AddElementToObject(request, "ccy", GetValue(market, "quoteId")) } else { AddElementToObject(request, "ctType", "inverse") AddElementToObject(request, "ccy", GetValue(market, "baseId")) } } } typeVarqueryVariable := this.HandleMarketTypeAndParams("fetchFundingHistory", market, params); typeVar := GetValue(typeVarqueryVariable,0); query := GetValue(typeVarqueryVariable,1) if IsTrue(IsEqual(typeVar, "swap")) { AddElementToObject(request, "instType", this.ConvertToInstrumentType(typeVar)) } // AccountBillsArchive has the same cost as AccountBills but supports three months of data response:= (<-this.PrivateGetAccountBillsArchive(this.Extend(request, query))) PanicOnError(response) // // { // "bal": "0.0242946200998573", // "balChg": "0.0000148752712240", // "billId": "377970609204146187", // "ccy": "ETH", // "execType": "", // "fee": "0", // "from": "", // "instId": "ETH-USD-SWAP", // "instType": "SWAP", // "mgnMode": "isolated", // "notes": "", // "ordId": "", // "pnl": "0.000014875271224", // "posBal": "0", // "posBalChg": "0", // "subType": "174", // "sz": "9", // "to": "", // "ts": "1636387215588", // "type": "8" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var entry interface{} = GetValue(data, i) var timestamp interface{} = this.SafeInteger(entry, "ts") var instId interface{} = this.SafeString(entry, "instId") var marketInner interface{} = this.SafeMarket(instId) var currencyId interface{} = this.SafeString(entry, "ccy") var code interface{} = this.SafeCurrencyCode(currencyId) AppendToArray(&result,map[string]interface{} { "info": entry, "symbol": GetValue(marketInner, "symbol"), "code": code, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "id": this.SafeString(entry, "billId"), "amount": this.SafeNumber(entry, "balChg"), }) } var sorted interface{} = this.SortBy(result, "timestamp") ch <- this.FilterBySymbolSinceLimit(sorted, symbol, since, limit) return nil }() return ch } /** * @method * @name okx#setLeverage * @description set the level of leverage for a market * @see https://www.okx.com/docs-v5/en/#rest-api-account-set-leverage * @param {float} leverage the rate of leverage * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.marginMode] 'cross' or 'isolated' * @param {string} [params.posSide] 'long' or 'short' or 'net' for isolated margin long/short mode on futures and swap markets, default is 'net' * @returns {object} response from the exchange */ func (this *okx) SetLeverage(leverage interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " setLeverage() requires a symbol argument"))) } // WARNING: THIS WILL INCREASE LIQUIDATION PRICE FOR OPEN ISOLATED LONG POSITIONS // AND DECREASE LIQUIDATION PRICE FOR OPEN ISOLATED SHORT POSITIONS if IsTrue(IsTrue((IsLessThan(leverage, 1))) || IsTrue((IsGreaterThan(leverage, 125)))) { panic(BadRequest(Add(this.Id, " setLeverage() leverage should be between 1 and 125"))) } retRes65228 := (<-this.LoadMarkets()) PanicOnError(retRes65228) var market interface{} = this.Market(symbol) var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("setLeverage", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) if IsTrue(IsEqual(marginMode, nil)) { marginMode = this.SafeString(params, "mgnMode", "cross") // cross as default marginMode } if IsTrue(IsTrue((!IsEqual(marginMode, "cross"))) && IsTrue((!IsEqual(marginMode, "isolated")))) { panic(BadRequest(Add(this.Id, " setLeverage() requires a marginMode parameter that must be either cross or isolated"))) } var request interface{} = map[string]interface{} { "lever": leverage, "mgnMode": marginMode, "instId": GetValue(market, "id"), } var posSide interface{} = this.SafeString(params, "posSide", "net") if IsTrue(IsEqual(marginMode, "isolated")) { if IsTrue(IsTrue(IsTrue(!IsEqual(posSide, "long")) && IsTrue(!IsEqual(posSide, "short"))) && IsTrue(!IsEqual(posSide, "net"))) { panic(BadRequest(Add(this.Id, " setLeverage() requires the posSide argument to be either \"long\", \"short\" or \"net\""))) } AddElementToObject(request, "posSide", posSide) } response:= (<-this.PrivatePostAccountSetLeverage(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "instId": "BTC-USDT-SWAP", // "lever": "5", // "mgnMode": "isolated", // "posSide": "long" // } // ], // "msg": "" // } // ch <- response return nil }() return ch } /** * @method * @name okx#fetchPositionMode * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-account-configuration * @description fetchs the position mode, hedged or one way, hedged for binance is set identically for all linear markets or all inverse markets * @param {string} symbol unified symbol of the market to fetch the order book for * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.accountId] if you have multiple accounts, you must specify the account id to fetch the position mode * @returns {object} an object detailing whether the market is in hedged or one-way mode */ func (this *okx) FetchPositionMode(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 accounts:= (<-this.FetchAccounts()) PanicOnError(accounts) var length interface{} = GetArrayLength(accounts) var selectedAccount interface{} = nil if IsTrue(IsGreaterThan(length, 1)) { var accountId interface{} = this.SafeString(params, "accountId") if IsTrue(IsEqual(accountId, nil)) { var accountIds interface{} = this.GetListFromObjectValues(accounts, "id") panic(ExchangeError(Add(Add(this.Id, " fetchPositionMode() can not detect position mode, because you have multiple accounts. Set params[\"accountId\"] to desired id from: "), Join(accountIds, ", ")))) } else { var accountsById interface{} = this.IndexBy(accounts, "id") selectedAccount = this.SafeDict(accountsById, accountId) } } else { selectedAccount = GetValue(accounts, 0) } var mainAccount interface{} = GetValue(selectedAccount, "info") var posMode interface{} = this.SafeString(mainAccount, "posMode") // long_short_mode, net_mode var isHedged interface{} = IsEqual(posMode, "long_short_mode") ch <- map[string]interface{} { "info": mainAccount, "hedged": isHedged, } return nil }() return ch } /** * @method * @name okx#setPositionMode * @description set hedged to true or false for a market * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-set-position-mode * @param {bool} hedged set to true to use long_short_mode, false for net_mode * @param {string} symbol not used by okx setPositionMode * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} response from the exchange */ func (this *okx) SetPositionMode(hedged interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params var hedgeMode interface{} = nil if IsTrue(hedged) { hedgeMode = "long_short_mode" } else { hedgeMode = "net_mode" } var request interface{} = map[string]interface{} { "posMode": hedgeMode, } response:= (<-this.PrivatePostAccountSetPositionMode(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "posMode": "net_mode" // } // ], // "msg": "" // } // ch <- response return nil }() return ch } /** * @method * @name okx#setMarginMode * @description set margin mode to 'cross' or 'isolated' * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-set-leverage * @param {string} marginMode 'cross' or 'isolated' * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.leverage] leverage * @returns {object} response from the exchange */ func (this *okx) SetMarginMode(marginMode interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " setMarginMode() requires a symbol argument"))) } // WARNING: THIS WILL INCREASE LIQUIDATION PRICE FOR OPEN ISOLATED LONG POSITIONS // AND DECREASE LIQUIDATION PRICE FOR OPEN ISOLATED SHORT POSITIONS marginMode = ToLower(marginMode) if IsTrue(IsTrue((!IsEqual(marginMode, "cross"))) && IsTrue((!IsEqual(marginMode, "isolated")))) { panic(BadRequest(Add(this.Id, " setMarginMode() marginMode must be either cross or isolated"))) } retRes66538 := (<-this.LoadMarkets()) PanicOnError(retRes66538) var market interface{} = this.Market(symbol) var lever interface{} = this.SafeInteger2(params, "lever", "leverage") if IsTrue(IsTrue(IsTrue((IsEqual(lever, nil))) || IsTrue((IsLessThan(lever, 1)))) || IsTrue((IsGreaterThan(lever, 125)))) { panic(BadRequest(Add(this.Id, " setMarginMode() params[\"lever\"] should be between 1 and 125"))) } params = this.Omit(params, []interface{}{"leverage"}) var request interface{} = map[string]interface{} { "lever": lever, "mgnMode": marginMode, "instId": GetValue(market, "id"), } response:= (<-this.PrivatePostAccountSetLeverage(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "instId": "BTC-USDT-SWAP", // "lever": "5", // "mgnMode": "isolated", // "posSide": "long" // } // ], // "msg": "" // } // ch <- response return nil }() return ch } /** * @method * @name okx#fetchCrossBorrowRates * @description fetch the borrow interest rates of all currencies * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-interest-rate * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a list of [borrow rate structures]{@link https://docs.ccxt.com/#/?id=borrow-rate-structure} */ func (this *okx) FetchCrossBorrowRates(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 retRes66928 := (<-this.LoadMarkets()) PanicOnError(retRes66928) response:= (<-this.PrivateGetAccountInterestRate(params)) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "ccy": "BTC", // "interestRate": "0.00000833" // } // ... // ], // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var rates interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { AppendToArray(&rates,this.ParseBorrowRate(GetValue(data, i))) } ch <- rates return nil }() return ch } /** * @method * @name okx#fetchCrossBorrowRate * @description fetch the rate of interest to borrow a currency for margin trading * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-interest-rate * @param {string} code unified currency code * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [borrow rate structure]{@link https://docs.ccxt.com/#/?id=borrow-rate-structure} */ func (this *okx) FetchCrossBorrowRate(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes67248 := (<-this.LoadMarkets()) PanicOnError(retRes67248) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "ccy": GetValue(currency, "id"), } response:= (<-this.PrivateGetAccountInterestRate(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "ccy": "USDT", // "interestRate": "0.00002065" // } // ... // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var rate interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseBorrowRate(rate) return nil }() return ch } func (this *okx) ParseBorrowRate(info interface{}, optionalArgs ...interface{}) interface{} { // // { // "amt": "992.10341195", // "ccy": "BTC", // "rate": "0.01", // "ts": "1643954400000" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var ccy interface{} = this.SafeString(info, "ccy") var timestamp interface{} = this.SafeInteger(info, "ts") return map[string]interface{} { "currency": this.SafeCurrencyCode(ccy), "rate": this.SafeNumber2(info, "interestRate", "rate"), "period": 86400000, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "info": info, } } func (this *okx) ParseBorrowRateHistories(response interface{}, codes interface{}, since interface{}, limit interface{}) interface{} { // // [ // { // "amt": "992.10341195", // "ccy": "BTC", // "rate": "0.01", // "ts": "1643954400000" // }, // ... // ] // var borrowRateHistories interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var item interface{} = GetValue(response, i) var code interface{} = this.SafeCurrencyCode(this.SafeString(item, "ccy")) if IsTrue(IsTrue(IsEqual(codes, nil)) || IsTrue(this.InArray(code, codes))) { if !IsTrue((InOp(borrowRateHistories, code))) { AddElementToObject(borrowRateHistories, code, []interface{}{}) } var borrowRateStructure interface{} = this.ParseBorrowRate(item) var borrrowRateCode interface{} = GetValue(borrowRateHistories, code) AppendToArray(&borrrowRateCode,borrowRateStructure) } } var keys interface{} = ObjectKeys(borrowRateHistories) for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ { var code interface{} = GetValue(keys, i) AddElementToObject(borrowRateHistories, code, this.FilterByCurrencySinceLimit(GetValue(borrowRateHistories, code), code, since, limit)) } return borrowRateHistories } /** * @method * @name okx#fetchBorrowRateHistories * @description retrieves a history of a multiple currencies borrow interest rate at specific time slots, returns all currencies if no symbols passed, default is undefined * @see https://www.okx.com/docs-v5/en/#financial-product-savings-get-public-borrow-history-public * @param {string[]|undefined} codes list of unified currency codes, default is undefined * @param {int} [since] timestamp in ms of the earliest borrowRate, default is undefined * @param {int} [limit] max number of borrow rate prices to return, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [borrow rate structures]{@link https://docs.ccxt.com/#/?id=borrow-rate-structure} indexed by the market symbol */ func (this *okx) FetchBorrowRateHistories(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) codes := GetArg(optionalArgs, 0, nil) _ = codes since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes68148 := (<-this.LoadMarkets()) PanicOnError(retRes68148) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "before", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PublicGetFinanceSavingsLendingRateHistory(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "amt": "992.10341195", // "ccy": "BTC", // "rate": "0.01", // "ts": "1643954400000" // }, // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseBorrowRateHistories(data, codes, since, limit) return nil }() return ch } /** * @method * @name okx#fetchBorrowRateHistory * @description retrieves a history of a currencies borrow interest rate at specific time slots * @see https://www.okx.com/docs-v5/en/#financial-product-savings-get-public-borrow-history-public * @param {string} code unified currency code * @param {int} [since] timestamp for the earliest borrow rate * @param {int} [limit] the maximum number of [borrow rate structures]{@link https://docs.ccxt.com/#/?id=borrow-rate-structure} to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of [borrow rate structures]{@link https://docs.ccxt.com/#/?id=borrow-rate-structure} */ func (this *okx) FetchBorrowRateHistory(code 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 retRes68588 := (<-this.LoadMarkets()) PanicOnError(retRes68588) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "ccy": GetValue(currency, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "before", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PublicGetFinanceSavingsLendingRateHistory(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "amt": "992.10341195", // "ccy": "BTC", // "rate": "0.01", // "ts": "1643954400000" // }, // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseBorrowRateHistory(data, code, since, limit) return nil }() return ch } func (this *okx) ModifyMarginHelper(symbol interface{}, amount interface{}, typeVar 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 retRes68928 := (<-this.LoadMarkets()) PanicOnError(retRes68928) var market interface{} = this.Market(symbol) var posSide interface{} = this.SafeString(params, "posSide", "net") params = this.Omit(params, []interface{}{"posSide"}) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), "amt": amount, "type": typeVar, "posSide": posSide, } response:= (<-this.PrivatePostAccountPositionMarginBalance(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "amt": "0.01", // "instId": "ETH-USD-SWAP", // "posSide": "net", // "type": "reduce" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var entry interface{} = this.SafeDict(data, 0, map[string]interface{} {}) var errorCode interface{} = this.SafeString(response, "code") ch <- this.Extend(this.ParseMarginModification(entry, market), map[string]interface{} { "status": Ternary(IsTrue((IsEqual(errorCode, "0"))), "ok", "failed"), }) return nil }() return ch } func (this *okx) ParseMarginModification(data interface{}, optionalArgs ...interface{}) interface{} { // // addMargin/reduceMargin // // { // "amt": "0.01", // "instId": "ETH-USD-SWAP", // "posSide": "net", // "type": "reduce" // } // // fetchMarginAdjustmentHistory // // { // bal: '67621.4325135010619812', // balChg: '-10.0000000000000000', // billId: '691293628710342659', // ccy: 'USDT', // clOrdId: '', // execType: '', // fee: '0', // fillFwdPx: '', // fillIdxPx: '', // fillMarkPx: '', // fillMarkVol: '', // fillPxUsd: '', // fillPxVol: '', // fillTime: '1711089244850', // from: '', // instId: 'XRP-USDT-SWAP', // instType: 'SWAP', // interest: '0', // mgnMode: 'isolated', // notes: '', // ordId: '', // pnl: '0', // posBal: '73.12', // posBalChg: '10.00', // px: '', // subType: '160', // sz: '10', // tag: '', // to: '', // tradeId: '0', // ts: '1711089244699', // type: '6' // } // market := GetArg(optionalArgs, 0, nil) _ = market var amountRaw interface{} = this.SafeString2(data, "amt", "posBalChg") var typeRaw interface{} = this.SafeString(data, "type") var typeVar interface{} = nil if IsTrue(IsEqual(typeRaw, "6")) { typeVar = Ternary(IsTrue(Precise.StringGt(amountRaw, "0")), "add", "reduce") } else { typeVar = typeRaw } var amount interface{} = Precise.StringAbs(amountRaw) var marketId interface{} = this.SafeString(data, "instId") var responseMarket interface{} = this.SafeMarket(marketId, market) var code interface{} = Ternary(IsTrue(GetValue(responseMarket, "inverse")), GetValue(responseMarket, "base"), GetValue(responseMarket, "quote")) var timestamp interface{} = this.SafeInteger(data, "ts") return map[string]interface{} { "info": data, "symbol": GetValue(responseMarket, "symbol"), "type": typeVar, "marginMode": "isolated", "amount": this.ParseNumber(amount), "code": code, "total": nil, "status": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), } } /** * @method * @name okx#reduceMargin * @description remove margin from a position * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-increase-decrease-margin * @param {string} symbol unified market symbol * @param {float} amount the amount of margin to remove * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=reduce-margin-structure} */ func (this *okx) ReduceMargin(symbol interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes701115 := (<-this.ModifyMarginHelper(symbol, amount, "reduce", params)) PanicOnError(retRes701115) ch <- retRes701115 return nil }() return ch } /** * @method * @name okx#addMargin * @description add margin * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-increase-decrease-margin * @param {string} symbol unified market symbol * @param {float} amount amount of margin to add * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=add-margin-structure} */ func (this *okx) AddMargin(symbol interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes702515 := (<-this.ModifyMarginHelper(symbol, amount, "add", params)) PanicOnError(retRes702515) ch <- retRes702515 return nil }() return ch } /** * @method * @name okx#fetchMarketLeverageTiers * @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes for a single market * @see https://www.okx.com/docs-v5/en/#rest-api-public-data-get-position-tiers * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.marginMode] 'cross' or 'isolated' * @returns {object} a [leverage tiers structure]{@link https://docs.ccxt.com/#/?id=leverage-tiers-structure} */ func (this *okx) FetchMarketLeverageTiers(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 retRes70398 := (<-this.LoadMarkets()) PanicOnError(retRes70398) var market interface{} = this.Market(symbol) var typeVar interface{} = Ternary(IsTrue(GetValue(market, "spot")), "MARGIN", this.ConvertToInstrumentType(GetValue(market, "type"))) var uly interface{} = this.SafeString(GetValue(market, "info"), "uly") if !IsTrue(uly) { if IsTrue(!IsEqual(typeVar, "MARGIN")) { panic(BadRequest(Add(Add(this.Id, " fetchMarketLeverageTiers() cannot fetch leverage tiers for "), symbol))) } } var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchMarketLeverageTiers", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) if IsTrue(IsEqual(marginMode, nil)) { marginMode = this.SafeString(params, "tdMode", "cross") // cross as default marginMode } var request interface{} = map[string]interface{} { "instType": typeVar, "tdMode": marginMode, "uly": uly, } if IsTrue(IsEqual(typeVar, "MARGIN")) { AddElementToObject(request, "instId", GetValue(market, "id")) } response:= (<-this.PublicGetPublicPositionTiers(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "baseMaxLoan": "500", // "imr": "0.1", // "instId": "ETH-USDT", // "maxLever": "10", // "maxSz": "500", // "minSz": "0", // "mmr": "0.03", // "optMgnFactor": "0", // "quoteMaxLoan": "200000", // "tier": "1", // "uly": "" // }, // ... // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseMarketLeverageTiers(data, market) return nil }() return ch } func (this *okx) ParseMarketLeverageTiers(info interface{}, optionalArgs ...interface{}) interface{} { /** * @ignore * @method * @param {object} info Exchange response for 1 market * @param {object} market CCXT market */ // // [ // { // "baseMaxLoan": "500", // "imr": "0.1", // "instId": "ETH-USDT", // "maxLever": "10", // "maxSz": "500", // "minSz": "0", // "mmr": "0.03", // "optMgnFactor": "0", // "quoteMaxLoan": "200000", // "tier": "1", // "uly": "" // }, // ... // ] // market := GetArg(optionalArgs, 0, nil) _ = market var tiers interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(info)); i++ { var tier interface{} = GetValue(info, i) var marketId interface{} = this.SafeString(tier, "instId") AppendToArray(&tiers,map[string]interface{} { "tier": this.SafeInteger(tier, "tier"), "symbol": this.SafeSymbol(marketId, market), "currency": GetValue(market, "quote"), "minNotional": this.SafeNumber(tier, "minSz"), "maxNotional": this.SafeNumber(tier, "maxSz"), "maintenanceMarginRate": this.SafeNumber(tier, "mmr"), "maxLeverage": this.SafeNumber(tier, "maxLever"), "info": tier, }) } return tiers } /** * @method * @name okx#fetchBorrowInterest * @description fetch the interest owed by the user for borrowing currency for margin trading * @see https://www.okx.com/docs-v5/en/#rest-api-account-get-interest-accrued-data * @param {string} code the unified currency code for the currency of the interest * @param {string} symbol the market symbol of an isolated margin market, if undefined, the interest for cross margin markets is returned * @param {int} [since] timestamp in ms of the earliest time to receive interest records for * @param {int} [limit] the number of [borrow interest structures]{@link https://docs.ccxt.com/#/?id=borrow-interest-structure} to retrieve * @param {object} [params] exchange specific parameters * @param {int} [params.type] Loan type 1 - VIP loans 2 - Market loans *Default is Market loans* * @param {string} [params.marginMode] 'cross' or 'isolated' * @returns {object[]} An list of [borrow interest structures]{@link https://docs.ccxt.com/#/?id=borrow-interest-structure} */ func (this *okx) FetchBorrowInterest(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code symbol := GetArg(optionalArgs, 1, nil) _ = symbol since := GetArg(optionalArgs, 2, nil) _ = since limit := GetArg(optionalArgs, 3, nil) _ = limit params := GetArg(optionalArgs, 4, map[string]interface{} {}) _ = params retRes71458 := (<-this.LoadMarkets()) PanicOnError(retRes71458) var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("fetchBorrowInterest", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) if IsTrue(IsEqual(marginMode, nil)) { marginMode = this.SafeString(params, "mgnMode", "cross") // cross as default marginMode } var request interface{} = map[string]interface{} { "mgnMode": marginMode, } var market interface{} = nil if IsTrue(!IsEqual(code, nil)) { var currency interface{} = this.Currency(code) AddElementToObject(request, "ccy", GetValue(currency, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "before", Subtract(since, 1)) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "instId", GetValue(market, "id")) } response:= (<-this.PrivateGetAccountInterestAccrued(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "ccy": "USDT", // "instId": "", // "interest": "0.0003960833333334", // "interestRate": "0.0000040833333333", // "liab": "97", // "mgnMode": "", // "ts": "1637312400000", // "type": "1" // }, // ... // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var interest interface{} = this.ParseBorrowInterests(data) ch <- this.FilterByCurrencySinceLimit(interest, code, since, limit) return nil }() return ch } func (this *okx) ParseBorrowInterest(info interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market var instId interface{} = this.SafeString(info, "instId") if IsTrue(!IsEqual(instId, nil)) { market = this.SafeMarket(instId, market) } var timestamp interface{} = this.SafeInteger(info, "ts") return map[string]interface{} { "info": info, "symbol": this.SafeString(market, "symbol"), "currency": this.SafeCurrencyCode(this.SafeString(info, "ccy")), "interest": this.SafeNumber(info, "interest"), "interestRate": this.SafeNumber(info, "interestRate"), "amountBorrowed": this.SafeNumber(info, "liab"), "marginMode": this.SafeString(info, "mgnMode"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), } } /** * @method * @name okx#borrowCrossMargin * @description create a loan to borrow margin (need to be VIP 5 and above) * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-vip-loans-borrow-and-repay * @param {string} code unified currency code of the currency to borrow * @param {float} amount the amount to borrow * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure} */ func (this *okx) BorrowCrossMargin(code interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes72248 := (<-this.LoadMarkets()) PanicOnError(retRes72248) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "ccy": GetValue(currency, "id"), "amt": this.CurrencyToPrecision(code, amount), "side": "borrow", } response:= (<-this.PrivatePostAccountBorrowRepay(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "amt": "102", // "ccy": "USDT", // "ordId": "544199684697214976", // "side": "borrow", // "state": "1" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var loan interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseMarginLoan(loan, currency) return nil }() return ch } /** * @method * @name okx#repayCrossMargin * @description repay borrowed margin and interest * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-vip-loans-borrow-and-repay * @param {string} code unified currency code of the currency to repay * @param {float} amount the amount to repay * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.id] the order ID of borrowing, it is necessary while repaying * @returns {object} a [margin loan structure]{@link https://docs.ccxt.com/#/?id=margin-loan-structure} */ func (this *okx) RepayCrossMargin(code interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes72648 := (<-this.LoadMarkets()) PanicOnError(retRes72648) var id interface{} = this.SafeString2(params, "id", "ordId") params = this.Omit(params, "id") if IsTrue(IsEqual(id, nil)) { panic(ArgumentsRequired(Add(this.Id, " repayCrossMargin() requires an id parameter"))) } var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "ccy": GetValue(currency, "id"), "amt": this.CurrencyToPrecision(code, amount), "side": "repay", "ordId": id, } response:= (<-this.PrivatePostAccountBorrowRepay(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "amt": "102", // "ccy": "USDT", // "ordId": "544199684697214976", // "side": "repay", // "state": "1" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var loan interface{} = this.SafeDict(data, 0, map[string]interface{} {}) ch <- this.ParseMarginLoan(loan, currency) return nil }() return ch } func (this *okx) ParseMarginLoan(info interface{}, optionalArgs ...interface{}) interface{} { // // { // "amt": "102", // "availLoan": "97", // "ccy": "USDT", // "loanQuota": "6000000", // "posLoan": "0", // "side": "repay", // "usedLoan": "97" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var currencyId interface{} = this.SafeString(info, "ccy") return map[string]interface{} { "id": nil, "currency": this.SafeCurrencyCode(currencyId, currency), "amount": this.SafeNumber(info, "amt"), "symbol": nil, "timestamp": nil, "datetime": nil, "info": info, } } /** * @method * @name okx#fetchOpenInterest * @description Retrieves the open interest of a currency * @see https://www.okx.com/docs-v5/en/#rest-api-public-data-get-open-interest * @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 *okx) 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 retRes73328 := (<-this.LoadMarkets()) PanicOnError(retRes73328) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "contract")) { panic(BadRequest(Add(this.Id, " fetchOpenInterest() supports contract markets only"))) } var typeVar interface{} = this.ConvertToInstrumentType(GetValue(market, "type")) var uly interface{} = this.SafeString(GetValue(market, "info"), "uly") var request interface{} = map[string]interface{} { "instType": typeVar, "uly": uly, "instId": GetValue(market, "id"), } response:= (<-this.PublicGetPublicOpenInterest(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "instId": "BTC-USDT-SWAP", // "instType": "SWAP", // "oi": "2125419", // "oiCcy": "21254.19", // "ts": "1664005108969" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOpenInterest(GetValue(data, 0), market) return nil }() return ch } /** * @method * @name okx#fetchOpenInterestHistory * @description Retrieves the open interest history of a currency * @see https://www.okx.com/docs-v5/en/#rest-api-trading-data-get-contracts-open-interest-and-volume * @see https://www.okx.com/docs-v5/en/#rest-api-trading-data-get-options-open-interest-and-volume * @param {string} symbol Unified CCXT currency code or unified symbol * @param {string} timeframe "5m", "1h", or "1d" for option only "1d" or "8h" * @param {int} [since] The time in ms of the earliest record to retrieve as a unix timestamp * @param {int} [limit] Not used by okx, but parsed internally by CCXT * @param {object} [params] Exchange specific parameters * @param {int} [params.until] The time in ms of the latest record to retrieve as a unix timestamp * @returns An array of [open interest structures]{@link https://docs.ccxt.com/#/?id=open-interest-structure} */ func (this *okx) FetchOpenInterestHistory(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) timeframe := GetArg(optionalArgs, 0, "1d") _ = timeframe since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params var options interface{} = this.SafeDict(this.Options, "fetchOpenInterestHistory", map[string]interface{} {}) var timeframes interface{} = this.SafeDict(options, "timeframes", map[string]interface{} {}) timeframe = this.SafeString(timeframes, timeframe, timeframe) if IsTrue(IsTrue(IsTrue(!IsEqual(timeframe, "5m")) && IsTrue(!IsEqual(timeframe, "1H"))) && IsTrue(!IsEqual(timeframe, "1D"))) { panic(BadRequest(Add(this.Id, " fetchOpenInterestHistory cannot only use the 5m, 1h, and 1d timeframe"))) } retRes73858 := (<-this.LoadMarkets()) PanicOnError(retRes73858) // handle unified currency code or symbol var currencyId interface{} = nil var market interface{} = nil if IsTrue(IsTrue((InOp(this.Markets, symbol))) || IsTrue((InOp(this.Markets_by_id, symbol)))) { market = this.Market(symbol) currencyId = GetValue(market, "baseId") } else { var currency interface{} = this.Currency(symbol) currencyId = GetValue(currency, "id") } var request interface{} = map[string]interface{} { "ccy": currencyId, "period": timeframe, } var typeVar interface{} = nil var response interface{} = nil typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchOpenInterestHistory", market, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) if IsTrue(IsEqual(typeVar, "option")) { response = (<-this.PublicGetRubikStatOptionOpenInterestVolume(this.Extend(request, params))) PanicOnError(response) } else { if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "begin", since) } var until interface{} = this.SafeInteger(params, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "end", until) params = this.Omit(params, []interface{}{"until"}) } response = (<-this.PublicGetRubikStatContractsOpenInterestVolume(this.Extend(request, params))) PanicOnError(response) } // // { // "code": "0", // "data": [ // [ // "1648221300000", // timestamp // "2183354317.945", // open interest (USD) // "74285877.617", // volume (USD) // ], // ... // ], // "msg": '' // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOpenInterestsHistory(data, nil, since, limit) return nil }() return ch } func (this *okx) ParseOpenInterest(interest interface{}, optionalArgs ...interface{}) interface{} { // // fetchOpenInterestHistory // // [ // "1648221300000", // timestamp // "2183354317.945", // open interest (USD) - (coin) for options // "74285877.617", // volume (USD) - (coin) for options // ] // // fetchOpenInterest // // { // "instId": "BTC-USD-230520-25500-P", // "instType": "OPTION", // "oi": "300", // "oiCcy": "3", // "oiUsd": "3", // "ts": "1684551166251" // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString(interest, "instId") market = this.SafeMarket(id, market) var time interface{} = this.SafeInteger(interest, "ts") var timestamp interface{} = this.SafeInteger(interest, 0, time) var baseVolume interface{} = nil var quoteVolume interface{} = nil var openInterestAmount interface{} = nil var openInterestValue interface{} = nil var typeVar interface{} = this.SafeString(this.Options, "defaultType") if IsTrue(IsArray(interest)) { if IsTrue(IsEqual(typeVar, "option")) { openInterestAmount = this.SafeNumber(interest, 1) baseVolume = this.SafeNumber(interest, 2) } else { openInterestValue = this.SafeNumber(interest, 1) quoteVolume = this.SafeNumber(interest, 2) } } else { baseVolume = this.SafeNumber(interest, "oiCcy") openInterestAmount = this.SafeNumber(interest, "oi") openInterestValue = this.SafeNumber(interest, "oiUsd") } return this.SafeOpenInterest(map[string]interface{} { "symbol": this.SafeSymbol(id), "baseVolume": baseVolume, "quoteVolume": quoteVolume, "openInterestAmount": openInterestAmount, "openInterestValue": openInterestValue, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "info": interest, }, market) } func (this *okx) SetSandboxMode(enable interface{}) { this.Exchange.SetSandboxMode(enable) AddElementToObject(this.Options, "sandboxMode", enable) if IsTrue(enable) { AddElementToObject(this.Headers, "x-simulated-trading", "1") } else if IsTrue(InOp(this.Headers, "x-simulated-trading")) { this.Headers = this.Omit(this.Headers, "x-simulated-trading") } } /** * @method * @name okx#fetchDepositWithdrawFees * @description fetch deposit and withdraw fees * @see https://www.okx.com/docs-v5/en/#rest-api-funding-get-currencies * @param {string[]|undefined} codes list of unified currency codes * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [fees structures]{@link https://docs.ccxt.com/#/?id=fee-structure} */ func (this *okx) FetchDepositWithdrawFees(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) codes := GetArg(optionalArgs, 0, nil) _ = codes params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes75098 := (<-this.LoadMarkets()) PanicOnError(retRes75098) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(codes, nil)) { var ids interface{} = this.CurrencyIds(codes) AddElementToObject(request, "ccy", Join(ids, ",")) } response:= (<-this.PrivateGetAssetCurrencies(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "canDep": true, // "canInternal": false, // "canWd": true, // "ccy": "USDT", // "chain": "USDT-TRC20", // "logoLink": "https://static.coinall.ltd/cdn/assets/imgs/221/5F74EB20302D7761.png", // "mainNet": false, // "maxFee": "1.6", // "maxWd": "8852150", // "minFee": "0.8", // "minWd": "2", // "name": "Tether", // "usedWdQuota": "0", // "wdQuota": "500", // "wdTickSz": "3" // }, // { // "canDep": true, // "canInternal": false, // "canWd": true, // "ccy": "USDT", // "chain": "USDT-ERC20", // "logoLink": "https://static.coinall.ltd/cdn/assets/imgs/221/5F74EB20302D7761.png", // "mainNet": false, // "maxFee": "16", // "maxWd": "8852150", // "minFee": "8", // "minWd": "2", // "name": "Tether", // "usedWdQuota": "0", // "wdQuota": "500", // "wdTickSz": "3" // }, // ... // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data") ch <- this.ParseDepositWithdrawFees(data, codes) return nil }() return ch } func (this *okx) ParseDepositWithdrawFees(response interface{}, optionalArgs ...interface{}) interface{} { // // [ // { // "canDep": true, // "canInternal": false, // "canWd": true, // "ccy": "USDT", // "chain": "USDT-TRC20", // "logoLink": "https://static.coinall.ltd/cdn/assets/imgs/221/5F74EB20302D7761.png", // "mainNet": false, // "maxFee": "1.6", // "maxWd": "8852150", // "minFee": "0.8", // "minWd": "2", // "name": "Tether", // "usedWdQuota": "0", // "wdQuota": "500", // "wdTickSz": "3" // } // ] // codes := GetArg(optionalArgs, 0, nil) _ = codes currencyIdKey := GetArg(optionalArgs, 1, nil) _ = currencyIdKey var depositWithdrawFees interface{} = map[string]interface{} {} codes = this.MarketCodes(codes) for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var feeInfo interface{} = GetValue(response, i) var currencyId interface{} = this.SafeString(feeInfo, "ccy") var code interface{} = this.SafeCurrencyCode(currencyId) if IsTrue(IsTrue((IsEqual(codes, nil))) || IsTrue((this.InArray(code, codes)))) { var depositWithdrawFee interface{} = this.SafeValue(depositWithdrawFees, code) if IsTrue(IsEqual(depositWithdrawFee, nil)) { AddElementToObject(depositWithdrawFees, code, this.DepositWithdrawFee(map[string]interface{} {})) } AddElementToObject(GetValue(GetValue(depositWithdrawFees, code), "info"), currencyId, feeInfo) var chain interface{} = this.SafeString(feeInfo, "chain") if IsTrue(IsEqual(chain, nil)) { continue } var chainSplit interface{} = Split(chain, "-") var networkId interface{} = this.SafeValue(chainSplit, 1) var withdrawFee interface{} = this.SafeNumber(feeInfo, "fee") var withdrawResult interface{} = map[string]interface{} { "fee": withdrawFee, "percentage": Ternary(IsTrue((!IsEqual(withdrawFee, nil))), false, nil), } var depositResult interface{} = map[string]interface{} { "fee": nil, "percentage": nil, } var networkCode interface{} = this.NetworkIdToCode(networkId, code) AddElementToObject(GetValue(GetValue(depositWithdrawFees, code), "networks"), networkCode, map[string]interface{} { "withdraw": withdrawResult, "deposit": depositResult, }) } } var depositWithdrawCodes interface{} = ObjectKeys(depositWithdrawFees) for i := 0; IsLessThan(i, GetArrayLength(depositWithdrawCodes)); i++ { var code interface{} = GetValue(depositWithdrawCodes, i) var currency interface{} = this.Currency(code) AddElementToObject(depositWithdrawFees, code, this.AssignDefaultDepositWithdrawFees(GetValue(depositWithdrawFees, code), currency)) } return depositWithdrawFees } /** * @method * @name okx#fetchSettlementHistory * @description fetches historical settlement records * @see https://www.okx.com/docs-v5/en/#rest-api-public-data-get-delivery-exercise-history * @param {string} symbol unified market symbol to fetch the settlement history for * @param {int} [since] timestamp in ms * @param {int} [limit] number of records * @param {object} [params] exchange specific params * @returns {object[]} a list of [settlement history objects]{@link https://docs.ccxt.com/#/?id=settlement-history-structure} */ func (this *okx) FetchSettlementHistory(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchSettlementHistory() requires a symbol argument"))) } retRes76438 := (<-this.LoadMarkets()) PanicOnError(retRes76438) var market interface{} = this.Market(symbol) var typeVar interface{} = nil typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchSettlementHistory", market, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) if IsTrue(IsTrue(!IsEqual(typeVar, "future")) && IsTrue(!IsEqual(typeVar, "option"))) { panic(NotSupported(Add(this.Id, " fetchSettlementHistory() supports futures and options markets only"))) } var request interface{} = map[string]interface{} { "instType": this.ConvertToInstrumentType(typeVar), "uly": Add(Add(GetValue(market, "baseId"), "-"), GetValue(market, "quoteId")), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "before", Subtract(since, 1)) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PublicGetPublicDeliveryExerciseHistory(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "details": [ // { // "insId": "BTC-USD-230523-25750-C", // "px": "27290.1486867000556483", // "type": "exercised" // }, // ], // "ts":"1684656000000" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var settlements interface{} = this.ParseSettlements(data, market) var sorted interface{} = this.SortBy(settlements, "timestamp") ch <- this.FilterBySymbolSinceLimit(sorted, GetValue(market, "symbol"), since, limit) return nil }() return ch } func (this *okx) ParseSettlement(settlement interface{}, market interface{}) interface{} { // // { // "insId": "BTC-USD-230521-28500-P", // "px": "27081.2007345984751516", // "type": "exercised" // } // var marketId interface{} = this.SafeString(settlement, "insId") return map[string]interface{} { "info": settlement, "symbol": this.SafeSymbol(marketId, market), "price": this.SafeNumber(settlement, "px"), "timestamp": nil, "datetime": nil, } } func (this *okx) ParseSettlements(settlements interface{}, market interface{}) interface{} { // // { // "details": [ // { // "insId": "BTC-USD-230523-25750-C", // "px": "27290.1486867000556483", // "type": "exercised" // }, // ], // "ts":"1684656000000" // } // var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(settlements)); i++ { var entry interface{} = GetValue(settlements, i) var timestamp interface{} = this.SafeInteger(entry, "ts") var details interface{} = this.SafeList(entry, "details", []interface{}{}) for j := 0; IsLessThan(j, GetArrayLength(details)); j++ { var settlement interface{} = this.ParseSettlement(GetValue(details, j), market) AppendToArray(&result,this.Extend(settlement, map[string]interface{} { "timestamp": timestamp, "datetime": this.Iso8601(timestamp), })) } } return result } /** * @method * @name okx#fetchUnderlyingAssets * @description fetches the market ids of underlying assets for a specific contract market type * @see https://www.okx.com/docs-v5/en/#public-data-rest-api-get-underlying * @param {object} [params] exchange specific params * @param {string} [params.type] the contract market type, 'option', 'swap' or 'future', the default is 'option' * @returns {object[]} a list of [underlying assets]{@link https://docs.ccxt.com/#/?id=underlying-assets-structure} */ func (this *okx) FetchUnderlyingAssets(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 retRes77428 := (<-this.LoadMarkets()) PanicOnError(retRes77428) var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchUnderlyingAssets", nil, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) if IsTrue(IsTrue((IsEqual(marketType, nil))) || IsTrue((IsEqual(marketType, "spot")))) { marketType = "option" } if IsTrue(IsTrue(IsTrue((!IsEqual(marketType, "option"))) && IsTrue((!IsEqual(marketType, "swap")))) && IsTrue((!IsEqual(marketType, "future")))) { panic(NotSupported(Add(this.Id, " fetchUnderlyingAssets() supports contract markets only"))) } var request interface{} = map[string]interface{} { "instType": this.ConvertToInstrumentType(marketType), } response:= (<-this.PublicGetPublicUnderlying(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // [ // "BTC-USD", // "ETH-USD" // ] // ], // "msg": "" // } // var underlyings interface{} = this.SafeList(response, "data", []interface{}{}) ch <- GetValue(underlyings, 0) return nil }() return ch } /** * @method * @name okx#fetchGreeks * @description fetches an option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract * @see https://www.okx.com/docs-v5/en/#public-data-rest-api-get-option-market-data * @param {string} symbol unified symbol of the market to fetch greeks for * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [greeks structure]{@link https://docs.ccxt.com/#/?id=greeks-structure} */ func (this *okx) FetchGreeks(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 retRes77818 := (<-this.LoadMarkets()) PanicOnError(retRes77818) var market interface{} = this.Market(symbol) var marketId interface{} = GetValue(market, "id") var optionParts interface{} = Split(marketId, "-") var request interface{} = map[string]interface{} { "uly": GetValue(GetValue(market, "info"), "uly"), "instFamily": GetValue(GetValue(market, "info"), "instFamily"), "expTime": this.SafeString(optionParts, 2), } response:= (<-this.PublicGetPublicOptSummary(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "askVol": "0", // "bidVol": "0", // "delta": "0.5105464486882039", // "deltaBS": "0.7325502184143025", // "fwdPx": "37675.80158694987186", // "gamma": "-0.13183515090501083", // "gammaBS": "0.000024139685826358558", // "instId": "BTC-USD-240329-32000-C", // "instType": "OPTION", // "lever": "4.504428015946619", // "markVol": "0.5916253554539876", // "realVol": "0", // "theta": "-0.0004202992014012855", // "thetaBS": "-18.52354631567909", // "ts": "1699586421976", // "uly": "BTC-USD", // "vega": "0.0020207455080045846", // "vegaBS": "74.44022302387287", // "volLv": "0.5948549730405797" // }, // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var entry interface{} = GetValue(data, i) var entryMarketId interface{} = this.SafeString(entry, "instId") if IsTrue(IsEqual(entryMarketId, marketId)) { ch <- this.ParseGreeks(entry, market) return nil } } return nil }() return ch } func (this *okx) ParseGreeks(greeks interface{}, optionalArgs ...interface{}) interface{} { // // { // "askVol": "0", // "bidVol": "0", // "delta": "0.5105464486882039", // "deltaBS": "0.7325502184143025", // "fwdPx": "37675.80158694987186", // "gamma": "-0.13183515090501083", // "gammaBS": "0.000024139685826358558", // "instId": "BTC-USD-240329-32000-C", // "instType": "OPTION", // "lever": "4.504428015946619", // "markVol": "0.5916253554539876", // "realVol": "0", // "theta": "-0.0004202992014012855", // "thetaBS": "-18.52354631567909", // "ts": "1699586421976", // "uly": "BTC-USD", // "vega": "0.0020207455080045846", // "vegaBS": "74.44022302387287", // "volLv": "0.5948549730405797" // } // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeInteger(greeks, "ts") var marketId interface{} = this.SafeString(greeks, "instId") var symbol interface{} = this.SafeSymbol(marketId, market) return map[string]interface{} { "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "delta": this.SafeNumber(greeks, "delta"), "gamma": this.SafeNumber(greeks, "gamma"), "theta": this.SafeNumber(greeks, "theta"), "vega": this.SafeNumber(greeks, "vega"), "rho": nil, "bidSize": nil, "askSize": nil, "bidImpliedVolatility": this.SafeNumber(greeks, "bidVol"), "askImpliedVolatility": this.SafeNumber(greeks, "askVol"), "markImpliedVolatility": this.SafeNumber(greeks, "markVol"), "bidPrice": nil, "askPrice": nil, "markPrice": nil, "lastPrice": nil, "underlyingPrice": nil, "info": greeks, } } /** * @method * @name okx#closePosition * @description closes open positions for a market * @see https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-close-positions * @param {string} symbol Unified CCXT market symbol * @param {string} [side] 'buy' or 'sell', leave as undefined in net mode * @param {object} [params] extra parameters specific to the okx api endpoint * @param {string} [params.clientOrderId] a unique identifier for the order * @param {string} [params.marginMode] 'cross' or 'isolated', default is 'cross; * @param {string} [params.code] *required in the case of closing cross MARGIN position for Single-currency margin* margin currency * * EXCHANGE SPECIFIC PARAMETERS * @param {boolean} [params.autoCxl] whether any pending orders for closing out needs to be automatically canceled when close position via a market order. false or true, the default is false * @param {string} [params.tag] order tag a combination of case-sensitive alphanumerics, all numbers, or all letters of up to 16 characters * @returns {object[]} [A list of position structures]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *okx) ClosePosition(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) side := GetArg(optionalArgs, 0, nil) _ = side params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes78998 := (<-this.LoadMarkets()) PanicOnError(retRes78998) var market interface{} = this.Market(symbol) var clientOrderId interface{} = this.SafeString(params, "clientOrderId") var code interface{} = this.SafeString(params, "code") var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("closePosition", params, "cross"); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), "mgnMode": marginMode, } if IsTrue(!IsEqual(side, nil)) { if IsTrue((IsEqual(side, "buy"))) { AddElementToObject(request, "posSide", "long") } else if IsTrue(IsEqual(side, "sell")) { AddElementToObject(request, "posSide", "short") } else { AddElementToObject(request, "posSide", side) } } if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "clOrdId", clientOrderId) } if IsTrue(!IsEqual(code, nil)) { var currency interface{} = this.Currency(code) AddElementToObject(request, "ccy", GetValue(currency, "id")) } response:= (<-this.PrivatePostTradeClosePosition(this.Extend(request, params))) PanicOnError(response) // // { // "code": "1", // "data": [ // { // "clOrdId":"e847386590ce4dBCe903bbc394dc88bf", // "ordId":"", // "sCode":"51000", // "sMsg":"Parameter posSide error ", // "tag":"e847386590ce4dBC" // } // ], // "inTime": "1701877077101064", // "msg": "All operations failed", // "outTime": "1701877077102579" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var order interface{} = this.SafeDict(data, 0) ch <- this.ParseOrder(order, market) return nil }() return ch } /** * @method * @name okx#fetchOption * @description fetches option data that is commonly found in an option chain * @see https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-ticker * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [option chain structure]{@link https://docs.ccxt.com/#/?id=option-chain-structure} */ func (this *okx) FetchOption(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 retRes79588 := (<-this.LoadMarkets()) PanicOnError(retRes79588) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } response:= (<-this.PublicGetMarketTicker(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "", // "data": [ // { // "instType": "OPTION", // "instId": "BTC-USD-241227-60000-P", // "last": "", // "lastSz": "0", // "askPx": "", // "askSz": "0", // "bidPx": "", // "bidSz": "0", // "open24h": "", // "high24h": "", // "low24h": "", // "volCcy24h": "0", // "vol24h": "0", // "ts": "1711176035035", // "sodUtc0": "", // "sodUtc8": "" // } // ] // } // var result interface{} = this.SafeList(response, "data", []interface{}{}) var chain interface{} = this.SafeDict(result, 0, map[string]interface{} {}) ch <- this.ParseOption(chain, nil, market) return nil }() return ch } /** * @method * @name okx#fetchOptionChain * @description fetches data for an underlying asset that is commonly found in an option chain * @see https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers * @param {string} code base currency to fetch an option chain for * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.uly] the underlying asset, can be obtained from fetchUnderlyingAssets () * @returns {object} a list of [option chain structures]{@link https://docs.ccxt.com/#/?id=option-chain-structure} */ func (this *okx) FetchOptionChain(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes80068 := (<-this.LoadMarkets()) PanicOnError(retRes80068) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "uly": Add(GetValue(currency, "code"), "-USD"), "instType": "OPTION", } response:= (<-this.PublicGetMarketTickers(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "msg": "", // "data": [ // { // "instType": "OPTION", // "instId": "BTC-USD-240323-52000-C", // "last": "", // "lastSz": "0", // "askPx": "", // "askSz": "0", // "bidPx": "", // "bidSz": "0", // "open24h": "", // "high24h": "", // "low24h": "", // "volCcy24h": "0", // "vol24h": "0", // "ts": "1711176207008", // "sodUtc0": "", // "sodUtc8": "" // }, // ] // } // var result interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOptionChain(result, nil, "instId") return nil }() return ch } func (this *okx) ParseOption(chain interface{}, optionalArgs ...interface{}) interface{} { // // { // "instType": "OPTION", // "instId": "BTC-USD-241227-60000-P", // "last": "", // "lastSz": "0", // "askPx": "", // "askSz": "0", // "bidPx": "", // "bidSz": "0", // "open24h": "", // "high24h": "", // "low24h": "", // "volCcy24h": "0", // "vol24h": "0", // "ts": "1711176035035", // "sodUtc0": "", // "sodUtc8": "" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency market := GetArg(optionalArgs, 1, nil) _ = market var marketId interface{} = this.SafeString(chain, "instId") market = this.SafeMarket(marketId, market) var timestamp interface{} = this.SafeInteger(chain, "ts") return map[string]interface{} { "info": chain, "currency": nil, "symbol": GetValue(market, "symbol"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "impliedVolatility": nil, "openInterest": nil, "bidPrice": this.SafeNumber(chain, "bidPx"), "askPrice": this.SafeNumber(chain, "askPx"), "midPrice": nil, "markPrice": nil, "lastPrice": this.SafeNumber(chain, "last"), "underlyingPrice": nil, "change": nil, "percentage": nil, "baseVolume": this.SafeNumber(chain, "volCcy24h"), "quoteVolume": nil, } } /** * @method * @name okx#fetchConvertQuote * @description fetch a quote for converting from one currency to another * @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-estimate-quote * @param {string} fromCode the currency that you want to sell and convert from * @param {string} toCode the currency that you want to buy and convert into * @param {float} [amount] how much you want to trade in units of the from currency * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure} */ func (this *okx) FetchConvertQuote(fromCode interface{}, toCode interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) amount := GetArg(optionalArgs, 0, nil) _ = amount params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes81008 := (<-this.LoadMarkets()) PanicOnError(retRes81008) var request interface{} = map[string]interface{} { "baseCcy": ToUpper(fromCode), "quoteCcy": ToUpper(toCode), "rfqSzCcy": ToUpper(fromCode), "rfqSz": this.NumberToString(amount), "side": "sell", } response:= (<-this.PrivatePostAssetConvertEstimateQuote(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "baseCcy": "ETH", // "baseSz": "0.01023052", // "clQReqId": "", // "cnvtPx": "2932.40104429", // "origRfqSz": "30", // "quoteCcy": "USDT", // "quoteId": "quoterETH-USDT16461885104612381", // "quoteSz": "30", // "quoteTime": "1646188510461", // "rfqSz": "30", // "rfqSzCcy": "USDT", // "side": "buy", // "ttlMs": "10000" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var result interface{} = this.SafeDict(data, 0, map[string]interface{} {}) var fromCurrencyId interface{} = this.SafeString(result, "baseCcy", fromCode) var fromCurrency interface{} = this.Currency(fromCurrencyId) var toCurrencyId interface{} = this.SafeString(result, "quoteCcy", toCode) var toCurrency interface{} = this.Currency(toCurrencyId) ch <- this.ParseConversion(result, fromCurrency, toCurrency) return nil }() return ch } /** * @method * @name okx#createConvertTrade * @description convert from one currency to another * @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-convert-trade * @param {string} id the id of the trade that you want to make * @param {string} fromCode the currency that you want to sell and convert from * @param {string} toCode the currency that you want to buy and convert into * @param {float} [amount] how much you want to trade in units of the from currency * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure} */ func (this *okx) CreateConvertTrade(id interface{}, fromCode interface{}, toCode interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) amount := GetArg(optionalArgs, 0, nil) _ = amount params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes81548 := (<-this.LoadMarkets()) PanicOnError(retRes81548) var request interface{} = map[string]interface{} { "quoteId": id, "baseCcy": fromCode, "quoteCcy": toCode, "szCcy": fromCode, "sz": this.NumberToString(amount), "side": "sell", } response:= (<-this.PrivatePostAssetConvertTrade(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "baseCcy": "ETH", // "clTReqId": "", // "fillBaseSz": "0.01023052", // "fillPx": "2932.40104429", // "fillQuoteSz": "30", // "instId": "ETH-USDT", // "quoteCcy": "USDT", // "quoteId": "quoterETH-USDT16461885104612381", // "side": "buy", // "state": "fullyFilled", // "tradeId": "trader16461885203381437", // "ts": "1646188520338" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var result interface{} = this.SafeDict(data, 0, map[string]interface{} {}) var fromCurrencyId interface{} = this.SafeString(result, "baseCcy", fromCode) var fromCurrency interface{} = this.Currency(fromCurrencyId) var toCurrencyId interface{} = this.SafeString(result, "quoteCcy", toCode) var toCurrency interface{} = this.Currency(toCurrencyId) ch <- this.ParseConversion(result, fromCurrency, toCurrency) return nil }() return ch } /** * @method * @name okx#fetchConvertTrade * @description fetch the data for a conversion trade * @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-history * @param {string} id the id of the trade that you want to fetch * @param {string} [code] the unified currency code of the conversion trade * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure} */ func (this *okx) FetchConvertTrade(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes82068 := (<-this.LoadMarkets()) PanicOnError(retRes82068) var request interface{} = map[string]interface{} { "clTReqId": id, } response:= (<-this.PrivateGetAssetConvertHistory(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "clTReqId": "", // "instId": "ETH-USDT", // "side": "buy", // "fillPx": "2932.401044", // "baseCcy": "ETH", // "quoteCcy": "USDT", // "fillBaseSz": "0.01023052", // "state": "fullyFilled", // "tradeId": "trader16461885203381437", // "fillQuoteSz": "30", // "ts": "1646188520000" // } // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var result interface{} = this.SafeDict(data, 0, map[string]interface{} {}) var fromCurrencyId interface{} = this.SafeString(result, "baseCcy") var toCurrencyId interface{} = this.SafeString(result, "quoteCcy") var fromCurrency interface{} = nil var toCurrency interface{} = nil if IsTrue(!IsEqual(fromCurrencyId, nil)) { fromCurrency = this.Currency(fromCurrencyId) } if IsTrue(!IsEqual(toCurrencyId, nil)) { toCurrency = this.Currency(toCurrencyId) } ch <- this.ParseConversion(result, fromCurrency, toCurrency) return nil }() return ch } /** * @method * @name okx#fetchConvertTradeHistory * @description fetch the users history of conversion trades * @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-history * @param {string} [code] the unified currency code * @param {int} [since] the earliest time in ms to fetch conversions for * @param {int} [limit] the maximum number of conversion structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest conversion to fetch * @returns {object[]} a list of [conversion structures]{@link https://docs.ccxt.com/#/?id=conversion-structure} */ func (this *okx) FetchConvertTradeHistory(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes82608 := (<-this.LoadMarkets()) PanicOnError(retRes82608) var request interface{} = map[string]interface{} {} requestparamsVariable := this.HandleUntilOption("after", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "before", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivateGetAssetConvertHistory(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "clTReqId": "", // "instId": "ETH-USDT", // "side": "buy", // "fillPx": "2932.401044", // "baseCcy": "ETH", // "quoteCcy": "USDT", // "fillBaseSz": "0.01023052", // "state": "fullyFilled", // "tradeId": "trader16461885203381437", // "fillQuoteSz": "30", // "ts": "1646188520000" // } // ], // "msg": "" // } // var rows interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseConversions(rows, code, "baseCcy", "quoteCcy", since, limit) return nil }() return ch } func (this *okx) ParseConversion(conversion interface{}, optionalArgs ...interface{}) interface{} { // // fetchConvertQuote // // { // "baseCcy": "ETH", // "baseSz": "0.01023052", // "clQReqId": "", // "cnvtPx": "2932.40104429", // "origRfqSz": "30", // "quoteCcy": "USDT", // "quoteId": "quoterETH-USDT16461885104612381", // "quoteSz": "30", // "quoteTime": "1646188510461", // "rfqSz": "30", // "rfqSzCcy": "USDT", // "side": "buy", // "ttlMs": "10000" // } // // createConvertTrade // // { // "baseCcy": "ETH", // "clTReqId": "", // "fillBaseSz": "0.01023052", // "fillPx": "2932.40104429", // "fillQuoteSz": "30", // "instId": "ETH-USDT", // "quoteCcy": "USDT", // "quoteId": "quoterETH-USDT16461885104612381", // "side": "buy", // "state": "fullyFilled", // "tradeId": "trader16461885203381437", // "ts": "1646188520338" // } // // fetchConvertTrade, fetchConvertTradeHistory // // { // "clTReqId": "", // "instId": "ETH-USDT", // "side": "buy", // "fillPx": "2932.401044", // "baseCcy": "ETH", // "quoteCcy": "USDT", // "fillBaseSz": "0.01023052", // "state": "fullyFilled", // "tradeId": "trader16461885203381437", // "fillQuoteSz": "30", // "ts": "1646188520000" // } // fromCurrency := GetArg(optionalArgs, 0, nil) _ = fromCurrency toCurrency := GetArg(optionalArgs, 1, nil) _ = toCurrency var timestamp interface{} = this.SafeInteger2(conversion, "quoteTime", "ts") var fromCoin interface{} = this.SafeString(conversion, "baseCcy") var fromCode interface{} = this.SafeCurrencyCode(fromCoin, fromCurrency) var to interface{} = this.SafeString(conversion, "quoteCcy") var toCode interface{} = this.SafeCurrencyCode(to, toCurrency) return map[string]interface{} { "info": conversion, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "id": this.SafeStringN(conversion, []interface{}{"clQReqId", "tradeId", "quoteId"}), "fromCurrency": fromCode, "fromAmount": this.SafeNumber2(conversion, "baseSz", "fillBaseSz"), "toCurrency": toCode, "toAmount": this.SafeNumber2(conversion, "quoteSz", "fillQuoteSz"), "price": this.SafeNumber2(conversion, "cnvtPx", "fillPx"), "fee": nil, } } /** * @method * @name okx#fetchConvertCurrencies * @description fetches all available currencies that can be converted * @see https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-currencies * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ func (this *okx) FetchConvertCurrencies(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 retRes83768 := (<-this.LoadMarkets()) PanicOnError(retRes83768) response:= (<-this.PrivateGetAssetConvertCurrencies(params)) PanicOnError(response) // // { // "code": "0", // "data": [ // { // "ccy": "BTC", // "max": "", // "min": "" // }, // ], // "msg": "" // } // var result interface{} = map[string]interface{} {} var data interface{} = this.SafeList(response, "data", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var entry interface{} = GetValue(data, i) var id interface{} = this.SafeString(entry, "ccy") var code interface{} = this.SafeCurrencyCode(id) AddElementToObject(result, code, map[string]interface{} { "info": entry, "id": id, "code": code, "networks": nil, "type": nil, "name": nil, "active": nil, "deposit": nil, "withdraw": nil, "fee": nil, "precision": nil, "limits": map[string]interface{} { "amount": map[string]interface{} { "min": this.SafeNumber(entry, "min"), "max": this.SafeNumber(entry, "max"), }, "withdraw": map[string]interface{} { "min": nil, "max": nil, }, "deposit": map[string]interface{} { "min": nil, "max": nil, }, }, "created": nil, }) } ch <- result return nil }() return ch } func (this *okx) 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 } // // { // "code": "1", // "data": [ // { // "clOrdId": "", // "ordId": "", // "sCode": "51119", // "sMsg": "Order placement failed due to insufficient balance. ", // "tag": "" // } // ], // "msg": "" // }, // { // "code": "58001", // "data": [], // "msg": "Incorrect trade password" // } // var code interface{} = this.SafeString(response, "code") if IsTrue(IsTrue((!IsEqual(code, "0"))) && IsTrue((!IsEqual(code, "2")))) { var feedback interface{} = Add(Add(this.Id, " "), body) var data interface{} = this.SafeList(response, "data", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var error interface{} = GetValue(data, i) var errorCode interface{} = this.SafeString(error, "sCode") var message interface{} = this.SafeString(error, "sMsg") this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorCode, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, feedback) } this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), code, feedback) panic(ExchangeError(feedback)) } return nil } /** * @method * @name okx#fetchMarginAdjustmentHistory * @description fetches the history of margin added or reduced from contract isolated positions * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-7-days * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months * @param {string} [symbol] not used by okx fetchMarginAdjustmentHistory * @param {string} [type] "add" or "reduce" * @param {int} [since] the earliest time in ms to fetch margin adjustment history for * @param {int} [limit] the maximum number of entries to retrieve * @param {object} params extra parameters specific to the exchange api endpoint * @param {boolean} [params.auto] true if fetching auto margin increases * @returns {object[]} a list of [margin structures]{@link https://docs.ccxt.com/#/?id=margin-loan-structure} */ func (this *okx) FetchMarginAdjustmentHistory(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol typeVar := GetArg(optionalArgs, 1, nil) _ = typeVar since := GetArg(optionalArgs, 2, nil) _ = since limit := GetArg(optionalArgs, 3, nil) _ = limit params := GetArg(optionalArgs, 4, map[string]interface{} {}) _ = params retRes84858 := (<-this.LoadMarkets()) PanicOnError(retRes84858) var auto interface{} = this.SafeBool(params, "auto") if IsTrue(IsEqual(typeVar, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchMarginAdjustmentHistory () requires a type argument"))) } var isAdd interface{} = IsEqual(typeVar, "add") var subType interface{} = Ternary(IsTrue(isAdd), "160", "161") if IsTrue(auto) { if IsTrue(isAdd) { subType = "162" } else { panic(BadRequest(Add(Add(this.Id, " cannot fetch margin adjustments for type "), typeVar))) } } var request interface{} = map[string]interface{} { "subType": subType, "mgnMode": "isolated", } var until interface{} = this.SafeInteger(params, "until") params = this.Omit(params, "until") if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "endTime", until) } var response interface{} = nil var now interface{} = this.Milliseconds() var oneWeekAgo interface{} = Subtract(now, 604800000) var threeMonthsAgo interface{} = Subtract(now, 7776000000) if IsTrue(IsTrue((IsEqual(since, nil))) || IsTrue((IsGreaterThan(since, oneWeekAgo)))) { response = (<-this.PrivateGetAccountBills(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsGreaterThan(since, threeMonthsAgo)) { response = (<-this.PrivateGetAccountBillsArchive(this.Extend(request, params))) PanicOnError(response) } else { panic(BadRequest(Add(this.Id, " fetchMarginAdjustmentHistory () cannot fetch margin adjustments older than 3 months"))) } // // { // code: '0', // data: [ // { // bal: '67621.4325135010619812', // balChg: '-10.0000000000000000', // billId: '691293628710342659', // ccy: 'USDT', // clOrdId: '', // execType: '', // fee: '0', // fillFwdPx: '', // fillIdxPx: '', // fillMarkPx: '', // fillMarkVol: '', // fillPxUsd: '', // fillPxVol: '', // fillTime: '1711089244850', // from: '', // instId: 'XRP-USDT-SWAP', // instType: 'SWAP', // interest: '0', // mgnMode: 'isolated', // notes: '', // ordId: '', // pnl: '0', // posBal: '73.12', // posBalChg: '10.00', // px: '', // subType: '160', // sz: '10', // tag: '', // to: '', // tradeId: '0', // ts: '1711089244699', // type: '6' // } // ], // msg: '' // } // var data interface{} = this.SafeList(response, "data") var modifications interface{} = this.ParseMarginModifications(data) ch <- this.FilterBySymbolSinceLimit(modifications, symbol, since, limit) return nil }() return ch } /** * @method * @name okx#fetchPositionsHistory * @description fetches historical positions * @see https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-positions-history * @param {string} [symbols] unified market symbols * @param {int} [since] timestamp in ms of the earliest position to fetch * @param {int} [limit] the maximum amount of records to fetch, default=100, max=100 * @param {object} params extra parameters specific to the exchange api endpoint * @param {string} [params.marginMode] "cross" or "isolated" * * EXCHANGE SPECIFIC PARAMETERS * @param {string} [params.instType] margin, swap, futures or option * @param {string} [params.type] the type of latest close position 1: close position partially, 2:close all, 3:liquidation, 4:partial liquidation; 5:adl, is it is the latest type if there are several types for the same position * @param {string} [params.posId] position id, there is attribute expiration, the posid will be expired if it is more than 30 days after the last full close position, then position will use new posid * @param {string} [params.before] timestamp in ms of the earliest position to fetch based on the last update time of the position * @param {string} [params.after] timestamp in ms of the latest position to fetch based on the last update time of the position * @returns {object[]} a list of [position structures]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *okx) FetchPositionsHistory(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes85928 := (<-this.LoadMarkets()) PanicOnError(retRes85928) var marginMode interface{} = this.SafeString(params, "marginMode") var instType interface{} = this.SafeStringUpper(params, "instType") params = this.Omit(params, []interface{}{"until", "marginMode", "instType"}) if IsTrue(IsEqual(limit, nil)) { limit = 100 } var request interface{} = map[string]interface{} { "limit": limit, } if IsTrue(!IsEqual(symbols, nil)) { var symbolsLength interface{} = GetArrayLength(symbols) if IsTrue(IsEqual(symbolsLength, 1)) { var market interface{} = this.Market(GetValue(symbols, 0)) AddElementToObject(request, "instId", GetValue(market, "id")) } } if IsTrue(!IsEqual(marginMode, nil)) { AddElementToObject(request, "mgnMode", marginMode) } if IsTrue(!IsEqual(instType, nil)) { AddElementToObject(request, "instType", instType) } response:= (<-this.PrivateGetAccountPositionsHistory(this.Extend(request, params))) PanicOnError(response) // // { // code: '0', // data: [ // { // cTime: '1708735940395', // ccy: 'USDT', // closeAvgPx: '0.6330444444444444', // closeTotalPos: '27', // direction: 'long', // fee: '-1.69566', // fundingFee: '-11.870404179341788', // instId: 'XRP-USDT-SWAP', // instType: 'SWAP', // lever: '3.0', // liqPenalty: '0', // mgnMode: 'cross', // openAvgPx: '0.623', // openMaxPos: '15', // pnl: '27.11999999999988', // pnlRatio: '0.0241732402722634', // posId: '681423155054862336', // realizedPnl: '13.553935820658092', // triggerPx: '', // type: '2', // uTime: '1711088748170', // uly: 'XRP-USDT' // }, // ... // ], // msg: '' // } // var data interface{} = this.SafeList(response, "data") var positions interface{} = this.ParsePositions(data, symbols, params) ch <- this.FilterBySinceLimit(positions, since, limit) return nil }() return ch } /** * @method * @name okx#fetchLongShortRatioHistory * @description fetches the long short ratio history for a unified market symbol * @see https://www.okx.com/docs-v5/en/#trading-statistics-rest-api-get-contract-long-short-ratio * @param {string} symbol unified symbol of the market to fetch the long short ratio for * @param {string} [timeframe] the period for the ratio * @param {int} [since] the earliest time in ms to fetch ratios for * @param {int} [limit] the maximum number of long short ratio structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest ratio to fetch * @returns {object[]} an array of [long short ratio structures]{@link https://docs.ccxt.com/#/?id=long-short-ratio-structure} */ func (this *okx) FetchLongShortRatioHistory(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol timeframe := GetArg(optionalArgs, 1, nil) _ = timeframe since := GetArg(optionalArgs, 2, nil) _ = since limit := GetArg(optionalArgs, 3, nil) _ = limit params := GetArg(optionalArgs, 4, map[string]interface{} {}) _ = params retRes86688 := (<-this.LoadMarkets()) PanicOnError(retRes86688) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "instId": GetValue(market, "id"), } var until interface{} = this.SafeString2(params, "until", "end") params = this.Omit(params, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "end", until) } if IsTrue(!IsEqual(timeframe, nil)) { AddElementToObject(request, "period", timeframe) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "begin", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PublicGetRubikStatContractsLongShortAccountRatioContract(this.Extend(request, params))) PanicOnError(response) // // { // "code": "0", // "data": [ // ["1729323600000", "0.9398602814619824"], // ["1729323300000", "0.9398602814619824"], // ["1729323000000", "0.9398602814619824"], // ], // "msg": "" // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var entry interface{} = GetValue(data, i) AppendToArray(&result,map[string]interface{} { "timestamp": this.SafeString(entry, 0), "longShortRatio": this.SafeString(entry, 1), }) } ch <- this.ParseLongShortRatioHistory(result, market) return nil }() return ch } func (this *okx) ParseLongShortRatio(info interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeInteger(info, "timestamp") var symbol interface{} = nil if IsTrue(!IsEqual(market, nil)) { symbol = GetValue(market, "symbol") } return map[string]interface{} { "info": info, "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "timeframe": nil, "longShortRatio": this.SafeNumber(info, "longShortRatio"), } } func (this *okx) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }