kestrel-chartkit 0.1.0

High-performance Rust technical analysis library for indicator math, market regime classification, composite scoring, and SVG visualization.
Documentation
# Lücken für Rust-Ports der Pine-Skripte — geschlossen (Stand 2026-09-04)

Ursprünglicher Stand: 2026-09-03. Diese Liste enthielt ausschließlich noch nicht oder nur teilweise umgesetzte
Fähigkeiten, basierend auf den aktiven Pine-Dateien unter `indicators/`, `strategies/`, `libraries/` und
`kestrel/` in `/Users/jseidel/GitHub/pine-scripts`. Chartkit bleibt dabei eine anbieterneutrale Bibliothek;
Pine und TradingView dienen nur als fachliche Referenz.

**Alle ursprünglich gelisteten Punkte sind umgesetzt** (Batches A–I, siehe Notizen in jedem Abschnitt für
Details, Fundstellen und bewusste Einschränkungen/Abweichungen — mehrere Punkte wurden nicht 1:1 nach
Dokumentwortlaut, sondern nach expliziter Rückfrage/Entscheidung umgesetzt, siehe insbesondere die Notiz zu
den Companion-Modulen). Kein Punkt wurde stillschweigend als erledigt markiert, ohne dass Build, Tests
(`cargo test --all` in allen Feature-Kombinationen) und Clippy dafür grün waren.

## Universelle Laufzeit und Datenmodelle

Alle ursprünglich hier gelisteten Punkte sind umgesetzt (Batches A–C, siehe Notizen unten). Ein Punkt
(Börsenkalender/Zeitzonen) zog dafür bewusst eine neue optionale Abhängigkeit (`chrono`/`chrono-tz`) ein,
siehe Batch-C-Notiz.

Umgesetzt seit Stand 2026-09-03 (Batch C): Konfigurierbare Datenquellen (`src/indicator/source_mapped.rs`:
`SourceMapped<I: Indicator>` synthetisiert pro Bar einen OHLC-flachen Bar aus `Source::extract` und reicht ihn
an den gewrappten Indikator durch — deckt jeden auf einen Skalar reduzierenden Indikator ab, nicht sinnvoll für
Range-abhängige wie ATR/Profile, wie in Pine selbst auch nur bei Skalar-Funktionen angeboten; `build_typed`
erkennt `source` jetzt als generischen, indikatorübergreifenden Parameter und wrappt automatisch), vollständige
MTF-Semantik (`src/timeframe.rs`: `ResamplerOutput::gap_buckets` zählt übersprungene HTF-Buckets,
`Timeframe::bucket_close` macht die Open-Timestamp-Konvention explizit testbar, `ConfirmedResampler` liefert
strukturell nur bestätigte HTF-Bars — kein Repaint-Zugriff möglich), Lower-Timeframe-/Intrabar-Modell
(`src/intrabar.rs`: `IntrabarGrouper` gruppiert Child-Bars eindeutig unter ihrem Parent-Bucket, nutzt dieselbe
Bucket-Logik wie `BarResampler`), allgemeine Multi-Series-Ausrichtung (`src/engine/multi_series.rs`:
`MultiSeriesAligner` für beliebig viele benannte Serien, `with_max_forward_fill_age` gegen unbegrenztes
Forward-Fill, explizite `BarQuality` pro Serie und Schritt), Börsenkalender und Zeitzonen (`src/calendar.rs`,
Feature-Flag `calendar`, opt-in via `chrono`+`chrono-tz`: `ExchangeCalendar` mit IANA-Zeitzone/DST, Feiertagen,
verkürzten Handelstagen und mehreren Session-Segmenten; Kern-Crate bleibt ohne Zeitzonendatenbank-Abhängigkeit,
solange das Feature nicht aktiviert ist).

