@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.mjs CHANGED
@@ -1,20 +1,33 @@
1
1
  // src/ByBit/index.ts
2
2
  import _ from "lodash";
3
3
  import chalk from "chalk";
4
- import { delay as delay2 } from "@tradejs/core/async";
5
- import { PRELOAD_FALLBACK_DAYS as PRELOAD_FALLBACK_DAYS2 } from "@tradejs/core/constants";
4
+ import { delay } from "@tradejs/core/async";
5
+ import { PRELOAD_FALLBACK_DAYS } from "@tradejs/core/constants";
6
6
  import { toJson } from "@tradejs/core/data";
7
7
  import { round } from "@tradejs/core/math";
8
8
  import { normalizeTickerData } from "@tradejs/core/tickers";
9
- import { formatUnix as formatUnix2, getTimestamp as getTimestamp2 } from "@tradejs/core/time";
10
- import { logger as logger3 } from "@tradejs/infra/logger";
9
+ import { formatUnix as formatUnix2, getTimestamp } from "@tradejs/core/time";
11
10
 
12
11
  // src/ByBit/client.ts
13
12
  import { RestClientV5 } from "bybit-api";
14
- import { logger } from "@tradejs/infra/logger";
15
- import { resolveTradingAccount } from "@tradejs/infra/tradingAccounts";
13
+
14
+ // src/shared/runtime.ts
15
+ var noop = () => void 0;
16
+ var silentConnectorLogger = {
17
+ log: noop,
18
+ info: noop,
19
+ warn: noop,
20
+ error: noop
21
+ };
22
+ var getConnectorLogger = (runtime) => runtime?.logger ?? silentConnectorLogger;
23
+ var getConnectorAccountResolver = (runtime) => runtime?.resolveTradingAccount ?? (async () => null);
24
+ var decorateConnectorKline = (runtime, options) => runtime?.createCachedKline(options) ?? options.request;
25
+
26
+ // src/ByBit/client.ts
16
27
  var PRIVATE_RECV_WINDOW_MS = 1e4;
