@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.
- package/README.md +0 -4
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/public-data/ohlc.js +13 -163
- package/dist/public-data/ohlc.js.map +1 -1
- package/dist/services/interest-ledger-service.js +23 -19
- package/dist/services/interest-ledger-service.js.map +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/lib/public-data/ohlc.js +12 -162
- package/lib/public-data/ohlc.js.map +1 -1
- package/lib/services/interest-ledger-service.js +23 -19
- package/lib/services/interest-ledger-service.js.map +1 -1
- package/package.json +7 -7
- package/temp/build/typescript/ts_xKrCYDcc.json +1 -1
- package/temp/package-deps.json +8 -11
- package/temp/test/jest/haste-map-0104fb5fee08bd97aacd02300cdbf195-f3ddf881f4f21e2e5ae6006d95adf2b1-267deb988b5111321a1cf92c4d020334 +0 -0
- package/dist/public-data/interest_rate.js +0 -118
- package/dist/public-data/interest_rate.js.map +0 -1
- package/dist/utils/provideOHLCFromTimeBackwardService.js +0 -49
- package/dist/utils/provideOHLCFromTimeBackwardService.js.map +0 -1
- package/dist/utils/provideSeriesFromTimeBackwardService.js +0 -59
- package/dist/utils/provideSeriesFromTimeBackwardService.js.map +0 -1
- package/lib/public-data/interest_rate.d.ts +0 -2
- package/lib/public-data/interest_rate.d.ts.map +0 -1
- package/lib/public-data/interest_rate.js +0 -120
- package/lib/public-data/interest_rate.js.map +0 -1
- package/lib/utils/provideOHLCFromTimeBackwardService.d.ts +0 -24
- package/lib/utils/provideOHLCFromTimeBackwardService.d.ts.map +0 -1
- package/lib/utils/provideOHLCFromTimeBackwardService.js +0 -53
- package/lib/utils/provideOHLCFromTimeBackwardService.js.map +0 -1
- package/lib/utils/provideSeriesFromTimeBackwardService.d.ts +0 -22
- package/lib/utils/provideSeriesFromTimeBackwardService.d.ts.map +0 -1
- package/lib/utils/provideSeriesFromTimeBackwardService.js +0 -63
- 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,
|
|
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"]}
|
package/dist/public-data/ohlc.js
CHANGED
|
@@ -1,44 +1,14 @@
|
|
|
1
|
-
|
|
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 {
|
|
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
|
|
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
|
|
51
|
+
const product_id_path = encodePath(datasource_id, instType, instId);
|
|
146
52
|
const candleType = DURATION_TO_OKX_CANDLE_TYPE[duration];
|
|
147
|
-
|
|
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
|
-
}),
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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;
|
|
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';
|
package/lib/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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,
|
|
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"]}
|
package/lib/public-data/ohlc.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
53
|
+
const product_id_path = (0, utils_1.encodePath)(datasource_id, instType, instId);
|
|
148
54
|
const candleType = DURATION_TO_OKX_CANDLE_TYPE[duration];
|
|
149
|
-
|
|
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,
|
|
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
|