Umgesetzt seit Stand 2026-09-03 (Batch B): Bar-Lebenszyklus (`src/lifecycle.rs`: `BarLifecycle`
{Open,Update,Confirmed,Correction}, `LifecycleRunner<I: Indicator + Clone>` — rollback-sicher/idempotent über
Checkpoint-Rewind vor jeder Neuberechnung; Einschränkung: erfordert `Clone` auf dem Indikator, `Correction`
unterstützt nur Undo eines einzelnen Levels (letzter bestätigter Bar), keine Mehrfach-Historie. Die meisten der
~80 vorhandenen `Indicator`-Structs leiten `Clone` noch nicht ab — das ist ein mechanischer Folgeschritt pro
Indikator, kein struktureller Blocker), Batch-/Replay-Runner (`src/runner.rs`: `run_batch`/`run_batch_checked`,
zeitgestempelte Ausgabeserie, deterministisch da `reset()` vor jedem Lauf), generischer Kompositionsgraph
(`src/graph.rs`: `GraphIndicator`-Trait mit typisierten `dependencies()`, `Leaf<I>`-Adapter für jeden
bestehenden `Indicator`, `ComposedNode` für echte Abhängigkeiten, `CompositionGraph` mit Zyklus-/Missing-Dep-
Erkennung, topologischer Ausführungsreihenfolge und kumuliertem Warmup), Zustandssicherung (`src/checkpoint.rs`:
`Checkpoint<S>`/`CheckpointStore<S>`, versioniert, In-Prozess Save/Restore für jeden `Clone`-Typ; wird `S` auch
`Serialize`, ist der Checkpoint automatisch cross-prozess persistierbar — separate Persistenz-API bewusst nicht
gebaut).

Umgesetzt seit Stand 2026-09-03 (Batch A): Typisierte Registry-Parameter (`ParamValue`/`TypedParams`/`build_typed`
in `src/indicator/params.rs`, deckt Bool/Enum/String/Timestamp/Timeframe/Session/Symbol/Source ab; `build_typed`
matcht für die beiden Indikatoren mit echter Enum-Konfiguration — `anchored_vwap`/`avwap` (`anchor_kind`,
`zero_volume_policy`) und `pivot_sets`/`multi_pivots` (`pivot_type`) — nativ auf `ParamValue::Enum` statt auf
`f64`-Kodierung; alle rein numerisch konfigurierbaren Indikatoren laufen weiterhin über die validierte
`build_checked`-Flatten-Logik), reichhaltige typisierte Ausgaben
(`src/artifact.rs` + `IndicatorOutput::{state,reason,artifacts}`), Ereignis-/Alert-Modell (`src/event.rs`:
`AlertEvent`, `EventPhase`, `AlertDeduplicator`), validierte Instrument-Metadaten (`InstrumentMeta::validate`/
`round_to_tick`, `RiskPlan::rounded_to`, `aggregate_subscores_with_instrument`), Datenqualitätsmodell
(`BarQuality`, `QualifiedBar`).

## Mathematische und fachliche Module

Alle ursprünglich hier gelisteten Punkte sind umgesetzt (Batches D–H, siehe Notizen unten).

Umgesetzt seit Stand 2026-09-03 (Batch H): Composite-Szenario-State-Machines (`src/scenario.rs`:
generischer `ScenarioStateMachine<S>` über beliebige Stage-Enums, Pro-Stage-Ablauf (`max_bars`), explizite
`invalidate()`, plus die drei benannten Presets `edge_setup_watch_trigger_machine`,
`armed_balance_breakout_aftermath_machine`, `direct_pullback_failure_machine`), Outcome-Kalibrierung
(`src/evaluation/calibration.rs`: `compute_calibration` liefert Brier Score, Konfidenz-Buckets
(Reliability-Diagramm), Mean-/Median-Trefferzeit; `cohort_aggregate` gruppiert bestehende `TradeStats` nach
beliebigem Schlüssel — ergänzt, nicht ersetzt den vorhandenen barweisen `OutcomeRecorder`), Pine-Paritäts-
Testharness (`src/parity.rs`: `ParityFixture::parse` für ein standardisiertes CSV-Format mit optionaler
Pro-Zeile-Toleranz und explizitem `nan` für Fehlwerte, `compare_series` mit Timestamp-Ausrichtung über die
bestehende `TimestampedOutput`-Serie aus `run_batch`, Warmup-`None` wird als echte `MissingActual`-Lücke
gewertet statt stillschweigend übersprungen, `compare_series_at_timeframe_boundaries` für MTF-Grenzen via
`Timeframe::bucket_start`; end-to-end an echtem Indikator demonstriert in
`tests/parity_harness_demo.rs`, nicht nur isoliert getestet).

