@pond-ts/react 0.44.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/CHANGELOG.md +117 -1
  2. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -8,7 +8,9 @@ The `@pond-ts` packages — `pond-ts`, `@pond-ts/react`, `@pond-ts/charts`,
8
8
  tag, so this file covers them all. Pre-1.0: minor bumps may include new features
9
9
  and type-level changes; patch bumps are strictly additive.
10
10
 
11
- [Unreleased]: https://github.com/pjm17971/pond-ts/compare/v0.44.0...HEAD
11
+ [Unreleased]: https://github.com/pjm17971/pond-ts/compare/v0.45.0...HEAD
12
+ [0.45.0]: https://github.com/pjm17971/pond-ts/compare/v0.44.1...v0.45.0
13
+ [0.44.1]: https://github.com/pjm17971/pond-ts/compare/v0.44.0...v0.44.1
12
14
  [0.44.0]: https://github.com/pjm17971/pond-ts/compare/v0.43.0...v0.44.0
13
15
  [0.43.0]: https://github.com/pjm17971/pond-ts/compare/v0.42.0...v0.43.0
14
16
  [0.42.0]: https://github.com/pjm17971/pond-ts/compare/v0.41.0...v0.42.0
@@ -42,6 +44,120 @@ and type-level changes; patch bumps are strictly additive.
42
44
 
43
45
  ## [Unreleased]
44
46
 
