@yuants/vendor-okx 0.22.16 → 0.22.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/trade.js CHANGED
@@ -17,13 +17,15 @@ const tradeParser = async (accountId, params) => {
17
17
  productIdSet.add(encodePath(item.instType, item.instId));
18
18
  mapTradeIdToBillList.set(item.tradeId, [...((_a = mapTradeIdToBillList.get(item.tradeId)) !== null && _a !== void 0 ? _a : []), item]);
19
19
  });
20
- const productList = await requestSQL(Terminal.fromNodeEnv(), `
21
- select * from product where product_id in (${Array.from(productIdSet)
22
- .map((productId) => escapeSQL(productId))
23
- .join(',')})
24
- `);
25
- if (productList.length > 0) {
26
- productList.forEach((p) => productIdToProduct.set(p.product_id, p));
20
+ if (productIdSet.size > 0) {
21
+ const productList = await requestSQL(Terminal.fromNodeEnv(), `
22
+ select * from product where product_id in (${Array.from(productIdSet)
23
+ .map((productId) => escapeSQL(productId))
24
+ .join(',')})
25
+ `);
26
+ if (productList.length > 0) {
27
+ productList.forEach((p) => productIdToProduct.set(p.product_id, p));
28
+ }
27
29
  }
28
30
  mapTradeIdToBillList.forEach(async (v, tradeId) => {
29
31
  var _a, _b;
package/dist/trade.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"trade.js","sourceRoot":"","sources":["../src/trade.ts"],"names":[],"mappings":"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","sourcesContent":["import { defer, first, of, repeat, retry, tap, timeout } from 'rxjs';\nimport { client } from './api';\nimport { ITrade } from '@yuants/data-trade';\nimport { accountUid$ } from './account';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { buildInsertManyIntoTableSQL, escapeSQL, requestSQL } from '@yuants/sql';\nimport { Terminal } from '@yuants/protocol';\nimport { IProduct } from '@yuants/data-product';\nconst tradeParser = async (accountId: string, params: Record<string, string>): Promise<ITrade[]> => {\n const tradeList: ITrade[] = [];\n const result = await client.getAccountBillsArchive(params);\n const productIdToProduct = new Map<string, IProduct>();\n const productIdSet = new Set<string>();\n if (result.code === '0' && result.data) {\n const data = result.data;\n const mapTradeIdToBillList = new Map<string, typeof data>();\n data.forEach((item) => {\n productIdSet.add(encodePath(item.instType, item.instId));\n mapTradeIdToBillList.set(item.tradeId, [...(mapTradeIdToBillList.get(item.tradeId) ?? []), item]);\n });\n const productList = await requestSQL<IProduct[]>(\n Terminal.fromNodeEnv(),\n `\n select * from product where product_id in (${Array.from(productIdSet)\n .map((productId) => escapeSQL(productId))\n .join(',')})\n `,\n );\n if (productList.length > 0) {\n productList.forEach((p) => productIdToProduct.set(p.product_id, p));\n }\n mapTradeIdToBillList.forEach(async (v, tradeId) => {\n if (!((v[0].instType === 'SPOT' && v.length === 2) || v[0].instType === 'SWAP')) return;\n\n const trade: ITrade = {\n id: tradeId,\n account_id: accountId,\n product_id: '',\n direction: '',\n traded_volume: '',\n traded_price: '',\n traded_value: '',\n fee: '',\n fee_currency: '',\n created_at: '0',\n };\n\n v.forEach((bill) => {\n trade.created_at = Math.max(Number(trade.created_at), Number(bill.ts)).toString();\n trade.product_id = encodePath(bill.instType, bill.instId);\n trade.traded_price = bill.px;\n if (bill.instType === 'SWAP') {\n if (bill.subType === '1') trade.direction = 'OPEN_LONG';\n if (bill.subType === '2') trade.direction = 'CLOSE_LONG';\n if (bill.subType === '3') trade.direction = 'OPEN_LONG';\n if (bill.subType === '4') trade.direction = 'OPEN_SHORT';\n if (bill.subType === '5') trade.direction = 'CLOSE_LONG';\n if (bill.subType === '6') trade.direction = 'CLOSE_SHORT';\n trade.traded_volume = bill.sz;\n trade.traded_value = (Number(bill.sz) * Number(bill.px)).toString();\n }\n if (bill.instType === 'SPOT') {\n if (bill.subType === '1') {\n if (bill.ccy !== 'USDT') {\n trade.direction = 'OPEN_LONG';\n } else {\n trade.direction = 'CLOSE_LONG';\n }\n }\n\n if (bill.ccy !== 'USDT') {\n trade.traded_volume = bill.sz;\n }\n if (bill.ccy === 'USDT') {\n trade.traded_value = bill.sz;\n }\n }\n // fee\n if (bill.fee !== '0') {\n trade.fee = Math.abs(Number(bill.fee)).toString();\n trade.fee_currency = bill.ccy;\n }\n });\n trade.created_at = formatTime(Number(trade.created_at));\n if (productIdToProduct.has(trade.product_id)) {\n trade.traded_value = (\n +trade.traded_value * +(productIdToProduct.get(trade.product_id)?.value_scale ?? 1)\n ).toString();\n } else {\n throw new Error(`Not Found Product With Product Id: ${trade.product_id}`);\n }\n tradeList.push(trade);\n });\n }\n return tradeList;\n};\n\nconst getAccountTradeWithAccountId = async (accountId: string) => {\n const currentTrade = await requestSQL<ITrade[]>(\n Terminal.fromNodeEnv(),\n `\n select * from trade where account_id=${escapeSQL(accountId)} order by created_at desc limit 1;\n `,\n );\n const params: Record<string, string> = {\n type: '2',\n begin: (new Date().getTime() - 1000 * 60 * 60 * 24 * 30 * 3).toString(),\n };\n if (currentTrade.length === 1) {\n params['begin'] = new Date(currentTrade[0].created_at ?? 0).getTime().toString();\n }\n console.log(formatTime(Date.now()), 'getAccountTrade', `params: ${JSON.stringify(params)}`);\n const tradeList = await tradeParser(accountId, params);\n console.log(formatTime(Date.now()), 'getAccountTrade', `tradeList: ${JSON.stringify(tradeList)}`);\n await requestSQL(\n Terminal.fromNodeEnv(),\n buildInsertManyIntoTableSQL(tradeList, 'trade', {\n columns: [\n 'id',\n 'account_id',\n 'product_id',\n 'traded_volume',\n 'traded_value',\n 'traded_price',\n 'direction',\n 'fee',\n 'fee_currency',\n 'created_at',\n ],\n conflictKeys: ['id'],\n }),\n );\n};\n\ndefer(() => accountUid$)\n .pipe(first())\n .subscribe((uid) => {\n const account_id = `okx/${uid}/trading`;\n console.log(formatTime(Date.now()), 'getAccountTrade', `AccountID: ${account_id}`);\n defer(() => getAccountTradeWithAccountId(account_id))\n .pipe(\n //\n timeout(10_000), // 超时设定:10 秒\n tap({\n error: (err) => {\n console.error(formatTime(Date.now()), 'getAccountTradeError', err);\n },\n }),\n repeat({ delay: 30_000 }),\n retry({ delay: 5000 }),\n )\n .subscribe();\n });\n"]}
1
+ {"version":3,"file":"trade.js","sourceRoot":"","sources":["../src/trade.ts"],"names":[],"mappings":"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","sourcesContent":["import { defer, first, of, repeat, retry, tap, timeout } from 'rxjs';\nimport { client } from './api';\nimport { ITrade } from '@yuants/data-trade';\nimport { accountUid$ } from './account';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { buildInsertManyIntoTableSQL, escapeSQL, requestSQL } from '@yuants/sql';\nimport { Terminal } from '@yuants/protocol';\nimport { IProduct } from '@yuants/data-product';\nconst tradeParser = async (accountId: string, params: Record<string, string>): Promise<ITrade[]> => {\n const tradeList: ITrade[] = [];\n const result = await client.getAccountBillsArchive(params);\n const productIdToProduct = new Map<string, IProduct>();\n const productIdSet = new Set<string>();\n if (result.code === '0' && result.data) {\n const data = result.data;\n const mapTradeIdToBillList = new Map<string, typeof data>();\n data.forEach((item) => {\n productIdSet.add(encodePath(item.instType, item.instId));\n mapTradeIdToBillList.set(item.tradeId, [...(mapTradeIdToBillList.get(item.tradeId) ?? []), item]);\n });\n if (productIdSet.size > 0) {\n const productList = await requestSQL<IProduct[]>(\n Terminal.fromNodeEnv(),\n `\n select * from product where product_id in (${Array.from(productIdSet)\n .map((productId) => escapeSQL(productId))\n .join(',')})\n `,\n );\n if (productList.length > 0) {\n productList.forEach((p) => productIdToProduct.set(p.product_id, p));\n }\n }\n mapTradeIdToBillList.forEach(async (v, tradeId) => {\n if (!((v[0].instType === 'SPOT' && v.length === 2) || v[0].instType === 'SWAP')) return;\n\n const trade: ITrade = {\n id: tradeId,\n account_id: accountId,\n product_id: '',\n direction: '',\n traded_volume: '',\n traded_price: '',\n traded_value: '',\n fee: '',\n fee_currency: '',\n created_at: '0',\n };\n\n v.forEach((bill) => {\n trade.created_at = Math.max(Number(trade.created_at), Number(bill.ts)).toString();\n trade.product_id = encodePath(bill.instType, bill.instId);\n trade.traded_price = bill.px;\n if (bill.instType === 'SWAP') {\n if (bill.subType === '1') trade.direction = 'OPEN_LONG';\n if (bill.subType === '2') trade.direction = 'CLOSE_LONG';\n if (bill.subType === '3') trade.direction = 'OPEN_LONG';\n if (bill.subType === '4') trade.direction = 'OPEN_SHORT';\n if (bill.subType === '5') trade.direction = 'CLOSE_LONG';\n if (bill.subType === '6') trade.direction = 'CLOSE_SHORT';\n trade.traded_volume = bill.sz;\n trade.traded_value = (Number(bill.sz) * Number(bill.px)).toString();\n }\n if (bill.instType === 'SPOT') {\n if (bill.subType === '1') {\n if (bill.ccy !== 'USDT') {\n trade.direction = 'OPEN_LONG';\n } else {\n trade.direction = 'CLOSE_LONG';\n }\n }\n\n if (bill.ccy !== 'USDT') {\n trade.traded_volume = bill.sz;\n }\n if (bill.ccy === 'USDT') {\n trade.traded_value = bill.sz;\n }\n }\n // fee\n if (bill.fee !== '0') {\n trade.fee = Math.abs(Number(bill.fee)).toString();\n trade.fee_currency = bill.ccy;\n }\n });\n trade.created_at = formatTime(Number(trade.created_at));\n if (productIdToProduct.has(trade.product_id)) {\n trade.traded_value = (\n +trade.traded_value * +(productIdToProduct.get(trade.product_id)?.value_scale ?? 1)\n ).toString();\n } else {\n throw new Error(`Not Found Product With Product Id: ${trade.product_id}`);\n }\n tradeList.push(trade);\n });\n }\n return tradeList;\n};\n\nconst getAccountTradeWithAccountId = async (accountId: string) => {\n const currentTrade = await requestSQL<ITrade[]>(\n Terminal.fromNodeEnv(),\n `\n select * from trade where account_id=${escapeSQL(accountId)} order by created_at desc limit 1;\n `,\n );\n const params: Record<string, string> = {\n type: '2',\n begin: (new Date().getTime() - 1000 * 60 * 60 * 24 * 30 * 3).toString(),\n };\n if (currentTrade.length === 1) {\n params['begin'] = new Date(currentTrade[0].created_at ?? 0).getTime().toString();\n }\n console.log(formatTime(Date.now()), 'getAccountTrade', `params: ${JSON.stringify(params)}`);\n const tradeList = await tradeParser(accountId, params);\n console.log(formatTime(Date.now()), 'getAccountTrade', `tradeList: ${JSON.stringify(tradeList)}`);\n await requestSQL(\n Terminal.fromNodeEnv(),\n buildInsertManyIntoTableSQL(tradeList, 'trade', {\n columns: [\n 'id',\n 'account_id',\n 'product_id',\n 'traded_volume',\n 'traded_value',\n 'traded_price',\n 'direction',\n 'fee',\n 'fee_currency',\n 'created_at',\n ],\n conflictKeys: ['id'],\n }),\n );\n};\n\ndefer(() => accountUid$)\n .pipe(first())\n .subscribe((uid) => {\n const account_id = `okx/${uid}/trading`;\n console.log(formatTime(Date.now()), 'getAccountTrade', `AccountID: ${account_id}`);\n defer(() => getAccountTradeWithAccountId(account_id))\n .pipe(\n //\n timeout(10_000), // 超时设定:10 秒\n tap({\n error: (err) => {\n console.error(formatTime(Date.now()), 'getAccountTradeError', err);\n },\n }),\n repeat({ delay: 30_000 }),\n retry({ delay: 5000 }),\n )\n .subscribe();\n });\n"]}
package/dist/websocket.js CHANGED
@@ -1,15 +1,16 @@
1
- import { PromRegistry } from '@yuants/protocol';
1
+ import { PromRegistry, Terminal } from '@yuants/protocol';
2
2
  import { encodePath, formatTime } from '@yuants/utils';
3
3
  import { catchError, defer, EMPTY, interval, Observable, tap, timeout } from 'rxjs';
4
4
  const MetricsWebSocketConnectionsGauge = PromRegistry.create('gauge', 'okx_websocket_connections', 'Number of active OKX WebSocket connections');
5
5
  const MetricsWebSocketChannelGauge = PromRegistry.create('gauge', 'okx_websocket_channel', 'Number of OKX WebSocket channels subscribed');
6
+ const terminal = Terminal.fromNodeEnv();
6
7
  class OKXWsClient {
7
8
  constructor(path) {
8
9
  this.connected = false;
9
10
  this.baseURL = `wss://ws.okx.com:8443`;
10
11
  // this.instId = instId;
11
12
  this.ws = new WebSocket(`${this.baseURL}/${path}`);
12
- MetricsWebSocketConnectionsGauge.inc({ path });
13
+ MetricsWebSocketConnectionsGauge.inc({ path, terminal_id: terminal.terminal_id });
13
14
  this.pendingSub = [];
14
15
  this.keepAlive = interval(25000)
15
16
  .pipe(tap(() => {
@@ -78,7 +79,7 @@ class OKXWsClient {
78
79
  this.pendingSub.push(JSON.stringify(subMsg));
79
80
  console.info(formatTime(Date.now()), `📩 add subscribe for ${channelId} to pending list`);
80
81
  }
81
- MetricsWebSocketChannelGauge.inc({ channel });
82
+ MetricsWebSocketChannelGauge.inc({ channel, terminal_id: terminal.terminal_id });
82
83
  this.subscriptions.add(channelId);
83
84
  if (handler) {
84
85
  this.handlers[channelId] = handler;
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"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","sourcesContent":["import { PromRegistry } from '@yuants/protocol';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { catchError, defer, EMPTY, interval, Observable, Subscription, tap, timeout } from 'rxjs';\n\nconst MetricsWebSocketConnectionsGauge = PromRegistry.create(\n 'gauge',\n 'okx_websocket_connections',\n 'Number of active OKX WebSocket connections',\n);\n\nconst MetricsWebSocketChannelGauge = PromRegistry.create(\n 'gauge',\n 'okx_websocket_channel',\n 'Number of OKX WebSocket channels subscribed',\n);\n\nclass OKXWsClient {\n ws: WebSocket;\n connected: boolean = false;\n subscriptions: Set<string>;\n handlers: Record<string, Function>;\n pendingSub: string[];\n keepAlive: Subscription;\n\n baseURL: string = `wss://ws.okx.com:8443`;\n constructor(path: string) {\n // this.instId = instId;\n this.ws = new WebSocket(`${this.baseURL}/${path}`);\n\n MetricsWebSocketConnectionsGauge.inc({ path });\n\n this.pendingSub = [];\n this.keepAlive = interval(25000)\n .pipe(\n tap(() => {\n if (this.connected) {\n this.ws.send('ping');\n }\n }),\n )\n .subscribe();\n // this.ws.\n this.ws.addEventListener('open', () => {\n this.connected = true;\n console.info(formatTime(Date.now()), '✅ WS connected');\n while (this.pendingSub.length > 0) {\n const msg = this.pendingSub.shift();\n if (msg) {\n this.ws.send(msg);\n console.info(formatTime(Date.now()), `📩 Sent subscribe for ${msg}`);\n }\n }\n });\n\n this.ws.addEventListener('message', (raw) => this.handleMessage(raw));\n this.ws.addEventListener('error', (raw) => {\n console.error(formatTime(Date.now()), '❌ WS error', raw);\n });\n this.ws.addEventListener('close', (event) => {\n console.error(formatTime(Date.now()), '❌ WS closed', event);\n\n MetricsWebSocketConnectionsGauge.dec({ path });\n });\n this.subscriptions = new Set();\n this.handlers = {}; // key: channel, value: callback\n }\n\n // 处理消息\n handleMessage(raw: any) {\n if (raw.data === 'pong') {\n return;\n }\n const msg = JSON.parse(raw.data);\n if (msg.arg?.channel) {\n const channelId = encodePath(msg.arg.channel, msg.arg.instId);\n const data = msg.data?.[0];\n if (data && this.handlers[channelId]) {\n this.handlers[channelId](data, msg.arg);\n }\n } else if (msg.event) {\n console.info(formatTime(Date.now()), 'Event:', msg);\n }\n }\n\n // 调用订阅\n subscribe(channel: string, instId?: string, handler?: Function) {\n const channelId = encodePath(channel, instId);\n if (this.subscriptions.has(channelId)) {\n console.info(formatTime(Date.now()), `⚠️ Already subscribed: ${channelId}`);\n return;\n }\n\n const subMsg = {\n op: 'subscribe',\n args: [{ channel, instId }],\n };\n\n if (this.connected) {\n this.ws.send(JSON.stringify(subMsg));\n console.info(formatTime(Date.now()), `📩 Sent subscribe for ${channelId}`);\n } else {\n this.pendingSub.push(JSON.stringify(subMsg));\n console.info(formatTime(Date.now()), `📩 add subscribe for ${channelId} to pending list`);\n }\n MetricsWebSocketChannelGauge.inc({ channel });\n this.subscriptions.add(channelId);\n if (handler) {\n this.handlers[channelId] = handler;\n }\n }\n\n // 取消订阅\n unsubscribe(channel: string, instId?: string) {\n const channelId = encodePath(channel, instId);\n if (!this.subscriptions.has(channelId)) return;\n\n const unSubMsg = {\n op: 'unsubscribe',\n args: [{ channel, instId }],\n };\n\n this.ws.send(JSON.stringify(unSubMsg));\n this.subscriptions.delete(channelId);\n if (this.subscriptions.size === 0) {\n this.keepAlive.unsubscribe();\n }\n MetricsWebSocketChannelGauge.dec({ channel });\n delete this.handlers[channelId];\n console.info(formatTime(Date.now()), `📩 Sent unsubscribe for ${channelId}`);\n }\n}\n\nconst wsPool: {\n path: string;\n client: OKXWsClient;\n requests: number;\n isFull: boolean;\n}[] = [];\n\n// ISSUE: 连接限制:3 次/秒 (基于IP)\n//\n// https://www.okx.com/docs-v5/zh/#overview-websocket-connect\n//\n// 当订阅公有频道时,使用公有服务的地址;当订阅私有频道时,使用私有服务的地址\n//\n// 请求限制:\n//\n// 每个连接 对于 订阅/取消订阅/登录 请求的总次数限制为 480 次/小时\nconst getWsClient = (path: string) => {\n const existing = wsPool.find((item) => item.path === path && !item.isFull);\n if (existing) {\n existing.requests++;\n if (existing.requests >= 480) {\n existing.isFull = true;\n }\n return existing.client;\n }\n const newClient = new OKXWsClient(path);\n wsPool.push({ path, client: newClient, requests: 1, isFull: false });\n return newClient;\n};\n\nconst fromWsChannelAndInstId = <T>(path: string, channel: string, instId: string) =>\n defer(\n () =>\n new Observable<T>((subscriber) => {\n const client = getWsClient(path);\n client.subscribe(channel, instId, (data: T) => {\n subscriber.next(data);\n });\n client.ws.addEventListener('error', (err) => {\n subscriber.error(err);\n });\n client.ws.addEventListener('close', () => {\n subscriber.error('WS Connection Closed');\n });\n subscriber.add(() => {\n client.unsubscribe(channel, instId);\n });\n }),\n ).pipe(\n // 防止单个连接断开导致数据流关闭\n timeout(60_000),\n tap({\n error: (err) => {\n console.info(formatTime(Date.now()), 'WS_SUBSCRIBE_ERROR', channel, instId, err);\n },\n }),\n // 暂时不太确定是否能支持 retry\n // retry({ delay: 1000 }),\n catchError(() => EMPTY),\n );\n\nexport const useTicker = (instId: string) =>\n fromWsChannelAndInstId<{\n instId: string;\n last: string;\n askPx: string;\n bidPx: string;\n askSz: string;\n bidSz: string;\n }>('ws/v5/public', 'tickers', instId);\n\nexport const useOpenInterest = (instId: string) =>\n fromWsChannelAndInstId<{\n instId: string;\n oi: string; // open interest\n }>('ws/v5/public', 'open-interest', instId);\n\nexport const useOHLC = (candleType: string, instId: string) =>\n fromWsChannelAndInstId<string[]>('ws/v5/business', candleType, instId);\n"]}
1
+ {"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"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","sourcesContent":["import { PromRegistry, Terminal } from '@yuants/protocol';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { catchError, defer, EMPTY, interval, Observable, Subscription, tap, timeout } from 'rxjs';\n\nconst MetricsWebSocketConnectionsGauge = PromRegistry.create(\n 'gauge',\n 'okx_websocket_connections',\n 'Number of active OKX WebSocket connections',\n);\n\nconst MetricsWebSocketChannelGauge = PromRegistry.create(\n 'gauge',\n 'okx_websocket_channel',\n 'Number of OKX WebSocket channels subscribed',\n);\n\nconst terminal = Terminal.fromNodeEnv();\n\nclass OKXWsClient {\n ws: WebSocket;\n connected: boolean = false;\n subscriptions: Set<string>;\n handlers: Record<string, Function>;\n pendingSub: string[];\n keepAlive: Subscription;\n\n baseURL: string = `wss://ws.okx.com:8443`;\n constructor(path: string) {\n // this.instId = instId;\n this.ws = new WebSocket(`${this.baseURL}/${path}`);\n\n MetricsWebSocketConnectionsGauge.inc({ path, terminal_id: terminal.terminal_id });\n\n this.pendingSub = [];\n this.keepAlive = interval(25000)\n .pipe(\n tap(() => {\n if (this.connected) {\n this.ws.send('ping');\n }\n }),\n )\n .subscribe();\n // this.ws.\n this.ws.addEventListener('open', () => {\n this.connected = true;\n console.info(formatTime(Date.now()), '✅ WS connected');\n while (this.pendingSub.length > 0) {\n const msg = this.pendingSub.shift();\n if (msg) {\n this.ws.send(msg);\n console.info(formatTime(Date.now()), `📩 Sent subscribe for ${msg}`);\n }\n }\n });\n\n this.ws.addEventListener('message', (raw) => this.handleMessage(raw));\n this.ws.addEventListener('error', (raw) => {\n console.error(formatTime(Date.now()), '❌ WS error', raw);\n });\n this.ws.addEventListener('close', (event) => {\n console.error(formatTime(Date.now()), '❌ WS closed', event);\n\n MetricsWebSocketConnectionsGauge.dec({ path });\n });\n this.subscriptions = new Set();\n this.handlers = {}; // key: channel, value: callback\n }\n\n // 处理消息\n handleMessage(raw: any) {\n if (raw.data === 'pong') {\n return;\n }\n const msg = JSON.parse(raw.data);\n if (msg.arg?.channel) {\n const channelId = encodePath(msg.arg.channel, msg.arg.instId);\n const data = msg.data?.[0];\n if (data && this.handlers[channelId]) {\n this.handlers[channelId](data, msg.arg);\n }\n } else if (msg.event) {\n console.info(formatTime(Date.now()), 'Event:', msg);\n }\n }\n\n // 调用订阅\n subscribe(channel: string, instId?: string, handler?: Function) {\n const channelId = encodePath(channel, instId);\n if (this.subscriptions.has(channelId)) {\n console.info(formatTime(Date.now()), `⚠️ Already subscribed: ${channelId}`);\n return;\n }\n\n const subMsg = {\n op: 'subscribe',\n args: [{ channel, instId }],\n };\n\n if (this.connected) {\n this.ws.send(JSON.stringify(subMsg));\n console.info(formatTime(Date.now()), `📩 Sent subscribe for ${channelId}`);\n } else {\n this.pendingSub.push(JSON.stringify(subMsg));\n console.info(formatTime(Date.now()), `📩 add subscribe for ${channelId} to pending list`);\n }\n MetricsWebSocketChannelGauge.inc({ channel, terminal_id: terminal.terminal_id });\n this.subscriptions.add(channelId);\n if (handler) {\n this.handlers[channelId] = handler;\n }\n }\n\n // 取消订阅\n unsubscribe(channel: string, instId?: string) {\n const channelId = encodePath(channel, instId);\n if (!this.subscriptions.has(channelId)) return;\n\n const unSubMsg = {\n op: 'unsubscribe',\n args: [{ channel, instId }],\n };\n\n this.ws.send(JSON.stringify(unSubMsg));\n this.subscriptions.delete(channelId);\n if (this.subscriptions.size === 0) {\n this.keepAlive.unsubscribe();\n }\n MetricsWebSocketChannelGauge.dec({ channel });\n delete this.handlers[channelId];\n console.info(formatTime(Date.now()), `📩 Sent unsubscribe for ${channelId}`);\n }\n}\n\nconst wsPool: {\n path: string;\n client: OKXWsClient;\n requests: number;\n isFull: boolean;\n}[] = [];\n\n// ISSUE: 连接限制:3 次/秒 (基于IP)\n//\n// https://www.okx.com/docs-v5/zh/#overview-websocket-connect\n//\n// 当订阅公有频道时,使用公有服务的地址;当订阅私有频道时,使用私有服务的地址\n//\n// 请求限制:\n//\n// 每个连接 对于 订阅/取消订阅/登录 请求的总次数限制为 480 次/小时\nconst getWsClient = (path: string) => {\n const existing = wsPool.find((item) => item.path === path && !item.isFull);\n if (existing) {\n existing.requests++;\n if (existing.requests >= 480) {\n existing.isFull = true;\n }\n return existing.client;\n }\n const newClient = new OKXWsClient(path);\n wsPool.push({ path, client: newClient, requests: 1, isFull: false });\n return newClient;\n};\n\nconst fromWsChannelAndInstId = <T>(path: string, channel: string, instId: string) =>\n defer(\n () =>\n new Observable<T>((subscriber) => {\n const client = getWsClient(path);\n client.subscribe(channel, instId, (data: T) => {\n subscriber.next(data);\n });\n client.ws.addEventListener('error', (err) => {\n subscriber.error(err);\n });\n client.ws.addEventListener('close', () => {\n subscriber.error('WS Connection Closed');\n });\n subscriber.add(() => {\n client.unsubscribe(channel, instId);\n });\n }),\n ).pipe(\n // 防止单个连接断开导致数据流关闭\n timeout(60_000),\n tap({\n error: (err) => {\n console.info(formatTime(Date.now()), 'WS_SUBSCRIBE_ERROR', channel, instId, err);\n },\n }),\n // 暂时不太确定是否能支持 retry\n // retry({ delay: 1000 }),\n catchError(() => EMPTY),\n );\n\nexport const useTicker = (instId: string) =>\n fromWsChannelAndInstId<{\n instId: string;\n last: string;\n askPx: string;\n bidPx: string;\n askSz: string;\n bidSz: string;\n }>('ws/v5/public', 'tickers', instId);\n\nexport const useOpenInterest = (instId: string) =>\n fromWsChannelAndInstId<{\n instId: string;\n oi: string; // open interest\n }>('ws/v5/public', 'open-interest', instId);\n\nexport const useOHLC = (candleType: string, instId: string) =>\n fromWsChannelAndInstId<string[]>('ws/v5/business', candleType, instId);\n"]}
package/lib/trade.js CHANGED
@@ -19,13 +19,15 @@ const tradeParser = async (accountId, params) => {
19
19
  productIdSet.add((0, utils_1.encodePath)(item.instType, item.instId));
20
20
  mapTradeIdToBillList.set(item.tradeId, [...((_a = mapTradeIdToBillList.get(item.tradeId)) !== null && _a !== void 0 ? _a : []), item]);
21
21
  });
22
- const productList = await (0, sql_1.requestSQL)(protocol_1.Terminal.fromNodeEnv(), `
23
- select * from product where product_id in (${Array.from(productIdSet)
24
- .map((productId) => (0, sql_1.escapeSQL)(productId))
25
- .join(',')})
26
- `);
27
- if (productList.length > 0) {
28
- productList.forEach((p) => productIdToProduct.set(p.product_id, p));
22
+ if (productIdSet.size > 0) {
23
+ const productList = await (0, sql_1.requestSQL)(protocol_1.Terminal.fromNodeEnv(), `
24
+ select * from product where product_id in (${Array.from(productIdSet)
25
+ .map((productId) => (0, sql_1.escapeSQL)(productId))
26
+ .join(',')})
27
+ `);
28
+ if (productList.length > 0) {
29
+ productList.forEach((p) => productIdToProduct.set(p.product_id, p));
30
+ }
29
31
  }
30
32
  mapTradeIdToBillList.forEach(async (v, tradeId) => {
31
33
  var _a, _b;
package/lib/trade.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"trade.js","sourceRoot":"","sources":["../src/trade.ts"],"names":[],"mappings":"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","sourcesContent":["import { defer, first, of, repeat, retry, tap, timeout } from 'rxjs';\nimport { client } from './api';\nimport { ITrade } from '@yuants/data-trade';\nimport { accountUid$ } from './account';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { buildInsertManyIntoTableSQL, escapeSQL, requestSQL } from '@yuants/sql';\nimport { Terminal } from '@yuants/protocol';\nimport { IProduct } from '@yuants/data-product';\nconst tradeParser = async (accountId: string, params: Record<string, string>): Promise<ITrade[]> => {\n const tradeList: ITrade[] = [];\n const result = await client.getAccountBillsArchive(params);\n const productIdToProduct = new Map<string, IProduct>();\n const productIdSet = new Set<string>();\n if (result.code === '0' && result.data) {\n const data = result.data;\n const mapTradeIdToBillList = new Map<string, typeof data>();\n data.forEach((item) => {\n productIdSet.add(encodePath(item.instType, item.instId));\n mapTradeIdToBillList.set(item.tradeId, [...(mapTradeIdToBillList.get(item.tradeId) ?? []), item]);\n });\n const productList = await requestSQL<IProduct[]>(\n Terminal.fromNodeEnv(),\n `\n select * from product where product_id in (${Array.from(productIdSet)\n .map((productId) => escapeSQL(productId))\n .join(',')})\n `,\n );\n if (productList.length > 0) {\n productList.forEach((p) => productIdToProduct.set(p.product_id, p));\n }\n mapTradeIdToBillList.forEach(async (v, tradeId) => {\n if (!((v[0].instType === 'SPOT' && v.length === 2) || v[0].instType === 'SWAP')) return;\n\n const trade: ITrade = {\n id: tradeId,\n account_id: accountId,\n product_id: '',\n direction: '',\n traded_volume: '',\n traded_price: '',\n traded_value: '',\n fee: '',\n fee_currency: '',\n created_at: '0',\n };\n\n v.forEach((bill) => {\n trade.created_at = Math.max(Number(trade.created_at), Number(bill.ts)).toString();\n trade.product_id = encodePath(bill.instType, bill.instId);\n trade.traded_price = bill.px;\n if (bill.instType === 'SWAP') {\n if (bill.subType === '1') trade.direction = 'OPEN_LONG';\n if (bill.subType === '2') trade.direction = 'CLOSE_LONG';\n if (bill.subType === '3') trade.direction = 'OPEN_LONG';\n if (bill.subType === '4') trade.direction = 'OPEN_SHORT';\n if (bill.subType === '5') trade.direction = 'CLOSE_LONG';\n if (bill.subType === '6') trade.direction = 'CLOSE_SHORT';\n trade.traded_volume = bill.sz;\n trade.traded_value = (Number(bill.sz) * Number(bill.px)).toString();\n }\n if (bill.instType === 'SPOT') {\n if (bill.subType === '1') {\n if (bill.ccy !== 'USDT') {\n trade.direction = 'OPEN_LONG';\n } else {\n trade.direction = 'CLOSE_LONG';\n }\n }\n\n if (bill.ccy !== 'USDT') {\n trade.traded_volume = bill.sz;\n }\n if (bill.ccy === 'USDT') {\n trade.traded_value = bill.sz;\n }\n }\n // fee\n if (bill.fee !== '0') {\n trade.fee = Math.abs(Number(bill.fee)).toString();\n trade.fee_currency = bill.ccy;\n }\n });\n trade.created_at = formatTime(Number(trade.created_at));\n if (productIdToProduct.has(trade.product_id)) {\n trade.traded_value = (\n +trade.traded_value * +(productIdToProduct.get(trade.product_id)?.value_scale ?? 1)\n ).toString();\n } else {\n throw new Error(`Not Found Product With Product Id: ${trade.product_id}`);\n }\n tradeList.push(trade);\n });\n }\n return tradeList;\n};\n\nconst getAccountTradeWithAccountId = async (accountId: string) => {\n const currentTrade = await requestSQL<ITrade[]>(\n Terminal.fromNodeEnv(),\n `\n select * from trade where account_id=${escapeSQL(accountId)} order by created_at desc limit 1;\n `,\n );\n const params: Record<string, string> = {\n type: '2',\n begin: (new Date().getTime() - 1000 * 60 * 60 * 24 * 30 * 3).toString(),\n };\n if (currentTrade.length === 1) {\n params['begin'] = new Date(currentTrade[0].created_at ?? 0).getTime().toString();\n }\n console.log(formatTime(Date.now()), 'getAccountTrade', `params: ${JSON.stringify(params)}`);\n const tradeList = await tradeParser(accountId, params);\n console.log(formatTime(Date.now()), 'getAccountTrade', `tradeList: ${JSON.stringify(tradeList)}`);\n await requestSQL(\n Terminal.fromNodeEnv(),\n buildInsertManyIntoTableSQL(tradeList, 'trade', {\n columns: [\n 'id',\n 'account_id',\n 'product_id',\n 'traded_volume',\n 'traded_value',\n 'traded_price',\n 'direction',\n 'fee',\n 'fee_currency',\n 'created_at',\n ],\n conflictKeys: ['id'],\n }),\n );\n};\n\ndefer(() => accountUid$)\n .pipe(first())\n .subscribe((uid) => {\n const account_id = `okx/${uid}/trading`;\n console.log(formatTime(Date.now()), 'getAccountTrade', `AccountID: ${account_id}`);\n defer(() => getAccountTradeWithAccountId(account_id))\n .pipe(\n //\n timeout(10_000), // 超时设定:10 秒\n tap({\n error: (err) => {\n console.error(formatTime(Date.now()), 'getAccountTradeError', err);\n },\n }),\n repeat({ delay: 30_000 }),\n retry({ delay: 5000 }),\n )\n .subscribe();\n });\n"]}
1
+ {"version":3,"file":"trade.js","sourceRoot":"","sources":["../src/trade.ts"],"names":[],"mappings":"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","sourcesContent":["import { defer, first, of, repeat, retry, tap, timeout } from 'rxjs';\nimport { client } from './api';\nimport { ITrade } from '@yuants/data-trade';\nimport { accountUid$ } from './account';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { buildInsertManyIntoTableSQL, escapeSQL, requestSQL } from '@yuants/sql';\nimport { Terminal } from '@yuants/protocol';\nimport { IProduct } from '@yuants/data-product';\nconst tradeParser = async (accountId: string, params: Record<string, string>): Promise<ITrade[]> => {\n const tradeList: ITrade[] = [];\n const result = await client.getAccountBillsArchive(params);\n const productIdToProduct = new Map<string, IProduct>();\n const productIdSet = new Set<string>();\n if (result.code === '0' && result.data) {\n const data = result.data;\n const mapTradeIdToBillList = new Map<string, typeof data>();\n data.forEach((item) => {\n productIdSet.add(encodePath(item.instType, item.instId));\n mapTradeIdToBillList.set(item.tradeId, [...(mapTradeIdToBillList.get(item.tradeId) ?? []), item]);\n });\n if (productIdSet.size > 0) {\n const productList = await requestSQL<IProduct[]>(\n Terminal.fromNodeEnv(),\n `\n select * from product where product_id in (${Array.from(productIdSet)\n .map((productId) => escapeSQL(productId))\n .join(',')})\n `,\n );\n if (productList.length > 0) {\n productList.forEach((p) => productIdToProduct.set(p.product_id, p));\n }\n }\n mapTradeIdToBillList.forEach(async (v, tradeId) => {\n if (!((v[0].instType === 'SPOT' && v.length === 2) || v[0].instType === 'SWAP')) return;\n\n const trade: ITrade = {\n id: tradeId,\n account_id: accountId,\n product_id: '',\n direction: '',\n traded_volume: '',\n traded_price: '',\n traded_value: '',\n fee: '',\n fee_currency: '',\n created_at: '0',\n };\n\n v.forEach((bill) => {\n trade.created_at = Math.max(Number(trade.created_at), Number(bill.ts)).toString();\n trade.product_id = encodePath(bill.instType, bill.instId);\n trade.traded_price = bill.px;\n if (bill.instType === 'SWAP') {\n if (bill.subType === '1') trade.direction = 'OPEN_LONG';\n if (bill.subType === '2') trade.direction = 'CLOSE_LONG';\n if (bill.subType === '3') trade.direction = 'OPEN_LONG';\n if (bill.subType === '4') trade.direction = 'OPEN_SHORT';\n if (bill.subType === '5') trade.direction = 'CLOSE_LONG';\n if (bill.subType === '6') trade.direction = 'CLOSE_SHORT';\n trade.traded_volume = bill.sz;\n trade.traded_value = (Number(bill.sz) * Number(bill.px)).toString();\n }\n if (bill.instType === 'SPOT') {\n if (bill.subType === '1') {\n if (bill.ccy !== 'USDT') {\n trade.direction = 'OPEN_LONG';\n } else {\n trade.direction = 'CLOSE_LONG';\n }\n }\n\n if (bill.ccy !== 'USDT') {\n trade.traded_volume = bill.sz;\n }\n if (bill.ccy === 'USDT') {\n trade.traded_value = bill.sz;\n }\n }\n // fee\n if (bill.fee !== '0') {\n trade.fee = Math.abs(Number(bill.fee)).toString();\n trade.fee_currency = bill.ccy;\n }\n });\n trade.created_at = formatTime(Number(trade.created_at));\n if (productIdToProduct.has(trade.product_id)) {\n trade.traded_value = (\n +trade.traded_value * +(productIdToProduct.get(trade.product_id)?.value_scale ?? 1)\n ).toString();\n } else {\n throw new Error(`Not Found Product With Product Id: ${trade.product_id}`);\n }\n tradeList.push(trade);\n });\n }\n return tradeList;\n};\n\nconst getAccountTradeWithAccountId = async (accountId: string) => {\n const currentTrade = await requestSQL<ITrade[]>(\n Terminal.fromNodeEnv(),\n `\n select * from trade where account_id=${escapeSQL(accountId)} order by created_at desc limit 1;\n `,\n );\n const params: Record<string, string> = {\n type: '2',\n begin: (new Date().getTime() - 1000 * 60 * 60 * 24 * 30 * 3).toString(),\n };\n if (currentTrade.length === 1) {\n params['begin'] = new Date(currentTrade[0].created_at ?? 0).getTime().toString();\n }\n console.log(formatTime(Date.now()), 'getAccountTrade', `params: ${JSON.stringify(params)}`);\n const tradeList = await tradeParser(accountId, params);\n console.log(formatTime(Date.now()), 'getAccountTrade', `tradeList: ${JSON.stringify(tradeList)}`);\n await requestSQL(\n Terminal.fromNodeEnv(),\n buildInsertManyIntoTableSQL(tradeList, 'trade', {\n columns: [\n 'id',\n 'account_id',\n 'product_id',\n 'traded_volume',\n 'traded_value',\n 'traded_price',\n 'direction',\n 'fee',\n 'fee_currency',\n 'created_at',\n ],\n conflictKeys: ['id'],\n }),\n );\n};\n\ndefer(() => accountUid$)\n .pipe(first())\n .subscribe((uid) => {\n const account_id = `okx/${uid}/trading`;\n console.log(formatTime(Date.now()), 'getAccountTrade', `AccountID: ${account_id}`);\n defer(() => getAccountTradeWithAccountId(account_id))\n .pipe(\n //\n timeout(10_000), // 超时设定:10 秒\n tap({\n error: (err) => {\n console.error(formatTime(Date.now()), 'getAccountTradeError', err);\n },\n }),\n repeat({ delay: 30_000 }),\n retry({ delay: 5000 }),\n )\n .subscribe();\n });\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsC,UAAU,EAA8B,MAAM,MAAM,CAAC;AA+LlG,eAAO,MAAM,SAAS,WAAY,MAAM;YAE5B,MAAM;UACR,MAAM;WACL,MAAM;WACN,MAAM;WACN,MAAM;WACN,MAAM;EACsB,CAAC;AAExC,eAAO,MAAM,eAAe,WAAY,MAAM;YAElC,MAAM;QACV,MAAM;EAC+B,CAAC;AAE9C,eAAO,MAAM,OAAO,eAAgB,MAAM,UAAU,MAAM,yBACc,CAAC"}
1
+ {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsC,UAAU,EAA8B,MAAM,MAAM,CAAC;AAiMlG,eAAO,MAAM,SAAS,WAAY,MAAM;YAE5B,MAAM;UACR,MAAM;WACL,MAAM;WACN,MAAM;WACN,MAAM;WACN,MAAM;EACsB,CAAC;AAExC,eAAO,MAAM,eAAe,WAAY,MAAM;YAElC,MAAM;QACV,MAAM;EAC+B,CAAC;AAE9C,eAAO,MAAM,OAAO,eAAgB,MAAM,UAAU,MAAM,yBACc,CAAC"}
package/lib/websocket.js CHANGED
@@ -6,13 +6,14 @@ const utils_1 = require("@yuants/utils");
6
6
  const rxjs_1 = require("rxjs");
7
7
  const MetricsWebSocketConnectionsGauge = protocol_1.PromRegistry.create('gauge', 'okx_websocket_connections', 'Number of active OKX WebSocket connections');
8
8
  const MetricsWebSocketChannelGauge = protocol_1.PromRegistry.create('gauge', 'okx_websocket_channel', 'Number of OKX WebSocket channels subscribed');
9
+ const terminal = protocol_1.Terminal.fromNodeEnv();
9
10
  class OKXWsClient {
10
11
  constructor(path) {
11
12
  this.connected = false;
12
13
  this.baseURL = `wss://ws.okx.com:8443`;
13
14
  // this.instId = instId;
14
15
  this.ws = new WebSocket(`${this.baseURL}/${path}`);
15
- MetricsWebSocketConnectionsGauge.inc({ path });
16
+ MetricsWebSocketConnectionsGauge.inc({ path, terminal_id: terminal.terminal_id });
16
17
  this.pendingSub = [];
17
18
  this.keepAlive = (0, rxjs_1.interval)(25000)
18
19
  .pipe((0, rxjs_1.tap)(() => {
@@ -81,7 +82,7 @@ class OKXWsClient {
81
82
  this.pendingSub.push(JSON.stringify(subMsg));
82
83
  console.info((0, utils_1.formatTime)(Date.now()), `📩 add subscribe for ${channelId} to pending list`);
83
84
  }
84
- MetricsWebSocketChannelGauge.inc({ channel });
85
+ MetricsWebSocketChannelGauge.inc({ channel, terminal_id: terminal.terminal_id });
85
86
  this.subscriptions.add(channelId);
86
87
  if (handler) {
87
88
  this.handlers[channelId] = handler;
@@ -1 +1 @@
1
- {"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"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","sourcesContent":["import { PromRegistry } from '@yuants/protocol';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { catchError, defer, EMPTY, interval, Observable, Subscription, tap, timeout } from 'rxjs';\n\nconst MetricsWebSocketConnectionsGauge = PromRegistry.create(\n 'gauge',\n 'okx_websocket_connections',\n 'Number of active OKX WebSocket connections',\n);\n\nconst MetricsWebSocketChannelGauge = PromRegistry.create(\n 'gauge',\n 'okx_websocket_channel',\n 'Number of OKX WebSocket channels subscribed',\n);\n\nclass OKXWsClient {\n ws: WebSocket;\n connected: boolean = false;\n subscriptions: Set<string>;\n handlers: Record<string, Function>;\n pendingSub: string[];\n keepAlive: Subscription;\n\n baseURL: string = `wss://ws.okx.com:8443`;\n constructor(path: string) {\n // this.instId = instId;\n this.ws = new WebSocket(`${this.baseURL}/${path}`);\n\n MetricsWebSocketConnectionsGauge.inc({ path });\n\n this.pendingSub = [];\n this.keepAlive = interval(25000)\n .pipe(\n tap(() => {\n if (this.connected) {\n this.ws.send('ping');\n }\n }),\n )\n .subscribe();\n // this.ws.\n this.ws.addEventListener('open', () => {\n this.connected = true;\n console.info(formatTime(Date.now()), '✅ WS connected');\n while (this.pendingSub.length > 0) {\n const msg = this.pendingSub.shift();\n if (msg) {\n this.ws.send(msg);\n console.info(formatTime(Date.now()), `📩 Sent subscribe for ${msg}`);\n }\n }\n });\n\n this.ws.addEventListener('message', (raw) => this.handleMessage(raw));\n this.ws.addEventListener('error', (raw) => {\n console.error(formatTime(Date.now()), '❌ WS error', raw);\n });\n this.ws.addEventListener('close', (event) => {\n console.error(formatTime(Date.now()), '❌ WS closed', event);\n\n MetricsWebSocketConnectionsGauge.dec({ path });\n });\n this.subscriptions = new Set();\n this.handlers = {}; // key: channel, value: callback\n }\n\n // 处理消息\n handleMessage(raw: any) {\n if (raw.data === 'pong') {\n return;\n }\n const msg = JSON.parse(raw.data);\n if (msg.arg?.channel) {\n const channelId = encodePath(msg.arg.channel, msg.arg.instId);\n const data = msg.data?.[0];\n if (data && this.handlers[channelId]) {\n this.handlers[channelId](data, msg.arg);\n }\n } else if (msg.event) {\n console.info(formatTime(Date.now()), 'Event:', msg);\n }\n }\n\n // 调用订阅\n subscribe(channel: string, instId?: string, handler?: Function) {\n const channelId = encodePath(channel, instId);\n if (this.subscriptions.has(channelId)) {\n console.info(formatTime(Date.now()), `⚠️ Already subscribed: ${channelId}`);\n return;\n }\n\n const subMsg = {\n op: 'subscribe',\n args: [{ channel, instId }],\n };\n\n if (this.connected) {\n this.ws.send(JSON.stringify(subMsg));\n console.info(formatTime(Date.now()), `📩 Sent subscribe for ${channelId}`);\n } else {\n this.pendingSub.push(JSON.stringify(subMsg));\n console.info(formatTime(Date.now()), `📩 add subscribe for ${channelId} to pending list`);\n }\n MetricsWebSocketChannelGauge.inc({ channel });\n this.subscriptions.add(channelId);\n if (handler) {\n this.handlers[channelId] = handler;\n }\n }\n\n // 取消订阅\n unsubscribe(channel: string, instId?: string) {\n const channelId = encodePath(channel, instId);\n if (!this.subscriptions.has(channelId)) return;\n\n const unSubMsg = {\n op: 'unsubscribe',\n args: [{ channel, instId }],\n };\n\n this.ws.send(JSON.stringify(unSubMsg));\n this.subscriptions.delete(channelId);\n if (this.subscriptions.size === 0) {\n this.keepAlive.unsubscribe();\n }\n MetricsWebSocketChannelGauge.dec({ channel });\n delete this.handlers[channelId];\n console.info(formatTime(Date.now()), `📩 Sent unsubscribe for ${channelId}`);\n }\n}\n\nconst wsPool: {\n path: string;\n client: OKXWsClient;\n requests: number;\n isFull: boolean;\n}[] = [];\n\n// ISSUE: 连接限制:3 次/秒 (基于IP)\n//\n// https://www.okx.com/docs-v5/zh/#overview-websocket-connect\n//\n// 当订阅公有频道时,使用公有服务的地址;当订阅私有频道时,使用私有服务的地址\n//\n// 请求限制:\n//\n// 每个连接 对于 订阅/取消订阅/登录 请求的总次数限制为 480 次/小时\nconst getWsClient = (path: string) => {\n const existing = wsPool.find((item) => item.path === path && !item.isFull);\n if (existing) {\n existing.requests++;\n if (existing.requests >= 480) {\n existing.isFull = true;\n }\n return existing.client;\n }\n const newClient = new OKXWsClient(path);\n wsPool.push({ path, client: newClient, requests: 1, isFull: false });\n return newClient;\n};\n\nconst fromWsChannelAndInstId = <T>(path: string, channel: string, instId: string) =>\n defer(\n () =>\n new Observable<T>((subscriber) => {\n const client = getWsClient(path);\n client.subscribe(channel, instId, (data: T) => {\n subscriber.next(data);\n });\n client.ws.addEventListener('error', (err) => {\n subscriber.error(err);\n });\n client.ws.addEventListener('close', () => {\n subscriber.error('WS Connection Closed');\n });\n subscriber.add(() => {\n client.unsubscribe(channel, instId);\n });\n }),\n ).pipe(\n // 防止单个连接断开导致数据流关闭\n timeout(60_000),\n tap({\n error: (err) => {\n console.info(formatTime(Date.now()), 'WS_SUBSCRIBE_ERROR', channel, instId, err);\n },\n }),\n // 暂时不太确定是否能支持 retry\n // retry({ delay: 1000 }),\n catchError(() => EMPTY),\n );\n\nexport const useTicker = (instId: string) =>\n fromWsChannelAndInstId<{\n instId: string;\n last: string;\n askPx: string;\n bidPx: string;\n askSz: string;\n bidSz: string;\n }>('ws/v5/public', 'tickers', instId);\n\nexport const useOpenInterest = (instId: string) =>\n fromWsChannelAndInstId<{\n instId: string;\n oi: string; // open interest\n }>('ws/v5/public', 'open-interest', instId);\n\nexport const useOHLC = (candleType: string, instId: string) =>\n fromWsChannelAndInstId<string[]>('ws/v5/business', candleType, instId);\n"]}
1
+ {"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"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","sourcesContent":["import { PromRegistry, Terminal } from '@yuants/protocol';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { catchError, defer, EMPTY, interval, Observable, Subscription, tap, timeout } from 'rxjs';\n\nconst MetricsWebSocketConnectionsGauge = PromRegistry.create(\n 'gauge',\n 'okx_websocket_connections',\n 'Number of active OKX WebSocket connections',\n);\n\nconst MetricsWebSocketChannelGauge = PromRegistry.create(\n 'gauge',\n 'okx_websocket_channel',\n 'Number of OKX WebSocket channels subscribed',\n);\n\nconst terminal = Terminal.fromNodeEnv();\n\nclass OKXWsClient {\n ws: WebSocket;\n connected: boolean = false;\n subscriptions: Set<string>;\n handlers: Record<string, Function>;\n pendingSub: string[];\n keepAlive: Subscription;\n\n baseURL: string = `wss://ws.okx.com:8443`;\n constructor(path: string) {\n // this.instId = instId;\n this.ws = new WebSocket(`${this.baseURL}/${path}`);\n\n MetricsWebSocketConnectionsGauge.inc({ path, terminal_id: terminal.terminal_id });\n\n this.pendingSub = [];\n this.keepAlive = interval(25000)\n .pipe(\n tap(() => {\n if (this.connected) {\n this.ws.send('ping');\n }\n }),\n )\n .subscribe();\n // this.ws.\n this.ws.addEventListener('open', () => {\n this.connected = true;\n console.info(formatTime(Date.now()), '✅ WS connected');\n while (this.pendingSub.length > 0) {\n const msg = this.pendingSub.shift();\n if (msg) {\n this.ws.send(msg);\n console.info(formatTime(Date.now()), `📩 Sent subscribe for ${msg}`);\n }\n }\n });\n\n this.ws.addEventListener('message', (raw) => this.handleMessage(raw));\n this.ws.addEventListener('error', (raw) => {\n console.error(formatTime(Date.now()), '❌ WS error', raw);\n });\n this.ws.addEventListener('close', (event) => {\n console.error(formatTime(Date.now()), '❌ WS closed', event);\n\n MetricsWebSocketConnectionsGauge.dec({ path });\n });\n this.subscriptions = new Set();\n this.handlers = {}; // key: channel, value: callback\n }\n\n // 处理消息\n handleMessage(raw: any) {\n if (raw.data === 'pong') {\n return;\n }\n const msg = JSON.parse(raw.data);\n if (msg.arg?.channel) {\n const channelId = encodePath(msg.arg.channel, msg.arg.instId);\n const data = msg.data?.[0];\n if (data && this.handlers[channelId]) {\n this.handlers[channelId](data, msg.arg);\n }\n } else if (msg.event) {\n console.info(formatTime(Date.now()), 'Event:', msg);\n }\n }\n\n // 调用订阅\n subscribe(channel: string, instId?: string, handler?: Function) {\n const channelId = encodePath(channel, instId);\n if (this.subscriptions.has(channelId)) {\n console.info(formatTime(Date.now()), `⚠️ Already subscribed: ${channelId}`);\n return;\n }\n\n const subMsg = {\n op: 'subscribe',\n args: [{ channel, instId }],\n };\n\n if (this.connected) {\n this.ws.send(JSON.stringify(subMsg));\n console.info(formatTime(Date.now()), `📩 Sent subscribe for ${channelId}`);\n } else {\n this.pendingSub.push(JSON.stringify(subMsg));\n console.info(formatTime(Date.now()), `📩 add subscribe for ${channelId} to pending list`);\n }\n MetricsWebSocketChannelGauge.inc({ channel, terminal_id: terminal.terminal_id });\n this.subscriptions.add(channelId);\n if (handler) {\n this.handlers[channelId] = handler;\n }\n }\n\n // 取消订阅\n unsubscribe(channel: string, instId?: string) {\n const channelId = encodePath(channel, instId);\n if (!this.subscriptions.has(channelId)) return;\n\n const unSubMsg = {\n op: 'unsubscribe',\n args: [{ channel, instId }],\n };\n\n this.ws.send(JSON.stringify(unSubMsg));\n this.subscriptions.delete(channelId);\n if (this.subscriptions.size === 0) {\n this.keepAlive.unsubscribe();\n }\n MetricsWebSocketChannelGauge.dec({ channel });\n delete this.handlers[channelId];\n console.info(formatTime(Date.now()), `📩 Sent unsubscribe for ${channelId}`);\n }\n}\n\nconst wsPool: {\n path: string;\n client: OKXWsClient;\n requests: number;\n isFull: boolean;\n}[] = [];\n\n// ISSUE: 连接限制:3 次/秒 (基于IP)\n//\n// https://www.okx.com/docs-v5/zh/#overview-websocket-connect\n//\n// 当订阅公有频道时,使用公有服务的地址;当订阅私有频道时,使用私有服务的地址\n//\n// 请求限制:\n//\n// 每个连接 对于 订阅/取消订阅/登录 请求的总次数限制为 480 次/小时\nconst getWsClient = (path: string) => {\n const existing = wsPool.find((item) => item.path === path && !item.isFull);\n if (existing) {\n existing.requests++;\n if (existing.requests >= 480) {\n existing.isFull = true;\n }\n return existing.client;\n }\n const newClient = new OKXWsClient(path);\n wsPool.push({ path, client: newClient, requests: 1, isFull: false });\n return newClient;\n};\n\nconst fromWsChannelAndInstId = <T>(path: string, channel: string, instId: string) =>\n defer(\n () =>\n new Observable<T>((subscriber) => {\n const client = getWsClient(path);\n client.subscribe(channel, instId, (data: T) => {\n subscriber.next(data);\n });\n client.ws.addEventListener('error', (err) => {\n subscriber.error(err);\n });\n client.ws.addEventListener('close', () => {\n subscriber.error('WS Connection Closed');\n });\n subscriber.add(() => {\n client.unsubscribe(channel, instId);\n });\n }),\n ).pipe(\n // 防止单个连接断开导致数据流关闭\n timeout(60_000),\n tap({\n error: (err) => {\n console.info(formatTime(Date.now()), 'WS_SUBSCRIBE_ERROR', channel, instId, err);\n },\n }),\n // 暂时不太确定是否能支持 retry\n // retry({ delay: 1000 }),\n catchError(() => EMPTY),\n );\n\nexport const useTicker = (instId: string) =>\n fromWsChannelAndInstId<{\n instId: string;\n last: string;\n askPx: string;\n bidPx: string;\n askSz: string;\n bidSz: string;\n }>('ws/v5/public', 'tickers', instId);\n\nexport const useOpenInterest = (instId: string) =>\n fromWsChannelAndInstId<{\n instId: string;\n oi: string; // open interest\n }>('ws/v5/public', 'open-interest', instId);\n\nexport const useOHLC = (candleType: string, instId: string) =>\n fromWsChannelAndInstId<string[]>('ws/v5/business', candleType, instId);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuants/vendor-okx",
3
- "version": "0.22.16",
3
+ "version": "0.22.17",
4
4
  "bin": "lib/cli.js",
5
5
  "main": "lib/index.js",
6
6
  "files": [
@@ -1,13 +1,13 @@
1
1
  {
2
- "apps/vendor-okx/CHANGELOG.json": "d4ce222125b9ce7e9a4af1d18cec78928b23df66",
3
- "apps/vendor-okx/CHANGELOG.md": "97f6bb177cf81d5b67290f2dd21e566b0371ab48",
2
+ "apps/vendor-okx/CHANGELOG.json": "3ae77b14d8b3d576465e7f597c7052ea964d325e",
3
+ "apps/vendor-okx/CHANGELOG.md": "26281edebbe13d8484355a1191376d40cf164534",
4
4
  "apps/vendor-okx/README.md": "ac3d1f6c4c8d73066664699b0bb1b01db02e67a2",
5
5
  "apps/vendor-okx/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c",
6
6
  "apps/vendor-okx/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
7
7
  "apps/vendor-okx/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
8
8
  "apps/vendor-okx/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
9
9
  "apps/vendor-okx/etc/vendor-okx.api.md": "92c54ccd547d2ad81ca6088158ca193e85c208df",
10
- "apps/vendor-okx/package.json": "9a733398dd18e1fad573a1c037680ae4a61d2783",
10
+ "apps/vendor-okx/package.json": "539e2953a5329d80bdea1e82c0e75d33451a2233",
11
11
  "apps/vendor-okx/src/account.ts": "a5d141e20b48f57ded83d35d395abb438ed11848",
12
12
  "apps/vendor-okx/src/api.ts": "a818895fddbfe76eab517cd0bbba9fafe6c0c2cc",
13
13
  "apps/vendor-okx/src/cli.ts": "9bf6b5559a6c6f33da20e74cc6c5d702c60ec891",
@@ -23,8 +23,8 @@
23
23
  "apps/vendor-okx/src/quote.ts": "40b3a637b9348f380d6461b50ccc07eaea3fb635",
24
24
  "apps/vendor-okx/src/services.ts": "7b7df830a6d78b6de5cee44bbcec66f282ab53ab",
25
25
  "apps/vendor-okx/src/strategy-account.ts": "b5669b8b9338792597d16ed611e8569b59266fe4",
26
- "apps/vendor-okx/src/trade.ts": "7e9f345bda2c9584d25a0ba0f0224eb2839f0ec1",
27
- "apps/vendor-okx/src/websocket.ts": "060aa81c4f9a57a939927de4497fb46302963812",
26
+ "apps/vendor-okx/src/trade.ts": "beab4381745eb173faf11ccedd3e80636659e3e9",
27
+ "apps/vendor-okx/src/websocket.ts": "6c0199bbb9db714ec96b59d90b35b3c801975194",
28
28
  "apps/vendor-okx/tsconfig.json": "81da8f78196974b5d15da0edb6b2d9f48641063c",
29
29
  "apps/vendor-okx/.rush/temp/shrinkwrap-deps.json": "0a6205550d411d42b6d36324572e5e2a0ba166b2",
30
30
  "libraries/protocol/temp/package-deps.json": "ff231b7689ff7d151498b496f70944d4598fcf33",