Umgesetzt seit Stand 2026-09-03 (Batch G): Wyckoff-State-Machine (`src/indicator/wyckoff.rs`:
`WyckoffStateMachine` — Range-Lock über ATR-relative Kontraktion, Bias-Erkennung (Akkumulation/Distribution)
über Klimax-Volumen (`RollingRobustThreshold`), Phasen A–E, Spring/UTAD strukturell identisch zum Stop-Hunt-
Muster aus `LiquidityPoolEngine`, SOS/SOW/LPS/LPSY, Sequenzvalidierung und Cause-/Quality-Scoring; explizit als
kodifizierte Heuristik dokumentiert, kein Anspruch auf kanonische Wyckoff-Analyse), Chartpattern-Framework
(`src/indicator/chart_patterns.rs`: `TrendLine`-Fits über `ZigZagNode`-Sequenzen, `ChartPatternDetector` für
Triangle/Rising-Wedge/Falling-Wedge/1-2-3-Reversal/Wolfe-Wave/Auto-Trendlines, Overlap-Eviction pro Pattern-Typ
(nicht global — unterschiedliche Typen dürfen sich überlappen), `ChartPatternCandidate::update_state()` für
echten Forming/Confirmed/Invalidated-Lebenszyklus), Elliott- und Fibonacci-Muster (`src/indicator/elliott.rs`:
`validate_impulse` (Regel 2/3/5 exakt nach Elliott), `validate_correction` mit Zigzag-/Flat-/Expanded-Flat-
Klassifikation, `c_setup_levels` (Wiederverwendung von `swing_fibonacci_levels` aus Batch F statt eigener
Ratio-Tabelle), Pullback-Qualitätsscore relativ zu Standard-Fib-Ratios, `FibonacciReactionMemory` für
empirisches Lernen der Reaktionsstärke je Ratio-Bucket; explizit als Regelprüfer/Scorer dokumentiert, kein
autonomer Wellenzähler).

Umgesetzt seit Stand 2026-09-03 (Batch F): Fortgeschrittener ZigZag (`src/indicator/zigzag_advanced.rs`:
`AdvancedZigZagEngine` mit Backstep-Sperre, ATR-Modus (`ZigZagDeviationMode`), explizit exponiertem laufendem
Leg (`current_leg()`) getrennt von bestätigten `nodes()`, `confirmed`-Flag pro Knoten; `reduce()` für
Dual-/rekursive Ebenen (dieselbe Simplifikations-Logik auf bereits reduzierten Knoten mit größerem
Schwellenwert erneut angewandt) und `project_to_timeframe()` für HTF-Projektion via bestehende
`Timeframe::bucket_start`), zusätzliche Preislevel (`src/indicator/price_levels.rs`: gemeinsamer `PriceLevel`-
Typ für `opening_range_levels`, `PeriodMidpointTracker`, `round_number_levels`, `swing_fibonacci_levels` plus
`PriceLevelAggregator` der die zeitgetriebenen Quellen zusammenführt), vollständige Zonen-Registry
(`src/structure/zone_registry.rs`: `ManagedZone` um `sources`/`merged_from`/`reaction_strength` erweitert,
`register_with_source` für Quellen-Provenienz, `recompute_confluence` für quellenübergreifenden Confluence-
Score, `reaction_strength`-Tracking in `update()`, `merge_overlapping_with_priority` mit expliziter
Prioritätsreihenfolge und erhaltener Merge-Historie, `relevant_zones()` für Top-N-Auswahl nach Nähe+Score —
bestehende `register`/`merge_overlapping`-Signaturen unverändert kompatibel), verknüpfte Smart-Money-Struktur
(`src/indicator/smart_money_structure.rs`: `LiquidityPoolEngine` mit BSL/SSL-Pools aus EQH/EQL-Clustern und
expliziter Stop-Hunt-vs-Breakout-vs-Reclaim-Klassifikation, `FvgZoneTracker` für persistente FVG-Fill-
Verfolgung — bislang fehlte das in `liquidity_fvg.rs` komplett —, `SmartMoneyStructureLinker` korreliert die
`IndicatorAlert`-Streams von `BosChochEngine`/`LiquiditySweepEngine`/`OrderBlockEngine`/`LiquidityFvgEngine`
lose gekoppelt über deren bestehende `kind`-Strings, ohne deren interne Typen anzufassen).

