QuanTAlib is platform-agnostic. Any .NET environment that can reference a DLL can use it. The complexity lies not in the library but in understanding each platform's quirks.
## Quantower
Quantower accepts custom indicators written in C#. Integration follows a wrapper pattern.
### Setup
1. Build QuanTAlib or grab the NuGet package
2. Add reference to `QuanTAlib.dll` in the Quantower indicator project
3. Create wrapper class inheriting from `Indicator`
**UpdateReason matters.** Quantower calls `OnUpdate` for both new bars and intra-bar ticks. The `args.Reason` check determines `isNew` flag behavior. Getting this wrong causes state corruption that manifests as mysteriously wrong indicator values.
**Historical data loads first.** Quantower calls `OnUpdate` repeatedly during historical load before live data arrives. The indicator warms up during this phase.
**Calculate mode affects isNew logic.** With `Calculate.OnBarClose`, every `OnBarUpdate` call represents a completed bar. With `Calculate.OnEachTick`, only the first tick of each bar should use `isNew = true`. Mixing these concepts produces indicators that work in backtest but fail live.
**Historical vs real-time.** NinjaTrader processes historical bars differently from real-time bars. The `State` property indicates the current phase. Indicator warmup should complete during historical processing.
## QuantConnect (LEAN)
LEAN supports custom libraries through NuGet integration.
**Decimal to double conversion.** LEAN uses `decimal` for prices; QuanTAlib uses `double`. Cast on input, cast back on output if needed. The precision difference rarely matters for indicator calculations.
**Resolution affects bar timing.** Daily bars have different `EndTime` semantics than minute bars. UTC timestamps prevent timezone confusion.
## Custom Platform Integration
For proprietary trading engines, Streaming Mode fits most use cases.
### Integration Checklist
| Consideration | Requirement | Consequence of Ignoring |
The `isNew` flag determines whether `Update()` advances to the next bar or corrects the current one. Correct implementation depends on data source semantics:
| Data Source Type | isNew = true When | isNew = false When |
| Bar-based feed | New bar arrives | Never (each bar final) |
| Tick-based, bar aggregation | First tick after bar close | Subsequent ticks within bar |
| Streaming with corrections | Timestamp advances | Same timestamp, updated price |
**Testing approach:** Feed identical data through the indicator in streaming mode (tick by tick with correct `isNew` flags) and batch mode (complete series at once). Compare final values. Mismatch indicates `isNew` flag logic error.