Worked Example: AI Trend Detector
How the published AI Trend Detector turns causal market features into a live Bear / Neutral / Bull classifier, then converts model output into an oscillator, adaptive cloud, confidence, and confirmed signals.
Goal and outputs
The model estimates current market pressure across three classes: Bear, Neutral, and Bull. NeuraLib powers the decision layer; ordinary Pine plotting turns those probabilities into a readable indicator.
Open the published AI Trend Detector on TradingView to see the model and visual system running on a live chart.
| Output | Meaning |
|---|---|
| Trend Oscillator | A 0–100 pressure gauge: low suggests bullish/oversold pressure, high suggests bearish/overbought pressure. |
| Adaptive MA Cloud | An adaptive baseline with a visual cloud widened by model pressure. The shifted edge is not a training feature. |
| Confirmed Triangles | Optional overbought/oversold interactions for zone entry, zone exit, or confirmed rotation. |
| Dashboard | Current state, signal value, and confidence. |
| Directional Confidence | The stronger of Bull or Bear probability, excluding Neutral probability. |
| Alerts | Confirmed alert conditions tied to the same triangle logic drawn on the chart. |
Features: three per bar
Each bar contributes percent return, a Kaufman-style adaptive moving-average value, and percent distance from price to that baseline. Thirty consecutive rows form one state window, producing 30 × 3 = 90 input values.
Labels only after the future resolves
The classifier uses a fixed eight-bar horizon. Once those eight bars have completed, the script measures the realized move, normalizes it by local volatility, and assigns one-hot Bear [1,0,0], Neutral [0,1,0], or Bull [0,0,1].
- The feature row belongs to the past anchor bar.
- The label is created only after the horizon has elapsed.
- No future value enters the original feature row.
- Rows are pushed only on confirmed bars.
RollingDataset with z-score scaling
var nl.RollingDataset dataset = nl.rollingDataset(
sequenceLength,
featureCount,
CLASS_COUNT,
datasetRows,
"trend_detector_rows")
dataset := dataset
.setInputScaler(nl.ScalerKind.zScore)
.setTargetScaler(nl.ScalerKind.none)Inputs are z-scored column by column, helping the same feature design behave across instruments with very different price levels. One-hot class targets remain unscaled.
Temporal classifier architecture
model := nl.sequential("trend_detector_nn")
.input(array.from(modelInputCount), "state_window")
model := model
.temporalConvStack(sequenceLength, featureCount, temporalFilters,
temporalKernel, temporalLayers, 1, nl.ActivationKind.relu,
dropoutRate, "temporal")
.globalAvgPool1d(temporalStepsOut, temporalFilters, "temporal_avg")
.dense(hiddenUnitsInput, nl.ActivationKind.relu, "detector_1")
.dense(CLASS_COUNT, nl.ActivationKind.linear, "trend_logits")
.build(nl.rng(seedInput))
.compile(cfg)- The temporal convolution stack extracts short sequence patterns.
- Global average pooling compresses time into a compact state vector.
- A dense hidden layer transforms the pooled representation.
- Three linear logits represent Bear, Neutral, and Bull.
The compile configuration uses softmax cross entropy from logits, categorical accuracy, AdamW, and norm clipping for stable three-class learning.
Controlled training cadence
The model permits history-wide calls but applies explicit gates: confirmed bars only, every N bars, and only within a bounded recent historical window. The dataset can continue collecting outside the training region.
This separates data availability from compute budget: resolved examples accumulate chronologically, while expensive updates occur at a controlled stride.
Inference and visual translation
Every bar, the current state window is built, scaled through dataset.scaleInput(), and passed to model.predict(). Temperature-controlled softmax converts logits to class probabilities.
- The oscillator inverts probability pressure for intuitive overbought/oversold reading.
- The adaptive cloud is a visual projection around the MA baseline.
- Confidence uses the stronger directional class rather than total certainty.
- Display smoothing uses current and past values only.
Confirmed signal timing
Triangle modes
| Mode | Trigger |
|---|---|
| Crossing into | Oscillator crosses into an overbought or oversold zone. |
| Going out of | Oscillator exits a zone. |
| Rotation inside zone | A peak or trough survives the configured confirmation window while still inside the zone. |
Rotation markers print on the confirmation bar, not retroactively on the older pivot. Triangle signals are gated by barstate.isconfirmed, and the script uses no negative offsets to move signals into history.
Reload behavior and adaptive state
The model estimates directional pressure. It does not know entries, exits, fees, slippage, position sizing, or risk tolerance. Treat it as one research component rather than a complete trading system.