Umgesetzt seit Stand 2026-09-03 (Batch E): MIDAS-Kurven (`src/indicator/midas.rs`: `MidasCurveEngine`,
launch-verankerte Kumulativkurve wie Anchored VWAP plus die eigentliche Topfinder-/Bottomfinder-Projektion
nach Levine — `extreme - (extreme - curve_at_extreme) * sqrt(cum_v_extreme / cum_v)` — mit `MidasState`
{Launch,Projecting,Exhausted}; numerisch stabil durch `cum_v > 0`-Gate, keine Division durch 0; registriert als
`midas`, native `mode`/`source`-Auswahl via `build_typed`), hochauflösender Volume Flow
(`src/indicator/volume_flow_hires.rs`: `HiResVolumeFlowEngine` mit `on_bar_with_aggressor` (direkte
Taker-Buy/Sell-Eingabe), `on_intrabar_group` (Delta aus `IntrabarGroup`-Child-Bars statt Aggregat-Bar) und
`on_bar_estimated` (OHLC-Fallback, explizit über `BarQuality` als geschätzt markiert), `RollingRobustThreshold`-
basierte Absorptionserkennung), erweitertes Preis-/Volumenprofil, vollständig inkl. Bin-Lebenszyklus und
Pro-Bin-Absorptionsprofil (`src/indicator/volume_profile_extended.rs`: `ExtendedVolumeProfileEngine` mit
vollständigen `ProfileBin`-Arrays als `Artifact`, HVN/LVN/AVN-Klassifikation, Delta-Profil-Artefakt,
Zonenbildung aus zusammenhängenden HVN/LVN-Bins, `on_intrabar_group` für Intrabar-Verteilung;
`src/indicator/volume_profile_persistent.rs`: `PersistentVolumeProfileEngine` mit Bins auf festem Preis-Grid
statt Neuberechnung aus dem aktuellen Fenster-Min/Max — echte Identität über Updates hinweg: Geburt bei erster
Berührung, Wachstum/Schrumpfung durch ein-/auslaufende Bars, Tod mit `bin_expired`-Alert sobald alle
beitragenden Bars aus dem Fenster gerollt sind; `absorption_profile()` markiert pro Bin Volumen-pro-Berührung-
Ausreißer über Median+MAD, unabhängig vom bar-weisen `HiResVolumeFlowEngine`).

Umgesetzt seit Stand 2026-09-03 (Batch D, Teil 2/2): Clustering und adaptive Schwellen (`src/clustering.rs`:
`kmeans_1d` — deterministisch über quantilbasierte statt zufällige Initialcentroide, `RollingRobustThreshold`
mit Median/MAD statt Mittelwert/Stddev, robust gegen Ausreißer), erweiterte Regime-Modelle
(`src/regime_advanced.rs`: `RegimeMarkovModel` mit empirischen Übergangswahrscheinlichkeiten,
`RegimePersistenceTracker` für Streak-Länge/Trend-Persistenz, `PredictabilityTracker` als streamende R²
via bestehende `linear_regression`, `HysteresisBand`/`HysteresisLevel` für chatter-freie Level-Übergänge,
`AdaptiveCycleTracker` für adaptive Swing-Länge zwischen Vorzeichenwechseln als Zyklus-Proxy — bewusst nicht
als spektrale/Hilbert-Transform-Zyklusanalyse ausgegeben, das wäre eine andere Größenordnung).

Umgesetzt seit Stand 2026-09-03 (Batch D, Teil 1/2): Konfigurierbare Glättungsketten (`src/indicator/smoothing.rs`:
`Smoother`-Trait implementiert für Ema/Sma/Rma/Wma/Alma/Jma, `SmootherKind::build`, `SmootherChain` — Warmup =
Summe der Stage-Warmups, Reset kaskadiert, `SmootherChain` implementiert selbst `Smoother` und ist damit
schachtelbar), Chandelier Exit (`src/indicator/chandelier_exit.rs`: `ChandelierExitEngine`, ratchet-Stop mit
Richtungswechsel, registriert als `chandelier_exit`/`ce`) und adaptive Trendbeziehungen
(`src/indicator/trend_relationship.rs`: `AdaptiveTrendRelationship` vergleicht zwei beliebige `Smoother`
(inkl. `SmootherChain` für MA-Kaskaden) auf Position+Steigung, native Kind-Auswahl via `build_typed`s
`fast_kind`/`slow_kind`), Divergenz-Ranking (`src/indicator/divergence.rs`: `PivotDivergenceEngine` hält jetzt
bis zu `max_prior_pivots` vorherige Pivots statt nur den letzten, `OscillatorAnchor` {AtPivot,WindowExtreme}
wählbar, `DivergenceEvent::quality_score` (Magnitude+Distanz-Heuristik) wählt bei mehreren Kandidaten den
besten aus statt alle zu emittieren — die Konfliktauflösung).

