> "Make it work, make it right, make it fast." Kent Beck (QuanTAlib skips straight to fast, assuming you already made it right)
QuanTAlib provides four operating modes. Each mode optimizes for different constraints. Choosing the wrong mode costs either performance or developer sanity. Sometimes both.
## Choosing Your Mode
| Mode | Best For | Allocations | Throughput | Complexity |
**Performance note:** Span mode processes 500,000 bars in approximately 300 microseconds (0.6 ns/bar) for simple indicators like SMA. Complex indicators like JMA take longer but still measure in microseconds.
**What happens internally:** When `isNew = false`, the indicator rolls back its state to before the previous update, then applies the new value. This ensures mid-bar corrections produce the same final result as if only the last value had been seen.
**Gotcha:** Forgetting to set `isNew = false` for corrections causes the indicator to treat each correction as a new bar. The output will be wrong and debugging will be painful.
## Mode 3: Batch (TSeries)
Wraps calculations in `TSeries` objects that manage timestamps and alignment. More convenient than Span mode, slightly less performant.
**When to use:**
- Jupyter-style exploration
- Prototyping trading strategies
- Situations where convenience beats raw speed
- Multi-indicator analysis with automatic alignment
```csharp
usingQuanTAlib;
// Create time series
varprices=newTSeries();
prices.Add(DateTime.UtcNow,100.0);
prices.Add(DateTime.UtcNow.AddMinutes(1),101.5);
prices.Add(DateTime.UtcNow.AddMinutes(2),99.8);
// ... add historical data ...
// Calculate (returns new TSeries aligned with input)
Console.WriteLine($"SMA at index 5: {sma[5].Value:F4}");
// Access as span for downstream processing
ReadOnlySpan<double>values=sma.Values;
```
**Gotcha:** Creating a new indicator with a TSeries computes all historical values immediately. For large datasets, this blocks until complete. For streaming scenarios, use Mode 2 instead.
## Mode 4: Event-Driven (Reactive)
Indicators can subscribe to other indicators or data sources. Changes propagate automatically through the dependency graph.
**When to use:**
- Complex indicator chains
- Reactive architectures
- Systems where manual update ordering is error-prone
**Gotcha:** Event subscriptions create strong references. Forgetting to unsubscribe causes memory leaks. In long-running applications, use weak event patterns or explicitly call `Dispose()` on indicators when done.
## Common Patterns
### Warmup Handling
Every indicator has a warmup period before output becomes meaningful. Check `IsHot` before using values:
Span mode runs 40x faster than streaming for batch operations. Streaming mode remains allocation-free but incurs per-call overhead. Choose based on the actual requirements, not assumptions.
## References
- [API Reference](api.md): Complete method signatures and parameters
- [Architecture](architecture.md): Internal design and memory model