@tradejs/connectors 3.0.1 → 3.1.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/dist/index.mjs CHANGED
@@ -1,20 +1,41 @@
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 getApiRegion = () => {
29
+ const apiRegion = process.env.TRADEJS_BYBIT_API_REGION?.trim();
30
+ return apiRegion ? apiRegion : void 0;
31
+ };
32
+ var getApiRegionOptions = () => {
33
+ const apiRegion = getApiRegion();
34
+ return apiRegion ? { apiRegion } : {};
35
+ };
36
+ var getClient = async (config, access = "private", runtime) => {
37
+ const logger = getConnectorLogger(runtime);
38
+ const resolveTradingAccount = getConnectorAccountResolver(runtime);
18
39
  const account = access === "public" && !config.accountId ? null : await resolveTradingAccount({
19
40
  userName: config.userName,
20
41
  accountId: config.accountId,
@@ -24,6 +45,7 @@ var getClient = async (config, access = "private") => {
24
45
  const useTestnet = account?.environment === "testnet";
25
46
  if (access === "public") {
26
47
  return new RestClientV5({
48
+ ...getApiRegionOptions(),
27
49
  parseAPIRateLimits: true,
28
50
  testnet: useTestnet
29
51
  });
@@ -42,6 +64,7 @@ var getClient = async (config, access = "private") => {
42
64
  return null;
43
65
  }
44
66
  const client = new RestClientV5({
67
+ ...getApiRegionOptions(),
45
68
  key: account.apiKey,
46
69
  secret: account.apiSecret,
47
70
  parseAPIRateLimits: true,
@@ -54,310 +77,6 @@ var getClient = async (config, access = "private") => {
54
77
  return client;
55
78
  };
56
79
 
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
80
  // src/ByBit/utils.ts
362
81
  import { formatUnix } from "@tradejs/core/time";
363
82
  var BYBIT_CATEGORY = "linear";
@@ -555,7 +274,8 @@ var loadFundingFeeRows = async ({
555
274
  client,
556
275
  startTime,
557
276
  endTime,
558
- symbol
277
+ symbol,
278
+ logger
559
279
  }) => {
560
280
  if (typeof client.getTransactionLog !== "function") {
561
281
  return [];
@@ -574,7 +294,7 @@ var loadFundingFeeRows = async ({
574
294
  ...cursor ? { cursor } : {}
575
295
  });
576
296
  if (response?.retCode !== 0) {
577
- logger3.log(
297
+ logger.log(
578
298
  "debug",
579
299
  "funding transaction log retCode: %s, %s",
580
300
  response?.retCode,
@@ -606,7 +326,7 @@ var loadFundingFeeRows = async ({
606
326
  }
607
327
  return rows;
608
328
  } catch (error) {
609
- logger3.log("debug", "funding transaction log failed: %s", error);
329
+ logger.log("debug", "funding transaction log failed: %s", error);
610
330
  return [];
611
331
  }
612
332
  };
@@ -653,7 +373,8 @@ var resolveKlineRetryDelayMs = (res, attempt) => {
653
373
  );
654
374
  return backoffMs + jitterMs;
655
375
  };
656
- var ByBitConnectorCreator = async (config) => {
376
+ var ByBitConnectorCreator = async (config, runtime) => {
377
+ const logger = getConnectorLogger(runtime);
657
378
  let state = {};
658
379
  const universe = resolveConnectorUniverse(
659
380
  BYBIT_CAPABILITIES,
@@ -664,11 +385,11 @@ var ByBitConnectorCreator = async (config) => {
664
385
  const positionSnapshotCache = /* @__PURE__ */ new Map();
665
386
  const inflightPositionSnapshots = /* @__PURE__ */ new Map();
666
387
  const getPublicClient = async () => {
667
- publicClientPromise ??= getClient(config, "public");
388
+ publicClientPromise ??= getClient(config, "public", runtime);
668
389
  return publicClientPromise;
669
390
  };
670
391
  const getPrivateClient = async () => {
671
- privateClientPromise ??= getClient(config, "private");
392
+ privateClientPromise ??= getClient(config, "private", runtime);
672
393
  return privateClientPromise;
673
394
  };
674
395
  const instrumentCache = /* @__PURE__ */ new Map();
@@ -796,7 +517,7 @@ var ByBitConnectorCreator = async (config) => {
796
517
  silent
797
518
  }) => {
798
519
  const normalizedStart = round(
799
- start || getTimestamp2(PRELOAD_FALLBACK_DAYS2),
520
+ start || getTimestamp(PRELOAD_FALLBACK_DAYS),
800
521
  0
801
522
  );
802
523
  const normalizedEnd = round(end || Date.now());
@@ -818,7 +539,7 @@ var ByBitConnectorCreator = async (config) => {
818
539
  if (isKlineRateLimited(kline)) {
819
540
  if (attempt < KLINE_RATE_LIMIT_MAX_ATTEMPTS) {
820
541
  const waitMs = resolveKlineRetryDelayMs(kline, attempt);
821
- logger3.log(
542
+ logger.log(
822
543
  "warn",
823
544
  "kline rate limited for %s %s: attempt=%s/%s waitMs=%s",
824
545
  symbol,
@@ -827,13 +548,13 @@ var ByBitConnectorCreator = async (config) => {
827
548
  KLINE_RATE_LIMIT_MAX_ATTEMPTS,
828
549
  waitMs
829
550
  );
830
- await delay2(waitMs);
551
+ await delay(waitMs);
831
552
  continue;
832
553
  }
833
554
  }
834
555
  if (!kline?.result?.list) {
835
556
  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(
557
+ logger.log(
837
558
  "error",
838
559
  "empty kline.list for %s %s%s",
839
560
  symbol,
@@ -843,7 +564,7 @@ var ByBitConnectorCreator = async (config) => {
843
564
  return [];
844
565
  }
845
566
  if (!silent && (process.stdout.isTTY || process.env.TRADEJS_LOG_KLINE_REQUESTS === "1")) {
846
- logger3.log(
567
+ logger.log(
847
568
  "info",
848
569
  "%s %s %s %s",
849
570
  chalk.yellow(formatUnix2(normalizedEnd)),
@@ -856,7 +577,7 @@ var ByBitConnectorCreator = async (config) => {
856
577
  }
857
578
  return [];
858
579
  } catch (error) {
859
- logger3.log(
580
+ logger.log(
860
581
  "error",
861
582
  "request kline: %s %s %s",
862
583
  normalizedStart,
@@ -884,7 +605,7 @@ var ByBitConnectorCreator = async (config) => {
884
605
  `bybit getPositionInfo ${symbol}`
885
606
  );
886
607
  if (positionRes.retCode !== 0) {
887
- logger3.log(
608
+ logger.log(
888
609
  getLogLevel(positionRes),
889
610
  "position retCode: %s, %s",
890
611
  symbol,
@@ -897,7 +618,7 @@ var ByBitConnectorCreator = async (config) => {
897
618
  return null;
898
619
  }
899
620
  const position = positions[0];
900
- logger3.log(
621
+ logger.log(
901
622
  "debug",
902
623
  "position: %s %s qty=%s price=%s",
903
624
  position.symbol,
@@ -909,7 +630,7 @@ var ByBitConnectorCreator = async (config) => {
909
630
  ...position
910
631
  };
911
632
  } catch (error) {
912
- logger3.log("error", "getPositionSnapshot failed: %s %s", symbol, error);
633
+ logger.log("error", "getPositionSnapshot failed: %s %s", symbol, error);
913
634
  return null;
914
635
  }
915
636
  };
@@ -948,7 +669,7 @@ var ByBitConnectorCreator = async (config) => {
948
669
  const meta = await getSymbolMeta(marketDataClient, symbol);
949
670
  const positionQty = qty ?? (await getPositionSnapshot(symbol))?.qty ?? 0;
950
671
  if (!Number.isFinite(positionQty) || positionQty <= 0) {
951
- logger3.log(
672
+ logger.log(
952
673
  "warn",
953
674
  "setTakeProfits: missing position qty: %s",
954
675
  toJson({ symbol, qty, positionQty, takeProfits }, true)
@@ -963,7 +684,7 @@ var ByBitConnectorCreator = async (config) => {
963
684
  meta
964
685
  );
965
686
  if (!tpSizeNum || tpSizeNum < meta.minOrderQty) {
966
- logger3.log(
687
+ logger.log(
967
688
  "warn",
968
689
  "tp skipped: size too small %s",
969
690
  toJson(
@@ -990,7 +711,7 @@ var ByBitConnectorCreator = async (config) => {
990
711
  positionIdx: 0
991
712
  });
992
713
  if (isTradingStopNotModified(tpRes)) {
993
- logger3.log(
714
+ logger.log(
994
715
  "debug",
995
716
  "tp unchanged: %s %s price=%s rate=%s",
996
717
  symbol,
@@ -999,7 +720,7 @@ var ByBitConnectorCreator = async (config) => {
999
720
  tp.rate
1000
721
  );
1001
722
  } else if (tpRes.retCode === 0) {
1002
- logger3.log(
723
+ logger.log(
1003
724
  "info",
1004
725
  "tp updated: %s %s price=%s rate=%s",
1005
726
  symbol,
@@ -1008,7 +729,7 @@ var ByBitConnectorCreator = async (config) => {
1008
729
  tp.rate
1009
730
  );
1010
731
  } else {
1011
- logger3.log(
732
+ logger.log(
1012
733
  "error",
1013
734
  "tp failed: %s %s price=%s rate=%s %s",
1014
735
  symbol,
@@ -1053,7 +774,7 @@ var ByBitConnectorCreator = async (config) => {
1053
774
  positionIdx: 0
1054
775
  });
1055
776
  if (isTradingStopNotModified(slRes)) {
1056
- logger3.log(
777
+ logger.log(
1057
778
  "debug",
1058
779
  "sl unchanged: %s %s stopLoss=%s",
1059
780
  symbol,
@@ -1061,7 +782,7 @@ var ByBitConnectorCreator = async (config) => {
1061
782
  slNormalized.priceStr
1062
783
  );
1063
784
  } else if (slRes.retCode === 0) {
1064
- logger3.log(
785
+ logger.log(
1065
786
  "info",
1066
787
  "sl updated: %s %s stopLoss=%s",
1067
788
  symbol,
@@ -1069,7 +790,7 @@ var ByBitConnectorCreator = async (config) => {
1069
790
  slNormalized.priceStr
1070
791
  );
1071
792
  } else {
1072
- logger3.log(
793
+ logger.log(
1073
794
  "error",
1074
795
  "sl failed: %s %s stopLoss=%s %s",
1075
796
  symbol,
@@ -1090,7 +811,7 @@ var ByBitConnectorCreator = async (config) => {
1090
811
  setState: async (newState) => {
1091
812
  state = { ...state, ...newState };
1092
813
  },
1093
- kline: createTimescaleCachedKline({
814
+ kline: decorateConnectorKline(runtime, {
1094
815
  provider: "bybit",
1095
816
  request,
1096
817
  intervalToMinutes: intervalToMinutes3,
@@ -1107,7 +828,7 @@ var ByBitConnectorCreator = async (config) => {
1107
828
  settleCoin: "USDT"
1108
829
  });
1109
830
  if (positionRes.retCode !== 0) {
1110
- logger3.log(
831
+ logger.log(
1111
832
  getLogLevel(positionRes),
1112
833
  "positions retCode: %s, %s",
1113
834
  positionRes.retCode
@@ -1130,7 +851,7 @@ var ByBitConnectorCreator = async (config) => {
1130
851
  settleCoin: "USDT"
1131
852
  });
1132
853
  if (positionRes.retCode !== 0) {
1133
- logger3.log(
854
+ logger.log(
1134
855
  getLogLevel(positionRes),
1135
856
  "positions pnl retCode: %s, %s",
1136
857
  positionRes.retCode
@@ -1190,7 +911,7 @@ var ByBitConnectorCreator = async (config) => {
1190
911
  ...cursor ? { cursor } : {}
1191
912
  });
1192
913
  if (response.retCode !== 0) {
1193
- logger3.log(
914
+ logger.log(
1194
915
  "error",
1195
916
  "closedPnl retCode: %s, %s",
1196
917
  response.retCode,
@@ -1212,7 +933,8 @@ var ByBitConnectorCreator = async (config) => {
1212
933
  client,
1213
934
  startTime,
1214
935
  endTime,
1215
- symbol
936
+ symbol,
937
+ logger
1216
938
  });
1217
939
  return closedPnlRows.map((item) => {
1218
940
  const qty = Number(item.qty ?? item.closedSize ?? Number.NaN);
@@ -1287,7 +1009,7 @@ var ByBitConnectorCreator = async (config) => {
1287
1009
  ...cursor ? { cursor } : {}
1288
1010
  });
1289
1011
  if (response.retCode !== 0) {
1290
- logger3.log(
1012
+ logger.log(
1291
1013
  "error",
1292
1014
  "entryExecutions retCode: %s, %s",
1293
1015
  response.retCode,
@@ -1309,7 +1031,8 @@ var ByBitConnectorCreator = async (config) => {
1309
1031
  client,
1310
1032
  startTime,
1311
1033
  endTime,
1312
- symbol
1034
+ symbol,
1035
+ logger
1313
1036
  });
1314
1037
  return executionRows.map((item) => {
1315
1038
  const qty = Number(item.execQty ?? item.orderQty ?? Number.NaN);
@@ -1371,7 +1094,7 @@ var ByBitConnectorCreator = async (config) => {
1371
1094
  if (signal) {
1372
1095
  signal.orderFailureReason = failureReason;
1373
1096
  }
1374
- logger3.log(
1097
+ logger.log(
1375
1098
  "warn",
1376
1099
  "placeOrder: rejected position increase: %s",
1377
1100
  toJson(
@@ -1396,7 +1119,7 @@ var ByBitConnectorCreator = async (config) => {
1396
1119
  signal.orderValue = normalizedQty.qtyNum * price;
1397
1120
  signal.orderFailureReason = "QTY_BELOW_MIN_ORDER";
1398
1121
  }
1399
- logger3.log(
1122
+ logger.log(
1400
1123
  "warn",
1401
1124
  "placeOrder: rejected qty below minOrderQty: %s",
1402
1125
  toJson(
@@ -1418,7 +1141,7 @@ var ByBitConnectorCreator = async (config) => {
1418
1141
  signal.orderValue = orderQty * price;
1419
1142
  }
1420
1143
  const entryNormalized = isLimit ? normalizePrice(price, "ENTRY", meta) : void 0;
1421
- logger3.log(
1144
+ logger.log(
1422
1145
  "info",
1423
1146
  "placeOrder: %s",
1424
1147
  toJson(
@@ -1451,7 +1174,7 @@ var ByBitConnectorCreator = async (config) => {
1451
1174
  orderFilter: "Order",
1452
1175
  orderLinkId: typeof orderId === "string" && orderId.trim() ? orderId : void 0
1453
1176
  });
1454
- logger3.log(
1177
+ logger.log(
1455
1178
  getLogLevel(orderRes),
1456
1179
  "placeOrder:response: %s",
1457
1180
  toJson(orderRes, true)
@@ -1484,7 +1207,7 @@ var ByBitConnectorCreator = async (config) => {
1484
1207
  qty: "0",
1485
1208
  reduceOnly: true
1486
1209
  });
1487
- logger3.log(
1210
+ logger.log(
1488
1211
  getLogLevel(closeRes),
1489
1212
  "closePosition: %s, %s, %s",
1490
1213
  symbol,
@@ -1595,7 +1318,6 @@ var ByBitConnectorCreator = async (config) => {
1595
1318
  };
1596
1319
 
1597
1320
  // src/Binance/index.ts
1598
- import { fetchWithRetry } from "@tradejs/infra/http";
1599
1321
  import {
1600
1322
  resolveConnectorUniverse as resolveConnectorUniverse2
1601
1323
  } from "@tradejs/types";
@@ -1605,6 +1327,7 @@ var DEFAULT_BINANCE_PUBLIC_API_URL = "https://data-api.binance.vision";
1605
1327
  var getBinancePublicApiUrl = () => process.env.BINANCE_BASE_URL?.trim() || DEFAULT_BINANCE_PUBLIC_API_URL;
1606
1328
 
1607
1329
  // src/Binance/index.ts
1330
+ import { fetchWithRetry } from "@tradejs/core/http";
1608
1331
  var INTERVAL_MAP = {
1609
1332
  "1": "1m",
1610
1333
  "3": "3m",
@@ -1651,7 +1374,7 @@ var capabilities = {
1651
1374
  supportedUniverses: ["crypto"],
1652
1375
  defaultUniverse: "crypto"
1653
1376
  };
1654
- var BinanceConnectorCreator = async (config) => {
1377
+ var BinanceConnectorCreator = async (config, runtime) => {
1655
1378
  let state = {};
1656
1379
  const universe = resolveConnectorUniverse2(capabilities, config.universe);
1657
1380
  const requestKline = async ({
@@ -1779,7 +1502,7 @@ var BinanceConnectorCreator = async (config) => {
1779
1502
  setState: async (newState) => {
1780
1503
  state = { ...state, ...newState };
1781
1504
  },
1782
- kline: createTimescaleCachedKline({
1505
+ kline: decorateConnectorKline(runtime, {
1783
1506
  provider: "binance",
1784
1507
  request: requestKline,
1785
1508
  intervalToMinutes
@@ -1874,10 +1597,10 @@ var BinanceConnectorCreator = async (config) => {
1874
1597
  };
1875
1598
 
1876
1599
  // src/Coinbase/index.ts
1877
- import { fetchWithRetry as fetchWithRetry2 } from "@tradejs/infra/http";
1878
1600
  import {
1879
1601
  resolveConnectorUniverse as resolveConnectorUniverse3
1880
1602
  } from "@tradejs/types";
1603
+ import { fetchWithRetry as fetchWithRetry2 } from "@tradejs/core/http";
1881
1604
  var INTERVAL_MS2 = {
1882
1605
  "1": 6e4,
1883
1606
  "3": 18e4,
@@ -1944,7 +1667,7 @@ var capabilities2 = {
1944
1667
  supportedUniverses: ["crypto"],
1945
1668
  defaultUniverse: "crypto"
1946
1669
  };
1947
- var CoinbaseConnectorCreator = async (config) => {
1670
+ var CoinbaseConnectorCreator = async (config, runtime) => {
1948
1671
  let state = {};
1949
1672
  const universe = resolveConnectorUniverse3(capabilities2, config.universe);
1950
1673
  const requestKline = async ({
@@ -2072,7 +1795,7 @@ var CoinbaseConnectorCreator = async (config) => {
2072
1795
  setState: async (newState) => {
2073
1796
  state = { ...state, ...newState };
2074
1797
  },
2075
- kline: createTimescaleCachedKline({
1798
+ kline: decorateConnectorKline(runtime, {
2076
1799
  provider: "coinbase",
2077
1800
  request: requestKline,
2078
1801
  intervalToMinutes: intervalToMinutes2
@@ -2092,7 +1815,7 @@ var CoinbaseConnectorCreator = async (config) => {
2092
1815
  };
2093
1816
 
2094
1817
  // src/marketData/spotKlineProviders.ts
2095
- import { fetchWithRetry as fetchWithRetry3 } from "@tradejs/infra/http";
1818
+ import { fetchWithRetry as fetchWithRetry3 } from "@tradejs/core/http";
2096
1819
  var toIntervalToken = (interval) => interval === "1h" ? "1h" : "15m";
2097
1820
  var mapBinanceKline = (payload) => payload.map((item) => {
2098
1821
  if (!Array.isArray(item)) return null;
@@ -2197,8 +1920,6 @@ var spotKlineProviders = {
2197
1920
  // src/ByBit/klineStream.ts
2198
1921
  import { WebsocketClient } from "bybit-api";
2199
1922
  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
1923
  var CATEGORY = "linear";
2203
1924
  var SUBSCRIPTION_BATCH_SIZE = 100;
2204
1925
  var KLINE_TOPIC_PATTERN = /^kline\.([^.]+)\.(.+)$/;
@@ -2255,22 +1976,23 @@ var parseBybitKlineEvent = (value, receivedAt = Date.now()) => {
2255
1976
  };
2256
1977
  var createBybitKlineStreamWithClient = ({
2257
1978
  client,
2258
- onEvent
1979
+ onEvent,
1980
+ logger = getConnectorLogger()
2259
1981
  }) => {
2260
1982
  let topics = /* @__PURE__ */ new Set();
2261
1983
  let closed = false;
2262
1984
  client.on("update", (value) => {
2263
1985
  for (const event of parseBybitKlineEvent(value)) {
2264
1986
  void Promise.resolve(onEvent(event)).catch((error) => {
2265
- logger4.error("Bybit kline stream handler failed: %s", String(error));
1987
+ logger.error("Bybit kline stream handler failed: %s", String(error));
2266
1988
  });
2267
1989
  }
2268
1990
  });
2269
1991
  client.on("reconnected", ({ wsKey }) => {
2270
- logger4.info("Bybit kline stream reconnected: %s", wsKey);
1992
+ logger.info("Bybit kline stream reconnected: %s", wsKey);
2271
1993
  });
2272
1994
  client.on("exception", (error) => {
2273
- logger4.error("Bybit kline stream exception: %s", String(error));
1995
+ logger.error("Bybit kline stream exception: %s", String(error));
2274
1996
  });
2275
1997
  return {
2276
1998
  setSubscriptions: (symbols, interval) => {
@@ -2284,16 +2006,16 @@ var createBybitKlineStreamWithClient = ({
2284
2006
  const removed = [...topics].filter((topic) => !nextTopics.has(topic));
2285
2007
  for (const batch of chunk(removed, SUBSCRIPTION_BATCH_SIZE)) {
2286
2008
  void Promise.all(client.unsubscribeV5(batch, CATEGORY)).catch(
2287
- (error) => logger4.error("Bybit kline unsubscribe failed: %s", String(error))
2009
+ (error) => logger.error("Bybit kline unsubscribe failed: %s", String(error))
2288
2010
  );
2289
2011
  }
2290
2012
  for (const batch of chunk(added, SUBSCRIPTION_BATCH_SIZE)) {
2291
2013
  void Promise.all(client.subscribeV5(batch, CATEGORY)).catch(
2292
- (error) => logger4.error("Bybit kline subscribe failed: %s", String(error))
2014
+ (error) => logger.error("Bybit kline subscribe failed: %s", String(error))
2293
2015
  );
2294
2016
  }
2295
2017
  topics = nextTopics;
2296
- logger4.info(
2018
+ logger.info(
2297
2019
  "Bybit kline stream subscriptions: topics=%s added=%s removed=%s",
2298
2020
  topics.size,
2299
2021
  added.length,
@@ -2314,9 +2036,11 @@ var createBybitKlineStreamWithClient = ({
2314
2036
  };
2315
2037
  var createBybitKlineStream = async ({
2316
2038
  config,
2317
- onEvent
2039
+ onEvent,
2040
+ runtime
2318
2041
  }) => {
2319
- const account = config.accountId ? await resolveTradingAccount2({
2042
+ const resolveTradingAccount = getConnectorAccountResolver(runtime);
2043
+ const account = config.accountId ? await resolveTradingAccount({
2320
2044
  userName: config.userName,
2321
2045
  accountId: config.accountId,
2322
2046
  provider: "bybit",
@@ -2329,7 +2053,11 @@ var createBybitKlineStream = async ({
2329
2053
  Number(process.env.BYBIT_WS_RECONNECT_TIMEOUT_MS ?? 1e3)
2330
2054
  )
2331
2055
  });
2332
- return createBybitKlineStreamWithClient({ client, onEvent });
2056
+ return createBybitKlineStreamWithClient({
2057
+ client,
2058
+ onEvent,
2059
+ logger: getConnectorLogger(runtime)
2060
+ });
2333
2061
  };
2334
2062
 
2335
2063
  // src/marketData/providers/binanceCoinbaseSpread.ts
@@ -2392,7 +2120,7 @@ var binanceCoinbaseSpreadProvider = {
2392
2120
  };
2393
2121
 
2394
2122
  // src/marketData/providers/coinalyze.ts
2395
- import { delay as delay3 } from "@tradejs/core/async";
2123
+ import { delay as delay2 } from "@tradejs/core/async";
2396
2124
  import {
2397
2125
  coinalyzePointsToRows,
2398
2126
  mergeCoinalyzeMetrics
@@ -2465,7 +2193,7 @@ var fetchCoinalyzeSeries = async (params) => {
2465
2193
  lastRequestTs + coinalyzeMinRequestDelayMs - now
2466
2194
  );
2467
2195
  if (waitMs > 0) {
2468
- await delay3(waitMs);
2196
+ await delay2(waitMs);
2469
2197
  }
2470
2198
  lastRequestTs = Date.now();
2471
2199
  const response = await fetch(url.toString(), { headers });
@@ -2479,7 +2207,7 @@ var fetchCoinalyzeSeries = async (params) => {
2479
2207
  const transient = response.status === 429 || response.status >= 500;
2480
2208
  if (attempt < coinalyzeMaxRetries && transient) {
2481
2209
  const backoffMs = Math.min(1e4, 750 * 2 ** attempt);
2482
- await delay3(retryAfterMs ?? backoffMs);
2210
+ await delay2(retryAfterMs ?? backoffMs);
2483
2211
  continue;
2484
2212
  }
2485
2213
  throw new Error(`Coinalyze ${endpoint} ${response.status}: ${text}`);