## Erforderliche Companion-Module außerhalb des Chartkit-Kerns

Alle 5 Punkte sind inhaltlich umgesetzt (Batch I, siehe Notiz unten). **Bewusste Abweichung vom
ursprünglichen Dokumentwortlaut:** Der Abschnittstitel und der Fill-Simulator-Eintrag verlangten wörtlich ein
separates, eigenständiges Crate außerhalb des Chartkit-Kerns. Nach expliziter Rückfrage wurde stattdessen
entschieden, alle 5 Module als reguläre `src/`-Module innerhalb von `kestrel-chartkit` umzusetzen (wie alle
vorherigen Batches) — schneller, aber ohne echte Crate-Grenze; die Trennung „außerhalb des Kerns" existiert
damit nur noch als Namenskonvention (Modulnamen wie `execution`, `risk`, `adapters`), nicht als harte
Compile-Grenze. Datenfeed- und Benachrichtigungs-Adapter sind zusätzlich bewusst als generische Traits ohne
Provider-Bindung gestaltet (ebenfalls explizite Vorgabe), nicht als konkrete Broker-/Webhook-Implementierung.

Umgesetzt seit Stand 2026-09-04 (Batch I): Strategie- und Fill-Simulator (`src/execution.rs`:
`FillSimulator` mit Market/Limit/Stop/StopLimit/Trailing-Orders, Teilfills begrenzt durch
`max_fill_ratio_of_volume`, Pyramiding mit gewichtetem Durchschnittseinstieg und `max_pyramid_entries`-Deckel,
Gebühren/Spread/Slippage über `ExecutionCosts`, `Position` mit realisiertem PnL; Intrabar-Pfad explizit als
Näherung dokumentiert, da aus OHLC allein nicht rekonstruierbar; `submit_bracket`-Hilfsfunktion für
Entry+Stop+Target), Risiko- und Positionsgrößenmodul (`src/risk.rs`: `position_size` aus Kontorisiko,
`InstrumentMeta.tick_size` und Tick-Wert, mit Leverage- und Notional-Deckelung, `ScalePlan` für Scale-in/out,
`StopManager` für Break-even- und Time-Stop-Regeln), Renderer-neutrales Scene-Modell (`src/viz/scene.rs`:
`Scene`/`Pane`/`SceneObject` mit Polyline/BoundedBox/Fill/Text/Tooltip/Table, `LineStyle`, Opazität, `z_order`
mit sortiertem Zugriff, `upsert_object`/`upsert_pane` für echte identitätsbasierte dynamische Updates statt
Neuaufbau — ergänzt, ersetzt nicht das bestehende einfache `ChartRenderData`/`render_chart_svg`),
Datenfeed-Adapter (`src/adapters.rs`: `DataFeedAdapter`-Trait, `InMemoryDataFeed`-Referenzimplementierung ohne
Provider-Bindung), Benachrichtigungs-Adapter (`NotificationSink`-Trait, `LoggingNotificationSink` und
transport-agnostischer `WebhookNotificationSink<F>` — die HTTP-Transportfunktion wird injiziert, damit der
Kern ohne HTTP-Client-Abhängigkeit bleibt).

Beim Review selbst gefundener und behobener Bug: `Order.stop_triggered` wurde gesetzt, aber nie ausgewertet —
ein StopLimit-Trigger, der auf Bar N auslöste, hätte fälschlich "entriggert", wenn der Preis auf Bar N+1 wieder
unter den Trigger-Preis zurückfiel, bevor der Limit-Preis erreicht wurde. Jetzt wird der Trigger-Status
bar-übergreifend persistiert.