17
- var getClient = async (config, access = "private") => {
28
+ var getClient = async (config, access = "private", runtime) => {
29
+ const logger = getConnectorLogger(runtime);
30
+ const resolveTradingAccount = getConnectorAccountResolver(runtime);
18
31
  const account = access === "public" && !config.accountId ? null : await resolveTradingAccount({
19
32
  userName: config.userName,
20
33
  accountId: config.accountId,
@@ -54,310 +67,6 @@ var getClient = async (config, access = "private") => {
54
67
  return client;
55
68
  };
56
69
 
57
- // src/shared/timescaleKlineCache.ts
58
- import { PRELOAD_FALLBACK_DAYS } from "@tradejs/core/constants";
59
- import { mergeData } from "@tradejs/core/data";
60
- import { getItemTimestamp, getTimestamp } from "@tradejs/core/time";
61
- import { delay } from "@tradejs/core/async";
62
- import { logger as logger2 } from "@tradejs/infra/logger";
63
- import {
64
- getCandlesRange,
65
- getDataEdges,
66
- toRows,
67
- upsertCandles
68
- } from "@tradejs/infra/timescale/candles";
69
- var DEFAULT_LIMIT = 1e3;
70
- var DEFAULT_CACHE_FALLBACK_WINDOW = 1e3;
71
- var DEFAULT_TIMESCALE_RETRIES = 2;
72
- var DEFAULT_TIMESCALE_RETRY_DELAY_MS = 1e3;
73
- var resolveNonNegativeInt = (value, fallback) => {
74
- const parsed = Number(value);
75
- if (!Number.isFinite(parsed) || parsed < 0) {
76
- return fallback;
77
- }
78
- return Math.floor(parsed);
79
- };
80
- var getTimescaleRetryCount = () => resolveNonNegativeInt(
81
- process.env.TIMESCALE_KLINE_RETRIES,
82
- DEFAULT_TIMESCALE_RETRIES
83
- );
84
- var getTimescaleRetryDelayMs = () => resolveNonNegativeInt(
85
- process.env.TIMESCALE_KLINE_RETRY_DELAY_MS,
86
- DEFAULT_TIMESCALE_RETRY_DELAY_MS
87
- );
88
- var intervalMsOf = (interval) => interval * 6e4;
89
- var clampToClosedCandle = (value, intervalMs) => Math.floor(value / intervalMs) * intervalMs;
90
- var normalizeRangeToClosed = (intervalMs, start, end) => {
91
- const lastClosed = Math.floor(Date.now() / intervalMs) * intervalMs;
92
- const normStart = start !== void 0 ? clampToClosedCandle(start, intervalMs) : 0;
93
- const cappedEnd = Math.min(end ?? Date.now(), lastClosed);
94
- const normEnd = clampToClosedCandle(cappedEnd, intervalMs);
95
- return { normStart, normEnd };
96
- };
97
- var rowsToKline = (rows) => rows.map(({ ts, ...data }) => ({
98
- timestamp: new Date(ts).getTime(),
99
- ...data
100
- }));
101
- var createTimescaleCachedKline = ({
102
- provider,
103
- request,
104
- intervalToMinutes: intervalToMinutes3,
105
- limit = DEFAULT_LIMIT,
106
- cacheFallbackWindow = DEFAULT_CACHE_FALLBACK_WINDOW
107
- }) => {
108
- let isTimescaleFallbackMode = false;
109
- const runTimescaleOperation = async (operation) => {
110
- const retries = getTimescaleRetryCount();
111
- const retryDelayMs = getTimescaleRetryDelayMs();
112
- for (let attempt = 0; ; attempt += 1) {
113
- try {
114
- return await operation();
115
- } catch (error) {
116
- if (attempt >= retries) {
117
- throw error;
118
- }
119
- const waitMs = retryDelayMs * 2 ** attempt;
120
- if (waitMs > 0) {
121
- await delay(waitMs);
122
- }
123
- }
124
- }
125
- };
126
- const loadData = async (direction, pointer, limitBoundary, requestParams, intervalMs, options = {}) => {
127
- if (pointer === void 0) return { data: [], loaded: false };
128
- let accumulated = [];
129
- let fulfilled = false;
130
- let loaded = false;
131
- const shouldAccumulate = options.accumulate ?? true;
132
- while (!fulfilled) {
133
- const currentPointer = pointer;
134
- const params = {
135
- symbol: requestParams.symbol,
136
- interval: requestParams.interval,
137
- silent: requestParams.silent,
138
- end: requestParams.end
139
- };
140
- if (direction === "older") {
141
- params.end = pointer;
142
- if (limitBoundary !== void 0) params.start = limitBoundary;
143
- } else {
144
- params.start = pointer;
145
- if (limitBoundary !== void 0) params.end = limitBoundary;
146
- }
147
- const partData = await request(params);
148
- if (!partData.length) {
149
- fulfilled = true;
150
- break;
151
- }
152
- loaded = true;
153
- if (options.onPartData) {
154
- await options.onPartData(partData);
155
- }
156
- if (shouldAccumulate) {
157
- accumulated = direction === "older" ? mergeData(partData, accumulated) : mergeData(accumulated, partData);
158
- }
159
- const boundaryReached = limitBoundary !== void 0 && (direction === "older" && currentPointer <= limitBoundary || direction === "newer" && currentPointer >= limitBoundary);
160
- if (partData.length < limit || boundaryReached) {
161
- fulfilled = true;
162
- break;
163
- }
164
- const nextPointer = direction === "older" ? getItemTimestamp(partData[0]) - intervalMs : getItemTimestamp(partData[partData.length - 1]) + intervalMs;
165
- if (!Number.isFinite(nextPointer) || nextPointer === currentPointer) {
166
- fulfilled = true;
167
- break;
168
- }
169
- pointer = nextPointer;
170
- }
171
- return { data: accumulated, loaded };
172
- };
173
- const refreshTail = async ({
174
- symbol,
175
- interval,
176
- silent,
177
- tailCount = 2
178
- }) => {
179
- const intMinutes = intervalToMinutes3(interval);
180
- if (!intMinutes) {
181
- logger2.log("error", "refreshTail: invalid interval %s", interval);
182
- return;
183
- }
184
- const intervalMs = intervalMsOf(intMinutes);
185
- const lastClosed = Math.floor(Date.now() / intervalMs) * intervalMs;
186
- const tailEnd = lastClosed + intervalMs;
187
- const tailStart = tailEnd - tailCount * intervalMs;
188
- const part = await request({
189
- symbol,
190
- interval,
191
- start: tailStart,
192
- end: tailEnd,
193
- silent
194
- });
195
- if (part.length) {
196
- await runTimescaleOperation(
197
- () => upsertCandles(toRows(provider, symbol, intMinutes, part))
198
- );
199
- }
200
- };
201
- return async ({
202
- symbol,
203
- interval,
204
- start: defaultStart,
205
- end: defaultEnd,
206
- silent = false,
207
- cacheOnly = false,
208
- warmOnly = false
209
- }) => {
210
- const intMinutes = intervalToMinutes3(interval);
211
- if (!intMinutes) {
212
- logger2.log("error", "kline: invalid interval %s", interval);
213
- return [];
214
- }
215
- if (defaultStart !== void 0 && defaultEnd !== void 0 && defaultEnd <= defaultStart) {
216
- return [];
217
- }
218
- const intervalMs = intervalMsOf(intMinutes);
219
- try {
220
- const edges = await runTimescaleOperation(
221
- () => getDataEdges(provider, symbol, intMinutes)
222
- );
223
- let dataStart = edges.min;
224
- let dataEnd = edges.max;
225
- const { normStart, normEnd } = normalizeRangeToClosed(
226
- intervalMs,
227
- defaultStart,
228
- defaultEnd
229
- );
230
- if (cacheOnly) {
231
- const base = edges.max ?? Date.now();
232
- const s = Math.max(
233
- defaultStart ?? base - cacheFallbackWindow * intervalMs,
234
- 0
235
- );
236
- const e = defaultEnd ?? base;
237
- const dbData2 = await runTimescaleOperation(
238
- () => getCandlesRange(provider, symbol, intMinutes, s, e)
239
- );
240
- return rowsToKline(dbData2);
241
- }
242
- const needOlderData = defaultStart !== void 0 && (dataStart === void 0 || normStart < dataStart);
243
- const persistPartData = warmOnly ? (partData) => runTimescaleOperation(
244
- () => upsertCandles(toRows(provider, symbol, intMinutes, partData))
245
- ) : void 0;
246
- if (needOlderData) {
247
- const pointerForOlder = dataStart ?? normEnd ?? Date.now();
248
- const olderResult = await loadData(
249
- "older",
250
- pointerForOlder,
251
- normStart,
252
- {
253
- symbol,
254
- interval,
255
- silent,
256
- start: normStart,
257
- end: pointerForOlder
258
- },
259
- intervalMs,
260
- {
261
- accumulate: !warmOnly,
262
- onPartData: persistPartData
263
- }
264
- );
265
- if (warmOnly && olderResult.loaded) {
266
- dataStart = normStart;
267
- if (dataEnd === void 0) {
268
- dataEnd = normEnd;
269
- }
270
- } else if (olderResult.data.length) {
271
- await runTimescaleOperation(
272
- () => upsertCandles(
273
- toRows(provider, symbol, intMinutes, olderResult.data)
274
- )
275
- );
276
- dataStart = normStart;
277
- if (dataEnd === void 0) {
278
- dataEnd = normEnd;
279
- }
280
- }
281
- }
282
- const needNewerData = defaultEnd !== void 0 && (dataEnd === void 0 || normEnd > dataEnd);
283
- if (needNewerData) {
284
- const fallbackStart = getTimestamp(PRELOAD_FALLBACK_DAYS);
285
- const pointerForNewer = dataEnd ?? (defaultStart !== void 0 ? normStart : fallbackStart) ?? 0;
286
- const newerResult = await loadData(
287
- "newer",
288
- pointerForNewer,
289
- normEnd,
290
- {
291
- symbol,
292
- interval,
293
- silent,
294
- start: pointerForNewer,
295
- end: normEnd
296
- },
297
- intervalMs,
298
- {
299
- accumulate: !warmOnly,
300
- onPartData: persistPartData
301
- }
302
- );
303
- if (warmOnly && newerResult.loaded) {
304
- dataEnd = normEnd;
305
- } else if (newerResult.data.length) {
306
- await runTimescaleOperation(
307
- () => upsertCandles(
308
- toRows(provider, symbol, intMinutes, newerResult.data)
309
- )
310
- );
311
- dataEnd = normEnd;
312
- }
313
- }
314
- const isRightEdgeQuery = defaultEnd === void 0 || defaultEnd && defaultEnd >= Date.now() - intervalMs;
315
- if (!cacheOnly && isRightEdgeQuery) {
316
- await refreshTail({ symbol, interval, silent });
317
- }
318
- if (warmOnly) {
319
- if (isTimescaleFallbackMode) {
320
- isTimescaleFallbackMode = false;
321
- logger2.log("info", "TimescaleDB connection restored for kline cache");
322
- }
323
- return [];
324
- }
325
- const rangeStart = defaultStart ?? dataStart ?? 0;
326
- const rangeEnd = defaultEnd ?? dataEnd ?? Date.now();
327
- const { normStart: finalStart, normEnd: finalEnd } = normalizeRangeToClosed(intervalMs, rangeStart, rangeEnd);
328
- const dbData = await runTimescaleOperation(
329
- () => getCandlesRange(provider, symbol, intMinutes, finalStart, finalEnd)
330
- );
331
- if (isTimescaleFallbackMode) {
332
- isTimescaleFallbackMode = false;
333
- logger2.log("info", "TimescaleDB connection restored for kline cache");
334
- }
335
- return rowsToKline(dbData);
336
- } catch (error) {
337
- if (!isTimescaleFallbackMode) {
338
- isTimescaleFallbackMode = true;
339
- logger2.log(
340
- "warn",
341
- "TimescaleDB unavailable for %s %s: %s. Falling back to exchange API.",
342
- symbol,
343
- interval,
344
- String(error)
345
- );
346
- }
347
- if (cacheOnly || warmOnly) {
348
- return [];
349
- }
350
- return request({
351
- symbol,
352
- interval,
353
- start: defaultStart,
354
- end: defaultEnd,
355
- silent
356
- });
357
- }
358
- };
359
- };
360
-
361
70
  // src/ByBit/utils.ts
362
71
  import { formatUnix } from "@tradejs/core/time";
363
72
  var BYBIT_CATEGORY = "linear";
@@ -555,7 +264,8 @@ var loadFundingFeeRows = async ({
555
264
  client,
556
265
  startTime,
557
266
  endTime,
558
- symbol
267
+ symbol,
268
+ logger
559
269
  }) => {
560
270
  if (typeof client.getTransactionLog !== "function") {
561
271
  return [];
@@ -574,7 +284,7 @@ var loadFundingFeeRows = async ({
574
284
  ...cursor ? { cursor } : {}
575
285
  });
576
286
  if (response?.retCode !== 0) {
577
- logger3.log(
287
+ logger.log(
578
288
  "debug",
579
289
  "funding transaction log retCode: %s, %s",
580
290
  response?.retCode,
@@ -606,7 +316,7 @@ var loadFundingFeeRows = async ({
606
316
  }
607
317
  return rows;
608
318
  } catch (error) {
609
- logger3.log("debug", "funding transaction log failed: %s", error);
319
+ logger.log("debug", "funding transaction log failed: %s", error);
610
320
  return [];
611
321
  }
612
322
  };
@@ -653,7 +363,8 @@ var resolveKlineRetryDelayMs = (res, attempt) => {
653
363
  );
654
364
  return backoffMs + jitterMs;
655
365
  };
656
- var ByBitConnectorCreator = async (config) => {
366
+ var ByBitConnectorCreator = async (config, runtime) => {
367
+ const logger = getConnectorLogger(runtime);
657
368
  let state = {};
658
369
  const universe = resolveConnectorUniverse(
659
370
  BYBIT_CAPABILITIES,
@@ -664,11 +375,11 @@ var ByBitConnectorCreator = async (config) => {
664
375
  const positionSnapshotCache = /* @__PURE__ */ new Map();
665
376
  const inflightPositionSnapshots = /* @__PURE__ */ new Map();
666
377
  const getPublicClient = async () => {
667
- publicClientPromise ??= getClient(config, "public");
378
+ publicClientPromise ??= getClient(config, "public", runtime);
668
379
  return publicClientPromise;
669
380
  };
670
381
  const getPrivateClient = async () => {
671
- privateClientPromise ??= getClient(config, "private");
382
+ privateClientPromise ??= getClient(config, "private", runtime);
672
383
  return privateClientPromise;
673
384
  };
674
385
  const instrumentCache = /* @__PURE__ */ new Map();
@@ -796,7 +507,7 @@ var ByBitConnectorCreator = async (config) => {
796
507
  silent
797
508
  }) => {
798
509
  const normalizedStart = round(
799
- start || getTimestamp2(PRELOAD_FALLBACK_DAYS2),
510
+ start || getTimestamp(PRELOAD_FALLBACK_DAYS),
800
511
  0
801
512
  );
802
513
  const normalizedEnd = round(end || Date.now());
@@ -818,7 +529,7 @@ var ByBitConnectorCreator = async (config) => {
818
529
  if (isKlineRateLimited(kline)) {
819
530
  if (attempt < KLINE_RATE_LIMIT_MAX_ATTEMPTS) {
820
531
  const waitMs = resolveKlineRetryDelayMs(kline, attempt);
821
- logger3.log(
532
+ logger.log(
822
533
  "warn",
823
534
  "kline rate limited for %s %s: attempt=%s/%s waitMs=%s",
824
535
  symbol,
@@ -827,13 +538,13 @@ var ByBitConnectorCreator = async (config) => {
827
538
  KLINE_RATE_LIMIT_MAX_ATTEMPTS,
828
539
  waitMs
829
540
  );
830
- await delay2(waitMs);
541
+ await delay(waitMs);
831
542
  continue;
832
543
  }
833
544
  }
834
545
  if (!kline?.result?.list) {
835
546
  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}` : "";
836
- logger3.log(
547
+ logger.log(
837
548
  "error",
838
549
  "empty kline.list for %s %s%s",
839
550
  symbol,
@@ -843,7 +554,7 @@ var ByBitConnectorCreator = async (config) => {
843
554
  return [];
844
555
  }
845
556
  if (!silent && (process.stdout.isTTY || process.env.TRADEJS_LOG_KLINE_REQUESTS === "1")) {
846
- logger3.log(
557
+ logger.log(
847
558
  "info",
848
559
  "%s %s %s %s",
849
560
  chalk.yellow(formatUnix2(normalizedEnd)),
@@ -856,7 +567,7 @@ var ByBitConnectorCreator = async (config) => {
856
567
  }
857
568
  return [];
858
569
  } catch (error) {
859
- logger3.log(
570
+ logger.log(
860
571
  "error",
861
572
  "request kline: %s %s %s",
862
573
  normalizedStart,
@@ -884,7 +595,7 @@ var ByBitConnectorCreator = async (config) => {
884
595
  `bybit getPositionInfo ${symbol}`
885
596
  );
886
597
  if (positionRes.retCode !== 0) {
887
- logger3.log(
598
+ logger.log(
888
599
  getLogLevel(positionRes),
889
600
  "position retCode: %s, %s",
890
601
  symbol,
@@ -897,7 +608,7 @@ var ByBitConnectorCreator = async (config) => {
897
608
  return null;
898
609
  }
899
610
  const position = positions[0];
900
- logger3.log(
611
+ logger.log(
901
612
  "debug",
902
613
  "position: %s %s qty=%s price=%s",
903
614
  position.symbol,
@@ -909,7 +620,7 @@ var ByBitConnectorCreator = async (config) => {
909
620
  ...position
910
621
  };
911
622
  } catch (error) {
912
- logger3.log("error", "getPositionSnapshot failed: %s %s", symbol, error);
623
+ logger.log("error", "getPositionSnapshot failed: %s %s", symbol, error);
913
624
  return null;
914
625
  }
915
626
  };
@@ -948,7 +659,7 @@ var ByBitConnectorCreator = async (config) => {
948
659
  const meta = await getSymbolMeta(marketDataClient, symbol);
949
660
  const positionQty = qty ?? (await getPositionSnapshot(symbol))?.qty ?? 0;
950
661
  if (!Number.isFinite(positionQty) || positionQty <= 0) {
951
- logger3.log(
662
+ logger.log(
952
663
  "warn",
953
664
  "setTakeProfits: missing position qty: %s",
954
665
  toJson({ symbol, qty, positionQty, takeProfits }, true)
@@ -963,7 +674,7 @@ var ByBitConnectorCreator = async (config) => {
963
674
  meta
964
675
  );
965
676
  if (!tpSizeNum || tpSizeNum < meta.minOrderQty) {
966
- logger3.log(
677
+ logger.log(
967
678
  "warn",
968
679
  "tp skipped: size too small %s",
969
680
  toJson(
@@ -990,7 +701,7 @@ var ByBitConnectorCreator = async (config) => {
990
701
  positionIdx: 0
991
702
  });
992
703
  if (isTradingStopNotModified(tpRes)) {
993
- logger3.log(
704
+ logger.log(
994
705
  "debug",
995
706
  "tp unchanged: %s %s price=%s rate=%s",
996
707
  symbol,
@@ -999,7 +710,7 @@ var ByBitConnectorCreator = async (config) => {
999
710
  tp.rate
1000
711
  );
1001
712
  } else if (tpRes.retCode === 0) {
1002
- logger3.log(
713
+ logger.log(
1003
714
  "info",
1004
715
  "tp updated: %s %s price=%s rate=%s",
1005
716
  symbol,
@@ -1008,7 +719,7 @@ var ByBitConnectorCreator = async (config) => {
1008
719
  tp.rate
1009
720
  );
1010
721
  } else {
1011
- logger3.log(
722
+ logger.log(
1012
723
  "error",
1013
724
  "tp failed: %s %s price=%s rate=%s %s",
1014
725
  symbol,
@@ -1053,7 +764,7 @@ var ByBitConnectorCreator = async (config) => {
1053
764
  positionIdx: 0
1054
765
  });
1055
766
  if (isTradingStopNotModified(slRes)) {
1056
- logger3.log(
767
+ logger.log(
1057
768
  "debug",
1058
769
  "sl unchanged: %s %s stopLoss=%s",
1059
770
  symbol,
@@ -1061,7 +772,7 @@ var ByBitConnectorCreator = async (config) => {
1061
772
  slNormalized.priceStr
1062
773
  );
1063
774
  } else if (slRes.retCode === 0) {
1064
- logger3.log(
775
+ logger.log(
1065
776
  "info",
1066
777
  "sl updated: %s %s stopLoss=%s",
1067
778
  symbol,
@@ -1069,7 +780,7 @@ var ByBitConnectorCreator = async (config) => {
1069
780
  slNormalized.priceStr
1070
781
  );
1071
782
  } else {
1072
- logger3.log(
783
+ logger.log(
1073
784
  "error",
1074
785
  "sl failed: %s %s stopLoss=%s %s",
1075
786
  symbol,
@@ -1090,7 +801,7 @@ var ByBitConnectorCreator = async (config) => {
1090
801
  setState: async (newState) => {
1091
802
  state = { ...state, ...newState };
1092
803
  },
1093
- kline: createTimescaleCachedKline({
804
+ kline: decorateConnectorKline(runtime, {
1094
805
  provider: "bybit",
1095
806
  request,
1096
807
  intervalToMinutes: intervalToMinutes3,
@@ -1107,7 +818,7 @@ var ByBitConnectorCreator = async (config) => {
1107
818
  settleCoin: "USDT"
1108
819
  });
1109
820
  if (positionRes.retCode !== 0) {
1110
- logger3.log(
821
+ logger.log(
1111
822
  getLogLevel(positionRes),
1112
823
  "positions retCode: %s, %s",
1113
824
  positionRes.retCode
@@ -1130,7 +841,7 @@ var ByBitConnectorCreator = async (config) => {
1130
841
  settleCoin: "USDT"
1131
842
  });
1132
843
  if (positionRes.retCode !== 0) {
1133
- logger3.log(
844
+ logger.log(
1134
845
  getLogLevel(positionRes),
1135
846
  "positions pnl retCode: %s, %s",
1136
847
  positionRes.retCode
@@ -1190,7 +901,7 @@ var ByBitConnectorCreator = async (config) => {
1190
901
  ...cursor ? { cursor } : {}
1191
902
  });
1192
903
  if (response.retCode !== 0) {
1193
- logger3.log(
904
+ logger.log(
1194
905
  "error",
1195
906
  "closedPnl retCode: %s, %s",
1196
907
  response.retCode,
@@ -1212,7 +923,8 @@ var ByBitConnectorCreator = async (config) => {
1212
923
  client,
1213
924
  startTime,
1214
925
  endTime,
1215
- symbol
926
+ symbol,
927
+ logger
1216
928
  });
1217
929
  return closedPnlRows.map((item) => {
1218
930
  const qty = Number(item.qty ?? item.closedSize ?? Number.NaN);
@@ -1287,7 +999,7 @@ var ByBitConnectorCreator = async (config) => {
1287
999
  ...cursor ? { cursor } : {}
1288
1000
  });
1289
1001
  if (response.retCode !== 0) {
1290
- logger3.log(
1002
+ logger.log(
1291
1003
  "error",
1292
1004
  "entryExecutions retCode: %s, %s",
1293
1005
  response.retCode,
@@ -1309,7 +1021,8 @@ var ByBitConnectorCreator = async (config) => {
1309
1021
  client,
1310
1022
  startTime,
1311
1023
  endTime,
1312
- symbol
1024
+ symbol,
1025
+ logger
1313
1026
  });
1314
1027
  return executionRows.map((item) => {
1315
1028
  const qty = Number(item.execQty ?? item.orderQty ?? Number.NaN);
@@ -1371,7 +1084,7 @@ var ByBitConnectorCreator = async (config) => {
1371
1084
  if (signal) {
1372
1085
  signal.orderFailureReason = failureReason;
1373
1086
  }
1374
- logger3.log(
1087
+ logger.log(
1375
1088
  "warn",
1376
1089
  "placeOrder: rejected position increase: %s",
1377
1090
  toJson(
@@ -1396,7 +1109,7 @@ var ByBitConnectorCreator = async (config) => {
1396
1109
  signal.orderValue = normalizedQty.qtyNum * price;
1397
1110
  signal.orderFailureReason = "QTY_BELOW_MIN_ORDER";
1398
1111
  }
1399
- logger3.log(
1112
+ logger.log(
1400
1113
  "warn",
1401
1114
  "placeOrder: rejected qty below minOrderQty: %s",
1402
1115
  toJson(
@@ -1418,7 +1131,7 @@ var ByBitConnectorCreator = async (config) => {
1418
1131
  signal.orderValue = orderQty * price;
1419
1132
  }
1420
1133
  const entryNormalized = isLimit ? normalizePrice(price, "ENTRY", meta) : void 0;
1421
- logger3.log(
1134
+ logger.log(
1422
1135
  "info",
1423
1136
  "placeOrder: %s",
1424
1137
  toJson(
@@ -1451,7 +1164,7 @@ var ByBitConnectorCreator = async (config) => {
1451
1164
  orderFilter: "Order",
1452
1165
  orderLinkId: typeof orderId === "string" && orderId.trim() ? orderId : void 0
1453
1166
  });
1454
- logger3.log(
1167
+ logger.log(
1455
1168
  getLogLevel(orderRes),
1456
1169
  "placeOrder:response: %s",
1457
1170
  toJson(orderRes, true)
@@ -1484,7 +1197,7 @@ var ByBitConnectorCreator = async (config) => {
1484
1197
  qty: "0",
1485
1198
  reduceOnly: true
1486
1199
  });
1487
- logger3.log(
1200
+ logger.log(
1488
1201
  getLogLevel(closeRes),
1489
1202
  "closePosition: %s, %s, %s",
1490
1203
  symbol,
@@ -1595,7 +1308,6 @@ var ByBitConnectorCreator = async (config) => {
1595
1308
  };
1596
1309
 
1597
1310
  // src/Binance/index.ts
1598
- import { fetchWithRetry } from "@tradejs/infra/http";
1599
1311
  import {
1600
1312
  resolveConnectorUniverse as resolveConnectorUniverse2
1601
1313
  } from "@tradejs/types";
@@ -1605,6 +1317,7 @@ var DEFAULT_BINANCE_PUBLIC_API_URL = "https://data-api.binance.vision";
1605
1317
  var getBinancePublicApiUrl = () => process.env.BINANCE_BASE_URL?.trim() || DEFAULT_BINANCE_PUBLIC_API_URL;
1606
1318
 
1607
1319
  // src/Binance/index.ts
1320
+ import { fetchWithRetry } from "@tradejs/core/http";
1608
1321
  var INTERVAL_MAP = {
1609
1322
  "1": "1m",
1610
1323
  "3": "3m",
@@ -1651,7 +1364,7 @@ var capabilities = {
1651
1364
  supportedUniverses: ["crypto"],
1652
1365
  defaultUniverse: "crypto"
1653
1366
  };
1654
- var BinanceConnectorCreator = async (config) => {
1367
+ var BinanceConnectorCreator = async (config, runtime) => {
1655
1368
  let state = {};
1656
1369
  const universe = resolveConnectorUniverse2(capabilities, config.universe);
1657
1370
  const requestKline = async ({
@@ -1779,7 +1492,7 @@ var BinanceConnectorCreator = async (config) => {
1779
1492
  setState: async (newState) => {
1780
1493
  state = { ...state, ...newState };
1781
1494
  },
1782
- kline: createTimescaleCachedKline({
1495
+ kline: decorateConnectorKline(runtime, {
1783
1496
  provider: "binance",
1784
1497
  request: requestKline,
1785
1498
  intervalToMinutes
@@ -1874,10 +1587,10 @@ var BinanceConnectorCreator = async (config) => {
1874
1587
  };
1875
1588
 
1876
1589
  // src/Coinbase/index.ts
1877
- import { fetchWithRetry as fetchWithRetry2 } from "@tradejs/infra/http";
1878
1590
  import {
1879
1591
  resolveConnectorUniverse as resolveConnectorUniverse3
1880
1592
  } from "@tradejs/types";
1593
+ import { fetchWithRetry as fetchWithRetry2 } from "@tradejs/core/http";
1881
1594
  var INTERVAL_MS2 = {
1882
1595
  "1": 6e4,
1883
1596
  "3": 18e4,
@@ -1944,7 +1657,7 @@ var capabilities2 = {
1944
1657
  supportedUniverses: ["crypto"],
1945
1658
  defaultUniverse: "crypto"
1946
1659
  };
1947
- var CoinbaseConnectorCreator = async (config) => {
1660
+ var CoinbaseConnectorCreator = async (config, runtime) => {
1948
1661
  let state = {};
1949
1662
  const universe = resolveConnectorUniverse3(capabilities2, config.universe);
1950
1663
  const requestKline = async ({
@@ -2072,7 +1785,7 @@ var CoinbaseConnectorCreator = async (config) => {
2072
1785
  setState: async (newState) => {
2073
1786
  state = { ...state, ...newState };
2074
1787
  },
2075
- kline: createTimescaleCachedKline({
1788
+ kline: decorateConnectorKline(runtime, {
2076
1789
  provider: "coinbase",
2077
1790
  request: requestKline,
2078
1791
  intervalToMinutes: intervalToMinutes2
@@ -2092,7 +1805,7 @@ var CoinbaseConnectorCreator = async (config) => {
2092
1805
  };
2093
1806
 
2094
1807
  // src/marketData/spotKlineProviders.ts
2095
- import { fetchWithRetry as fetchWithRetry3 } from "@tradejs/infra/http";
1808
+ import { fetchWithRetry as fetchWithRetry3 } from "@tradejs/core/http";
2096
1809
  var toIntervalToken = (interval) => interval === "1h" ? "1h" : "15m";
2097
1810
  var mapBinanceKline = (payload) => payload.map((item) => {
2098
1811
  if (!Array.isArray(item)) return null;
@@ -2197,8 +1910,6 @@ var spotKlineProviders = {
2197
1910
  // src/ByBit/klineStream.ts
2198
1911
  import { WebsocketClient } from "bybit-api";
2199
1912
  import { formatUnix as formatUnix3 } from "@tradejs/core/time";
2200
- import { logger as logger4 } from "@tradejs/infra/logger";
2201
- import { resolveTradingAccount as resolveTradingAccount2 } from "@tradejs/infra/tradingAccounts";
2202
1913
  var CATEGORY = "linear";
2203
1914
  var SUBSCRIPTION_BATCH_SIZE = 100;
2204
1915
  var KLINE_TOPIC_PATTERN = /^kline\.([^.]+)\.(.+)$/;
@@ -2255,22 +1966,23 @@ var parseBybitKlineEvent = (value, receivedAt = Date.now()) => {
2255
1966
  };
2256
1967
  var createBybitKlineStreamWithClient = ({
2257
1968
  client,
2258
- onEvent
1969
+ onEvent,
1970
+ logger = getConnectorLogger()
2259
1971
  }) => {
2260
1972
  let topics = /* @__PURE__ */ new Set();
2261
1973
  let closed = false;
2262
1974
  client.on("update", (value) => {
2263
1975
  for (const event of parseBybitKlineEvent(value)) {
2264
1976
  void Promise.resolve(onEvent(event)).catch((error) => {
2265
- logger4.error("Bybit kline stream handler failed: %s", String(error));
1977
+ logger.error("Bybit kline stream handler failed: %s", String(error));
2266
1978
  });
2267
1979
  }
2268
1980
  });
2269
1981
  client.on("reconnected", ({ wsKey }) => {
2270
- logger4.info("Bybit kline stream reconnected: %s", wsKey);
1982
+ logger.info("Bybit kline stream reconnected: %s", wsKey);
2271
1983
  });
2272
1984
  client.on("exception", (error) => {
2273
- logger4.error("Bybit kline stream exception: %s", String(error));
1985
+ logger.error("Bybit kline stream exception: %s", String(error));
2274
1986
  });
2275
1987
  return {
2276
1988
  setSubscriptions: (symbols, interval) => {
@@ -2284,16 +1996,16 @@ var createBybitKlineStreamWithClient = ({
2284
1996
  const removed = [...topics].filter((topic) => !nextTopics.has(topic));
2285
1997
  for (const batch of chunk(removed, SUBSCRIPTION_BATCH_SIZE)) {
2286
1998
  void Promise.all(client.unsubscribeV5(batch, CATEGORY)).catch(
2287
- (error) => logger4.error("Bybit kline unsubscribe failed: %s", String(error))
1999
+ (error) => logger.error("Bybit kline unsubscribe failed: %s", String(error))
2288
2000
  );
2289
2001
  }
2290
2002
  for (const batch of chunk(added, SUBSCRIPTION_BATCH_SIZE)) {
2291
2003
  void Promise.all(client.subscribeV5(batch, CATEGORY)).catch(
2292
- (error) => logger4.error("Bybit kline subscribe failed: %s", String(error))
2004
+ (error) => logger.error("Bybit kline subscribe failed: %s", String(error))
2293
2005
  );
2294
2006
  }
2295
2007
  topics = nextTopics;
2296
- logger4.info(
2008
+ logger.info(
2297
2009
  "Bybit kline stream subscriptions: topics=%s added=%s removed=%s",
2298
2010
  topics.size,
2299
2011
  added.length,
@@ -2314,9 +2026,11 @@ var createBybitKlineStreamWithClient = ({
2314
2026
  };
2315
2027
  var createBybitKlineStream = async ({
2316
2028
  config,
2317
- onEvent
2029
+ onEvent,
2030
+ runtime
2318
2031
  }) => {
2319
- const account = config.accountId ? await resolveTradingAccount2({
2032
+ const resolveTradingAccount = getConnectorAccountResolver(runtime);
2033
+ const account = config.accountId ? await resolveTradingAccount({
2320
2034
  userName: config.userName,
2321
2035
  accountId: config.accountId,
2322
2036
  provider: "bybit",
@@ -2329,7 +2043,11 @@ var createBybitKlineStream = async ({
2329
2043
  Number(process.env.BYBIT_WS_RECONNECT_TIMEOUT_MS ?? 1e3)
2330
2044
  )
2331
2045
  });
2332
- return createBybitKlineStreamWithClient({ client, onEvent });
2046
+ return createBybitKlineStreamWithClient({
2047
+ client,
2048
+ onEvent,
2049
+ logger: getConnectorLogger(runtime)
2050
+ });
2333
2051
  };
2334
2052
 
2335
2053
  // src/marketData/providers/binanceCoinbaseSpread.ts
@@ -2392,7 +2110,7 @@ var binanceCoinbaseSpreadProvider = {
2392
2110
  };
2393
2111
 
2394
2112
  // src/marketData/providers/coinalyze.ts
2395
- import { delay as delay3 } from "@tradejs/core/async";
2113
+ import { delay as delay2 } from "@tradejs/core/async";
2396
2114
  import {
2397
2115
  coinalyzePointsToRows,
2398
2116
  mergeCoinalyzeMetrics
@@ -2465,7 +2183,7 @@ var fetchCoinalyzeSeries = async (params) => {
2465
2183
  lastRequestTs + coinalyzeMinRequestDelayMs - now
2466
2184
  );
2467
2185
  if (waitMs > 0) {
2468
- await delay3(waitMs);
2186
+ await delay2(waitMs);
2469
2187
  }
2470
2188
  lastRequestTs = Date.now();
2471
2189
  const response = await fetch(url.toString(), { headers });
@@ -2479,7 +2197,7 @@ var fetchCoinalyzeSeries = async (params) => {
2479
2197
  const transient = response.status === 429 || response.status >= 500;
2480
2198
  if (attempt < coinalyzeMaxRetries && transient) {
2481
2199
  const backoffMs = Math.min(1e4, 750 * 2 ** attempt);
2482
- await delay3(retryAfterMs ?? backoffMs);
2200
+ await delay2(retryAfterMs ?? backoffMs);
2483
2201
  continue;
2484
2202
  }
2485
2203
  throw new Error(`Coinalyze ${endpoint} ${response.status}: ${text}`);