This file is a merged representation of a subset of the codebase, containing files not matching ignore patterns, combined into a single document by Repomix. The content has been processed where content has been compressed (code blocks are separated by ⋮---- delimiter). ================================================================ File Summary ================================================================ Purpose: -------- This file contains a packed representation of a subset of the repository's contents that is considered the most important context. It is designed to be easily consumable by AI systems for analysis, code review, or other automated processes. File Format: ------------ The content is organized as follows: 1. This summary section 2. Repository information 3. Directory structure 4. Repository files (if enabled) 5. Multiple file entries, each consisting of: a. A separator line (================) b. The file path (File: path/to/file) c. Another separator line d. The full contents of the file e. A blank line Usage Guidelines: ----------------- - This file should be treated as read-only. Any changes should be made to the original repository files, not this packed version. - When processing this file, use the file path to distinguish between different files in the repository. - Be aware that this file may contain sensitive information. Handle it with the same level of security as you would the original repository. Notes: ------ - Some files may have been excluded based on .gitignore rules and Repomix's configuration - Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files - Files matching these patterns are excluded: .github/, examples/apidoc/, docs/images/, docs/endpointFunctionList.md, test/, src/util/ - Files matching patterns in .gitignore are excluded - Files matching default ignore patterns are excluded - Content has been compressed - code blocks are separated by ⋮---- delimiter - Files are sorted by Git change count (files with more changes are at the bottom) ================================================================ Directory Structure ================================================================ examples/ auth/ fasterHmacSign.ts app.okx.com.ts demo-trading.ts my.okx.com.ts README.md rest-private-trade-market.ts rest-private-trade.ts rest-public.ts ws-api-client.ts ws-api-trade-raw.ts ws-private-handle-auth-fail.ts ws-private.ts ws-public.ts src/ constants/ funding.ts types/ rest/ request/ account.ts block-trading.ts convert.ts copy-trading.ts funding.ts grid-trading.ts public.ts recurring-buy.ts shared.ts signal-bot.ts simple-earn.ts spread-trading.ts subaccount.ts trade.ts response/ private-account.ts private-block-trading.ts private-copy-trading.ts private-flexible-loan.ts private-funding.ts private-recurring-buy.ts private-signal-bot.ts private-spread-trading.ts private-subaccount.ts private-trade.ts public-data.ts client.ts shared.ts websockets/ ws-api-request.ts ws-api-response.ts ws-api.ts ws-events.ts ws-general.ts ws-request.ts shared.ts index.ts rest-client.ts websocket-api-client.ts websocket-client-legacy.ts websocket-client.ts webpack/ webpack.config.js .eslintrc.cjs .gitignore .jshintrc .nvmrc .prettierrc jest.config.ts LICENSE.md package.json postBuild.sh README.md tsconfig.cjs.json tsconfig.esm.json tsconfig.json tsconfig.linting.json ================================================================ Files ================================================================ ================ File: examples/README.md ================ # Examples These samples can be executed using `ts-node`: ``` ts-node ./examples/rest-spot-public.ts ``` ================ File: examples/rest-private-trade-market.ts ================ import { OrderRequest, RestClient } from '../src/index'; ⋮---- // or // import { RestClient, OrderRequest } from 'okx-api'; ⋮---- // read from environmental variables ⋮---- // If running from CLI in unix, you can pass env vars as such: // API_KEY_COM='lkm12n3-2ba3-1mxf-fn13-lkm12n3a' API_SECRET_COM='035B2B9637E1BDFFEE2646BFBDDB8CE4' API_PASSPHRASE_COM='ComplexPa$$!23$5^' ts-node examples/rest-private-trade-market.ts ⋮---- // note the single quotes, preventing special characters such as $ from being incorrectly passed ⋮---- // apiKey: 'apiKeyHere', ⋮---- // apiSecret: 'apiSecretHere', ⋮---- // apiPass: 'apiPassHere', ⋮---- /** Get available balance for an asset */ async function getAssetBalance( client: RestClient, coin: string, ): Promise ⋮---- /** * This is a simple REST API demo script wrapped in a immediately invoked function expression. The logic below will immediately execute if you run this script. * * It is designed to: * - check for any available USDT balance * - immediately use half the balance to buy bitcoin (in spot) * - check the available BTC balance * - immediately sell all available BTC back to USDT */ ================ File: examples/rest-public.ts ================ import { RestClient } from '../src/index'; ⋮---- // or // import { RestClient } from 'okx-api'; ⋮---- /** * This is a simple script wrapped in a immediately invoked function expression, designed to make public API calls without credentials */ ================ File: src/constants/funding.ts ================ /** * Asset bill type, auto-generated using table from funding asset bill details: * https://www.okx.com/docs-v5/en/#rest-api-funding-asset-bills-details */ export enum ASSET_BILL_TYPE { DEPOSIT = '1', WITHDRAWAL = '2', CANCELED_WITHDRAWAL = '13', TRANSFER_TO_SUB_ACCOUNT = '20', TRANSFER_FROM_SUB_ACCOUNT = '21', CLAIM = '28', SYSTEM_REVERSAL = '47', RECEIVED_FROM_ACTIVITIES = '48', GIVEN_AWAY_TO_ACTIVITIES = '49', RECEIVED_FROM_APPOINTMENTS = '50', DEDUCTED_FROM_APPOINTMENTS = '51', RED_PACKET_SENT = '52', RED_PACKET_SNATCHED = '53', RED_PACKET_REFUNDED = '54', CONVERSION = '61', CLAIM_REBATE_CARD = '68', DISTRIBUTE_REBATE_CARD = '69', TOKEN_RECEIVED = '72', TOKEN_GIVEN_AWAY = '73', TOKEN_REFUNDED = '74', SUBSCRIPTION_TO_SAVINGS = '75', REDEMPTION_TO_SAVINGS = '76', DISTRIBUTE = '77', LOCK_UP = '78', NODE_VOTING = '79', STAKING_1 = '80', VOTE_REDEMPTION = '81', STAKING_REDEMPTION_1 = '82', STAKING_YIELD = '83', VIOLATION_FEE = '84', POW_MINING_YIELD = '85', CLOUD_MINING_PAY = '86', CLOUD_MINING_YIELD = '87', SUBSIDY = '88', STAKING_2 = '89', STAKING_SUBSCRIPTION = '90', STAKING_REDEMPTION_2 = '91', ADD_COLLATERAL = '92', REDEEM_COLLATERAL = '93', INVESTMENT = '94', BORROWER_BORROWS = '95', PRINCIPAL_TRANSFERRED_IN = '96', BORROWER_TRANSFERRED_LOAN_OUT = '97', BORROWER_TRANSFERRED_INTEREST_OUT = '98', INVESTOR_TRANSFERRED_INTEREST_IN = '99', PREPAYMENT_PENALTY_TRANSFERRED_IN = '102', PREPAYMENT_PENALTY_TRANSFERRED_OUT = '103', FEE_TRANSFERRED_IN = '104', FEE_TRANSFERRED_OUT = '105', OVERDUE_FEE_TRANSFERRED_IN = '106', OVERDUE_FEE_TRANSFERRED_OUT = '107', OVERDUE_INTEREST_TRANSFERRED_OUT = '108', OVERDUE_INTEREST_TRANSFERRED_IN = '109', COLLATERAL_FOR_CLOSED_POSITION_TRANSFERRED_IN = '110', COLLATERAL_FOR_CLOSED_POSITION_TRANSFERRED_OUT = '111', COLLATERAL_FOR_LIQUIDATION_TRANSFERRED_IN = '112', COLLATERAL_FOR_LIQUIDATION_TRANSFERRED_OUT = '113', INSURANCE_FUND_TRANSFERRED_IN = '114', INSURANCE_FUND_TRANSFERRED_OUT_ = '115', PLACE_AN_ORDER = '116', FULFILL_AN_ORDER = '117', CANCEL_AN_ORDER = '118', MERCHANTS_UNLOCK_DEPOSIT = '119', MERCHANTS_ADD_DEPOSIT = '120', FIATGATEWAY_PLACE_AN_ORDER = '121', FIATGATEWAY_CANCEL_AN_ORDER = '122', FIATGATEWAY_FULFILL_AN_ORDER = '123', JUMPSTART_UNLOCKING = '124', MANUAL_DEPOSIT = '125', INTEREST_DEPOSIT = '126', INVESTMENT_FEE_TRANSFERRED_IN = '127', INVESTMENT_FEE_TRANSFERRED_OUT = '128', REWARDS_TRANSFERRED_IN = '129', TRANSFERRED_FROM_TRADING_ACCOUNT = '130', TRANSFERRED_TO_TRADING_ACCOUNT = '131', FROZEN_BY_CUSTOMER_SERVICE = '132', UNFROZEN_BY_CUSTOMER_SERVICE = '133', TRANSFERRED_BY_CUSTOMER_SERVICE = '134', CROSS_CHAIN_EXCHANGE = '135', CONVERT = '136', ETH_2_0_SUBSCRIPTION = '137', ETH_2_0_SWAPPING = '138', ETH_2_0_EARNINGS = '139', FEE_TRANSFER_IN = '141', FEE_TRANSFER_OUT = '142', SYSTEM_REVERSE = '143', TRANSFER_OUT_OF_UNIFIED_ACCOUNT_RESERVE = '144', REWARD_EXPIRED = '145', CUSTOMER_FEEDBACK = '146', VESTED_SUSHI_REWARDS = '147', AFFILIATE_COMMISSION = '150', REFERRAL_REWARD = '151', BROKER_REWARD = '152', JOINER_REWARD = '153', MYSTERY_BOX_REWARD = '154', REWARDS_WITHDRAW = '155', FEE_REBATE_1 = '156', COLLECTED_CRYPTO = '157', DUAL_INVESTMENT_SUBSCRIBE = '160', DUAL_INVESTMENT_COLLECTION = '161', DUAL_INVESTMENT_PROFIT = '162', DUAL_INVESTMENT_REFUND = '163', NEW_YEAR_REWARDS_2022 = '169', REFERRAL_REFERRED_CUSTOMER = '170', REFERRAL_WAS_REFERRED = '171', SUB_AFFILIATE_COMMISSION = '172', FEE_REBATE_2 = '173', PAY = '174', LOCKED_COLLATERAL = '175', LOAN = '176', ADDED_COLLATERAL = '177', RETURNED_COLLATERAL = '178', REPAYMENT = '179', UNLOCKED_COLLATERAL = '180', REPAY_AIRDROPPED_CRYPTO = '181', FEEDBACK_BOUNTY = '182', INVITE_FRIENDS_REWARDS = '183', DIVIDE_THE_REWARD_POOL = '184', BROKER_CONVERT_REWARD = '185', FREEETH = '186', CONVERT_TRANSFER = '187', SLOT_AUCTION_CONVERSION = '188', MYSTERY_BOX_BONUS = '189', CARD_PAYMENT_BUY_1 = '193', CARD_PAYMENT_BUY_2 = '194', UNTRADABLE_ASSET_WITHDRAWAL = '195', UNTRADABLE_ASSET_WITHDRAWAL_REVOKED = '196', UNTRADABLE_ASSET_DEPOSIT = '197', UNTRADABLE_ASSET_COLLECTION_1 = '198', UNTRADABLE_ASSET_COLLECTION_2 = '199', BUY = '200', WIN_CRYPTO_WITH_SATOSHI = '211', } ⋮---- export type AssetBillType = `${ASSET_BILL_TYPE}`; ================ File: src/types/rest/request/convert.ts ================ export interface ConvertQuoteEstimateRequest { baseCcy: string; quoteCcy: string; side: string; rfqSz: string; rfqSzCcy: string; clTReqId?: string; tag?: string; } export interface ConvertTradeRequest { quoteId: string; baseCcy: string; quoteCcy: string; side: string; sz: string; szCcy: string; clTReqId?: string; tag?: string; } ================ File: src/types/rest/request/copy-trading.ts ================ export interface GetCurrentSubpositionsRequest { instType?: 'SPOT' | 'SWAP'; instId?: string; uniqueCode?: string; subPosType?: 'lead' | 'copy'; after?: string; before?: string; limit?: string; } ⋮---- export interface GetSubpositionsHistoryRequest { instType?: 'SPOT' | 'SWAP'; instId?: string; subPosType?: 'lead' | 'copy'; after?: string; before?: string; limit?: string; } ⋮---- export interface PlaceCTAlgoOrderRequest { instType?: 'SPOT' | 'SWAP'; subPosId: string; tpTriggerPx?: string; slTriggerPx?: string; tpOrdPx?: string; slOrdPx?: string; tpTriggerPxType?: 'last' | 'index' | 'mark'; slTriggerPxType?: 'last' | 'index' | 'mark'; tag?: string; subPosType?: 'lead' | 'copy'; } ⋮---- export interface CloseSubpositionRequest { instType?: 'SPOT' | 'SWAP'; subPosType?: 'lead' | 'copy'; subPosId: string; ordType?: 'market' | 'limit'; px?: string; tag?: string; } ⋮---- export interface GetCTProfitDetailsRequest { instType?: 'SPOT' | 'SWAP'; after?: string; before?: string; limit?: string; } ⋮---- export interface CopySettingsRequest { instType?: 'SWAP'; uniqueCode: string; copyMgnMode: 'cross' | 'isolated' | 'copy'; copyInstIdType: 'custom' | 'copy'; instId?: string; copyMode?: 'fixed_amount' | 'ratio_copy'; copyTotalAmt: string; copyAmt?: string; copyRatio?: string; tpRatio?: string; slRatio?: string; slTotalAmt?: string; subPosCloseType: 'market_close' | 'copy_close' | 'manual_close'; } ⋮---- export interface GetCTBatchLeverageInfoRequest { mgnMode: 'cross' | 'isolated'; uniqueCode: string; instId?: string; } ⋮---- export interface SetCTBatchLeverageRequest { mgnMode: 'cross' | 'isolated'; lever: string; instId: string; } ⋮---- export interface GetCTHistoryLeadTradersRequest { instType?: 'SWAP'; after?: string; before?: string; limit?: string; } ⋮---- export interface GetLeadTraderRanksRequest { instType?: 'SWAP'; sortType?: | 'overview' | 'pnl' | 'aum' | 'win_ratio' | 'pnl_ratio' | 'current_copy_trader_pnl'; state?: '0' | '1'; minLeadDays?: '1' | '2' | '3' | '4'; minAssets?: string; maxAssets?: string; minAum?: string; maxAum?: string; dataVer?: string; page?: string; limit?: string; } ⋮---- export interface GetLeadTraderStatsRequest { instType?: 'SWAP'; uniqueCode: string; lastDays: '1' | '2' | '3' | '4'; } ⋮---- export interface GetLeadTraderPositionsRequest { instType?: 'SWAP'; uniqueCode: string; after?: string; before?: string; limit?: string; } ⋮---- export interface GetCopyTradersRequest { instType?: 'SWAP'; uniqueCode: string; limit?: string; } ⋮---- export interface GetPrivateLeadTraderRanksRequest { instType?: 'SWAP'; sortType?: | 'overview' | 'pnl' | 'aum' | 'win_ratio' | 'pnl_ratio' | 'current_copy_trader_pnl'; state?: '0' | '1'; minLeadDays?: '1' | '2' | '3' | '4'; minAssets?: string; maxAssets?: string; minAum?: string; maxAum?: string; dataVer?: string; page?: string; limit?: string; } ================ File: src/types/rest/request/grid-trading.ts ================ export type GridAlgoOrderType = 'grid' | 'contract_grid' | 'moon_grid'; ⋮---- export interface GetGridAlgoOrdersRequest { algoOrdType: GridAlgoOrderType; algoId?: string; instId?: string; instType?: 'SPOT' | 'MARGIN' | 'SWAP' | 'FUTURES'; after?: string; before?: string; limit?: string; } ⋮---- export interface GridAlgoTrigger { triggerAction: 'start' | 'stop'; triggerStrategy: 'instant' | 'price' | 'rsi'; delaySeconds?: string; timeframe?: '3m' | '5m' | '15m' | '30m' | '1H' | '4H' | '1D'; thold?: string; triggerCond?: 'cross_up' | 'cross_down' | 'above' | 'below' | 'cross'; timePeriod?: string; triggerPx?: string; stopType?: '1' | '2'; } ⋮---- export interface GridAlgoOrderRequest { instId: string; algoOrdType: GridAlgoOrderType; maxPx: string; minPx: string; gridNum: string; runType: '1' | '2'; quoteSz?: string; baseSz?: string; sz?: string; direction?: 'long' | 'short' | 'neutral'; lever?: string; basePos?: boolean; tpRatio?: string; slRatio?: string; triggerParams?: GridAlgoTrigger[]; } ⋮---- export interface StopGridAlgoOrderRequest { algoId: string; instId: string; algoOrdType: GridAlgoOrderType; stopType: '1' | '2'; } ⋮---- export interface CloseContractGridPositionRequest { algoId: string; mktClose: boolean; sz?: string; px?: string; } ⋮---- export interface GetRSIBackTestingRequest { instId: string; timeframe: '3m' | '5m' | '15m' | '30m' | '1H' | '4H' | '1D'; thold: string; timePeriod: string; triggerCond?: 'cross_up' | 'cross_down' | 'above' | 'below' | 'cross'; duration?: string; } ⋮---- export interface MaxGridQuantityRequest { instId: string; runType: '1' | '2'; algoOrdType: 'grid' | 'contract_grid'; maxPx: string; minPx: string; lever?: string; } ================ File: src/types/rest/request/public.ts ================ export interface EconomicCalendarRequest { region?: string; importance?: '1' | '2' | '3'; before?: string; after?: string; limit?: string; } ⋮---- export interface UnitConvertRequest { type?: '1' | '2'; instId: string; sz: string; px?: string; unit?: 'coin' | 'usds'; opType: 'open' | 'close'; } ⋮---- export interface CandleRequest { instId: string; after?: string; before?: string; bar?: string; limit?: string; } ⋮---- export interface GetPremiumHistoryRequest { instId: string; after?: string; before?: string; limit?: string; } ⋮---- export interface GetContractOpenInterestHistoryRequest { instId: string; period?: string; end?: string; begin?: string; limit?: string; } ⋮---- export interface GetContractTakerVolumeRequest { instId: string; period?: string; unit?: string; end?: string; begin?: string; limit?: string; } ⋮---- export interface GetTopTradersContractLongShortRatioRequest { instId: string; period?: string; end?: string; begin?: string; limit?: string; } ⋮---- export interface GetOptionTradesRequest { instId?: string; instFamily?: string; optType?: 'C' | 'P'; } ================ File: src/types/rest/request/recurring-buy.ts ================ export interface RecurringBuyInfo { ccy: string; ratio: string; } ⋮---- export interface PlaceRecurringBuyOrderRequest { stgyName: string; recurringList: RecurringBuyInfo[]; period: 'monthly' | 'weekly' | 'daily' | 'hourly'; recurringDay?: string; recurringHour?: string; recurringTime: string; timeZone: string; amt: string; investmentCcy: 'USDT' | 'USDC'; tdMode: 'cross' | 'cash'; algoClOrdId?: string; tag?: string; } ⋮---- export interface AmendRecurringBuyOrderRequest { algoId: string; stgyName: string; } ⋮---- export interface GetRecurringBuyOrderListRequest { algoId?: string; after?: string; before?: string; limit?: string; } ================ File: src/types/rest/request/signal-bot.ts ================ export interface CreateSignalRequest { signalChanName: string; signalChanDesc?: string; } ⋮---- export interface GetSignalsRequest { signalSourceType: string; signalChanId?: string; after?: string; before?: string; limit?: string; } ⋮---- export interface EntrySettingParam { allowMultipleEntry?: string; entryType?: string; amt?: string; ratio?: { ratio: string }[]; } ⋮---- export interface ExitSettingParam { tpSlType: string; tpPct?: string; slPct?: string; } ⋮---- export interface CreateSignalBotRequest { signalChanId: string; lever: string; investAmt: string; subOrdType: string; includeAll?: boolean; instIds?: string; ratio?: string; entrySettingParam?: EntrySettingParam; exitSettingParam?: ExitSettingParam; } ⋮---- export interface AdjustMarginBalanceRequest { algoId: string; type: 'add' | 'reduce'; amt: string; allowReinvest?: boolean; } ⋮---- export interface AmendTPSLRequest { algoId: string; exitSettingParam: ExitSettingParam; } ⋮---- export interface SetSignalInstrumentsRequest { algoId: string; instIds: string[]; includeAll: boolean; } ⋮---- export interface GetSignalBotRequest { algoOrdType: string; algoId: string; after: string; before?: string; limit?: string; } ⋮---- export interface GetSignalBotPositionHistoryRequest { algoId?: string; instId?: string; after?: string; before?: string; limit?: string; } ⋮---- export interface PlaceSubOrderRequest { instId: string; algoId: string; side: 'buy' | 'sell'; ordType: 'market' | 'limit'; sz: string; px?: string; reduceOnly?: boolean; } ⋮---- export interface CancelSubOrderRequest { algoId: string; instId: string; signalOrdId: string; } ⋮---- export interface GetSignalBotSubOrdersRequest { algoId: string; algoOrdType: 'contract'; type?: 'live' | 'filled'; clOrdId?: string; state?: 'live' | 'partially_filled' | 'filled' | 'cancelled'; signalOrdId?: string; after?: string; before?: string; begin?: string; end?: string; limit?: string; } ⋮---- export interface GetSignalBotEventHistoryRequest { algoId: string; after?: string; before?: string; limit?: string; } ================ File: src/types/rest/request/simple-earn.ts ================ export interface GetLendingOrderListRequest { ordId?: string; ccy?: string; term?: '30D'; state?: 'pending' | 'earning' | 'expired' | 'settled'; after?: string; before?: string; limit?: string; } ⋮---- export interface LendingOrder { ccy: string; amt: string; rate?: string; term: '30D'; autoRenewal?: boolean; } ⋮---- export interface GetLendingSubOrderListRequest { ordId: string; state?: 'earning' | 'expired' | 'settled'; after?: string; before?: string; limit?: string; } ================ File: src/types/rest/request/spread-trading.ts ================ export interface PlaceSpreadOrderRequest { sprdId: string; clOrdId?: string; tag?: string; side: 'buy' | 'sell'; ordType: 'limit' | 'post_only' | 'ioc' | 'market'; sz: string; px: string; } ⋮---- export interface UpdateSpreadOrderRequest { ordId?: string; clOrdId?: string; reqId?: string; newSz?: string; newPx?: string; } ⋮---- export interface GetActiveSpreadOrdersRequest { sprdId?: string; ordType?: 'limit' | 'post_only' | 'ioc' | 'market'; state?: 'live' | 'partially_filled'; beginId?: string; endId?: string; limit?: string; } ⋮---- export interface GetSpreadOrderHistoryRequest { sprdId?: string; ordType?: 'limit' | 'post_only' | 'ioc' | 'market'; state?: 'canceled' | 'filled'; beginId?: string; endId?: string; begin?: string; end?: string; limit?: string; } ⋮---- export interface GetSpreadOrderHistoryArchiveRequest { sprdId?: string; ordType?: 'limit' | 'post_only' | 'ioc' | 'market'; state?: 'canceled' | 'filled'; instType?: 'SPOT' | 'FUTURES' | 'SWAP'; instFamily?: string; beginId?: string; endId?: string; begin?: string; end?: string; limit?: string; } ⋮---- export interface GetSpreadTradesRequest { sprdId?: string; tradeId?: string; ordId?: string; beginId?: string; endId?: string; begin?: string; end?: string; limit?: string; } ⋮---- export interface GetSpreadsRequest { baseCcy?: string; instId?: string; sprdId?: string; state?: 'live' | 'suspend' | 'expired'; } ⋮---- export interface GetSpreadCandlesRequest { sprdId: string; bar?: string; after?: string; before?: string; limit?: string; } ================ File: src/types/rest/request/subaccount.ts ================ type AccountType = '6' | '18'; ⋮---- export interface SubAccountTransferRequest { ccy: string; amt: string; from: AccountType; to: AccountType; fromSubAccount: string; toSubAccount: string; loanTrans?: boolean; omitPosRisk?: boolean; } ⋮---- export interface GetSubAccountMaxWithdrawalsRequest { subAcct: string; ccy?: string; } ⋮---- export interface GetManagedSubAccountTransferHistoryRequest { ccy?: string; type?: '0' | '1'; subAcct?: string; subUid?: string; after?: string; before?: string; limit?: string; } ⋮---- export interface LoanAllocation { subAcct: string; loanAlloc: string; } ⋮---- export interface SetSubAccountLoanAllocationRequest { enable: boolean; alloc?: LoanAllocation[]; } ================ File: src/types/rest/response/private-copy-trading.ts ================ export interface CurrentSubposition { algoId: string; ccy: string; instId: string; instType: string; lever: string; margin: string; markPx: string; mgnMode: string; openAvgPx: string; openOrdId: string; openTime: string; posSide: string; slOrdPx: string; slTriggerPx: string; subPos: string; subPosId: string; tpOrdPx: string; tpTriggerPx: string; uniqueCode: string; upl: string; uplRatio: string; availSubPos: string; } ⋮---- export interface SubpositionsHistory { ccy: string; closeAvgPx: string; closeTime: string; instId: string; instType: string; lever: string; margin: string; markPx: string; mgnMode: string; openAvgPx: string; openOrdId: string; openTime: string; pnl: string; pnlRatio: string; posSide: string; profitSharingAmt: string; subPos: string; closeSubPos: string; type: string; subPosId: string; uniqueCode: string; } ⋮---- export interface PlaceCTAlgoOrderResult { subPosId: string; tag: string; } ⋮---- export interface GetCTProfitDetailsResult { ccy: string; nickName: string; profitSharingAmt: string; profitSharingId: string; portLink: string; ts: string; instType: string; } ⋮---- export interface GetCTTotalProfitResult { ccy: string; totalProfitSharingAmt: string; instType: string; } ⋮---- export interface GetCTUnrealizedProfitResult { ccy: string; nickName: string; portLink: string; ts: string; unrealizedProfitSharingAmt: string; instType: string; } ⋮---- export interface AccountConfigurationDetails { copyTraderNum: string; instType: 'SPOT' | 'SWAP'; maxCopyTraderNum: string; profitSharingRatio: string; roleType: '0' | '1' | '2'; } ⋮---- export interface GetAccountConfigurationResult { uniqueCode: string; nickName: string; portLink: string; details: AccountConfigurationDetails[]; } ⋮---- export interface CopySettingsInstId { instId: string; enabled: string; } ⋮---- export interface GetCopySettingsResult { ccy: string; copyAmt: string; copyInstIdType: 'custom' | 'copy'; copyMgnMode: 'cross' | 'isolated' | 'copy'; copyMode: 'fixed_amount' | 'ratio_copy'; copyRatio: string; copyState: '0' | '1'; copyTotalAmt: string; instIds: CopySettingsInstId[]; slRatio: string; slTotalAmt: string; subPosCloseType: 'market_close' | 'copy_close' | 'manual_close'; tpRatio: string; } ⋮---- export interface LeverageInfo { lever: string; posSide: 'long' | 'short'; } ⋮---- export interface GetCTBatchLeverageInfoResult { instId: string; mgnMode: 'cross' | 'isolated'; leadTraderLevers: LeverageInfo[]; myLevers: LeverageInfo[]; } ⋮---- export interface SetCTBatchLeverageResult { succInstId: string; failInstId: string; result: '0' | '1' | '2'; } ⋮---- export interface GetCTMyLeadTradersResult { portLink: string; nickName: string; margin: string; copyTotalAmt: string; copyTotalPnl: string; uniqueCode: string; ccy: string; profitSharingRatio: string; beginCopyTime: string; upl: string; todayPnl: string; leadMode: 'public' | 'private'; } ⋮---- export interface GetCTHistoryLeadTradersResult { portLink: string; nickName: string; uniqueCode: string; copyNum: string; copyTotalAmt: string; copyTotalPnl: string; copyAmt: string; copyMode: 'fixed_amount' | 'ratio_copy'; copyRatio: string; ccy: string; profitSharingRatio: string; beginCopyTime: string; endCopyTime: string; copyRelId: string; copyState: '0' | '1'; leadMode: 'public' | 'private'; } ⋮---- export interface GetCopyTradingConfigResult { maxCopyAmt: string; minCopyAmt: string; maxCopyTotalAmt: string; minCopyRatio: string; maxCopyRatio: string; maxTpRatio: string; maxSlRatio: string; } ⋮---- export interface PnlRatio { beginTs: string; pnlRatio: string; } ⋮---- export interface LeadTraderRank { accCopyTraderNum: string; aum: string; ccy: string; copyState: '0' | '1'; copyTraderNum: string; leadDays: string; maxCopyTraderNum: string; nickName: string; pnl: string; pnlRatio: string; pnlRatios: PnlRatio[]; portLink: string; traderInsts: string[]; uniqueCode: string; winRatio: string; } ⋮---- export interface GetLeadTraderRanksResult { dataVer: string; ranks: LeadTraderRank[]; totalPage: string; } ⋮---- export interface LeadTraderPnl { beginTs: string; pnl: string; pnlRatio: string; } ⋮---- export interface LeadTraderStats { avgSubPosNotional: string; ccy: string; curCopyTraderPnl: string; investAmt: string; lossDays: string; profitDays: string; winRatio: string; } ⋮---- export interface LeadTraderPreference { ccy: string; ratio: string; } ⋮---- export interface LeadTraderCurrentPosition { ccy: string; instId: string; instType: string; lever: string; margin: string; markPx: string; mgnMode: string; openAvgPx: string; openTime: string; posSide: string; subPos: string; subPosId: string; uniqueCode: string; upl: string; uplRatio: string; } ⋮---- export interface LeadTraderPositionHistory { ccy: string; closeAvgPx: string; closeTime: string; instId: string; instType: string; lever: string; margin: string; mgnMode: string; openAvgPx: string; openTime: string; pnl: string; pnlRatio: string; posSide: string; subPos: string; subPosId: string; uniqueCode: string; } ⋮---- export interface CopyTraderInfo { beginCopyTime: string; nickName: string; portLink: string; pnl: string; } ⋮---- export interface GetCopyTradersResult { copyTotalPnl: string; ccy: string; copyTraderNumChg: string; copyTraderNumChgRatio: string; copyTraders: CopyTraderInfo[]; } ⋮---- export interface GetPrivateLeadTraderRanksResult { dataVer: string; chanType: 'OKX' | 'ND'; ranks: LeadTraderRank[]; totalPage: string; } ================ File: src/types/rest/response/private-flexible-loan.ts ================ export interface CollateralAsset { ccy: string; amt: string; notionalUsd: string; } ⋮---- export interface CollateralAssetsResponse { assets: CollateralAsset[]; } ⋮---- export interface SupplementaryCollateral { ccy: string; amt: string; } ⋮---- export interface MaxLoanRequest { borrowCcy: string; supCollateral?: SupplementaryCollateral[]; } ⋮---- export interface MaxLoanResponse { borrowCcy: string; maxLoan: string; notionalUsd: string; remainingQuota: string; } ⋮---- export interface AdjustCollateralRequest { type: 'add' | 'reduce'; collateralCcy: string; collateralAmt: string; } ⋮---- export interface LoanCurrencyData { ccy: string; amt: string; } ⋮---- export interface RiskWarningData { instId: string; liqPx: string; } ⋮---- export interface LoanInfo { loanNotionalUsd: string; loanData: LoanCurrencyData[]; collateralNotionalUsd: string; collateralData: LoanCurrencyData[]; riskWarningData: RiskWarningData; curLTV: string; marginCallLTV: string; liqLTV: string; } ⋮---- export interface LoanHistoryRequest { type?: | 'borrowed' | 'repaid' | 'collateral_locked' | 'collateral_released' | 'forced_repayment_buy' | 'forced_repayment_sell' | 'forced_liquidation' | 'partial_liquidation'; after?: string; before?: string; limit?: string; } ⋮---- export interface LoanHistoryItem { refId: string; type: string; ccy: string; amt: string; ts: string; } ⋮---- export interface AccruedInterestRequest { ccy?: string; after?: string; before?: string; limit?: string; } ⋮---- export interface AccruedInterestItem { refId: string; ccy: string; loan: string; interest: string; interestRate: string; ts: string; } ================ File: src/types/rest/response/private-recurring-buy.ts ================ export interface RecurringBuyOrderResult { algoId: string; algoClOrdId: string; sCode: string; sMsg: string; } ⋮---- export interface RecurringBuyInfoResult { ccy: string; ratio: string; } ⋮---- export interface RecurringBuyOrder { algoId: string; algoClOrdId: string; instType: string; cTime: string; uTime: string; algoOrdType: 'recurring'; state: 'running' | 'stopping' | 'pause'; stgyName: string; recurringList: RecurringBuyInfoResult[]; period: 'monthly' | 'weekly' | 'daily' | 'hourly'; recurringDay?: string; recurringHour?: string; recurringTime: string; timeZone: string; amt: string; investmentAmt: string; investmentCcy: 'USDT' | 'USDC'; totalPnl: string; totalAnnRate: string; pnlRatio: string; mktCap: string; cycles: string; tag: string; } ⋮---- export interface RecurringBuyInfoOrder { ccy: string; ratio: string; totalAmt: string; profit: string; avgPx: string; px: string; } ⋮---- export interface RecurringBuySubOrder { algoId: string; instType: string; instId: string; algoOrdType: 'recurring'; ordId: string; cTime: string; uTime: string; tdMode: 'cross' | 'cash'; ordType: 'market'; sz: string; state: 'canceled' | 'live' | 'partially_filled' | 'filled' | 'cancelling'; side: 'buy' | 'sell'; px: string; fee: string; feeCcy: string; avgPx: string; accFillSz: string; tag: string; } ================ File: src/types/rest/response/private-signal-bot.ts ================ export interface CreateSignalResult { signalChanId: string; signalToken: string; } ⋮---- export interface GetSignalsResult { signalChanId: string; signalChanName: string; signalChanDesc: string; signalChanToken: string; signalSourceType: string; } ⋮---- export interface CreateSignalBotResult { algoId: string; algoClOrdId: string; sCode: string; sMsg: string; } ⋮---- export interface CancelSignalBotsResult { algoId: string; sCode: string; sMsg: string; } ================ File: src/types/rest/response/private-spread-trading.ts ================ export interface PlaceSpreadOrderResponse { ordId: string; clOrdId: string; tag: string; sCode: string; sMsg: string; } ⋮---- export interface CancelSpreadOrderResponse { ordId: string; clOrdId: string; sCode: string; sMsg: string; } ⋮---- export interface UpdateSpreadOrderResponse { ordId: string; clOrdId: string; reqId: string; sCode: string; sMsg: string; } ⋮---- export interface SpreadOrder { instId: string; ordId: string; clOrdId: string; tag: string; px: string; sz: string; ordType: 'limit' | 'post_only' | 'ioc'; side: 'buy' | 'sell'; fillSz: string; fillPx: string; tradeId: string; accFillSz: string; pendingFillSz: string; pendingSettleSz: string; canceledSz: string; avgPx: string; state: 'canceled' | 'live' | 'partially_filled' | 'filled'; cancelSource: string; uTime: string; cTime: string; } ⋮---- export interface SpreadTradeLeg { instId: string; px: string; sz: string; side: 'buy' | 'sell'; fee: string; szCont: string; feeCcy: string; tradeId: string; } ⋮---- export interface SpreadTrade { sprdId: string; tradeId: string; ordId: string; clOrdId: string; tag: string; fillPx: string; fillSz: string; side: 'buy' | 'sell'; state: 'filled' | 'rejected'; execType: 'T' | 'M'; ts: string; legs: SpreadTradeLeg[]; } ⋮---- export interface SpreadLeg { instId: string; side: 'buy' | 'sell'; } ⋮---- export interface SpreadDetails { sprdId: string; sprdType: 'linear' | 'inverse' | 'hybrid'; state: 'live' | 'expired' | 'suspend'; baseCcy: string; szCcy: string; quoteCcy: string; tickSz: string; minSz: string; lotSz: string; listTime: string; expTime: string; uTime: string; legs: SpreadLeg[]; } ⋮---- export interface OrderBookEntry { price: string; quantity: string; orderCount: string; } ⋮---- export interface SpreadOrderBook { asks: OrderBookEntry[]; bids: OrderBookEntry[]; ts: string; } ⋮---- export interface SpreadTicker { sprdId: string; last: string; lastSz: string; askPx: string; askSz: string; bidPx: string; bidSz: string; open24h: string; high24h: string; low24h: string; vol24h: string; ts: string; } ⋮---- export interface PublicSpreadTrade { sprdId: string; tradeId: string; px: string; sz: string; side: 'buy' | 'sell'; ts: string; } ⋮---- export interface SpreadCandle { ts: string; o: string; h: string; l: string; c: string; vol: string; confirm: string; } ================ File: src/types/rest/response/private-subaccount.ts ================ export interface SubAccount { enable: boolean; subAcct: string; type: string; label: string; mobile: string; gAuth: boolean; canTransOut: boolean; ts: string; } ⋮---- export interface SubAccountAPIReset { subAcct: string; label: string; apiKey: string; perm: string; ip: string; ts: string; } ⋮---- export interface SubAccountBalanceDetail { availBal: string; availEq: string; cashBal: string; ccy: string; crossLiab: string; disEq: string; eq: string; eqUsd: string; frozenBal: string; interest: string; isoEq: string; isoLiab: string; liab: string; maxLoan: string; mgnRatio: string; notionalLever: string; ordFrozen: string; twap: string; uTime: string; upl: string; uplLiab: string; spotBal: string; // Spot balance. The unit is currency, e.g. BTC. openAvgPx: string[]; // Spot average cost price. The unit is USD. accAvgPx: string[]; // Spot accumulated cost price. The unit is USD. spotUpl: string; // Spot unrealized profit and loss. The unit is USD. spotUplRatio: string; // Spot unrealized profit and loss ratio. totalPnl: string; // Spot accumulated profit and loss. The unit is USD. totalPnlRatio: string; // Spot accumulated profit and loss ratio. } ⋮---- spotBal: string; // Spot balance. The unit is currency, e.g. BTC. openAvgPx: string[]; // Spot average cost price. The unit is USD. accAvgPx: string[]; // Spot accumulated cost price. The unit is USD. spotUpl: string; // Spot unrealized profit and loss. The unit is USD. spotUplRatio: string; // Spot unrealized profit and loss ratio. totalPnl: string; // Spot accumulated profit and loss. The unit is USD. totalPnlRatio: string; // Spot accumulated profit and loss ratio. ⋮---- export interface SubAccountBalances { adjEq: string; details: SubAccountBalanceDetail[]; imr: string; isoEq: string; mgnRatio: string; mmr: string; notionalUsd: string; ordFroz: string; totalEq: string; uTime: string; spotCopyTradingEq: string; } ⋮---- export interface SubAccountTransferResult { transId: string; } ⋮---- export interface SubAccountMaxWithdrawal { ccy: string; maxWd: string; maxWdEx: string; spotOffsetMaxWd: string; spotOffsetMaxWdEx: string; } ⋮---- export interface ManagedSubAccountTransfer { billId: string; ccy: string; amt: string; type: string; subAcct: string; subUid: string; ts: string; } ================ File: webpack/webpack.config.js ================ function generateConfig(name) ⋮---- // Add '.ts' and '.tsx' as resolvable extensions. ⋮---- // All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'. ⋮---- // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'. ================ File: .jshintrc ================ { "esversion": 8, "asi": true, "laxbreak": true, "predef": [ "-Promise" ] } ================ File: .nvmrc ================ v22.17.1 ================ File: LICENSE.md ================ Copyright 2022 Tiago Siebler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================ File: examples/auth/fasterHmacSign.ts ================ import { createHmac } from 'crypto'; ⋮---- import { DefaultLogger, RestClient, WebsocketClient } from '../../src/'; ⋮---- // or // import { createHmac } from 'crypto'; // import { DefaultLogger, RestClient, WebsocketClient } from 'okx-api'; ⋮---- /** * Injecting a custom signMessage function. * * As of version 3.0.0 of the okx-api Node.js/TypeScript/JavaScript * SDK for OKX, the SDK uses the Web Crypto API for signing requests. * While it is compatible with Node and Browser environments, it is * slightly slower than using Node's native crypto module (only * available in backend Node environments). * * For latency sensitive users, you can inject the previous node crypto sign * method (or your own even faster implementation), if this change affects you. * * This example demonstrates how to inject a custom sign function, to achieve * the same peformance as seen before the Web Crypto API was introduced. * * For context on standard usage, the "signMessage" function is used: * - During every single API call * - After opening a new private WebSocket connection */ ⋮---- // If running from CLI in unix, you can pass env vars as such: // API_KEY_COM='lkm12n3-2ba3-1mxf-fn13-lkm12n3a' API_SECRET_COM='035B2B9637E1BDFFEE2646BFBDDB8CE4' API_PASSPHRASE_COM='ComplexPa$$!23$5^' ts-node examples/rest-private-trade.ts ⋮---- // note the single quotes, preventing special characters such as $ from being incorrectly passed ⋮---- // apiKey: 'apiKeyHere', ⋮---- // apiSecret: 'apiSecretHere', ⋮---- // apiPass: 'apiPassHere', /** * Overkill in almost every case, but if you need any optimisation available, * you can inject a faster sign mechanism such as node's native createHmac: */ ⋮---- // Optional, uncomment the "trace" override to log a lot more info about what the WS client is doing ⋮---- // trace: (...params) => console.log('trace', ...params), ⋮---- // For private topics, include one or more accounts in an array. Otherwise only public topics will work ⋮---- /** * Overkill in almost every case, but if you need any optimisation available, * you can inject a faster sign mechanism such as node's native createHmac: */ ⋮---- function setWsClientEventListeners( websocketClient: WebsocketClient, accountRef: string, ): Promise ⋮---- // console.log('raw message received ', JSON.stringify(data, null, 2)); ⋮---- // Simple promise to ensure we're subscribed before trying anything else ⋮---- // Start trading ================ File: examples/demo-trading.ts ================ import { RestClient, WebsocketClient } from '../src/index'; ⋮---- // or // import { RestClient} from 'okx-api'; ⋮---- // read from environmental variables, your demo trading keys ⋮---- // okx api credentials ⋮---- // Raw data will arrive on the 'update' event ⋮---- // console.log('ws update (raw data received)', JSON.stringify(data, null, 2)); ⋮---- // Replies (e.g. authenticating or subscribing to channels) will arrive on the 'response' event ⋮---- // console.log('ws response: ', JSON.stringify(data, null, 2)); ⋮---- // Subscribe to demo account events: ⋮---- /** Simple examples for private REST API calls with bybit's V5 REST APIs */ ⋮---- // Trade USDT linear perps ================ File: examples/rest-private-trade.ts ================ /* eslint-disable @typescript-eslint/no-unused-vars */ import { RestClient } from '../src/index.js'; import { OrderRequest } from '../src/types/rest/request/trade.js'; ⋮---- // or // import { SpotClient } from 'okx-api'; ⋮---- // read from environmental variables ⋮---- // If running from CLI in unix, you can pass env vars as such: // API_KEY_COM='lkm12n3-2ba3-1mxf-fn13-lkm12n3a' API_SECRET_COM='035B2B9637E1BDFFEE2646BFBDDB8CE4' API_PASSPHRASE_COM='ComplexPa$$!23$5^' ts-node examples/rest-private-trade.ts ⋮---- // note the single quotes, preventing special characters such as $ from being incorrectly passed ⋮---- // apiKey: 'apiKeyHere', ⋮---- // apiSecret: 'apiSecretHere', ⋮---- // apiPass: 'apiPassHere', ⋮---- // const wsClient = new WebsocketClient({ // apiKey: API_KEY, // apiSecret: API_SECRET, // apiPass: API_PASS, // }); ⋮---- function logWSEvent(type, data) ⋮---- // simple sleep function function promiseSleep(milliseconds) ⋮---- // WARNING: for sensitive math you should be using a library such as decimal.js! function roundDown(value, decimals) ⋮---- /** This is a simple script wrapped in a immediately invoked function expression, designed to check for any available BTC balance and immediately sell the full amount for USDT */ ⋮---- // // Add event listeners to log websocket events on account // wsClient.on('update', (data) => logWSEvent('update', data)); // wsClient.on('open', (data) => logWSEvent('open', data)); // wsClient.on('response', (data) => logWSEvent('response', data)); // wsClient.on('reconnect', (data) => logWSEvent('reconnect', data)); // wsClient.on('reconnected', (data) => logWSEvent('reconnected', data)); // wsClient.on('authenticated', (data) => logWSEvent('authenticated', data)); // wsClient.on('exception', (data) => logWSEvent('exception', data)); ⋮---- // // Subscribe to private account topics // wsClient.subscribeTopic('SPBL', 'account'); // wsClient.subscribeTopic('SPBL', 'orders'); ⋮---- // wait briefly for ws to be ready (could also use the response or authenticated events, to make sure topics are subscribed to before starting) ⋮---- // const balances = allBalances.filter((bal) => Number(bal.available) != 0); ⋮---- // console.log('balance: ', JSON.stringify(balances, null, 2)); ⋮---- // example to find minimum allowed size for a symbol and place an order with it /* const symbol = 'BTC-USDT-SWAP'; const symbolsResult = await client.getInstruments({ instType: 'SWAP', }); const btcRules = symbolsResult.find((rule) => rule.instId === symbol); console.log('btc trading rules: ', btcRules); if (!btcRules) { return console.log('no rules found for trading ' + symbol); } const minSize = Number(btcRules.minSz); const order = { instId: symbol, tdMode: 'cross', ordType: 'market', side: 'sell', sz: String(minSize), } as const; console.log('submitting order: ', order); const sellResult = await client.submitOrder(order); console.log('sell result: ', sellResult); */ ================ File: examples/ws-api-client.ts ================ import { DefaultLogger, WebsocketAPIClient } from '../src'; ⋮---- // or use the module installed via `npm install okx-api`: // import { WebsocketClient, DefaultLogger } from 'okx-api'; ⋮---- // or if you're not using typescript (e.g. pure nodejs), change the "import" to "require": // const { WebsocketClient, DefaultLogger } = require('okx-api'); ⋮---- // function attachEventHandlers( // wsClient: TWSClient, // ): void { // wsClient.on('update', (data) => { // console.log('raw message received ', JSON.stringify(data)); // }); // wsClient.on('open', (data) => { // console.log('ws connected', data.wsKey); // }); // wsClient.on('reconnect', ({ wsKey }) => { // console.log('ws automatically reconnecting.... ', wsKey); // }); // wsClient.on('reconnected', (data) => { // console.log('ws has reconnected ', data?.wsKey); // }); // wsClient.on('authenticated', (data) => { // console.log('ws has authenticated ', data?.wsKey); // }); // } ⋮---- // For private events, all 3 of the following are required (per account): ⋮---- // If running from CLI in unix, you can pass env vars as such: // API_KEY_COM='lkm12n3-2ba3-1mxf-fn13-lkm12n3a' API_SECRET_COM='035B2B9637E1BDFFEE2646BFBDDB8CE4' API_PASSPHRASE_COM='ComplexPa$$!23$5^' ts-node examples/ws-private.ts ⋮---- // For Global users (www.okx.com), you don't need to set the market. // It will use global by default. // Not needed: market: 'GLOBAL', ⋮---- // For EEA users (my.okx.com), set market to "EEA": // market: 'EEA', ⋮---- // For US users (app.okx.com), set market to "US": // market: 'US', ⋮---- // For private topics, include one or more accounts in an array. Otherwise only public topics will work ⋮---- // Optional, see above "attachEventListeners". Attach basic event handlers, so nothing is left unhandled // attachEventHandlers(wsClient.getWSClient()); ⋮---- // Optional: prepare the WebSocket API connection in advance. // This happens automatically but you can do this early before making any API calls, to prevent delays from a cold start. // await wsClient.connectWSAPI(); ⋮---- /** * OKX's WebSocket API be used like a REST API, through this SDK's WebsocketAPIClient. The WebsocketAPIClient is a utility class wrapped around WebsocketClient's sendWSAPIRequest() capabilities. * * Each request sent via the WebsocketAPIClient will automatically: * - route via the active WS API connection * - return a Promise, which automatically resolves/rejects when a matching response is received */ ⋮---- /** * Place Order * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order */ ⋮---- /** const res = { id: '2', op: 'order', code: '1', msg: '', data: [ { tag: '159881cb7207BCDE', ts: '1753714603721', ordId: '', clOrdId: '', sCode: '51008', sMsg: 'Order failed. Insufficient USDT balance in account.' } ], inTime: '1753714603720755', outTime: '1753714603721942', wsKey: 'prodPrivate', isWSAPIResponse: false } const res = { id: '2', op: 'order', code: '1', msg: '', data: [ { tag: '159881cb7207BCDE', ts: '1753714567149', ordId: '', clOrdId: '', sCode: '51010', sMsg: "You can't complete this request under your current account mode." } ], inTime: '1753714567149196', outTime: '1753714567149913', wsKey: 'prodPrivate', isWSAPIResponse: false } */ ⋮---- /** * Submit multiple orders in a batch * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-multiple-orders */ ================ File: examples/ws-api-trade-raw.ts ================ // If you cloned the repo and are using typescript, you can import from src directly: import { DefaultLogger, WebsocketClient, WS_KEY_MAP } from '../src'; ⋮---- // or use the module installed via `npm install okx-api`: // import { WebsocketClient, DefaultLogger } from 'okx-api'; ⋮---- // or if you're not using typescript (e.g. pure nodejs), change the "import" to "require": // const { WebsocketClient, DefaultLogger } = require('okx-api'); ⋮---- // For private events, all 3 of the following are required (per account): ⋮---- // If running from CLI in unix, you can pass env vars as such: // API_KEY_COM='lkm12n3-2ba3-1mxf-fn13-lkm12n3a' API_SECRET_COM='035B2B9637E1BDFFEE2646BFBDDB8CE4' API_PASSPHRASE_COM='ComplexPa$$!23$5^' ts-node examples/ws-private.ts ⋮---- // For private topics, include one or more accounts in an array. Otherwise only public topics will work ⋮---- // console.log('WS raw message received ', JSON.stringify(data, null, 2)); ⋮---- // prodPrivate is for the www.okx.com /ws/v5/private channel ⋮---- // prodBusiness is for the www.okx.com /ws/v5/business channel // const OKX_GLOBAL_BUSINESS_CHANNEL = WS_KEY_MAP.prodBusiness; ⋮---- /** * OKX's WebSocket API can be used via the sendWSAPIRequest() method. * * The correct WS Key depends on where you registered (www.okx.com vs app.okx.com vs my.okx.com), and whether you are using book trading (uses private connection) or spread trading (uses business connection) functionality. * * Note: for a better user experience, it is recommended to use the WebsocketAPIClient. */ ⋮---- /** * Place Order * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order */ ⋮---- /** const res = { id: '2', op: 'order', code: '1', msg: '', data: [ { tag: '159881cb7207BCDE', ts: '1753714603721', ordId: '', clOrdId: '', sCode: '51008', sMsg: 'Order failed. Insufficient USDT balance in account.' } ], inTime: '1753714603720755', outTime: '1753714603721942', wsKey: 'prodPrivate', isWSAPIResponse: false } const res = { id: '2', op: 'order', code: '1', msg: '', data: [ { tag: '159881cb7207BCDE', ts: '1753714567149', ordId: '', clOrdId: '', sCode: '51010', sMsg: "You can't complete this request under your current account mode." } ], inTime: '1753714567149196', outTime: '1753714567149913', wsKey: 'prodPrivate', isWSAPIResponse: false } */ ⋮---- /** * Cancel Order * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-order */ ⋮---- /** const res = { id: '2', op: 'cancel-order', code: '1', msg: '', data: [ { ts: '1753714393003', ordId: '2510789768709120', clOrdId: '', sCode: '51400', sMsg: 'Order cancellation failed as the order has been filled, canceled or does not exist.' } ], inTime: '1753714393003190', outTime: '1753714393004074', wsKey: 'prodPrivate', isWSAPIResponse: false } */ ================ File: examples/ws-private-handle-auth-fail.ts ================ // If you cloned the repo and are using typescript, you can import from src directly: import { WebsocketClient } from '../src'; ⋮---- /** * * This simple example demonstrates one way to handle failed authentication, stopping the * websocket client from running into a reconnect-loop when authentication fails (e.g. bad API keys). * * However, keep in mind it might be safer to make a test REST API call (e.g. fetch account balance) before * trying to make a private WS connection to the account. * */ ⋮---- // For private topics, include one or more accounts in an array. Otherwise only public topics will work ⋮---- // Raw data will arrive on the 'update' event ⋮---- // console.log('ws update (raw data received)', JSON.stringify(data, null, 2)); ⋮---- // Replies (e.g. authenticating or subscribing to channels) will arrive on the 'response' event ⋮---- // console.log('ws response: ', JSON.stringify(data, null, 2)); ⋮---- // Optional, connect before subscribing: ⋮---- // This is optional though. The wsclient will automatically open and subscribe if the connection doesn't exist yet. ⋮---- // Subscribe one event at a time: ================ File: src/types/rest/request/shared.ts ================ import { numberInString } from '../shared.js'; ⋮---- export interface PaginatedSymbolRequest { ccy?: string; after?: numberInString; before?: numberInString; limit?: numberInString; } ================ File: src/types/rest/response/private-trade.ts ================ import { AlgoOrderState, AlgoOrderType, AlgoPositionSide, numberInString, OrderState, OrderType, PositionSide, } from '../shared.js'; ⋮---- export interface OrderResult { clOrdId: string; ordId: string; tag: string; ts: string; sCode: numberInString; sMsg: string; } ⋮---- export interface CancelledOrderResult { clOrdId: string; ordId: string; sCode: string; sMsg: string; } ⋮---- export interface AmendedOrder { clOrdId: string; ordId: string; reqId: string; sCode: string; sMsg: string; } export interface ClosedPositions { instId: string; posSide: PositionSide; } ⋮---- export interface OrderDetails { instType: string; instId: string; ccy: string; ordId: string; clOrdId: string; tag: string; px: string; sz: string; pnl: string; ordType: OrderType; side: string; posSide: PositionSide; tdMode: string; accFillSz: string; fillPx: string; tradeId: string; fillSz: string; fillTime: string; state: OrderState; avgPx: string; lever: string; tpTriggerPx: string; tpTriggerPxType: string; tpOrdPx: string; slTriggerPx: string; slTriggerPxType: string; slOrdPx: string; feeCcy: string; fee: string; rebateCcy: string; rebate: string; tgtCcy: string; category: string; uTime: string; cTime: string; } ⋮---- export interface OrderListItem { accFillSz: string; avgPx: string; cTime: string; category: string; ccy: string; clOrdId: string; fee: string; feeCcy: string; fillPx: string; fillSz: string; fillTime: string; instId: string; instType: string; lever: string; ordId: string; ordType: OrderType; pnl: string; posSide: PositionSide; px: string; pxUsd: string; pxVol: string; pxType: string; rebate: string; rebateCcy: string; side: string; attachAlgoClOrdId: string; slOrdPx: string; slTriggerPx: string; slTriggerPxType: string; attachAlgoOrds: any[]; state: OrderState; stpId: string; stpMode: string; sz: string; tag: string; tgtCcy: string; tdMode: string; source: string; tpOrdPx: string; tpTriggerPx: string; tpTriggerPxType: string; tradeId: string; reduceOnly: string; quickMgnType: string; algoClOrdId: string; algoId: string; uTime: string; } ⋮---- export interface HistoricOrder { instType: string; instId: string; ccy: string; ordId: string; clOrdId: string; tag: string; px: string; pxUsd: string; pxVol: string; pxType: string; sz: string; ordType: OrderType; side: string; posSide: PositionSide; tdMode: string; accFillSz: string; fillPx: string; tradeId: string; fillSz: string; fillTime: string; state: OrderState; avgPx: string; lever: string; attachAlgoClOrdId: string; tpTriggerPx: string; tpTriggerPxType: string; tpOrdPx: string; slTriggerPx: string; slTriggerPxType: string; slOrdPx: string; attachAlgoOrds: any[]; stpId: string; stpMode: string; feeCcy: string; fee: string; rebateCcy: string; source: string; rebate: string; tgtCcy: string; pnl: string; category: string; reduceOnly: string; cancelSource: string; cancelSourceReason: string; algoClOrdId: string; algoId: string; uTime: string; cTime: string; } ⋮---- export interface OrderFill { instType: string; instId: string; tradeId: string; ordId: string; clOrdId: string; billId: string; tag: string; fillPx: string; fillSz: string; side: string; posSide: PositionSide; execType: string; feeCcy: string; fee: string; ts: string; } ⋮---- export interface AlgoOrderResult { algoId: string; algoClOrdId: string; sCode: string; sMsg: string; } ⋮---- export interface AmendAlgoOrderResult extends AlgoOrderResult { reqId: string; } ⋮---- export interface AlgoOrderDetailsResult { instType: string; instId: string; ordId: string; ordIdList: string[]; ccy: string; clOrdId: string; algoId: string; attachAlgoOrds: any[]; sz: string; closeFraction: string; ordType: AlgoOrderType; side: string; posSide: AlgoPositionSide; tdMode: string; tgtCcy: string; state: AlgoOrderState; lever: string; tpTriggerPx: string; tpTriggerPxType: string; tpOrdPx: string; slTriggerPx: string; slTriggerPxType: string; slOrdPx: string; triggerPx: string; triggerPxType: string; ordPx: string; actualSz: string; actualPx: string; actualSide: string; pxVar: string; pxSpread: string; pxLimit: string; szLimit: string; tag: string; timeInterval: string; callbackRatio: string; callbackSpread: string; activePx: string; moveTriggerPx: string; reduceOnly: string; triggerTime: string; quickMgnType: string; last: string; failCode: string; algoClOrdId: string; amendPxOnTriggerType: string; cTime: string; isTradeBorrowMode: boolean; chaseType?: string; chaseVal?: string; maxChaseType?: string; maxChaseVal?: string; } ⋮---- export interface AlgoOrderListItem { activePx: string; actualPx: string; actualSide: string; actualSz: string; algoId: string; attachAlgoOrds: any[]; cTime: string; callbackRatio: string; callbackSpread: string; ccy: string; clOrdId: string; instId: string; instType: string; lever: string; moveTriggerPx: string; ordId: string; ordIdList: any[]; ordPx: string; ordType: AlgoOrderType; posSide: AlgoPositionSide; pxLimit: string; pxSpread: string; pxVar: string; side: string; slOrdPx: string; slTriggerPx: string; slTriggerPxType: string; state: AlgoOrderState; sz: string; closeFraction: string; szLimit: string; tag: string; tdMode: string; tgtCcy: string; timeInterval: string; tpOrdPx: string; tpTriggerPx: string; tpTriggerPxType: string; triggerPx: string; reduceOnly: string; triggerPxType: string; quickMgnType: string; last: string; failCode: string; algoClOrdId: string; triggerTime: string; amendPxOnTriggerType: string; isTradeBorrowMode: boolean; chaseType?: string; chaseVal?: string; maxChaseType?: string; maxChaseVal?: string; } ⋮---- export interface HistoricAlgoOrder { activePx: string; actualPx: string; actualSide: string; actualSz: string; algoClOrdId: string; algoId: string; attachAlgoOrds: any[]; cTime: string; callbackRatio: string; callbackSpread: string; ccy: string; clOrdId: string; closeFraction: string; failCode: string; instId: string; instType: string; last: string; lever: string; moveTriggerPx: string; ordId: string; ordIdList: string[]; ordPx: string; ordType: AlgoOrderType; posSide: AlgoPositionSide; pxLimit: string; pxSpread: string; pxVar: string; quickMgnType: string; reduceOnly: string; side: string; slOrdPx: string; slTriggerPx: string; slTriggerPxType: string; state: AlgoOrderState; sz: string; szLimit: string; tag: string; tdMode: string; tgtCcy: string; timeInterval: string; tpOrdPx: string; tpTriggerPx: string; tpTriggerPxType: string; triggerPx: string; triggerPxType: string; triggerTime: string; amendPxOnTriggerType: string; isTradeBorrowMode: boolean; chaseType?: string; chaseVal?: string; maxChaseType?: string; maxChaseVal?: string; } ⋮---- export interface CancelAllAfterResponse { triggerTime: string; tag: string; ts: string; } ================ File: src/types/rest/shared.ts ================ export type numberInString = T; ⋮---- export interface APIResponse { code: '0'; msg: ''; data: T; } ⋮---- export type AlgoOrderType = | 'conditional' | 'oco' | 'trigger' | 'move_order_stop' | 'iceberg' | 'twap' | 'chase'; ⋮---- export type AlgoOrderState = | 'live' | 'pause' | 'partially_effective' | 'effective' | 'canceled' | 'order_failed' | 'partially_failed'; ⋮---- export type AlgoPositionSide = 'long' | 'short'; ⋮---- export type ContractGridDirection = 'long' | 'short' | 'neutral'; ⋮---- export type GridAlgoSubOrderType = 'live' | 'filled'; ⋮---- export type InstrumentType = 'SPOT' | 'MARGIN' | 'SWAP' | 'FUTURES' | 'OPTION'; ⋮---- export type MarginMode = 'cross' | 'isolated'; ⋮---- export type OrderSide = 'buy' | 'sell'; ⋮---- export type OrderType = | 'market' | 'limit' | 'post_only' | 'fok' | 'ioc' | 'optimal_limit_ioc' | 'mmp' | 'mmp_and_post_only' | 'elp'; ⋮---- export type OrderState = | 'canceled' | 'live' | 'partially_filled' | 'filled' | 'mmp_canceled'; ⋮---- export type PositionSide = 'net' | 'long' | 'short'; ⋮---- export type PriceTriggerType = 'last' | 'index' | 'mark'; ⋮---- export interface RFQLeg { instId: string; sz: string; side: OrderSide; tgtCcy?: string; } ⋮---- export interface RFQQuoteLegExtended { px: string; sz: string; instId: string; side: string; fee: string; feeCcy: string; tradeId: string; } ⋮---- export type TradeMode = 'cross' | 'isolated' | 'cash' | 'spot_isolated'; ⋮---- export interface TimestampObject { ts: numberInString; } ⋮---- export interface Pagination { after?: string; before?: string; limit?: string; } ⋮---- export type PosMode = 'long_short_mode' | 'net_mode'; ⋮---- export type AccountLevel = '1' | '2' | '3' | '4'; ⋮---- export type WithdrawState = | '-3' | '-2' | '-1' | '0' | '1' | '2' | '4' | '5' | '6' | '8' | '9' | '10' | '12'; ================ File: src/types/websockets/ws-request.ts ================ export interface WsAuthRequestArg { apiKey: string; passphrase: string; timestamp: string; sign: string; } ⋮---- export type WsTradeOp = | 'order' | 'batch-orders' | 'cancel-order' | 'batch-cancel-orders' | 'amend-order' | 'batch-amend-order'; ⋮---- export type WsPrivateChannel = | 'account' | 'positions' | 'balance_and_position' | 'orders' | 'orders-algo' | 'algo-advance' | 'liquidation-warning' | 'account-greeks' | 'grid-orders-spot' | 'grid-orders-contract' | 'grid-orders-moon' | 'grid-positions' | 'grid-sub-orders'; ⋮---- export type WsPublicKlineChannel = | 'candle1Y' | 'candle6M' | 'candle3M' | 'candle1M' | 'candle1W' | 'candle1D' | 'candle2D' | 'candle3D' | 'candle5D' | 'candle12H' | 'candle6H' | 'candle4H' | 'candle2H' | 'candle1H' | 'candle30m' | 'candle15m' | 'candle5m' | 'candle3m' | 'candle1m' | 'candle1s' | 'candle1Yutc' | 'candle3Mutc' | 'candle1Mutc' | 'candle1Wutc' | 'candle1Dutc' | 'candle2Dutc' | 'candle3Dutc' | 'candle5Dutc' | 'candle12Hutc' | 'candle6Hutc'; ⋮---- export type WsPublicMarkPriceKlineChannel = | 'mark-price-candle1Y' | 'mark-price-candle6M' | 'mark-price-candle3M' | 'mark-price-candle1M' | 'mark-price-candle1W' | 'mark-price-candle1D' | 'mark-price-candle2D' | 'mark-price-candle3D' | 'mark-price-candle5D' | 'mark-price-candle12H' | 'mark-price-candle6H' | 'mark-price-candle4H' | 'mark-price-candle2H' | 'mark-price-candle1H' | 'mark-price-candle30m' | 'mark-price-candle15m' | 'mark-price-candle5m' | 'mark-price-candle3m' | 'mark-price-candle1m' | 'mark-price-candle1Yutc' | 'mark-price-candle3Mutc' | 'mark-price-candle1Mutc' | 'mark-price-candle1Wutc' | 'mark-price-candle1Dutc' | 'mark-price-candle2Dutc' | 'mark-price-candle3Dutc' | 'mark-price-candle5Dutc' | 'mark-price-candle12Hutc' | 'mark-price-candle6Hutc'; ⋮---- export type WsPublicIndexKlineChannel = | 'index-candle1Y' | 'index-candle6M' | 'index-candle3M' | 'index-candle1M' | 'index-candle1W' | 'index-candle1D' | 'index-candle2D' | 'index-candle3D' | 'index-candle5D' | 'index-candle12H' | 'index-candle6H' | 'index-candle4H index -candle2H' | 'index-candle1H' | 'index-candle30m' | 'index-candle15m' | 'index-candle5m' | 'index-candle3m' | 'index-candle1m' | 'index-candle1Yutc' | 'index-candle3Mutc' | 'index-candle1Mutc' | 'index-candle1Wutc' | 'index-candle1Dutc' | 'index-candle2Dutc' | 'index-candle3Dutc' | 'index-candle5Dutc' | 'index-candle12Hutc' | 'index-candle6Hutc'; ⋮---- export type WsPublicOrderBooksChannel = | 'books' | 'books5' | 'bbo-tbt' | 'books-l2-tbt' | 'books50-l2-tpt'; ⋮---- export type WsPublicChannel = | 'instruments' | 'tickers' | 'open-interest' | WsPublicKlineChannel | WsPublicMarkPriceKlineChannel | WsPublicIndexKlineChannel | 'trades' | 'estimated-price' | 'mark-price' | 'price-limit' | WsPublicOrderBooksChannel | 'opt-summary' | 'funding-rate' | 'index-tickers' | 'status' | 'liquidation-orders'; ⋮---- export type WsBusinessPrivateChannel = | 'orders-algo' | 'algo-advance' | 'deposit-info' | 'withdrawal-info' | 'grid-orders-spot' | 'grid-orders-contract' | 'grid-orders-moon' | 'grid-positions' | 'grid-sub-orders' | 'algo-recurring-buy'; ⋮---- export type WsBusinessPublicChannel = | WsPublicKlineChannel | WsPublicMarkPriceKlineChannel | WsPublicIndexKlineChannel; ⋮---- export type WsBusinessChannel = | WsBusinessPrivateChannel | WsBusinessPublicChannel; ⋮---- export type WsChannel = WsPublicChannel | WsPrivateChannel | WsBusinessChannel; ⋮---- /** Used to trigger order actions over websockets (e.g. placing & cancelling orders) */ export interface WsTradeBaseRequest { op: WsTradeOp; id: string; args: any[]; } ⋮---- export interface WsBaseRequestArg { channel: WsChannel; } ⋮---- /** * * Args to be sent with top level requests * */ ⋮---- export interface WsPrivateChannelArgTickers extends WsBaseRequestArg { channel: 'tickers'; instId: string; } ⋮---- export interface WsPrivateChannelArgWithCcy extends WsBaseRequestArg { channel: 'account' | 'account-greeks' | 'withdrawal-info'; ccy?: string; } ⋮---- export type WsChannelArgInstType = | 'SPOT' | 'MARGIN' | 'SWAP' | 'FUTURES' | 'OPTION' | 'ANY'; ⋮---- export interface WsPrivateChannelArgWithInstFamily extends WsBaseRequestArg { channel: 'positions' | 'orders' | 'orders-algo' | 'liquidation-warning'; instType: WsChannelArgInstType; instFamily?: string; instId?: string; } ⋮---- export interface WsPrivateChannelArgAlgo extends WsBaseRequestArg { channel: 'algo-advance'; instType: WsChannelArgInstType; instId?: string; algoId?: string; } ⋮---- export interface WsPrivateChannelArgBalanceAndPosition extends WsBaseRequestArg { channel: 'balance_and_position'; } ⋮---- export interface WsPrivateChannelArgGridOrders extends WsBaseRequestArg { channel: 'grid-orders-spot' | 'grid-orders-contract' | 'grid-orders-moon'; instType: 'SPOT' | 'ANY'; instId?: string; algoId?: string; } ⋮---- export interface WsPrivateChannelArgGridOther extends WsBaseRequestArg { channel: 'grid-positions' | 'grid-sub-orders'; algoId: string; } ⋮---- export interface WsPublicChannelArgInstType extends WsBaseRequestArg { channel: 'instruments'; instType: WsChannelArgInstType; } ⋮---- export interface WsPublicChannelArgInstId extends WsBaseRequestArg { channel: | 'tickers' | 'open-interest' | WsPublicKlineChannel | WsPublicMarkPriceKlineChannel | WsPublicIndexKlineChannel | 'trades' | 'mark-price' | 'price-limit' | WsPublicOrderBooksChannel | 'funding-rate' | 'index-tickers'; instId: string; } ⋮---- export type WsPublicChannelArgInstIdOrFamily = { channel: 'estimated-price'; instType: 'OPTION' | 'FUTURES'; } & ( | { instId: string; } | { instFamily: string; } ); ⋮---- export interface WsPublicChannelArgOptionSummary extends WsBaseRequestArg { channel: 'opt-summary'; instFamily: string; } ⋮---- export interface WsPublicChannelArgStatus extends WsBaseRequestArg { channel: 'status'; } ⋮---- export interface WsPublicChannelArgLiquidationOrders extends WsBaseRequestArg { channel: 'liquidation-orders'; instType: 'SWAP' | 'FUTURES'; } ⋮---- export type WsChannelSubUnSubRequestArg = | WsPrivateChannelArgTickers | WsPrivateChannelArgWithCcy | WsPrivateChannelArgWithInstFamily | WsPrivateChannelArgAlgo | WsPrivateChannelArgBalanceAndPosition | WsPrivateChannelArgGridOrders | WsPrivateChannelArgGridOther | WsPublicChannelArgInstType | WsPublicChannelArgInstId | WsPublicChannelArgInstIdOrFamily | WsPublicChannelArgOptionSummary | WsPublicChannelArgStatus | WsPublicChannelArgLiquidationOrders; ================ File: .eslintrc.cjs ================ 'require-extensions', // only once moved to ESM ⋮---- 'plugin:require-extensions/recommended', // only once moved to ESM ⋮---- // 'no-unused-vars': ['warn'], ================ File: .prettierrc ================ { "tabWidth": 2, "singleQuote": true, "trailingComma": "all" } ================ File: jest.config.ts ================ /** * For a detailed explanation regarding each configuration property, visit: * https://jestjs.io/docs/configuration */ ⋮---- import type { Config } from 'jest'; ⋮---- // All imported modules in your tests should be mocked automatically // automock: false, ⋮---- // Stop running tests after `n` failures // bail: 0, bail: false, // enable to stop test when an error occur, ⋮---- // The directory where Jest should store its cached dependency information // cacheDirectory: "/private/var/folders/kf/2k3sz4px6c9cbyzj1h_b192h0000gn/T/jest_dx", ⋮---- // Automatically clear mock calls, instances, contexts and results before every test ⋮---- // Indicates whether the coverage information should be collected while executing the test ⋮---- // An array of glob patterns indicating a set of files for which coverage information should be collected ⋮---- // The directory where Jest should output its coverage files ⋮---- // An array of regexp pattern strings used to skip coverage collection // coveragePathIgnorePatterns: [ // "/node_modules/" // ], ⋮---- // Indicates which provider should be used to instrument code for coverage ⋮---- // A list of reporter names that Jest uses when writing coverage reports // coverageReporters: [ // "json", // "text", // "lcov", // "clover" // ], ⋮---- // An object that configures minimum threshold enforcement for coverage results // coverageThreshold: undefined, ⋮---- // A path to a custom dependency extractor // dependencyExtractor: undefined, ⋮---- // Make calling deprecated APIs throw helpful error messages // errorOnDeprecated: false, ⋮---- // The default configuration for fake timers // fakeTimers: { // "enableGlobally": false // }, ⋮---- // Force coverage collection from ignored files using an array of glob patterns // forceCoverageMatch: [], ⋮---- // A path to a module which exports an async function that is triggered once before all test suites // globalSetup: undefined, ⋮---- // A path to a module which exports an async function that is triggered once after all test suites // globalTeardown: undefined, ⋮---- // A set of global variables that need to be available in all test environments // globals: {}, ⋮---- // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. // maxWorkers: "50%", ⋮---- // An array of directory names to be searched recursively up from the requiring module's location // moduleDirectories: [ // "node_modules" // ], ⋮---- // An array of file extensions your modules use ⋮---- // modulePaths: ['src'], ⋮---- // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module // moduleNameMapper: {}, ⋮---- // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader // modulePathIgnorePatterns: [], ⋮---- // Activates notifications for test results // notify: false, ⋮---- // An enum that specifies notification mode. Requires { notify: true } // notifyMode: "failure-change", ⋮---- // A preset that is used as a base for Jest's configuration // preset: undefined, ⋮---- // Run tests from one or more projects // projects: undefined, ⋮---- // Use this configuration option to add custom reporters to Jest // reporters: undefined, ⋮---- // Automatically reset mock state before every test // resetMocks: false, ⋮---- // Reset the module registry before running each individual test // resetModules: false, ⋮---- // A path to a custom resolver // resolver: undefined, ⋮---- // Automatically restore mock state and implementation before every test // restoreMocks: false, ⋮---- // The root directory that Jest should scan for tests and modules within // rootDir: undefined, ⋮---- // A list of paths to directories that Jest should use to search for files in // roots: [ // "" // ], ⋮---- // Allows you to use a custom runner instead of Jest's default test runner // runner: "jest-runner", ⋮---- // The paths to modules that run some code to configure or set up the testing environment before each test // setupFiles: [], ⋮---- // A list of paths to modules that run some code to configure or set up the testing framework before each test // setupFilesAfterEnv: [], ⋮---- // The number of seconds after which a test is considered as slow and reported as such in the results. // slowTestThreshold: 5, ⋮---- // A list of paths to snapshot serializer modules Jest should use for snapshot testing // snapshotSerializers: [], ⋮---- // The test environment that will be used for testing // testEnvironment: "jest-environment-node", ⋮---- // Options that will be passed to the testEnvironment // testEnvironmentOptions: {}, ⋮---- // Adds a location field to test results // testLocationInResults: false, ⋮---- // The glob patterns Jest uses to detect test files ⋮---- // "**/__tests__/**/*.[jt]s?(x)", ⋮---- // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped // testPathIgnorePatterns: [ // "/node_modules/" // ], ⋮---- // The regexp pattern or array of patterns that Jest uses to detect test files // testRegex: [], ⋮---- // This option allows the use of a custom results processor // testResultsProcessor: undefined, ⋮---- // This option allows use of a custom test runner // testRunner: "jest-circus/runner", ⋮---- // A map from regular expressions to paths to transformers // transform: undefined, ⋮---- // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation // transformIgnorePatterns: [ // "/node_modules/", // "\\.pnp\\.[^\\/]+$" // ], ⋮---- // Prevents import esm module error from v1 axios release, issue #5026 ⋮---- // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them // unmockedModulePathPatterns: undefined, ⋮---- // Indicates whether each individual test should be reported during the run // verbose: undefined, verbose: true, // report individual test ⋮---- // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode // watchPathIgnorePatterns: [], ⋮---- // Whether to use watchman for file crawling // watchman: true, ================ File: postBuild.sh ================ #!/bin/bash # # Add package.json files to cjs/mjs subtrees # cat >dist/cjs/package.json <dist/mjs/package.json <[]; groupId?: string; acctAlloc?: AccountAllocationResult[]; } ⋮---- export interface CancelBlockRFQResult { rfqId: string; clRfqId: string; sCode: string; sMsg: string; } ⋮---- export interface AccountAllocationLegExecutionResult { instId: string; sz: string; fee: string; feeCcy: string; tradeId: string; } ⋮---- export interface AccountAllocationExecutionResult { acct: string; blockTdId: string; sCode: string; sMsg: string; legs: AccountAllocationLegExecutionResult[]; } export interface ExecuteBlockQuoteResult { blockTdId: string; rfqId: string; clRfqId: string; quoteId: string; clQuoteId: string; tTraderCode: string; mTraderCode: string; cTime: string; tag?: string; legs: RFQQuoteLegExtended[]; acctAlloc?: AccountAllocationExecutionResult[]; } ⋮---- export interface CreatedBlockQuoteLeg { px: string; sz: string; instId: string; side: string; tgtCcy: string; } ⋮---- export interface CreateBlockQuoteResult { cTime: string; uTime: string; quoteId: string; clQuoteId: string; rfqId: string; quoteSide: string; state: string; validUntil: string; legs: CreatedBlockQuoteLeg[]; } ⋮---- export interface CancelBlockQuoteResult { rfqId: string; clQuoteId: string; sCode: string; sMsg: string; } ⋮---- export interface BlockRFQResult { rfqId: string; clRfqId: string; traderCode: string; validUntil: string; state: string; counterparties: string[]; legs: Required[]; cTime: string; uTime: string; allowPartialExecution?: boolean; groupId?: string; acctAlloc?: AccountAllocationResult[]; } ⋮---- export interface BlockQuoteLeg { px: string; sz: string; instId: string; side: string; tgtCcy: string; } ⋮---- export interface GetBlockQuoteResult { validUntil: string; uTime: string; cTime: string; legs: BlockQuoteLeg[]; quoteId: string; rfqId: string; quoteSide: string; state: string; clQuoteId: string; clRfqId: string; traderCode: string; } ⋮---- export interface BlockMakerInstrumentData { uly?: string; instId?: string; maxBlockSz?: string; makerPxBand?: string; } ⋮---- export interface AccountAllocationTradeLegResult { instId: string; sz: string; tradeId: string; fee: string; feeCcy: string; } export interface AccountAllocationTradeResult { blockTdId: string; errorCode: string; acct: string; legs: AccountAllocationTradeLegResult[]; } ⋮---- export interface BlockTradeLeg { instId: string; side: string; sz: string; px: string; tradeId: string; fee: string; feeCcy: string; tradeQuoteCcy?: string; } ⋮---- export interface BlockTradeResult { rfqId: string; clRfqId: string; quoteId: string; clQuoteId: string; blockTdId: string; tag: string; isSuccessful: boolean; errorCode: string; cTime: string; tTraderCode: string; mTraderCode: string; legs: BlockTradeLeg[]; groupId?: string; acctAlloc?: AccountAllocationTradeResult[]; } ⋮---- export interface BlockMakerInstrumentSettings { instType: string; includeALL: boolean; data: BlockMakerInstrumentData[]; } ⋮---- export interface SetMmpConfigResult { timeInterval: string; frozenInterval: string; countLimit: string; } ⋮---- export interface BlockMMPConfig { frozenInterval: string; mmpFrozen: boolean; mmpFrozenUntil: string; countLimit: string; timeInterval: string; } ⋮---- export interface PublicBlockTradeLeg { instId: string; tradeId: string; px: string; sz: string; side: 'buy' | 'sell'; } ⋮---- export interface PublicBlockTrade { blockTdId: string; groupId?: string; legs: PublicBlockTradeLeg[]; strategy?: string; cTime: string; } ================ File: src/types/rest/client.ts ================ import { APIMarket } from '../shared.js'; ⋮---- export interface RestClientOptions { apiKey?: string; apiSecret?: string; apiPass?: string; /** * The API group this client should connect to: * - market: 'prod' (default: connects to OKX global) https://www.okx.com/docs-v5/en/#overview-production-trading-services * - market: 'EEA' // also known as "my.okx.com" https://my.okx.com/docs-v5/en/#overview-production-trading-services * - market: 'US' // also known as "app.okx.com" https://app.okx.com/docs-v5/en/#overview-production-trading-services */ market?: APIMarket; /** * Set to `true` to use OKX's demo trading functionality */ demoTrading?: boolean; // Default: false. If true, we'll throw errors if any params are undefined strict_param_validation?: boolean; // Optionally override API protocol + domain. // Note: to use my.okx or app.okx or eea.okx or us.okx, use the "market" parameter // e.g 'https://eea.okx.com' baseUrl?: string; // Default: true. whether to try and post-process request exceptions. parse_exceptions?: boolean; /** * Enable keep alive for REST API requests (via axios). */ keepAlive?: boolean; /** * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. * Only relevant if keepAlive is set to true. * Default: 1000 (defaults comes from https agent) */ keepAliveMsecs?: number; /** * Allows you to provide a custom "signMessage" function, e.g. to use node's much faster createHmac method * * Look in the examples folder for a demonstration on using node's createHmac instead. */ customSignMessageFn?: (message: string, secret: string) => Promise; } ⋮---- /** * The API group this client should connect to: * - market: 'prod' (default: connects to OKX global) https://www.okx.com/docs-v5/en/#overview-production-trading-services * - market: 'EEA' // also known as "my.okx.com" https://my.okx.com/docs-v5/en/#overview-production-trading-services * - market: 'US' // also known as "app.okx.com" https://app.okx.com/docs-v5/en/#overview-production-trading-services */ ⋮---- /** * Set to `true` to use OKX's demo trading functionality */ ⋮---- // Default: false. If true, we'll throw errors if any params are undefined ⋮---- // Optionally override API protocol + domain. // Note: to use my.okx or app.okx or eea.okx or us.okx, use the "market" parameter // e.g 'https://eea.okx.com' ⋮---- // Default: true. whether to try and post-process request exceptions. ⋮---- /** * Enable keep alive for REST API requests (via axios). */ ⋮---- /** * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. * Only relevant if keepAlive is set to true. * Default: 1000 (defaults comes from https agent) */ ⋮---- /** * Allows you to provide a custom "signMessage" function, e.g. to use node's much faster createHmac method * * Look in the examples folder for a demonstration on using node's createHmac instead. */ ================ File: src/types/websockets/ws-api-request.ts ================ import { numberInString, OrderSide, OrderType, PositionSide, TradeMode, } from '../rest/shared.js'; ⋮---- export interface WSAPIPlaceOrderRequestV5 { instId: string; tdMode: TradeMode; ccy?: string; clOrdId?: string; tag?: string; side: OrderSide; posSide?: PositionSide; ordType: OrderType; /** Quantity to buy or sell */ sz: numberInString; px?: numberInString; pxUsd?: numberInString; pxVol?: numberInString; reduceOnly?: boolean; /** A spot buy on BTC-USDT with "base_ccy" would mean the QTY (sz) is in USDT */ tgtCcy?: 'base_ccy' | 'quote_ccy'; banAmend?: boolean; tradeQuoteCcy?: string; stpMode?: 'cancel_maker' | 'cancel_taker' | 'cancel_both'; } ⋮---- /** Quantity to buy or sell */ ⋮---- /** A spot buy on BTC-USDT with "base_ccy" would mean the QTY (sz) is in USDT */ ⋮---- export interface WSAPIAmendOrderRequestV5 { instId: string; cxlOnFail?: boolean; ordId?: string; clOrdId?: string; reqId?: string; newSz?: string; newPx?: string; newPxUsd?: string; newPxVol?: string; } ⋮---- export interface WSAPIMassCancelOrdersRequestV5 { instType: string; instFamily: string; lockInterval?: string; } ⋮---- export interface WSAPIPlaceSpreadOrderRequestV5 { sprdId: string; clOrdId?: string; tag?: string; side: OrderSide; ordType: OrderType; sz: numberInString; px?: numberInString; } ⋮---- export interface WSAPIAmendSpreadOrderRequestV5 { ordId?: string; clOrdId?: string; reqId?: string; newSz?: string; newPx?: string; } ⋮---- export interface WSAPICancelSpreadOrderRequestV5 { ordId?: string; clOrdId?: string; } ⋮---- export interface WSAPISpreadMassCancelOrdersRequestV5 { sprdId?: string; } ================ File: src/types/websockets/ws-api-response.ts ================ import { numberInString } from '../rest/shared.js'; ⋮---- export interface WSAPICancelOrderResultV5 { clOrdId: string; ordId: string; ts: numberInString; sCode: string; sMsg: string; } ⋮---- export interface WSAPISpreadPlaceOrderResultV5 { clOrdId: string; ordId: string; tag: string; sCode: numberInString; sMsg: string; } ⋮---- export interface WSAPISpreadAmendOrderResultV5 { clOrdId: string; ordId: string; reqId: string; sCode: string; sMsg: string; } ⋮---- export interface WSAPISpreadCancelOrderResultV5 { clOrdId: string; ordId: string; sCode: string; sMsg: string; } ================ File: src/types/websockets/ws-events.ts ================ import { WsChannel } from './ws-request.js'; ⋮---- export interface MessageEventLike { target: WebSocket; type: 'message'; data: string; } ⋮---- export function isMessageEvent(msg: unknown): msg is MessageEventLike ⋮---- export interface WsEvent { event: 'error' | 'login' | 'subscribe' | 'unsubscribe' | 'channel-conn-count'; code?: string; msg?: string; arg?: any; data?: any; } ⋮---- export interface WsDataEvent { arg: { channel: WsChannel; uid?: string; instId?: string; instFamily?: string; }; data: T; } ⋮---- export interface WsLoginEvent extends WsEvent { event: 'login'; } ⋮---- export interface WsChannelConnInfoEvent extends WsEvent { event: 'channel-conn-count'; channel: string; connId: string; connCount: string; } ⋮---- export type WsResponse = WsEvent; ================ File: .gitignore ================ !.gitkeep .DS_STORE *.log npm-debug.log* yarn-debug.log* yarn-error.log* lerna-debug.log* report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json pids *.pid *.seed *.pid.lock node_modules/ .npm .eslintcache .node_repl_history *.tgz .yarn-integrity .env .env.test .cache lib dist bundleReport.html .history/ .idea privaterepotracker restClientRegex.ts testfile.ts localtest.sh repomix.sh ================ File: examples/ws-private.ts ================ // If you cloned the repo and are using typescript, you can import from src directly: import { DefaultLogger, WebsocketClient } from '../src'; ⋮---- // or use the module installed via `npm install okx-api`: // import { WebsocketClient, DefaultLogger } from 'okx-api'; ⋮---- // or if you're not using typescript (e.g. pure nodejs), change the "import" to "require": // const { WebsocketClient, DefaultLogger } = require('okx-api'); ⋮---- // Optional: Inject a custom logger. // This example overrides the default logger to also log "trace" (super verbose) messages, which are disabled by default ⋮---- // trace: (...params) => console.log('trace', ...params), ⋮---- // For private events, all 3 of the following are required (per account): ⋮---- // If running from CLI in unix, you can pass env vars as such: // API_KEY_COM='lkm12n3-2ba3-1mxf-fn13-lkm12n3a' API_SECRET_COM='035B2B9637E1BDFFEE2646BFBDDB8CE4' API_PASSPHRASE_COM='ComplexPa$$!23$5^' ts-node examples/ws-private.ts ⋮---- // note the single quotes, preventing special characters such as $ from being incorrectly passed ⋮---- // For Global users (www.okx.com), you don't need to set the market. // It will use global by default. // Not needed: market: 'GLOBAL', ⋮---- // For EEA users (my.okx.com), set market to "EEA": // market: 'EEA', ⋮---- // For US users (app.okx.com), set market to "US": // market: 'US', ⋮---- // For private topics, include one or more accounts in an array. Otherwise only public topics will work ⋮---- // { // apiKey: 'yourApiKeyHere', // apiSecret: 'yourApiSecretHere', // apiPass: 'yourApiPassHere', // }, // { // apiKey: 'anotherAccountKey', // apiSecret: 'anotherAccountSecret', // apiPass: 'anotherAccountPass', // }, ⋮---- // Raw data will arrive on the 'update' event ⋮---- // console.log('ws update (raw data received)', JSON.stringify(data, null, 2)); ⋮---- // Replies (e.g. authenticating or subscribing to channels) will arrive on the 'response' event ⋮---- // console.log('ws response: ', JSON.stringify(data, null, 2)); ⋮---- // Optional, connect before subscribing: // wsClient.connectPrivate(); ⋮---- // This is optional though. The wsclient will automatically open and subscribe if the connection doesn't exist yet. ⋮---- /** * # Subscribing to channels * * Subscribe to channels using the inner "args" part of the subscription request described in the OKX API docs. * * For example, if the docs state your request should look as such: { op: "subscribe", args: [ { channel: "account" } ] } * * You should call the wsClient.subscribe function using only the "args". * * Either of these examples is correct (one channel vs one or more channels in an array): wsClient.subscribe({ channel: 'account' }); wsClient.subscribe([ { channel: "account" } ]) */ ⋮---- // Subscribe one event at a time: ⋮---- // OR, combine multiple subscription events into one request using an array instead of an object: ⋮---- /** * Examples for each private channel listed in the API docs: * https://www.okx.com/docs-v5/en/#websocket-api-private-channel */ ⋮---- // Account events for all symbols ⋮---- // Account events for specific symbol only ⋮---- // Withdrawal events for specific symbol only ⋮---- // Position events on any instrument type ⋮---- // Position events on specific instruments ⋮---- // Balance & position channel ⋮---- // Order channel ⋮---- // Order channel with extra args ⋮---- // Algo orders channel ⋮---- // Advance algo orders channel ⋮---- // Position risk warning channel ⋮---- // Account greeks channel ⋮---- // Spot grid algo orders channel ⋮---- // Contract grid orders channel ⋮---- // Moon grid orders channel ⋮---- // Moon grid orders channel ⋮---- // Grid positions channel ⋮---- // Grid sub orders channel ================ File: examples/ws-public.ts ================ import { DefaultLogger, WebsocketClient } from '../src'; ⋮---- // or use the module installed via `npm install okx-api`: // import { WebsocketClient, DefaultLogger } from 'okx-api'; ⋮---- // or if you're not using typescript (e.g. pure nodejs), change the "import" to "require": // const { WebsocketClient, DefaultLogger } = require('okx-api'); ⋮---- // Optional: Inject a custom logger. // This example overrides the default logger to also log "trace" (super verbose) messages, which are disabled by default ⋮---- // trace: (...params) => console.log('trace', ...params), ⋮---- // For Global users (www.okx.com), you don't need to set the market. // It will use global by default. // Not needed: market: 'GLOBAL', // For EEA users (my.okx.com), set market to "EEA": // market: 'EEA', // For US users (app.okx.com), set market to "US": // market: 'US', ⋮---- logger, // Optional: inject the custom logger here ⋮---- // Raw data will arrive on the 'update' event ⋮---- // console.log( // new Date(), // 'ws update (raw data received)', // JSON.stringify(data, null, 2), // ); // console.log('ws update (raw data received)', JSON.stringify(data, null, 2)); ⋮---- // Replies (e.g. authenticating or subscribing to channels) will arrive on the 'response' event ⋮---- // Send one topic at a time ⋮---- // Or an array of requests ⋮---- /** * * Examples for each channel: https://www.okx.com/docs-v5/en/#websocket-api-public-channel * */ ⋮---- // Instruments channel ⋮---- // Tickers channel ⋮---- // Open interest channel ⋮---- // Candlesticks channel ⋮---- // Trades channel ⋮---- // Estimated delivery/exercise price channel ⋮---- // Mark price channel ⋮---- // Mark price candlesticks channel ⋮---- // Price limit channel ⋮---- // Order book channel ⋮---- // OPTION summary channel ⋮---- // Funding rate channel ⋮---- // Index candlesticks channel ⋮---- // Index tickers channel ⋮---- // Status channel ⋮---- // Liquidation orders channel ================ File: src/types/rest/request/account.ts ================ import { InstrumentType, MarginMode, PositionSide, WithdrawState, } from '../shared.js'; ⋮---- export interface SetLeverageRequest { instId?: string; ccy?: string; lever: string; mgnMode: MarginMode; posSide?: 'long' | 'short'; } ⋮---- export interface ChangePositionMarginRequest { instId: string; posSide: PositionSide; type: 'add' | 'reduce'; amt: string; ccy?: string; auto?: boolean; loanTrans?: boolean; } ⋮---- export interface GetPositionsParams { instType?: InstrumentType; instId?: string; posId?: string; } ⋮---- export interface GetHistoricPositionParams { instType?: InstrumentType; instId?: string; mgnMode?: string; type?: string; posId?: string; after?: string; before?: string; limit?: string; } ⋮---- export interface WithdrawalHistoryRequest { ccy?: string; wdId?: string; clientId?: string; txId?: string; type?: '3' | '4'; state?: WithdrawState; after?: string; before?: string; limit?: string; } ⋮---- export interface GetInstrumentsRequest { instType: 'SPOT' | 'MARGIN' | 'SWAP' | 'FUTURES' | 'OPTION'; uly?: string; instFamily?: string; instId?: string; } ⋮---- export interface QuickMarginBorrowRepayRequest { instId: string; ccy: string; side: 'borrow' | 'repay'; amt: string; posSide?: 'long' | 'short'; } ⋮---- export interface GetQuickMarginBorrowRepayHistoryRequest { instId?: string; ccy?: string; side?: 'borrow' | 'repay'; after?: string; before?: string; begin?: string; end?: string; limit?: string; } ⋮---- export interface GetVIPInterestRequest { ccy?: string; ordId?: string; after?: string; before?: string; limit?: string; } ⋮---- export interface GetVIPLoanOrderListRequest { ordId?: string; state?: '1' | '2' | '3' | '4' | '5'; ccy?: string; after?: string; before?: string; limit?: string; } ⋮---- export interface GetVIPLoanOrderDetailRequest { ordId: string; ccy?: string; after?: string; before?: string; limit?: string; } ⋮---- export interface GetFixedLoanBorrowQuoteRequest { type: 'normal' | 'reborrow'; ccy?: string; amt?: string; maxRate?: string; term?: string; ordId?: string; } ⋮---- export interface SubmitFixedLoanBorrowingOrderRequest { ccy: string; amt: string; maxRate: string; term: string; reborrow?: boolean; reborrowRate?: string; } ⋮---- export interface UpdateFixedLoanBorrowingOrderRequest { ordId: string; reborrow?: boolean; renewMaxRate?: string; } ⋮---- export interface GetFixedLoanBorrowingOrdersListRequest { ordId?: string; ccy?: string; state?: string; after?: string; before?: string; limit?: string; term?: string; } ⋮---- export interface GetBorrowRepayHistoryRequest { ccy?: string; type?: 'auto_borrow' | 'auto_repay' | 'manual_borrow' | 'manual_repay'; after?: string; before?: string; limit?: string; } ⋮---- export interface PositionBuilderRequest { inclRealPosAndEq?: boolean; spotOffsetType?: '1' | '2' | '3'; simPos?: { instId: string; pos: string; }[]; simAsset?: { ccy: string; amt: string; }[]; greeksType?: 'BS' | 'PA' | 'CASH'; } ⋮---- export interface SetMMPConfigRequest { instFamily: string; timeInterval: string; frozenInterval: string; qtyLimit: string; } ⋮---- export interface SetSettleCurrencyRequest { settleCcy: string; } ⋮---- export interface SetFeeTypeRequest { feeType: '0' | '1'; } ⋮---- export interface SetTradingConfigRequest { type: 'stgyType'; // Trading config type stgyType?: '0' | '1'; // Strategy type: 0=general strategy, 1=delta neutral strategy. Only applicable when type is stgyType } ⋮---- type: 'stgyType'; // Trading config type stgyType?: '0' | '1'; // Strategy type: 0=general strategy, 1=delta neutral strategy. Only applicable when type is stgyType ⋮---- export interface PrecheckSetDeltaNeutralRequest { stgyType: '0' | '1'; // Strategy type: 0=general strategy, 1=delta neutral strategy } ⋮---- stgyType: '0' | '1'; // Strategy type: 0=general strategy, 1=delta neutral strategy ================ File: src/types/rest/request/trade.ts ================ import { AlgoOrderState, AlgoOrderType, AlgoPositionSide, InstrumentType, MarginMode, numberInString, OrderSide, OrderType, PositionSide, PriceTriggerType, TradeMode, } from '../shared.js'; ⋮---- export interface AlgoRecentHistoryRequest { ordType: AlgoOrderType; algoId?: string; instType?: InstrumentType; instId?: string; after?: string; before?: string; limit?: string; } ⋮---- export interface AlgoLongHistoryRequest { ordType: AlgoOrderType; state?: AlgoOrderState; algoId?: string; instType?: InstrumentType; instId?: string; after?: string; before?: string; limit?: string; } ⋮---- interface AlgoTriggerOrder { newTpTriggerPx?: string; newTpTriggerPxType?: 'last' | 'index' | 'mark'; newTpOrdPx?: string; newSlTriggerPx?: string; newSlTriggerPxType?: 'last' | 'index' | 'mark'; newSlOrdPx?: string; } ⋮---- export interface AlgoOrderRequest { instId: string; tdMode: TradeMode; ccy?: string; side: OrderSide; posSide?: AlgoPositionSide; ordType: AlgoOrderType; algoClOrdId?: string; sz: numberInString; tag?: string; reduceOnly?: boolean; tgtCcy?: string; tpTriggerPx?: numberInString; tpTriggerPxType?: PriceTriggerType; tpOrdPx?: numberInString; tpOrdKind?: string; slTriggerPx?: numberInString; slTriggerPxType?: PriceTriggerType; slOrdPx?: numberInString; cxlOnClosePos?: boolean; triggerPx?: numberInString; triggerPxType?: PriceTriggerType; orderPx?: numberInString; chaseType?: string; chaseVal?: numberInString; maxChaseType?: string; maxChaseVal?: numberInString; callbackRatio?: numberInString; callbackSpread?: numberInString; activePx?: numberInString; pxVar?: numberInString; pxSpread?: numberInString; szLimit?: numberInString; pxLimit?: numberInString; timeInterval?: string; quickMgnType?: string; closeFraction?: numberInString; advanceOrdType?: 'fok' | 'ioc' | ''; attachAlgoOrds?: { attachAlgoClOrdId?: string; tpTriggerPx?: string; tpOrdPx?: string; slTriggerPx?: string; slOrdPx?: string; tpTriggerPxType?: string; slTriggerPxType?: string; }[]; } ⋮---- export interface AmendOrderRequest { instId: string; cxlOnFail?: boolean; ordId?: string; clOrdId?: string; reqId?: string; newSz?: string; newPx?: string; } ⋮---- export type AlgoOrderDetailsRequest = | { algoId: string; } | { algoClOrdId: string; }; ⋮---- export interface AmendAlgoOrderRequest { instId: string; algoId?: string; algoClOrdId?: string; cxlOnFail?: boolean; reqId?: string; newSz?: string; newTpTriggerPx?: string; newTpOrdPx?: string; newSlTriggerPx?: string; newSlOrdPx?: string; newTpTriggerPxType?: 'last' | 'index' | 'mark'; newSlTriggerPxType?: 'last' | 'index' | 'mark'; newTriggerPx: string; newOrdPx: string; newTriggerPxType?: 'last' | 'index' | 'mark'; attachAlgoOrds?: AlgoTriggerOrder[]; } ⋮---- export interface CancelAlgoOrderRequest { instId: string; algoId?: string; algoClOrdId?: string; } ⋮---- export interface ClosePositionRequest { instId: string; posSide?: PositionSide; mgnMode: MarginMode; ccy?: string; autoCxl?: boolean; clOrdId?: string; tag?: string; } ⋮---- export interface FillsHistoryRequest { instType?: InstrumentType; uly?: string; instId?: string; ordId?: string; after?: string; before?: string; begin?: string; end?: string; limit?: string; } ⋮---- export interface OrderIdRequest { instId: string; ordId?: string; clOrdId?: string; } ⋮---- export interface OrderHistoryRequest { instType: InstrumentType; uly?: string; instId?: string; ordType?: OrderType; state?: string; category?: string; after?: string; before?: string; begin?: string; end?: string; limit?: string; } ⋮---- export interface OrderRequest { instId: string; tdMode: TradeMode; ccy?: string; clOrdId?: string; tag?: string; side: OrderSide; posSide?: PositionSide; ordType: OrderType; /** Quantity to buy or sell */ sz: numberInString; px?: string; reduceOnly?: boolean; /** A spot buy on BTC-USDT with "base_ccy" would mean the QTY (sz) is in USDT */ tgtCcy?: 'base_ccy' | 'quote_ccy'; banAmend?: boolean; /** Take Profit & Stop Loss params */ tpTriggerPx?: string; tpOrdPx?: string; slTriggerPx?: string; slOrdPx?: string; tpTriggerPxType?: PriceTriggerType; slTriggerPxType?: PriceTriggerType; /** Quick margin type */ quickMgnType?: 'manual' | 'auto_borrow' | 'auto_repay'; } ⋮---- /** Quantity to buy or sell */ ⋮---- /** A spot buy on BTC-USDT with "base_ccy" would mean the QTY (sz) is in USDT */ ⋮---- /** Take Profit & Stop Loss params */ ⋮---- /** Quick margin type */ ⋮---- export interface GetTransactionDetailsArchiveRequest { year: string; quarter: 'Q1' | 'Q2' | 'Q3' | 'Q4'; } ⋮---- export interface OrderPrecheckRequest { instId: string; tdMode: string; side: string; posSide?: string; ordType: string; sz: string; px?: string; reduceOnly?: boolean; tgtCcy?: string; attachAlgoOrds?: { attachAlgoClOrdId?: string; tpTriggerPx?: string; tpOrdPx?: string; tpOrdKind?: string; slTriggerPx?: string; slOrdPx?: string; tpTriggerPxType?: string; slTriggerPxType?: string; sz?: string; }[]; } ================ File: src/types/rest/response/private-account.ts ================ import { AccountLevel, MarginMode, PositionSide, WithdrawState, } from '../shared.js'; ⋮---- export interface AccountBalanceDetail { availBal: string; availEq: string; cashBal: string; ccy: string; crossLiab: string; disEq: string; eq: string; eqUsd: string; frozenBal: string; interest: string; isoEq: string; isoLiab: string; isoUpl: string; liab: string; maxLoan: string; mgnRatio: string; notionalLever: string; ordFrozen: string; twap: string; uTime: string; upl: string; uplLiab: string; stgyEq: string; spotBal: string; // Spot balance. The unit is currency, e.g. BTC. openAvgPx: string[]; // Spot average cost price. The unit is USD. accAvgPx: string[]; // Spot accumulated cost price. The unit is USD. spotUpl: string; // Spot unrealized profit and loss. The unit is USD. spotUplRatio: string; // Spot unrealized profit and loss ratio. totalPnl: string; // Spot accumulated profit and loss. The unit is USD. totalPnlRatio: string; // Spot accumulated profit and loss ratio. } ⋮---- spotBal: string; // Spot balance. The unit is currency, e.g. BTC. openAvgPx: string[]; // Spot average cost price. The unit is USD. accAvgPx: string[]; // Spot accumulated cost price. The unit is USD. spotUpl: string; // Spot unrealized profit and loss. The unit is USD. spotUplRatio: string; // Spot unrealized profit and loss ratio. totalPnl: string; // Spot accumulated profit and loss. The unit is USD. totalPnlRatio: string; // Spot accumulated profit and loss ratio. ⋮---- export interface AccountBalance { adjEq: string; details: AccountBalanceDetail[]; imr: string; isoEq: string; mgnRatio: string; mmr: string; notionalUsd: string; notionalUsdForBorrow: string; notionalUsdForFutures: string; notionalUsdForOption: string; notionalUsdForSwap: string; ordFroz: string; totalEq: string; uTime: string; spotCopyTradingEq: string; upl: string; frpType?: string; // Delta neutral strategy fields delta: string; // Delta (USD) deltaLever: string; // Delta neutral strategy account level delta leverage (deltaLever = delta / totalEq) deltaNeutralStatus: string; // Delta risk status: 0=normal, 1=transfer restricted, 2=delta reducing } ⋮---- // Delta neutral strategy fields delta: string; // Delta (USD) deltaLever: string; // Delta neutral strategy account level delta leverage (deltaLever = delta / totalEq) deltaNeutralStatus: string; // Delta risk status: 0=normal, 1=transfer restricted, 2=delta reducing ⋮---- export interface AccountPosition { adl: string; availPos: string; avgPx: string; cTime: string; ccy: string; deltaBS: string; deltaPA: string; gammaBS: string; gammaPA: string; imr: string; instId: string; instType: string; interest: string; usdPx: string; last: string; lever: string; liab: string; liabCcy: string; liqPx: string; markPx: string; margin: string; mgnMode: MarginMode; mgnRatio: string; mmr: string; notionalUsd: string; optVal: string; pTime: string; pos: string; hedgedPos: string; // Hedged position size. Only returned for accounts in delta neutral strategy (stgyType:1). Returns "" for accounts in general strategy. posCcy: string; posId: string; posSide: PositionSide; thetaBS: string; thetaPA: string; tradeId: string; uTime: string; upl: string; uplRatio: string; vegaBS: string; vegaPA: string; } ⋮---- hedgedPos: string; // Hedged position size. Only returned for accounts in delta neutral strategy (stgyType:1). Returns "" for accounts in general strategy. ⋮---- export interface HistoricAccountPosition { cTime: string; ccy: string; closeAvgPx: string; closeTotalPos: string; instId: string; instType: string; lever: string; mgnMode: MarginMode; openAvgPx: string; openMaxPos: string; pnl: string; pnlRatio: string; posId: string; posSide: PositionSide; triggerPx: string; type: string; uTime: string; uly: string; } ⋮---- export interface AccountBalanceRiskData { ccy: string; disEq: string; eq: string; } ⋮---- export interface AccountPositionRiskData { baseBal: string; ccy: string; instId: string; instType: string; mgnMode: MarginMode; notionalCcy: string; notionalUsd: string; pos: string; posCcy: string; posId: string; posSide: PositionSide; quoteBal: string; } ⋮---- export interface AccountPositionRisk { adjEq: string; balData: AccountBalanceRiskData[]; posData: AccountPositionRiskData[]; ts: string; } ⋮---- export interface AccountBill { bal: string; balChg: string; billId: string; ccy: string; execType: string; fee: string; from: string; instId: string; instType: string; mgnMode: MarginMode; notes: string; ordId: string; pnl: string; posBal: string; posBalChg: string; subType: string; sz: string; to: string; ts: string; type: string; earnAmt?: string; earnApr?: string; } ⋮---- export interface AccountHistoryBill { fileHref: string; result: string; ts: string; } ⋮---- export interface AccountConfiguration { acctLv: string; autoLoan: boolean; ctIsoMode: string; greeksType: string; level: string; levelTmp: string; mgnIsoMode: string; posMode: string; spotOffsetType: string; stgyType: string; // Strategy type: 0=general strategy, 1=delta neutral strategy uid: string; label: string; roleType: string; traderInsts: any[]; spotRoleType: string; spotTraderInsts: any[]; opAuth: string; kycLv: string; ip: string; perm: string; mainUid: string; discountType: '0' | '1'; enableSpotBorrow: boolean; spotBorrowAutoRepay: boolean; feeType: string; settleCcy: string; settleCcyList: string[]; } ⋮---- stgyType: string; // Strategy type: 0=general strategy, 1=delta neutral strategy ⋮---- export interface AccountPositionModeResult { posMode: string; } ⋮---- export interface AccountModeResult { acctLv: AccountLevel; } ⋮---- export interface AutoLoanResult { autoLoan: boolean; } ⋮---- export interface AccountLeverageResult { lever: string; mgnMode: MarginMode; instId: string; posSide: PositionSide; } ⋮---- export interface AccountMaxOrderAmount { ccy: string; instId: string; maxBuy: string; maxSell: string; } ⋮---- export interface AccountMaxTradableAmount { instId: string; availBuy: string; availSell: string; } ⋮---- export interface AccountChangeMarginResult { amt: string; ccy: string; instId: string; leverage: string; posSide: PositionSide; type: string; } ⋮---- export interface AccountLeverage { instId: string; mgnMode: MarginMode; posSide: PositionSide; lever: string; } ⋮---- export interface AccountMaxLoan { instId: string; mgnMode: MarginMode; mgnCcy: string; maxLoan: string; ccy: string; side: string; } ⋮---- export interface FeeGroup { taker: string; maker: string; groupId: string; } ⋮---- export interface AccountFeeRate { category: never; delivery: string; exercise: string; instType: string; level: string; maker: string; makerU: string; taker: string; takerU: string; ts: string; ruleType: string; feeGroup?: FeeGroup[]; // Fee groups. Applicable to SPOT/MARGIN/SWAP/FUTURES/OPTION } ⋮---- feeGroup?: FeeGroup[]; // Fee groups. Applicable to SPOT/MARGIN/SWAP/FUTURES/OPTION ⋮---- export interface AccountIsolatedMode { isoMode: 'autonomy' | 'automatic'; } ⋮---- export interface AdjustLeverageInfo { estAvailQuoteTrans: string; estAvailTrans: string; estLiqPx: string; estMgn: string; estQuoteMgn: string; estMaxAmt: string; estQuoteMaxAmt: string; existOrd: boolean; maxLever: string; minLever: string; } ⋮---- export interface InterestAccrued { type: '1' | '2'; ccy: string; instId: string; mgnMode: MarginMode; interest: string; interestRate: string; liab: string; ts: string; } ⋮---- export interface InterestRate { interestRate: string; ccy: string; } ⋮---- export interface Greeks { greeksType: string; } ⋮---- export interface MaxWithdrawal { ccy: string; maxWd: string; maxWdEx: string; spotOffsetMaxWd: string; spotOffsetMaxWdEx: string; } ⋮---- export interface AccountRiskState { atRisk: string; atRiskIdx: string; atRiskMgn: string; ts: string; } ⋮---- export interface WithdrawalHistory { ccy: string; chain: string; nonTradableAsset: boolean; amt: string; ts: string; from: string; areaCodeFrom: string; to: string; areaCodeTo: string; tag: string; pmtId: string; memo: string; addrExt: any; txId: string; fee: string; feeCcy: string; state: WithdrawState; wdId: string; clientId: string; } ⋮---- export interface AccountInstrument { baseCcy: string; ctMult: string; ctType: string; ctVal: string; ctValCcy: string; expTime: string; instFamily: string; instId: string; instType: string; lever: string; listTime: string; contTdSwTime: string; // Continuous trading switch time. The switch time from call auction/prequote to continuous trading. Unix timestamp format in milliseconds. preMktSwTime: string; // The time premarket swap switched to normal swap. Unix timestamp format in milliseconds. Only applicable to premarket SWAP. lotSz: string; maxIcebergSz: string; maxLmtAmt: string; maxLmtSz: string; maxMktAmt: string; maxMktSz: string; maxStopSz: string; maxTriggerSz: string; maxTwapSz: string; minSz: string; optType: string; openType: string; // Open type: fix_price (fix price opening), pre_quote (pre-quote), call_auction (call auction). Only applicable to SPOT/MARGIN. quoteCcy: string; tradeQuoteCcyList: string[]; // List of quote currencies available for trading, e.g. ["USD", "USDC"] settleCcy: string; state: string; stk: string; tickSz: string; ruleType: string; auctionEndTime: string; futureSettlement: boolean; // Whether daily settlement for expiry feature is enabled. Applicable to FUTURES cross. instIdCode: number; // Instrument ID code. For simple binary encoding, must use instIdCode instead of instId. posLmtAmt: string; // Maximum position value (USD) for this instrument at the user level. Applicable to SWAP/FUTURES. posLmtPct: string; // Maximum position ratio (e.g., 30 for 30%) a user may hold relative to platform's current total position value. Applicable to SWAP/FUTURES. maxPlatOILmt: string; // Platform-wide maximum position value (USD) for this instrument. Applicable to SWAP/FUTURES. groupId?: string; // Instrument trading fee group ID } ⋮---- contTdSwTime: string; // Continuous trading switch time. The switch time from call auction/prequote to continuous trading. Unix timestamp format in milliseconds. preMktSwTime: string; // The time premarket swap switched to normal swap. Unix timestamp format in milliseconds. Only applicable to premarket SWAP. ⋮---- openType: string; // Open type: fix_price (fix price opening), pre_quote (pre-quote), call_auction (call auction). Only applicable to SPOT/MARGIN. ⋮---- tradeQuoteCcyList: string[]; // List of quote currencies available for trading, e.g. ["USD", "USDC"] ⋮---- futureSettlement: boolean; // Whether daily settlement for expiry feature is enabled. Applicable to FUTURES cross. instIdCode: number; // Instrument ID code. For simple binary encoding, must use instIdCode instead of instId. posLmtAmt: string; // Maximum position value (USD) for this instrument at the user level. Applicable to SWAP/FUTURES. posLmtPct: string; // Maximum position ratio (e.g., 30 for 30%) a user may hold relative to platform's current total position value. Applicable to SWAP/FUTURES. maxPlatOILmt: string; // Platform-wide maximum position value (USD) for this instrument. Applicable to SWAP/FUTURES. groupId?: string; // Instrument trading fee group ID ⋮---- export interface QuickMarginBorrowRepayResult { instId: string; ccy: string; side: 'borrow' | 'repay'; amt: string; posSide: string; ts: string; } ⋮---- export interface QuickMarginBorrowRepayRecord { instId: string; ccy: string; side: 'borrow' | 'repay'; accBorrowed: string; amt: string; refId: string; ts: string; } ⋮---- export interface VIPInterest { ordId: string; ccy: string; interest: string; interestRate: string; liab: string; ts: string; } ⋮---- export interface VIPLoanOrder { ts: string; nextRefreshTime: string; ccy: string; ordId: string; state: '1' | '2' | '3' | '4' | '5'; origRate: string; curRate: string; dueAmt: string; borrowAmt: string; repayAmt: string; } ⋮---- export interface VIPLoanOrderDetail { amt: string; ccy: string; failReason: string; rate: string; ts: string; type: '1' | '2' | '3' | '4'; } ⋮---- export interface FixedLoanBorrowingLimitDetail { ccy: string; used: string; borrowed: string; availBorrow: string; minBorrow: string; term: string; } ⋮---- export interface FixedLoanBorrowingLimit { totalBorrowLmt: string; totalAvailBorrow: string; borrowed: string; used: string; availRepay: string; details: FixedLoanBorrowingLimitDetail[]; ts: string; } ⋮---- export interface FixedLoanBorrowQuote { ccy: string; term: string; estAvailBorrow: string; estRate: string; estInterest: string; penaltyInterest: string; ts: string; } ⋮---- export interface SetMMPConfigResult { instFamily: string; timeInterval: string; frozenInterval: string; qtyLimit: string; } ⋮---- export interface MMPConfig { frozenInterval: string; instFamily: string; mmpFrozen: boolean; mmpFrozenUntil: string; qtyLimit: string; timeInterval: string; } ⋮---- export interface BorrowRepayHistoryItem { ccy: string; type: 'auto_borrow' | 'auto_repay' | 'manual_borrow' | 'manual_repay'; amt: string; accBorrowed: string; ts: string; } ⋮---- export interface SetCollateralAssetsResult { type: 'all' | 'custom'; ccyList: string[]; collateralEnabled: boolean; } ⋮---- export interface GetCollateralAssetsResult { ccy: string; collateralEnabled: boolean; } ⋮---- export interface SetSettleCurrencyResult { settleCcy: string; } ⋮---- export interface SetFeeTypeResult { feeType: string; } ⋮---- export interface SetTradingConfigResult { type: string; // Trading config type stgyType: string; // Strategy type } ⋮---- type: string; // Trading config type stgyType: string; // Strategy type ⋮---- export interface UnmatchedInfo { type: string; // Unmatched information type: spot_mode, futures_mode, isolated_margin, isolated_contract, positions_options, isolated_pending_orders, pending_orders_options, trading_bot, repay_borrowings, loan, delta_risk, collateral_all deltaLever?: string; // Delta leverage. Applicable when type is delta_risk ordList?: string[]; // Unmatched order list, order ID. Applicable when type is isolated_pending_orders/pending_orders_options posList?: string[]; // Unmatched position list, position ID. Applicable when type is isolated_margin/isolated_contract/positions_options } ⋮---- type: string; // Unmatched information type: spot_mode, futures_mode, isolated_margin, isolated_contract, positions_options, isolated_pending_orders, pending_orders_options, trading_bot, repay_borrowings, loan, delta_risk, collateral_all deltaLever?: string; // Delta leverage. Applicable when type is delta_risk ordList?: string[]; // Unmatched order list, order ID. Applicable when type is isolated_pending_orders/pending_orders_options posList?: string[]; // Unmatched position list, position ID. Applicable when type is isolated_margin/isolated_contract/positions_options ⋮---- export interface PrecheckSetDeltaNeutralResult { unmatchedInfoCheck: UnmatchedInfo[]; } ================ File: src/types/rest/response/private-funding.ts ================ import { ASSET_BILL_TYPE } from '../../../constants/funding.js'; ⋮---- export interface FundingCurrency { ccy: string; // Currency code (e.g., "BTC") name: string; // Currency name logoLink: string; // Currency logo URL chain: string; // Chain name (e.g., "BTC-Bitcoin") ctAddr: string; // Contract address canDep: boolean; // Deposit availability canWd: boolean; // Withdrawal availability canInternal: boolean; // Internal transfer availability depEstOpenTime: string; // Estimated deposit opening time (timestamp) wdEstOpenTime: string; // Estimated withdrawal opening time (timestamp) minDep: string; // Minimum deposit amount minWd: string; // Minimum withdrawal amount minInternal: string; // Minimum internal transfer amount maxWd: string; // Maximum withdrawal amount per transaction wdTickSz: string; // Withdrawal precision (decimal places) wdQuota: string; // 24h withdrawal limit in USD usedWdQuota: string; // Used withdrawal quota in USD fee: string; // Fixed withdrawal fee minFee: string; // Minimum withdrawal fee (deprecated) maxFee: string; // Maximum withdrawal fee (deprecated) minFeeForCtAddr: string; // Minimum contract address withdrawal fee (deprecated) maxFeeForCtAddr: string; // Maximum contract address withdrawal fee (deprecated) burningFeeRate: string; // Burning fee rate (e.g., "0.05" for 5%) mainNet: boolean; // Is main network needTag: boolean; // Requires tag/memo for withdrawal minDepArrivalConfirm: string; // Min confirmations for deposit credit minWdUnlockConfirm: string; // Min confirmations for withdrawal unlock depQuotaFixed: string; // Fixed deposit limit in USD usedDepQuotaFixed: string; // Used fixed deposit quota in USD depQuoteDailyLayer2: string; // Layer2 daily deposit limit } ⋮---- ccy: string; // Currency code (e.g., "BTC") name: string; // Currency name logoLink: string; // Currency logo URL chain: string; // Chain name (e.g., "BTC-Bitcoin") ctAddr: string; // Contract address canDep: boolean; // Deposit availability canWd: boolean; // Withdrawal availability canInternal: boolean; // Internal transfer availability depEstOpenTime: string; // Estimated deposit opening time (timestamp) wdEstOpenTime: string; // Estimated withdrawal opening time (timestamp) minDep: string; // Minimum deposit amount minWd: string; // Minimum withdrawal amount minInternal: string; // Minimum internal transfer amount maxWd: string; // Maximum withdrawal amount per transaction wdTickSz: string; // Withdrawal precision (decimal places) wdQuota: string; // 24h withdrawal limit in USD usedWdQuota: string; // Used withdrawal quota in USD fee: string; // Fixed withdrawal fee minFee: string; // Minimum withdrawal fee (deprecated) maxFee: string; // Maximum withdrawal fee (deprecated) minFeeForCtAddr: string; // Minimum contract address withdrawal fee (deprecated) maxFeeForCtAddr: string; // Maximum contract address withdrawal fee (deprecated) burningFeeRate: string; // Burning fee rate (e.g., "0.05" for 5%) mainNet: boolean; // Is main network needTag: boolean; // Requires tag/memo for withdrawal minDepArrivalConfirm: string; // Min confirmations for deposit credit minWdUnlockConfirm: string; // Min confirmations for withdrawal unlock depQuotaFixed: string; // Fixed deposit limit in USD usedDepQuotaFixed: string; // Used fixed deposit quota in USD depQuoteDailyLayer2: string; // Layer2 daily deposit limit ⋮---- export interface FundingBalance { availBal: string; bal: string; ccy: string; frozenBal: string; } ⋮---- export interface AccountAssetValuation { details: { classic: string; earn: string; funding: string; trading: string; }; totalBal: string; ts: string; } ⋮---- export interface FundTransferResult { transId: string; ccy: string; clientId: string; from: string; amt: string; to: string; } export interface FundTransferState { amt: string; ccy: string; clientId: string; from: string; instId: never; // deprecated state: string; subAcct: string; to: string; toInstId: never; // deprecated transId: string; type: string; } ⋮---- instId: never; // deprecated ⋮---- toInstId: never; // deprecated ⋮---- export interface AssetBillDetails { billId: string; ccy: string; clientId: string; balChg: string; bal: string; type: `${ASSET_BILL_TYPE}`; notes: string; ts: string; } ⋮---- export interface WithdrawResponse { ccy: string; chain: string; amt: string; wdId: string; clientId: string; } ⋮---- export interface NonTradableAsset { ccy: string; name: string; logoLink: string; bal: string; canWd: boolean; chain: string; minWd: string; wdAll: boolean; fee: string; ctAddr: string; wdTickSz: string; needTag: boolean; burningFeeRate: string; feeCcy: string; } ⋮---- export interface DepositHistory { ccy: string; // Currency, e.g. BTC chain: string; // Chain name amt: string; // Deposit amount from: string; // Deposit account. If the deposit comes from internal transfer, displays account info (phone/email, masked). Returns "" otherwise. areaCodeFrom: string; // If from is a phone number, this parameter returns area code of the phone number to: string; // Deposit address. If the deposit comes from on-chain, displays the on-chain address. Returns "" otherwise. txId: string; // Hash record of the deposit ts: string; // Timestamp that the deposit record is created, Unix timestamp format in milliseconds, e.g. 1655251200000 state: string; // Status of deposit: 0=waiting for confirmation, 1=deposit credited, 2=deposit successful, 8=pending due to temp suspension, 11=match blacklist, 12=account/deposit frozen, 13=sub-account deposit interception, 14=KYC limit depId: string; // Deposit ID fromWdId: string; // Internal transfer initiator's withdrawal ID. If deposit comes from internal transfer, displays the withdrawal ID, returns "" otherwise actualDepBlkConfirm: string; // The actual amount of blockchain confirmed in a single deposit } ⋮---- ccy: string; // Currency, e.g. BTC chain: string; // Chain name amt: string; // Deposit amount from: string; // Deposit account. If the deposit comes from internal transfer, displays account info (phone/email, masked). Returns "" otherwise. areaCodeFrom: string; // If from is a phone number, this parameter returns area code of the phone number to: string; // Deposit address. If the deposit comes from on-chain, displays the on-chain address. Returns "" otherwise. txId: string; // Hash record of the deposit ts: string; // Timestamp that the deposit record is created, Unix timestamp format in milliseconds, e.g. 1655251200000 state: string; // Status of deposit: 0=waiting for confirmation, 1=deposit credited, 2=deposit successful, 8=pending due to temp suspension, 11=match blacklist, 12=account/deposit frozen, 13=sub-account deposit interception, 14=KYC limit depId: string; // Deposit ID fromWdId: string; // Internal transfer initiator's withdrawal ID. If deposit comes from internal transfer, displays the withdrawal ID, returns "" otherwise actualDepBlkConfirm: string; // The actual amount of blockchain confirmed in a single deposit ================ File: src/types/rest/response/public-data.ts ================ import { InstrumentType, numberInString } from '../shared.js'; ⋮---- export interface Ticker { instType: InstrumentType; instId: string; last: numberInString; lastSz: numberInString; askPx: numberInString; askSz: numberInString; bidPx: numberInString; bidSz: numberInString; open24h: numberInString; high24h: numberInString; low24h: numberInString; volCcy24h: numberInString; vol24h: numberInString; sodUtc0: numberInString; sodUtc8: numberInString; ts: numberInString; } ⋮---- export interface IndexTicker { instId: string; idxPx: string; high24h: string; sodUtc0: string; open24h: string; low24h: string; sodUtc8: string; ts: string; } ⋮---- type OBPrice = string; type OBAssetQty = string; type OBOrderCount = string; type OrderBookLevel = [OBPrice, OBAssetQty, '0', OBOrderCount]; ⋮---- export interface OrderBook { asks: OrderBookLevel[]; bids: OrderBookLevel[]; ts: string; } ⋮---- type timestamp = string; type openPrice = string; type highPrice = string; type lowPrice = string; type closePrice = string; type vol = string; type volCcy = string; type volCcyQuote = string; type confirm = string; ⋮---- export type Candle = [ timestamp, openPrice, highPrice, lowPrice, closePrice, vol, volCcy, volCcyQuote, confirm, ]; ⋮---- export type CandleNoVolume = [ timestamp, openPrice, highPrice, lowPrice, closePrice, ]; ⋮---- export interface Trade { instId: string; side: string; sz: string; px: string; tradeId: string; ts: string; source?: string; } ⋮---- export interface Instrument { instType: InstrumentType; instId: string; uly: string; instFamily: string; category: string; baseCcy: string; quoteCcy: string; settleCcy: string; ctVal: string; ctMult: string; ctValCcy: string; optType: string; stk: string; listTime: string; contTdSwTime?: string; // Continuous trading switch time. The switch time from call auction/prequote to continuous trading. Unix timestamp format in milliseconds. preMktSwTime?: string; // The time premarket swap switched to normal swap. Unix timestamp format in milliseconds. Only applicable to premarket SWAP. expTime: string; lever: string; tickSz: string; lotSz: string; minSz: string; ctType: string; alias: string; state: string; openType?: string; // Open type: fix_price (fix price opening), pre_quote (pre-quote), call_auction (call auction). Only applicable to SPOT/MARGIN. maxLmtSz: string; maxLmtAmt?: string; // Max USD amount for a single limit order maxMktSz: string; maxMktAmt?: string; // Max USD amount for a single market order. Only applicable to SPOT/MARGIN. maxTwapSz: string; maxIcebergSz: string; maxTriggerSz: string; maxStopSz: string; ruleType: string; auctionEndTime: string; futureSettlement?: boolean; // Whether daily settlement for expiry feature is enabled. Applicable to FUTURES cross. tradeQuoteCcyList?: string[]; // List of quote currencies available for trading, e.g. ["USD", "USDC"] instIdCode?: number; // Instrument ID code. For simple binary encoding, must use instIdCode instead of instId. posLmtAmt?: string; // Maximum position value (USD) for this instrument at the user level. Applicable to SWAP/FUTURES. posLmtPct?: string; // Maximum position ratio (e.g., 30 for 30%) a user may hold relative to platform's current total position value. Applicable to SWAP/FUTURES. maxPlatOILmt?: string; // Platform-wide maximum position value (USD) for this instrument. Applicable to SWAP/FUTURES. groupId?: string; // Instrument trading fee group ID } ⋮---- contTdSwTime?: string; // Continuous trading switch time. The switch time from call auction/prequote to continuous trading. Unix timestamp format in milliseconds. preMktSwTime?: string; // The time premarket swap switched to normal swap. Unix timestamp format in milliseconds. Only applicable to premarket SWAP. ⋮---- openType?: string; // Open type: fix_price (fix price opening), pre_quote (pre-quote), call_auction (call auction). Only applicable to SPOT/MARGIN. ⋮---- maxLmtAmt?: string; // Max USD amount for a single limit order ⋮---- maxMktAmt?: string; // Max USD amount for a single market order. Only applicable to SPOT/MARGIN. ⋮---- futureSettlement?: boolean; // Whether daily settlement for expiry feature is enabled. Applicable to FUTURES cross. tradeQuoteCcyList?: string[]; // List of quote currencies available for trading, e.g. ["USD", "USDC"] instIdCode?: number; // Instrument ID code. For simple binary encoding, must use instIdCode instead of instId. posLmtAmt?: string; // Maximum position value (USD) for this instrument at the user level. Applicable to SWAP/FUTURES. posLmtPct?: string; // Maximum position ratio (e.g., 30 for 30%) a user may hold relative to platform's current total position value. Applicable to SWAP/FUTURES. maxPlatOILmt?: string; // Platform-wide maximum position value (USD) for this instrument. Applicable to SWAP/FUTURES. groupId?: string; // Instrument trading fee group ID ⋮---- export interface EconomicCalendarData { calendarId: string; date: string; region: string; category: string; event: string; refDate: string; actual: string; previous: string; forecast: string; dateSpan: string; importance: string; uTime: string; prevInitial: string; ccy: string; unit: string; } ⋮---- export interface UnitConvertData { type: '1' | '2'; instId: string; px: string; sz: string; unit: 'coin' | 'usds'; } ⋮---- export interface FundingRateHistory { instType: string; instId: string; fundingRate: string; realizedRate: string; fundingTime: string; method: string; } ⋮---- export interface SystemTime { ts: string; } ⋮---- export interface OptionsTradeInfo { instId: string; tradeId: string; px: string; sz: string; side: 'buy' | 'sell'; ts: string; } ⋮---- export interface OptionTrade { vol24h: string; optType: 'C' | 'P'; tradeInfo: OptionsTradeInfo[]; } ⋮---- export interface OptionTrades { instId: string; instFamily: string; tradeId: string; px: string; sz: string; side: 'buy' | 'sell'; optType: 'C' | 'P'; fillVol: string; fwdPx: string; idxPx: string; markPx: string; ts: string; } ⋮---- export interface Announcement { annType: string; pTime: string; // The actual time the announcement was first published. Unix timestamp format in milliseconds, e.g. 1597026383085 businessPTime: string; // The time displayed on the announcement page for user reference. Unix timestamp format in milliseconds, e.g. 1597026383085 title: string; url: string; } ⋮---- pTime: string; // The actual time the announcement was first published. Unix timestamp format in milliseconds, e.g. 1597026383085 businessPTime: string; // The time displayed on the announcement page for user reference. Unix timestamp format in milliseconds, e.g. 1597026383085 ⋮---- export interface BasicInterestRate { ccy: string; // Currency rate: string; // Daily borrowing rate quota: string; // Max borrow } ⋮---- ccy: string; // Currency rate: string; // Daily borrowing rate quota: string; // Max borrow ⋮---- export interface VIPInterestInfo { level: string; // VIP Level, e.g. VIP1 loanQuotaCoef: string; // Loan quota coefficient. Loan quota = quota * level irDiscount: string; // Interest rate discount (Deprecated) } ⋮---- level: string; // VIP Level, e.g. VIP1 loanQuotaCoef: string; // Loan quota coefficient. Loan quota = quota * level irDiscount: string; // Interest rate discount (Deprecated) ⋮---- export interface RegularUserInterestInfo { level: string; // Regular user Level, e.g. Lv1 loanQuotaCoef: string; // Loan quota coefficient. Loan quota = quota * level irDiscount: string; // Interest rate discount (Deprecated) } ⋮---- level: string; // Regular user Level, e.g. Lv1 loanQuotaCoef: string; // Loan quota coefficient. Loan quota = quota * level irDiscount: string; // Interest rate discount (Deprecated) ⋮---- export interface ConfigCcyItem { ccy: string; // Currency rate: string; // Daily rate } ⋮---- ccy: string; // Currency rate: string; // Daily rate ⋮---- export interface LoanQuotaConfig { ccy: string; // Currency stgyType: string; // Strategy type: 0=general strategy, 1=delta neutral strategy. If only 0 is returned, loan quota is shared between strategies quota: string; // Loan quota in absolute value level: string; // VIP level } ⋮---- ccy: string; // Currency stgyType: string; // Strategy type: 0=general strategy, 1=delta neutral strategy. If only 0 is returned, loan quota is shared between strategies quota: string; // Loan quota in absolute value level: string; // VIP level ⋮---- export interface InterestRateAndLoanQuota { basic: BasicInterestRate[]; vip: VIPInterestInfo[]; regular: RegularUserInterestInfo[]; configCcyList: ConfigCcyItem[]; // Currencies that have loan quota configured using customized absolute value config: LoanQuotaConfig[]; // The currency details of loan quota configured using customized absolute value } ⋮---- configCcyList: ConfigCcyItem[]; // Currencies that have loan quota configured using customized absolute value config: LoanQuotaConfig[]; // The currency details of loan quota configured using customized absolute value ================ File: src/types/shared.ts ================ export interface APICredentials { apiKey: string; apiSecret: string; apiPass: string; } ⋮---- /** * The API Market represents the OKX Domain that you have signed up for. At this time, there are 3 supported domain groups: * * - GLOBAL, otherwise known as "www.okx.com". * - EEA, otherwise known as "my.okx.com". * - US, otherwise known as "app.okx.com". */ export type APIMarket = | 'prod' // same as GLOBAL. Kept for some backwards compatibility // also known as "www.okx.com" or OKX Global: https://www.okx.com/docs-v5/en/#overview-production-trading-services | 'GLOBAL' // also known as "my.okx.com" https://my.okx.com/docs-v5/en/#overview-production-trading-services | 'EEA' // also known as "app.okx.com" https://app.okx.com/docs-v5/en/#overview-production-trading-services | 'US'; ⋮---- | 'prod' // same as GLOBAL. Kept for some backwards compatibility // also known as "www.okx.com" or OKX Global: https://www.okx.com/docs-v5/en/#overview-production-trading-services ⋮---- // also known as "my.okx.com" https://my.okx.com/docs-v5/en/#overview-production-trading-services ⋮---- // also known as "app.okx.com" https://app.okx.com/docs-v5/en/#overview-production-trading-services ================ File: src/index.ts ================ // Top level REST types ⋮---- // REST/request ⋮---- // REST/response ⋮---- // ================ File: tsconfig.json ================ { "compilerOptions": { "allowSyntheticDefaultImports": true, "baseUrl": ".", "noEmitOnError": true, "declaration": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": false, "inlineSourceMap": false, "lib": ["esnext", "DOM"], "listEmittedFiles": false, "listFiles": false, "moduleResolution": "node", "noFallthroughCasesInSwitch": true, "noImplicitAny": true, "noUnusedParameters": true, "pretty": true, "removeComments": false, "resolveJsonModule": true, "skipLibCheck": false, "sourceMap": true, "strict": true, "strictNullChecks": true, "types": ["node", "jest"], "module": "CommonJS", "outDir": "dist/cjs", "target": "ESNext" }, "compileOnSave": true, "include": ["src/**/*.*", "test/**/*.*", ".eslintrc.cjs"], "exclude": ["node_modules", "**/node_modules/*", "coverage", "doc", "dist"] } ================ File: src/types/websockets/ws-general.ts ================ import { RestClientOptions } from '../rest/client.js'; import { APICredentials, APIMarket } from '../shared.js'; ⋮---- export interface WSClientConfigurableOptions { accounts?: APICredentials[]; /** * The API group this client should connect to: * - market: 'prod' (default: connects to OKX global) https://www.okx.com/docs-v5/en/#overview-production-trading-services * - market: 'EEA' // also known as "my.okx.com" https://my.okx.com/docs-v5/en/#overview-production-trading-services * - market: 'US' // also known as "app.okx.com" https://app.okx.com/docs-v5/en/#overview-production-trading-services */ market?: APIMarket; /** * Set to `true` to use OKX's demo trading functionality */ demoTrading?: boolean; // Disable ping/pong ws heartbeat mechanism (not recommended). // Not supported for OKX disableHeartbeat?: boolean; /** How often to check if the connection is alive */ pingInterval?: number; /** How long to wait for a pong (heartbeat reply) before assuming the connection is dead */ pongTimeout?: number; /** Delay in milliseconds before respawning the connection */ reconnectTimeout?: number; requestOptions?: RestClientOptions; wsOptions?: { protocols?: string[]; agent?: any; }; wsUrl?: string; /** * Allows you to provide a custom "signMessage" function, e.g. to use node's much faster createHmac method * * Look in the examples folder for a demonstration on using node's createHmac instead. */ customSignMessageFn?: (message: string, secret: string) => Promise; } ⋮---- /** * The API group this client should connect to: * - market: 'prod' (default: connects to OKX global) https://www.okx.com/docs-v5/en/#overview-production-trading-services * - market: 'EEA' // also known as "my.okx.com" https://my.okx.com/docs-v5/en/#overview-production-trading-services * - market: 'US' // also known as "app.okx.com" https://app.okx.com/docs-v5/en/#overview-production-trading-services */ ⋮---- /** * Set to `true` to use OKX's demo trading functionality */ ⋮---- // Disable ping/pong ws heartbeat mechanism (not recommended). // Not supported for OKX ⋮---- /** How often to check if the connection is alive */ ⋮---- /** How long to wait for a pong (heartbeat reply) before assuming the connection is dead */ ⋮---- /** Delay in milliseconds before respawning the connection */ ⋮---- /** * Allows you to provide a custom "signMessage" function, e.g. to use node's much faster createHmac method * * Look in the examples folder for a demonstration on using node's createHmac instead. */ ⋮---- export interface WebsocketClientOptions extends WSClientConfigurableOptions { market: APIMarket; pongTimeout: number; pingInterval: number; reconnectTimeout: number; authPrivateConnectionsOnConnect: boolean; authPrivateRequests: boolean; /** * Whether to use native WebSocket ping/pong frames for heartbeats */ useNativeHeartbeats: boolean; } ⋮---- /** * Whether to use native WebSocket ping/pong frames for heartbeats */ ⋮---- export type WsEventInternalSrc = 'event' | 'function'; ================ File: src/rest-client.ts ================ import { ASSET_BILL_TYPE } from './constants/funding.js'; import { ChangePositionMarginRequest, GetBorrowRepayHistoryRequest, GetFixedLoanBorrowingOrdersListRequest, GetFixedLoanBorrowQuoteRequest, GetHistoricPositionParams, GetInstrumentsRequest, GetPositionsParams, GetQuickMarginBorrowRepayHistoryRequest, GetVIPInterestRequest, GetVIPLoanOrderDetailRequest, GetVIPLoanOrderListRequest, PositionBuilderRequest, PrecheckSetDeltaNeutralRequest, QuickMarginBorrowRepayRequest, SetFeeTypeRequest, SetLeverageRequest, SetMMPConfigRequest, SetSettleCurrencyRequest, SetTradingConfigRequest, SubmitFixedLoanBorrowingOrderRequest, UpdateFixedLoanBorrowingOrderRequest, WithdrawalHistoryRequest, } from './types/rest/request/account.js'; import { CancelBlockQuoteRequest, CancelBlockRFQRequest, CancelMultipleBlockQuoteRequest, CancelMultipleBlockRFQRequest, CreateBlockQuoteRequest, CreateBlockRFQRequest, ExecuteBlockQuoteRequest, GetBlockQuoteParams, GetBlockRFQSParams, SetMmpConfigRequest, SetQuoteProductsRequest, } from './types/rest/request/block-trading.js'; import { ConvertQuoteEstimateRequest, ConvertTradeRequest, } from './types/rest/request/convert.js'; import { CloseSubpositionRequest, CopySettingsRequest, GetCopyTradersRequest, GetCTBatchLeverageInfoRequest, GetCTHistoryLeadTradersRequest, GetCTProfitDetailsRequest, GetCurrentSubpositionsRequest, GetLeadTraderPositionsRequest, GetLeadTraderRanksRequest, GetLeadTraderStatsRequest, GetPrivateLeadTraderRanksRequest, GetSubpositionsHistoryRequest, PlaceCTAlgoOrderRequest, SetCTBatchLeverageRequest, } from './types/rest/request/copy-trading.js'; import { FundingRateRequest, FundsTransferRequest, GetDepositHistoryRequest, GetDepositWithdrawStatusRequest, WithdrawRequest, } from './types/rest/request/funding.js'; import { CloseContractGridPositionRequest, GetGridAlgoOrdersRequest, GetRSIBackTestingRequest, GridAlgoOrderRequest, GridAlgoOrderType, MaxGridQuantityRequest, StopGridAlgoOrderRequest, } from './types/rest/request/grid-trading.js'; import { CandleRequest, EconomicCalendarRequest, GetContractOpenInterestHistoryRequest, GetContractTakerVolumeRequest, GetOptionTradesRequest, GetPremiumHistoryRequest, GetTopTradersContractLongShortRatioRequest, UnitConvertRequest, } from './types/rest/request/public.js'; import { AmendRecurringBuyOrderRequest, GetRecurringBuyOrderListRequest, PlaceRecurringBuyOrderRequest, } from './types/rest/request/recurring-buy.js'; import { PaginatedSymbolRequest } from './types/rest/request/shared.js'; import { AdjustMarginBalanceRequest, AmendTPSLRequest, CancelSubOrderRequest, CreateSignalBotRequest, CreateSignalRequest, GetSignalBotEventHistoryRequest, GetSignalBotPositionHistoryRequest, GetSignalBotRequest, GetSignalBotSubOrdersRequest, GetSignalsRequest, PlaceSubOrderRequest, SetSignalInstrumentsRequest, } from './types/rest/request/signal-bot.js'; import { GetLendingOrderListRequest, GetLendingSubOrderListRequest, LendingOrder, } from './types/rest/request/simple-earn.js'; import { GetActiveSpreadOrdersRequest, GetSpreadCandlesRequest, GetSpreadOrderHistoryArchiveRequest, GetSpreadOrderHistoryRequest, GetSpreadsRequest, GetSpreadTradesRequest, PlaceSpreadOrderRequest, UpdateSpreadOrderRequest, } from './types/rest/request/spread-trading.js'; import { GetManagedSubAccountTransferHistoryRequest, GetSubAccountMaxWithdrawalsRequest, SetSubAccountLoanAllocationRequest, SubAccountTransferRequest, } from './types/rest/request/subaccount.js'; import { AlgoLongHistoryRequest, AlgoOrderDetailsRequest, AlgoOrderRequest, AlgoRecentHistoryRequest, AmendAlgoOrderRequest, AmendOrderRequest, CancelAlgoOrderRequest, ClosePositionRequest, FillsHistoryRequest, OrderHistoryRequest, OrderIdRequest, OrderPrecheckRequest, OrderRequest, } from './types/rest/request/trade.js'; import { AccountBalance, AccountBill, AccountChangeMarginResult, AccountConfiguration, AccountFeeRate, AccountHistoryBill, AccountInstrument, AccountIsolatedMode, AccountLeverage, AccountLeverageResult, AccountMaxLoan, AccountMaxOrderAmount, AccountMaxTradableAmount, AccountModeResult, AccountPosition, AccountPositionModeResult, AccountPositionRisk, AccountRiskState, AdjustLeverageInfo, AutoLoanResult, BorrowRepayHistoryItem, FixedLoanBorrowingLimit, FixedLoanBorrowQuote, Greeks, HistoricAccountPosition, InterestAccrued, InterestRate, MaxWithdrawal, MMPConfig, PrecheckSetDeltaNeutralResult, QuickMarginBorrowRepayRecord, QuickMarginBorrowRepayResult, SetFeeTypeResult, SetMMPConfigResult, SetSettleCurrencyResult, SetTradingConfigResult, VIPInterest, VIPLoanOrder, VIPLoanOrderDetail, } from './types/rest/response/private-account.js'; import { BlockCounterParty, BlockMakerInstrumentSettings, BlockMMPConfig, BlockRFQResult, BlockTradeResult, CancelBlockQuoteResult, CancelBlockRFQResult, CreateBlockQuoteResult, CreateRFQResult, ExecuteBlockQuoteResult, GetBlockQuoteResult, PublicBlockTrade, SetMmpConfigResult, } from './types/rest/response/private-block-trading.js'; import { CurrentSubposition, GetAccountConfigurationResult, GetCopySettingsResult, GetCopyTradersResult, GetCopyTradingConfigResult, GetCTBatchLeverageInfoResult, GetCTHistoryLeadTradersResult, GetCTMyLeadTradersResult, GetCTProfitDetailsResult, GetCTTotalProfitResult, GetCTUnrealizedProfitResult, GetLeadTraderRanksResult, GetPrivateLeadTraderRanksResult, LeadTraderCurrentPosition, LeadTraderPnl, LeadTraderPositionHistory, LeadTraderPreference, LeadTraderStats, PlaceCTAlgoOrderResult, SetCTBatchLeverageResult, SubpositionsHistory, } from './types/rest/response/private-copy-trading.js'; import { AccruedInterestItem, AccruedInterestRequest, AdjustCollateralRequest, CollateralAssetsResponse, LoanHistoryItem, LoanHistoryRequest, LoanInfo, MaxLoanRequest, MaxLoanResponse, } from './types/rest/response/private-flexible-loan.js'; import { AccountAssetValuation, AssetBillDetails, DepositHistory, FundingBalance, FundingCurrency, FundTransferResult, FundTransferState, NonTradableAsset, WithdrawResponse, } from './types/rest/response/private-funding.js'; import { RecurringBuyOrder, RecurringBuyOrderResult, RecurringBuySubOrder, } from './types/rest/response/private-recurring-buy.js'; import { CancelSignalBotsResult, CreateSignalBotResult, CreateSignalResult, GetSignalsResult, } from './types/rest/response/private-signal-bot.js'; import { CancelSpreadOrderResponse, PlaceSpreadOrderResponse, PublicSpreadTrade, SpreadCandle, SpreadDetails, SpreadOrder, SpreadOrderBook, SpreadTicker, SpreadTrade, UpdateSpreadOrderResponse, } from './types/rest/response/private-spread-trading.js'; import { ManagedSubAccountTransfer, SubAccount, SubAccountAPIReset, SubAccountBalances, SubAccountMaxWithdrawal, SubAccountTransferResult, } from './types/rest/response/private-subaccount.js'; import { AlgoOrderDetailsResult, AlgoOrderListItem, AlgoOrderResult, AmendAlgoOrderResult, AmendedOrder, CancelAllAfterResponse, CancelledOrderResult, ClosedPositions, HistoricAlgoOrder, HistoricOrder, OrderDetails, OrderFill, OrderListItem, OrderResult, } from './types/rest/response/private-trade.js'; import { Announcement, Candle, CandleNoVolume, EconomicCalendarData, IndexTicker, Instrument, InterestRateAndLoanQuota, OptionTrade, OptionTrades, OrderBook, SystemTime, Ticker, Trade, UnitConvertData, } from './types/rest/response/public-data.js'; import { AccountLevel, APIResponse, ContractGridDirection, GridAlgoSubOrderType, InstrumentType, MarginMode, numberInString, Pagination, PositionSide, PosMode, TimestampObject, } from './types/rest/shared.js'; import BaseRestClient from './util/BaseRestClient.js'; ⋮---- export class RestClient extends BaseRestClient ⋮---- /** * * Custom SDK functions * */ ⋮---- /** * This method is used to get the latency and time sync between the client and the server. * This is not official API endpoint and is only used for internal testing purposes. * Use this method to check the latency and time sync between the client and the server. * Final values might vary slightly, but it should be within few ms difference. * If you have any suggestions or improvements to this measurement, please create an issue or pull request on GitHub. */ async fetchLatencySummary(): Promise ⋮---- // Adjust server time by adding estimated one-way latency ⋮---- // Calculate time difference between adjusted server time and local time ⋮---- /** * * OKX misc endpoints * */ ⋮---- async getServerTime(): Promise ⋮---- /** * * Trading account endpoints * */ ⋮---- getAccountInstruments( params: GetInstrumentsRequest, ): Promise ⋮---- getBalance(params?: ⋮---- getPositions(params?: GetPositionsParams): Promise ⋮---- getPositionsHistory( params?: GetHistoricPositionParams, ): Promise ⋮---- getAccountPositionRisk(params?: { instType?: Omit<'SPOT', InstrumentType>; }): Promise ⋮---- /** Up to last 7 days */ getBills(params?: any): Promise ⋮---- /** Last 3 months */ getBillsArchive(params?: any): Promise ⋮---- /** * Apply for bill data since 1 February, 2021 except for the current quarter. * Check the file link from the "Get bills details (since 2021)" endpoint in 30 hours to allow for data generation. * During peak demand, data generation may take longer. If the file link is still unavailable after 48 hours, reach out to customer support for assistance. * It is only applicable to the data from the unified account. * * This endpoint submits a request for bill data. You can then use getRequestedBillsHistoryLink to get the link to the bill data. * It may take some time to generate the data. */ requestBillsHistoryDownloadLink(params: { year: string; quarter: 'Q1' | 'Q2' | 'Q3' | 'Q4'; }): Promise ⋮---- /** * This endpoint returns the link to the bill data which you can request using requestBillsHistoryDownloadLink. */ getRequestedBillsHistoryLink(params: { year: string; quarter: 'Q1' | 'Q2' | 'Q3' | 'Q4'; }): Promise ⋮---- getAccountConfiguration(): Promise ⋮---- setPositionMode(params: { posMode: PosMode; }): Promise ⋮---- setSettleCurrency( params: SetSettleCurrencyRequest, ): Promise ⋮---- setFeeType(params: SetFeeTypeRequest): Promise ⋮---- setLeverage(params: SetLeverageRequest): Promise ⋮---- /** Max buy/sell amount or open amount */ getMaxBuySellAmount(params: { instId: string; tdMode: 'cross' | 'isolated' | 'cash'; ccy?: string; px?: string; leverage?: string; unSpotOffset?: boolean; }): Promise ⋮---- getMaxAvailableTradableAmount(params: { instId: string; ccy?: string; tdMode: 'cross' | 'isolated' | 'cash'; reduceOnly?: boolean; unSpotOffset?: boolean; }): Promise ⋮---- changePositionMargin( params: ChangePositionMarginRequest, ): Promise ⋮---- getLeverage(params: { instId?: string; ccy?: string; mgnMode: MarginMode; }): Promise ⋮---- /** * @deprecated - will be removed in next major release * Use getLeverage() instead */ getLeverageV2(params: { instId?: string; ccy?: string; mgnMode: MarginMode; }): Promise ⋮---- getLeverageEstimatedInfo(params: { instType: string; mgnMode: MarginMode; lever: string; instId?: string; ccy?: string; posSide: PositionSide; }): Promise ⋮---- getMaxLoan(params: { instId: string; mgnMode: MarginMode; mgnCcy?: string; ccy?: string; }): Promise ⋮---- getFeeRates(params: { instType: InstrumentType; instId?: string; uly?: string; instFamily?: string; ruleType?: string; }): Promise ⋮---- getInterestAccrued(params?: { type?: '1' | '2'; ccy?: string; instId?: string; mgnMode?: MarginMode; after?: string; before?: string; limit?: string; }): Promise ⋮---- getInterestRate(params?: ⋮---- setGreeksDisplayType(params: ⋮---- setIsolatedMode(params: { isoMode: 'automatic' | 'autonomy'; type: 'MARGIN' | 'CONTRACTS'; }): Promise ⋮---- getMaxWithdrawals(params?: ⋮---- getAccountRiskState(): Promise ⋮---- setAccountCollateralAssets(params: { type: 'all' | 'custom'; collateralEnabled: boolean; ccyList?: string[]; }): Promise< { type: string; ccyList: string[]; collateralEnabled: boolean; }[] > { return this.postPrivate('/api/v5/account/set-collateral-assets', params); ⋮---- getAccountCollateralAssets(params?: { ccy?: string; collateralEnabled?: boolean; }): Promise< { ccy: string; collateralEnabled: boolean; }[] > { return this.getPrivate('/api/v5/account/collateral-assets', params); ⋮---- submitQuickMarginBorrowRepay( params: QuickMarginBorrowRepayRequest, ): Promise ⋮---- getQuickMarginBorrowRepayHistory( params: GetQuickMarginBorrowRepayHistoryRequest, ): Promise ⋮---- borrowRepayVIPLoan(params: { ccy: string; side: 'borrow' | 'repay'; amt: numberInString; ordId?: string; }): Promise ⋮---- getVIPLoanBorrowRepayHistory(params?: any): Promise ⋮---- getVIPInterestAccrued(params: GetVIPInterestRequest): Promise ⋮---- getVIPInterestDeducted( params: GetVIPInterestRequest, ): Promise ⋮---- getVIPLoanOrders( params: GetVIPLoanOrderListRequest, ): Promise ⋮---- getVIPLoanOrder( params: GetVIPLoanOrderDetailRequest, ): Promise ⋮---- getBorrowInterestLimits(params?: { type?: '1' | '2'; ccy?: string; }): Promise ⋮---- getFixedLoanBorrowLimit(): Promise ⋮---- getFixedLoanBorrowQuote( params: GetFixedLoanBorrowQuoteRequest, ): Promise ⋮---- submitFixedLoanBorrowOrder( params: SubmitFixedLoanBorrowingOrderRequest, ): Promise< { ordId: string; }[] > { return this.postPrivate( '/api/v5/account/fixed-loan/borrowing-order', params, ); ⋮---- updateFixedLoanBorrowOrder( params: UpdateFixedLoanBorrowingOrderRequest, ): Promise< { ordId: string; }[] > { return this.postPrivate( '/api/v5/account/fixed-loan/amend-borrowing-order', params, ); ⋮---- manualRenewFixedLoanBorrowOrder(params: { ordId: string; maxRate: string; }): Promise< { ordId: string; }[] > { return this.postPrivate( '/api/v5/account/fixed-loan/manual-reborrow', params, ); ⋮---- repayFixedLoanBorrowOrder(params: { ordId: string }): Promise< { ordId: string; }[] > { return this.postPrivate( '/api/v5/account/fixed-loan/repay-borrowing-order', params, ); ⋮---- convertFixedLoanToMarketLoan(params: { ordId: string }): Promise< { ordId: string; }[] > { return this.postPrivate( '/api/v5/account/fixed-loan/convert-to-market-loan', params, ); ⋮---- reduceFixedLoanLiabilities(params: { ordId: string; pendingRepay: boolean; }): Promise< { ordId: string; pendingRepay: boolean; }[] > { return this.postPrivate( '/api/v5/account/fixed-loan/reduce-liabilities', params, ); ⋮---- getFixedLoanBorrowOrders( params: GetFixedLoanBorrowingOrdersListRequest, ): Promise ⋮---- manualBorrowRepay(params: { ccy: string; side: 'borrow' | 'repay'; amt: string; }): Promise< { ccy: string; side: 'borrow' | 'repay'; amt: string; }[] > { return this.postPrivate('/api/v5/account/spot-manual-borrow-repay', params); ⋮---- setAutoRepay(params: { autoRepay: boolean }): Promise< { autoRepay: boolean; }[] > { return this.postPrivate('/api/v5/account/set-auto-repay', params); ⋮---- getBorrowRepayHistory( params?: GetBorrowRepayHistoryRequest, ): Promise ⋮---- positionBuilder(params: PositionBuilderRequest): Promise ⋮---- updateRiskOffsetAmount(params: { ccy: string; clSpotInUseAmt: string; }): Promise< { ccy: string; clSpotInUseAmt: string; }[] > { return this.postPrivate('/api/v5/account/set-riskOffset-amt', params); ⋮---- getGreeks(params?: ⋮---- getPMLimitation(params: { instType: 'SWAP' | 'FUTURES' | 'OPTION'; uly?: string; instFamily?: string; }): Promise ⋮---- updateRiskOffsetType(params: { type: '1' | '2' | '3' | '4' }): Promise< { type: '1' | '2' | '3' | '4'; }[] > { return this.postPrivate('/api/v5/account/set-riskOffset-type', params); ⋮---- activateOption(): Promise< { ts: string; }[] > { return this.postPrivate('/api/v5/account/activate-option'); ⋮---- setAutoLoan(params: ⋮---- presetAccountLevelSwitch(params: { acctLv: '2' | '3' | '4'; lever?: string; riskOffsetType?: '1' | '2' | '3' | '4'; }): Promise ⋮---- getAccountSwitchPrecheck(params: { acctLv: '1' | '2' | '3' | '4'; }): Promise ⋮---- setAccountMode(params: { acctLv: AccountLevel; }): Promise ⋮---- resetMMPStatus(params: { instType?: 'OPTION'; instFamily: string }): Promise< { result: boolean; }[] > { return this.postPrivate('/api/v5/account/mmp-reset', params); ⋮---- setMMPConfig(params: SetMMPConfigRequest): Promise ⋮---- getMMPConfig(params?: ⋮---- setTradingConfig( params: SetTradingConfigRequest, ): Promise ⋮---- precheckSetDeltaNeutral( params: PrecheckSetDeltaNeutralRequest, ): Promise ⋮---- /** * * Orderbook trading - trade endpoints * */ ⋮---- submitOrder(params: OrderRequest): Promise ⋮---- submitMultipleOrders(params: OrderRequest[]): Promise ⋮---- cancelOrder(params: OrderIdRequest): Promise ⋮---- cancelMultipleOrders( params: OrderIdRequest[], ): Promise ⋮---- amendOrder(params: AmendOrderRequest): Promise ⋮---- amendMultipleOrders(params: AmendOrderRequest[]): Promise ⋮---- closePositions(params: ClosePositionRequest): Promise ⋮---- getOrderDetails(params: OrderIdRequest): Promise ⋮---- getOrderList(params?: OrderHistoryRequest): Promise ⋮---- /** * Get history for last 7 days */ getOrderHistory(params: OrderHistoryRequest): Promise ⋮---- /** * Get history for last 3 months */ getOrderHistoryArchive( params: OrderHistoryRequest, ): Promise ⋮---- /** * Get history for last 7 days */ getFills(params?: FillsHistoryRequest): Promise ⋮---- /** * Get history for last 3 months */ getFillsHistory(params: FillsHistoryRequest): Promise ⋮---- /** Get easy convert currency list */ getEasyConvertCurrencies(params?: ⋮---- /** * * Place easy convert : Convert small currencies to mainstream currencies. * Only applicable to the crypto balance less than $10. * * Maximum 5 currencies can be selected in one order. * If there are multiple currencies, separate them with commas in the "from" field. * */ submitEasyConvert(params: { fromCcys: string[]; toCcy: string; source?: string; }): Promise> ⋮---- /** Get easy convert history : Get the history and status of easy convert trades. */ getEasyConvertHistory(params?: Pagination): Promise> ⋮---- /** * * Get one-click repay currency list : Get list of debt currency data and repay currencies. * Debt currencies include both cross and isolated debts. */ getOneClickRepayCurrencyList(params?: { debtType?: 'cross' | 'isolated'; }): Promise> ⋮---- /** * Trade one-click repay to repay cross debts. * Isolated debts are not applicable. * The maximum repayment amount is based on the remaining available balance of funding and trading accounts. */ submitOneClickRepay(params: { debtCcys: string[]; repayCcy: string; }): Promise> ⋮---- /** Get the history and status of one-click repay trades. */ getOneClickRepayHistory(params?: Pagination): Promise> ⋮---- cancelMassOrder(params: { instType: string; instFamily: string; lockInterval?: string; }): Promise< { result: boolean; }[] > { return this.postPrivate('/api/v5/trade/mass-cancel', params); ⋮---- cancelAllAfter(params: { timeOut: string; tag?: string; }): Promise ⋮---- getAccountRateLimit(): Promise ⋮---- submitOrderPrecheck(params: OrderPrecheckRequest): Promise ⋮---- /** * * Orderbook trading - Algo trading endpoints * */ ⋮---- placeAlgoOrder(params: AlgoOrderRequest): Promise ⋮---- cancelAlgoOrder( params: CancelAlgoOrderRequest[], ): Promise ⋮---- amendAlgoOrder( params: AmendAlgoOrderRequest, ): Promise ⋮---- cancelAdvanceAlgoOrder( params: CancelAlgoOrderRequest[], ): Promise ⋮---- getAlgoOrderDetails( params: AlgoOrderDetailsRequest, ): Promise ⋮---- getAlgoOrderList( params: AlgoRecentHistoryRequest, ): Promise ⋮---- getAlgoOrderHistory( params: AlgoLongHistoryRequest, ): Promise ⋮---- /** * * Orderbook trading - Grid trading endpoints * */ ⋮---- placeGridAlgoOrder(params: GridAlgoOrderRequest): Promise ⋮---- amendGridAlgoOrder(params: { algoId: string; instId: string; slTriggerPx?: string; tpTriggerPx?: string; tpRatio?: string; slRatio?: string; triggerParams?: { triggerAction?: string; triggerStrategy?: string; triggerPx?: string; stopType?: string; }[]; }): Promise ⋮---- stopGridAlgoOrder(orders: StopGridAlgoOrderRequest[]): Promise ⋮---- closeGridContractPosition( params: CloseContractGridPositionRequest, ): Promise ⋮---- cancelGridContractCloseOrder(params: { algoId: string; ordId: string; }): Promise ⋮---- instantTriggerGridAlgoOrder(params: { algoId: string }): Promise< { algoId: string; algoClOrdId: string; }[] > { return this.postPrivate( '/api/v5/tradingBot/grid/order-instant-trigger', params, ); ⋮---- getGridAlgoOrderList(params: GetGridAlgoOrdersRequest): Promise ⋮---- getGridAlgoOrderHistory(params: GetGridAlgoOrdersRequest): Promise ⋮---- getGridAlgoOrderDetails(params: { algoOrdType: GridAlgoOrderType; algoId: string; }): Promise ⋮---- getGridAlgoSubOrders(params: { algoOrdType: GridAlgoOrderType; algoId: string; type: GridAlgoSubOrderType; groupId?: string; after?: numberInString; before?: numberInString; limit?: number; }): Promise ⋮---- getGridAlgoOrderPositions(params: { algoOrdType: 'contract_grid'; algoId: string; }): Promise ⋮---- spotGridWithdrawIncome(params: ⋮---- computeGridMarginBalance(params: { algoId: string; type: 'add' | 'reduce'; amt?: numberInString; }): Promise ⋮---- adjustGridMarginBalance(params: { algoId: string; type: 'add' | 'reduce'; amt?: numberInString; percent?: numberInString; }): Promise ⋮---- adjustGridInvestment(params: { algoId: string; amt: string }): Promise< { algoId: string; }[] > { return this.postPrivate( '/api/v5/tradingBot/grid/adjust-investment', params, ); ⋮---- getGridAIParameter(params: { algoOrdType: GridAlgoOrderType; instId: string; direction: ContractGridDirection; duration?: '7D' | '30D' | '180D'; }): Promise ⋮---- computeGridMinInvestment(params: { amt: string; ccy: string; }): Promise ⋮---- getRSIBackTesting(params: GetRSIBackTestingRequest): Promise< { triggerNum: string; }[] > { return this.get('/api/v5/tradingBot/public/rsi-back-testing', params); ⋮---- getMaxGridQuantity(params: MaxGridQuantityRequest): Promise< { maxGridQty: string; }[] > { return this.get('/api/v5/tradingBot/grid/grid-quantity', params); ⋮---- /** * * Orderbook trading - Signal bot trading endpoints * */ ⋮---- createSignal(params: CreateSignalRequest): Promise ⋮---- getSignals(params: GetSignalsRequest): Promise ⋮---- createSignalBot( params: CreateSignalBotRequest, ): Promise ⋮---- cancelSignalBots(params: { algoId: string; }): Promise ⋮---- updateSignalMargin(params: AdjustMarginBalanceRequest): Promise< { algoId: string; }[] > { return this.postPrivate('/api/v5/tradingBot/signal/margin-balance', params); ⋮---- updateSignalTPSL(params: AmendTPSLRequest): Promise< { algoId: string; }[] > { return this.postPrivate('/api/v5/tradingBot/signal/amendTPSL', params); ⋮---- setSignalInstruments(params: SetSignalInstrumentsRequest): Promise< { algoId: string; }[] > { return this.postPrivate( '/api/v5/tradingBot/signal/set-instruments', params, ); ⋮---- getSignalBotOrder(params: { algoOrdType: string; algoId: string; }): Promise ⋮---- getActiveSignalBot(params: GetSignalBotRequest): Promise ⋮---- getSignalBotHistory(params: GetSignalBotRequest): Promise ⋮---- getSignalBotPositions(params: { algoOrdType: string; algoId: string; }): Promise ⋮---- getSignalBotPositionHistory( params: GetSignalBotPositionHistoryRequest, ): Promise ⋮---- closeSignalBotPosition(params: { algoId: string; instId: string }): Promise< { algoId: string; }[] > { return this.postPrivate('/api/v5/tradingBot/signal/close-position', params); ⋮---- placeSignalBotSubOrder(params: PlaceSubOrderRequest): Promise ⋮---- cancelSubOrder(params: CancelSubOrderRequest): Promise ⋮---- getSignalBotSubOrders(params: GetSignalBotSubOrdersRequest): Promise ⋮---- getSignalBotEventHistory( params: GetSignalBotEventHistoryRequest, ): Promise ⋮---- /** * * Orderbook trading - Recurring buy endpoints * */ ⋮---- submitRecurringBuyOrder( params: PlaceRecurringBuyOrderRequest, ): Promise ⋮---- amendRecurringBuyOrder( params: AmendRecurringBuyOrderRequest, ): Promise ⋮---- stopRecurringBuyOrder(params: { algoId: string; }): Promise ⋮---- getRecurringBuyOrders( params: GetRecurringBuyOrderListRequest, ): Promise ⋮---- getRecurringBuyOrderHistory( params: GetRecurringBuyOrderListRequest, ): Promise ⋮---- getRecurringBuyOrderDetails(params: { algoId: string; }): Promise ⋮---- getRecurringBuySubOrders( params: GetRecurringBuyOrderListRequest, ): Promise ⋮---- /** * * Orderbook trading - Copy trading endpoints * */ ⋮---- getCopytradingSubpositions( params?: GetCurrentSubpositionsRequest, ): Promise ⋮---- getCopytradingSubpositionsHistory( params?: GetSubpositionsHistoryRequest, ): Promise ⋮---- submitCopytradingAlgoOrder( params: PlaceCTAlgoOrderRequest, ): Promise ⋮---- closeCopytradingSubposition(params: CloseSubpositionRequest): Promise< { subPosId: string; tag: string; }[] > { return this.postPrivate('/api/v5/copytrading/close-subposition', params); ⋮---- getCopytradingInstruments(params?: { instType?: 'SPOT' | 'SWAP' }): Promise< { instId: string; enabled: boolean; }[] > { return this.getPrivate('/api/v5/copytrading/instruments', params); ⋮---- setCopytradingInstruments(params: { instType?: 'SPOT' | 'SWAP'; instId: string; }): Promise< { instId: string; enabled: boolean; }[] > { return this.postPrivate('/api/v5/copytrading/set-instruments', params); ⋮---- getCopytradingProfitDetails( params?: GetCTProfitDetailsRequest, ): Promise ⋮---- getCopytradingTotalProfit(params?: { instType?: 'SPOT' | 'SWAP'; }): Promise ⋮---- getCopytradingUnrealizedProfit(params?: { instType?: 'SPOT' | 'SWAP'; }): Promise ⋮---- getCopytradingTotalUnrealizedProfit(params?: { instType?: 'SWAP' }): Promise< { instType?: 'SWAP'; instId: string; }[] > { return this.getPrivate( '/api/v5/copytrading/total-unrealized-profit-sharing', params, ); ⋮---- applyCopytradingLeadTrading(params: { profitSharingTs: string; totalUnrealizedProfitSharingAmt: string; }): Promise< { result: boolean; }[] > { return this.postPrivate('/api/v5/copytrading/apply-lead-trading', params); ⋮---- stopCopytradingLeadTrading(params?: { instType?: 'SWAP' }): Promise< { result: boolean; }[] > { return this.postPrivate('/api/v5/copytrading/stop-lead-trading', params); ⋮---- updateCopytradingProfitSharing(params: { instType?: 'SWAP'; profitSharingRatio: string; }): Promise< { result: boolean; }[] > { return this.postPrivate( '/api/v5/copytrading/amend-profit-sharing-ratio', params, ); ⋮---- getCopytradingAccount(): Promise ⋮---- setCopytradingFirstCopy(params: CopySettingsRequest): Promise< { result: boolean; }[] > { return this.postPrivate('/api/v5/copytrading/first-copy-settings', params); ⋮---- updateCopytradingCopySettings(params: CopySettingsRequest): Promise< { result: boolean; }[] > { return this.postPrivate('/api/v5/copytrading/amend-copy-settings', params); ⋮---- stopCopytradingCopy(params: { instType?: 'SWAP'; uniqueCode: string; subPosCloseType: 'market_close' | 'copy_close' | 'manual_close'; }): Promise< { result: boolean; }[] > { return this.postPrivate('/api/v5/copytrading/stop-copy-trading', params); ⋮---- getCopytradingCopySettings(params: { instType?: 'SWAP'; uniqueCode: string; }): Promise ⋮---- getCopytradingBatchLeverageInfo( params: GetCTBatchLeverageInfoRequest, ): Promise ⋮---- setCopytradingBatchLeverage( params: SetCTBatchLeverageRequest, ): Promise ⋮---- getCopytradingMyLeadTraders(params?: { instType?: 'SWAP'; }): Promise ⋮---- getCopytradingLeadTradersHistory( params?: GetCTHistoryLeadTradersRequest, ): Promise ⋮---- getCopytradingConfig(params?: { instType?: 'SWAP'; }): Promise ⋮---- getCopytradingLeadRanks( params?: GetLeadTraderRanksRequest, ): Promise ⋮---- getCopytradingLeadWeeklyPnl(params: { instType?: 'SWAP'; uniqueCode: string; }): Promise ⋮---- getCopytradingLeadDailyPnl( params: GetLeadTraderStatsRequest, ): Promise ⋮---- getCopytradingLeadStats( params: GetLeadTraderStatsRequest, ): Promise ⋮---- getCopytradingLeadPreferences(params: { instType?: 'SWAP'; uniqueCode: string; }): Promise ⋮---- getCopytradingLeadOpenPositions( params: GetLeadTraderPositionsRequest, ): Promise ⋮---- getCopytradingLeadPositionHistory( params: GetLeadTraderPositionsRequest, ): Promise ⋮---- getCopyTraders( params: GetCopyTradersRequest, ): Promise ⋮---- getCopytradingLeadPrivateRanks( params?: GetPrivateLeadTraderRanksRequest, ): Promise ⋮---- getCopytradingLeadPrivateWeeklyPnl(params: { instType?: 'SWAP'; uniqueCode: string; }): Promise ⋮---- getCopytradingPLeadPrivateDailyPnl( params: GetLeadTraderStatsRequest, ): Promise ⋮---- geCopytradingLeadPrivateStats( params: GetLeadTraderStatsRequest, ): Promise ⋮---- getCopytradingLeadPrivatePreferences(params: { instType?: 'SWAP'; uniqueCode: string; }): Promise ⋮---- getCopytradingLeadPrivateOpenPositions( params: GetLeadTraderPositionsRequest, ): Promise ⋮---- getCopytradingLeadPrivatePositionHistory( params: GetLeadTraderPositionsRequest, ): Promise ⋮---- getCopyTradersPrivate( params: GetCopyTradersRequest, ): Promise ⋮---- /** * * Orderbook trading - Market data endpoints * */ ⋮---- getTickers(params: { instType: InstrumentType; uly?: string; instFamily?: string; }): Promise ⋮---- getTicker(params: ⋮---- getOrderBook(params: { instId: string; sz?: numberInString; }): Promise ⋮---- getFullOrderBook(params: { instId: string; sz?: string; }): Promise ⋮---- getCandles(params: CandleRequest): Promise ⋮---- getHistoricCandles(params: CandleRequest): Promise ⋮---- getTrades(params: ⋮---- getHistoricTrades(params: { instId: string; after?: numberInString; before?: numberInString; limit?: numberInString; type?: '1' | '2'; }): Promise ⋮---- getOptionTradesByInstrument(params: { instFamily: string; }): Promise ⋮---- getOptionTrades(params: GetOptionTradesRequest): Promise ⋮---- get24hrTotalVolume(): Promise ⋮---- /** * * Block trading - REST endpoints * */ ⋮---- getBlockCounterParties(): Promise ⋮---- createBlockRFQ(params: CreateBlockRFQRequest): Promise ⋮---- cancelBlockRFQ( params: CancelBlockRFQRequest, ): Promise ⋮---- cancelMultipleBlockRFQs( params: CancelMultipleBlockRFQRequest, ): Promise ⋮---- cancelAllRFQs(): Promise ⋮---- executeBlockQuote( params: ExecuteBlockQuoteRequest, ): Promise ⋮---- getQuoteProducts(): Promise ⋮---- updateBlockQuoteProducts(params: SetQuoteProductsRequest): Promise< { result: boolean; }[] > { return this.postPrivate('/api/v5/rfq/maker-instrument-settings', params); ⋮---- resetBlockMmp(): Promise< { ts: string; }[] > { return this.postPrivate('/api/v5/rfq/mmp-reset'); ⋮---- updateBlockMmpConfig( params: SetMmpConfigRequest, ): Promise ⋮---- getBlockMmpConfig(): Promise ⋮---- createBlockQuote( params: CreateBlockQuoteRequest, ): Promise ⋮---- cancelBlockQuote( params: CancelBlockQuoteRequest, ): Promise ⋮---- cancelMultipleBlockQuotes( params: CancelMultipleBlockQuoteRequest, ): Promise ⋮---- cancelAllBlockQuotes(): Promise ⋮---- cancelAllBlockAfter(params: { timeOut: string }): Promise< { triggerTime: string; ts: string; }[] > { return this.postPrivate('/api/v5/rfq/cancel-all-after', params); ⋮---- getBlockRFQs(params?: GetBlockRFQSParams): Promise ⋮---- getBlockQuotes(params?: GetBlockQuoteParams): Promise ⋮---- getBlockTrades(params?: any): Promise ⋮---- getPublicRFQBlockTrades(params?: any): Promise ⋮---- getBlockTickers(params: { instType: InstrumentType; uly?: string; }): Promise ⋮---- getBlockTicker(params: ⋮---- getBlockPublicTrades(params: { instId: string; }): Promise ⋮---- /** * * Spread trading - REST endpoints * */ ⋮---- submitSpreadOrder( params: PlaceSpreadOrderRequest, ): Promise ⋮---- cancelSpreadOrder(params?: { ordId?: string; clOrdId?: string; }): Promise ⋮---- cancelAllSpreadOrders(params?: { sprdId?: string }): Promise< { result: boolean; }[] > { return this.postPrivate('/api/v5/sprd/mass-cancel', params); ⋮---- updateSpreadOrder( params: UpdateSpreadOrderRequest, ): Promise ⋮---- getSpreadOrder(params: { ordId?: string; clOrdId?: string; }): Promise ⋮---- getSpreadActiveOrders( params?: GetActiveSpreadOrdersRequest, ): Promise ⋮---- getSpreadOrdersRecent( params?: GetSpreadOrderHistoryRequest, ): Promise ⋮---- getSpreadOrdersArchive( params?: GetSpreadOrderHistoryArchiveRequest, ): Promise ⋮---- getSpreadTrades(params?: GetSpreadTradesRequest): Promise ⋮---- getSpreads(params?: GetSpreadsRequest): Promise ⋮---- getSpreadOrderBook(params: { sprdId: string; sz?: string; }): Promise ⋮---- getSpreadTicker(params: ⋮---- getSpreadPublicTrades(params?: { sprdId?: string; }): Promise ⋮---- getSpreadCandles(params: GetSpreadCandlesRequest): Promise ⋮---- getSpreadHistoryCandles( params: GetSpreadCandlesRequest, ): Promise ⋮---- cancelSpreadAllAfter(params: { timeOut: string }): Promise< { triggerTime: string; ts: string; }[] > { return this.postPrivate('/api/v5/sprd/cancel-all-after', params); ⋮---- /** * * Public data - rest endpoints * */ ⋮---- getInstruments(params: { instType: InstrumentType; uly?: string; instFamily?: string; instId?: string; }): Promise ⋮---- getDeliveryExerciseHistory(params: any): Promise ⋮---- getOpenInterest(params: any): Promise ⋮---- getFundingRate(params: any): Promise ⋮---- getFundingRateHistory(params: FundingRateRequest): Promise ⋮---- getMinMaxLimitPrice(params: any): Promise ⋮---- getOptionMarketData(params: any): Promise ⋮---- getEstimatedDeliveryExercisePrice(params: any): Promise ⋮---- getDiscountRateAndInterestFreeQuota(params: any): Promise ⋮---- getSystemTime(params: any): Promise ⋮---- getMarkPrice(params: any): Promise ⋮---- getPositionTiers(params: any): Promise ⋮---- getInterestRateAndLoanQuota(): Promise ⋮---- getVIPInterestRateAndLoanQuota(params: any): Promise ⋮---- getUnderlying(params: any): Promise ⋮---- getInsuranceFund(params: any): Promise ⋮---- getUnitConvert(params: UnitConvertRequest): Promise ⋮---- getOptionTickBands(params: { instType: string; instFamily?: string; }): Promise ⋮---- getPremiumHistory(params: GetPremiumHistoryRequest): Promise ⋮---- getIndexTickers(params?: { quoteCcy?: string; instId?: string; }): Promise ⋮---- getIndexCandles(params: CandleRequest): Promise ⋮---- getHistoricIndexCandles(params: CandleRequest): Promise ⋮---- getMarkPriceCandles(params: CandleRequest): Promise ⋮---- getHistoricMarkPriceCandles( params: CandleRequest, ): Promise ⋮---- getOracle(): Promise ⋮---- getExchangeRate(): Promise ⋮---- getIndexComponents(params: ⋮---- getEconomicCalendar( params: EconomicCalendarRequest, ): Promise ⋮---- getPublicBlockTrades(params: ⋮---- /** * * Trading statistics - REST endpoints * */ ⋮---- getSupportCoin(): Promise ⋮---- getOpenInterestHistory( params: GetContractOpenInterestHistoryRequest, ): Promise ⋮---- getTakerVolume(params: { instType: string; ccy: string; period?: string; end?: string; begin?: string; }): Promise ⋮---- getContractTakerVolume( params: GetContractTakerVolumeRequest, ): Promise ⋮---- getMarginLendingRatio(params: { ccy: string; begin?: numberInString; end?: numberInString; period: '5m' | '1H' | '1D'; }): Promise ⋮---- getTopTradersAccountRatio( params: GetTopTradersContractLongShortRatioRequest, ): Promise ⋮---- getTopTradersContractPositionRatio( params: GetTopTradersContractLongShortRatioRequest, ): Promise ⋮---- getLongShortContractRatio( params: GetTopTradersContractLongShortRatioRequest, ): Promise ⋮---- getLongShortRatio(params: { ccy: string; begin?: numberInString; end?: numberInString; period: '5m' | '1H' | '1D'; }): Promise ⋮---- getContractsOpenInterestAndVolume(params: { ccy: string; begin?: numberInString; end?: numberInString; period: '5m' | '1H' | '1D'; }): Promise ⋮---- getOptionsOpenInterestAndVolume(params: { ccy: string; period: '8H' | '1D'; }): Promise ⋮---- getPutCallRatio(params: { ccy: string; period: '8H' | '1D'; }): Promise ⋮---- getOpenInterestAndVolumeExpiry(params: { ccy: string; period: '8H' | '1D'; }): Promise ⋮---- getOpenInterestAndVolumeStrike(params: { ccy: string; expTime: string; period: '8H' | '1D'; }): Promise ⋮---- getTakerFlow(params: ⋮---- /** * * Funding account - REST endpoints * */ ⋮---- getCurrencies(params?: ⋮---- getBalances(params?: ⋮---- getNonTradableAssets(params?: ⋮---- getAccountAssetValuation(params?: { ccy?: string; }): Promise ⋮---- fundsTransfer(params: FundsTransferRequest): Promise ⋮---- /** Either parameter transId or clientId is required. */ getFundsTransferState(params?: { transId?: string; clientId?: string; type?: '0' | '1' | '2'; }): Promise ⋮---- /** * Query the billing record in the past month. */ getAssetBillsDetails(params?: { ccy?: string; type?: `${ASSET_BILL_TYPE}`; clientId?: string; after?: numberInString; before?: numberInString; limit?: numberInString; }): Promise ⋮---- /** * Query the billing records of all time since 1 February, 2021. * * ⚠️ IMPORTANT: Data updates occur every 30 seconds. Update frequency may vary based on data volume - please be aware of potential delays during high-traffic periods. * * Rate Limit: 1 Requests per second * @param params * @returns */ getAssetBillsHistoric(params?: { ccy?: string; type?: `${ASSET_BILL_TYPE}`; clientId?: string; after?: numberInString; before?: numberInString; limit?: numberInString; pagingType?: '0' | '1'; }): Promise ⋮---- getLightningDeposits(params: { ccy: string; amt: numberInString; to?: '6' | '18'; }): Promise ⋮---- getDepositAddress(params: ⋮---- getDepositHistory( params?: GetDepositHistoryRequest, ): Promise ⋮---- submitWithdraw(params: WithdrawRequest): Promise ⋮---- submitWithdrawLightning(params: { ccy: string; invoice: string; memo?: string; }): Promise ⋮---- cancelWithdrawal(params: ⋮---- getWithdrawalHistory(params?: WithdrawalHistoryRequest): Promise ⋮---- getDepositWithdrawStatus( params: GetDepositWithdrawStatusRequest, ): Promise ⋮---- getExchanges(): Promise ⋮---- applyForMonthlyStatement(params?: ⋮---- getMonthlyStatement(params: ⋮---- getConvertCurrencies(): Promise ⋮---- getConvertCurrencyPair(params: { fromCcy: string; toCcy: string; }): Promise ⋮---- estimateConvertQuote(params: ConvertQuoteEstimateRequest): Promise ⋮---- convertTrade(params: ConvertTradeRequest): Promise ⋮---- getConvertHistory(params?: any): Promise ⋮---- /** * * Subaccount - REST endpoints * */ ⋮---- /** View sub-account list */ getSubAccountList(params?: any): Promise ⋮---- resetSubAccountAPIKey(params: { subAcct: string; apiKey: string; label?: string; perm?: string; ip?: string; }): Promise ⋮---- getSubAccountBalances(params: { subAcct: string; }): Promise ⋮---- getSubAccountFundingBalances(params: { subAcct: string; ccy?: string; }): Promise ⋮---- getSubAccountMaxWithdrawal( params: GetSubAccountMaxWithdrawalsRequest, ): Promise ⋮---- /** History of sub-account transfer */ getSubAccountTransferHistory(params?: { ccy?: string; type?: '0' | '1'; subAcct?: string; after?: string; before?: string; limit?: string; }): Promise ⋮---- getManagedSubAccountTransferHistory( params: GetManagedSubAccountTransferHistoryRequest, ): Promise ⋮---- /** Master accounts manage the transfers between sub-accounts */ transferSubAccountBalance( params: SubAccountTransferRequest, ): Promise ⋮---- setSubAccountTransferOutPermission(params: { subAcct: string; canTransOut: boolean; }): Promise ⋮---- getSubAccountCustodyTradingList(params?: { subAcct?: string; }): Promise ⋮---- setSubAccountLoanAllocation( params: SetSubAccountLoanAllocationRequest, ): Promise< { result: boolean; }[] > { return this.postPrivate( '/api/v5/account/subaccount/set-loan-allocation', params, ); ⋮---- getSubAccountBorrowInterestAndLimit(params: { subAcct: string; ccy?: string; }): Promise ⋮---- /** * * Financial product - on chain earn endpoints * */ ⋮---- /** Get earn offers */ getStakingOffers(params?: { productId?: string; protocolType?: 'staking' | 'defi'; ccy?: string; }): Promise ⋮---- submitStake(params: { productId: string; investData: { ccy: string; amt: string; }[]; term?: string; }): Promise ⋮---- redeemStake(params: { ordId: string; protocolType: 'staking' | 'defi'; allowEarlyRedeem?: boolean; }): Promise ⋮---- cancelStakingRequest(params: { ordId: string; protocolType: 'staking' | 'defi'; }): Promise ⋮---- /** Earn/staking get active orders */ getActiveStakingOrders(params?: { productId?: string; protocolType?: 'staking' | 'defi'; ccy?: string; state?: '8' | '13' | '9' | '1' | '2'; }): Promise ⋮---- /** Earn/staking get order history */ getStakingOrderHistory(params?: { productId?: string; protocolType?: string; ccy?: string; after?: string; before?: string; limit?: string; }): Promise ⋮---- /** * * Financial product - ETH staking endpoints * */ ⋮---- getETHStakingProductInfo(): Promise ⋮---- purchaseETHStaking(params: ⋮---- redeemETHStaking(params: ⋮---- getETHStakingBalance(): Promise ⋮---- getETHStakingHistory(params: { type?: 'purchase' | 'redeem'; status?: 'pending' | 'success' | 'failed' | 'cancelled'; after?: string; before?: string; limit?: string; }): Promise ⋮---- cancelRedeemETHStaking(params: { ordId: string }): Promise< { ordId: string; }[] > { return this.postPrivate( '/api/v5/finance/staking-defi/eth/cancel-redeem', params, ); ⋮---- getAPYHistory(params: ⋮---- /** * * Financial product - simple earn flexible endpoints * */ ⋮---- getSavingBalance(params?: ⋮---- savingsPurchaseRedemption(params: { ccy: string; amt: numberInString; side: 'purchase' | 'redempt'; rate: numberInString; }): Promise ⋮---- setLendingRate(params: { ccy: string; rate: numberInString; }): Promise ⋮---- getLendingHistory(params?: PaginatedSymbolRequest): Promise ⋮---- getPublicBorrowInfo(params?: ⋮---- getPublicBorrowHistory(params?: PaginatedSymbolRequest): Promise ⋮---- /** * * Financial product - simple earn fixed endpoints * */ ⋮---- getLendingOffers(params?: ⋮---- getLendingAPYHistory(params: ⋮---- getLendingVolume(params: ⋮---- placeLendingOrder(params: LendingOrder): Promise ⋮---- amendLendingOrder(params: LendingOrder): Promise ⋮---- getLendingOrders(params: GetLendingOrderListRequest): Promise ⋮---- getLendingSubOrders(params: GetLendingSubOrderListRequest): Promise ⋮---- /** * * Financial product - Flexible loan endpoints * */ ⋮---- getBorrowableCurrencies(): Promise< { borrowCcy: string; }[] > { return this.get('/api/v5/finance/flexible-loan/borrow-currencies'); ⋮---- getCollateralAssets(params?: { ccy?: string; }): Promise ⋮---- getMaxLoanAmount(params: MaxLoanRequest): Promise ⋮---- adjustCollateral(params: AdjustCollateralRequest): Promise<[]> ⋮---- getLoanInfo(): Promise ⋮---- getLoanHistory(params?: LoanHistoryRequest): Promise ⋮---- getAccruedInterest( params?: AccruedInterestRequest, ): Promise ⋮---- /** * * Affiliate endpoints * */ ⋮---- getInviteeDetail(params: ⋮---- getAffiliateRebateInfo(params: ⋮---- /** * * Status endpoints (public) * */ ⋮---- getSystemStatus(params: { state?: 'scheduled' | 'ongoing' | 'pre_open' | 'completed' | 'canceled'; }): Promise ⋮---- /** * * Announcement endpoints * */ ⋮---- getAnnouncements(params?: { annType?: string; page?: string }): Promise< { totalPage: string; details: Announcement[]; }[] > { return this.get('/api/v5/support/announcements', params); ⋮---- getAnnouncementTypes(): Promise< { annType: string; annTypeDesc: string; }[] > { return this.get('/api/v5/support/announcement-types'); ⋮---- /** * * Broker endpoints (private) * */ ⋮---- createSubAccount(params: { subAcct: string; label?: string; clientIP?: string; mainAcct: string; }): Promise ⋮---- deleteSubAccount(params: ⋮---- createSubAccountAPIKey(params: { subAcct: string; label: string; passphrase: string; ip?: string; perm?: string; }): Promise ================ File: src/types/websockets/ws-api.ts ================ import { WS_KEY_MAP, WsKey } from '../../util/websocket-util.js'; import { OrderIdRequest } from '../rest/request/trade.js'; import { OrderResult } from '../rest/response/private-trade.js'; import { numberInString } from '../rest/shared.js'; import { WSAPIAmendOrderRequestV5, WSAPIAmendSpreadOrderRequestV5, WSAPICancelSpreadOrderRequestV5, WSAPIMassCancelOrdersRequestV5, WSAPIPlaceOrderRequestV5, WSAPIPlaceSpreadOrderRequestV5, WSAPISpreadMassCancelOrdersRequestV5, } from './ws-api-request.js'; import { WSAPICancelOrderResultV5, WSAPISpreadAmendOrderResultV5, WSAPISpreadCancelOrderResultV5, WSAPISpreadPlaceOrderResultV5, } from './ws-api-response.js'; import { WsAuthRequestArg, WsChannelSubUnSubRequestArg } from './ws-request.js'; ⋮---- export interface WSAPIRequestFlags { /** If true, will skip auth requirement for WS API connection */ authIsOptional?: boolean | undefined; /** * Request effective deadline. Unix timestamp format in milliseconds, e.g. 1597026383085 * * Only applies for order placement and order amend (batch commands included) */ expTime?: numberInString; } ⋮---- /** If true, will skip auth requirement for WS API connection */ ⋮---- /** * Request effective deadline. Unix timestamp format in milliseconds, e.g. 1597026383085 * * Only applies for order placement and order amend (batch commands included) */ ⋮---- export type WSOperation = 'subscribe' | 'unsubscribe' | 'login'; ⋮---- /** * * Top level requests with args * */ ⋮---- /** /** * request looks like this: { "id": "1512", "op": "subscribe", "args": [ { "channel": "tickers", "instId": "BTC-USDT" } ] } */ export interface WsRequestOperationOKX { id: string; op: WSOperation; args?: TWSRequestArg[]; } ⋮---- export interface WsSubRequest extends WsRequestOperationOKX { op: 'subscribe'; } ⋮---- export interface WsUnsubRequest extends WsRequestOperationOKX { op: 'unsubscribe'; } ⋮---- export interface WsAuthRequest extends WsRequestOperationOKX { op: 'login'; } ⋮---- export type WSAPIPrivateOperations = // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order | 'order' // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-multiple-orders | 'batch-orders' // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-order | 'cancel-order' // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-multiple-orders | 'batch-cancel-orders' // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-order | 'amend-order' // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-multiple-orders | 'batch-amend-orders' // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-mass-cancel-order | 'mass-cancel'; ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-multiple-orders ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-order ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-multiple-orders ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-order ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-multiple-orders ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-mass-cancel-order ⋮---- export type WSAPIBusinessOperations = // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-place-order | 'sprd-order' // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-amend-order | 'sprd-amend-order' // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-order | 'sprd-cancel-order' // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-order | 'sprd-mass-cancel'; ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-place-order ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-amend-order ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-order ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-order ⋮---- // When new WS API operations are added, make sure to also update WS_API_Operations[] below export type WSAPIOperation = WSAPIPrivateOperations | WSAPIBusinessOperations; ⋮---- export interface WSAPIRequestOKX { id: numberInString; op: WSAPIOperation; expTime?: numberInString; args: TRequestParams[]; } ⋮---- export interface WSAPIResponse< TResponseData extends object = object, TOperation extends WSAPIOperation = WSAPIOperation, > { wsKey: WsKey; id: numberInString; op: TOperation; code: numberInString; msg: string; data: TResponseData; inTime: numberInString; outTime: numberInString; } ⋮---- export interface WSOperationLoginParams { apiKey: string; passphrase: string; timestamp: number; sign: string; } ⋮---- export type Exact = { // This part says: if there's any key that's not in T, it's an error [K: string]: never; } & { [K in keyof T]: T[K]; }; ⋮---- // This part says: if there's any key that's not in T, it's an error ⋮---- /** * List of operations supported for this WsKey (connection) */ export interface WsAPIWsKeyTopicMap { // Global [WS_KEY_MAP.prodPrivate]: WSAPIPrivateOperations; [WS_KEY_MAP.prodDemoPrivate]: WSAPIPrivateOperations; [WS_KEY_MAP.prodBusiness]: WSAPIBusinessOperations; [WS_KEY_MAP.prodDemoBusiness]: WSAPIBusinessOperations; // [WS_KEY_MAP.prodPublic]: never; // [WS_KEY_MAP.prodDemoPublic]: never; // EEA [WS_KEY_MAP.eeaLivePrivate]: WSAPIPrivateOperations; [WS_KEY_MAP.eeaDemoPrivate]: WSAPIPrivateOperations; // [WS_KEY_MAP.eeaLiveBusiness]: never; // [WS_KEY_MAP.eeaDemoBusiness]: never; // [WS_KEY_MAP.eeaLivePublic]: never; // [WS_KEY_MAP.eeaDemoPublic]: never; // US [WS_KEY_MAP.usLivePrivate]: WSAPIPrivateOperations; [WS_KEY_MAP.usDemoPrivate]: WSAPIPrivateOperations; // [WS_KEY_MAP.usLiveBusiness]: never; // [WS_KEY_MAP.usDemoBusiness]: never; // [WS_KEY_MAP.usLivePublic]: never; // [WS_KEY_MAP.usDemoPublic]: never; } ⋮---- // Global ⋮---- // [WS_KEY_MAP.prodPublic]: never; // [WS_KEY_MAP.prodDemoPublic]: never; ⋮---- // EEA ⋮---- // [WS_KEY_MAP.eeaLiveBusiness]: never; // [WS_KEY_MAP.eeaDemoBusiness]: never; ⋮---- // [WS_KEY_MAP.eeaLivePublic]: never; // [WS_KEY_MAP.eeaDemoPublic]: never; ⋮---- // US ⋮---- // [WS_KEY_MAP.usLiveBusiness]: never; // [WS_KEY_MAP.usDemoBusiness]: never; ⋮---- // [WS_KEY_MAP.usLivePublic]: never; // [WS_KEY_MAP.usDemoPublic]: never; ⋮---- /** * Request parameters expected per operation */ export interface WsAPITopicRequestParamMap { // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order order: WSAPIPlaceOrderRequestV5; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-multiple-orders 'batch-orders': WSAPIPlaceOrderRequestV5[]; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-order 'cancel-order': OrderIdRequest; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-multiple-orders 'batch-cancel-orders': OrderIdRequest[]; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-order 'amend-order': WSAPIAmendOrderRequestV5; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-multiple-orders 'batch-amend-orders': WSAPIAmendOrderRequestV5[]; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-mass-cancel-order 'mass-cancel': WSAPIMassCancelOrdersRequestV5; // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-place-order 'sprd-order': WSAPIPlaceSpreadOrderRequestV5; // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-amend-order 'sprd-amend-order': WSAPIAmendSpreadOrderRequestV5; // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-order 'sprd-cancel-order': WSAPICancelSpreadOrderRequestV5; // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-all-orders 'sprd-mass-cancel': WSAPISpreadMassCancelOrdersRequestV5; } ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-multiple-orders ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-order ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-multiple-orders ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-order ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-multiple-orders ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-mass-cancel-order ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-place-order ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-amend-order ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-order ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-all-orders ⋮---- /** * Response structure expected for each operation */ export interface WsAPIOperationResponseMap { // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order order: WSAPIResponse<[OrderResult], 'order'>; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-multiple-orders 'batch-orders': WSAPIResponse; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-order 'cancel-order': WSAPIResponse<[WSAPICancelOrderResultV5], 'cancel-order'>; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-multiple-orders 'batch-cancel-orders': WSAPIResponse< WSAPICancelOrderResultV5[], 'batch-cancel-orders' >; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-order 'amend-order': WSAPIResponse<[OrderResult], 'amend-order'>; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-multiple-orders 'batch-amend-orders': WSAPIResponse<[OrderResult], 'batch-amend-orders'>; // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-mass-cancel-order 'mass-cancel': WSAPIResponse<[{ result: boolean }], 'mass-cancel'>; // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-place-order 'sprd-order': WSAPIResponse<[WSAPISpreadPlaceOrderResultV5], 'sprd-order'>; // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-amend-order 'sprd-amend-order': WSAPIResponse< [WSAPISpreadAmendOrderResultV5], 'sprd-amend-order' >; // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-order 'sprd-cancel-order': WSAPIResponse< [WSAPISpreadCancelOrderResultV5], 'sprd-cancel-order' >; // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-all-orders 'sprd-mass-cancel': WSAPIResponse<[{ result: boolean }], 'sprd-mass-cancel'>; } ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-multiple-orders ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-order ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-multiple-orders ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-order ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-multiple-orders ⋮---- // https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-mass-cancel-order ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-place-order ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-amend-order ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-order ⋮---- // https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-all-orders ================ File: src/websocket-api-client.ts ================ import { OrderIdRequest } from './types/rest/request/trade.js'; import { OrderResult } from './types/rest/response/private-trade.js'; import { WSAPIResponse } from './types/websockets/ws-api.js'; import { WSAPIAmendOrderRequestV5, WSAPIAmendSpreadOrderRequestV5, WSAPICancelSpreadOrderRequestV5, WSAPIMassCancelOrdersRequestV5, WSAPIPlaceOrderRequestV5, WSAPIPlaceSpreadOrderRequestV5, WSAPISpreadMassCancelOrdersRequestV5, } from './types/websockets/ws-api-request.js'; import { WSAPICancelOrderResultV5, WSAPISpreadAmendOrderResultV5, WSAPISpreadCancelOrderResultV5, WSAPISpreadPlaceOrderResultV5, } from './types/websockets/ws-api-response.js'; import { WSClientConfigurableOptions } from './types/websockets/ws-general.js'; import { DefaultLogger } from './util/logger.js'; import { WebsocketClient } from './websocket-client.js'; ⋮---- /** * Configurable options specific to only the REST-like WebsocketAPIClient */ export interface WSAPIClientConfigurableOptions { /** * Default: true * * Attach default event listeners, which will console log any high level * events (opened/reconnecting/reconnected/etc). * * If you disable this, you should set your own event listeners * on the embedded WS Client `wsApiClient.getWSClient().on(....)`. */ attachEventListeners: boolean; } ⋮---- /** * Default: true * * Attach default event listeners, which will console log any high level * events (opened/reconnecting/reconnected/etc). * * If you disable this, you should set your own event listeners * on the embedded WS Client `wsApiClient.getWSClient().on(....)`. */ ⋮---- /** * This is a minimal Websocket API wrapper around the WebsocketClient. It allows you to use the WebSocket API in a promise-driven way, send a request and await the response. * * Note: You can also directly use the sendWSAPIRequest() method to make WS API calls, but some * may find the below methods slightly more intuitive. * * Refer to the WS API promises example for a more detailed example on using sendWSAPIRequest() directly: * https://github.com/tiagosiebler/okx-api/blob/master/examples/ws-api-trade-raw.ts */ export class WebsocketAPIClient ⋮---- constructor( options?: WSClientConfigurableOptions & Partial, logger?: DefaultLogger, ) ⋮---- public getWSClient(): WebsocketClient ⋮---- public setTimeOffsetMs(newOffset: number): void ⋮---- /** * * * OKX WebSocket API Methods * * */ ⋮---- /** * Submit a new order * * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order */ submitNewOrder( params: WSAPIPlaceOrderRequestV5, ): Promise> ⋮---- /** * Submit multiple orders in a batch * * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-multiple-orders */ submitMultipleOrders( params: WSAPIPlaceOrderRequestV5[], ): Promise> ⋮---- /** * Cancel a single order * * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-order */ cancelOrder( params: OrderIdRequest, ): Promise> ⋮---- /** * Cancel multiple orders * * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-cancel-multiple-orders */ cancelMultipleOrders( params: OrderIdRequest[], ): Promise> ⋮---- /** * Amend a single order * * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-order */ amendOrder( params: WSAPIAmendOrderRequestV5, ): Promise> ⋮---- /** * Amend multiple orders * * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-multiple-orders */ amendMultipleOrders( params: WSAPIAmendOrderRequestV5[], ): Promise> ⋮---- /** * Mass cancel orders * * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-mass-cancel-order */ massCancelOrders( params: WSAPIMassCancelOrdersRequestV5, ): Promise> ⋮---- /** * Amend a spread order * * https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-amend-order */ amendSpreadOrder( params: WSAPIAmendSpreadOrderRequestV5, ): Promise< WSAPIResponse<[WSAPISpreadAmendOrderResultV5], 'sprd-amend-order'> > { return this.wsClient.sendWSAPIRequest( this.getWSClient().getMarketWsKey('business'), 'sprd-amend-order', params, ); ⋮---- /** * Cancel a spread order * * https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-order */ cancelSpreadOrder( params: WSAPICancelSpreadOrderRequestV5, ): Promise< WSAPIResponse<[WSAPISpreadCancelOrderResultV5], 'sprd-cancel-order'> > { return this.wsClient.sendWSAPIRequest( this.getWSClient().getMarketWsKey('business'), 'sprd-cancel-order', params, ); ⋮---- /** * Mass cancel spread orders * * https://www.okx.com/docs-v5/en/#spread-trading-websocket-trade-api-ws-cancel-all-orders */ massCancelSpreadOrders( params: WSAPISpreadMassCancelOrdersRequestV5, ): Promise>( event: U, listener: WSClientEventMap[U], ): this; emit>( event: U, ...args: Parameters[U]> ): boolean; } ⋮---- on>( event: U, listener: WSClientEventMap[U], ): this; ⋮---- emit>( event: U, ...args: Parameters[U]> ): boolean; ⋮---- /** * @deprecated This is the old WebsocketClient that was part of the SDK prior to the V3 release. This legacy WebsocketClient is temporarily included but will be removed with the next major release. */ export class WebsocketClientLegacy extends EventEmitter ⋮---- constructor(options: WSClientConfigurableOptions, logger?: DefaultLogger) ⋮---- // Automatically send an authentication op/request after a connection opens, for private connections. ⋮---- // Individual requests do not require a signature, so this is disabled. ⋮---- /** * Subscribe to topics & track/persist them. They will be automatically resubscribed to if the connection drops/reconnects. * @param wsEvents topic or list of topics * @param isPrivateTopic optional - the library will try to detect private topics, you can use this to mark a topic as private (if the topic isn't recognised yet) */ public subscribe( wsEvents: WsChannelSubUnSubRequestArg[] | WsChannelSubUnSubRequestArg, isPrivateTopic?: boolean, ) ⋮---- // Persist topic for reconnects ⋮---- // if connected, send subscription request ⋮---- // start connection process if it hasn't yet begun. Topics are automatically subscribed to on-connect ⋮---- /** * Unsubscribe from topics & remove them from memory. They won't be re-subscribed to if the connection reconnects. * @param wsTopics topic or list of topics * @param isPrivateTopic optional - the library will try to detect private topics, you can use this to mark a topic as private (if the topic isn't recognised yet) */ public unsubscribe( wsTopics: WsChannelSubUnSubRequestArg[] | WsChannelSubUnSubRequestArg, isPrivateTopic?: boolean, ) ⋮---- // Remove topic from persistence for reconnects ⋮---- // unsubscribe request only necessary if active connection exists ⋮---- /** Get the WsStore that tracks websocket & topic state */ public getWsStore(): WsStore ⋮---- public close(wsKey: WsKey, force?: boolean) ⋮---- public closeAll(force?: boolean) ⋮---- /** * Request connection of all dependent (public & private) websockets, instead of waiting for automatic connection by library */ public connectAll(): Promise[] ⋮---- public connectPublic( businessEndpoint?: boolean, ): Promise ⋮---- public connectPrivate( businessEndpoint?: boolean, ): Promise ⋮---- private async connect(wsKey: WsKey): Promise ⋮---- private parseWsError(context: string, error: any, wsKey: WsKey) ⋮---- /** * Return params required to make authorized request */ private async getWsAuthRequest( wsKey: WsKey, ): Promise | undefined> ⋮---- // Filter out failed accounts ⋮---- private async getWsAuthSignature( wsKey: WsKey, credentials: APICredentials, ): Promise< ⋮---- // const signatureExpiresAt = timestamp + 5; ⋮---- private async sendAuthRequest(wsKey: WsKey): Promise ⋮---- private reconnectWithDelay(wsKey: WsKey, connectionDelayMs: number) ⋮---- private ping(wsKey: WsKey) ⋮---- /** * Closes a connection, if it's even open. If open, this will trigger a reconnect asynchronously. * If closed, trigger a reconnect immediately. */ private executeReconnectableClose(wsKey: WsKey, reason: string) ⋮---- private clearTimers(wsKey: WsKey) ⋮---- // Send a ping at intervals private clearPingTimer(wsKey: WsKey) ⋮---- // Expect a pong within a time limit private clearPongTimer(wsKey: WsKey) ⋮---- private clearReconnectTimer(wsKey: WsKey) ⋮---- /** * @private Use the `subscribe(topics)` method to subscribe to topics. Send WS message to subscribe to topics. */ private requestSubscribeTopics( wsKey: WsKey, topics: WsChannelSubUnSubRequestArg[], ) ⋮---- /** * @private Use the `unsubscribe(topics)` method to unsubscribe from topics. Send WS message to unsubscribe from topics. */ private requestUnsubscribeTopics( wsKey: WsKey, topics: WsChannelSubUnSubRequestArg[], ) ⋮---- public tryWsSend(wsKey: WsKey, wsMessage: string): void ⋮---- private connectToWsUrl(url: string, wsKey: WsKey): WebSocket ⋮---- private async onWsOpen( event: WebSocket.Event, wsKey: WsKey, url: string, ws: WebSocket, ) ⋮---- // Private websockets require an auth packet to be sent after opening the connection ⋮---- // Any requested private topics will be subscribed to once authentication succeeds (in onWsMessage handler) ⋮---- // Private topics will be subscribed to once authentication is confirmed as successful ⋮---- // Public topics can be subscribed to immediately ⋮---- // Since public channels have their own ws key, these topics must be public ones already ⋮---- private onWsMessage(event: any, wsKey: WsKey, _ws: WebSocket) ⋮---- // any message can clear the pong timer - wouldn't get a message if the ws dropped ⋮---- // Successfully authenticated ⋮---- // Since private topics have a dedicated WsKey, these are automatically all private topics (no filtering required before the subscribe call) ⋮---- // this.logger.trace(`Ws subscribe reply:`, { ...msg, wsKey }); ⋮---- private onWsClose(event: any, wsKey: WsKey) ================ File: README.md ================ # Node.js & Typescript OKX (OKEX) API & WebSocket SDK [![E2E Tests](https://github.com/tiagosiebler/okx-api/actions/workflows/e2etest.yml/badge.svg?branch=master)](https://github.com/tiagosiebler/okx-api/actions/workflows/e2etest.yml) [![npm downloads](https://img.shields.io/npm/dt/okx-api)][1] [![npm version](https://img.shields.io/npm/v/okx-api)][1] [![npm size](https://img.shields.io/bundlephobia/min/okx-api/latest)][1] [![last commit](https://img.shields.io/github/last-commit/tiagosiebler/okx-api)][1] [![CodeFactor](https://www.codefactor.io/repository/github/tiagosiebler/okx-api/badge)](https://www.codefactor.io/repository/github/tiagosiebler/okx-api)

