openalgo-charts 1.7.1 → 1.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.
package/README.md CHANGED
@@ -269,7 +269,7 @@ npm run verify # typecheck + test + build + size
269
269
 
270
270
  ## Status & limitations
271
271
 
272
- Version **1.7.1**. All engine build phases are implemented with 1953 unit tests across 106 files.
272
+ Version **1.8.1**. All engine build phases are implemented with 2038 unit tests across 110 files.
273
273
 
274
274
  Known gaps, stated plainly:
275
275
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /** Library version string. Matches package.json (published npm release). */
2
- declare const VERSION = "1.7.1";
2
+ declare const VERSION = "1.8.1";
3
3
  /** Returns the current library version. */
4
4
  declare function version(): string;
5
5
 
@@ -1493,6 +1493,27 @@ interface IndicatorPlot {
1493
1493
  * series without a full rebuild.
1494
1494
  */
1495
1495
  colorKey?: string;
1496
+ /**
1497
+ * Four `calc` keys to draw this plot as bar-shaped elements instead of one
1498
+ * value per bar: candles, hollow candles, OHLC bars, high-low.
1499
+ *
1500
+ * A single column cannot express those at all, and the alternative (a second
1501
+ * result shape for `calc`) would fork the contract every descriptor and every
1502
+ * helper is written against. Naming four columns inside the *same*
1503
+ * `IndicatorValues` keeps one shape: a smoothed Heikin-Ashi overlay, a
1504
+ * higher-timeframe candle, a synthetic spread instrument each return four
1505
+ * ordinary columns and point at them from here.
1506
+ *
1507
+ * The named columns must all exist and be bar-aligned, or `addIndicator`
1508
+ * throws. `key` stays the series identity and the legend reading falls back to
1509
+ * the `close` column.
1510
+ */
1511
+ ohlc?: {
1512
+ open: string;
1513
+ high: string;
1514
+ low: string;
1515
+ close: string;
1516
+ };
1496
1517
  /**
1497
1518
  * Per-bar colour, for plots whose meaning changes bar to bar — a MACD
1498
1519
  * histogram is four colours by sign and direction, a conditional study two.
@@ -1581,6 +1602,76 @@ type IndicatorDrawing = {
1581
1602
  type IndicatorValues = Record<string, readonly (number | null)[]>;
1582
1603
  /** Per-instance scratch owned by the descriptor (Tier-2 data lands here). */
1583
1604
  type IndicatorStore = Record<string, unknown>;
1605
+ /**
1606
+ * The fourth, optional argument to `calc` (and the sixth to `calcTail`): what
1607
+ * the calculation cannot read off the bars themselves.
1608
+ *
1609
+ * It is optional so that every descriptor written against `calc(bars, settings,
1610
+ * store)` keeps its exact signature and its exact behaviour, which is the whole
1611
+ * point: a calculation that ignores the context computes what it always did.
1612
+ */
1613
+ interface IndicatorCalcContext {
1614
+ /**
1615
+ * Where the last bar stands, so a study can act once per bar rather than once
1616
+ * per tick, or refuse to signal off a bar that is still moving.
1617
+ */
1618
+ barState: {
1619
+ /** The most recent update appended a bar rather than replacing one. */
1620
+ isNew: boolean;
1621
+ /** The last bar has closed: its interval has elapsed on the chart clock. */
1622
+ isConfirmed: boolean;
1623
+ /** A live feed is driving updates, rather than a one-off history load. */
1624
+ isRealtime: boolean;
1625
+ /** Index of the last bar, `bars.length - 1` (-1 when there are none). */
1626
+ lastIndex: number;
1627
+ };
1628
+ /** The instrument, when the host knows one. See `IndicatorAttachContext`. */
1629
+ symbol?: string;
1630
+ /** The timeframe (`'5m'`, `'1d'`), on the same terms as `symbol`. */
1631
+ interval?: string;
1632
+ /** The chart's IANA zone, the calendar its axis is labelled in. */
1633
+ timezone: string;
1634
+ /** Chart wall clock in UTC seconds, the clock the countdown row reads. */
1635
+ now(): number;
1636
+ }
1637
+ /** What an alert's `when` predicate is handed, for the bar it is judging. */
1638
+ interface IndicatorAlertContext {
1639
+ bars: readonly Bar[];
1640
+ values: IndicatorValues;
1641
+ settings: Readonly<IndicatorSettings>;
1642
+ /** The bar being evaluated. */
1643
+ index: number;
1644
+ }
1645
+ /**
1646
+ * A condition the runtime watches, declared by the descriptor rather than wired
1647
+ * up by the host: the indicator is the only thing that knows what a crossover of
1648
+ * its own columns means.
1649
+ *
1650
+ * Evaluated once per bar, for bars that are new since the last evaluation, so
1651
+ * adding the indicator to a loaded chart fires nothing for history.
1652
+ */
1653
+ interface IndicatorAlertSpec {
1654
+ /** Stable within the descriptor, e.g. `'cross-up'`. */
1655
+ id: string;
1656
+ /** Short human label, e.g. `'MACD crossed up'`. */
1657
+ title: string;
1658
+ /** Longer text for a notification; defaults to `title`. */
1659
+ message?: string;
1660
+ when(ctx: IndicatorAlertContext): boolean;
1661
+ }
1662
+ /** Payload of the `'indicator:alert'` event on the chart's own bus. */
1663
+ interface IndicatorAlertPayload {
1664
+ /** Descriptor id, e.g. `'macd'`. */
1665
+ indicatorId: string;
1666
+ /** Instance id, so a host can tell three EMAs apart. */
1667
+ instanceId: string;
1668
+ alertId: string;
1669
+ title: string;
1670
+ message: string;
1671
+ /** The bar that triggered it: UTC seconds, and its index in `bars`. */
1672
+ time: number;
1673
+ index: number;
1674
+ }
1584
1675
  /** What an indicator's `attach` lifecycle can reach. */
1585
1676
  interface IndicatorAttachContext {
1586
1677
  /** Current settings (live — read at call time, not captured). */
@@ -1612,6 +1703,14 @@ interface IndicatorAttachContext {
1612
1703
  /** Attach a primitive to this indicator's pane, and detach it again. */
1613
1704
  addPrimitive?(p: IPrimitive): void;
1614
1705
  removePrimitive?(p: IPrimitive): void;
1706
+ /**
1707
+ * Emit on the chart's own event bus, the one `chart.on(name, cb)` listens to.
1708
+ *
1709
+ * The declarative `alerts` slot covers a condition read off the bars; this is
1710
+ * the imperative half, for an indicator whose signal arrives from outside the
1711
+ * calculation entirely (a subscription its `attach` opened).
1712
+ */
1713
+ emit?(event: string, payload: unknown): void;
1615
1714
  }
1616
1715
  /**
1617
1716
  * What `levels` is handed. It carries `bars` and `values` **and** spreads the
@@ -1664,7 +1763,7 @@ interface IndicatorDescriptor {
1664
1763
  * `store`. Tier-2 indicators — the ones with their own data — read the
1665
1764
  * external series their `attach` lifecycle put in `store`.
1666
1765
  */
1667
- calc(bars: readonly Bar[], settings: Readonly<IndicatorSettings>, store: IndicatorStore): IndicatorValues;
1766
+ calc(bars: readonly Bar[], settings: Readonly<IndicatorSettings>, store: IndicatorStore, ctx?: IndicatorCalcContext): IndicatorValues;
1668
1767
  /**
1669
1768
  * Optional per-instance lifecycle, for indicators whose data is not derived
1670
1769
  * from the chart's bars (open interest, CVD, an external feed). Called once
@@ -1684,7 +1783,7 @@ interface IndicatorDescriptor {
1684
1783
  * microseconds for one indicator over 50k bars, but it is O(n) per tick per
1685
1784
  * indicator, so implement this for anything meant to run in a busy live pane.
1686
1785
  */
1687
- calcTail?(bars: readonly Bar[], settings: Readonly<IndicatorSettings>, fromIndex: number, previous: IndicatorValues, store: IndicatorStore): IndicatorValues | null;
1786
+ calcTail?(bars: readonly Bar[], settings: Readonly<IndicatorSettings>, fromIndex: number, previous: IndicatorValues, store: IndicatorStore, ctx?: IndicatorCalcContext): IndicatorValues | null;
1688
1787
  /**
1689
1788
  * Optional bar-anchored signal markers — a named "Buy"/"Sell" plate, an arrow
1690
1789
  * at a crossover. Runs after every `calc`, so it reads the values it just
@@ -1729,6 +1828,47 @@ interface IndicatorDescriptor {
1729
1828
  values: IndicatorValues;
1730
1829
  settings: Readonly<IndicatorSettings>;
1731
1830
  }): readonly IndicatorDrawing[];
1831
+ /**
1832
+ * Optional per-bar shading behind everything else in the indicator's pane: a
1833
+ * full-height column per bar, `null` where nothing should be shaded.
1834
+ *
1835
+ * A regime study answers "which state is the market in right now", and that is
1836
+ * a property of the whole bar, not a price. Drawn as a plot it would need a
1837
+ * value to sit at and would fight the pane's autoscale; as a column behind the
1838
+ * candles it reads at a glance and costs the scale nothing.
1839
+ *
1840
+ * Runs after every `calc`. Return `[]` to clear the layer.
1841
+ */
1842
+ background?(ctx: {
1843
+ bars: readonly Bar[];
1844
+ values: IndicatorValues;
1845
+ settings: Readonly<IndicatorSettings>;
1846
+ }): readonly (string | null)[];
1847
+ /**
1848
+ * Optional recolouring of the **main price candles**, one entry per bar,
1849
+ * `null` to leave that bar with its own colour.
1850
+ *
1851
+ * Distinct from a plot's `colorBy`, which paints the indicator's own series: a
1852
+ * trend filter, a volatility regime or a higher-timeframe bias is a statement
1853
+ * about the price bars themselves, and drawing it as a second series beside
1854
+ * them says something weaker.
1855
+ *
1856
+ * Only one indicator's colours can be on the candles at a time; the most
1857
+ * recent publisher wins, and publishers run in `addIndicator` order, so the
1858
+ * winner is the same one from frame to frame. Removing it, or hiding it,
1859
+ * restores the bars' own colours.
1860
+ */
1861
+ barColors?(ctx: {
1862
+ bars: readonly Bar[];
1863
+ values: IndicatorValues;
1864
+ settings: Readonly<IndicatorSettings>;
1865
+ }): readonly (string | null)[];
1866
+ /**
1867
+ * Optional conditions the runtime watches on the descriptor's behalf, emitted
1868
+ * as `'indicator:alert'` on the chart's event bus with an
1869
+ * {@link IndicatorAlertPayload}. See {@link IndicatorAlertSpec}.
1870
+ */
1871
+ alerts?: readonly IndicatorAlertSpec[];
1732
1872
  /**
1733
1873
  * Optional horizontal reference levels drawn in the indicator's pane.
1734
1874
  * Recomputed after every `calc`, so a level derived from the data (the
@@ -2171,6 +2311,19 @@ interface IndicatorHost {
2171
2311
  interval?(): string | undefined;
2172
2312
  /** Chart wall clock in UTC seconds. Absent means the system clock. */
2173
2313
  now?(): number;
2314
+ /**
2315
+ * Publish an indicator's per-bar colours onto the **primary price series**,
2316
+ * or withdraw them with `null`. `owner` is the instance id: a host holds one
2317
+ * overlay at a time and only lets its current owner withdraw it, so a second
2318
+ * publisher taking over does not get cleared by the first one's teardown.
2319
+ *
2320
+ * Optional, like `timezone`: a host that does not implement it simply gives a
2321
+ * `barColors` descriptor nowhere to publish, and the indicator's own plots are
2322
+ * unaffected.
2323
+ */
2324
+ setBarColors?(colors: readonly (string | null)[] | null, owner: string): void;
2325
+ /** Emit on the chart's event bus (indicator alerts, and `attach`'s own events). */
2326
+ emit?(event: string, payload: unknown): void;
2174
2327
  /** Pin a pane's price scale to a fixed range, or release it with `null`. */
2175
2328
  setPaneRange(paneIndex: number, range: {
2176
2329
  min: number;
@@ -2552,6 +2705,49 @@ declare class TradingController {
2552
2705
  private _onDragEnd;
2553
2706
  }
2554
2707
 
2708
+ /**
2709
+ * Interactive value capture (ARCHITECTURE.md §7). A settings input that names a
2710
+ * price or a time is declarative and the host renders it, but the *value* can
2711
+ * come from pointing at the chart, and only the engine knows what is under the
2712
+ * cursor. So the host arms a pick ("the user is now choosing a price"), the next
2713
+ * click on the plot answers with one, and the pick disarms itself.
2714
+ *
2715
+ * Built on the `click` event the draw tier's placement mode already resolves
2716
+ * anchors from, rather than a second capture path: same pane resolution, same
2717
+ * on-demand autoscale, same payload.
2718
+ *
2719
+ * Placement mode is deliberately *not* armed while picking. A pick wants panning
2720
+ * left alone (scroll back to the bar you mean, then click it), and a drag emits
2721
+ * no click outside placement mode, so panning cannot answer the pick by
2722
+ * accident. It also keeps a pick from cancelling an active drawing tool.
2723
+ */
2724
+ type PickKind = 'price' | 'time';
2725
+ /**
2726
+ * The slice of the chart a pick needs. Structural, so `Chart` satisfies it with
2727
+ * nothing to cast and this module never imports the core (which imports this).
2728
+ */
2729
+ interface PickHost {
2730
+ on(event: string, cb: (payload: unknown) => void): () => void;
2731
+ emit(event: string, payload: unknown): void;
2732
+ readonly dataLayer: {
2733
+ timeToIndexFloat(time: number): number;
2734
+ indexToTime(index: number): number | undefined;
2735
+ };
2736
+ }
2737
+ /**
2738
+ * Arm the next plot click to resolve to a price or a bar time and hand it to
2739
+ * `cb`. Returns a cancel function; calling it (or arming another pick on the
2740
+ * same chart) disarms without calling back. The chart emits `pick:start`
2741
+ * (`{ kind }`) and `pick:end` (`{ kind, value }`, `value` null when cancelled)
2742
+ * so a host can show its own cursor or hint while the pick is live.
2743
+ *
2744
+ * A time is snapped to the bar the click landed on, because a time between two
2745
+ * bars matches no bar and anything anchored to it would never line up. Clicking
2746
+ * past the last bar keeps the projected time, which is what a pick in the empty
2747
+ * right-hand space means.
2748
+ */
2749
+ declare function beginPick(host: PickHost, kind: PickKind, cb: (value: number) => void): () => void;
2750
+
2555
2751
  /**
2556
2752
  * Event markers (ARCHITECTURE.md §8.2): Earnings / Dividend / Split badges in a
2557
2753
  * strip near the bottom of the plot. Time-anchored only (no price). Hover/click
@@ -3140,6 +3336,17 @@ declare class Chart {
3140
3336
  private readonly _indicators;
3141
3337
  /** Guards indicator recompute against re-entry via its own `series.setData`. */
3142
3338
  private _recomputing;
3339
+ /** Instance id of the indicator whose colours are on the price bars, if any. */
3340
+ private _barColorOwner;
3341
+ private _barColors;
3342
+ /**
3343
+ * Each price bar's own colour, indexed like the series. The overlay overwrites
3344
+ * `Bar.color`, so a bar's own value is only readable the first time we touch
3345
+ * it, and removing the indicator has to put something back.
3346
+ */
3347
+ private readonly _barColorBase;
3348
+ /** Time of bar 0 when the snapshot was taken, to catch a replaced history. */
3349
+ private _barColorAnchor;
3143
3350
  /** Opaque drawing-tier payload, round-tripped through get/restoreState. */
3144
3351
  private _drawingState;
3145
3352
  /** Pane currently maximized, and the weights to restore when it un-maximizes. */
@@ -3309,6 +3516,30 @@ declare class Chart {
3309
3516
  /** Remove one indicator instance by its handle id. Returns true if it existed. */
3310
3517
  removeIndicator(instanceId: string): boolean;
3311
3518
  private _indicatorHost;
3519
+ /**
3520
+ * Take (or withdraw) the price bars' colour overlay on behalf of one
3521
+ * indicator instance.
3522
+ *
3523
+ * Only one overlay can be on the candles, so this is last writer wins. That is
3524
+ * deterministic rather than arbitrary: publishers run inside
3525
+ * `_recomputeIndicators`, in `addIndicator` order, so the same instance wins
3526
+ * every frame. Withdrawal is gated on ownership, or the first publisher's
3527
+ * teardown would wipe the second one's colours. If the *winner* is removed
3528
+ * while another publisher is still live, the bars go back to their own colours
3529
+ * until that publisher's next recompute.
3530
+ */
3531
+ private _setBarColors;
3532
+ /**
3533
+ * Republish the primary series with the overlay applied.
3534
+ *
3535
+ * The bars in the data layer are the **caller's own objects** (`setData` keeps
3536
+ * the references), so painting a colour onto them in place would reach back
3537
+ * into the host's array and outlive the indicator. Cloning the ones that
3538
+ * change is what keeps that from happening; unchanged bars are passed through,
3539
+ * and a pass where nothing changed writes nothing at all, which is the common
3540
+ * case on a live tick.
3541
+ */
3542
+ private _applyBarColors;
3312
3543
  /**
3313
3544
  * Recompute every indicator after a source-data change. Reentrant-guarded:
3314
3545
  * an indicator writes its plots with `series.setData`, which re-enters the
@@ -3562,6 +3793,14 @@ declare class Chart {
3562
3793
  * in one gesture. `DrawingController` drives this for you.
3563
3794
  */
3564
3795
  setPlacementMode(active: boolean): void;
3796
+ /**
3797
+ * Arm the next plot click to answer with a price or a bar time, handed to
3798
+ * `cb`. Returns a cancel function; arming another pick on this chart cancels
3799
+ * the pending one. `pick:start` and `pick:end` bracket it so a host can show
3800
+ * its own cursor while the pick is live. See `input/pick` for why this does
3801
+ * not touch placement mode.
3802
+ */
3803
+ beginPick(kind: PickKind, cb: (value: number) => void): () => void;
3565
3804
  /** Swap the palette at runtime (dark/light toggle) without recreating the chart. */
3566
3805
  setTheme(theme: ChartTheme): void;
3567
3806
  /**
@@ -3847,7 +4086,28 @@ declare class Chart {
3847
4086
  /** Create a chart inside the given container element. */
3848
4087
  declare function createChart(container: HTMLElement, options?: ChartOptions): Chart;
3849
4088
 
4089
+ /** The color as rgba() with the given alpha (parse failure returns the input). */
4090
+ declare function withAlpha(color: string, alpha: number): string;
4091
+
4092
+ /**
4093
+ * Re-exported, not reimplemented: one import path covers an indicator's colour
4094
+ * work, while the only colour parser in the engine stays in `pill.ts`. A second
4095
+ * copy here would cost base bytes and drift out of step with the first.
4096
+ */
4097
+
3850
4098
  declare function verticalGradient(ctx: CanvasRenderingContext2D, heightPx: number, topColor: string, bottomColor: string): CanvasGradient;
4099
+ /**
4100
+ * Blend `low` to `high` in sRGB by where `value` sits in [min, max], clamped
4101
+ * outside. Heatmap plots and per-bar colouring call this once per bar, so it
4102
+ * allocates only the result string: no closure, no cache, no lookup table.
4103
+ *
4104
+ * The clamp is two comparisons rather than Math.min/Math.max because both are
4105
+ * false against a not-available value, which lands it on `low` instead of
4106
+ * poisoning the output with NaN. Canvas ignores an unparseable fillStyle and
4107
+ * silently keeps the previous one, so a bad string would bleed a neighbour's
4108
+ * colour across the bar rather than fail loudly.
4109
+ */
4110
+ declare function fromGradient(value: number, min: number, max: number, low: string, high: string): string;
3851
4111
 
3852
4112
  /**
3853
4113
  * Generate up to ~`maxTicks` nicely-rounded tick values spanning [min, max].
@@ -4734,6 +4994,38 @@ declare class IndicatorDrawings implements IPrimitive {
4734
4994
  draw(ctx: CanvasRenderingContext2D, rc: PrimitiveRenderContext): void;
4735
4995
  }
4736
4996
 
4997
+ /**
4998
+ * Per-bar pane shading: one full-height column behind the data, in whatever
4999
+ * colour the descriptor gave that bar.
5000
+ *
5001
+ * A regime study answers "which state is the market in", and that is a property
5002
+ * of the whole bar rather than of a price. As a column it reads at a glance and
5003
+ * costs the price scale nothing, where a plot would need a value to sit at and
5004
+ * would drag the pane's autoscale around with it.
5005
+ *
5006
+ * What makes it affordable is the work skipped: everything outside the visible
5007
+ * range is dropped before anything is painted, and adjacent bars sharing a
5008
+ * colour become one rect instead of one rect each. A year of two-state shading
5009
+ * is a handful of fills, not one per bar per frame.
5010
+ */
5011
+
5012
+ declare class IndicatorBackground implements IPrimitive {
5013
+ private _colors;
5014
+ /** Time of `_colors[0]`'s bar. See `draw` for why this is a time, not an index. */
5015
+ private _anchor;
5016
+ private _host;
5017
+ private _visible;
5018
+ attached(host: PrimitiveHost): void;
5019
+ detached(): void;
5020
+ /** The same layer the bands use: behind the series, so the candles stay crisp. */
5021
+ zOrder(): ZOrder;
5022
+ /** Shading has no price of its own and must never widen the pane's range. */
5023
+ autoscaleInfo(): null;
5024
+ setColors(colors: readonly (string | null)[], bars: readonly Bar[]): void;
5025
+ setVisible(on: boolean): void;
5026
+ draw(ctx: CanvasRenderingContext2D, rc: PrimitiveRenderContext): void;
5027
+ }
5028
+
4737
5029
  /**
4738
5030
  * Price-level family, built on the primitive API (ARCHITECTURE.md §8). A price
4739
5031
  * level is a horizontal line at a meaningful price **and** a matching tag on the
@@ -6292,6 +6584,58 @@ declare function bucketStartOf(b: Bucketing, timeSec: number, zone?: string): nu
6292
6584
  * or 31 days for a month, and an hour short of that across a spring forward.
6293
6585
  */
6294
6586
  declare function nextBucketStart(b: Bucketing, timeSec: number, zone?: string): number | null;
6587
+ /**
6588
+ * How a bar's length reads to a human: a count, and the unit it counts.
6589
+ *
6590
+ * `M` is months, so a quarter reads as 3 and a year as 12, keeping the token
6591
+ * grammar's rule that lower-case `m` is minutes and upper-case `M` is a month.
6592
+ * `tick` counts trades. `other` is a bucket with neither a clock length nor a
6593
+ * trade count, which today means volume, and is where a later count-driven
6594
+ * mode can land without silently changing what an existing unit means.
6595
+ */
6596
+ interface IntervalParts {
6597
+ multiplier: number;
6598
+ unit: 's' | 'm' | 'h' | 'D' | 'W' | 'M' | 'tick' | 'other';
6599
+ }
6600
+ /**
6601
+ * Split a code into a count and a unit, or null when nothing recognises it.
6602
+ * For an indicator that knows its own interval and wants to reason about it,
6603
+ * rather than hard-coding the handful of codes its author happened to test on.
6604
+ *
6605
+ * Read off the bucketing rule, not off the code's spelling, so it answers for
6606
+ * a registered code the built-in grammar never parsed, and it answers
6607
+ * canonically: `120m` and `2h` are the same bar and both read as 2 h. The
6608
+ * coarsest unit that divides the length wins, which is also why a 90-second
6609
+ * bar reads as 90 s rather than as one and a half minutes.
6610
+ */
6611
+ declare function intervalParts(code: string): IntervalParts | null;
6612
+ /**
6613
+ * True when the bar is not a whole number of minutes long, so its labels need
6614
+ * second precision. `1s`, `15s` and `90s` all qualify; `5m` does not.
6615
+ */
6616
+ declare function isSecondsInterval(code: string): boolean;
6617
+ /**
6618
+ * True for a fixed-length bar shorter than a day: the ones that want a session
6619
+ * reset, such as a VWAP anchored to the day's open or an opening range.
6620
+ *
6621
+ * A calendar period is false because it is coarser, and a count-driven bar is
6622
+ * false because it has no clock length to compare, not because it is known to
6623
+ * be long. Ask `isTickInterval` or `intervalParts` for those.
6624
+ */
6625
+ declare function isIntradayInterval(code: string): boolean;
6626
+ /**
6627
+ * True for a bar exactly one day long, whether spelled `D`, `24h` or `1440m`.
6628
+ *
6629
+ * Deliberately not "daily or coarser": weekly and monthly answer false, so a
6630
+ * caller can branch on intraday, daily and coarser as three independent
6631
+ * questions instead of an ordered ladder where the wrong order swallows a case.
6632
+ */
6633
+ declare function isDailyInterval(code: string): boolean;
6634
+ /**
6635
+ * True for a bar that closes after N trades. Volume bars close on quantity, not
6636
+ * on trade count, so they answer false; `intervalParts` separates the two.
6637
+ */
6638
+ declare function isTickInterval(code: string): boolean;
6295
6639
 
6296
6640
  /**
6297
6641
  * Tick aggregation (ARCHITECTURE.md 10.2). Aggregates raw trade ticks into
@@ -6675,6 +7019,34 @@ declare function sessionStartFlags(times: readonly number[], zone?: string): boo
6675
7019
  * session.
6676
7020
  */
6677
7021
  declare function calendarPeriodFlags(times: readonly number[], isNew: (prevUtcSeconds: number, utcSeconds: number) => boolean): boolean[];
7022
+ /** A trading window in local wall-clock terms, as parsed from a spec string. */
7023
+ interface SessionSpec {
7024
+ /** Minutes from midnight, inclusive. */
7025
+ start: number;
7026
+ /** Minutes from midnight, exclusive. */
7027
+ end: number;
7028
+ /** Days the window opens on, 1..7 with 1 = Sunday. Absent means every day. */
7029
+ days?: readonly number[];
7030
+ }
7031
+ /**
7032
+ * Parse `"0915-1015"`, optionally with a day filter after a colon:
7033
+ * `"0930-1600:23456"` is Monday to Friday. Whitespace around the parts is
7034
+ * ignored. An end at or before the start is a window that runs past midnight.
7035
+ *
7036
+ * Returns null rather than throwing, because the spec is normally a string a
7037
+ * user typed into a settings field and a half-typed one arrives on every
7038
+ * keystroke.
7039
+ */
7040
+ declare function parseSessionSpec(spec: string): SessionSpec | null;
7041
+ /** True if this instant falls inside `spec` as read in `zone`. */
7042
+ declare function inSessionAt(utcSeconds: number, spec: SessionSpec, zone?: string): boolean;
7043
+ /**
7044
+ * Per-bar flags marking the bars inside `spec`. An unparseable spec string
7045
+ * marks nothing: a chart that keeps drawing beats one that dies on a stray
7046
+ * character, and the caller can check `parseSessionSpec` itself to tell an
7047
+ * empty window from a bad one.
7048
+ */
7049
+ declare function sessionFlags(times: readonly number[], spec: string | SessionSpec, zone?: string): boolean[];
6678
7050
 
6679
7051
  /** Clamp `value` into the inclusive range [min, max]. */
6680
7052
  declare function clamp(value: number, min: number, max: number): number;
@@ -6687,4 +7059,4 @@ declare function lerp(a: number, b: number, t: number): number;
6687
7059
  */
6688
7060
  declare function roundToTick(value: number, step: number): number;
6689
7061
 
6690
- export { ALT_PRESET, type AddSeriesOptions, type AggTick, type AxisChromeOptions, BUILTIN_COMMANDS, type Bar, BarCache, type BarCacheOptions, type BarCacheStats, type BarCacheStore, type BarUpdate, type BarsRequest, type Bucketing, BuySellButtons, type BuySellButtonsOptions, CHART_STATE_VERSION, type CachedBars, type CachedBarsRequest, type CalendarBucketing, type CalendarUnit, CandleBuilder, type CandleBuilderOptions, type CandleStyle, type CandleUpdate, type CanvasLineStyle, type CanvasOptions, Chart, type ChartEvent, type ChartEventOptions, type ChartOptions, type ChartSettingsState, type ChartSettingsTab, type ChartSettingsTabId, type ChartSettingsValue, type ChartSettingsValues, type ChartState, ChartTable, type ChartTableOptions, type ChartTheme, type ComparisonAlignment, type ComparisonChartHost, ComparisonController, type ComparisonControllerOptions, type ComparisonHandle, type ComparisonMode, type ComparisonOptions, type ComparisonPane, type ContextMenuEvent, type ContextMenuTarget, type ContextMenuTargetKind, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairStyle, type CustomShortcut, DEFAULT_CANDLE_BUILDER_OPTIONS, DEFAULT_CANDLE_STYLE, DEFAULT_CHART_TABLE_OPTIONS, DEFAULT_HISTOGRAM_STYLE, DEFAULT_KEYMAP, DEFAULT_PRICE_SCALE_OPTIONS, DEFAULT_THEME, DEFAULT_TIMEZONE, DEFAULT_TIME_NAVIGATOR_OPTIONS, DEFAULT_TIME_SCALE_OPTIONS, DEFAULT_TRADING_COLORS, type DataFeed, DataLayer, type DecodedOrder, type DepthLevel, type DrawAnchor, type DrawItem, EventMarkers, FakeDataFeed, type FeedScheduler, type FillGradient, type FillPoint, type GridAxisStyle, type GridOptions, type GridStyle, type HistogramStyle, INDICATOR_LINE_STYLES, INDICATOR_PLOT_STYLES, INDICATOR_SOURCES, type IPrimitive, IST_OFFSET_SECONDS, type IndexedBar, type IndicatorApi, type IndicatorAttachContext, type IndicatorDescriptor, type IndicatorDrawing, IndicatorDrawings, IndicatorFill, type IndicatorFillOptions, type IndicatorFillSpec, type IndicatorHost, type IndicatorInput, type IndicatorLevel, type IndicatorLevelContext, type IndicatorLineStyle, type IndicatorPlot, type IndicatorSettings, type IndicatorSource, type IndicatorState, type IndicatorStore, type IndicatorValues, type IntervalBucketing, type IntervalDescriptor, InvalidationLevel, type IstParts, type KeymapEntry, LINK_CROSSHAIR_ALPHA, type LateTickPolicy, type LegendField, type LegendStatusData, type LegendStatusLineOptions, type LegendStatusSource, type LegendTitleMode, type LegendValue, type LinePoint, type LinkChart, LinkCrosshair, type LinkDataLayer, LinkGroup, type LinkMemberOptions, type LinkMissingPolicy, type LinkOptions, type LogicalRange, LogoWatermark, type LogoWatermarkOptions, type LtpEvent, type MarkerPosition, type MarkerShape, type MarkerSize, type MarketDepth, type MarketPhase, type MarketPhaseFn, type MaybePromise, type ModeCheck, type OpenAlgoConfig, OpenAlgoDataFeed, type OpenAlgoLiveConfig, OpenAlgoLiveDataFeed, type OpenAlgoTradeConfig, OpenAlgoTradeFeed, type OpenAlgoWsConfig, OpenAlgoWsFeed, type OrderBookSnapshot, type OrderDecodeCode, type OrderDecodeIssue, type OrderDecodeResult, type OrderSide$1 as OrderSide, type OrderType$1 as OrderType, type OriginalTime, PRICE_LEVEL_KINDS, PRICE_SCALE_MODES, Pane, type PaneInvalidation, PaneLegend, type PaneLegendAction, type PaneLegendOptions, type PaneState, type PlaceOrder, type PlotMarginOptions, type PositionSide, type PriceAxisState, type PriceLevelInput, type PriceLevelKind, type PriceLevelQuote, type PriceLevelStyle, type PriceLevelValues, PriceLevels, type PriceLevelsOptions, PriceLine, type PriceLineOptions, type PriceRange, PriceScale, type PriceScaleId, type PriceScaleMode, type PriceScaleOptions, type PriceScaleState, type PrimitiveAnchor, type PrimitiveHit, type PrimitiveHost, type PrimitivePlacement, type PrimitiveRenderContext, type QuarantinedRow, type RawOrder, type RendererEntry, type ReplayChartHost, ReplayController, type ReplayOptions, type ReplayScheduler, type ReplayState, type ReplayViewport, type ResolvedLinkOptions, type RestoreReport, SCALE_FONT_MAX, SCALE_FONT_MIN, type ScaleCanvasOptions, type SeriesApi, type SeriesDataItem, type SeriesId, type SeriesMarker, SeriesMarkers, type SeriesRenderContext, type SeriesState, type SeriesStyle, type SeriesType, type ShortcutListItem, ShortcutManager, type ShortcutManagerOptions, type ShortcutPreset, type ShortcutScope, type ShortcutTriggerEvent, type Size, type SocketFactory, type SocketLike, type SupertrendPoint, type TableCell, type TablePosition, type Tick, TickBarAggregator, type TickBarOptions, type TickCountBucketing, type TickMarkType, type TickTimeframe, TimeNavigator, type TimeNavigatorAction, type TimeNavigatorOptions, TimeScale, type TimeScaleOp, type TimeScaleOptions, type TradeFeed, type TradeMarkerVariant, TradeMarkersPrimitive, type TradingColors, TradingController, type TradingHost, type TradingLineStyle, type TradingLineVariant, type TradingOrder, type TradingOrderSide, type TradingOrderType, type TradingPosition, type TradingSettings, type TradingSyncPayload, type TradingTrade, type UTCSeconds, UnknownIntervalError, type UnsubscribeFn, VERSION, type VolumeBucketing, type VolumeMode, type WatermarkPosition, type Whitespace, type WsClientWarning, type WsControlMessage, type WsMode, type WsState, type ZOrder, type ZonedParts, type ZonedPeriod, addComparison, alignToPrimary, applyChartSettings, atr, autoscaleRange, backoffDelayMs, barCacheKey, barCloseSec, bestHit, bitmapSize, bucketStartOf, calendarPeriodFlags, chartSettingsSchema, clamp, classifyAuthAck, compactVolume, comparisonController, computePriceLevels, conflateBars, conflateItems, conflationGroupSize, createChart, createLinkGroup, darkTheme, dashPattern, decodeOrder, drawLabel, drawShape, effectiveMarkerPx, ema, emaSeries, epochMsToUtcSeconds, eventToCombo, followerIndex, followerRange, formatCombo, formatIstCrosshairLabel, formatIstDate, formatIstTime, formatIstTimeSeconds, formatSubscribe, formatUnsubscribe, formatZonedCrosshairLabel, formatZonedDate, formatZonedTime, formatZonedTimeSeconds, generateBars, getChartType, getIndicator, hasIndicator, indicatorDefaults, indicatorStyleInputs, intervalToSeconds, isKnownInterval, isNewIstDay, isNewZonedDay, isNewZonedMonth, isNewZonedPeriod, isNewZonedQuarter, isNewZonedWeek, isNewZonedYear, isRebasing, isReservedCombo, isTimeBucketed, isValidCombo, isValidTimezone, isWhitespace, istStringToUtcSeconds, lastPriceLevelFromSeriesStyle, lerp, lightTheme, mapHistoryResponse, mapOrder, mapOrderStatus, mapPosition, markerSizePx, mergeBars, nextBucketStart, niceTicks, normalizeCombo, optimalBarWidth, parseCombo, parseMessage, parseTopic, plotStyleKeys, precisionForStep, readChartSettings, readSequence, registerChartType, registerIndicator, registerInterval, registeredChartTypes, registeredIndicators, registeredIntervals, resolveCrosshairStyle, resolveGridStyle, resolveInterval, resolvePlotMargins, resolveScaleStyle, roundToTick, rowTimeToUtcSeconds, rsi, rsiSeries, seriesStyleForLastPriceLevel, sessionStartFlags, sessionStartIndices, snapToDevicePixel, sourceValue, sourceValues, startOfZonedDay, startOfZonedMonth, startOfZonedWeek, supertrend, supertrendSeries, tableOrigin, toBar, trueRange, tryResolveInterval, unregisterInterval, utcSecondsToIstDateString, utcSecondsToIstParts, utcSecondsToZonedDateString, utcSecondsToZonedParts, version, verticalGradient, watermarkRect, withBarCache, zoneOffsetSeconds, zonedDayIndex, zonedStringToUtcSeconds, zonedWallClockToUtcSeconds, zonedWeekIndex };
7062
+ export { ALT_PRESET, type AddSeriesOptions, type AggTick, type AxisChromeOptions, BUILTIN_COMMANDS, type Bar, BarCache, type BarCacheOptions, type BarCacheStats, type BarCacheStore, type BarUpdate, type BarsRequest, type Bucketing, BuySellButtons, type BuySellButtonsOptions, CHART_STATE_VERSION, type CachedBars, type CachedBarsRequest, type CalendarBucketing, type CalendarUnit, CandleBuilder, type CandleBuilderOptions, type CandleStyle, type CandleUpdate, type CanvasLineStyle, type CanvasOptions, Chart, type ChartEvent, type ChartEventOptions, type ChartOptions, type ChartSettingsState, type ChartSettingsTab, type ChartSettingsTabId, type ChartSettingsValue, type ChartSettingsValues, type ChartState, ChartTable, type ChartTableOptions, type ChartTheme, type ComparisonAlignment, type ComparisonChartHost, ComparisonController, type ComparisonControllerOptions, type ComparisonHandle, type ComparisonMode, type ComparisonOptions, type ComparisonPane, type ContextMenuEvent, type ContextMenuTarget, type ContextMenuTargetKind, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairStyle, type CustomShortcut, DEFAULT_CANDLE_BUILDER_OPTIONS, DEFAULT_CANDLE_STYLE, DEFAULT_CHART_TABLE_OPTIONS, DEFAULT_HISTOGRAM_STYLE, DEFAULT_KEYMAP, DEFAULT_PRICE_SCALE_OPTIONS, DEFAULT_THEME, DEFAULT_TIMEZONE, DEFAULT_TIME_NAVIGATOR_OPTIONS, DEFAULT_TIME_SCALE_OPTIONS, DEFAULT_TRADING_COLORS, type DataFeed, DataLayer, type DecodedOrder, type DepthLevel, type DrawAnchor, type DrawItem, EventMarkers, FakeDataFeed, type FeedScheduler, type FillGradient, type FillPoint, type GridAxisStyle, type GridOptions, type GridStyle, type HistogramStyle, INDICATOR_LINE_STYLES, INDICATOR_PLOT_STYLES, INDICATOR_SOURCES, type IPrimitive, IST_OFFSET_SECONDS, type IndexedBar, type IndicatorAlertContext, type IndicatorAlertPayload, type IndicatorAlertSpec, type IndicatorApi, type IndicatorAttachContext, IndicatorBackground, type IndicatorCalcContext, type IndicatorDescriptor, type IndicatorDrawing, IndicatorDrawings, IndicatorFill, type IndicatorFillOptions, type IndicatorFillSpec, type IndicatorHost, type IndicatorInput, type IndicatorLevel, type IndicatorLevelContext, type IndicatorLineStyle, type IndicatorPlot, type IndicatorSettings, type IndicatorSource, type IndicatorState, type IndicatorStore, type IndicatorValues, type IntervalBucketing, type IntervalDescriptor, type IntervalParts, InvalidationLevel, type IstParts, type KeymapEntry, LINK_CROSSHAIR_ALPHA, type LateTickPolicy, type LegendField, type LegendStatusData, type LegendStatusLineOptions, type LegendStatusSource, type LegendTitleMode, type LegendValue, type LinePoint, type LinkChart, LinkCrosshair, type LinkDataLayer, LinkGroup, type LinkMemberOptions, type LinkMissingPolicy, type LinkOptions, type LogicalRange, LogoWatermark, type LogoWatermarkOptions, type LtpEvent, type MarkerPosition, type MarkerShape, type MarkerSize, type MarketDepth, type MarketPhase, type MarketPhaseFn, type MaybePromise, type ModeCheck, type OpenAlgoConfig, OpenAlgoDataFeed, type OpenAlgoLiveConfig, OpenAlgoLiveDataFeed, type OpenAlgoTradeConfig, OpenAlgoTradeFeed, type OpenAlgoWsConfig, OpenAlgoWsFeed, type OrderBookSnapshot, type OrderDecodeCode, type OrderDecodeIssue, type OrderDecodeResult, type OrderSide$1 as OrderSide, type OrderType$1 as OrderType, type OriginalTime, PRICE_LEVEL_KINDS, PRICE_SCALE_MODES, Pane, type PaneInvalidation, PaneLegend, type PaneLegendAction, type PaneLegendOptions, type PaneState, type PickHost, type PickKind, type PlaceOrder, type PlotMarginOptions, type PositionSide, type PriceAxisState, type PriceLevelInput, type PriceLevelKind, type PriceLevelQuote, type PriceLevelStyle, type PriceLevelValues, PriceLevels, type PriceLevelsOptions, PriceLine, type PriceLineOptions, type PriceRange, PriceScale, type PriceScaleId, type PriceScaleMode, type PriceScaleOptions, type PriceScaleState, type PrimitiveAnchor, type PrimitiveHit, type PrimitiveHost, type PrimitivePlacement, type PrimitiveRenderContext, type QuarantinedRow, type RawOrder, type RendererEntry, type ReplayChartHost, ReplayController, type ReplayOptions, type ReplayScheduler, type ReplayState, type ReplayViewport, type ResolvedLinkOptions, type RestoreReport, SCALE_FONT_MAX, SCALE_FONT_MIN, type ScaleCanvasOptions, type SeriesApi, type SeriesDataItem, type SeriesId, type SeriesMarker, SeriesMarkers, type SeriesRenderContext, type SeriesState, type SeriesStyle, type SeriesType, type SessionSpec, type ShortcutListItem, ShortcutManager, type ShortcutManagerOptions, type ShortcutPreset, type ShortcutScope, type ShortcutTriggerEvent, type Size, type SocketFactory, type SocketLike, type SupertrendPoint, type TableCell, type TablePosition, type Tick, TickBarAggregator, type TickBarOptions, type TickCountBucketing, type TickMarkType, type TickTimeframe, TimeNavigator, type TimeNavigatorAction, type TimeNavigatorOptions, TimeScale, type TimeScaleOp, type TimeScaleOptions, type TradeFeed, type TradeMarkerVariant, TradeMarkersPrimitive, type TradingColors, TradingController, type TradingHost, type TradingLineStyle, type TradingLineVariant, type TradingOrder, type TradingOrderSide, type TradingOrderType, type TradingPosition, type TradingSettings, type TradingSyncPayload, type TradingTrade, type UTCSeconds, UnknownIntervalError, type UnsubscribeFn, VERSION, type VolumeBucketing, type VolumeMode, type WatermarkPosition, type Whitespace, type WsClientWarning, type WsControlMessage, type WsMode, type WsState, type ZOrder, type ZonedParts, type ZonedPeriod, addComparison, alignToPrimary, applyChartSettings, atr, autoscaleRange, backoffDelayMs, barCacheKey, barCloseSec, beginPick, bestHit, bitmapSize, bucketStartOf, calendarPeriodFlags, chartSettingsSchema, clamp, classifyAuthAck, compactVolume, comparisonController, computePriceLevels, conflateBars, conflateItems, conflationGroupSize, createChart, createLinkGroup, darkTheme, dashPattern, decodeOrder, drawLabel, drawShape, effectiveMarkerPx, ema, emaSeries, epochMsToUtcSeconds, eventToCombo, followerIndex, followerRange, formatCombo, formatIstCrosshairLabel, formatIstDate, formatIstTime, formatIstTimeSeconds, formatSubscribe, formatUnsubscribe, formatZonedCrosshairLabel, formatZonedDate, formatZonedTime, formatZonedTimeSeconds, fromGradient, generateBars, getChartType, getIndicator, hasIndicator, inSessionAt, indicatorDefaults, indicatorStyleInputs, intervalParts, intervalToSeconds, isDailyInterval, isIntradayInterval, isKnownInterval, isNewIstDay, isNewZonedDay, isNewZonedMonth, isNewZonedPeriod, isNewZonedQuarter, isNewZonedWeek, isNewZonedYear, isRebasing, isReservedCombo, isSecondsInterval, isTickInterval, isTimeBucketed, isValidCombo, isValidTimezone, isWhitespace, istStringToUtcSeconds, lastPriceLevelFromSeriesStyle, lerp, lightTheme, mapHistoryResponse, mapOrder, mapOrderStatus, mapPosition, markerSizePx, mergeBars, nextBucketStart, niceTicks, normalizeCombo, optimalBarWidth, parseCombo, parseMessage, parseSessionSpec, parseTopic, plotStyleKeys, precisionForStep, readChartSettings, readSequence, registerChartType, registerIndicator, registerInterval, registeredChartTypes, registeredIndicators, registeredIntervals, resolveCrosshairStyle, resolveGridStyle, resolveInterval, resolvePlotMargins, resolveScaleStyle, roundToTick, rowTimeToUtcSeconds, rsi, rsiSeries, seriesStyleForLastPriceLevel, sessionFlags, sessionStartFlags, sessionStartIndices, snapToDevicePixel, sourceValue, sourceValues, startOfZonedDay, startOfZonedMonth, startOfZonedWeek, supertrend, supertrendSeries, tableOrigin, toBar, trueRange, tryResolveInterval, unregisterInterval, utcSecondsToIstDateString, utcSecondsToIstParts, utcSecondsToZonedDateString, utcSecondsToZonedParts, version, verticalGradient, watermarkRect, withAlpha, withBarCache, zoneOffsetSeconds, zonedDayIndex, zonedStringToUtcSeconds, zonedWallClockToUtcSeconds, zonedWeekIndex };