47
+ ## [0.45.0] — 2026-07-14
48
+
49
+ ### Added
50
+
51
+ - **charts:** the time axis now walks a **logical tick ladder** — clock/calendar
52
+ units (1s…30s, 1m…30m, 1H…12H, day / week / month / quarter / year), picking
53
+ the finest grain that fits the width-derived cap — and renders **two-tier labels**:
54
+ a first row at the tick grain (`14:00`, `Feb 02`, `Feb`, `2026`) plus a
55
+ **boundary row** carrying the coarser context the first row omits (the date
56
+ under clock ticks, the year under day/week/month ticks — never a unit the
57
+ first row already shows), shown once under
58
+ the first tick of each new period. Hour anchors are generated in **live**
59
+ trading time, so none lands in a collapsed gap, an early close, or a lunch
60
+ break. `TradingTimeScale` gains `tickBoundaries(count)`; a cramped leading
61
+ partial-period anchor (the `"Jun 23Jul 07"` pile-up) is dropped. Systematic
62
+ story matrix under `Charts/TimeAxisTicks`.
63
+ - **financial:** the rest of the first study batch — `rollingStdev`,
64
+ `rollingMin`, `rollingMax`, `rollingPercentile` (linear interpolation),
65
+ `zScore` (rolling), `envelope` (MA ± percent, `maType` sma/ema), and
66
+ `percentChange` (n-bar rate of change). Same shape as the others — `column` /
67
+ `output` (or `prefix`) on every one, bar-count periods, length-preserving
68
+ warm-up — and each has a fluent method (`bars.zScore({ period: 20 })`) and a
69
+ **pandas oracle** case (values cross-validated bar-for-bar). This completes the
70
+ #449 first batch.
71
+ - **financial:** opt-in **fluent studies** via `import '@pond-ts/financial/fluent'`
72
+ — mounts `sma` / `ema` / `bollinger` as chainable `TimeSeries` methods so
73
+ composition reads like the core operators beside it:
74
+ `bars.sma({ period: 20 }).ema({ period: 12 }).bollinger({ period: 20 })`.
75
+ Opt-in by import (the default entry leaves `TimeSeries` untouched, so a
76
+ non-financial series never sees `.sma()`); the methods are exactly the
77
+ standalone functions bound to `this`, fully typed (each appends its column to
78
+ the schema). Same prototype-augmentation pattern core uses for column methods.
79
+ - **financial:** `@pond-ts/financial` gains its first **studies** — `sma`, `ema`,
80
+ and `bollinger` (Bollinger Bands®) — pure functions that append a column (or a
81
+ `${prefix}Middle/Upper/Lower` family) to a bar series. Every study takes a
82
+ `column` source (default `'close'`) and an `output` name, so a study runs over
83
+ any numeric column including another study's output; periods are **bar counts**
84
+ (on core's count window, gap-correct); warm-up rows are `undefined`
85
+ (length-preserving). Plus the `OhlcvColumns` contract + `DEFAULT_OHLCV`. (Core
86
+ `AppendColumn` is now exported so study return types name their appended
87
+ column.)
88
+ - **core:** `smooth(col, 'ema', …)` gains the financial **`span`** rate
89
+ convention (`α = 2/(span+1)`, e.g. `{ span: 12 }` for a 12-period EMA) as an
90
+ alternative to `alpha` (exactly one required), and a length-preserving
91
+ **`minSamples`** warm-up that emits `undefined` for the first `N` present
92
+ values while **keeping the row count** — mirroring `rolling`'s `minSamples`,
93
+ the one warm-up convention studies use so a smoothed line aligns on its
94
+ source's time axis. (The existing `warmup` option is unchanged — it still
95
+ *drops* the head rows; `minSamples` is the length-preserving counterpart.)
96
+ - **core:** `TimeSeries.rolling` accepts a **count-based** window —
97
+ `rolling({ count: N }, mapping, opts?)` reduces the last / next / centered
98
+ `N` _rows_ (bars) by position instead of a time span. Unlike a duration
99
+ window, an N-bar window stays correct across session gaps (weekends,
100
+ overnight) where `N` bars do not equal `N × barSize` of time — the load-
101
+ bearing primitive for financial N-bar studies (SMA-20, Bollinger-20, rolling
102
+ stdev). Honours `alignment` and `minSamples` exactly like a duration window
103
+ (`minSamples: N` gives the conventional first-`N-1`-rows-`undefined` warmup);
104
+ per-row output only (not supported with a sequence). Same amortized-O(1)-per-
105
+ row sweep as the duration path.
106
+ - **charts:** `<LineChart sessionBreaks>` breaks the line at each trading-axis
107
+ discontinuity (a session / day / lunch close→open) instead of connecting the
108
+ prior close straight to the next open across the collapsed gap. For intraday
109
+ data on a `discontinuities` / `calendar` axis this gives the terminal look —
110
+ the line ends at the close and re-starts at the open, so one session's price
111
+ doesn't visually flow into the next. It's a **scale** break (driven by the
112
+ axis's collapsed gaps), orthogonal to `gaps` (a **data** break, a NaN run) —
113
+ set both independently. Default `false`; a no-op on a continuous axis or a
114
+ provider without `boundaries`. New `Charts/TradingTimeAxis/SessionBreaks`
115
+ story (connected vs broken) + `sessionRuns` / `gappingTicks` helpers.
116
+
117
+ ### Changed
118
+
119
+ - **charts:** a **plain continuous time axis** now runs the same ladder as a
120
+ trading-calendar axis (via an internal gap-free identity provider) instead of
121
+ d3's multi-scale default — so a year of daily data ticks cleanly on month
122
+ starts (`Jul Aug … Jun` + the year underneath) rather than mixed
123
+ `"Jun 23" / "Sep" / "Dec"` labels, and its tick count is now width-derived
124
+ like the trading axis's. Month/quarter-grain anchor labels are now bare
125
+ months (`Feb`, was `Feb 02`) with the year on the boundary row;
126
+ `coarsenCalendar`'s finest granularity is renamed `'session'` → `'day'`.
127
+
128
+ ### Fixed
129
+
130
+ - **core:** `TimeSeries.withColumn` now appends an **optional** column
131
+ (`required: false`) rather than a required one. It already accepted
132
+ `(number | undefined)[]`, but marking the column required meant a later
133
+ strict-intake rebuild (`smooth`, any row reconstruction) threw on the gaps —
134
+ so a column with a warm-up (a rolling study fed into an EMA, e.g.
135
+ `ema(sma(bars, …), …)`) crashed. The appended column's type is now
136
+ `number | undefined`, matching `smooth`'s optional append. (`OptionalNumberColumn`
137
+ is exported for the widened return type.)
138
+
139
+ ## [0.44.1] — 2026-07-13
140
+
141
+ A `@pond-ts/charts` patch: fixes trading-time axis tick density. `pond-ts`,
142
+ `@pond-ts/react`, `@pond-ts/fit`, and `@pond-ts/financial` carry no code
143
+ changes — republished in lock-step; their `^0.44.0` peer ranges already
144
+ admit this patch.
145
+
146
+ ### Fixed
147
+
148
+ - **charts:** trading-time axis tick density now derives from plot width
149
+ instead of a fixed count of 5. The trading scale's tick `count` caps how many
150
+ calendar buckets `coarsenCalendar` may keep, so the fixed count coarsened any
151
+ ≳6-month daily view to quarter or year grain — a 1-year daily chart on a
152
+ ~900px plot showed 2 ticks; it now lands on month grain (~12). Continuous
153
+ (non-trading) time and value axes keep the fixed default, unchanged. The
154
+ count is shared through the container frame (`xTickCount`), so axis labels,
155
+ x gridlines, session dividers, and the cursor-time formatter all derive from
156
+ the same instants — previously the label formatter anchored at the scale's
157
+ internal default (10) while ticks used 5, which is why sparse year-grain
158
+ ticks were labelled with dates (`Jun 22`) instead of years. (Tidal friction
159
+ report, charts 0.44.)
160
+
45
161
  ## [0.44.0] — 2026-07-11
46
162
 
47
163
  The **value-axis charts** release: cross-sectional data (a volatility smile keyed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pond-ts/react",
3
- "version": "0.44.0",
3
+ "version": "0.45.0",
4
4
  "description": "React hooks for pond-ts live time series",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -33,7 +33,7 @@
33
33
  "test:runtime": "vitest run"
34
34
  },
35
35
  "peerDependencies": {
36
- "pond-ts": "^0.44.0",
36
+ "pond-ts": "^0.45.0",
37
37
  "react": "^18.0.0 || ^19.0.0"
38
38
  },
39
39
  "devDependencies": {