# qta — Streaming Technical Analysis Indicators

Published crate: [crates.io/crates/qta](https://crates.io/crates/qta) | [docs.rs/qta](https://docs.rs/qta)
Edition 2024, rust-version 1.85. Consumer: [flowsurface](../../../../fork-tools/flowsurface/) via path dependency.

## Indicators

| Module   | Description                                               | Tests                            |
| -------- | --------------------------------------------------------- | -------------------------------- |
| `zigzag` | Streaming ZigZag swing detection (no-repaint, O(1) state) | 31 unit + 7 proptest + 2 doctest |

## Architecture

Follows **ta-rs** (flat re-exports at root) and **yata** (Config/State separation) patterns.

- `lib.rs` — Re-exports only: `pub use zigzag::{BarInput, ZigZagConfig, ZigZagState, ...}`
- `zigzag/config.rs` — Immutable validated params. `ZigZagConfig::new()` → `Result<Self, ZigZagError>`
- `zigzag/state.rs` — Streaming state machine. `process_bar(&bar)` → `ZigZagOutput`
- `zigzag/types.rs` — Domain types: `BarInput`, `Pivot`, `PivotKind`, `Segment`, `BaseClass`, `ZigZagOutput`
- `zigzag/ctrends.rs` — Post-filter: `filter_ctrends(pivots, config) -> Vec<Pivot>`
- `zigzag/direction.rs` — Internal `pub(crate)` direction tracking
- `zigzag/base_class.rs` — Pivot classification and z-score
- `zigzag/segment.rs` — Rolling window `SegmentStats`

## Key Patterns

- **Prices as fixed-point `i64`** (× 1e8) — never `f64` for prices
- **Config/State separation** — config immutable after construction, state holds runtime values
- **No-repaint guarantee** — once `ConfirmationStatus::Confirmed` is set, the pivot never mutates (enforced by proptest)
- **Serde feature-gated** — `#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]`
- **Threshold formulas:** `δ = price × bar_threshold_dbps / 100_000`, `τ = N × δ`, `ε = E × δ`

## Clippy Config

`deny(all)` + `warn(pedantic)` with specific allows in `Cargo.toml`:

- `doc_markdown` (needed for ZigZag/FixedPoint terms)
- `cast_possible_truncation`, `cast_sign_loss`, `cast_precision_loss` (intentional fixed-point math)

## Adding New Indicators

1. Create `src/<indicator>/mod.rs` with types, config, state
2. Add `pub mod <indicator>;` to `src/lib.rs`
3. Re-export key types at crate root
4. Add property-based tests in `tests/`

## Known Gaps

- `confirmed_pivots: Vec<Pivot>` grows unboundedly (memory concern for long streams)
- `ThresholdMode::DurationWeighted` and `AtrBased` exist but are never consumed
- Only 2 of ~15 public types have doc examples