SDK Logo

[1]: https://www.npmjs.com/package/okx-api Complete, updated & performant Node.js SDK for the OKX(OKEX) APIs and WebSockets: - Complete integration with OKX REST APIs, WebSockets & WebSocket APIs. - TypeScript support (with type declarations for most API requests & responses). - Over 100 end-to-end tests making real API calls & WebSocket connections, validating any changes before they reach npm. - Supports all available OKX regions: - OKX Global (www.okx.com), by default. - OKX EEA (my.okx.com), by setting `market: 'EEA'`. - OKX US (app.okx.com), by setting `market: 'US'`. - Actively maintained with a modern, promise-driven interface. - Robust WebSocket integration - Configurable connection heartbeats (automatically detect failing connections). - Automatic reconnect then resubscribe workflows. - Automatic authentication and heartbeat handling. - Supports WebSocket API in all supported regions & product groups: - Use the WebsocketClient's event-driven `sendWSAPIRequest()` method, or; - Use the WebsocketAPIClient for a REST-like experience. - Use the WebSocket API like a REST API! - Automatic routing to business vs private WebSocket endpoints. - End to end types. - See [examples/ws-api-client.ts](./examples/ws-api-client.ts) for a demonstration. - Browser support (via webpack bundle - see "Browser Usage" below). ## Table of Contents - [Installation](#installation) - [Issues & Discussion](#issues--discussion) - [Related Projects](#related-projects) - [Documentation](#documentation) - [Contributions & Thanks](#contributions--thanks) - [Structure](#structure) - [Usage](#usage) - [REST Client](#rest-client) - [Requests & Responses](#requests--responses) - [Example](#example) - [WebSockets](#websockets) - [Sending Orders via WebSockets](#sending-orders-via-websockets) - [Receiving Realtime Data](#receiving-realtime-data) - [Public Events](#public-events) - [Private Events](#private-events) - [Browser/Frontend Usage](#browserfrontend-usage) - [Import](#import) - [Webpack](#webpack) - [Use with LLMs & AI](#use-with-llms--ai) - [Contributions & Pull Requests](#contributions--pull-requests) - [Used By](#used-by) - [Star History](#star-history) ## Installation ```bash npm install okx-api ``` ## Issues & Discussion - Issues? Check the [issues tab](https://github.com/tiagosiebler/okx-api/issues). - Discuss & collaborate with other node devs? Join our [Node.js Algo Traders](https://t.me/nodetraders) engineering community on telegram. - Follow our announcement channel for real-time updates on [X/Twitter](https://x.com/sieblyio) ## Related Projects Check out my related JavaScript/TypeScript/Node.js projects: - Try our REST API & WebSocket SDKs published on npmjs: - [Bybit Node.js SDK: bybit-api](https://www.npmjs.com/package/bybit-api) - [OKX/OKEX Node.js SDK: okx-api](https://www.npmjs.com/package/okx-api) - [Binance Node.js SDK: binance](https://www.npmjs.com/package/binance) - [Gate (gate.com) Node.js SDK: gateio-api](https://www.npmjs.com/package/gateio-api) - [Bitget Node.js SDK: bitget-api](https://www.npmjs.com/package/bitget-api) - [Kucoin Node.js SDK: kucoin-api](https://www.npmjs.com/package/kucoin-api) - [Kraken Node.js SDK: @siebly/kraken-api](https://www.npmjs.com/package/coinbase-api) - [Coinbase Node.js SDK: coinbase-api](https://www.npmjs.com/package/coinbase-api) - [Bitmart Node.js SDK: bitmart-api](https://www.npmjs.com/package/bitmart-api) - Try my misc utilities: - [OrderBooks Node.js: orderbooks](https://www.npmjs.com/package/orderbooks) - [Crypto Exchange Account State Cache: accountstate](https://www.npmjs.com/package/accountstate) - Check out my examples: - [awesome-crypto-examples Node.js](https://github.com/tiagosiebler/awesome-crypto-examples) ## Documentation Most methods accept JS objects. These can be populated using parameters specified by okx's API documentation, or check the type definition in the rest-client class methods. - [RestClient](src/rest-client.ts) - [OKX API Documentation](https://www.okx.com/docs-v5/en/#rest-api) - [REST Endpoint Function List](./docs/endpointFunctionList.md) ## Contributions & Thanks Support my efforts to make algo trading accessible to all - register with my referral links: - [Bybit](https://www.bybit.com/en-US/register?affiliate_id=9410&language=en-US&group_id=0&group_type=1) - [Binance](https://www.binance.com/en/register?ref=20983262) - [OKX](https://www.okx.com/join/18504944) For more ways to give thanks & support my efforts, visit [Contributions & Thanks](https://github.com/tiagosiebler/awesome-crypto-examples/wiki/Contributions-&-Thanks)! ## Structure This project uses typescript. Resources are stored in 3 key structures: - [src](./src) - the whole connector written in typescript - [lib](./lib) - the javascript version of the project (compiled from typescript). This should not be edited directly, as it will be overwritten with each release. This is also the version published to npm. - [dist](./dist) - the packed bundle of the project for use in browser environments (manual, using webpack). - [examples](./examples) - some implementation examples & demonstrations. Contributions are welcome! --- ## Usage Create API credentials at okx - [OKX/account/API](https://www.okx.com/account/my-api) ## REST Client ### Requests & Responses - If your IDE doesn't have IntelliSense, check the [rest-client.ts](./src/rest-client.ts) for a list of methods, params & return types. - Requests follow the same ordering and format as the categories in the [API docs](https://www.okx.com/docs-v5/en/#rest-api). - Responses are parsed automatically for less nesting. Error responses are thrown in full: - If the response looks successful (HTTP 200 and "code" in the response body === "0"), only the `data` property is directly (without the `code`, `data` & `msg` properties). - If the response looks like an error (HTTP error OR the "code" property in the response does not equal "0"), the full response is thrown (including `code` and `msg` properties). See the interface for [APIResponse](./src/types/rest/shared.ts). ### Example ```ts import { RestClient } from 'okx-api'; const client = new RestClient({ apiKey: 'apiKeyHere', apiSecret: 'apiSecretHere', apiPass: 'apiPassHere', // For Global users (www.okx.com), you don't need to set the market. // It will use global by default. // Not needed: market: 'GLOBAL', // For EEA users (my.okx.com), set market to "EEA": // market: 'EEA', // For US users (app.okx.com), set market to "US": // market: 'US', }); // Submit a buy and sell market order (async () => { try { const allBalances = await client.getBalance(); console.log('All balances: ', allBalances); const buyResult = await client.submitOrder({ instId: 'BTC-USDT', ordType: 'market', side: 'buy', sz: '0.1', tdMode: 'cash', tgtCcy: 'base_ccy', }); console.log('buy order result: ', buyResult); const sellResult = await client.submitOrder({ instId: 'BTC-USDT', ordType: 'market', side: 'sell', sz: '0.1', tdMode: 'cash', tgtCcy: 'base_ccy', }); console.log('Sell order result: ', sellResult); } catch (e) { console.error('request failed: ', e); } })(); ``` ## WebSockets This connector includes a high-performance Node.js, TypeScript & JavaScript WebSocket client for the OKX public & private WebSocket, including the OKX WebSocket API for order placement. API credentials are optional unless private streams will be used (such as account order updates). - If your IDE doesn't have IntelliSense, check the [websocket-client.ts](./src/websocket-client.ts) for a list of methods, params & return types. - When subscribing to channels, only the "args" should be passed as an object or array when calling the websocket client subcribe() function: [API docs](https://www.okx.com/docs-v5/en/#websocket-api-subscribe). - TypeScript recommended (but it is not required) for a richer experience: ![typescript-subscribe](./docs/images/subscribe-with-typescript.gif) - The ws client will automatically open connections as needed when subscribing to a channel. - If the connection is lost for any reason, the ws client will detect this (via the connection heartbeats). It will then: - Automatically teardown the dead connection. - Automatically respawn a fresh connection. - Automatically reauthenticate, if using private channels. - Automatically resubscribe to previously subscribed topics. - Resume producing events as before, without extra handling needed in your logic. - The ws client will automatically authenticate if accounts are provided and a private channel is subscribed to. - Up to 100 accounts are supported on the private connection, as per the [API docs](https://www.okx.com/docs-v5/en/#websocket-api-login). Authentication is automatic if accounts are provided. - For examples in using the websocket client, check the examples in the repo: - Private channels (account data): [examples/ws-private.ts](./examples/ws-private.ts) - Public chanels (market data): [examples/ws-public.ts](./examples/ws-public.ts) - These examples are written in TypeScript, so can be executed with ts-node for easy testing: `ts-node examples/ws-private.ts` - Or convert them to javascript: - Change the `import { ... } from 'okx-api'` to `const { ... } = require('okx-api');` - Rename the file to `ws-private.js` - And execute with node: `node examples/ws-private.js` ### Sending orders via WebSockets OKX supports some order management capabilities via a persisted WebSocket connection. This SDK supports this with two convenient approaches. The recommended route is to use the dedicated WebsocketAPIClient class, included with this SDK: - Dedicated functions for every available WebSocket API operation - Fully typed requests and responses - Asynchronous promisified wrapper around WS API commands. It looks & feels like a REST API client, but uses WebSockets, via the WebsocketClient's sendWSAPIRequest method (which you can use directly if you prefer). A simple example is below but for a more thorough example, check the example here: [./examples/ws-api-client.ts](./examples/ws-api-client.ts). ```typescript import { WebsocketAPIClient } from 'okx-api'; // or if you prefer require: // const { WebsocketAPIClient } = require("okx-api"); // For private events, all 3 of the following are required (per account): const API_KEY = process.env.API_KEY_COM; const API_SECRET = process.env.API_SECRET_COM; const API_PASSPHRASE = process.env.API_PASSPHRASE_COM; // If running from CLI in unix, you can pass env vars as such: // API_KEY_COM='lkm12n3-2ba3-1mxf-fn13-lkm12n3a' API_SECRET_COM='035B2B9637E1BDFFEE2646BFBDDB8CE4' API_PASSPHRASE_COM='ComplexPa$$!23$5^' ts-node examples/ws-private.ts const wsClient = new WebsocketAPIClient({ // For Global users (www.okx.com), you don't need to set the market. // It will use global by default. // Not needed: market: 'GLOBAL', // For EEA users (my.okx.com), set market to "EEA": // market: 'EEA', // For US users (app.okx.com), set market to "US": // market: 'US', accounts: [ { apiKey: API_KEY, apiSecret: API_SECRET, apiPass: API_PASSPHRASE, }, ], }); async function start() { // Optional: prepare the WebSocket API connection in advance. // This happens automatically but you can do this early before making any API calls, to prevent delays from a cold start. // await wsClient.connectWSAPI(); /** * OKX's WebSocket API be used like a REST API, through this SDK's WebsocketAPIClient. The WebsocketAPIClient is a utility class wrapped around WebsocketClient's sendWSAPIRequest() capabilities. * * Each request sent via the WebsocketAPIClient will automatically: * - route via the active WS API connection * - return a Promise, which automatically resolves/rejects when a matching response is received */ /** * Place Order * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order */ try { const res = await wsClient.submitNewOrder({ instId: 'BTC-USDT', tdMode: 'cash', side: 'buy', ordType: 'market', sz: '100', }); /** const res = { id: '2', op: 'order', code: '1', msg: '', data: [ { tag: '159881cb7207BCDE', ts: '1753714603721', ordId: '', clOrdId: '', sCode: '51008', sMsg: 'Order failed. Insufficient USDT balance in account.' } ], inTime: '1753714603720755', outTime: '1753714603721942', wsKey: 'prodPrivate', isWSAPIResponse: false } const res = { id: '2', op: 'order', code: '1', msg: '', data: [ { tag: '159881cb7207BCDE', ts: '1753714567149', ordId: '', clOrdId: '', sCode: '51010', sMsg: "You can't complete this request under your current account mode." } ], inTime: '1753714567149196', outTime: '1753714567149913', wsKey: 'prodPrivate', isWSAPIResponse: false } */ console.log(new Date(), 'WS API "submitNewOrder()" result: ', res); } catch (e) { console.error(new Date(), 'Exception with WS API "submitNewOrder()": ', e); } /** * Submit multiple orders in a batch * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-multiple-orders */ try { const res = await wsClient.submitMultipleOrders([ { instId: 'BTC-USDT', tdMode: 'cash', side: 'buy', ordType: 'market', sz: '100', }, { instId: 'BTC-USDT', tdMode: 'cash', side: 'buy', ordType: 'market', sz: '50', }, ]); console.log(new Date(), 'WS API "submitMultipleOrders()" result: ', res); } catch (e) { console.error( new Date(), 'Exception with WS API "submitMultipleOrders()": ', e, ); } } start(); ``` ### Receiving realtime data The below example demonstrates connecting as a consumer, to receive WebSocket events from OKX, using the included WebsocketClient: ```javascript import { WebsocketClient } from 'okx-api'; // or if you prefer require: // const { WebsocketClient } = require("okx-api"); // For private events, all 3 of the following are required (per account): const API_KEY = process.env.API_KEY_COM; const API_SECRET = process.env.API_SECRET_COM; const API_PASSPHRASE = process.env.API_PASSPHRASE_COM; // If running from CLI in unix, you can pass env vars as such: // API_KEY_COM='lkm12n3-2ba3-1mxf-fn13-lkm12n3a' API_SECRET_COM='035B2B9637E1BDFFEE2646BFBDDB8CE4' API_PASSPHRASE_COM='ComplexPa$$!23$5^' ts-node examples/ws-private.ts // Note the single quotes, preventing special characters such as $ from being incorrectly passed const wsClient = new WebsocketClient({ // For Global users (www.okx.com), you don't need to set the market. // It will use global by default. // Not needed: market: 'GLOBAL', // For EEA users (my.okx.com), set market to "EEA": // market: 'EEA', // For US users (app.okx.com), set market to "US": // market: 'US', accounts: [ // For private topics, include one or more accounts in an array. Otherwise only public topics will work { apiKey: API_KEY, apiSecret: API_SECRET, apiPass: API_PASSPHRASE, }, // { // apiKey: 'yourApiKeyHere', // apiSecret: 'yourApiSecretHere', // apiPass: 'yourApiPassHere', // }, // { // apiKey: 'anotherAccountKey', // apiSecret: 'anotherAccountSecret', // apiPass: 'anotherAccountPass', // }, ], }); // Raw data will arrive on the 'update' event wsClient.on('update', (data) => { console.log('ws update (raw data received)', JSON.stringify(data)); }); wsClient.on('open', (data) => { console.log('connection opened open:', data.wsKey); }); // Replies (e.g. authenticating or subscribing to channels) will arrive on the 'response' event wsClient.on('response', (data) => { // console.log('ws response: ', JSON.stringify(data, null, 2)); console.log('ws response: ', JSON.stringify(data)); }); wsClient.on('reconnect', ({ wsKey }) => { console.log('ws automatically reconnecting.... ', wsKey); }); wsClient.on('reconnected', (data) => { console.log('ws has reconnected ', data?.wsKey); }); wsClient.on('exception', (data) => { console.error('ws exception: ', data); }); /** * Simply call subscribe to request the channels that you're interested in. * * If authentication is required, the WSClient will automatically authenticate with the available credentials. */ // Subscribe one event at a time: wsClient.subscribe({ channel: 'account', }); // OR, combine multiple subscription events into one request using an array instead of an object: wsClient.subscribe([ { channel: 'account', }, { channel: 'positions', instType: 'ANY', }, ]); // Public topics, for comparison. These do not require authentication / api keys: wsClient.subscribe([ { channel: 'instruments', instType: 'SPOT', }, { channel: 'instruments', instType: 'FUTURES', }, { channel: 'tickers', instId: 'LTC-BTC', }, ]); ``` #### Public Events See [examples/ws-public.ts](./examples/ws-public.ts) for a full example: ![typescript-events-public](./docs/images/subscribe-events-public.gif) #### Private Events See [examples/ws-private.ts](./examples/ws-private.ts) for a full example: ![typescript-events](./docs/images/subscribe-events.gif) ## Browser/Frontend Usage ### Import This is the "modern" way, allowing the package to be directly imported into frontend projects with full typescript support. 1. Install these dependencies ```sh npm install crypto-browserify stream-browserify ``` 2. Add this to your `tsconfig.json` ```json { "compilerOptions": { "paths": { "crypto": [ "./node_modules/crypto-browserify" ], "stream": [ "./node_modules/stream-browserify" ] } ``` 3. Declare this in the global context of your application (ex: in polyfills for angular) ```js (window as any).global = window; ``` ### Webpack This is the "old" way of using this package on webpages. This will build a minified js bundle that can be pulled in using a script tag on a website. Build a bundle using webpack: - `npm install` - `npm build` - `npm pack` The bundle can be found in `dist/`. Altough usage should be largely consistent, smaller differences will exist. Documentation is still TODO. ## Use with LLMs & AI This SDK includes a bundled `llms.txt` file in the root of the repository. If you're developing with LLMs, use the included `llms.txt` with your LLM - it will significantly improve the LLMs understanding of how to correctly use this SDK. This file contains AI optimised structure of all the functions in this package, and their parameters for easier use with any learning models or artificial intelligence. --- ### Contributions & Thanks Have my projects helped you? Share the love, there are many ways you can show your thanks: - Star & share my projects. - Are my projects useful? Sponsor me on Github and support my effort to maintain & improve them: https://github.com/sponsors/tiagosiebler - Have an interesting project? Get in touch & invite me to it. - Or buy me all the coffee: - ETH(ERC20): `0xA3Bda8BecaB4DCdA539Dc16F9C54a592553Be06C` - Sign up with my referral links: - OKX (receive a 20% fee discount!): https://www.okx.com/join/42013004 - Binance (receive a 20% fee discount!): https://accounts.binance.com/register?ref=OKFFGIJJ - HyperLiquid (receive a 4% fee discount!): https://app.hyperliquid.xyz/join/SDK - Gate: https://www.gate.io/signup/NODESDKS?ref_type=103 ## Contributions & Pull Requests Contributions are encouraged, I will review any incoming pull requests. See the issues tab for todo items. ## Used By The following represents some of the known public projects that use this SDK on GitHub: [![Repository Users Preview Image](https://dependents.info/tiagosiebler/okx-api/image)](https://github.com/tiagosiebler/okx-api/network/dependents) ## Star History [![Star History Chart](https://api.star-history.com/svg?repos=tiagosiebler/bybit-api,tiagosiebler/okx-api,tiagosiebler/binance,tiagosiebler/bitget-api,tiagosiebler/bitmart-api,tiagosiebler/gateio-api,tiagosiebler/kucoin-api,tiagosiebler/coinbase-api,tiagosiebler/orderbooks,tiagosiebler/accountstate,tiagosiebler/awesome-crypto-examples&type=Date)](https://star-history.com/#tiagosiebler/bybit-api&tiagosiebler/okx-api&tiagosiebler/binance&tiagosiebler/bitget-api&tiagosiebler/bitmart-api&tiagosiebler/gateio-api&tiagosiebler/kucoin-api&tiagosiebler/coinbase-api&tiagosiebler/orderbooks&tiagosiebler/accountstate&tiagosiebler/awesome-crypto-examples&Date) ================ File: src/websocket-client.ts ================ /* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */ ⋮---- import { APICredentials } from './types/shared.js'; import { WsAPIOperationResponseMap, WSAPIRequestFlags, WSAPIRequestOKX, WsAPITopicRequestParamMap, WsAPIWsKeyTopicMap, WsAuthRequest, WSOperation, WsRequestOperationOKX, } from './types/websockets/ws-api.js'; import { MessageEventLike, WsDataEvent } from './types/websockets/ws-events.js'; import { WSClientConfigurableOptions } from './types/websockets/ws-general.js'; import { WsAuthRequestArg, WsChannelSubUnSubRequestArg, } from './types/websockets/ws-request.js'; import { BaseWebsocketClient, EmittableEvent, MidflightWsRequestEvent, WSClientEventMap, } from './util/BaseWSClient.js'; import { DefaultLogger } from './util/logger.js'; import { isConnCountEvent, isWSAPIResponse, isWsDataEvent, isWsErrorEvent, isWsLoginEvent, isWsSubscribeEvent, isWsUnsubscribeEvent, neverGuard, } from './util/typeGuards.js'; import { SignAlgorithm, SignEncodeMethod, signMessage, } from './util/webCryptoAPI.js'; import { getDemoWsKey, getPromiseRefForWSAPIRequest, getWsKeyForMarket, getWsKeyForTopicChannel, getWsUrlForWsKey, isWsPong, PRIVATE_WS_KEYS, PUBLIC_WS_KEYS, requiresWSAPITag, validateWSAPITag, WS_EVENT_CODE_ENUM, WS_KEY_MAP, WS_LOGGER_CATEGORY, WsKey, WsTopicRequest, } from './util/websocket-util.js'; import { WSConnectedResult } from './util/WsStore.types.js'; ⋮---- // Type safety for on and emit handlers: https://stackoverflow.com/a/61609010/880837 export declare interface WebsocketClient { on>( event: U, listener: WSClientEventMap[U], ): this; emit>( event: U, ...args: Parameters[U]> ): boolean; } ⋮---- on>( event: U, listener: WSClientEventMap[U], ): this; ⋮---- emit>( event: U, ...args: Parameters[U]> ): boolean; ⋮---- export class WebsocketClient extends BaseWebsocketClient< ⋮---- constructor(options?: WSClientConfigurableOptions, logger?: DefaultLogger) ⋮---- /** * Request connection of all dependent (public & private) websockets, instead of waiting for automatic connection by library */ public connectAll(): Promise[] ⋮---- public connectPublic( businessEndpoint?: boolean, ): Promise ⋮---- public connectPrivate( businessEndpoint?: boolean, ): Promise ⋮---- /** * Ensures the WS API connection is active and ready. * * You do not need to call this, but if you call this before making any WS API requests, * it can accelerate the first request (by preparing the connection in advance). */ public connectWSAPI(): Promise ⋮---- /** This call automatically ensures the connection is active AND authenticated before resolving */ ⋮---- /** * Subscribe to topics & track/persist them. They will be automatically resubscribed to if the connection drops/reconnects. * @param wsEvents topic or list of topics * @param isPrivateTopic optional - the library will try to detect private topics, you can use this to mark a topic as private (if the topic isn't recognised yet) */ public subscribe( wsEvents: WsChannelSubUnSubRequestArg[] | WsChannelSubUnSubRequestArg, isPrivateTopic?: boolean, ): Promise[] ⋮---- // Format and batch topic requests by WsKey (resolved dynamically) ⋮---- // Arrange into per-wsKey sorted lists ⋮---- /** * Unsubscribe from topics & remove them from memory. They won't be re-subscribed to if the connection reconnects. * @param wsTopics topic or list of topics * @param isPrivateTopic optional - the library will try to detect private topics, you can use this to mark a topic as private (if the topic isn't recognised yet) */ public unsubscribe( wsEvents: WsChannelSubUnSubRequestArg[] | WsChannelSubUnSubRequestArg, isPrivateTopic?: boolean, ) ⋮---- // Format and batch topic requests by WsKey (resolved dynamically) ⋮---- // Arrange into per-wsKey sorted lists ⋮---- /** * * * Internal methods required to integrate with the BaseWSClient * * */ ⋮---- public getMarketWsKey(type: 'private' | 'business'): WsKey ⋮---- // returns private or business ws key for the active api market // defaults to global // automatically resolves to demo trading wsKeys under the hood (WSClient) ⋮---- protected sendPingEvent(wsKey: WsKey): void ⋮---- protected sendPongEvent(wsKey: WsKey): void ⋮---- protected isWsPing(data: any): boolean ⋮---- protected isWsPong(data: any): boolean ⋮---- protected isPrivateTopicRequest( _request: WsTopicRequest, wsKey: WsKey, ): boolean ⋮---- protected getPrivateWSKeys(): WsKey[] ⋮---- protected isAuthOnConnectWsKey(wsKey: WsKey): boolean ⋮---- protected async getWsUrl(wsKey: WsKey): Promise ⋮---- protected getMaxTopicsPerSubscribeEvent(): number | null ⋮---- /** * @returns one or more correctly structured request events for performing a operations over WS. This can vary per exchange spec. */ protected async getWsRequestEvents( operation: WSOperation, requests: WsTopicRequest[], ): Promise>[]> ⋮---- // Previously used to track topics in a request. Keeping this for subscribe/unsubscribe requests, no need for incremental values ⋮---- /** { "op":"subscribe", "args":[ { "channel": "tickers", "instId": "BTC-USDT" }, { "channel": "tickers", "instId": "BTC-USDT" } ] } */ ⋮---- // const request = { // topic: 'tickers', // payload: { instId: 'BTC-USDT' }, // }; // becomes: // const request = { // channel: 'ticker', // instId: 'BTC-USDT', // }; ⋮---- private async signMessage( paramsStr: string, secret: string, method: SignEncodeMethod, algorithm: SignAlgorithm, ): Promise ⋮---- protected async getWsAuthRequestEvent( wsKey: WsKey, skipIsPublicWsKeyCheck: boolean, ): Promise | null> ⋮---- // Filter out failed accounts ⋮---- private async getWsAuthSignature( wsKey: WsKey, credentials: APICredentials, ): Promise< ⋮---- // const signatureExpiresAt = timestamp + 5; ⋮---- /** * Abstraction called to sort ws events into emittable event types (response to a request, data update, etc) */ protected resolveEmittableEvents( wsKey: WsKey, event: MessageEventLike, ): EmittableEvent[] ⋮---- /** * WS API response handling */ ⋮---- // const eg1 = { // id: '2', // op: 'order', // code: '1', // msg: '', // data: [ // { // tag: '159881cb7207BCDE', // ts: '1753783406701', // ordId: '', // clOrdId: '', // sCode: '51008', // sMsg: 'Order failed. Insufficient USDT balance in account.', // }, // ], // inTime: '1753783406701275', // outTime: '1753783406702251', // wsKey: 'prodPrivate', // }; ⋮---- // check getPromiseRefForWSAPIRequest ⋮---- // WS API Success ⋮---- // messageType: typeof msg, // messageString: JSON.stringify(msg), ⋮---- // Successfully authenticated ⋮---- // this.logger.trace(`Ws subscribe reply:`, { ...msg, wsKey }); ⋮---- // Queue immediate reconnection workflow ⋮---- // Emit notice to client for visibility ⋮---- // messageType: typeof msg, // messageString: JSON.stringify(msg), ⋮---- // fallback emit anyway ⋮---- /** * OKX supports order placement via WebSockets. This is the WS API: * https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order * * For convenient promise-wrapped usage of the WS API, instance the WebsocketAPIClient class exported by this SDK. * * For demo trading, set demoTrading:true in the WS Client config. * * @returns a promise that resolves/rejects when a matching response arrives */ async sendWSAPIRequest< TWSKey extends keyof WsAPIWsKeyTopicMap, TWSOperation extends WsAPIWsKeyTopicMap[TWSKey], TWSParams extends WsAPITopicRequestParamMap[TWSOperation], TWSAPIResponse extends WsAPIOperationResponseMap[TWSOperation] = WsAPIOperationResponseMap[TWSOperation], >( rawWsKey: WsKey, operation: TWSOperation, params: TWSParams & { signRequest?: boolean }, requestFlags?: WSAPIRequestFlags, ): Promise ⋮---- // If demo trading, enforce demo wskey for WS API calls ⋮---- // Ensure "args" is always wrapped as array ⋮---- // Store deferred promise, resolved within the "resolveEmittableEvents" method while parsing incoming events ⋮---- // Enriched WS API response includes wsKey & the request that was connected to the response type DeferredWSAPIResponse = TWSAPIResponse & { request: WSAPIRequestOKX & { wsKey: WsKey }; }; ⋮---- // Enrich returned promise with request context for easier debugging ⋮---- // throw e; ⋮---- // Send event ⋮---- // Return deferred promise, so caller can await this call ================ File: package.json ================ { "name": "okx-api", "version": "3.0.13", "description": "Complete Node.js SDK for OKX's REST APIs and WebSockets, with TypeScript & end-to-end tests", "scripts": { "test": "jest", "test:public": "jest --testPathIgnorePatterns='.*private.*'", "test:private": "jest --testPathPattern='.*private.*'", "test:watch": "jest --watch", "clean": "rm -rf lib dist", "build": "npm run clean && tsc -p tsconfig.esm.json && tsc -p tsconfig.cjs.json && bash ./postBuild.sh", "build:clean": "npm run clean && npm run build", "build:watch": "npm run clean && tsc --watch", "pack": "webpack --config webpack/webpack.config.js", "lint": "eslint src", "prepublish": "npm run build:clean", "betapublish": "npm publish --tag beta" }, "main": "dist/cjs/index.js", "module": "dist/mjs/index.js", "types": "dist/mjs/index.d.ts", "exports": { ".": { "import": "./dist/mjs/index.js", "require": "./dist/cjs/index.js", "types": "./dist/mjs/index.d.ts" } }, "files": [ "dist/*", "llms.txt" ], "type": "module", "author": "Tiago Siebler (https://github.com/tiagosiebler)", "contributors": [], "dependencies": { "axios": "^1.12.2", "isomorphic-ws": "^5.0.0", "ws": "^8.18.3" }, "devDependencies": { "@types/jest": "^29.5.11", "@types/node": "^22.17.2", "@types/ws": "^8.18.1", "@typescript-eslint/eslint-plugin": "^8.18.0", "@typescript-eslint/parser": "^8.18.0", "eslint": "^8.24.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-require-extensions": "^0.1.3", "eslint-plugin-simple-import-sort": "^12.1.1", "jest": "^29.7.0", "ts-jest": "^29.1.2", "ts-node": "^10.9.2", "typescript": "^5.7.3" }, "optionalDependencies": { "source-map-loader": "^4.0.0", "ts-loader": "^9.3.1", "webpack": "^5.74.0", "webpack-bundle-analyzer": "^4.6.1", "webpack-cli": "^4.10.0" }, "keywords": [ "okx", "okx api", "okex", "okex api", "api", "websocket", "okx websocket api", "okx websocket api javascript", "okx ws api", "rest", "rest api", "usdt", "trading bots", "nodejs", "node", "trading", "cryptocurrency", "bitcoin", "best" ], "funding": { "type": "individual", "url": "https://github.com/sponsors/tiagosiebler" }, "license": "MIT", "repository": { "type": "git", "url": "https://github.com/tiagosiebler/okx-api" }, "bugs": { "url": "https://github.com/tiagosiebler/okx-api/issues" }, "homepage": "https://github.com/tiagosiebler/okx-api#readme" } ================================================================ End of Codebase ================================================================