← Library
Pine Script v6 · Strategy · TradingView V1 — EMA Crossover

IRON-SIGHT-V1

EMA Crossover Entry Model with RSI Telemetry and JSON Alert Output

File: iron_sight_v1.pine Type: strategy() — backtestable Capital: $100,000 initial Direction: Long only Pine Version: v6

Overview

IRON-SIGHT-V1 is a baseline trend-following strategy built on a classic dual-EMA crossover. It enters long when the fast 9-period EMA crosses above the slow 21-period EMA, signaling a momentum shift to the upside.

RSI(14) is captured at entry and included in the alert payload as metadata — it is not used as a filter in V1, making this a pure crossover model. The strategy outputs a structured JSON alert message compatible with webhook-based automation pipelines (e.g., NIGHTHAWK).

Role in the Iron Sight System V1 is the foundational entry model. It establishes the alert message schema (JSON with model_id, rsi, ema_gap) that downstream systems consume. V2 extends this architecture with ICT/Smart Money logic.

Indicators Used

Fast EMA
EMA(9)
Plotted in blue. Short-term momentum. Crossing above EMA(21) triggers entry.
Slow EMA
EMA(21)
Plotted in red. Medium-term trend baseline. Acts as the crossover threshold.
RSI (Metadata)
RSI(14)
Not used as an entry filter. Captured at the moment of entry and embedded in the alert JSON for downstream analysis.
EMA Gap (Metadata)
EMA(9) − EMA(21)
Difference between fast and slow EMA at entry. Included in alert payload to quantify momentum strength.

Entry Logic

EMA(9) crosses
above EMA(21)
Build JSON
alert message
strategy.entry
"Long"
ConditionLogicNotes
Long Entry ta.crossover(EMA9, EMA21) Fires on the bar where the fast EMA crosses above the slow EMA
Short Entry Not defined V1 is long-only; no short conditions exist
Exit Logic Not explicitly defined TradingView default: reversal on opposite crossover or end of backtest
No Explicit Exit — V1 Limitation IRON-SIGHT-V1 does not define strategy.exit() or strategy.close() calls. Positions are closed by TradingView's default behavior (next opposing signal or end of data). For live trading, manual exits or a downstream system must handle position closure.

Alert Message — JSON Payload

When a long entry triggers, the following JSON string is passed as the alert_message parameter of strategy.entry() and delivered as the POST body to NIGHTHAWK:

// Long entry payload — fired by strategy.entry() on EMA crossover { "secret": "tac_com_alpha_9", "model_id": "IRON-SIGHT-V1", "ticker": "NASDAQ:AAPL", "action": "BUY", "price": 187.42, "metadata": { "rsi": 54.3, "ema_gap": 1.2847, "timestamp": 1745000000000 } }
// Manual test payload — fired by alert() from FORCE MANUAL TRIGGER toggle { "secret": "tac_com_alpha_9", "model_id": "IRON-SIGHT-V1", "ticker": "NASDAQ:AAPL", "action": "TEST", "price": 187.42, "metadata": { "rsi": 54.3, "note": "MANUAL_TRIGGER", "timestamp": 1745000000000 } }
FieldTypeDescription
secretstringAuth token. NIGHTHAWK returns 401 Unauthorized if missing or incorrect.
model_idstringMust match the model_id row in the SENTINEL models table exactly.
tickerstringTradingView full symbol ID including exchange prefix (e.g., syminfo.tickerid).
actionstringBUY, SELL, or TEST.
pricefloatClose price at the entry bar (close).
metadata.rsifloatRSI(14) at the moment of entry — logged for downstream analysis, not used as a filter.
metadata.ema_gapfloatEMA(9) minus EMA(21). Positive value confirms bullish momentum width at entry.
metadata.timestampintUnix millisecond timestamp from TradingView's timenow.
Webhook Integration In TradingView, create an alert on this strategy. Set Trigger to Once Per Bar Close and paste your NIGHTHAWK endpoint in the Webhook URL field. The alert condition for production signals should be set to Order fills. For the manual test block, create a separate alert with condition Any alert() function call.

Chart Visuals

ElementColorPurpose
Fast EMA lineBlueEMA(9) — short-term momentum
Slow EMA lineRedEMA(21) — medium-term trend
Crossover pointTradingView default markerLong entry marked automatically by strategy engine

TradingView Setup

  1. Open a chart on your desired instrument and timeframe.
  2. Open the Pine Script Editor (Alt+P), clear existing code, paste iron_sight_v1.pine.
  3. Click Add to chart. The strategy overlay and EMA lines will appear.
  4. Open the Strategy Tester tab (bottom panel) to review backtest results.
  5. To activate alerts: hover over the indicator name → ···Add alert.
  6. Set Trigger to Once Per Bar Close to avoid intra-bar noise.
  7. If using a webhook, paste your endpoint URL in the Webhook URL field.

On-Screen Dashboard

A 5-row table is rendered in the top-right corner of the chart on the final bar (barstate.islast). It gives a real-time read on strategy conditions without opening the Strategy Tester.

RowConditionGreen When
Fast EMA > Slow EMAfastEMA > slowEMAEMA(9) is above EMA(21) — bullish alignment
EMA CrossoverlongConditionThe crossover fired on the most recent bar
RSI > 50rsiValue > 50Momentum is in bullish territory
RSI (live)Text displayLive RSI(14) value — green if > 50
Signal BiasText: LONG / WATCH / WAITLONG (crossover active), WATCH (EMA aligned, no cross), WAIT (bearish)
RSI is Metadata Only in V1 The RSI value shown in the dashboard is for monitoring. It does not gate entries in V1 — a crossover fires regardless of RSI level. This is intentional: V1 is a pure EMA model.

Manual Test Block — FORCE MANUAL TRIGGER

A checkbox input (FORCE MANUAL TRIGGER) appears in the strategy settings. When toggled ON, the script fires a TEST webhook on the current bar's close using alert(test_msg, alert.freq_all).

Two Different Alert Types — Separate TradingView Alerts Required
  • Production signal (strategy.entry(alert_message=...)): Create alert with condition set to Order fills.
  • Manual test (alert()): Create a separate alert with condition set to Any alert() function call.

Toggle FORCE MANUAL TRIGGER ON, wait for the next bar close, and verify NIGHTHAWK returns {"status":"Logged"}. Toggle it back OFF immediately after testing.

Known Limitations / V1 vs V2

FeatureV1 StatusV2 Status
Entry logicEMA(9/21) crossover8AM range + liquidity sweep + IFVG
Short entriesNot implementedImplemented (VANGUARD_SHORT)
Explicit exitsNot definedTP/SL via strategy.exit() (SENTINEL)
RSI filterMetadata only (no filter)Not used in V2 either
HTF dataNonePrevious day H/L + 1H highs/lows
Session timingNone (trades all hours)8AM–12PM NY time only
Alert JSONsecret, model_id, ticker, action, price, metadata.rsi, metadata.ema_gapsecret, model_id, ticker, action, price, metadata.tier, metadata.liquidity, metadata.note