@tradejs/connectors 3.0.0 → 3.1.0
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/index.d.mts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +104 -381
- package/dist/index.mjs +86 -368
- package/package.json +3 -4
package/dist/index.js
CHANGED
|
@@ -51,21 +51,34 @@ module.exports = __toCommonJS(index_exports);
|
|
|
51
51
|
// src/ByBit/index.ts
|
|
52
52
|
var import_lodash = __toESM(require("lodash"));
|
|
53
53
|
var import_chalk = __toESM(require("chalk"));
|
|
54
|
-
var
|
|
55
|
-
var
|
|
56
|
-
var
|
|
54
|
+
var import_async = require("@tradejs/core/async");
|
|
55
|
+
var import_constants = require("@tradejs/core/constants");
|
|
56
|
+
var import_data = require("@tradejs/core/data");
|
|
57
57
|
var import_math = require("@tradejs/core/math");
|
|
58
58
|
var import_tickers = require("@tradejs/core/tickers");
|
|
59
|
-
var
|
|
60
|
-
var import_logger3 = require("@tradejs/infra/logger");
|
|
59
|
+
var import_time2 = require("@tradejs/core/time");
|
|
61
60
|
|
|
62
61
|
// src/ByBit/client.ts
|
|
63
62
|
var import_bybit_api = require("bybit-api");
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
|
|
64
|
+
// src/shared/runtime.ts
|
|
65
|
+
var noop = () => void 0;
|
|
66
|
+
var silentConnectorLogger = {
|
|
67
|
+
log: noop,
|
|
68
|
+
info: noop,
|
|
69
|
+
warn: noop,
|
|
70
|
+
error: noop
|
|
71
|
+
};
|
|
72
|
+
var getConnectorLogger = (runtime) => runtime?.logger ?? silentConnectorLogger;
|
|
73
|
+
var getConnectorAccountResolver = (runtime) => runtime?.resolveTradingAccount ?? (async () => null);
|
|
74
|
+
var decorateConnectorKline = (runtime, options) => runtime?.createCachedKline(options) ?? options.request;
|
|
75
|
+
|
|
76
|
+
// src/ByBit/client.ts
|
|
66
77
|
var PRIVATE_RECV_WINDOW_MS = 1e4;
|
|
67
|
-
var getClient = async (config, access = "private") => {
|
|
68
|
-
const
|
|
78
|
+
var getClient = async (config, access = "private", runtime) => {
|
|
79
|
+
const logger = getConnectorLogger(runtime);
|
|
80
|
+
const resolveTradingAccount = getConnectorAccountResolver(runtime);
|
|
81
|
+
const account = access === "public" && !config.accountId ? null : await resolveTradingAccount({
|
|
69
82
|
userName: config.userName,
|
|
70
83
|
accountId: config.accountId,
|
|
71
84
|
provider: "bybit",
|
|
@@ -80,14 +93,14 @@ var getClient = async (config, access = "private") => {
|
|
|
80
93
|
}
|
|
81
94
|
if (!account?.apiKey || !account.apiSecret) {
|
|
82
95
|
if (config.accountId) {
|
|
83
|
-
|
|
96
|
+
logger.log(
|
|
84
97
|
"error",
|
|
85
98
|
"Bybit trading account config not found: user=%s account=%s",
|
|
86
99
|
config.userName,
|
|
87
100
|
config.accountId
|
|
88
101
|
);
|
|
89
102
|
} else {
|
|
90
|
-
|
|
103
|
+
logger.log("error", "connection config not found: %s", config.userName);
|
|
91
104
|
}
|
|
92
105
|
return null;
|
|
93
106
|
}
|
|
@@ -104,310 +117,11 @@ var getClient = async (config, access = "private") => {
|
|
|
104
117
|
return client;
|
|
105
118
|
};
|
|
106
119
|
|
|
107
|
-
// src/shared/timescaleKlineCache.ts
|
|
108
|
-
var import_constants = require("@tradejs/core/constants");
|
|
109
|
-
var import_data = require("@tradejs/core/data");
|
|
110
|
-
var import_time = require("@tradejs/core/time");
|
|
111
|
-
var import_async = require("@tradejs/core/async");
|
|
112
|
-
var import_logger2 = require("@tradejs/infra/logger");
|
|
113
|
-
var import_candles = require("@tradejs/infra/timescale/candles");
|
|
114
|
-
var DEFAULT_LIMIT = 1e3;
|
|
115
|
-
var DEFAULT_CACHE_FALLBACK_WINDOW = 1e3;
|
|
116
|
-
var DEFAULT_TIMESCALE_RETRIES = 2;
|
|
117
|
-
var DEFAULT_TIMESCALE_RETRY_DELAY_MS = 1e3;
|
|
118
|
-
var resolveNonNegativeInt = (value, fallback) => {
|
|
119
|
-
const parsed = Number(value);
|
|
120
|
-
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
121
|
-
return fallback;
|
|
122
|
-
}
|
|
123
|
-
return Math.floor(parsed);
|
|
124
|
-
};
|
|
125
|
-
var getTimescaleRetryCount = () => resolveNonNegativeInt(
|
|
126
|
-
process.env.TIMESCALE_KLINE_RETRIES,
|
|
127
|
-
DEFAULT_TIMESCALE_RETRIES
|
|
128
|
-
);
|
|
129
|
-
var getTimescaleRetryDelayMs = () => resolveNonNegativeInt(
|
|
130
|
-
process.env.TIMESCALE_KLINE_RETRY_DELAY_MS,
|
|
131
|
-
DEFAULT_TIMESCALE_RETRY_DELAY_MS
|
|
132
|
-
);
|
|
133
|
-
var intervalMsOf = (interval) => interval * 6e4;
|
|
134
|
-
var clampToClosedCandle = (value, intervalMs) => Math.floor(value / intervalMs) * intervalMs;
|
|
135
|
-
var normalizeRangeToClosed = (intervalMs, start, end) => {
|
|
136
|
-
const lastClosed = Math.floor(Date.now() / intervalMs) * intervalMs;
|
|
137
|
-
const normStart = start !== void 0 ? clampToClosedCandle(start, intervalMs) : 0;
|
|
138
|
-
const cappedEnd = Math.min(end ?? Date.now(), lastClosed);
|
|
139
|
-
const normEnd = clampToClosedCandle(cappedEnd, intervalMs);
|
|
140
|
-
return { normStart, normEnd };
|
|
141
|
-
};
|
|
142
|
-
var rowsToKline = (rows) => rows.map(({ ts, ...data }) => ({
|
|
143
|
-
timestamp: new Date(ts).getTime(),
|
|
144
|
-
...data
|
|
145
|
-
}));
|
|
146
|
-
var createTimescaleCachedKline = ({
|
|
147
|
-
provider,
|
|
148
|
-
request,
|
|
149
|
-
intervalToMinutes: intervalToMinutes3,
|
|
150
|
-
limit = DEFAULT_LIMIT,
|
|
151
|
-
cacheFallbackWindow = DEFAULT_CACHE_FALLBACK_WINDOW
|
|
152
|
-
}) => {
|
|
153
|
-
let isTimescaleFallbackMode = false;
|
|
154
|
-
const runTimescaleOperation = async (operation) => {
|
|
155
|
-
const retries = getTimescaleRetryCount();
|
|
156
|
-
const retryDelayMs = getTimescaleRetryDelayMs();
|
|
157
|
-
for (let attempt = 0; ; attempt += 1) {
|
|
158
|
-
try {
|
|
159
|
-
return await operation();
|
|
160
|
-
} catch (error) {
|
|
161
|
-
if (attempt >= retries) {
|
|
162
|
-
throw error;
|
|
163
|
-
}
|
|
164
|
-
const waitMs = retryDelayMs * 2 ** attempt;
|
|
165
|
-
if (waitMs > 0) {
|
|
166
|
-
await (0, import_async.delay)(waitMs);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
const loadData = async (direction, pointer, limitBoundary, requestParams, intervalMs, options = {}) => {
|
|
172
|
-
if (pointer === void 0) return { data: [], loaded: false };
|
|
173
|
-
let accumulated = [];
|
|
174
|
-
let fulfilled = false;
|
|
175
|
-
let loaded = false;
|
|
176
|
-
const shouldAccumulate = options.accumulate ?? true;
|
|
177
|
-
while (!fulfilled) {
|
|
178
|
-
const currentPointer = pointer;
|
|
179
|
-
const params = {
|
|
180
|
-
symbol: requestParams.symbol,
|
|
181
|
-
interval: requestParams.interval,
|
|
182
|
-
silent: requestParams.silent,
|
|
183
|
-
end: requestParams.end
|
|
184
|
-
};
|
|
185
|
-
if (direction === "older") {
|
|
186
|
-
params.end = pointer;
|
|
187
|
-
if (limitBoundary !== void 0) params.start = limitBoundary;
|
|
188
|
-
} else {
|
|
189
|
-
params.start = pointer;
|
|
190
|
-
if (limitBoundary !== void 0) params.end = limitBoundary;
|
|
191
|
-
}
|
|
192
|
-
const partData = await request(params);
|
|
193
|
-
if (!partData.length) {
|
|
194
|
-
fulfilled = true;
|
|
195
|
-
break;
|
|
196
|
-
}
|
|
197
|
-
loaded = true;
|
|
198
|
-
if (options.onPartData) {
|
|
199
|
-
await options.onPartData(partData);
|
|
200
|
-
}
|
|
201
|
-
if (shouldAccumulate) {
|
|
202
|
-
accumulated = direction === "older" ? (0, import_data.mergeData)(partData, accumulated) : (0, import_data.mergeData)(accumulated, partData);
|
|
203
|
-
}
|
|
204
|
-
const boundaryReached = limitBoundary !== void 0 && (direction === "older" && currentPointer <= limitBoundary || direction === "newer" && currentPointer >= limitBoundary);
|
|
205
|
-
if (partData.length < limit || boundaryReached) {
|
|
206
|
-
fulfilled = true;
|
|
207
|
-
break;
|
|
208
|
-
}
|
|
209
|
-
const nextPointer = direction === "older" ? (0, import_time.getItemTimestamp)(partData[0]) - intervalMs : (0, import_time.getItemTimestamp)(partData[partData.length - 1]) + intervalMs;
|
|
210
|
-
if (!Number.isFinite(nextPointer) || nextPointer === currentPointer) {
|
|
211
|
-
fulfilled = true;
|
|
212
|
-
break;
|
|
213
|
-
}
|
|
214
|
-
pointer = nextPointer;
|
|
215
|
-
}
|
|
216
|
-
return { data: accumulated, loaded };
|
|
217
|
-
};
|
|
218
|
-
const refreshTail = async ({
|
|
219
|
-
symbol,
|
|
220
|
-
interval,
|
|
221
|
-
silent,
|
|
222
|
-
tailCount = 2
|
|
223
|
-
}) => {
|
|
224
|
-
const intMinutes = intervalToMinutes3(interval);
|
|
225
|
-
if (!intMinutes) {
|
|
226
|
-
import_logger2.logger.log("error", "refreshTail: invalid interval %s", interval);
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
const intervalMs = intervalMsOf(intMinutes);
|
|
230
|
-
const lastClosed = Math.floor(Date.now() / intervalMs) * intervalMs;
|
|
231
|
-
const tailEnd = lastClosed + intervalMs;
|
|
232
|
-
const tailStart = tailEnd - tailCount * intervalMs;
|
|
233
|
-
const part = await request({
|
|
234
|
-
symbol,
|
|
235
|
-
interval,
|
|
236
|
-
start: tailStart,
|
|
237
|
-
end: tailEnd,
|
|
238
|
-
silent
|
|
239
|
-
});
|
|
240
|
-
if (part.length) {
|
|
241
|
-
await runTimescaleOperation(
|
|
242
|
-
() => (0, import_candles.upsertCandles)((0, import_candles.toRows)(provider, symbol, intMinutes, part))
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
return async ({
|
|
247
|
-
symbol,
|
|
248
|
-
interval,
|
|
249
|
-
start: defaultStart,
|
|
250
|
-
end: defaultEnd,
|
|
251
|
-
silent = false,
|
|
252
|
-
cacheOnly = false,
|
|
253
|
-
warmOnly = false
|
|
254
|
-
}) => {
|
|
255
|
-
const intMinutes = intervalToMinutes3(interval);
|
|
256
|
-
if (!intMinutes) {
|
|
257
|
-
import_logger2.logger.log("error", "kline: invalid interval %s", interval);
|
|
258
|
-
return [];
|
|
259
|
-
}
|
|
260
|
-
if (defaultStart !== void 0 && defaultEnd !== void 0 && defaultEnd <= defaultStart) {
|
|
261
|
-
return [];
|
|
262
|
-
}
|
|
263
|
-
const intervalMs = intervalMsOf(intMinutes);
|
|
264
|
-
try {
|
|
265
|
-
const edges = await runTimescaleOperation(
|
|
266
|
-
() => (0, import_candles.getDataEdges)(provider, symbol, intMinutes)
|
|
267
|
-
);
|
|
268
|
-
let dataStart = edges.min;
|
|
269
|
-
let dataEnd = edges.max;
|
|
270
|
-
const { normStart, normEnd } = normalizeRangeToClosed(
|
|
271
|
-
intervalMs,
|
|
272
|
-
defaultStart,
|
|
273
|
-
defaultEnd
|
|
274
|
-
);
|
|
275
|
-
if (cacheOnly) {
|
|
276
|
-
const base = edges.max ?? Date.now();
|
|
277
|
-
const s = Math.max(
|
|
278
|
-
defaultStart ?? base - cacheFallbackWindow * intervalMs,
|
|
279
|
-
0
|
|
280
|
-
);
|
|
281
|
-
const e = defaultEnd ?? base;
|
|
282
|
-
const dbData2 = await runTimescaleOperation(
|
|
283
|
-
() => (0, import_candles.getCandlesRange)(provider, symbol, intMinutes, s, e)
|
|
284
|
-
);
|
|
285
|
-
return rowsToKline(dbData2);
|
|
286
|
-
}
|
|
287
|
-
const needOlderData = defaultStart !== void 0 && (dataStart === void 0 || normStart < dataStart);
|
|
288
|
-
const persistPartData = warmOnly ? (partData) => runTimescaleOperation(
|
|
289
|
-
() => (0, import_candles.upsertCandles)((0, import_candles.toRows)(provider, symbol, intMinutes, partData))
|
|
290
|
-
) : void 0;
|
|
291
|
-
if (needOlderData) {
|
|
292
|
-
const pointerForOlder = dataStart ?? normEnd ?? Date.now();
|
|
293
|
-
const olderResult = await loadData(
|
|
294
|
-
"older",
|
|
295
|
-
pointerForOlder,
|
|
296
|
-
normStart,
|
|
297
|
-
{
|
|
298
|
-
symbol,
|
|
299
|
-
interval,
|
|
300
|
-
silent,
|
|
301
|
-
start: normStart,
|
|
302
|
-
end: pointerForOlder
|
|
303
|
-
},
|
|
304
|
-
intervalMs,
|
|
305
|
-
{
|
|
306
|
-
accumulate: !warmOnly,
|
|
307
|
-
onPartData: persistPartData
|
|
308
|
-
}
|
|
309
|
-
);
|
|
310
|
-
if (warmOnly && olderResult.loaded) {
|
|
311
|
-
dataStart = normStart;
|
|
312
|
-
if (dataEnd === void 0) {
|
|
313
|
-
dataEnd = normEnd;
|
|
314
|
-
}
|
|
315
|
-
} else if (olderResult.data.length) {
|
|
316
|
-
await runTimescaleOperation(
|
|
317
|
-
() => (0, import_candles.upsertCandles)(
|
|
318
|
-
(0, import_candles.toRows)(provider, symbol, intMinutes, olderResult.data)
|
|
319
|
-
)
|
|
320
|
-
);
|
|
321
|
-
dataStart = normStart;
|
|
322
|
-
if (dataEnd === void 0) {
|
|
323
|
-
dataEnd = normEnd;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
const needNewerData = defaultEnd !== void 0 && (dataEnd === void 0 || normEnd > dataEnd);
|
|
328
|
-
if (needNewerData) {
|
|
329
|
-
const fallbackStart = (0, import_time.getTimestamp)(import_constants.PRELOAD_FALLBACK_DAYS);
|
|
330
|
-
const pointerForNewer = dataEnd ?? (defaultStart !== void 0 ? normStart : fallbackStart) ?? 0;
|
|
331
|
-
const newerResult = await loadData(
|
|
332
|
-
"newer",
|
|
333
|
-
pointerForNewer,
|
|
334
|
-
normEnd,
|
|
335
|
-
{
|
|
336
|
-
symbol,
|
|
337
|
-
interval,
|
|
338
|
-
silent,
|
|
339
|
-
start: pointerForNewer,
|
|
340
|
-
end: normEnd
|
|
341
|
-
},
|
|
342
|
-
intervalMs,
|
|
343
|
-
{
|
|
344
|
-
accumulate: !warmOnly,
|
|
345
|
-
onPartData: persistPartData
|
|
346
|
-
}
|
|
347
|
-
);
|
|
348
|
-
if (warmOnly && newerResult.loaded) {
|
|
349
|
-
dataEnd = normEnd;
|
|
350
|
-
} else if (newerResult.data.length) {
|
|
351
|
-
await runTimescaleOperation(
|
|
352
|
-
() => (0, import_candles.upsertCandles)(
|
|
353
|
-
(0, import_candles.toRows)(provider, symbol, intMinutes, newerResult.data)
|
|
354
|
-
)
|
|
355
|
-
);
|
|
356
|
-
dataEnd = normEnd;
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
const isRightEdgeQuery = defaultEnd === void 0 || defaultEnd && defaultEnd >= Date.now() - intervalMs;
|
|
360
|
-
if (!cacheOnly && isRightEdgeQuery) {
|
|
361
|
-
await refreshTail({ symbol, interval, silent });
|
|
362
|
-
}
|
|
363
|
-
if (warmOnly) {
|
|
364
|
-
if (isTimescaleFallbackMode) {
|
|
365
|
-
isTimescaleFallbackMode = false;
|
|
366
|
-
import_logger2.logger.log("info", "TimescaleDB connection restored for kline cache");
|
|
367
|
-
}
|
|
368
|
-
return [];
|
|
369
|
-
}
|
|
370
|
-
const rangeStart = defaultStart ?? dataStart ?? 0;
|
|
371
|
-
const rangeEnd = defaultEnd ?? dataEnd ?? Date.now();
|
|
372
|
-
const { normStart: finalStart, normEnd: finalEnd } = normalizeRangeToClosed(intervalMs, rangeStart, rangeEnd);
|
|
373
|
-
const dbData = await runTimescaleOperation(
|
|
374
|
-
() => (0, import_candles.getCandlesRange)(provider, symbol, intMinutes, finalStart, finalEnd)
|
|
375
|
-
);
|
|
376
|
-
if (isTimescaleFallbackMode) {
|
|
377
|
-
isTimescaleFallbackMode = false;
|
|
378
|
-
import_logger2.logger.log("info", "TimescaleDB connection restored for kline cache");
|
|
379
|
-
}
|
|
380
|
-
return rowsToKline(dbData);
|
|
381
|
-
} catch (error) {
|
|
382
|
-
if (!isTimescaleFallbackMode) {
|
|
383
|
-
isTimescaleFallbackMode = true;
|
|
384
|
-
import_logger2.logger.log(
|
|
385
|
-
"warn",
|
|
386
|
-
"TimescaleDB unavailable for %s %s: %s. Falling back to exchange API.",
|
|
387
|
-
symbol,
|
|
388
|
-
interval,
|
|
389
|
-
String(error)
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
if (cacheOnly || warmOnly) {
|
|
393
|
-
return [];
|
|
394
|
-
}
|
|
395
|
-
return request({
|
|
396
|
-
symbol,
|
|
397
|
-
interval,
|
|
398
|
-
start: defaultStart,
|
|
399
|
-
end: defaultEnd,
|
|
400
|
-
silent
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
};
|
|
404
|
-
};
|
|
405
|
-
|
|
406
120
|
// src/ByBit/utils.ts
|
|
407
|
-
var
|
|
121
|
+
var import_time = require("@tradejs/core/time");
|
|
408
122
|
var BYBIT_CATEGORY = "linear";
|
|
409
123
|
var parseKlineItem = (item) => ({
|
|
410
|
-
dt: (0,
|
|
124
|
+
dt: (0, import_time.formatUnix)(parseInt(item[0])),
|
|
411
125
|
timestamp: parseInt(item[0]),
|
|
412
126
|
open: parseFloat(item[1]),
|
|
413
127
|
high: parseFloat(item[2]),
|
|
@@ -598,7 +312,8 @@ var loadFundingFeeRows = async ({
|
|
|
598
312
|
client,
|
|
599
313
|
startTime,
|
|
600
314
|
endTime,
|
|
601
|
-
symbol
|
|
315
|
+
symbol,
|
|
316
|
+
logger
|
|
602
317
|
}) => {
|
|
603
318
|
if (typeof client.getTransactionLog !== "function") {
|
|
604
319
|
return [];
|
|
@@ -617,7 +332,7 @@ var loadFundingFeeRows = async ({
|
|
|
617
332
|
...cursor ? { cursor } : {}
|
|
618
333
|
});
|
|
619
334
|
if (response?.retCode !== 0) {
|
|
620
|
-
|
|
335
|
+
logger.log(
|
|
621
336
|
"debug",
|
|
622
337
|
"funding transaction log retCode: %s, %s",
|
|
623
338
|
response?.retCode,
|
|
@@ -649,7 +364,7 @@ var loadFundingFeeRows = async ({
|
|
|
649
364
|
}
|
|
650
365
|
return rows;
|
|
651
366
|
} catch (error) {
|
|
652
|
-
|
|
367
|
+
logger.log("debug", "funding transaction log failed: %s", error);
|
|
653
368
|
return [];
|
|
654
369
|
}
|
|
655
370
|
};
|
|
@@ -696,7 +411,8 @@ var resolveKlineRetryDelayMs = (res, attempt) => {
|
|
|
696
411
|
);
|
|
697
412
|
return backoffMs + jitterMs;
|
|
698
413
|
};
|
|
699
|
-
var ByBitConnectorCreator = async (config) => {
|
|
414
|
+
var ByBitConnectorCreator = async (config, runtime) => {
|
|
415
|
+
const logger = getConnectorLogger(runtime);
|
|
700
416
|
let state = {};
|
|
701
417
|
const universe = (0, import_types.resolveConnectorUniverse)(
|
|
702
418
|
BYBIT_CAPABILITIES,
|
|
@@ -707,11 +423,11 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
707
423
|
const positionSnapshotCache = /* @__PURE__ */ new Map();
|
|
708
424
|
const inflightPositionSnapshots = /* @__PURE__ */ new Map();
|
|
709
425
|
const getPublicClient = async () => {
|
|
710
|
-
publicClientPromise ??= getClient(config, "public");
|
|
426
|
+
publicClientPromise ??= getClient(config, "public", runtime);
|
|
711
427
|
return publicClientPromise;
|
|
712
428
|
};
|
|
713
429
|
const getPrivateClient = async () => {
|
|
714
|
-
privateClientPromise ??= getClient(config, "private");
|
|
430
|
+
privateClientPromise ??= getClient(config, "private", runtime);
|
|
715
431
|
return privateClientPromise;
|
|
716
432
|
};
|
|
717
433
|
const instrumentCache = /* @__PURE__ */ new Map();
|
|
@@ -839,7 +555,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
839
555
|
silent
|
|
840
556
|
}) => {
|
|
841
557
|
const normalizedStart = (0, import_math.round)(
|
|
842
|
-
start || (0,
|
|
558
|
+
start || (0, import_time2.getTimestamp)(import_constants.PRELOAD_FALLBACK_DAYS),
|
|
843
559
|
0
|
|
844
560
|
);
|
|
845
561
|
const normalizedEnd = (0, import_math.round)(end || Date.now());
|
|
@@ -861,7 +577,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
861
577
|
if (isKlineRateLimited(kline)) {
|
|
862
578
|
if (attempt < KLINE_RATE_LIMIT_MAX_ATTEMPTS) {
|
|
863
579
|
const waitMs = resolveKlineRetryDelayMs(kline, attempt);
|
|
864
|
-
|
|
580
|
+
logger.log(
|
|
865
581
|
"warn",
|
|
866
582
|
"kline rate limited for %s %s: attempt=%s/%s waitMs=%s",
|
|
867
583
|
symbol,
|
|
@@ -870,13 +586,13 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
870
586
|
KLINE_RATE_LIMIT_MAX_ATTEMPTS,
|
|
871
587
|
waitMs
|
|
872
588
|
);
|
|
873
|
-
await (0,
|
|
589
|
+
await (0, import_async.delay)(waitMs);
|
|
874
590
|
continue;
|
|
875
591
|
}
|
|
876
592
|
}
|
|
877
593
|
if (!kline?.result?.list) {
|
|
878
594
|
const responseError = typeof kline?.retMsg === "string" && kline.retMsg !== "OK" ? `${kline.retMsg}${typeof kline?.retCode === "number" ? ` (retCode: ${kline.retCode})` : ""}` : typeof kline?.retCode === "number" && kline.retCode !== 0 ? `retCode: ${kline.retCode}` : "";
|
|
879
|
-
|
|
595
|
+
logger.log(
|
|
880
596
|
"error",
|
|
881
597
|
"empty kline.list for %s %s%s",
|
|
882
598
|
symbol,
|
|
@@ -886,10 +602,10 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
886
602
|
return [];
|
|
887
603
|
}
|
|
888
604
|
if (!silent && (process.stdout.isTTY || process.env.TRADEJS_LOG_KLINE_REQUESTS === "1")) {
|
|
889
|
-
|
|
605
|
+
logger.log(
|
|
890
606
|
"info",
|
|
891
607
|
"%s %s %s %s",
|
|
892
|
-
import_chalk.default.yellow((0,
|
|
608
|
+
import_chalk.default.yellow((0, import_time2.formatUnix)(normalizedEnd)),
|
|
893
609
|
import_chalk.default.cyan(symbol),
|
|
894
610
|
import_chalk.default.cyan(interval),
|
|
895
611
|
import_chalk.default.yellow(kline.result.list.length)
|
|
@@ -899,7 +615,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
899
615
|
}
|
|
900
616
|
return [];
|
|
901
617
|
} catch (error) {
|
|
902
|
-
|
|
618
|
+
logger.log(
|
|
903
619
|
"error",
|
|
904
620
|
"request kline: %s %s %s",
|
|
905
621
|
normalizedStart,
|
|
@@ -927,7 +643,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
927
643
|
`bybit getPositionInfo ${symbol}`
|
|
928
644
|
);
|
|
929
645
|
if (positionRes.retCode !== 0) {
|
|
930
|
-
|
|
646
|
+
logger.log(
|
|
931
647
|
getLogLevel(positionRes),
|
|
932
648
|
"position retCode: %s, %s",
|
|
933
649
|
symbol,
|
|
@@ -940,7 +656,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
940
656
|
return null;
|
|
941
657
|
}
|
|
942
658
|
const position = positions[0];
|
|
943
|
-
|
|
659
|
+
logger.log(
|
|
944
660
|
"debug",
|
|
945
661
|
"position: %s %s qty=%s price=%s",
|
|
946
662
|
position.symbol,
|
|
@@ -952,7 +668,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
952
668
|
...position
|
|
953
669
|
};
|
|
954
670
|
} catch (error) {
|
|
955
|
-
|
|
671
|
+
logger.log("error", "getPositionSnapshot failed: %s %s", symbol, error);
|
|
956
672
|
return null;
|
|
957
673
|
}
|
|
958
674
|
};
|
|
@@ -991,10 +707,10 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
991
707
|
const meta = await getSymbolMeta(marketDataClient, symbol);
|
|
992
708
|
const positionQty = qty ?? (await getPositionSnapshot(symbol))?.qty ?? 0;
|
|
993
709
|
if (!Number.isFinite(positionQty) || positionQty <= 0) {
|
|
994
|
-
|
|
710
|
+
logger.log(
|
|
995
711
|
"warn",
|
|
996
712
|
"setTakeProfits: missing position qty: %s",
|
|
997
|
-
(0,
|
|
713
|
+
(0, import_data.toJson)({ symbol, qty, positionQty, takeProfits }, true)
|
|
998
714
|
);
|
|
999
715
|
return false;
|
|
1000
716
|
}
|
|
@@ -1006,10 +722,10 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1006
722
|
meta
|
|
1007
723
|
);
|
|
1008
724
|
if (!tpSizeNum || tpSizeNum < meta.minOrderQty) {
|
|
1009
|
-
|
|
725
|
+
logger.log(
|
|
1010
726
|
"warn",
|
|
1011
727
|
"tp skipped: size too small %s",
|
|
1012
|
-
(0,
|
|
728
|
+
(0, import_data.toJson)(
|
|
1013
729
|
{ symbol, tp, tpSizeNum, minOrderQty: meta.minOrderQty },
|
|
1014
730
|
true
|
|
1015
731
|
)
|
|
@@ -1033,7 +749,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1033
749
|
positionIdx: 0
|
|
1034
750
|
});
|
|
1035
751
|
if (isTradingStopNotModified(tpRes)) {
|
|
1036
|
-
|
|
752
|
+
logger.log(
|
|
1037
753
|
"debug",
|
|
1038
754
|
"tp unchanged: %s %s price=%s rate=%s",
|
|
1039
755
|
symbol,
|
|
@@ -1042,7 +758,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1042
758
|
tp.rate
|
|
1043
759
|
);
|
|
1044
760
|
} else if (tpRes.retCode === 0) {
|
|
1045
|
-
|
|
761
|
+
logger.log(
|
|
1046
762
|
"info",
|
|
1047
763
|
"tp updated: %s %s price=%s rate=%s",
|
|
1048
764
|
symbol,
|
|
@@ -1051,14 +767,14 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1051
767
|
tp.rate
|
|
1052
768
|
);
|
|
1053
769
|
} else {
|
|
1054
|
-
|
|
770
|
+
logger.log(
|
|
1055
771
|
"error",
|
|
1056
772
|
"tp failed: %s %s price=%s rate=%s %s",
|
|
1057
773
|
symbol,
|
|
1058
774
|
direction,
|
|
1059
775
|
tpPriceNorm.priceStr,
|
|
1060
776
|
tp.rate,
|
|
1061
|
-
(0,
|
|
777
|
+
(0, import_data.toJson)(tpRes, true)
|
|
1062
778
|
);
|
|
1063
779
|
}
|
|
1064
780
|
if (!isTradingStopAccepted(tpRes)) {
|
|
@@ -1096,7 +812,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1096
812
|
positionIdx: 0
|
|
1097
813
|
});
|
|
1098
814
|
if (isTradingStopNotModified(slRes)) {
|
|
1099
|
-
|
|
815
|
+
logger.log(
|
|
1100
816
|
"debug",
|
|
1101
817
|
"sl unchanged: %s %s stopLoss=%s",
|
|
1102
818
|
symbol,
|
|
@@ -1104,7 +820,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1104
820
|
slNormalized.priceStr
|
|
1105
821
|
);
|
|
1106
822
|
} else if (slRes.retCode === 0) {
|
|
1107
|
-
|
|
823
|
+
logger.log(
|
|
1108
824
|
"info",
|
|
1109
825
|
"sl updated: %s %s stopLoss=%s",
|
|
1110
826
|
symbol,
|
|
@@ -1112,13 +828,13 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1112
828
|
slNormalized.priceStr
|
|
1113
829
|
);
|
|
1114
830
|
} else {
|
|
1115
|
-
|
|
831
|
+
logger.log(
|
|
1116
832
|
"error",
|
|
1117
833
|
"sl failed: %s %s stopLoss=%s %s",
|
|
1118
834
|
symbol,
|
|
1119
835
|
direction,
|
|
1120
836
|
slNormalized.priceStr,
|
|
1121
|
-
(0,
|
|
837
|
+
(0, import_data.toJson)(slRes, true)
|
|
1122
838
|
);
|
|
1123
839
|
}
|
|
1124
840
|
return isTradingStopAccepted(slRes);
|
|
@@ -1133,7 +849,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1133
849
|
setState: async (newState) => {
|
|
1134
850
|
state = { ...state, ...newState };
|
|
1135
851
|
},
|
|
1136
|
-
kline:
|
|
852
|
+
kline: decorateConnectorKline(runtime, {
|
|
1137
853
|
provider: "bybit",
|
|
1138
854
|
request,
|
|
1139
855
|
intervalToMinutes: intervalToMinutes3,
|
|
@@ -1150,7 +866,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1150
866
|
settleCoin: "USDT"
|
|
1151
867
|
});
|
|
1152
868
|
if (positionRes.retCode !== 0) {
|
|
1153
|
-
|
|
869
|
+
logger.log(
|
|
1154
870
|
getLogLevel(positionRes),
|
|
1155
871
|
"positions retCode: %s, %s",
|
|
1156
872
|
positionRes.retCode
|
|
@@ -1173,7 +889,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1173
889
|
settleCoin: "USDT"
|
|
1174
890
|
});
|
|
1175
891
|
if (positionRes.retCode !== 0) {
|
|
1176
|
-
|
|
892
|
+
logger.log(
|
|
1177
893
|
getLogLevel(positionRes),
|
|
1178
894
|
"positions pnl retCode: %s, %s",
|
|
1179
895
|
positionRes.retCode
|
|
@@ -1233,7 +949,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1233
949
|
...cursor ? { cursor } : {}
|
|
1234
950
|
});
|
|
1235
951
|
if (response.retCode !== 0) {
|
|
1236
|
-
|
|
952
|
+
logger.log(
|
|
1237
953
|
"error",
|
|
1238
954
|
"closedPnl retCode: %s, %s",
|
|
1239
955
|
response.retCode,
|
|
@@ -1255,7 +971,8 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1255
971
|
client,
|
|
1256
972
|
startTime,
|
|
1257
973
|
endTime,
|
|
1258
|
-
symbol
|
|
974
|
+
symbol,
|
|
975
|
+
logger
|
|
1259
976
|
});
|
|
1260
977
|
return closedPnlRows.map((item) => {
|
|
1261
978
|
const qty = Number(item.qty ?? item.closedSize ?? Number.NaN);
|
|
@@ -1330,7 +1047,7 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1330
1047
|
...cursor ? { cursor } : {}
|
|
1331
1048
|
});
|
|
1332
1049
|
if (response.retCode !== 0) {
|
|
1333
|
-
|
|
1050
|
+
logger.log(
|
|
1334
1051
|
"error",
|
|
1335
1052
|
"entryExecutions retCode: %s, %s",
|
|
1336
1053
|
response.retCode,
|
|
@@ -1352,7 +1069,8 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1352
1069
|
client,
|
|
1353
1070
|
startTime,
|
|
1354
1071
|
endTime,
|
|
1355
|
-
symbol
|
|
1072
|
+
symbol,
|
|
1073
|
+
logger
|
|
1356
1074
|
});
|
|
1357
1075
|
return executionRows.map((item) => {
|
|
1358
1076
|
const qty = Number(item.execQty ?? item.orderQty ?? Number.NaN);
|
|
@@ -1414,10 +1132,10 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1414
1132
|
if (signal) {
|
|
1415
1133
|
signal.orderFailureReason = failureReason;
|
|
1416
1134
|
}
|
|
1417
|
-
|
|
1135
|
+
logger.log(
|
|
1418
1136
|
"warn",
|
|
1419
1137
|
"placeOrder: rejected position increase: %s",
|
|
1420
|
-
(0,
|
|
1138
|
+
(0, import_data.toJson)(
|
|
1421
1139
|
{
|
|
1422
1140
|
symbol,
|
|
1423
1141
|
direction,
|
|
@@ -1439,10 +1157,10 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1439
1157
|
signal.orderValue = normalizedQty.qtyNum * price;
|
|
1440
1158
|
signal.orderFailureReason = "QTY_BELOW_MIN_ORDER";
|
|
1441
1159
|
}
|
|
1442
|
-
|
|
1160
|
+
logger.log(
|
|
1443
1161
|
"warn",
|
|
1444
1162
|
"placeOrder: rejected qty below minOrderQty: %s",
|
|
1445
|
-
(0,
|
|
1163
|
+
(0, import_data.toJson)(
|
|
1446
1164
|
{
|
|
1447
1165
|
symbol,
|
|
1448
1166
|
qty,
|
|
@@ -1461,10 +1179,10 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1461
1179
|
signal.orderValue = orderQty * price;
|
|
1462
1180
|
}
|
|
1463
1181
|
const entryNormalized = isLimit ? normalizePrice(price, "ENTRY", meta) : void 0;
|
|
1464
|
-
|
|
1182
|
+
logger.log(
|
|
1465
1183
|
"info",
|
|
1466
1184
|
"placeOrder: %s",
|
|
1467
|
-
(0,
|
|
1185
|
+
(0, import_data.toJson)(
|
|
1468
1186
|
{
|
|
1469
1187
|
symbol,
|
|
1470
1188
|
price,
|
|
@@ -1494,10 +1212,10 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1494
1212
|
orderFilter: "Order",
|
|
1495
1213
|
orderLinkId: typeof orderId === "string" && orderId.trim() ? orderId : void 0
|
|
1496
1214
|
});
|
|
1497
|
-
|
|
1215
|
+
logger.log(
|
|
1498
1216
|
getLogLevel(orderRes),
|
|
1499
1217
|
"placeOrder:response: %s",
|
|
1500
|
-
(0,
|
|
1218
|
+
(0, import_data.toJson)(orderRes, true)
|
|
1501
1219
|
);
|
|
1502
1220
|
if (orderRes.retCode !== 0) {
|
|
1503
1221
|
if (signal) {
|
|
@@ -1527,12 +1245,12 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1527
1245
|
qty: "0",
|
|
1528
1246
|
reduceOnly: true
|
|
1529
1247
|
});
|
|
1530
|
-
|
|
1248
|
+
logger.log(
|
|
1531
1249
|
getLogLevel(closeRes),
|
|
1532
1250
|
"closePosition: %s, %s, %s",
|
|
1533
1251
|
symbol,
|
|
1534
1252
|
direction,
|
|
1535
|
-
(0,
|
|
1253
|
+
(0, import_data.toJson)(closeRes, true)
|
|
1536
1254
|
);
|
|
1537
1255
|
if (closeRes.retCode !== 0) {
|
|
1538
1256
|
return false;
|
|
@@ -1638,7 +1356,6 @@ var ByBitConnectorCreator = async (config) => {
|
|
|
1638
1356
|
};
|
|
1639
1357
|
|
|
1640
1358
|
// src/Binance/index.ts
|
|
1641
|
-
var import_http = require("@tradejs/infra/http");
|
|
1642
1359
|
var import_types2 = require("@tradejs/types");
|
|
1643
1360
|
|
|
1644
1361
|
// src/shared/binancePublicApi.ts
|
|
@@ -1646,6 +1363,7 @@ var DEFAULT_BINANCE_PUBLIC_API_URL = "https://data-api.binance.vision";
|
|
|
1646
1363
|
var getBinancePublicApiUrl = () => process.env.BINANCE_BASE_URL?.trim() || DEFAULT_BINANCE_PUBLIC_API_URL;
|
|
1647
1364
|
|
|
1648
1365
|
// src/Binance/index.ts
|
|
1366
|
+
var import_http = require("@tradejs/core/http");
|
|
1649
1367
|
var INTERVAL_MAP = {
|
|
1650
1368
|
"1": "1m",
|
|
1651
1369
|
"3": "3m",
|
|
@@ -1692,7 +1410,7 @@ var capabilities = {
|
|
|
1692
1410
|
supportedUniverses: ["crypto"],
|
|
1693
1411
|
defaultUniverse: "crypto"
|
|
1694
1412
|
};
|
|
1695
|
-
var BinanceConnectorCreator = async (config) => {
|
|
1413
|
+
var BinanceConnectorCreator = async (config, runtime) => {
|
|
1696
1414
|
let state = {};
|
|
1697
1415
|
const universe = (0, import_types2.resolveConnectorUniverse)(capabilities, config.universe);
|
|
1698
1416
|
const requestKline = async ({
|
|
@@ -1820,7 +1538,7 @@ var BinanceConnectorCreator = async (config) => {
|
|
|
1820
1538
|
setState: async (newState) => {
|
|
1821
1539
|
state = { ...state, ...newState };
|
|
1822
1540
|
},
|
|
1823
|
-
kline:
|
|
1541
|
+
kline: decorateConnectorKline(runtime, {
|
|
1824
1542
|
provider: "binance",
|
|
1825
1543
|
request: requestKline,
|
|
1826
1544
|
intervalToMinutes
|
|
@@ -1915,8 +1633,8 @@ var BinanceConnectorCreator = async (config) => {
|
|
|
1915
1633
|
};
|
|
1916
1634
|
|
|
1917
1635
|
// src/Coinbase/index.ts
|
|
1918
|
-
var import_http2 = require("@tradejs/infra/http");
|
|
1919
1636
|
var import_types3 = require("@tradejs/types");
|
|
1637
|
+
var import_http2 = require("@tradejs/core/http");
|
|
1920
1638
|
var INTERVAL_MS2 = {
|
|
1921
1639
|
"1": 6e4,
|
|
1922
1640
|
"3": 18e4,
|
|
@@ -1983,7 +1701,7 @@ var capabilities2 = {
|
|
|
1983
1701
|
supportedUniverses: ["crypto"],
|
|
1984
1702
|
defaultUniverse: "crypto"
|
|
1985
1703
|
};
|
|
1986
|
-
var CoinbaseConnectorCreator = async (config) => {
|
|
1704
|
+
var CoinbaseConnectorCreator = async (config, runtime) => {
|
|
1987
1705
|
let state = {};
|
|
1988
1706
|
const universe = (0, import_types3.resolveConnectorUniverse)(capabilities2, config.universe);
|
|
1989
1707
|
const requestKline = async ({
|
|
@@ -2111,7 +1829,7 @@ var CoinbaseConnectorCreator = async (config) => {
|
|
|
2111
1829
|
setState: async (newState) => {
|
|
2112
1830
|
state = { ...state, ...newState };
|
|
2113
1831
|
},
|
|
2114
|
-
kline:
|
|
1832
|
+
kline: decorateConnectorKline(runtime, {
|
|
2115
1833
|
provider: "coinbase",
|
|
2116
1834
|
request: requestKline,
|
|
2117
1835
|
intervalToMinutes: intervalToMinutes2
|
|
@@ -2131,7 +1849,7 @@ var CoinbaseConnectorCreator = async (config) => {
|
|
|
2131
1849
|
};
|
|
2132
1850
|
|
|
2133
1851
|
// src/marketData/spotKlineProviders.ts
|
|
2134
|
-
var import_http3 = require("@tradejs/
|
|
1852
|
+
var import_http3 = require("@tradejs/core/http");
|
|
2135
1853
|
var toIntervalToken = (interval) => interval === "1h" ? "1h" : "15m";
|
|
2136
1854
|
var mapBinanceKline = (payload) => payload.map((item) => {
|
|
2137
1855
|
if (!Array.isArray(item)) return null;
|
|
@@ -2235,9 +1953,7 @@ var spotKlineProviders = {
|
|
|
2235
1953
|
|
|
2236
1954
|
// src/ByBit/klineStream.ts
|
|
2237
1955
|
var import_bybit_api2 = require("bybit-api");
|
|
2238
|
-
var
|
|
2239
|
-
var import_logger4 = require("@tradejs/infra/logger");
|
|
2240
|
-
var import_tradingAccounts2 = require("@tradejs/infra/tradingAccounts");
|
|
1956
|
+
var import_time3 = require("@tradejs/core/time");
|
|
2241
1957
|
var CATEGORY = "linear";
|
|
2242
1958
|
var SUBSCRIPTION_BATCH_SIZE = 100;
|
|
2243
1959
|
var KLINE_TOPIC_PATTERN = /^kline\.([^.]+)\.(.+)$/;
|
|
@@ -2277,7 +1993,7 @@ var parseBybitKlineEvent = (value, receivedAt = Date.now()) => {
|
|
|
2277
1993
|
symbol: symbol.toUpperCase(),
|
|
2278
1994
|
interval,
|
|
2279
1995
|
candle: {
|
|
2280
|
-
dt: (0,
|
|
1996
|
+
dt: (0, import_time3.formatUnix)(timestamp),
|
|
2281
1997
|
timestamp,
|
|
2282
1998
|
open,
|
|
2283
1999
|
high,
|
|
@@ -2294,22 +2010,23 @@ var parseBybitKlineEvent = (value, receivedAt = Date.now()) => {
|
|
|
2294
2010
|
};
|
|
2295
2011
|
var createBybitKlineStreamWithClient = ({
|
|
2296
2012
|
client,
|
|
2297
|
-
onEvent
|
|
2013
|
+
onEvent,
|
|
2014
|
+
logger = getConnectorLogger()
|
|
2298
2015
|
}) => {
|
|
2299
2016
|
let topics = /* @__PURE__ */ new Set();
|
|
2300
2017
|
let closed = false;
|
|
2301
2018
|
client.on("update", (value) => {
|
|
2302
2019
|
for (const event of parseBybitKlineEvent(value)) {
|
|
2303
2020
|
void Promise.resolve(onEvent(event)).catch((error) => {
|
|
2304
|
-
|
|
2021
|
+
logger.error("Bybit kline stream handler failed: %s", String(error));
|
|
2305
2022
|
});
|
|
2306
2023
|
}
|
|
2307
2024
|
});
|
|
2308
2025
|
client.on("reconnected", ({ wsKey }) => {
|
|
2309
|
-
|
|
2026
|
+
logger.info("Bybit kline stream reconnected: %s", wsKey);
|
|
2310
2027
|
});
|
|
2311
2028
|
client.on("exception", (error) => {
|
|
2312
|
-
|
|
2029
|
+
logger.error("Bybit kline stream exception: %s", String(error));
|
|
2313
2030
|
});
|
|
2314
2031
|
return {
|
|
2315
2032
|
setSubscriptions: (symbols, interval) => {
|
|
@@ -2323,16 +2040,16 @@ var createBybitKlineStreamWithClient = ({
|
|
|
2323
2040
|
const removed = [...topics].filter((topic) => !nextTopics.has(topic));
|
|
2324
2041
|
for (const batch of chunk(removed, SUBSCRIPTION_BATCH_SIZE)) {
|
|
2325
2042
|
void Promise.all(client.unsubscribeV5(batch, CATEGORY)).catch(
|
|
2326
|
-
(error) =>
|
|
2043
|
+
(error) => logger.error("Bybit kline unsubscribe failed: %s", String(error))
|
|
2327
2044
|
);
|
|
2328
2045
|
}
|
|
2329
2046
|
for (const batch of chunk(added, SUBSCRIPTION_BATCH_SIZE)) {
|
|
2330
2047
|
void Promise.all(client.subscribeV5(batch, CATEGORY)).catch(
|
|
2331
|
-
(error) =>
|
|
2048
|
+
(error) => logger.error("Bybit kline subscribe failed: %s", String(error))
|
|
2332
2049
|
);
|
|
2333
2050
|
}
|
|
2334
2051
|
topics = nextTopics;
|
|
2335
|
-
|
|
2052
|
+
logger.info(
|
|
2336
2053
|
"Bybit kline stream subscriptions: topics=%s added=%s removed=%s",
|
|
2337
2054
|
topics.size,
|
|
2338
2055
|
added.length,
|
|
@@ -2353,9 +2070,11 @@ var createBybitKlineStreamWithClient = ({
|
|
|
2353
2070
|
};
|
|
2354
2071
|
var createBybitKlineStream = async ({
|
|
2355
2072
|
config,
|
|
2356
|
-
onEvent
|
|
2073
|
+
onEvent,
|
|
2074
|
+
runtime
|
|
2357
2075
|
}) => {
|
|
2358
|
-
const
|
|
2076
|
+
const resolveTradingAccount = getConnectorAccountResolver(runtime);
|
|
2077
|
+
const account = config.accountId ? await resolveTradingAccount({
|
|
2359
2078
|
userName: config.userName,
|
|
2360
2079
|
accountId: config.accountId,
|
|
2361
2080
|
provider: "bybit",
|
|
@@ -2368,7 +2087,11 @@ var createBybitKlineStream = async ({
|
|
|
2368
2087
|
Number(process.env.BYBIT_WS_RECONNECT_TIMEOUT_MS ?? 1e3)
|
|
2369
2088
|
)
|
|
2370
2089
|
});
|
|
2371
|
-
return createBybitKlineStreamWithClient({
|
|
2090
|
+
return createBybitKlineStreamWithClient({
|
|
2091
|
+
client,
|
|
2092
|
+
onEvent,
|
|
2093
|
+
logger: getConnectorLogger(runtime)
|
|
2094
|
+
});
|
|
2372
2095
|
};
|
|
2373
2096
|
|
|
2374
2097
|
// src/marketData/providers/binanceCoinbaseSpread.ts
|
|
@@ -2427,7 +2150,7 @@ var binanceCoinbaseSpreadProvider = {
|
|
|
2427
2150
|
};
|
|
2428
2151
|
|
|
2429
2152
|
// src/marketData/providers/coinalyze.ts
|
|
2430
|
-
var
|
|
2153
|
+
var import_async2 = require("@tradejs/core/async");
|
|
2431
2154
|
var import_indicators2 = require("@tradejs/core/indicators");
|
|
2432
2155
|
var coinalyzeIntervalMap = {
|
|
2433
2156
|
"15m": "15min",
|
|
@@ -2497,7 +2220,7 @@ var fetchCoinalyzeSeries = async (params) => {
|
|
|
2497
2220
|
lastRequestTs + coinalyzeMinRequestDelayMs - now
|
|
2498
2221
|
);
|
|
2499
2222
|
if (waitMs > 0) {
|
|
2500
|
-
await (0,
|
|
2223
|
+
await (0, import_async2.delay)(waitMs);
|
|
2501
2224
|
}
|
|
2502
2225
|
lastRequestTs = Date.now();
|
|
2503
2226
|
const response = await fetch(url.toString(), { headers });
|
|
@@ -2511,7 +2234,7 @@ var fetchCoinalyzeSeries = async (params) => {
|
|
|
2511
2234
|
const transient = response.status === 429 || response.status >= 500;
|
|
2512
2235
|
if (attempt < coinalyzeMaxRetries && transient) {
|
|
2513
2236
|
const backoffMs = Math.min(1e4, 750 * 2 ** attempt);
|
|
2514
|
-
await (0,
|
|
2237
|
+
await (0, import_async2.delay)(retryAfterMs ?? backoffMs);
|
|
2515
2238
|
continue;
|
|
2516
2239
|
}
|
|
2517
2240
|
throw new Error(`Coinalyze ${endpoint} ${response.status}: ${text}`);
|