@orderly.network/ui-tradingview 2.8.10 → 2.8.11-alpha.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
@@ -1072,16 +1072,37 @@ var _HistoryProvider = class _HistoryProvider {
1072
1072
  countBack
1073
1073
  );
1074
1074
  if (needsFallback) {
1075
- const klineResult = await this._tryKlineFallback(
1076
- requestParams,
1077
- countBack
1078
- );
1079
- if (klineResult !== null) {
1080
- result = klineResult;
1081
- usedHistoryResult = false;
1082
- this._klinePreference.set(preferenceKey, true);
1075
+ const earliestTime = this._getEarliestTime(result.bars);
1076
+ if (earliestTime !== null) {
1077
+ const remainingCountBack = Math.max(
1078
+ 0,
1079
+ countBack - result.bars.length
1080
+ );
1081
+ const mergedResult = await this._tryKlineFallbackWithMerge(
1082
+ requestParams,
1083
+ remainingCountBack,
1084
+ earliestTime,
1085
+ result
1086
+ );
1087
+ if (mergedResult !== null) {
1088
+ result = mergedResult;
1089
+ usedHistoryResult = false;
1090
+ this._klinePreference.set(preferenceKey, true);
1091
+ } else {
1092
+ this._klinePreference.set(preferenceKey, false);
1093
+ }
1083
1094
  } else {
1084
- this._klinePreference.set(preferenceKey, false);
1095
+ const klineResult = await this._tryKlineFallback(
1096
+ requestParams,
1097
+ countBack
1098
+ );
1099
+ if (klineResult !== null) {
1100
+ result = klineResult;
1101
+ usedHistoryResult = false;
1102
+ this._klinePreference.set(preferenceKey, true);
1103
+ } else {
1104
+ this._klinePreference.set(preferenceKey, false);
1105
+ }
1085
1106
  }
1086
1107
  } else {
1087
1108
  this._klinePreference.set(preferenceKey, false);
@@ -1296,6 +1317,106 @@ var _HistoryProvider = class _HistoryProvider {
1296
1317
  }
1297
1318
  return params;
1298
1319
  }
1320
+ /**
1321
+ * Get the earliest time from bars array
1322
+ * @param bars - Array of bars
1323
+ * @returns Earliest timestamp in seconds, or null if bars array is empty
1324
+ */
1325
+ _getEarliestTime(bars) {
1326
+ if (bars.length === 0) {
1327
+ return null;
1328
+ }
1329
+ return bars[0].time / 1e3;
1330
+ }
1331
+ /**
1332
+ * Try kline fallback with merge logic
1333
+ * Requests kline data from the earliest time in history result to the original end time,
1334
+ * then merges the kline data with history data
1335
+ * @param requestParams - Original request parameters
1336
+ * @param countBack - Count back value
1337
+ * @param earliestTime - Earliest time from history result (in seconds)
1338
+ * @param historyResult - History result to merge with
1339
+ * @returns Merged result or null if kline request fails
1340
+ */
1341
+ async _tryKlineFallbackWithMerge(requestParams, countBack, earliestTime, historyResult) {
1342
+ try {
1343
+ const klineParams = {
1344
+ ...requestParams,
1345
+ from: requestParams.from,
1346
+ to: earliestTime
1347
+ };
1348
+ const klineResult = await this._requestKlineHistory(
1349
+ this._buildKlineParams(klineParams, countBack)
1350
+ );
1351
+ if (klineResult.bars.length === 0) {
1352
+ return null;
1353
+ }
1354
+ return this._mergeBars(historyResult, klineResult);
1355
+ } catch {
1356
+ return null;
1357
+ }
1358
+ }
1359
+ /**
1360
+ * Merge history bars with kline bars
1361
+ * Optimized for the case where klineBars are earlier data than historyBars
1362
+ * Uses direct concatenation when no overlap, otherwise uses two-pointer merge
1363
+ * Assumes both arrays are sorted by time (ascending, earliest first)
1364
+ * Kline data takes precedence when timestamps match
1365
+ * @param historyResult - History result (later time range)
1366
+ * @param klineResult - Kline result (earlier time range)
1367
+ * @returns Merged result with sorted bars
1368
+ */
1369
+ _mergeBars(historyResult, klineResult) {
1370
+ const historyBars = historyResult.bars;
1371
+ const klineBars = klineResult.bars;
1372
+ if (historyBars.length === 0) {
1373
+ return klineResult;
1374
+ }
1375
+ if (klineBars.length === 0) {
1376
+ return historyResult;
1377
+ }
1378
+ const latestKlineTime = klineBars[klineBars.length - 1].time;
1379
+ const earliestHistoryTime = historyBars[0].time;
1380
+ let mergedBars;
1381
+ if (latestKlineTime < earliestHistoryTime) {
1382
+ mergedBars = [...klineBars, ...historyBars];
1383
+ } else if (latestKlineTime === earliestHistoryTime) {
1384
+ mergedBars = [...klineBars, ...historyBars.slice(1)];
1385
+ } else {
1386
+ mergedBars = [];
1387
+ let historyIdx = 0;
1388
+ let klineIdx = 0;
1389
+ while (historyIdx < historyBars.length && klineIdx < klineBars.length) {
1390
+ const historyBar = historyBars[historyIdx];
1391
+ const klineBar = klineBars[klineIdx];
1392
+ if (historyBar.time < klineBar.time) {
1393
+ mergedBars.push(historyBar);
1394
+ historyIdx++;
1395
+ } else if (historyBar.time > klineBar.time) {
1396
+ mergedBars.push(klineBar);
1397
+ klineIdx++;
1398
+ } else {
1399
+ mergedBars.push(klineBar);
1400
+ historyIdx++;
1401
+ klineIdx++;
1402
+ }
1403
+ }
1404
+ while (historyIdx < historyBars.length) {
1405
+ mergedBars.push(historyBars[historyIdx++]);
1406
+ }
1407
+ while (klineIdx < klineBars.length) {
1408
+ mergedBars.push(klineBars[klineIdx++]);
1409
+ }
1410
+ }
1411
+ const meta = {
1412
+ noData: klineResult.meta.noData && historyResult.meta.noData,
1413
+ nextTime: klineResult.meta.nextTime ?? historyResult.meta.nextTime
1414
+ };
1415
+ return {
1416
+ bars: mergedBars,
1417
+ meta
1418
+ };
1419
+ }
1299
1420
  async _tryKlineFallback(requestParams, countBack) {
1300
1421
  try {
1301
1422
  const result = await this._requestKlineHistory(
@@ -2461,6 +2582,8 @@ var limitOrdersByInterval = (orders, interval) => {
2461
2582
  });
2462
2583
  return res;
2463
2584
  };
2585
+
2586
+ // src/tradingviewAdapter/renderer/execution.service.ts
2464
2587
  var ExecutionService = class _ExecutionService {
2465
2588
  constructor(instance, broker) {
2466
2589
  this.interval = "1D";
@@ -2519,7 +2642,8 @@ var ExecutionService = class _ExecutionService {
2519
2642
  try {
2520
2643
  this.instance.activeChart().onIntervalChanged().unsubscribe(null, changeInterval);
2521
2644
  } catch (e) {
2522
- if (e instanceof Error && e.message === "Cannot read properties of null (reading 'tradingViewApi')") ;
2645
+ const errorString = e?.toString() || String(e);
2646
+ if (errorString.includes("tradingViewApi") || errorString.includes("Cannot read properties of null") || errorString.includes("Cannot read property") || e instanceof TypeError && errorString.includes("null")) ;
2523
2647
  }
2524
2648
  }
2525
2649
  destroy() {
@@ -2642,9 +2766,31 @@ var _OrderLineService = class _OrderLineService {
2642
2766
  orderLine.remove();
2643
2767
  }
2644
2768
  }
2769
+ /**
2770
+ * Creates a base order line with default styling.
2771
+ * Returns null if the chart is not ready (e.g., during initialization, hot reload, or chart switching).
2772
+ *
2773
+ * @returns IOrderLineAdapter instance or null if chart is not available
2774
+ */
2645
2775
  getBaseOrderLine() {
2646
- const colorConfig = this.broker.colorConfig;
2647
- return this.instance.activeChart().createOrderLine().setCancelTooltip(i18n.t("orders.cancelOrder")).setQuantityTextColor(colorConfig.qtyTextColor).setQuantityBackgroundColor(colorConfig.chartBG).setBodyBackgroundColor(colorConfig.chartBG).setCancelButtonBackgroundColor(colorConfig.chartBG).setLineStyle(1).setBodyFont(colorConfig.font).setQuantityFont(colorConfig.font);
2776
+ try {
2777
+ const activeChart = this.instance.activeChart();
2778
+ if (!activeChart) {
2779
+ return null;
2780
+ }
2781
+ const colorConfig = this.broker.colorConfig;
2782
+ const orderLine = activeChart.createOrderLine();
2783
+ if (!orderLine) {
2784
+ return null;
2785
+ }
2786
+ return orderLine.setCancelTooltip(i18n.t("orders.cancelOrder")).setQuantityTextColor(colorConfig.qtyTextColor).setQuantityBackgroundColor(colorConfig.chartBG).setBodyBackgroundColor(colorConfig.chartBG).setCancelButtonBackgroundColor(colorConfig.chartBG).setLineStyle(1).setBodyFont(colorConfig.font).setQuantityFont(colorConfig.font);
2787
+ } catch (e) {
2788
+ const errorString = e?.toString() || String(e);
2789
+ if (errorString.includes("Value is null") || errorString.includes("tradingViewApi") || errorString.includes("Cannot read properties of null") || errorString.includes("Cannot read property") || e instanceof TypeError && errorString.includes("null")) {
2790
+ return null;
2791
+ }
2792
+ throw e;
2793
+ }
2648
2794
  }
2649
2795
  static getCombinationType(order) {
2650
2796
  const { algo_type: algoType, type } = order;
@@ -2726,7 +2872,11 @@ var _OrderLineService = class _OrderLineService {
2726
2872
  return null;
2727
2873
  }
2728
2874
  const colorConfig = this.broker.colorConfig;
2729
- const orderLine = this.pendingOrderLineMap.get(orderId) ?? this.getBaseOrderLine();
2875
+ const existingOrderLine = this.pendingOrderLineMap.get(orderId);
2876
+ const orderLine = existingOrderLine ?? this.getBaseOrderLine();
2877
+ if (!orderLine) {
2878
+ return null;
2879
+ }
2730
2880
  const color = pendingOrder.side === "BUY" /* BUY */ ? colorConfig.upColor : colorConfig.downColor;
2731
2881
  pendingOrder.side === "BUY" /* BUY */ ? colorConfig.pnlUpColor : colorConfig.pnlDownColor;
2732
2882
  const price = _OrderLineService.getOrderPrice(pendingOrder);
@@ -4362,5 +4512,5 @@ var TradingviewWidget = forwardRef((props, ref) => {
4362
4512
  });
4363
4513
 
4364
4514
  export { TradingviewUI, TradingviewWidget, useTradingviewScript };
4365
- //# sourceMappingURL=out.js.map
4515
+ //# sourceMappingURL=index.mjs.map
4366
4516
  //# sourceMappingURL=index.mjs.map