diff --git a/nano/library/mean_reversion/bollinger_band_touch.nano b/nano/library/mean_reversion/bollinger_band_touch.nano index 64c45b0..02ccfa7 100644 --- a/nano/library/mean_reversion/bollinger_band_touch.nano +++ b/nano/library/mean_reversion/bollinger_band_touch.nano @@ -1,6 +1,18 @@ // Bollinger lower-band touch. BB_PCT_B = (close - lower) / (upper - lower), // Pine's ta.bb %B, provided by the host data feed. Below 0 = close under // the lower band. +// REGIME: range-bound with stable band width. Do NOT fire in a downtrend or a +// volatility expansion - %B sits below 0 for long runs in a trend, and every +// touch there is a knife-catch. +// CONDITIONS: band width flat or contracting, and the prior swing low still +// holding on the timeframe above. +// INVALIDATION: a second consecutive close below the lower band, or band width +// expanding while price falls. Both mean continuation, not reversion. +// SHAPE: 1h; a wick piercing the lower band that closes back inside it. +// NOT bb_squeeze_breakout: same indicator family, opposite intent. That one +// enters on expansion out of compression; this one needs the range to hold. +// CALIBRATED ON: US large-cap equity ETF, 1h. %B itself is scale-free, but +// "band width is stable" is not - re-derive it for a new instrument class. strategy BollingerBandTouch { every 1h { diff --git a/nano/library/mean_reversion/cci_extreme.nano b/nano/library/mean_reversion/cci_extreme.nano index 74072dc..5f431bb 100644 --- a/nano/library/mean_reversion/cci_extreme.nano +++ b/nano/library/mean_reversion/cci_extreme.nano @@ -1,6 +1,18 @@ // CCI oversold extreme. Pine's ta.cci goes deeply negative when oversold; // the feed provides the negated series: CCI_NEG = -CCI. // CCI_NEG >= 100 is the classic CCI < -100 oversold zone. +// REGIME: range, or a pullback inside a standing uptrend. Do NOT fire in a +// sustained downtrend - CCI pins beyond -100 and stays there for many bars. +// CONDITIONS: a definable range floor, and the higher timeframe not printing +// new lows. +// INVALIDATION: CCI_NEG continuing past roughly 200 (the move is accelerating, +// not exhausting), or a close beneath the range floor. +// SHAPE: 1h; a sharp excursion below recent congestion that snaps back. +// NOT zscore_reversion: both measure distance from a mean, but CCI normalises +// by mean absolute deviation rather than standard deviation, so it reacts +// sooner and fires considerably more often in chop. +// CALIBRATED ON: US tech equity ETF, 1h. The +/-100 convention is standard; +// how often it is actually reached is entirely instrument-dependent. strategy CciExtreme { every 1h { diff --git a/nano/library/mean_reversion/zscore_reversion.nano b/nano/library/mean_reversion/zscore_reversion.nano index 5487345..8a24a6c 100644 --- a/nano/library/mean_reversion/zscore_reversion.nano +++ b/nano/library/mean_reversion/zscore_reversion.nano @@ -1,6 +1,18 @@ // Mean-reversion z-score entry. Nano numbers are non-negative, so the feed // provides the negated series: ZSCORE_NEG = -((close - sma) / stdev). // ZSCORE_NEG >= 2 means price is 2+ standard deviations BELOW the mean. +// REGIME: statistically stationary - a range whose mean is flat. Do NOT fire +// during a trend or a repricing event: once the mean itself moves, distance +// from it stops being information. +// CONDITIONS: the 20-period mean roughly flat, and stdev not expanding. +// INVALIDATION: ZSCORE_NEG holding at or above 2 across several bars, or the +// mean turning down. Both say the distribution moved rather than the price. +// SHAPE: 4h; a visible stretch away from a horizontal mean. +// NOT cci_extreme: the same idea measured more strictly and more slowly, so it +// produces far fewer signals. If both fire, that is one setup, not two. +// CALIBRATED ON: crypto, 4h - continuous trading, no session boundaries, and a +// higher baseline volatility than an index future. On a session-bound +// instrument the 20-period window straddles the overnight gap. strategy ZscoreReversion { every 4h { diff --git a/nano/library/momentum/roc_momentum.nano b/nano/library/momentum/roc_momentum.nano index c95071f..6218b13 100644 --- a/nano/library/momentum/roc_momentum.nano +++ b/nano/library/momentum/roc_momentum.nano @@ -1,5 +1,16 @@ // Rate-of-change momentum (Pine: ta.roc(close, 10) > 5). // ROC = percent change of close over the lookback window. +// REGIME: trend or expansion. Do NOT fire in chop - in a range a 5 percent +// 10-bar move marks the top of the range, so this becomes buy-the-high. +// CONDITIONS: range expanding, higher highs on the timeframe above. +// INVALIDATION: ROC decaying back under the threshold while price stalls +// (momentum exhaustion), or the whole move coming from one spike bar. +// SHAPE: 1h; a sustained directional push, not a single candle. +// NOT macd_histogram_flip: that signals a change of trend, this one signals +// continuation of a trend already running. +// CALIBRATED ON: crypto, 1h. The threshold is the danger here - a 5 percent +// move over 10 bars is an ordinary afternoon for BTC and a limit-move event +// for an index future. Do not carry the number across instrument classes. strategy RocMomentum { every 1h { diff --git a/nano/library/momentum/rsi_oversold_reversal.nano b/nano/library/momentum/rsi_oversold_reversal.nano index c5e2af7..aacc958 100644 --- a/nano/library/momentum/rsi_oversold_reversal.nano +++ b/nano/library/momentum/rsi_oversold_reversal.nano @@ -1,5 +1,19 @@ // Classic RSI oversold reversal (Pine: ta.rsi(close, 14) < 30). // Buy when the 14-period RSI dips below 30. +// REGIME: a pullback inside an uptrend, or a range. Do NOT fire in a sustained +// downtrend - RSI can hold under 30 for dozens of bars while price keeps +// falling, and this is the single most common way the strategy loses. +// CONDITIONS: the higher timeframe trending up or neutral, and a prior support +// level within reach. +// INVALIDATION: RSI making a lower low together with price. Oversold that gets +// more oversold is trend, not exhaustion. +// SHAPE: 15m; a flush into support that turns within a few bars. +// NOT stochastic_oversold: that measures position inside the recent range and +// fires earlier and far more often. NOT volume_spike_confirmation: that is +// this exact RSI condition plus a volume gate, so it is a strict subset - when +// both fire it is one setup, not two. +// CALIBRATED ON: crypto, 15m. RSI is bounded 0-100 so the threshold travels, +// but how long an instrument stays sub-30 does not. strategy RsiOversoldReversal { every 15m { diff --git a/nano/library/momentum/stochastic_oversold.nano b/nano/library/momentum/stochastic_oversold.nano index f2152ff..1661ca5 100644 --- a/nano/library/momentum/stochastic_oversold.nano +++ b/nano/library/momentum/stochastic_oversold.nano @@ -1,6 +1,19 @@ // Stochastic oversold entry (Pine: ta.stoch(close, high, low, 14) < 20). // STOCH_K = %K line of the 14-period stochastic oscillator, provided by // the host data feed. +// REGIME: range. Do NOT fire in a trend - %K pins under 20 for the length of a +// downtrend, and this is the fastest of the oscillators, so it pins first. +// CONDITIONS: a defined support level, and a range wide enough that the low of +// the lookback window is meaningful. +// INVALIDATION: %K flat under 20 across several bars rather than turning up. +// SHAPE: 30m; price probing the bottom of an established range. +// NOT rsi_oversold_reversal: RSI measures average gain against average loss, +// %K measures position within the recent high-low range. %K fires earlier and +// more often, so it is the noisier of the pair. +// NOT williams_r_reversal: that is the same construction inverted. Firing both +// is one idea counted twice. +// CALIBRATED ON: crypto, 30m. The 0-100 bound travels; the dwell time below 20 +// is a property of the instrument. strategy StochasticOversold { every 30m { diff --git a/nano/library/momentum/williams_r_reversal.nano b/nano/library/momentum/williams_r_reversal.nano index a0db3fe..00bd083 100644 --- a/nano/library/momentum/williams_r_reversal.nano +++ b/nano/library/momentum/williams_r_reversal.nano @@ -1,6 +1,18 @@ // Williams %R reversal. Pine's ta.wpr ranges -100..0; Nano numbers are // non-negative, so the feed provides the shifted series: // WILLR_POS = Williams %R + 100 (range 0..100; < 20 means oversold). +// REGIME: range, or a pullback within an uptrend. Do NOT fire in a sustained +// downtrend - like every position-in-range oscillator it pins at the bottom +// and stays there. +// CONDITIONS: a defined range with a floor that has held at least once. +// INVALIDATION: WILLR_POS remaining under 20 while the range floor gives way. +// SHAPE: 1h; a probe of the low of the 14-period range that recovers. +// NOT stochastic_oversold: Williams %R is the inverted stochastic - the same +// measurement of position within the recent range. These two agreeing is a +// single idea counted twice, not confirmation. +// CALIBRATED ON: high-beta crypto, 1h. The 0-100 bound travels; on a slower +// instrument the oscillator reaches 20 far less often, so this will simply go +// quiet rather than misfire. strategy WilliamsRReversal { every 1h { diff --git a/nano/library/risk/max_drawdown_breaker.nano b/nano/library/risk/max_drawdown_breaker.nano index 930ae8e..a4bceef 100644 --- a/nano/library/risk/max_drawdown_breaker.nano +++ b/nano/library/risk/max_drawdown_breaker.nano @@ -1,5 +1,18 @@ // Max-drawdown circuit breaker: when portfolio drawdown reaches 5 percent, // pause all proposals and hand control to the named risk agent. +// REGIME: all of them. This is a control, not a directional hypothesis, and it +// is always applicable. It must never be promoted into an execution slot or +// counted as a setup - it emits PAUSE, never BUY or SELL. +// CONDITIONS: none. It is armed whenever the book is open. +// INVALIDATION: none. A breaker is not a trade and does not get invalidated; +// it is reset by the risk agent, deliberately and outside this strategy. +// SHAPE: 1m, so it reacts within a bar rather than after one. +// NOT atr_volatility_halt: that one halts on market volatility, this one halts +// on realised portfolio loss. They are not redundant - the tape can be calm +// while the book bleeds, and violent while the book is flat. Both should be +// armed, and neither substitutes for the other. +// CALIBRATED ON: nothing instrument-specific. 5 percent is a portfolio-level +// figure and is the one threshold in this library that travels unchanged. strategy MaxDrawdownBreaker { agent RiskDesk diff --git a/nano/library/trend/donchian_breakout.nano b/nano/library/trend/donchian_breakout.nano index b974680..9757e92 100644 --- a/nano/library/trend/donchian_breakout.nano +++ b/nano/library/trend/donchian_breakout.nano @@ -1,6 +1,20 @@ // Donchian channel breakout. DONCHIAN_POS = (close - lower) / (upper - lower) // over the 20-period channel, provided by the host data feed. // A value at or above 1 means close broke the prior 20-period high. +// REGIME: expansion. Do NOT fire in a range - inside a range the 20-period +// high IS the range ceiling, so every touch mean-reverts and this becomes a +// systematic top-buyer. Range versus expansion is the whole decision here. +// CONDITIONS: a prior contraction to break out of, and participation behind +// the break (rising volume or range). +// INVALIDATION: a close back inside the channel. A breakout that does not hold +// is a failed breakout and usually resolves the other way. +// SHAPE: 1d; a clean push through a flat multi-week ceiling. +// NOT bb_squeeze_breakout: that anticipates expansion while still compressed; +// this confirms expansion once it has begun. Sequence, not synonym - if both +// fire, the squeeze fired first and this is its confirmation. +// CALIBRATED ON: crypto, daily. DONCHIAN_POS is scale-free, so the threshold +// travels cleanly; what does not travel is the gap behaviour of a +// session-bound instrument, where the open can clear the channel outright. strategy DonchianBreakout { every 1d { diff --git a/nano/library/trend/golden_cross.nano b/nano/library/trend/golden_cross.nano index 84c3f85..440a451 100644 --- a/nano/library/trend/golden_cross.nano +++ b/nano/library/trend/golden_cross.nano @@ -1,6 +1,21 @@ // Golden cross as a spread signal. Nano cannot compute crosses in-language; // the feed provides SMA_SPREAD = SMA(50) - SMA(200). Positive spread means // the fast average is above the slow one (post-golden-cross regime). +// REGIME: established uptrend. Read this as a REGIME FILTER, not an entry. +// The distinction matters: a positive spread is a persistent state that stays +// true for months, so treating it as a trigger fires it on every single bar of +// a bull market. Use it to permit or veto other setups, not to open a trade. +// CONDITIONS: none beyond the spread itself - that is precisely the problem +// with using it alone. +// INVALIDATION: the spread crossing back through zero, which is a death cross +// and a regime change rather than a stop on a position. +// SHAPE: 1d; the slow pair of averages fanned apart and holding. +// NOT macd_histogram_flip: that is an event on a fast pair and marks a moment; +// this is a state on a slow pair and marks a season. If both are true, only +// the MACD flip carries timing information. +// CALIBRATED ON: US large-cap equity ETF, daily, where the 50/200 pair is the +// convention. On a 24/7 instrument "200 days" spans a different amount of +// price action than it does on a session-bound one. strategy GoldenCross { every 1d { diff --git a/nano/library/trend/macd_histogram_flip.nano b/nano/library/trend/macd_histogram_flip.nano index 63af90f..8310466 100644 --- a/nano/library/trend/macd_histogram_flip.nano +++ b/nano/library/trend/macd_histogram_flip.nano @@ -1,5 +1,19 @@ // MACD histogram flip to positive (Pine: ta.macd histogram > 0). // MACD_HIST = MACD line - signal line, provided by the host data feed. +// REGIME: trend initiation, or resumption after a pullback. Do NOT fire in +// chop - the histogram oscillates around zero in a range, so it flips +// constantly and produces a stream of one-bar signals that mean nothing. +// CONDITIONS: a directional context on the timeframe above; the flip is a +// timing input and needs a trend to be timing into. +// INVALIDATION: the histogram dropping back below zero within a bar or two. +// A flip that does not persist was noise around the zero line. +// SHAPE: 4h; histogram bars crossing from below zero to above and staying. +// NOT golden_cross: that is a persistent state on a slow average pair, this is +// a discrete event on a fast one. NOT roc_momentum: that measures the size of +// a move already underway, this measures a change in its direction. +// CALIBRATED ON: crypto, 4h. The zero crossing is scale-free and travels, but +// flip frequency scales with noise, so a choppier instrument will produce many +// more of these for the same amount of real trend. strategy MacdHistogramFlip { every 4h { diff --git a/nano/library/volatility/atr_volatility_halt.nano b/nano/library/volatility/atr_volatility_halt.nano index 4454d7d..7b35edd 100644 --- a/nano/library/volatility/atr_volatility_halt.nano +++ b/nano/library/volatility/atr_volatility_halt.nano @@ -1,6 +1,23 @@ // ATR circuit breaker. ATR_PCT = ATR(14) / close * 100, provided by the // host data feed. When volatility exceeds 5 percent of price, stop // proposing entries until the regime calms down. +// REGIME: all of them. This is a control, not a directional hypothesis. It is +// always applicable, emits PAUSE rather than BUY or SELL, and must never be +// promoted into an execution slot or counted as a setup. +// CONDITIONS: none. It is armed whenever the feed is live. +// INVALIDATION: none - a breaker is not a trade. It releases when ATR_PCT +// falls back under the threshold. +// SHAPE: 5m, so a volatility spike is caught inside the move rather than after +// it. +// NOT max_drawdown_breaker: that halts on realised portfolio loss, this halts +// on market volatility. Both should be armed; neither substitutes for the +// other, because the tape can be violent while the book is flat. +// CALIBRATED ON: crypto, 5m - and this is the most dangerous threshold in the +// library to transplant. A 5 percent ATR is an ordinary volatile session in +// crypto and a once-in-years event on an index future, whose ATR_PCT normally +// sits well under 1 percent. Carried across unchanged this breaker does not +// misfire, it does something worse: it never fires at all, and the volatility +// brake silently disappears. Re-derive the threshold per instrument class. strategy AtrVolatilityHalt { every 5m { diff --git a/nano/library/volatility/bb_squeeze_breakout.nano b/nano/library/volatility/bb_squeeze_breakout.nano index b77f12a..eeef687 100644 --- a/nano/library/volatility/bb_squeeze_breakout.nano +++ b/nano/library/volatility/bb_squeeze_breakout.nano @@ -1,6 +1,22 @@ // Bollinger squeeze breakout. BB_WIDTH = (upper - lower) / middle * 100 // (band width percent); MOM = close - close[10] momentum. A tight squeeze // with positive momentum anticipates an upside expansion. +// REGIME: contraction, on the edge of expansion. Do NOT fire once expansion is +// already underway - by then the bands are wide, the edge is gone, and the +// entry is late. +// CONDITIONS: band width at the low end of its own recent range, and momentum +// already leaning positive. The squeeze alone is directionless; MOM is what +// picks the side, and it is the weaker half of the pair. +// INVALIDATION: width expanding while price resolves downward. A squeeze +// resolves in some direction, and being early is not the same as being right. +// SHAPE: 1h; bands pinched to a narrow ribbon, price coiled against the top. +// NOT bollinger_band_touch: same indicator, opposite regime - that one needs +// the range to hold, this one is betting it breaks. NOT donchian_breakout: +// this anticipates the expansion, that confirms it after the fact. +// CALIBRATED ON: crypto, 1h. BB_WIDTH < 4 is an absolute percentage and does +// NOT travel - band width percent scales with the instrument's own +// volatility, so on a quieter instrument 4 percent is permanently satisfied +// and the squeeze condition stops discriminating at all. strategy BbSqueezeBreakout { every 1h { diff --git a/nano/library/volume/obv_trend.nano b/nano/library/volume/obv_trend.nano index 9e3cc0a..d5f7860 100644 --- a/nano/library/volume/obv_trend.nano +++ b/nano/library/volume/obv_trend.nano @@ -1,6 +1,21 @@ // On-balance-volume trend confirmation. OBV_SLOPE = linear-regression slope // of OBV over the lookback window, provided by the host data feed. // A positive slope confirms accumulation. +// REGIME: any directional regime. This is a CONFIRMATION input and is weak on +// its own - a positive OBV slope is true through most of any advance, so +// firing it standalone is close to firing on "the market went up". +// CONDITIONS: compose it with a directional trigger and let this gate the +// trigger. It answers "is there participation behind the move", nothing else. +// INVALIDATION: slope flattening or turning negative while price still rises - +// the classic distribution divergence, and the one case where this input is +// genuinely informative on its own. +// SHAPE: 4h; OBV grinding upward underneath a rising price. +// NOT volume_spike_confirmation: that is a single-bar capitulation event, this +// is sustained accumulation across a window. Opposite time scales. +// CALIBRATED ON: crypto, 4h - and volume is the least portable series in this +// library. Crypto volume is per-venue and unaudited; futures volume is +// exchange-consolidated; equity volume fragments across lit and dark venues. +// An OBV slope computed on one is not comparable to the other. strategy ObvTrend { every 4h { diff --git a/nano/library/volume/volume_spike_confirmation.nano b/nano/library/volume/volume_spike_confirmation.nano index d4fb4ed..fc0ea4f 100644 --- a/nano/library/volume/volume_spike_confirmation.nano +++ b/nano/library/volume/volume_spike_confirmation.nano @@ -1,6 +1,22 @@ // Volume-confirmed capitulation buy. VOL_RATIO = volume / SMA(volume, 20), // provided by the host data feed. A 3x volume spike while RSI is oversold // marks a high-conviction reversal candidate. +// REGIME: capitulation or climax, inside a larger range or an uptrend +// pullback. Do NOT fire in an orderly downtrend - steady selling produces +// oversold RSI without the volume climax, and the volume gate is the only +// thing separating this from catching a falling knife. +// CONDITIONS: both halves must hold in the same bar. The volume spike is the +// evidence of exhaustion; the RSI reading alone is not. +// INVALIDATION: the next bar making a new low on equal or greater volume. +// That is continuation on participation, which is the opposite of exhaustion. +// SHAPE: 15m; a high-volume flush candle with a long lower wick. +// NOT rsi_oversold_reversal: this is that exact condition plus a volume gate, +// so it is a strict subset of it. When both fire it is one setup with two +// names, and treating them as two independent confirmations double-counts the +// same evidence. +// CALIBRATED ON: crypto, 15m. RSI 30 travels; the 3x volume ratio does not - +// it depends entirely on the venue's volume profile and on how much of the +// instrument's real volume the feed actually sees. strategy VolumeSpikeConfirmation { every 15m {