Releases: acpuchades/fugazi
Release list
v0.83.0
Full Changelog: v0.82.0...v0.83.0
v0.82.0
v0.81.1
Two fixes from downstream reports against 0.81.0. Both change behaviour that previously produced output — read the first two sections before upgrading.
Breaking: --smooth / smooth= refuses a grid with no lattice
Smoothing reads a neighbourhood per subgrid, so an enumerated point list (--grid once per point, or Python grid=[{...}, {...}] of one-point dicts) is N one-point lattices, not one lattice of N points. It used to return each point's raw ranking key unchanged at support 1.0 — the same number a fully interior point reports — so the alarming reading and the reassuring one were identical, and --smooth-min-support could not separate them: any floor in 0..=1 passes 1.0.
A grid where no subgrid sweeps a numeric axis of two or more values (an enumerated point list, an all-categorical grid) is now an error, in the same shape as the existing unmatched --smooth-scale pin refusal. Pass the swept axes as a block. Filtering a Cartesian product down to its legal combinations (FAST < SLOW) is the common way in; pass the block and let the illegal corner score None — a None neighbour already contributes no weight and lowers support.
A grid that mixes the two stays legal.
Breaking: SmoothedKey::support is Option<Real>
A point whose subgrid has no smoothed axis — a lone pinned point stacked beside a swept block — now reports no support rather than the empty product's 1.0, because nothing was measured for it. Its raw key still rides into the smoothed ranking, and a --smooth-min-support above 0 now drops it.
- Rust:
SmoothedKey::supportisOption<Real>. - CSV: the
<metric>_supportcell is written empty. - Python:
row.support/fold.is_supportcan beNone.
panel_axis= substitutes a typed member key
panel_axis= substituted a member's name as a JSON string unconditionally. Correct for a ticker, and it made every typed slot unreachable — !sma { period: !param FAST } was handed "5" and failed to build. That was a divergence between two surfaces for one feature: the CLI's --pooled AXIS reads its members from a --params / --grid entry as typed values, so pooling over a numeric parameter was expressible there and nowhere in Python.
A panel= mapping key now carries its own JSON type through:
ta.optimize(
doc,
panel={f: list(SNAPS) for f in (5, 10, 15)}, # one series, three members
panel_axis="FAST", # reaches `period:` as the number 5
grid=[{"SLOW": [30, 50]}],
best_by="sharpe",
)str keys behave exactly as before; int / float / bool are newly accepted. Nothing is parsed out of the label, so {5: ...} and {"5": ...} are different members and a member genuinely named "5" stays unambiguous. A key of any other type is a TypeError. Note a panel member always carries its own stream, so the parameter case hands the same series over once per member.
Also
- Docs: the
smooth=paragraph ofdocs/PYTHON.mdand--smooth's section indocs/CLI.mdboth state the lattice requirement and the mixed-grid support reading. TODO.mdrecords the rejected alternatives — point-cloud smoothing, a Pythonpooled=axis parameter, parsing the member label.- Regression tests at the kernel, CLI and Python layers, each verified to fail against 0.81.0.
panel=had no Python tests before this release; it has some now.
Thanks to the fugazi-web integration for both reports.