ccxt-go/okx.go
zhangkun9038@dingtalk.com 1a2ce7046a first add
2025-02-28 10:33:20 +08:00

9982 lines
443 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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, 2close all, 3liquidation, 4partial liquidation; 5adl, 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
}