@yuants/vendor-okx 0.31.11 → 0.32.1

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.
Files changed (37) hide show
  1. package/README.md +0 -4
  2. package/dist/index.js +0 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/public-data/ohlc.js +13 -163
  5. package/dist/public-data/ohlc.js.map +1 -1
  6. package/dist/services/interest-ledger-service.js +23 -19
  7. package/dist/services/interest-ledger-service.js.map +1 -1
  8. package/lib/index.d.ts +0 -1
  9. package/lib/index.d.ts.map +1 -1
  10. package/lib/index.js +0 -1
  11. package/lib/index.js.map +1 -1
  12. package/lib/public-data/ohlc.js +12 -162
  13. package/lib/public-data/ohlc.js.map +1 -1
  14. package/lib/services/interest-ledger-service.js +23 -19
  15. package/lib/services/interest-ledger-service.js.map +1 -1
  16. package/package.json +7 -7
  17. package/temp/build/typescript/ts_xKrCYDcc.json +1 -1
  18. package/temp/package-deps.json +8 -11
  19. package/temp/test/jest/haste-map-0104fb5fee08bd97aacd02300cdbf195-f3ddf881f4f21e2e5ae6006d95adf2b1-267deb988b5111321a1cf92c4d020334 +0 -0
  20. package/dist/public-data/interest_rate.js +0 -118
  21. package/dist/public-data/interest_rate.js.map +0 -1
  22. package/dist/utils/provideOHLCFromTimeBackwardService.js +0 -49
  23. package/dist/utils/provideOHLCFromTimeBackwardService.js.map +0 -1
  24. package/dist/utils/provideSeriesFromTimeBackwardService.js +0 -59
  25. package/dist/utils/provideSeriesFromTimeBackwardService.js.map +0 -1
  26. package/lib/public-data/interest_rate.d.ts +0 -2
  27. package/lib/public-data/interest_rate.d.ts.map +0 -1
  28. package/lib/public-data/interest_rate.js +0 -120
  29. package/lib/public-data/interest_rate.js.map +0 -1
  30. package/lib/utils/provideOHLCFromTimeBackwardService.d.ts +0 -24
  31. package/lib/utils/provideOHLCFromTimeBackwardService.d.ts.map +0 -1
  32. package/lib/utils/provideOHLCFromTimeBackwardService.js +0 -53
  33. package/lib/utils/provideOHLCFromTimeBackwardService.js.map +0 -1
  34. package/lib/utils/provideSeriesFromTimeBackwardService.d.ts +0 -22
  35. package/lib/utils/provideSeriesFromTimeBackwardService.d.ts.map +0 -1
  36. package/lib/utils/provideSeriesFromTimeBackwardService.js +0 -63
  37. package/lib/utils/provideSeriesFromTimeBackwardService.js.map +0 -1
package/README.md CHANGED
@@ -49,7 +49,6 @@ src/
49
49
  │ ├── ohlc.ts # K线数据
50
50
  │ ├── product.ts # 产品信息
51
51
  │ ├── quote.ts # 报价数据
52
- │ ├── interest_rate.ts # 利率数据
53
52
  │ └── market-order.ts # 市价单数据
54
53
  ├── accountInfos/ # 账户信息处理
55
54
  │ ├── trading.ts # 交易账户信息
@@ -61,9 +60,6 @@ src/
61
60
  │ ├── submitOrder.ts # 提交订单
62
61
  │ ├── modifyOrder.ts # 修改订单
63
62
  │ └── cancelOrder.ts # 取消订单
64
- ├── utils/ # 工具函数
65
- │ ├── provideOHLCFromTimeBackwardService.ts
66
- │ └── provideSeriesFromTimeBackwardService.ts
67
63
  └── *.ts # 核心服务模块
