oakscriptjs 0.8.0 → 0.8.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.
@@ -26,6 +26,7 @@ __export(index_exports, {
26
26
  alertcondition: () => alertcondition,
27
27
  barcolor: () => barcolor,
28
28
  barmerge: () => barmerge,
29
+ barstate: () => barstate,
29
30
  bgcolor: () => bgcolor,
30
31
  box: () => box,
31
32
  chart: () => chart,
@@ -59,6 +60,7 @@ __export(index_exports, {
59
60
  ohlc4: () => ohlc4,
60
61
  open: () => open,
61
62
  plot: () => plot,
63
+ plotarrow: () => plotarrow,
62
64
  plotchar: () => plotchar,
63
65
  plotshape: () => plotshape,
64
66
  polyline: () => polyline,
@@ -338,7 +340,7 @@ var Series = class _Series {
338
340
  return new _Series(this.dataSource, (bar, i, data) => {
339
341
  const a = this.extractor(bar, i, data);
340
342
  const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
341
- return b2 !== 0 ? a / b2 : NaN;
343
+ return a / b2;
342
344
  });
343
345
  }
344
346
  /**
@@ -711,7 +713,7 @@ function sma(source, length2) {
711
713
  const window = [];
712
714
  for (let i = 0; i < source.length; i++) {
713
715
  const v = source[i];
714
- if (v !== void 0 && v !== null && !Number.isNaN(v)) {
716
+ if (v !== void 0 && v !== null && Number.isFinite(v)) {
715
717
  window.push(v);
716
718
  if (window.length > len) window.shift();
717
719
  }
@@ -1055,7 +1057,7 @@ function lowest(source, length2) {
1055
1057
  function cum(source) {
1056
1058
  let sum2 = 0;
1057
1059
  return source.map((v) => {
1058
- if (Number.isNaN(v)) return NaN;
1060
+ if (!Number.isFinite(v)) return NaN;
1059
1061
  sum2 += v;
1060
1062
  return sum2;
1061
1063
  });
@@ -1073,41 +1075,24 @@ function cross(source1, source2) {
1073
1075
  }
1074
1076
  return result;
1075
1077
  }
1076
- function rising(source, length2) {
1078
+ function monotonic(source, length2, step) {
1077
1079
  const result = [];
1080
+ const values = [];
1078
1081
  for (let i = 0; i < source.length; i++) {
1079
- if (i < length2) {
1080
- result.push(false);
1081
- } else {
1082
- let isRising = true;
1083
- for (let j = 1; j <= length2; j++) {
1084
- if (source[i - j + 1] <= source[i - j]) {
1085
- isRising = false;
1086
- break;
1087
- }
1088
- }
1089
- result.push(isRising);
1090
- }
1082
+ const v = source[i];
1083
+ if (!Number.isNaN(v)) values.push(v);
1084
+ const n = values.length;
1085
+ let ok = n > length2;
1086
+ for (let j = 1; ok && j <= length2; j++) ok = step(values[n - j], values[n - j - 1]);
1087
+ result.push(ok);
1091
1088
  }
1092
1089
  return result;
1093
1090
  }
1091
+ function rising(source, length2) {
1092
+ return monotonic(source, length2, gt);
1093
+ }
1094
1094
  function falling(source, length2) {
1095
- const result = [];
1096
- for (let i = 0; i < source.length; i++) {
1097
- if (i < length2) {
1098
- result.push(false);
1099
- } else {
1100
- let isFalling = true;
1101
- for (let j = 1; j <= length2; j++) {
1102
- if (source[i - j + 1] >= source[i - j]) {
1103
- isFalling = false;
1104
- break;
1105
- }
1106
- }
1107
- result.push(isFalling);
1108
- }
1109
- }
1110
- return result;
1095
+ return monotonic(source, length2, lt);
1111
1096
  }
1112
1097
  function roc(source, length2) {
1113
1098
  const result = [];
@@ -1331,33 +1316,16 @@ function correlation(source1, source2, length2) {
1331
1316
  function percentrank(source, length2) {
1332
1317
  const result = [];
1333
1318
  for (let i = 0; i < source.length; i++) {
1334
- if (i < length2) {
1319
+ const currentValue = source[i];
1320
+ if (i < length2 || Number.isNaN(currentValue)) {
1335
1321
  result.push(NaN);
1336
- } else {
1337
- if (isNaN(source[i])) {
1338
- result.push(NaN);
1339
- continue;
1340
- }
1341
- let hasNaN = false;
1342
- for (let j = 1; j <= length2; j++) {
1343
- if (isNaN(source[i - j])) {
1344
- hasNaN = true;
1345
- break;
1346
- }
1347
- }
1348
- if (hasNaN) {
1349
- result.push(NaN);
1350
- } else {
1351
- const currentValue = source[i];
1352
- let countLessOrEqual = 0;
1353
- for (let j = 1; j <= length2; j++) {
1354
- if (source[i - j] <= currentValue) {
1355
- countLessOrEqual++;
1356
- }
1357
- }
1358
- result.push(countLessOrEqual / length2 * 100);
1359
- }
1322
+ continue;
1323
+ }
1324
+ let countLessOrEqual = 0;
1325
+ for (let j = 1; j <= length2; j++) {
1326
+ if (le(source[i - j], currentValue)) countLessOrEqual++;
1360
1327
  }
1328
+ result.push(countLessOrEqual / length2 * 100);
1361
1329
  }
1362
1330
  return result;
1363
1331
  }
@@ -1884,63 +1852,36 @@ function mode(source, length2) {
1884
1852
  return result;
1885
1853
  }
1886
1854
  function percentile_linear_interpolation(source, length2, percentage) {
1855
+ return sortedWindow(source, length2, (s) => {
1856
+ const pos2 = percentage / 100 * length2 - 0.5;
1857
+ if (pos2 <= 0) return s[0];
1858
+ if (pos2 >= length2 - 1) return s[length2 - 1];
1859
+ const lo = Math.floor(pos2);
1860
+ return s[lo] + (pos2 - lo) * (s[lo + 1] - s[lo]);
1861
+ });
1862
+ }
1863
+ function sortedWindow(source, length2, fn) {
1887
1864
  const result = [];
1865
+ const values = [];
1866
+ const bars2 = [];
1888
1867
  for (let i = 0; i < source.length; i++) {
1889
- if (i < length2 - 1) {
1890
- result.push(NaN);
1891
- continue;
1892
- }
1893
- const values = [];
1894
- for (let j = 0; j < length2; j++) {
1895
- const value = source[i - j];
1896
- values.push(value);
1897
- }
1898
- if (values.some((v) => isNaN(v))) {
1899
- result.push(NaN);
1900
- continue;
1901
- }
1902
- const sorted = [...values].sort((a, b2) => a - b2);
1903
- const position = percentage / 100 * (sorted.length - 1);
1904
- const lowerIndex = Math.floor(position);
1905
- const upperIndex = Math.ceil(position);
1906
- if (lowerIndex === upperIndex) {
1907
- result.push(sorted[lowerIndex]);
1908
- } else {
1909
- const fraction = position - lowerIndex;
1910
- const interpolated = sorted[lowerIndex] + fraction * (sorted[upperIndex] - sorted[lowerIndex]);
1911
- result.push(interpolated);
1868
+ const v = source[i];
1869
+ let k = 0;
1870
+ while (k < values.length && !(values[k] >= v)) k++;
1871
+ values.splice(k, 0, v);
1872
+ bars2.splice(k, 0, i);
1873
+ if (i >= length2) {
1874
+ const old = bars2.indexOf(i - length2);
1875
+ values.splice(old, 1);
1876
+ bars2.splice(old, 1);
1912
1877
  }
1878
+ result.push(i < length2 - 1 ? NaN : fn(values));
1913
1879
  }
1914
1880
  return result;
1915
1881
  }
1916
1882
  function percentile_nearest_rank(source, length2, percentage) {
1917
- const result = [];
1918
- for (let i = 0; i < source.length; i++) {
1919
- if (i < length2 - 1) {
1920
- result.push(NaN);
1921
- continue;
1922
- }
1923
- const values = [];
1924
- for (let j = 0; j < length2; j++) {
1925
- const value = source[i - j];
1926
- if (!isNaN(value)) {
1927
- values.push(value);
1928
- }
1929
- }
1930
- if (values.length === 0) {
1931
- result.push(NaN);
1932
- continue;
1933
- }
1934
- const sorted = [...values].sort((a, b2) => a - b2);
1935
- if (percentage >= 100) {
1936
- result.push(sorted[sorted.length - 1]);
1937
- continue;
1938
- }
1939
- const rank = Math.ceil(percentage / 100 * sorted.length);
1940
- const index = Math.max(0, rank - 1);
1941
- result.push(sorted[index]);
1942
- }
1943
- return result;
1883
+ const rank = Math.min(length2, Math.max(1, Math.ceil(percentage / 100 * length2)));
1884
+ return sortedWindow(source, length2, (s) => s[rank - 1]);
1944
1885
  }
1945
1886
  function rci(source, length2) {
1946
1887
  const result = [];
@@ -2806,11 +2747,13 @@ __export(color_exports, {
2806
2747
  white: () => white,
2807
2748
  yellow: () => yellow
2808
2749
  });
2750
+ var channel = (v) => v === null || v === void 0 || Number.isNaN(v) ? 0 : Math.max(0, Math.min(255, Math.trunc(v)));
2751
+ var alphaOf = (transp) => transp === null || Number.isNaN(transp) ? 0 : 1 - Math.max(0, Math.min(100, transp)) / 100;
2809
2752
  function rgb(red2, green2, blue2, transp) {
2810
- const r2 = Math.max(0, Math.min(255, red2));
2811
- const g2 = Math.max(0, Math.min(255, green2));
2812
- const b2 = Math.max(0, Math.min(255, blue2));
2813
- const a = transp !== void 0 ? 1 - transp / 100 : 1;
2753
+ const r2 = channel(red2);
2754
+ const g2 = channel(green2);
2755
+ const b2 = channel(blue2);
2756
+ const a = transp !== void 0 ? alphaOf(transp) : 1;
2814
2757
  if (a === 1) {
2815
2758
  return `rgb(${r2}, ${g2}, ${b2})`;
2816
2759
  }
@@ -2837,7 +2780,8 @@ function b(clr) {
2837
2780
  return parseColor(clr).b;
2838
2781
  }
2839
2782
  function t(clr) {
2840
- return parseColor(clr).t;
2783
+ const alpha = Math.round((1 - parseColor(clr).t / 100) * 255);
2784
+ return Math.round((1 - alpha / 255) * 100);
2841
2785
  }
2842
2786
  function parseColor(clr) {
2843
2787
  if (typeof clr === "string") {
@@ -2890,13 +2834,12 @@ function from_gradient(value, bottom_value, top_value, bottom_color, top_color)
2890
2834
  };
2891
2835
  const c1 = rgba(bottom_color);
2892
2836
  const c2 = rgba(top_color);
2893
- const w1 = c1.a * (1 - k);
2894
- const w2 = c2.a * k;
2895
- const a = w1 + w2;
2837
+ const a = c1.a * (1 - k) + c2.a * k;
2896
2838
  if (a === 0) return transparent;
2897
- const mix = (x1, x2) => Math.floor((x1 * w1 + x2 * w2) / a);
2839
+ const mix = (x1, x2) => Math.floor((x1 / 255 * c1.a * (1 - k) + x2 / 255 * c2.a * k) / (a / 255));
2898
2840
  const [r2, g2, b2] = [mix(c1.r, c2.r), mix(c1.g, c2.g), mix(c1.b, c2.b)];
2899
- return a === 255 ? `rgb(${r2}, ${g2}, ${b2})` : `rgba(${r2}, ${g2}, ${b2}, ${a / 255})`;
2841
+ const alpha = Math.floor(a);
2842
+ return alpha === 255 ? `rgb(${r2}, ${g2}, ${b2})` : `rgba(${r2}, ${g2}, ${b2}, ${alpha / 255})`;
2900
2843
  }
2901
2844
 
2902
2845
  // src/drawing/registry.ts
@@ -2960,7 +2903,7 @@ function setDrawingLimits(newLimits) {
2960
2903
 
2961
2904
  // src/utils/index.ts
2962
2905
  function isNA(value) {
2963
- return value === null || value === void 0 || Number.isNaN(value) || isDeleted(value);
2906
+ return value === null || value === void 0 || Number.isNaN(value) || value === Infinity || value === -Infinity || isDeleted(value);
2964
2907
  }
2965
2908
  function nz(value, defaultValue = 0) {
2966
2909
  return isNA(value) ? defaultValue : value;
@@ -2969,7 +2912,7 @@ function fixnan(source) {
2969
2912
  let last;
2970
2913
  let seen = false;
2971
2914
  return source.map((v) => {
2972
- if (!isNA(v)) {
2915
+ if (!(v === null || v === void 0 || Number.isNaN(v) || isDeleted(v))) {
2973
2916
  last = v;
2974
2917
  seen = true;
2975
2918
  return v;
@@ -5344,9 +5287,10 @@ var STRATEGY_DEFAULTS = {
5344
5287
  calc_on_order_fills: false,
5345
5288
  calc_on_every_tick: false,
5346
5289
  backtest_fill_limits_assumption: 0,
5347
- default_qty_type: "fixed",
5348
- default_qty_value: 1,
5349
- initial_capital: 1e6,
5290
+ // v6 values; PineScript v5: fixed / 1 / 1000000 and margins 0
5291
+ default_qty_type: "percent_of_equity",
5292
+ default_qty_value: 100,
5293
+ initial_capital: 1e5,
5350
5294
  slippage: 0,
5351
5295
  commission_type: "percent",
5352
5296
  commission_value: 0,
@@ -5420,6 +5364,8 @@ function freshCollector(inputValues) {
5420
5364
  fillConfig: [],
5421
5365
  shapeConfig: [],
5422
5366
  markers: [],
5367
+ arrowConfig: [],
5368
+ arrows: [],
5423
5369
  barColorConfig: [],
5424
5370
  bgcolors: [],
5425
5371
  barcolors: [],
@@ -5457,6 +5403,7 @@ function executeScript(body, barsInput, inputs = {}, chart2 = {}, options = {})
5457
5403
  hlineConfig: c.hlineConfig,
5458
5404
  fillConfig: c.fillConfig,
5459
5405
  shapeConfig: c.shapeConfig,
5406
+ arrowConfig: c.arrowConfig,
5460
5407
  barColorConfig: c.barColorConfig,
5461
5408
  defaultInputs: c.defaultInputs,
5462
5409
  alertConfig: c.alertConfig,
@@ -5466,6 +5413,7 @@ function executeScript(body, barsInput, inputs = {}, chart2 = {}, options = {})
5466
5413
  plots: c.plots,
5467
5414
  fills: c.fills.length ? c.fills : void 0,
5468
5415
  markers: c.markers.length ? c.markers : void 0,
5416
+ arrows: c.arrows.length ? c.arrows : void 0,
5469
5417
  bgcolors: c.bgcolors.length ? c.bgcolors : void 0,
5470
5418
  barcolors: c.barcolors.length ? c.barcolors : void 0,
5471
5419
  alerts: c.alerts.length ? c.alerts : void 0
@@ -5496,6 +5444,15 @@ function declare(c, kind) {
5496
5444
  }
5497
5445
  c.declaration = kind;
5498
5446
  }
5447
+ function common(opts) {
5448
+ const out = {};
5449
+ if (opts.group !== void 0) out.group = opts.group;
5450
+ if (opts.inline !== void 0) out.inline = opts.inline;
5451
+ if (opts.tooltip !== void 0) out.tooltip = opts.tooltip;
5452
+ if (opts.confirm !== void 0) out.confirm = opts.confirm;
5453
+ if (opts.display !== void 0) out.display = opts.display;
5454
+ return out;
5455
+ }
5499
5456
  function registerInput(config, fallbackId) {
5500
5457
  const c = collector();
5501
5458
  const id = slugId(config.title, fallbackId, c.inputIds);
@@ -5506,7 +5463,7 @@ function registerInput(config, fallbackId) {
5506
5463
  }
5507
5464
  function registerNumeric(type, defval, title, opts = {}) {
5508
5465
  const v = registerInput(
5509
- { type, defval, title, min: opts.minval, max: opts.maxval, step: opts.step },
5466
+ { type, defval, title, min: opts.minval, max: opts.maxval, step: opts.step, ...common(opts) },
5510
5467
  `input_${type}`
5511
5468
  );
5512
5469
  return typeof v === "number" ? v : defval;
@@ -5518,31 +5475,37 @@ var input = {
5518
5475
  float(defval, title, opts = {}) {
5519
5476
  return registerNumeric("float", defval, title, opts);
5520
5477
  },
5521
- bool(defval, title) {
5522
- return registerInput({ type: "bool", defval, title }, "input_bool");
5478
+ bool(defval, title, opts = {}) {
5479
+ return registerInput({ type: "bool", defval, title, ...common(opts) }, "input_bool");
5523
5480
  },
5524
5481
  string(defval, title, opts = {}) {
5525
- return registerInput({ type: "string", defval, title, options: opts.options }, "input_string");
5482
+ return registerInput({ type: "string", defval, title, options: opts.options, ...common(opts) }, "input_string");
5526
5483
  },
5527
- color(defval, title) {
5528
- return registerInput({ type: "color", defval, title }, "input_color");
5484
+ color(defval, title, opts = {}) {
5485
+ return registerInput({ type: "color", defval, title, ...common(opts) }, "input_color");
5529
5486
  },
5530
5487
  /** Declares a source input and returns it as a Series. */
5531
- source(defval = "close", title) {
5532
- const name = registerInput({ type: "source", defval, title }, "input_source");
5488
+ source(defval = "close", title, opts = {}) {
5489
+ const name = registerInput({ type: "source", defval, title, ...common(opts) }, "input_source");
5533
5490
  return sourceSeries(name);
5534
5491
  },
5535
5492
  /** Timeframe string ("60", "1D", "W"). As in PineScript, "" means the chart timeframe. */
5536
5493
  timeframe(defval, title, opts = {}) {
5537
- return registerInput({ type: "timeframe", defval, title, options: opts.options }, "input_timeframe");
5494
+ return registerInput(
5495
+ { type: "timeframe", defval, title, options: opts.options, ...common(opts) },
5496
+ "input_timeframe"
5497
+ );
5538
5498
  },
5539
5499
  /** Session string ("0930-1600", "0930-1600:23456"). */
5540
5500
  session(defval, title, opts = {}) {
5541
- return registerInput({ type: "session", defval, title, options: opts.options }, "input_session");
5501
+ return registerInput(
5502
+ { type: "session", defval, title, options: opts.options, ...common(opts) },
5503
+ "input_session"
5504
+ );
5542
5505
  },
5543
5506
  /** Date and time as a UNIX time in milliseconds, e.g. `input.time(timestamp('2024-01-01'), 'Start')`. */
5544
- time(defval, title) {
5545
- const v = registerInput({ type: "time", defval, title }, "input_time");
5507
+ time(defval, title, opts = {}) {
5508
+ const v = registerInput({ type: "time", defval, title, ...common(opts) }, "input_time");
5546
5509
  return typeof v === "number" ? v : defval;
5547
5510
  }
5548
5511
  };
@@ -5596,6 +5559,8 @@ var ta2 = {
5596
5559
  const a = anchor ?? changeOf("1D");
5597
5560
  return stdev_mult === void 0 ? vwap2(source, volume, a) : vwapBands(source, volume, a, stdev_mult);
5598
5561
  }),
5562
+ /** `ta.mfi(source, length)` with the chart volume (PineScript takes 2 arguments). */
5563
+ mfi: (source, length2) => mfi2(source, length2, volume),
5599
5564
  /** `ta.pivothigh(source, leftbars, rightbars)` or `ta.pivothigh(leftbars, rightbars)` (source = high).
5600
5565
  * The value appears `rightbars` bars after the pivot bar, as in PineScript. */
5601
5566
  pivothigh: (sourceOrLeft, leftOrRight, rightbars) => typeof sourceOrLeft === "number" ? pivothigh2(high, sourceOrLeft, leftOrRight) : pivothigh2(sourceOrLeft, leftOrRight, rightbars),
@@ -5622,7 +5587,7 @@ var color = {
5622
5587
  new: new_color,
5623
5588
  when: colorWhen
5624
5589
  };
5625
- function plot(series, title, options = {}) {
5590
+ function plotImpl(series, title, options = {}) {
5626
5591
  const c = collector();
5627
5592
  const id = `plot${c.plotConfig.length}`;
5628
5593
  const perBar2 = Array.isArray(options.color) ? options.color : void 0;
@@ -5633,6 +5598,7 @@ function plot(series, title, options = {}) {
5633
5598
  color: staticColor,
5634
5599
  lineWidth: options.linewidth,
5635
5600
  style: options.style,
5601
+ linestyle: options.linestyle,
5636
5602
  display: options.display,
5637
5603
  histbase: options.histbase
5638
5604
  });
@@ -5641,13 +5607,29 @@ function plot(series, title, options = {}) {
5641
5607
  const data = [];
5642
5608
  for (let i = 0; i < b2.length; i++) {
5643
5609
  const value = values[i];
5644
- if (value === void 0 || Number.isNaN(value)) continue;
5610
+ if (value === void 0 || !Number.isFinite(value)) continue;
5645
5611
  data.push(perBar2 ? { time: b2[i].time, value, color: perBar2[i] } : { time: b2[i].time, value });
5646
5612
  }
5647
5613
  c.plots[id] = data;
5648
5614
  return { id, kind: "plot" };
5649
5615
  }
5650
- function hline(price, title, options = {}) {
5616
+ var plot = Object.assign(plotImpl, {
5617
+ style_line: "line",
5618
+ style_linebr: "linebr",
5619
+ style_stepline: "stepline",
5620
+ style_steplinebr: "steplinebr",
5621
+ style_stepline_diamond: "stepline_diamond",
5622
+ style_histogram: "histogram",
5623
+ style_columns: "columns",
5624
+ style_area: "area",
5625
+ style_areabr: "areabr",
5626
+ style_circles: "circles",
5627
+ style_cross: "cross",
5628
+ linestyle_solid: "solid",
5629
+ linestyle_dotted: "dotted",
5630
+ linestyle_dashed: "dashed"
5631
+ });
5632
+ function hlineImpl(price, title, options = {}) {
5651
5633
  const c = collector();
5652
5634
  const id = `hline${c.hlineConfig.length}`;
5653
5635
  c.hlineConfig.push({
@@ -5655,11 +5637,16 @@ function hline(price, title, options = {}) {
5655
5637
  price,
5656
5638
  title,
5657
5639
  color: options.color,
5658
- linestyle: options.linestyle,
5640
+ linestyle: options.linestyle ?? "dashed",
5659
5641
  linewidth: options.linewidth
5660
5642
  });
5661
5643
  return { id, kind: "hline" };
5662
5644
  }
5645
+ var hline = Object.assign(hlineImpl, {
5646
+ style_solid: "solid",
5647
+ style_dotted: "dotted",
5648
+ style_dashed: "dashed"
5649
+ });
5663
5650
  function perBarValues(v, n) {
5664
5651
  return v instanceof Series ? v.toArray().slice(0, n) : new Array(n).fill(v);
5665
5652
  }
@@ -5762,6 +5749,35 @@ function plotshape(condition, title, options = {}) {
5762
5749
  function plotchar(condition, title, options = {}) {
5763
5750
  emitMarkers("char", condition, title, options);
5764
5751
  }
5752
+ function plotarrow(series, title, options = {}) {
5753
+ const c = collector();
5754
+ const id = `arrow${c.arrowConfig.length}`;
5755
+ const pick = (col2, fallback, i) => col2 === void 0 ? fallback : typeof col2 === "string" ? col2 : col2[i];
5756
+ const colorup = typeof options.colorup === "string" ? options.colorup : "#00FF00";
5757
+ const colordown = typeof options.colordown === "string" ? options.colordown : "#FF0000";
5758
+ c.arrowConfig.push({
5759
+ id,
5760
+ title,
5761
+ colorup,
5762
+ colordown,
5763
+ minheight: options.minheight ?? 5,
5764
+ maxheight: options.maxheight ?? 100,
5765
+ offset: options.offset,
5766
+ display: options.display
5767
+ });
5768
+ const values = series.toArray();
5769
+ const b2 = bars();
5770
+ const off = options.offset ?? 0;
5771
+ for (let i = 0; i < b2.length; i++) {
5772
+ const v = values[i];
5773
+ if (v === void 0 || Number.isNaN(v) || v === 0) continue;
5774
+ const j = i + off;
5775
+ if (j < 0 || j >= b2.length) continue;
5776
+ const color2 = v > 0 ? pick(options.colorup, "#00FF00", i) : pick(options.colordown, "#FF0000", i);
5777
+ if (color2 === void 0) continue;
5778
+ c.arrows.push({ time: b2[j].time, id, value: v, color: color2 });
5779
+ }
5780
+ }
5765
5781
  function emitBarColors(kind, colors, options) {
5766
5782
  const c = collector();
5767
5783
  const id = `${kind}${c.barColorConfig.filter((x) => x.kind === kind).length}`;
@@ -6163,6 +6179,37 @@ function flag(key) {
6163
6179
  const values = sessionFlags(ctxBars.bars.map(barTime), bars2, regular)[key];
6164
6180
  return Series.fromArray(ctxBars, values.map((v) => v ? 1 : 0));
6165
6181
  }
6182
+ function barFlag(test) {
6183
+ const n = ctxBars.bars.length;
6184
+ return Series.fromArray(ctxBars, Array.from({ length: n }, (_, i) => test(i, n) ? 1 : 0));
6185
+ }
6186
+ var lastRealtime = (i, n) => i === n - 1 && chartCtx.realtime === true;
6187
+ var barstate = {
6188
+ get isfirst() {
6189
+ return barFlag((i) => i === 0);
6190
+ },
6191
+ get islast() {
6192
+ return barFlag((i, n) => i === n - 1);
6193
+ },
6194
+ get isconfirmed() {
6195
+ return barFlag((i, n) => i < n - 1 || chartCtx.lastBarConfirmed === true);
6196
+ },
6197
+ get isrealtime() {
6198
+ return barFlag(lastRealtime);
6199
+ },
6200
+ get ishistory() {
6201
+ return barFlag((i, n) => !lastRealtime(i, n));
6202
+ },
6203
+ get isnew() {
6204
+ return barFlag((i, n) => !lastRealtime(i, n) || chartCtx.lastBarNew !== false);
6205
+ },
6206
+ get islastconfirmedhistory() {
6207
+ return barFlag((i, n) => {
6208
+ const lastConfirmed = chartCtx.lastBarConfirmed === true && chartCtx.realtime !== true;
6209
+ return i === (lastConfirmed ? n - 1 : n - 2);
6210
+ });
6211
+ }
6212
+ };
6166
6213
  var session = {
6167
6214
  regular: "regular",
6168
6215
  extended: "extended",