@yuants/vendor-okx 0.18.0 → 0.18.2
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/interest_rate.js +1 -1
- package/dist/interest_rate.js.map +1 -1
- package/dist/ohlc.js +1 -1
- package/dist/ohlc.js.map +1 -1
- package/dist/websocket.js +5 -4
- package/dist/websocket.js.map +1 -1
- package/lib/interest_rate.js +1 -1
- package/lib/interest_rate.js.map +1 -1
- package/lib/ohlc.js +1 -1
- package/lib/ohlc.js.map +1 -1
- package/lib/websocket.d.ts +2 -1
- package/lib/websocket.d.ts.map +1 -1
- package/lib/websocket.js +5 -4
- package/lib/websocket.js.map +1 -1
- package/package.json +2 -2
- package/temp/image-tag +1 -1
- package/temp/package-deps.json +7 -7
package/dist/interest_rate.js
CHANGED
@@ -21,7 +21,7 @@ createSQLWriter(Terminal.fromNodeEnv(), {
|
|
21
21
|
data$: usdtSwapProducts$.pipe(mergeAll(), map((x) => ({
|
22
22
|
series_id: encodePath(x.datasource_id, x.product_id),
|
23
23
|
table_name: 'interest_rate',
|
24
|
-
cron_pattern: '0 * * * *
|
24
|
+
cron_pattern: '0 * * * *',
|
25
25
|
cron_timezone: 'UTC',
|
26
26
|
disabled: false,
|
27
27
|
replay_count: 0,
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"interest_rate.js","sourceRoot":"","sources":["../src/interest_rate.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,eAAe,CAAwB,QAAQ,CAAC,WAAW,EAAE,EAAE;IAC7D,KAAK,EAAE,iBAAiB,CAAC,IAAI,CAC3B,QAAQ,EAAE,EACV,GAAG,CACD,CAAC,CAAC,EAAyB,EAAE,CAAC,CAAC;QAC7B,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,UAAU,CAAC;QACpD,UAAU,EAAE,eAAe;QAC3B,YAAY,EAAE,
|
1
|
+
{"version":3,"file":"interest_rate.js","sourceRoot":"","sources":["../src/interest_rate.ts"],"names":[],"mappings":"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","sourcesContent":["import { IInterestRate } from '@yuants/data-interest-rate';\nimport { createSeriesProvider, ISeriesCollectingTask } from '@yuants/data-series';\nimport { Terminal } from '@yuants/protocol';\nimport { createSQLWriter } from '@yuants/sql';\nimport { decodePath, encodePath, formatTime } from '@yuants/utils';\nimport { firstValueFrom, map, mergeAll, timer } from 'rxjs';\nimport { client } from './api';\nimport { usdtSwapProducts$ } from './product';\n\ncreateSQLWriter<ISeriesCollectingTask>(Terminal.fromNodeEnv(), {\n data$: usdtSwapProducts$.pipe(\n mergeAll(),\n map(\n (x): ISeriesCollectingTask => ({\n series_id: encodePath(x.datasource_id, x.product_id),\n table_name: 'interest_rate',\n cron_pattern: '0 * * * *', // 每小时执行一次\n cron_timezone: 'UTC',\n disabled: false,\n replay_count: 0,\n }),\n ),\n ),\n tableName: 'series_collecting_task',\n writeInterval: 1000,\n conflictKeys: ['series_id', 'table_name'],\n});\n\ncreateSeriesProvider<IInterestRate>(Terminal.fromNodeEnv(), {\n tableName: 'interest_rate',\n series_id_prefix_parts: ['OKX'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({ series_id, started_at, ended_at }) {\n const start = started_at || 0;\n const end = ended_at || Date.now();\n const [datasource_id, product_id] = decodePath(series_id);\n const [instType, instId] = decodePath(product_id);\n\n if (instType === 'SWAP') {\n let current_end = end;\n while (true) {\n // 接口行为备注:向前翻页,时间降序,不含 after 当前时间点\n const res = await client.getFundingRateHistory({\n instId: instId,\n after: `${current_end}`,\n });\n if (res.code !== '0') {\n throw `getFundingRateHistory failed: ${res.code} ${res.msg}`;\n }\n // 如果没有数据了,就退出\n if (res.data.length === 0) {\n break;\n }\n console.info(formatTime(Date.now()), 'getFundingRateHistory', JSON.stringify(res.data));\n const data = res.data.map(\n (v): IInterestRate => ({\n series_id: series_id,\n product_id,\n datasource_id,\n created_at: formatTime(+v.fundingTime),\n long_rate: `${-v.fundingRate}`,\n short_rate: `${v.fundingRate}`,\n settlement_price: '',\n }),\n );\n yield data;\n current_end = +res.data[res.data.length - 1].fundingTime;\n if (current_end <= start) {\n break;\n }\n // for API rate limit\n await firstValueFrom(timer(1000));\n }\n }\n\n if (instType === 'MARGIN') {\n // MARGIN/BTC-USDT\n const [base, quote] = instId.split('-');\n let current_end = end;\n while (true) {\n const resBase = await client.getLendingRateHistory({ ccy: base, after: `${current_end}` });\n const resQuote = await client.getLendingRateHistory({ ccy: quote, after: `${current_end}` });\n\n if (resBase.code !== '0') {\n throw `getLendingRateHistory failed: ${resBase.code} ${resBase.msg}`;\n }\n if (resBase.data.length === 0) {\n break;\n }\n console.info(formatTime(Date.now()), 'getLendingRateHistory', JSON.stringify(resBase.data));\n\n if (resQuote.code !== '0') {\n throw `getLendingRateHistory failed: ${resQuote.code} ${resQuote.msg}`;\n }\n if (resQuote.data.length === 0) {\n break;\n }\n console.info(formatTime(Date.now()), 'getLendingRateHistory', JSON.stringify(resQuote.data));\n\n // 做多时,借入 quote 的资金,做空时,借入 base 的资金\n // 用 quote 的 rate 作为 long_rate,base 的 rate 作为 short_rate\n\n const mapTsToBaseRate = new Map<string, string>();\n resBase.data.forEach((v) => {\n mapTsToBaseRate.set(v.ts, v.rate);\n });\n\n const data: IInterestRate[] = [];\n\n resQuote.data.forEach((v) => {\n if (!mapTsToBaseRate.has(v.ts)) return;\n const long_rate = +v.rate / 365 / 24; // 转换为小时利率\n const short_rate = +mapTsToBaseRate.get(v.ts)! / 365 / 24; // 转换为小时利率\n data.push({\n series_id,\n product_id,\n datasource_id,\n created_at: formatTime(+v.ts),\n long_rate: `${-long_rate}`,\n short_rate: `${-short_rate}`,\n settlement_price: '',\n });\n });\n\n yield data;\n current_end = new Date(data[data.length - 1].created_at).getTime();\n if (current_end <= start) {\n break;\n }\n // for API rate limit\n await firstValueFrom(timer(1000));\n }\n }\n },\n});\n"]}
|
package/dist/ohlc.js
CHANGED
@@ -130,7 +130,7 @@ Terminal.fromNodeEnv().channel.publishChannel('ohlc', { pattern: `^OKX/` }, (ser
|
|
130
130
|
console.info(formatTime(Date.now()), `subscribe`, series_id);
|
131
131
|
return new Observable((subscriber) => {
|
132
132
|
console.info(formatTime(Date.now()), `subscribe`, candleType, instId);
|
133
|
-
const okxBusinessWsClient = new OKXWsClient('
|
133
|
+
const okxBusinessWsClient = new OKXWsClient('ws/v5/business');
|
134
134
|
okxBusinessWsClient.subscribe(candleType, instId, async (data) => {
|
135
135
|
const created_at = Number(data[0]);
|
136
136
|
const closed_at = created_at + offset;
|
package/dist/ohlc.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ohlc.js","sourceRoot":"","sources":["../src/ohlc.ts"],"names":[],"mappings":"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","sourcesContent":["import { IOHLC } from '@yuants/data-ohlc';\nimport { createSeriesProvider } from '@yuants/data-series';\nimport { Terminal } from '@yuants/protocol';\nimport { convertDurationToOffset, decodePath, encodePath, formatTime } from '@yuants/utils';\nimport { firstValueFrom, Observable, of, timer } from 'rxjs';\nimport { client } from './api';\nimport { OKXWsClient } from './websocket';\nimport { writeToSQL } from '@yuants/sql';\n\n// 时间粒度,默认值1m\n// 如 [1m/3m/5m/15m/30m/1H/2H/4H]\n// 香港时间开盘价k线:[6H/12H/1D/1W/1M]\n// UTC时间开盘价k线:[6Hutc/12Hutc/1Dutc/1Wutc/1Mutc]\n\nconst DURATION_TO_OKX_BAR_TYPE: Record<string, string> = {\n PT1M: '1m',\n PT3M: '3m',\n PT5M: '5m',\n PT15M: '15m',\n PT30M: '30m',\n\n PT1H: '1H',\n PT2H: '2H',\n PT4H: '4H',\n PT6H: '6H',\n PT12H: '12H',\n\n P1D: '1D',\n P1W: '1W',\n P1M: '1M',\n};\n\nconst DURATION_TO_OKX_CANDLE_TYPE: Record<string, string> = {\n PT1M: 'mark-price-candle1m',\n PT3M: 'mark-price-candle3m',\n PT5M: 'mark-price-candle5m',\n PT15M: 'mark-price-candle15m',\n PT30M: 'mark-price-candle30m',\n\n PT1H: 'mark-price-candle1H',\n PT2H: 'mark-price-candle2H',\n PT4H: 'mark-price-candle4H',\n PT6H: 'mark-price-candle6H',\n PT12H: 'mark-price-candle12H',\n\n P1D: 'mark-price-candle1D',\n P1W: 'mark-price-candle1W',\n P1M: 'mark-price-candle1M',\n};\n\ncreateSeriesProvider<IOHLC>(Terminal.fromNodeEnv(), {\n tableName: 'ohlc',\n series_id_prefix_parts: ['OKX'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({ series_id, ended_at }) {\n const [datasource_id, product_id, duration] = decodePath(series_id);\n const offset = convertDurationToOffset(duration);\n if (!datasource_id) {\n throw 'datasource_id is required';\n }\n if (!product_id) {\n throw 'product_id is required';\n }\n if (!offset) {\n throw 'duration is invalid';\n }\n const [instType, instId] = decodePath(product_id);\n if (!instId) {\n throw `invalid product_id: ${product_id}`;\n }\n\n const bar = DURATION_TO_OKX_BAR_TYPE[duration];\n if (!bar) {\n throw `unsupported duration: ${duration}`;\n }\n\n let currentStartTime = ended_at;\n\n while (true) {\n // 向前翻页,时间降序,不含 after 时间点\n const res = await client.getHistoryCandles({\n instId,\n bar,\n after: `${currentStartTime}`,\n limit: '100',\n });\n if (res.code !== '0') {\n throw `API failed: ${res.code} ${res.msg}`;\n }\n if (res.data.length === 0) break;\n currentStartTime = +res.data[res.data.length - 1][0];\n const data = res.data.map(\n (x): IOHLC => ({\n series_id,\n datasource_id,\n product_id,\n duration,\n created_at: formatTime(+x[0]),\n closed_at: formatTime(+x[0] + offset),\n open: x[1],\n high: x[2],\n low: x[3],\n close: x[4],\n volume: x[5],\n open_interest: '0',\n }),\n );\n yield data;\n await firstValueFrom(timer(1000));\n }\n },\n});\n\nTerminal.fromNodeEnv().channel.publishChannel('ohlc', { pattern: `^OKX/` }, (series_id) => {\n // const [] = decodePath(args)\n const [datasource_id, product_id, duration] = decodePath(series_id);\n const [, instId] = decodePath(product_id);\n const offset = convertDurationToOffset(duration);\n if (!datasource_id) {\n throw 'datasource_id is required';\n }\n if (!product_id) {\n throw 'product_id is required';\n }\n if (!offset) {\n throw 'duration is invalid';\n }\n const candleType = DURATION_TO_OKX_CANDLE_TYPE[duration];\n console.info(formatTime(Date.now()), `subscribe`, series_id);\n return new Observable<IOHLC>((subscriber) => {\n console.info(formatTime(Date.now()), `subscribe`, candleType, instId);\n const okxBusinessWsClient = new OKXWsClient('wss://wspap.okx.com:8443/ws/v5/business');\n okxBusinessWsClient.subscribe(candleType, instId, async (data: string[]) => {\n const created_at = Number(data[0]);\n const closed_at = created_at + offset;\n const open = data[1];\n const high = data[2];\n const low = data[3];\n const close = data[4];\n if (isNaN(closed_at)) {\n return;\n }\n console.info(formatTime(Date.now()), `insertData`, data);\n const cancelData: IOHLC = {\n closed_at: formatTime(closed_at),\n created_at: formatTime(created_at),\n open,\n high,\n low,\n close,\n series_id,\n datasource_id,\n duration,\n product_id,\n volume: '0',\n open_interest: '0',\n };\n subscriber.next(cancelData);\n });\n return () => {\n okxBusinessWsClient.unsubscribe(candleType, instId);\n };\n }).pipe(\n writeToSQL({\n tableName: 'ohlc',\n conflictKeys: ['created_at', 'series_id'],\n writeInterval: 1000,\n terminal: Terminal.fromNodeEnv(),\n keyFn: (x) => encodePath(x.created_at, x.series_id),\n }),\n );\n});\n"]}
|
1
|
+
{"version":3,"file":"ohlc.js","sourceRoot":"","sources":["../src/ohlc.ts"],"names":[],"mappings":"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","sourcesContent":["import { IOHLC } from '@yuants/data-ohlc';\nimport { createSeriesProvider } from '@yuants/data-series';\nimport { Terminal } from '@yuants/protocol';\nimport { convertDurationToOffset, decodePath, encodePath, formatTime } from '@yuants/utils';\nimport { firstValueFrom, Observable, of, timer } from 'rxjs';\nimport { client } from './api';\nimport { OKXWsClient } from './websocket';\nimport { writeToSQL } from '@yuants/sql';\n\n// 时间粒度,默认值1m\n// 如 [1m/3m/5m/15m/30m/1H/2H/4H]\n// 香港时间开盘价k线:[6H/12H/1D/1W/1M]\n// UTC时间开盘价k线:[6Hutc/12Hutc/1Dutc/1Wutc/1Mutc]\n\nconst DURATION_TO_OKX_BAR_TYPE: Record<string, string> = {\n PT1M: '1m',\n PT3M: '3m',\n PT5M: '5m',\n PT15M: '15m',\n PT30M: '30m',\n\n PT1H: '1H',\n PT2H: '2H',\n PT4H: '4H',\n PT6H: '6H',\n PT12H: '12H',\n\n P1D: '1D',\n P1W: '1W',\n P1M: '1M',\n};\n\nconst DURATION_TO_OKX_CANDLE_TYPE: Record<string, string> = {\n PT1M: 'mark-price-candle1m',\n PT3M: 'mark-price-candle3m',\n PT5M: 'mark-price-candle5m',\n PT15M: 'mark-price-candle15m',\n PT30M: 'mark-price-candle30m',\n\n PT1H: 'mark-price-candle1H',\n PT2H: 'mark-price-candle2H',\n PT4H: 'mark-price-candle4H',\n PT6H: 'mark-price-candle6H',\n PT12H: 'mark-price-candle12H',\n\n P1D: 'mark-price-candle1D',\n P1W: 'mark-price-candle1W',\n P1M: 'mark-price-candle1M',\n};\n\ncreateSeriesProvider<IOHLC>(Terminal.fromNodeEnv(), {\n tableName: 'ohlc',\n series_id_prefix_parts: ['OKX'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({ series_id, ended_at }) {\n const [datasource_id, product_id, duration] = decodePath(series_id);\n const offset = convertDurationToOffset(duration);\n if (!datasource_id) {\n throw 'datasource_id is required';\n }\n if (!product_id) {\n throw 'product_id is required';\n }\n if (!offset) {\n throw 'duration is invalid';\n }\n const [instType, instId] = decodePath(product_id);\n if (!instId) {\n throw `invalid product_id: ${product_id}`;\n }\n\n const bar = DURATION_TO_OKX_BAR_TYPE[duration];\n if (!bar) {\n throw `unsupported duration: ${duration}`;\n }\n\n let currentStartTime = ended_at;\n\n while (true) {\n // 向前翻页,时间降序,不含 after 时间点\n const res = await client.getHistoryCandles({\n instId,\n bar,\n after: `${currentStartTime}`,\n limit: '100',\n });\n if (res.code !== '0') {\n throw `API failed: ${res.code} ${res.msg}`;\n }\n if (res.data.length === 0) break;\n currentStartTime = +res.data[res.data.length - 1][0];\n const data = res.data.map(\n (x): IOHLC => ({\n series_id,\n datasource_id,\n product_id,\n duration,\n created_at: formatTime(+x[0]),\n closed_at: formatTime(+x[0] + offset),\n open: x[1],\n high: x[2],\n low: x[3],\n close: x[4],\n volume: x[5],\n open_interest: '0',\n }),\n );\n yield data;\n await firstValueFrom(timer(1000));\n }\n },\n});\n\nTerminal.fromNodeEnv().channel.publishChannel('ohlc', { pattern: `^OKX/` }, (series_id) => {\n // const [] = decodePath(args)\n const [datasource_id, product_id, duration] = decodePath(series_id);\n const [, instId] = decodePath(product_id);\n const offset = convertDurationToOffset(duration);\n if (!datasource_id) {\n throw 'datasource_id is required';\n }\n if (!product_id) {\n throw 'product_id is required';\n }\n if (!offset) {\n throw 'duration is invalid';\n }\n const candleType = DURATION_TO_OKX_CANDLE_TYPE[duration];\n console.info(formatTime(Date.now()), `subscribe`, series_id);\n return new Observable<IOHLC>((subscriber) => {\n console.info(formatTime(Date.now()), `subscribe`, candleType, instId);\n const okxBusinessWsClient = new OKXWsClient('ws/v5/business');\n okxBusinessWsClient.subscribe(candleType, instId, async (data: string[]) => {\n const created_at = Number(data[0]);\n const closed_at = created_at + offset;\n const open = data[1];\n const high = data[2];\n const low = data[3];\n const close = data[4];\n if (isNaN(closed_at)) {\n return;\n }\n console.info(formatTime(Date.now()), `insertData`, data);\n const cancelData: IOHLC = {\n closed_at: formatTime(closed_at),\n created_at: formatTime(created_at),\n open,\n high,\n low,\n close,\n series_id,\n datasource_id,\n duration,\n product_id,\n volume: '0',\n open_interest: '0',\n };\n subscriber.next(cancelData);\n });\n return () => {\n okxBusinessWsClient.unsubscribe(candleType, instId);\n };\n }).pipe(\n writeToSQL({\n tableName: 'ohlc',\n conflictKeys: ['created_at', 'series_id'],\n writeInterval: 1000,\n terminal: Terminal.fromNodeEnv(),\n keyFn: (x) => encodePath(x.created_at, x.series_id),\n }),\n );\n});\n"]}
|
package/dist/websocket.js
CHANGED
@@ -2,10 +2,11 @@ import { encodePath, formatTime } from '@yuants/utils';
|
|
2
2
|
import { interval, tap } from 'rxjs';
|
3
3
|
// import WebSocket from 'ws';
|
4
4
|
export class OKXWsClient {
|
5
|
-
constructor(
|
5
|
+
constructor(path) {
|
6
6
|
this.connected = false;
|
7
|
+
this.baseURL = `wss://ws.okx.com:8443`;
|
7
8
|
// this.instId = instId;
|
8
|
-
this.ws = new WebSocket(
|
9
|
+
this.ws = new WebSocket(`${this.baseURL}/${path}`);
|
9
10
|
this.pendingSub = [];
|
10
11
|
this.keepAlive = interval(25000)
|
11
12
|
.pipe(tap(() => {
|
@@ -45,7 +46,7 @@ export class OKXWsClient {
|
|
45
46
|
}
|
46
47
|
}
|
47
48
|
else if (msg.event) {
|
48
|
-
console.info('Event:', msg);
|
49
|
+
console.info(formatTime(Date.now()), 'Event:', msg);
|
49
50
|
}
|
50
51
|
}
|
51
52
|
// 调用订阅
|
@@ -87,7 +88,7 @@ export class OKXWsClient {
|
|
87
88
|
this.keepAlive.unsubscribe();
|
88
89
|
}
|
89
90
|
delete this.handlers[channelId];
|
90
|
-
console.info(`📩 Sent unsubscribe for ${channelId}`);
|
91
|
+
console.info(formatTime(Date.now()), `📩 Sent unsubscribe for ${channelId}`);
|
91
92
|
}
|
92
93
|
}
|
93
94
|
//# sourceMappingURL=websocket.js.map
|
package/dist/websocket.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAgB,GAAG,EAAE,MAAM,MAAM,CAAC;AACnD,8BAA8B;AAE9B,MAAM,OAAO,WAAW;
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"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","sourcesContent":["import { encodePath, formatTime } from '@yuants/utils';\nimport { interval, Subscription, tap } from 'rxjs';\n// import WebSocket from 'ws';\n\nexport class 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 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.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 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 delete this.handlers[channelId];\n console.info(formatTime(Date.now()), `📩 Sent unsubscribe for ${channelId}`);\n }\n}\n"]}
|
package/lib/interest_rate.js
CHANGED
@@ -23,7 +23,7 @@ const product_1 = require("./product");
|
|
23
23
|
data$: product_1.usdtSwapProducts$.pipe((0, rxjs_1.mergeAll)(), (0, rxjs_1.map)((x) => ({
|
24
24
|
series_id: (0, utils_1.encodePath)(x.datasource_id, x.product_id),
|
25
25
|
table_name: 'interest_rate',
|
26
|
-
cron_pattern: '0 * * * *
|
26
|
+
cron_pattern: '0 * * * *',
|
27
27
|
cron_timezone: 'UTC',
|
28
28
|
disabled: false,
|
29
29
|
replay_count: 0,
|
package/lib/interest_rate.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"interest_rate.js","sourceRoot":"","sources":["../src/interest_rate.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AACA,qDAAkF;AAClF,+CAA4C;AAC5C,qCAA8C;AAC9C,yCAAmE;AACnE,+BAA4D;AAC5D,+BAA+B;AAC/B,uCAA8C;AAE9C,IAAA,qBAAe,EAAwB,mBAAQ,CAAC,WAAW,EAAE,EAAE;IAC7D,KAAK,EAAE,2BAAiB,CAAC,IAAI,CAC3B,IAAA,eAAQ,GAAE,EACV,IAAA,UAAG,EACD,CAAC,CAAC,EAAyB,EAAE,CAAC,CAAC;QAC7B,SAAS,EAAE,IAAA,kBAAU,EAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,UAAU,CAAC;QACpD,UAAU,EAAE,eAAe;QAC3B,YAAY,EAAE,
|
1
|
+
{"version":3,"file":"interest_rate.js","sourceRoot":"","sources":["../src/interest_rate.ts"],"names":[],"mappings":"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","sourcesContent":["import { IInterestRate } from '@yuants/data-interest-rate';\nimport { createSeriesProvider, ISeriesCollectingTask } from '@yuants/data-series';\nimport { Terminal } from '@yuants/protocol';\nimport { createSQLWriter } from '@yuants/sql';\nimport { decodePath, encodePath, formatTime } from '@yuants/utils';\nimport { firstValueFrom, map, mergeAll, timer } from 'rxjs';\nimport { client } from './api';\nimport { usdtSwapProducts$ } from './product';\n\ncreateSQLWriter<ISeriesCollectingTask>(Terminal.fromNodeEnv(), {\n data$: usdtSwapProducts$.pipe(\n mergeAll(),\n map(\n (x): ISeriesCollectingTask => ({\n series_id: encodePath(x.datasource_id, x.product_id),\n table_name: 'interest_rate',\n cron_pattern: '0 * * * *', // 每小时执行一次\n cron_timezone: 'UTC',\n disabled: false,\n replay_count: 0,\n }),\n ),\n ),\n tableName: 'series_collecting_task',\n writeInterval: 1000,\n conflictKeys: ['series_id', 'table_name'],\n});\n\ncreateSeriesProvider<IInterestRate>(Terminal.fromNodeEnv(), {\n tableName: 'interest_rate',\n series_id_prefix_parts: ['OKX'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({ series_id, started_at, ended_at }) {\n const start = started_at || 0;\n const end = ended_at || Date.now();\n const [datasource_id, product_id] = decodePath(series_id);\n const [instType, instId] = decodePath(product_id);\n\n if (instType === 'SWAP') {\n let current_end = end;\n while (true) {\n // 接口行为备注:向前翻页,时间降序,不含 after 当前时间点\n const res = await client.getFundingRateHistory({\n instId: instId,\n after: `${current_end}`,\n });\n if (res.code !== '0') {\n throw `getFundingRateHistory failed: ${res.code} ${res.msg}`;\n }\n // 如果没有数据了,就退出\n if (res.data.length === 0) {\n break;\n }\n console.info(formatTime(Date.now()), 'getFundingRateHistory', JSON.stringify(res.data));\n const data = res.data.map(\n (v): IInterestRate => ({\n series_id: series_id,\n product_id,\n datasource_id,\n created_at: formatTime(+v.fundingTime),\n long_rate: `${-v.fundingRate}`,\n short_rate: `${v.fundingRate}`,\n settlement_price: '',\n }),\n );\n yield data;\n current_end = +res.data[res.data.length - 1].fundingTime;\n if (current_end <= start) {\n break;\n }\n // for API rate limit\n await firstValueFrom(timer(1000));\n }\n }\n\n if (instType === 'MARGIN') {\n // MARGIN/BTC-USDT\n const [base, quote] = instId.split('-');\n let current_end = end;\n while (true) {\n const resBase = await client.getLendingRateHistory({ ccy: base, after: `${current_end}` });\n const resQuote = await client.getLendingRateHistory({ ccy: quote, after: `${current_end}` });\n\n if (resBase.code !== '0') {\n throw `getLendingRateHistory failed: ${resBase.code} ${resBase.msg}`;\n }\n if (resBase.data.length === 0) {\n break;\n }\n console.info(formatTime(Date.now()), 'getLendingRateHistory', JSON.stringify(resBase.data));\n\n if (resQuote.code !== '0') {\n throw `getLendingRateHistory failed: ${resQuote.code} ${resQuote.msg}`;\n }\n if (resQuote.data.length === 0) {\n break;\n }\n console.info(formatTime(Date.now()), 'getLendingRateHistory', JSON.stringify(resQuote.data));\n\n // 做多时,借入 quote 的资金,做空时,借入 base 的资金\n // 用 quote 的 rate 作为 long_rate,base 的 rate 作为 short_rate\n\n const mapTsToBaseRate = new Map<string, string>();\n resBase.data.forEach((v) => {\n mapTsToBaseRate.set(v.ts, v.rate);\n });\n\n const data: IInterestRate[] = [];\n\n resQuote.data.forEach((v) => {\n if (!mapTsToBaseRate.has(v.ts)) return;\n const long_rate = +v.rate / 365 / 24; // 转换为小时利率\n const short_rate = +mapTsToBaseRate.get(v.ts)! / 365 / 24; // 转换为小时利率\n data.push({\n series_id,\n product_id,\n datasource_id,\n created_at: formatTime(+v.ts),\n long_rate: `${-long_rate}`,\n short_rate: `${-short_rate}`,\n settlement_price: '',\n });\n });\n\n yield data;\n current_end = new Date(data[data.length - 1].created_at).getTime();\n if (current_end <= start) {\n break;\n }\n // for API rate limit\n await firstValueFrom(timer(1000));\n }\n }\n },\n});\n"]}
|
package/lib/ohlc.js
CHANGED
@@ -132,7 +132,7 @@ protocol_1.Terminal.fromNodeEnv().channel.publishChannel('ohlc', { pattern: `^OK
|
|
132
132
|
console.info((0, utils_1.formatTime)(Date.now()), `subscribe`, series_id);
|
133
133
|
return new rxjs_1.Observable((subscriber) => {
|
134
134
|
console.info((0, utils_1.formatTime)(Date.now()), `subscribe`, candleType, instId);
|
135
|
-
const okxBusinessWsClient = new websocket_1.OKXWsClient('
|
135
|
+
const okxBusinessWsClient = new websocket_1.OKXWsClient('ws/v5/business');
|
136
136
|
okxBusinessWsClient.subscribe(candleType, instId, async (data) => {
|
137
137
|
const created_at = Number(data[0]);
|
138
138
|
const closed_at = created_at + offset;
|
package/lib/ohlc.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ohlc.js","sourceRoot":"","sources":["../src/ohlc.ts"],"names":[],"mappings":"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
|
1
|
+
{"version":3,"file":"ohlc.js","sourceRoot":"","sources":["../src/ohlc.ts"],"names":[],"mappings":"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","sourcesContent":["import { IOHLC } from '@yuants/data-ohlc';\nimport { createSeriesProvider } from '@yuants/data-series';\nimport { Terminal } from '@yuants/protocol';\nimport { convertDurationToOffset, decodePath, encodePath, formatTime } from '@yuants/utils';\nimport { firstValueFrom, Observable, of, timer } from 'rxjs';\nimport { client } from './api';\nimport { OKXWsClient } from './websocket';\nimport { writeToSQL } from '@yuants/sql';\n\n// 时间粒度,默认值1m\n// 如 [1m/3m/5m/15m/30m/1H/2H/4H]\n// 香港时间开盘价k线:[6H/12H/1D/1W/1M]\n// UTC时间开盘价k线:[6Hutc/12Hutc/1Dutc/1Wutc/1Mutc]\n\nconst DURATION_TO_OKX_BAR_TYPE: Record<string, string> = {\n PT1M: '1m',\n PT3M: '3m',\n PT5M: '5m',\n PT15M: '15m',\n PT30M: '30m',\n\n PT1H: '1H',\n PT2H: '2H',\n PT4H: '4H',\n PT6H: '6H',\n PT12H: '12H',\n\n P1D: '1D',\n P1W: '1W',\n P1M: '1M',\n};\n\nconst DURATION_TO_OKX_CANDLE_TYPE: Record<string, string> = {\n PT1M: 'mark-price-candle1m',\n PT3M: 'mark-price-candle3m',\n PT5M: 'mark-price-candle5m',\n PT15M: 'mark-price-candle15m',\n PT30M: 'mark-price-candle30m',\n\n PT1H: 'mark-price-candle1H',\n PT2H: 'mark-price-candle2H',\n PT4H: 'mark-price-candle4H',\n PT6H: 'mark-price-candle6H',\n PT12H: 'mark-price-candle12H',\n\n P1D: 'mark-price-candle1D',\n P1W: 'mark-price-candle1W',\n P1M: 'mark-price-candle1M',\n};\n\ncreateSeriesProvider<IOHLC>(Terminal.fromNodeEnv(), {\n tableName: 'ohlc',\n series_id_prefix_parts: ['OKX'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({ series_id, ended_at }) {\n const [datasource_id, product_id, duration] = decodePath(series_id);\n const offset = convertDurationToOffset(duration);\n if (!datasource_id) {\n throw 'datasource_id is required';\n }\n if (!product_id) {\n throw 'product_id is required';\n }\n if (!offset) {\n throw 'duration is invalid';\n }\n const [instType, instId] = decodePath(product_id);\n if (!instId) {\n throw `invalid product_id: ${product_id}`;\n }\n\n const bar = DURATION_TO_OKX_BAR_TYPE[duration];\n if (!bar) {\n throw `unsupported duration: ${duration}`;\n }\n\n let currentStartTime = ended_at;\n\n while (true) {\n // 向前翻页,时间降序,不含 after 时间点\n const res = await client.getHistoryCandles({\n instId,\n bar,\n after: `${currentStartTime}`,\n limit: '100',\n });\n if (res.code !== '0') {\n throw `API failed: ${res.code} ${res.msg}`;\n }\n if (res.data.length === 0) break;\n currentStartTime = +res.data[res.data.length - 1][0];\n const data = res.data.map(\n (x): IOHLC => ({\n series_id,\n datasource_id,\n product_id,\n duration,\n created_at: formatTime(+x[0]),\n closed_at: formatTime(+x[0] + offset),\n open: x[1],\n high: x[2],\n low: x[3],\n close: x[4],\n volume: x[5],\n open_interest: '0',\n }),\n );\n yield data;\n await firstValueFrom(timer(1000));\n }\n },\n});\n\nTerminal.fromNodeEnv().channel.publishChannel('ohlc', { pattern: `^OKX/` }, (series_id) => {\n // const [] = decodePath(args)\n const [datasource_id, product_id, duration] = decodePath(series_id);\n const [, instId] = decodePath(product_id);\n const offset = convertDurationToOffset(duration);\n if (!datasource_id) {\n throw 'datasource_id is required';\n }\n if (!product_id) {\n throw 'product_id is required';\n }\n if (!offset) {\n throw 'duration is invalid';\n }\n const candleType = DURATION_TO_OKX_CANDLE_TYPE[duration];\n console.info(formatTime(Date.now()), `subscribe`, series_id);\n return new Observable<IOHLC>((subscriber) => {\n console.info(formatTime(Date.now()), `subscribe`, candleType, instId);\n const okxBusinessWsClient = new OKXWsClient('ws/v5/business');\n okxBusinessWsClient.subscribe(candleType, instId, async (data: string[]) => {\n const created_at = Number(data[0]);\n const closed_at = created_at + offset;\n const open = data[1];\n const high = data[2];\n const low = data[3];\n const close = data[4];\n if (isNaN(closed_at)) {\n return;\n }\n console.info(formatTime(Date.now()), `insertData`, data);\n const cancelData: IOHLC = {\n closed_at: formatTime(closed_at),\n created_at: formatTime(created_at),\n open,\n high,\n low,\n close,\n series_id,\n datasource_id,\n duration,\n product_id,\n volume: '0',\n open_interest: '0',\n };\n subscriber.next(cancelData);\n });\n return () => {\n okxBusinessWsClient.unsubscribe(candleType, instId);\n };\n }).pipe(\n writeToSQL({\n tableName: 'ohlc',\n conflictKeys: ['created_at', 'series_id'],\n writeInterval: 1000,\n terminal: Terminal.fromNodeEnv(),\n keyFn: (x) => encodePath(x.created_at, x.series_id),\n }),\n );\n});\n"]}
|
package/lib/websocket.d.ts
CHANGED
@@ -6,7 +6,8 @@ export declare class OKXWsClient {
|
|
6
6
|
handlers: Record<string, Function>;
|
7
7
|
pendingSub: string[];
|
8
8
|
keepAlive: Subscription;
|
9
|
-
|
9
|
+
baseURL: string;
|
10
|
+
constructor(path: string);
|
10
11
|
handleMessage(raw: any): void;
|
11
12
|
subscribe(channel: string, instId?: string, handler?: Function): void;
|
12
13
|
unsubscribe(channel: string, instId?: string): void;
|
package/lib/websocket.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,YAAY,EAAO,MAAM,MAAM,CAAC;AAGnD,qBAAa,WAAW;IACtB,EAAE,EAAE,SAAS,CAAC;IACd,SAAS,EAAE,OAAO,CAAS;IAC3B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,YAAY,CAAC;
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,YAAY,EAAO,MAAM,MAAM,CAAC;AAGnD,qBAAa,WAAW;IACtB,EAAE,EAAE,SAAS,CAAC;IACd,SAAS,EAAE,OAAO,CAAS;IAC3B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,YAAY,CAAC;IAExB,OAAO,EAAE,MAAM,CAA2B;gBAC9B,IAAI,EAAE,MAAM;IAgCxB,aAAa,CAAC,GAAG,EAAE,GAAG;IAiBtB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ;IA0B9D,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAiB7C"}
|
package/lib/websocket.js
CHANGED
@@ -5,10 +5,11 @@ const utils_1 = require("@yuants/utils");
|
|
5
5
|
const rxjs_1 = require("rxjs");
|
6
6
|
// import WebSocket from 'ws';
|
7
7
|
class OKXWsClient {
|
8
|
-
constructor(
|
8
|
+
constructor(path) {
|
9
9
|
this.connected = false;
|
10
|
+
this.baseURL = `wss://ws.okx.com:8443`;
|
10
11
|
// this.instId = instId;
|
11
|
-
this.ws = new WebSocket(
|
12
|
+
this.ws = new WebSocket(`${this.baseURL}/${path}`);
|
12
13
|
this.pendingSub = [];
|
13
14
|
this.keepAlive = (0, rxjs_1.interval)(25000)
|
14
15
|
.pipe((0, rxjs_1.tap)(() => {
|
@@ -48,7 +49,7 @@ class OKXWsClient {
|
|
48
49
|
}
|
49
50
|
}
|
50
51
|
else if (msg.event) {
|
51
|
-
console.info('Event:', msg);
|
52
|
+
console.info((0, utils_1.formatTime)(Date.now()), 'Event:', msg);
|
52
53
|
}
|
53
54
|
}
|
54
55
|
// 调用订阅
|
@@ -90,7 +91,7 @@ class OKXWsClient {
|
|
90
91
|
this.keepAlive.unsubscribe();
|
91
92
|
}
|
92
93
|
delete this.handlers[channelId];
|
93
|
-
console.info(`📩 Sent unsubscribe for ${channelId}`);
|
94
|
+
console.info((0, utils_1.formatTime)(Date.now()), `📩 Sent unsubscribe for ${channelId}`);
|
94
95
|
}
|
95
96
|
}
|
96
97
|
exports.OKXWsClient = OKXWsClient;
|
package/lib/websocket.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":";;;AAAA,yCAAuD;AACvD,+BAAmD;AACnD,8BAA8B;AAE9B,MAAa,WAAW;
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"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","sourcesContent":["import { encodePath, formatTime } from '@yuants/utils';\nimport { interval, Subscription, tap } from 'rxjs';\n// import WebSocket from 'ws';\n\nexport class 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 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.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 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 delete this.handlers[channelId];\n console.info(formatTime(Date.now()), `📩 Sent unsubscribe for ${channelId}`);\n }\n}\n"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@yuants/vendor-okx",
|
3
|
-
"version": "0.18.
|
3
|
+
"version": "0.18.2",
|
4
4
|
"bin": "lib/cli.js",
|
5
5
|
"files": [
|
6
6
|
"dist",
|
@@ -10,7 +10,7 @@
|
|
10
10
|
"dependencies": {
|
11
11
|
"@yuants/protocol": "0.37.3",
|
12
12
|
"@yuants/transfer": "0.2.5",
|
13
|
-
"@yuants/data-account": "0.3.
|
13
|
+
"@yuants/data-account": "0.3.6",
|
14
14
|
"@yuants/data-order": "0.2.2",
|
15
15
|
"@yuants/utils": "0.6.0",
|
16
16
|
"@yuants/sql": "0.8.4",
|
package/temp/image-tag
CHANGED
@@ -1 +1 @@
|
|
1
|
-
sha-
|
1
|
+
sha-8ca567edc8e5070eb44741f8a0c8d96ff73cd0db
|
package/temp/package-deps.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
|
-
"apps/vendor-okx/CHANGELOG.json": "
|
3
|
-
"apps/vendor-okx/CHANGELOG.md": "
|
2
|
+
"apps/vendor-okx/CHANGELOG.json": "a839cd82d19894169cc6f677dc50c57aa08c562d",
|
3
|
+
"apps/vendor-okx/CHANGELOG.md": "e7e2b9e84ac2c1e4033c1a966c273b605e6129be",
|
4
4
|
"apps/vendor-okx/README.md": "ac3d1f6c4c8d73066664699b0bb1b01db02e67a2",
|
5
5
|
"apps/vendor-okx/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c",
|
6
6
|
"apps/vendor-okx/build/Dockerfile": "e625b9593e496c343297c9ce133d6cc4be9617a7",
|
@@ -8,26 +8,26 @@
|
|
8
8
|
"apps/vendor-okx/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
|
9
9
|
"apps/vendor-okx/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
|
10
10
|
"apps/vendor-okx/etc/vendor-okx.api.md": "92c54ccd547d2ad81ca6088158ca193e85c208df",
|
11
|
-
"apps/vendor-okx/package.json": "
|
11
|
+
"apps/vendor-okx/package.json": "1eed797d170cc8cbae3f0020cad0d6308c27072e",
|
12
12
|
"apps/vendor-okx/src/account.ts": "7e8bb44845269a401a850aff2e5bf170b0811bd8",
|
13
13
|
"apps/vendor-okx/src/api.ts": "24d7484abffc5a06c67c70c624aa7e401b3be8f2",
|
14
14
|
"apps/vendor-okx/src/cli.ts": "9bf6b5559a6c6f33da20e74cc6c5d702c60ec891",
|
15
15
|
"apps/vendor-okx/src/cluster.ts": "9971d8d5e6af16e09d2d1fe5e9f05ccee87281e8",
|
16
16
|
"apps/vendor-okx/src/extension.ts": "e5c9bc791d3c4beade4c8a1854d1351ba3ddd3aa",
|
17
17
|
"apps/vendor-okx/src/index.ts": "6c9f8e299d58c3acdcf99d75f3173abba085f385",
|
18
|
-
"apps/vendor-okx/src/interest_rate.ts": "
|
18
|
+
"apps/vendor-okx/src/interest_rate.ts": "f5ee44bf6b92a484dccc57863c47a7101a78e793",
|
19
19
|
"apps/vendor-okx/src/legacy_index.ts": "1bf031b9f8f870a099d74867292b257346344e4d",
|
20
20
|
"apps/vendor-okx/src/logger.ts": "d25d427e74f46819a601e0cb17d5358b22c8db7b",
|
21
|
-
"apps/vendor-okx/src/ohlc.ts": "
|
21
|
+
"apps/vendor-okx/src/ohlc.ts": "31f7d72513dc32a31938313e79c7e75b0964906c",
|
22
22
|
"apps/vendor-okx/src/order.ts": "09509ae5af4b212cc1c99c55c436b3b0ce8bda33",
|
23
23
|
"apps/vendor-okx/src/product.ts": "a2e7feb86bc01fe3b1af6dcb9a9ebfba6be91434",
|
24
24
|
"apps/vendor-okx/src/quote.ts": "b8dd019e6cceb50e486a9d41e54385bda4e21ab0",
|
25
|
-
"apps/vendor-okx/src/websocket.ts": "
|
25
|
+
"apps/vendor-okx/src/websocket.ts": "dbfbe9785d9ce06ceae0092750f1db5518be8151",
|
26
26
|
"apps/vendor-okx/tsconfig.json": "81da8f78196974b5d15da0edb6b2d9f48641063c",
|
27
27
|
"apps/vendor-okx/.rush/temp/shrinkwrap-deps.json": "87df045a10e829fd62d50013da30fd929442d54c",
|
28
28
|
"libraries/protocol/temp/package-deps.json": "43291b31649f44821b64235587e30fe4663fc305",
|
29
29
|
"libraries/transfer/temp/package-deps.json": "a662579703128c1770f30f8ffaab3f5a233f9d48",
|
30
|
-
"libraries/data-account/temp/package-deps.json": "
|
30
|
+
"libraries/data-account/temp/package-deps.json": "6271fcb95ec701464eb1e36e3efad6d674644484",
|
31
31
|
"libraries/data-order/temp/package-deps.json": "0ec7bb60f94eb437a05ee53e46841ca0ed718635",
|
32
32
|
"libraries/utils/temp/package-deps.json": "ecdd5e56cb2b6db83ee9caf8784ad342484f1699",
|
33
33
|
"libraries/sql/temp/package-deps.json": "ccd7161a4384bf97c6a29bff21030ed3bea5336f",
|