68
64
  ```
69
65
 
package/dist/index.js CHANGED
@@ -5,7 +5,6 @@ import './experimental/exchange';
5
5
  import './order';
6
6
  import './order-actions';
7
7
  import './order-actions-with-credential';
8
- import './public-data/interest_rate';
9
8
  import './public-data/market-order';
10
9
  import './public-data/ohlc';
11
10
  import './public-data/quote';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAC;AACnB,OAAO,mCAAmC,CAAC;AAC3C,OAAO,eAAe,CAAC;AACvB,OAAO,yBAAyB,CAAC;AACjC,OAAO,SAAS,CAAC;AACjB,OAAO,iBAAiB,CAAC;AACzB,OAAO,iCAAiC,CAAC;AACzC,OAAO,6BAA6B,CAAC;AACrC,OAAO,4BAA4B,CAAC;AACpC,OAAO,oBAAoB,CAAC;AAC5B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,YAAY,CAAC;AACpB,OAAO,oBAAoB,CAAC;AAC5B,OAAO,SAAS,CAAC;AACjB,OAAO,YAAY,CAAC;AACpB,OAAO,yBAAyB,CAAC;AACjC,OAAO,mBAAmB,CAAC;AAC3B,OAAO,yBAAyB,CAAC;AACjC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,oCAAoC,CAAC","sourcesContent":["import './account';\nimport './account-actions-with-credential';\nimport './api-service';\nimport './experimental/exchange';\nimport './order';\nimport './order-actions';\nimport './order-actions-with-credential';\nimport './public-data/interest_rate';\nimport './public-data/market-order';\nimport './public-data/ohlc';\nimport './public-data/quote';\nimport './services';\nimport './strategy-account';\nimport './trade';\nimport './transfer';\nimport './public-data/new-quote';\nimport './services/quotes';\nimport './services/ohlc-service';\nimport './services/interest-rate-service';\nimport './services/interest-ledger-service';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAC;AACnB,OAAO,mCAAmC,CAAC;AAC3C,OAAO,eAAe,CAAC;AACvB,OAAO,yBAAyB,CAAC;AACjC,OAAO,SAAS,CAAC;AACjB,OAAO,iBAAiB,CAAC;AACzB,OAAO,iCAAiC,CAAC;AACzC,OAAO,4BAA4B,CAAC;AACpC,OAAO,oBAAoB,CAAC;AAC5B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,YAAY,CAAC;AACpB,OAAO,oBAAoB,CAAC;AAC5B,OAAO,SAAS,CAAC;AACjB,OAAO,YAAY,CAAC;AACpB,OAAO,yBAAyB,CAAC;AACjC,OAAO,mBAAmB,CAAC;AAC3B,OAAO,yBAAyB,CAAC;AACjC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,oCAAoC,CAAC","sourcesContent":["import './account';\nimport './account-actions-with-credential';\nimport './api-service';\nimport './experimental/exchange';\nimport './order';\nimport './order-actions';\nimport './order-actions-with-credential';\nimport './public-data/market-order';\nimport './public-data/ohlc';\nimport './public-data/quote';\nimport './services';\nimport './strategy-account';\nimport './trade';\nimport './transfer';\nimport './public-data/new-quote';\nimport './services/quotes';\nimport './services/ohlc-service';\nimport './services/interest-rate-service';\nimport './services/interest-ledger-service';\n"]}
@@ -1,44 +1,14 @@
1
- var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
2
- var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
3
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
4
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
5
- return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
6
- function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
7
- function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
8
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
9
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
10
- function fulfill(value) { resume("next", value); }
11
- function reject(value) { resume("throw", value); }
12
- function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
13
- };
14
- import { createSeriesProvider } from '@yuants/data-series';
1
+ import { decodeOHLCSeriesId, encodeOHLCSeriesId } from '@yuants/data-ohlc';
15
2
  import { Terminal } from '@yuants/protocol';
16
3
  import { writeToSQL } from '@yuants/sql';
17
4
  import { convertDurationToOffset, decodePath, encodePath, formatTime } from '@yuants/utils';
18
- import { firstValueFrom, map, timer } from 'rxjs';
19
- import { getHistoryCandles } from '../api/public-api';
20
- import { provideOHLCFromTimeBackwardService } from '../utils/provideOHLCFromTimeBackwardService';
5
+ import { map } from 'rxjs';
21
6
  import { useOHLC } from '../ws';
22
7
  const terminal = Terminal.fromNodeEnv();
23
8
  // 时间粒度,默认值1m
24
9
  // 如 [1m/3m/5m/15m/30m/1H/2H/4H]
25
10
  // 香港时间开盘价k线:[6H/12H/1D/1W/1M]
26
11
  // UTC时间开盘价k线:[6Hutc/12Hutc/1Dutc/1Wutc/1Mutc]
27
- const DURATION_TO_OKX_BAR_TYPE = {
28
- PT1M: '1m',
29
- PT3M: '3m',
30
- PT5M: '5m',
31
- PT15M: '15m',
32
- PT30M: '30m',
33
- PT1H: '1H',
34
- PT2H: '2H',
35
- PT4H: '4H',
36
- PT6H: '6H',
37
- PT12H: '12H',
38
- P1D: '1D',
39
- P1W: '1W',
40
- P1M: '1M',
41
- };
42
12
  const DURATION_TO_OKX_CANDLE_TYPE = {
43
13
  PT1M: 'candle1m',
44
14
  PT3M: 'candle3m',
@@ -65,86 +35,26 @@ const OHLC_V2_WRITE_COLUMNS = [
65
35
  'volume',
66
36
  'open_interest',
67
37
  ];
68
- createSeriesProvider(terminal, {
69
- tableName: 'ohlc',
70
- series_id_prefix_parts: ['OKX'],
71
- reversed: true,
72
- serviceOptions: { concurrent: 1 },
73
- queryFn: function (_a) {
74
- return __asyncGenerator(this, arguments, function* ({ series_id, ended_at }) {
75
- const [datasource_id, product_id, duration] = decodePath(series_id);
76
- const offset = convertDurationToOffset(duration);
77
- if (!datasource_id) {
78
- throw 'datasource_id is required';
79
- }
80
- if (!product_id) {
81
- throw 'product_id is required';
82
- }
83
- if (!offset) {
84
- throw 'duration is invalid';
85
- }
86
- const [instType, instId] = decodePath(product_id);
87
- if (!instId) {
88
- throw `invalid product_id: ${product_id}`;
89
- }
90
- const bar = DURATION_TO_OKX_BAR_TYPE[duration];
91
- if (!bar) {
92
- throw `unsupported duration: ${duration}`;
93
- }
94
- let currentStartTime = ended_at;
95
- while (true) {
96
- // 向前翻页,时间降序,不含 after 时间点
97
- const res = yield __await(getHistoryCandles({
98
- instId,
99
- bar,
100
- after: `${currentStartTime}`,
101
- limit: '100',
102
- }));
103
- if (res.code !== '0') {
104
- throw `API failed: ${res.code} ${res.msg}`;
105
- }
106
- if (res.data.length === 0)
107
- break;
108
- currentStartTime = +res.data[res.data.length - 1][0];
109
- const data = res.data.map((x) => ({
110
- series_id,
111
- datasource_id,
112
- product_id,
113
- duration,
114
- created_at: formatTime(+x[0]),
115
- closed_at: formatTime(+x[0] + offset),
116
- open: x[1],
117
- high: x[2],
118
- low: x[3],
119
- close: x[4],
120
- volume: x[5],
121
- open_interest: '0',
122
- }));
123
- yield yield __await(data);
124
- yield __await(firstValueFrom(timer(1000)));
125
- }
126
- });
127
- },
128
- });
129
38
  terminal.channel.publishChannel('ohlc', { pattern: `^OKX/` }, (series_id) => {
130
- const [datasource_id, product_id, duration] = decodePath(series_id);
131
- const [instType, instId] = decodePath(product_id);
39
+ const { product_id, duration } = decodeOHLCSeriesId(series_id);
40
+ const [datasource_id, instType, instId] = decodePath(product_id);
132
41
  const offset = convertDurationToOffset(duration);
133
42
  if (!datasource_id) {
134
43
  throw 'datasource_id is required';
135
44
  }
136
- if (!product_id) {
137
- throw 'product_id is required';
138
- }
139
45
  if (!instType || !instId) {
140
46
  throw `invalid product_id: ${product_id}`;
141
47
  }
142
48
  if (!offset) {
143
49
  throw 'duration is invalid';
144
50
  }
145
- const series_id_v2 = `${encodePath(datasource_id, instType, instId)}/${duration}`;
51
+ const product_id_path = encodePath(datasource_id, instType, instId);
146
52
  const candleType = DURATION_TO_OKX_CANDLE_TYPE[duration];
147
- console.info(formatTime(Date.now()), `subscribe`, series_id, product_id);
53
+ if (!candleType) {
54
+ throw `unsupported duration: ${duration}`;
55
+ }
56
+ const normalized_series_id = encodeOHLCSeriesId(product_id_path, duration);
57
+ console.info(formatTime(Date.now()), `subscribe`, normalized_series_id, product_id_path);
148
58
  return useOHLC(candleType, instId).pipe(map((data) => {
149
59
  const created_at = Number(data[0][0]);
150
60
  const closed_at = created_at + offset;
@@ -160,79 +70,19 @@ terminal.channel.publishChannel('ohlc', { pattern: `^OKX/` }, (series_id) => {
160
70
  high,
161
71
  low,
162
72
  close,
163
- series_id,
73
+ series_id: normalized_series_id,
164
74
  datasource_id,
165
75
  duration,
166
- product_id,
76
+ product_id: product_id_path,
167
77
  volume,
168
78
  open_interest: '0',
169
79
  };
170
- }), map((x) => ({
171
- __origin: x,
172
- series_id: series_id_v2,
173
- created_at: x.created_at,
174
- closed_at: x.closed_at,
175
- open: x.open,
176
- high: x.high,
177
- low: x.low,
178
- close: x.close,
179
- volume: x.volume,
180
- open_interest: x.open_interest,
181
- })), writeToSQL({
80
+ }), writeToSQL({
182
81
  tableName: 'ohlc_v2',
183
82
  columns: OHLC_V2_WRITE_COLUMNS,
184
83
  conflictKeys: ['series_id', 'created_at'],
185
84
  writeInterval: 1000,
186
85
  terminal,
187
- }), map((x) => x.__origin), writeToSQL({
188
- tableName: 'ohlc',
189
- conflictKeys: ['series_id', 'created_at'],
190
- writeInterval: 1000,
191
- terminal,
192
86
  }));
193
87
  });
194
- provideOHLCFromTimeBackwardService({
195
- terminal,
196
- datasource_id: 'OKX',
197
- supported_durations: Object.keys(DURATION_TO_OKX_BAR_TYPE),
198
- queryFn: async ({ series_id, datasource_id, product_id, duration, offset, time }) => {
199
- const [instType, instId] = decodePath(product_id);
200
- if (!instId) {
201
- throw `invalid product_id: ${product_id}`;
202
- }
203
- const bar = DURATION_TO_OKX_BAR_TYPE[duration];
204
- if (!bar) {
205
- throw `unsupported duration: ${duration}`;
206
- }
207
- // 从指定时间点向过去获取一页数据
208
- const res = await getHistoryCandles({
209
- instId,
210
- bar,
211
- after: `${new Date(time).getTime()}`, // 不包含该时间点 (标准的右开)
212
- limit: `300`,
213
- });
214
- if (res.code !== '0') {
215
- throw `API failed: ${res.code} ${res.msg}`;
216
- }
217
- return res.data.map((x) => ({
218
- series_id,
219
- datasource_id,
220
- product_id,
221
- duration,
222
- created_at: formatTime(+x[0]),
223
- closed_at: formatTime(+x[0] + offset),
224
- open: x[1],
225
- high: x[2],
226
- low: x[3],
227
- close: x[4],
228
- volume: x[5],
229
- open_interest: '0',
230
- }));
231
- },
232
- serviceOptions: {
233
- // Rate limit: 20 requests per 2 seconds
234
- egress_token_capacity: 20,
235
- egress_token_refill_interval: 2000,
236
- },
237
- });
238
88
  //# sourceMappingURL=ohlc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ohlc.js","sourceRoot":"","sources":["../../src/public-data/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 { writeToSQL } from '@yuants/sql';\nimport { convertDurationToOffset, decodePath, encodePath, formatTime } from '@yuants/utils';\nimport { firstValueFrom, map, timer } from 'rxjs';\nimport { getHistoryCandles } from '../api/public-api';\nimport { provideOHLCFromTimeBackwardService } from '../utils/provideOHLCFromTimeBackwardService';\nimport { useOHLC } from '../ws';\n\nconst terminal = Terminal.fromNodeEnv();\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: 'candle1m',\n PT3M: 'candle3m',\n PT5M: 'candle5m',\n PT15M: 'candle15m',\n PT30M: 'candle30m',\n\n PT1H: 'candle1H',\n PT2H: 'candle2H',\n PT4H: 'candle4H',\n PT6H: 'candle6H',\n PT12H: 'candle12H',\n\n P1D: 'candle1D',\n P1W: 'candle1W',\n P1M: 'candle1M',\n};\n\ntype IOHLCV2WriteRow = Pick<\n IOHLC,\n 'series_id' | 'created_at' | 'closed_at' | 'open' | 'high' | 'low' | 'close' | 'volume' | 'open_interest'\n> & { __origin: IOHLC };\n\nconst OHLC_V2_WRITE_COLUMNS: Array<keyof IOHLCV2WriteRow> = [\n 'series_id',\n 'created_at',\n 'closed_at',\n 'open',\n 'high',\n 'low',\n 'close',\n 'volume',\n 'open_interest',\n];\n\ncreateSeriesProvider<IOHLC>(terminal, {\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 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.channel.publishChannel('ohlc', { pattern: `^OKX/` }, (series_id) => {\n const [datasource_id, product_id, duration] = decodePath(series_id);\n const [instType, 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 (!instType || !instId) {\n throw `invalid product_id: ${product_id}`;\n }\n if (!offset) {\n throw 'duration is invalid';\n }\n const series_id_v2 = `${encodePath(datasource_id, instType, instId)}/${duration}`;\n const candleType = DURATION_TO_OKX_CANDLE_TYPE[duration];\n console.info(formatTime(Date.now()), `subscribe`, series_id, product_id);\n\n return useOHLC(candleType, instId).pipe(\n map((data): IOHLC => {\n const created_at = Number(data[0][0]);\n const closed_at = created_at + offset;\n const open = data[0][1];\n const high = data[0][2];\n const low = data[0][3];\n const close = data[0][4];\n const volume = data[0][5];\n return {\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,\n open_interest: '0',\n };\n }),\n map(\n (x): IOHLCV2WriteRow => ({\n __origin: x,\n series_id: series_id_v2,\n created_at: x.created_at,\n closed_at: x.closed_at,\n open: x.open,\n high: x.high,\n low: x.low,\n close: x.close,\n volume: x.volume,\n open_interest: x.open_interest,\n }),\n ),\n writeToSQL({\n tableName: 'ohlc_v2',\n columns: OHLC_V2_WRITE_COLUMNS,\n conflictKeys: ['series_id', 'created_at'],\n writeInterval: 1000,\n terminal,\n }),\n map((x) => x.__origin),\n writeToSQL({\n tableName: 'ohlc',\n conflictKeys: ['series_id', 'created_at'],\n writeInterval: 1000,\n terminal,\n }),\n );\n});\n\nprovideOHLCFromTimeBackwardService({\n terminal,\n datasource_id: 'OKX',\n supported_durations: Object.keys(DURATION_TO_OKX_BAR_TYPE),\n queryFn: async ({ series_id, datasource_id, product_id, duration, offset, time }) => {\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 // 从指定时间点向过去获取一页数据\n const res = await getHistoryCandles({\n instId,\n bar,\n after: `${new Date(time).getTime()}`, // 不包含该时间点 (标准的右开)\n limit: `300`,\n });\n\n if (res.code !== '0') {\n throw `API failed: ${res.code} ${res.msg}`;\n }\n\n return 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 },\n serviceOptions: {\n // Rate limit: 20 requests per 2 seconds\n egress_token_capacity: 20,\n egress_token_refill_interval: 2000,\n },\n});\n"]}
1
+ {"version":3,"file":"ohlc.js","sourceRoot":"","sources":["../../src/public-data/ohlc.ts"],"names":[],"mappings":"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","sourcesContent":["import { decodeOHLCSeriesId, encodeOHLCSeriesId, IOHLC } from '@yuants/data-ohlc';\nimport { Terminal } from '@yuants/protocol';\nimport { writeToSQL } from '@yuants/sql';\nimport { convertDurationToOffset, decodePath, encodePath, formatTime } from '@yuants/utils';\nimport { map } from 'rxjs';\nimport { useOHLC } from '../ws';\n\nconst terminal = Terminal.fromNodeEnv();\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_CANDLE_TYPE: Record<string, string> = {\n PT1M: 'candle1m',\n PT3M: 'candle3m',\n PT5M: 'candle5m',\n PT15M: 'candle15m',\n PT30M: 'candle30m',\n\n PT1H: 'candle1H',\n PT2H: 'candle2H',\n PT4H: 'candle4H',\n PT6H: 'candle6H',\n PT12H: 'candle12H',\n\n P1D: 'candle1D',\n P1W: 'candle1W',\n P1M: 'candle1M',\n};\n\nconst OHLC_V2_WRITE_COLUMNS: Array<keyof IOHLC> = [\n 'series_id',\n 'created_at',\n 'closed_at',\n 'open',\n 'high',\n 'low',\n 'close',\n 'volume',\n 'open_interest',\n];\n\nterminal.channel.publishChannel('ohlc', { pattern: `^OKX/` }, (series_id) => {\n const { product_id, duration } = decodeOHLCSeriesId(series_id);\n const [datasource_id, instType, instId] = decodePath(product_id);\n const offset = convertDurationToOffset(duration);\n if (!datasource_id) {\n throw 'datasource_id is required';\n }\n if (!instType || !instId) {\n throw `invalid product_id: ${product_id}`;\n }\n if (!offset) {\n throw 'duration is invalid';\n }\n const product_id_path = encodePath(datasource_id, instType, instId);\n const candleType = DURATION_TO_OKX_CANDLE_TYPE[duration];\n if (!candleType) {\n throw `unsupported duration: ${duration}`;\n }\n const normalized_series_id = encodeOHLCSeriesId(product_id_path, duration);\n console.info(formatTime(Date.now()), `subscribe`, normalized_series_id, product_id_path);\n\n return useOHLC(candleType, instId).pipe(\n map((data): IOHLC => {\n const created_at = Number(data[0][0]);\n const closed_at = created_at + offset;\n const open = data[0][1];\n const high = data[0][2];\n const low = data[0][3];\n const close = data[0][4];\n const volume = data[0][5];\n return {\n closed_at: formatTime(closed_at),\n created_at: formatTime(created_at),\n open,\n high,\n low,\n close,\n series_id: normalized_series_id,\n datasource_id,\n duration,\n product_id: product_id_path,\n volume,\n open_interest: '0',\n };\n }),\n writeToSQL({\n tableName: 'ohlc_v2',\n columns: OHLC_V2_WRITE_COLUMNS,\n conflictKeys: ['series_id', 'created_at'],\n writeInterval: 1000,\n terminal,\n }),\n );\n});\n"]}
@@ -6,28 +6,32 @@ const terminal = Terminal.fromNodeEnv();
6
6
  const WINDOW_MS = 365 * 24 * 3600000;
7
7
  const fetchInterestRateLedgerBackward = async (req) => {
8
8
  var _a;
9
- const params = {};
10
- params.end = req.time.toString();
11
- params.begin = (req.time - WINDOW_MS).toString();
12
- params.limit = 100;
13
- params.type = req.ledger_type;
14
- const res = await getAccountBillsArchive(req.credential.payload, params);
15
- return ((_a = res.data) !== null && _a !== void 0 ? _a : [])
16
- .map((v) => {
17
- const ms = Number(v.ts);
18
- return {
19
- id: v.billId,
20
- product_id: encodePath('OKX', v.instType, v.instId),
21
- amount: v.balChg,
22
- account_id: req.account_id,
23
- currency: v.ccy,
24
- created_at: formatTime(ms),
25
- };
26
- })
27
- .filter((x) => Date.parse(x.created_at) <= req.time);
9
+ if (req.ledger_type === 'FUNDING_FEE') {
10
+ const params = {};
11
+ params.end = req.time.toString();
12
+ params.begin = (req.time - WINDOW_MS).toString();
13
+ params.limit = 100;
14
+ params.type = '8';
15
+ const res = await getAccountBillsArchive(req.credential.payload, params);
16
+ return ((_a = res.data) !== null && _a !== void 0 ? _a : [])
17
+ .map((v) => {
18
+ const ms = Number(v.ts);
19
+ return {
20
+ id: v.billId,
21
+ product_id: encodePath('OKX', v.instType, v.instId),
22
+ amount: v.balChg,
23
+ account_id: req.account_id,
24
+ currency: v.ccy,
25
+ created_at: formatTime(ms),
26
+ };
27
+ })
28
+ .filter((x) => Date.parse(x.created_at) <= req.time);
29
+ }
30
+ return [];
28
31
  };
29
32
  provideInterestLedgerService(terminal, {
30
33
  direction: 'backward',
31
34
  type: 'OKX',
35
+ ledger_type: ['FUNDING_FEE'],
32
36
  }, fetchInterestRateLedgerBackward);
33
37
  //# sourceMappingURL=interest-ledger-service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"interest-ledger-service.js","sourceRoot":"","sources":["../../src/services/interest-ledger-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAO5D,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,SAAS,GAAG,GAAG,GAAG,EAAE,GAAG,OAAQ,CAAC;AAEtC,MAAM,+BAA+B,GAAG,KAAK,EAAE,GAK9C,EAA8B,EAAE;;IAC/B,MAAM,MAAM,GAAoC,EAAE,CAAC;IACnD,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;IACjC,MAAM,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;IACjD,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC;IACnB,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzE,OAAO,CAAC,MAAA,GAAG,CAAC,IAAI,mCAAI,EAAE,CAAC;SACpB,GAAG,CAAC,CAAC,CAAC,EAAmB,EAAE;QAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxB,OAAO;YACL,EAAE,EAAE,CAAC,CAAC,MAAM;YACZ,UAAU,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;YACnD,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,QAAQ,EAAE,CAAC,CAAC,GAAG;YACf,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC;SACR,CAAC;IACvB,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAW,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;AAC1D,CAAC,CAAC;AAEF,4BAA4B,CAC1B,QAAQ,EACR;IACE,SAAS,EAAE,UAAU;IACrB,IAAI,EAAE,KAAK;CACZ,EACD,+BAA+B,CAChC,CAAC","sourcesContent":["import { IInterestLedger } from '@yuants/data-interest-rate';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { provideInterestLedgerService } from '@yuants/exchange';\nimport { getAccountBillsArchive } from '../api/private-api';\n\ninterface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst WINDOW_MS = 365 * 24 * 3600_000;\n\nconst fetchInterestRateLedgerBackward = async (req: {\n credential: IExchangeCredential;\n account_id: string;\n time: number;\n ledger_type: string;\n}): Promise<IInterestLedger[]> => {\n const params: Record<string, string | number> = {};\n params.end = req.time.toString();\n params.begin = (req.time - WINDOW_MS).toString();\n params.limit = 100;\n params.type = req.ledger_type;\n const res = await getAccountBillsArchive(req.credential.payload, params);\n return (res.data ?? [])\n .map((v): IInterestLedger => {\n const ms = Number(v.ts);\n return {\n id: v.billId,\n product_id: encodePath('OKX', v.instType, v.instId),\n amount: v.balChg,\n account_id: req.account_id,\n currency: v.ccy,\n created_at: formatTime(ms),\n } as IInterestLedger;\n })\n .filter((x) => Date.parse(x.created_at!) <= req.time);\n};\n\nprovideInterestLedgerService(\n terminal,\n {\n direction: 'backward',\n type: 'OKX',\n },\n fetchInterestRateLedgerBackward,\n);\n"]}
1
+ {"version":3,"file":"interest-ledger-service.js","sourceRoot":"","sources":["../../src/services/interest-ledger-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAO5D,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,SAAS,GAAG,GAAG,GAAG,EAAE,GAAG,OAAQ,CAAC;AAEtC,MAAM,+BAA+B,GAAG,KAAK,EAAE,GAK9C,EAA8B,EAAE;;IAC/B,IAAI,GAAG,CAAC,WAAW,KAAK,aAAa,EAAE,CAAC;QACtC,MAAM,MAAM,GAAoC,EAAE,CAAC;QACnD,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;QACjD,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC;QACnB,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC;QAClB,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACzE,OAAO,CAAC,MAAA,GAAG,CAAC,IAAI,mCAAI,EAAE,CAAC;aACpB,GAAG,CAAC,CAAC,CAAC,EAAmB,EAAE;YAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACxB,OAAO;gBACL,EAAE,EAAE,CAAC,CAAC,MAAM;gBACZ,UAAU,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;gBACnD,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,QAAQ,EAAE,CAAC,CAAC,GAAG;gBACf,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC;aACR,CAAC;QACvB,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAW,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF,4BAA4B,CAC1B,QAAQ,EACR;IACE,SAAS,EAAE,UAAU;IACrB,IAAI,EAAE,KAAK;IACX,WAAW,EAAE,CAAC,aAAa,CAAC;CAC7B,EACD,+BAA+B,CAChC,CAAC","sourcesContent":["import { IInterestLedger } from '@yuants/data-interest-rate';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { provideInterestLedgerService } from '@yuants/exchange';\nimport { getAccountBillsArchive } from '../api/private-api';\n\ninterface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst WINDOW_MS = 365 * 24 * 3600_000;\n\nconst fetchInterestRateLedgerBackward = async (req: {\n credential: IExchangeCredential;\n account_id: string;\n time: number;\n ledger_type: string;\n}): Promise<IInterestLedger[]> => {\n if (req.ledger_type === 'FUNDING_FEE') {\n const params: Record<string, string | number> = {};\n params.end = req.time.toString();\n params.begin = (req.time - WINDOW_MS).toString();\n params.limit = 100;\n params.type = '8';\n const res = await getAccountBillsArchive(req.credential.payload, params);\n return (res.data ?? [])\n .map((v): IInterestLedger => {\n const ms = Number(v.ts);\n return {\n id: v.billId,\n product_id: encodePath('OKX', v.instType, v.instId),\n amount: v.balChg,\n account_id: req.account_id,\n currency: v.ccy,\n created_at: formatTime(ms),\n } as IInterestLedger;\n })\n .filter((x) => Date.parse(x.created_at!) <= req.time);\n }\n return [];\n};\n\nprovideInterestLedgerService(\n terminal,\n {\n direction: 'backward',\n type: 'OKX',\n ledger_type: ['FUNDING_FEE'],\n },\n fetchInterestRateLedgerBackward,\n);\n"]}
package/lib/index.d.ts CHANGED
@@ -5,7 +5,6 @@ import './experimental/exchange';
5
5
  import './order';
6
6
  import './order-actions';
7
7
  import './order-actions-with-credential';
8
- import './public-data/interest_rate';
9
8
  import './public-data/market-order';
10
9
  import './public-data/ohlc';
11
10
  import './public-data/quote';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAC;AACnB,OAAO,mCAAmC,CAAC;AAC3C,OAAO,eAAe,CAAC;AACvB,OAAO,yBAAyB,CAAC;AACjC,OAAO,SAAS,CAAC;AACjB,OAAO,iBAAiB,CAAC;AACzB,OAAO,iCAAiC,CAAC;AACzC,OAAO,6BAA6B,CAAC;AACrC,OAAO,4BAA4B,CAAC;AACpC,OAAO,oBAAoB,CAAC;AAC5B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,YAAY,CAAC;AACpB,OAAO,oBAAoB,CAAC;AAC5B,OAAO,SAAS,CAAC;AACjB,OAAO,YAAY,CAAC;AACpB,OAAO,yBAAyB,CAAC;AACjC,OAAO,mBAAmB,CAAC;AAC3B,OAAO,yBAAyB,CAAC;AACjC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,oCAAoC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAC;AACnB,OAAO,mCAAmC,CAAC;AAC3C,OAAO,eAAe,CAAC;AACvB,OAAO,yBAAyB,CAAC;AACjC,OAAO,SAAS,CAAC;AACjB,OAAO,iBAAiB,CAAC;AACzB,OAAO,iCAAiC,CAAC;AACzC,OAAO,4BAA4B,CAAC;AACpC,OAAO,oBAAoB,CAAC;AAC5B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,YAAY,CAAC;AACpB,OAAO,oBAAoB,CAAC;AAC5B,OAAO,SAAS,CAAC;AACjB,OAAO,YAAY,CAAC;AACpB,OAAO,yBAAyB,CAAC;AACjC,OAAO,mBAAmB,CAAC;AAC3B,OAAO,yBAAyB,CAAC;AACjC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,oCAAoC,CAAC"}
package/lib/index.js CHANGED
@@ -7,7 +7,6 @@ require("./experimental/exchange");
7
7
  require("./order");
8
8
  require("./order-actions");
9
9
  require("./order-actions-with-credential");
10
- require("./public-data/interest_rate");
11
10
  require("./public-data/market-order");
12
11
  require("./public-data/ohlc");
13
12
  require("./public-data/quote");
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,qBAAmB;AACnB,6CAA2C;AAC3C,yBAAuB;AACvB,mCAAiC;AACjC,mBAAiB;AACjB,2BAAyB;AACzB,2CAAyC;AACzC,uCAAqC;AACrC,sCAAoC;AACpC,8BAA4B;AAC5B,+BAA6B;AAC7B,sBAAoB;AACpB,8BAA4B;AAC5B,mBAAiB;AACjB,sBAAoB;AACpB,mCAAiC;AACjC,6BAA2B;AAC3B,mCAAiC;AACjC,4CAA0C;AAC1C,8CAA4C","sourcesContent":["import './account';\nimport './account-actions-with-credential';\nimport './api-service';\nimport './experimental/exchange';\nimport './order';\nimport './order-actions';\nimport './order-actions-with-credential';\nimport './public-data/interest_rate';\nimport './public-data/market-order';\nimport './public-data/ohlc';\nimport './public-data/quote';\nimport './services';\nimport './strategy-account';\nimport './trade';\nimport './transfer';\nimport './public-data/new-quote';\nimport './services/quotes';\nimport './services/ohlc-service';\nimport './services/interest-rate-service';\nimport './services/interest-ledger-service';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,qBAAmB;AACnB,6CAA2C;AAC3C,yBAAuB;AACvB,mCAAiC;AACjC,mBAAiB;AACjB,2BAAyB;AACzB,2CAAyC;AACzC,sCAAoC;AACpC,8BAA4B;AAC5B,+BAA6B;AAC7B,sBAAoB;AACpB,8BAA4B;AAC5B,mBAAiB;AACjB,sBAAoB;AACpB,mCAAiC;AACjC,6BAA2B;AAC3B,mCAAiC;AACjC,4CAA0C;AAC1C,8CAA4C","sourcesContent":["import './account';\nimport './account-actions-with-credential';\nimport './api-service';\nimport './experimental/exchange';\nimport './order';\nimport './order-actions';\nimport './order-actions-with-credential';\nimport './public-data/market-order';\nimport './public-data/ohlc';\nimport './public-data/quote';\nimport './services';\nimport './strategy-account';\nimport './trade';\nimport './transfer';\nimport './public-data/new-quote';\nimport './services/quotes';\nimport './services/ohlc-service';\nimport './services/interest-rate-service';\nimport './services/interest-ledger-service';\n"]}
@@ -1,46 +1,16 @@
1
1
  "use strict";
2
- var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
3
- var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
4
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
5
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
6
- return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
7
- function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
8
- function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
9
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
10
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
11
- function fulfill(value) { resume("next", value); }
12
- function reject(value) { resume("throw", value); }
13
- function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
14
- };
15
2
  Object.defineProperty(exports, "__esModule", { value: true });
16
- const data_series_1 = require("@yuants/data-series");
3
+ const data_ohlc_1 = require("@yuants/data-ohlc");
17
4
  const protocol_1 = require("@yuants/protocol");
18
5
  const sql_1 = require("@yuants/sql");
19
6
  const utils_1 = require("@yuants/utils");
20
7
  const rxjs_1 = require("rxjs");
21
- const public_api_1 = require("../api/public-api");
22
- const provideOHLCFromTimeBackwardService_1 = require("../utils/provideOHLCFromTimeBackwardService");
23
8
  const ws_1 = require("../ws");
24
9
  const terminal = protocol_1.Terminal.fromNodeEnv();
25
10
  // 时间粒度,默认值1m
26
11
  // 如 [1m/3m/5m/15m/30m/1H/2H/4H]
27
12
  // 香港时间开盘价k线:[6H/12H/1D/1W/1M]
28
13
  // UTC时间开盘价k线:[6Hutc/12Hutc/1Dutc/1Wutc/1Mutc]
29
- const DURATION_TO_OKX_BAR_TYPE = {
30
- PT1M: '1m',
31
- PT3M: '3m',
32
- PT5M: '5m',
33
- PT15M: '15m',
34
- PT30M: '30m',
35
- PT1H: '1H',
36
- PT2H: '2H',
37
- PT4H: '4H',
38
- PT6H: '6H',
39
- PT12H: '12H',
40
- P1D: '1D',
41
- P1W: '1W',
42
- P1M: '1M',
43
- };
44
14
  const DURATION_TO_OKX_CANDLE_TYPE = {
45
15
  PT1M: 'candle1m',
46
16
  PT3M: 'candle3m',
@@ -67,86 +37,26 @@ const OHLC_V2_WRITE_COLUMNS = [
67
37
  'volume',
68
38
  'open_interest',
69
39
  ];
70
- (0, data_series_1.createSeriesProvider)(terminal, {
71
- tableName: 'ohlc',
72
- series_id_prefix_parts: ['OKX'],
73
- reversed: true,
74
- serviceOptions: { concurrent: 1 },
75
- queryFn: function (_a) {
76
- return __asyncGenerator(this, arguments, function* ({ series_id, ended_at }) {
77
- const [datasource_id, product_id, duration] = (0, utils_1.decodePath)(series_id);
78
- const offset = (0, utils_1.convertDurationToOffset)(duration);
79
- if (!datasource_id) {
80
- throw 'datasource_id is required';
81
- }
82
- if (!product_id) {
83
- throw 'product_id is required';
84
- }
85
- if (!offset) {
86
- throw 'duration is invalid';
87
- }
88
- const [instType, instId] = (0, utils_1.decodePath)(product_id);
89
- if (!instId) {
90
- throw `invalid product_id: ${product_id}`;
91
- }
92
- const bar = DURATION_TO_OKX_BAR_TYPE[duration];
93
- if (!bar) {
94
- throw `unsupported duration: ${duration}`;
95
- }
96
- let currentStartTime = ended_at;
97
- while (true) {
98
- // 向前翻页,时间降序,不含 after 时间点
99
- const res = yield __await((0, public_api_1.getHistoryCandles)({
100
- instId,
101
- bar,
102
- after: `${currentStartTime}`,
103
- limit: '100',
104
- }));
105
- if (res.code !== '0') {
106
- throw `API failed: ${res.code} ${res.msg}`;
107
- }
108
- if (res.data.length === 0)
109
- break;
110
- currentStartTime = +res.data[res.data.length - 1][0];
111
- const data = res.data.map((x) => ({
112
- series_id,
113
- datasource_id,
114
- product_id,
115
- duration,
116
- created_at: (0, utils_1.formatTime)(+x[0]),
117
- closed_at: (0, utils_1.formatTime)(+x[0] + offset),
118
- open: x[1],
119
- high: x[2],
120
- low: x[3],
121
- close: x[4],
122
- volume: x[5],
123
- open_interest: '0',
124
- }));
125
- yield yield __await(data);
126
- yield __await((0, rxjs_1.firstValueFrom)((0, rxjs_1.timer)(1000)));
127
- }
128
- });
129
- },
130
- });
131
40
  terminal.channel.publishChannel('ohlc', { pattern: `^OKX/` }, (series_id) => {
132
- const [datasource_id, product_id, duration] = (0, utils_1.decodePath)(series_id);
133
- const [instType, instId] = (0, utils_1.decodePath)(product_id);
41
+ const { product_id, duration } = (0, data_ohlc_1.decodeOHLCSeriesId)(series_id);
42
+ const [datasource_id, instType, instId] = (0, utils_1.decodePath)(product_id);
134
43
  const offset = (0, utils_1.convertDurationToOffset)(duration);
135
44
  if (!datasource_id) {
136
45
  throw 'datasource_id is required';
137
46
  }
138
- if (!product_id) {
139
- throw 'product_id is required';
140
- }
141
47
  if (!instType || !instId) {
142
48
  throw `invalid product_id: ${product_id}`;
143
49
  }
144
50
  if (!offset) {
145
51
  throw 'duration is invalid';
146
52
  }
147
- const series_id_v2 = `${(0, utils_1.encodePath)(datasource_id, instType, instId)}/${duration}`;
53
+ const product_id_path = (0, utils_1.encodePath)(datasource_id, instType, instId);
148
54
  const candleType = DURATION_TO_OKX_CANDLE_TYPE[duration];
149
- console.info((0, utils_1.formatTime)(Date.now()), `subscribe`, series_id, product_id);
55
+ if (!candleType) {
56
+ throw `unsupported duration: ${duration}`;
57
+ }
58
+ const normalized_series_id = (0, data_ohlc_1.encodeOHLCSeriesId)(product_id_path, duration);
59
+ console.info((0, utils_1.formatTime)(Date.now()), `subscribe`, normalized_series_id, product_id_path);
150
60
  return (0, ws_1.useOHLC)(candleType, instId).pipe((0, rxjs_1.map)((data) => {
151
61
  const created_at = Number(data[0][0]);
152
62
  const closed_at = created_at + offset;
@@ -162,79 +72,19 @@ terminal.channel.publishChannel('ohlc', { pattern: `^OKX/` }, (series_id) => {
162
72
  high,
163
73
  low,
164
74
  close,
165
- series_id,
75
+ series_id: normalized_series_id,
166
76
  datasource_id,
167
77
  duration,
168
- product_id,
78
+ product_id: product_id_path,
169
79
  volume,
170
80
  open_interest: '0',
171
81
  };
172
- }), (0, rxjs_1.map)((x) => ({
173
- __origin: x,
174
- series_id: series_id_v2,
175
- created_at: x.created_at,
176
- closed_at: x.closed_at,
177
- open: x.open,
178
- high: x.high,
179
- low: x.low,
180
- close: x.close,
181
- volume: x.volume,
182
- open_interest: x.open_interest,
183
- })), (0, sql_1.writeToSQL)({
82
+ }), (0, sql_1.writeToSQL)({
184
83
  tableName: 'ohlc_v2',
185
84
  columns: OHLC_V2_WRITE_COLUMNS,
186
85
  conflictKeys: ['series_id', 'created_at'],
187
86
  writeInterval: 1000,
188
87
  terminal,
189
- }), (0, rxjs_1.map)((x) => x.__origin), (0, sql_1.writeToSQL)({
190
- tableName: 'ohlc',
191
- conflictKeys: ['series_id', 'created_at'],
192
- writeInterval: 1000,
193
- terminal,
194
88
  }));
195
89
  });
196
- (0, provideOHLCFromTimeBackwardService_1.provideOHLCFromTimeBackwardService)({
197
- terminal,
198
- datasource_id: 'OKX',
199
- supported_durations: Object.keys(DURATION_TO_OKX_BAR_TYPE),
200
- queryFn: async ({ series_id, datasource_id, product_id, duration, offset, time }) => {
201
- const [instType, instId] = (0, utils_1.decodePath)(product_id);
202
- if (!instId) {
203
- throw `invalid product_id: ${product_id}`;
204
- }
205
- const bar = DURATION_TO_OKX_BAR_TYPE[duration];
206
- if (!bar) {
207
- throw `unsupported duration: ${duration}`;
208
- }
209
- // 从指定时间点向过去获取一页数据
210
- const res = await (0, public_api_1.getHistoryCandles)({
211
- instId,
212
- bar,
213
- after: `${new Date(time).getTime()}`, // 不包含该时间点 (标准的右开)
214
- limit: `300`,
215
- });
216
- if (res.code !== '0') {
217
- throw `API failed: ${res.code} ${res.msg}`;
218
- }
219
- return res.data.map((x) => ({
220
- series_id,
221
- datasource_id,
222
- product_id,
223
- duration,
224
- created_at: (0, utils_1.formatTime)(+x[0]),
225
- closed_at: (0, utils_1.formatTime)(+x[0] + offset),
226
- open: x[1],
227
- high: x[2],
228
- low: x[3],
229
- close: x[4],
230
- volume: x[5],
231
- open_interest: '0',
232
- }));
233
- },
234
- serviceOptions: {
235
- // Rate limit: 20 requests per 2 seconds
236
- egress_token_capacity: 20,
237
- egress_token_refill_interval: 2000,
238
- },
239
- });
240
90
  //# sourceMappingURL=ohlc.js.map