shares = acct·5%/(2·ATR), contracts = round(shares/(Δ·100)))DUM545361 — paper-only fallback if Read-Only
| Strategy | Ticker | Dir | Score | Shares | Stock $ | Strike | Expiry | Entry $ | Entry Time | Exit $ | Exit Time | Reason | P&L % | P&L $ | Live P&L | Stop |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| No trades yet | ||||||||||||||||
has_chair OR score≥20: cluster breadth (CEO+CFO+Director+GC) implies
real top-rank conviction even when the chairman label is missing. Recovers 15 historical
trades (11 winners, 73% WR) without raising drawdown.
v8.A.1 targets the archetype: multi-rank C-suite + board buying during deep drawdowns in non-micro-cap stocks, with no 10%-owner involvement. Four filters on the v4 baseline produce 48 high-conviction trades over 5 years. Out-of-sample validated on 2024-26 holdout (TEST WR 69%, comparable to TRAIN WR 77%).
score = 2 × n_insiders
+ 5 if any CEO buying + 4 if any CFO buying
+ 4 if any Chairman/COB + 3 if any President/Pres
+ 2 if any COO + 2 if any Director/Dir
+ 1 if any 10%-owner buying
(v8.A does NOT use score as a hard cutoff — has_chair filter
implicitly captures ~all score-20+ clusters anyway.)
| Train 2021-23: | n=16, WR 68.8%, Sharpe 1.20 |
| Test 2024-26: | n=17, WR 82.4%, Sharpe 1.46 |
| Test/Train Sharpe ratio +1.22 — only deployment candidate where holdout beat training period. | |
python scripts/v8_live_signals.py to populate.| Status | Entry | Exit | Ticker | Score | N | Sector | CapTier | VIX | DD 6mo | Cluster $ | Entry $ | Exit $ | Return | Hold | Reason |
|---|
| Date | Ticker | Score | Roles | Sector | VIX | SPY trend | 60d ret | Trade Ret | Hold | Exit | v4 |
|---|
Goal: leverage v4's high WR (75.9%) and low DD (-22%) to maximize total P&L. Tested 16 variants including margin-style leverage (1x/2x/3x/4x), Kelly-fraction sizing, volatility-targeted sizing, tighter cluster filters (n_insiders>=3 or chairman-required), and options at 5/10/15/25/35/50% sizing with the -50% hard option stop REMOVED (per prior verdict).
| Variant | N | WR | EV/trade | PF | Sharpe | Max DD | Final $ | P&L $ | CAGR |
|---|
Tested 7 ideas: (1) 2x margin × n≥3 combo, (2) wider profit-lock (PL=15%), (3) looser trail (8/10/15/18/20%), (4) ATR-based trail (2.0/2.5/3.0/4.0×ATR14), (5) pyramid retest on v4 cohort, (6) capital rotation (idle equity in SPY), (7) reduced options slippage (skipped — options didn't compete).
| Variant | N | WR | EV | PF | Sharpe | Sortino | Max DD | P&L $ | CAGR |
|---|
Tested 60 combinations of ATR-trail (2.5 / 3.0 / 3.5 / 4.0 × ATR14) × profit-lock (5/10/15/20/25%) × leverage (1x/2x/3x), plus SPY rotation overlay on top variants. Goal: stack ATR-trail and wider profit-lock (the two best single changes) to find the global optimum.
| ATR × | PL 5% | PL 10% | PL 15% | PL 20% | PL 25% |
|---|---|---|---|---|---|
| 2.5× ATR | 18.9% PF 7.5 $494.5K | 19.6% PF 9.3 $638.1K | 21.2% PF 10.4 $986.3K | 21.1% PF 9.9 $949.5K | 22.7% PF 11.0 $1.40M |
| 3.0× ATR | 21.5% PF 9.3 $1.02M | 22.0% PF 10.2 $1.17M | 23.6% PF 11.7 $1.78M | 23.6% PF 11.8 $1.78M | 23.6% PF 11.8 $1.80M |
| 3.5× ATR | 21.2% PF 8.6 $979.7K | 21.8% PF 10.1 $1.17M | 23.5% PF 12.1 $1.85M | 23.7% PF 12.9 $1.92M | ⭐23.8% PF 13.0 $2.02M |
| 4.0× ATR | 20.6% PF 8.4 $882.4K | 21.2% PF 10.0 $1.07M | 22.6% PF 12.5 $1.56M | 22.6% PF 12.5 $1.56M | 22.6% PF 12.5 $1.56M |
Cell shows EV per trade · PF · Total P&L (compounded $10K, 1x leverage). Brighter green = higher EV. ⭐ = winner.
| Variant | N | WR | EV | PF | Sharpe | Sortino | Max DD | P&L | CAGR |
|---|
Same parameters (ATR-trail 3.5×ATR14 + Profit-Lock 25% + 2x margin + SPY rotation) tested on extended 10-year data (2016-2026, including 2018 correction, COVID 2020, and 2022 bear). Every metric is slightly better on 10y than 5y, with the same -45.8% max drawdown. The combo's parameters are robust across regimes — not over-fit to 2021-2026.
| Metric | 5y (2021-2026) | 10y (2016-2026) | Δ | Verdict |
|---|---|---|---|---|
| n trades | 29 | 30 | +1 | nearly identical signal frequency in extended period |
| Win rate | 79.3% | 80.0% | +0.7 pp | ↑ improved |
| Per-trade EV | 23.85% | 24.04% | +0.19 pp | ↑ improved |
| Profit factor | 13.03 | 13.55 | +0.51 | ↑ improved |
| Sharpe (ann) | 1.42 | 1.46 | +0.04 | ↑ improved |
| Sortino (ann) | 5.93 | 5.98 | +0.05 | ↑ improved |
| Max DD curve | -45.8% | -45.8% | ±0.0 pp | = unchanged ⭐ regime-robust |
| Final equity ($10K start) | $54.49M | $127.24M | +$72.75M | 2.34× more $ |
| Total P&L | $54.48M | $127.23M | +$72.75M | 2.34× more $ |
| CAGR (period) | 397.8% | 149.9% | − | 5y CAGR higher due to lucky sequencing of 2021-2026 vs full 10y |
The CAGR drop (531% → 154%) is purely a math artifact of compounding over a longer window from the same $10K start — NOT a deterioration. The 5y sub-period (2021-2026) of the 10y curve produces equivalent CAGR; the 2016-2020 portion grew at a slower rate.
| Variant | N | WR | EV | PF | Sharpe | Max DD | P&L (10y) | CAGR |
|---|
| # | Ticker | Shares | Entry $ | Cur $ | Unr P&L | Unr % | Real P&L | Status | Entered | Exit Reason |
|---|---|---|---|---|---|---|---|---|---|---|
| No Plan ETF trades yet. Fires when SPXL enters the Value Zone and SPY isn't overextended. | ||||||||||
| Date ↕ | Ticker ↕ | Sector ↕ | Signal ↕ | Close ↕ | Days ago |
|---|---|---|---|---|---|
| Click Reload to scan the universe. | |||||
| Ticker | Spot | ATR | Stk Trend | Stk Buy | CONF | F&G ↑ | Not OB | >10 EMA | ≥ $10 | Not Block | Earn ≥4d | Liq | 80Δ Contract | Size | Verdict | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Loading snapshot from deep-itm-bot… | ||||||||||||||||
| # | Ticker | Sector | Strike | Exp | Ctrs | Δ | Entry $ | Under @ | ATR@entry | Cur $ | Cur Under | Unr P&L | Unr P&L % | Real P&L | Total P&L | Total % | Rolls | Status | Entered | Exit Reason |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| No Plan M paper trades yet — bot will open entries when all 3 gates pass. | ||||||||||||||||||||
n ≥ 5 AND expectancy > 0 AND win_rate ≥ 40%. Cache: 24 h.0 7 1 * * (1st of month 07:00 UTC) → build_universe_cache.py --minimal.buy_signal_validity_bars=5 AND the bullish stack is still intact. Mirrors OVTLYR's "still has a buy signal" semantics — the signal is a STATE, not a same-bar event.gap_from_overbought.SECTOR_ETF alias table.buy_signal_validity_bars=5 bars AND the stack is still intact today.buy_signal_min_bars_ago=1 bar ago AND today's close ≥ the fire-bar's close. Rejects same-day fires (no follow-through). 5y backtest: +$1.3 M / +7.7 % WR alone.min_days_to_earnings=2 days away.ticker_cooldown_days=5 after any closed loser (slide 9, prevents revenge trades).HIGH/MED/LOW by (β, market_cap, bars_ago); position size is base_contracts × tier_multiplier (HIGH=1.5x, MED=1.0x, LOW=0.5x).shares = account × risk% / (2 × ATR)contracts = shares / (Δ × 100)contracts × CONV_tier_multiplier (HIGH=1.5x, MED=1.0x, LOW=0.5x).OFF — 5y backtest showed adding contracts at higher strikes lost ~$4 M (delta-exposure tradeoff doesn't pay).(ask−bid)/ask.(mid − intrinsic)/mid.entry + 2·ATR (trail_activate_atr=2.0).highest_close_seen − 0.5·ATR; ratchets UP only.entry − 2·ATR (slide 38). Active only while TRSP not armed (i.e. trade hasn't yet moved +2·ATR up).entry − 3·ATR (slide 49–50). Always active.EMA10 < EMA20 AND price < EMA50 (Joe Ovtlyr video proxy, verified Apr 2026).
RSI is intentionally NOT part of this.close_before_earnings_days=1 day before next earnings (slide 45).DTE ≤ pre_expiry_decision_dte=7 days, the bot evaluates the position for forced close.check_rollover finds the next ATR-step strike with positive credit, executes the combo). Effectively extends the position into a longer-dated expiry.expiry − 1 day as a last-bar fallback. Live bot never reaches this — PRE_EXPIRY_NO_CREDIT_ROLL or a credit roll fires first.+0.5 ATR from original entry; every +1 ATR after that (anchored to entry).spot_close ≥ entry + N·ATR (EOD Close — locked in after the intraday-vs-EOD comparison cost $1.55 M).realized_pnl; premium_at_entry is reset to the new strike's mid; underlying_at_entry KEPT as fixed roll-trigger anchor; orig_contracts KEPT as PYR baseline (PYR is OFF so contracts stay constant).len(roll_history) — never drifts.^VIX > 30 AND VIX rising over the last vix_lookback=5 trading days.OFF by default — backtest showed it self-reinforced losses on the 200-name universe (3 unrelated losses on the same day are statistically guaranteed). Set daily_loser_limit=999.deep_itm_bot.is_circuit_breaker_active().20EMA ≤ price ≤ 20EMA + 2·ATR) AND ≥2·ATR clear of 90-day swing high (OB proxy) AND SPY exit not active.proxy:true in outputs.plan_m_trades has paper=1. Promote to live by flipping the flag and wiring an IB order-placement function.
CYCLE_SECONDS); during US market hours (9:30–16:00 ET, computed via ZoneInfo("America/New_York")) maintain + scan + enter; off-hours snapshot only.
| Time | Ticker | Signal | Alert | TF | Price | Target | Upside% | Bear OB% | EMA5 | EMA10 | EMA20 | EMA50 | EMA200 | Stage | Bot2 | RSI | TMF | Score ⇅ | OptFlow caps? | Rallies | Catalyst | Actions |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| No alerts yet. Set up your TradingView webhook to start receiving alerts. | ||||||||||||||||||||||
Step 1 — In TradingView, create an alert → enable Webhook URL
Step 2 — Set the Webhook URL to:
loading…
Step 3 — Set the Message body to:
{"ticker":"{{ticker}}","alert_type":"EMA_CROSS","price":{{close}},"volume":{{volume}},"timeframe":"{{interval}}","exchange":"{{exchange}}"}
⚠️ TradingView requires HTTPS. Configure nginx + SSL on your VPS, or use a Cloudflare Tunnel for the webhook URL.
Source-truth doc. Every value below is from trading_rules.json · plan_m,
dashboard.py:_ditm_validate_and_size(), or deep_itm.py:check_plan_m_exits/check_rollover.
Generated 2026-05-08 to mirror the deployed r7a_g3 + earn2 config exactly.
POST /webhook/tradingview?secret=…alerts table with scan_status='pending'conviction_score → scan_status='done'dashboard.py:_run_watchlist_scan)BUY / LONG / BULL'done'_get_stock_price() — entry price is the moment-of-decision quote, not the alert's stale {close}CONVICTION_GATE_SCORE=0 (off); live now mirrors. Score is still computed and stored as entry_score for display in the trader log, just not used as a filter.disable_v59=true AND alert_name contains "V59" → reject (44% WR drag in backtest)disable_cont_4h=true AND (timeframe ∈ {240, 4H, 4h} OR alert_name has CONTINUATION_4H) → reject5 days had ≥ 2 losing exits → pause new entries10 exits had ≥ 60% hit an OVTLYR Order Block → pause 3 days (chop regime)3% × notional ($50K) → block remainder of dayvol_spike_reduce=true AND SPY ATR(5)/ATR(30) > 1.3 → multiply risk_pct by 0.5_ditm_validate_and_size, in execution order)spy_regime_filter=true): reject if SPY close < daily EMA200 · cached 5 min · fail-open on yfinance errorsector_trend_filter=true, sector_trend_use_ema200=true): map ticker → sector ETF (XLK/XLV/XLF/XLE/…); reject if that ETF < EMA200us_only_filter=false): reject non-US tickers when enabledmin_days_to_earnings=2): reject if earnings within 2 days · 6h TTL cache · live yfinance + locked v2 cache (98.6% coverage of 443 tickers)target_delta=0.8 · IB greeks first, yfinance + Black-Scholes fallback(ask−bid)/ask(mid − intrinsic)/midposition_cap_enabled=false): tier-based contract cap; currently DISABLED — re-enable when account > $5MIf any gate fails, the bot falls back to STOCK-ONLY tracking: a phantom row in wl_ditm_trades with no IB order, no expiry, no real option contract. Stock-only rows are excluded from the Options Trades panel and Live Paper KPIs.
0.8 (canonical 2026-05-02 — 5-Δ sweep showed peak P&L)STRIKE_FRAC = 0.75 (≈ 25% ITM) — used when chain unavailabletarget_delta; if IB unavailable, BS-approximated from yfinance IV_ditm_validate_and_size)shares = account × risk_pct / (2 × ATR) contracts = max(1, round(shares / (delta × 100)))
$50,0002.5%signal_risk_pct_override, keyed on alert_name):
Bot2Slow Stocks → 5.0%ATM-X → 2.5%Portfolio Bot2Slow Stocks → 5.0%Portfolio ATM-X → 2.5%risk_pct when SPY ATR(5)/ATR(30) > 1.3In-trade roll evaluation runs in the maintenance loop (EOD pass + on-demand /api/wl/ditm/refresh?auto_close=1).
deep_itm.check_rollover)spot ≥ entry + 0.5 × ATR+1.0 × ATR after first (so 0.5, 1.5, 2.5, …)old_intrinsic − new_intrinsic > 0_wl_select_roll_strike) — multi-strike when regime activemulti_strike_regime_mode = "stack" — choices: off, ema50_x_200, stack (current), stack_vixmulti_strike_max_steps=4; picks the candidate that maximizes net credit20010%30%0.8 floor (keeps the position deep-ITM)_wl_place_roll_orders)wl_ditm_trades.roll_history (JSON list of all rolls)spot ≥ entry + 2.0 × ATR (trail_activate_atr default in deep_itm.py PLAN_M_DEFAULTS)0.5 × ATR below high-water-mark of underlyingpyramid_on_trail_arm=true): add +50% contracts at current strike when trail activatesdeep_itm.check_plan_m_exits)Bearish-signal-only exits use 2-bar confirmation (two_bar_confirmation_bearish_exits=true) — must fire on the prior bar too. Stops/earnings/expiry never deferred.
| Reason | Condition |
|---|---|
| 2_ATR_STOP | spot ≤ entry − 2.0 × ATR |
| 3_ATR_EMERGENCY | spot ≤ entry − 3.0 × ATR (gap protection) |
| TRAILING_STOP | trail armed AND spot ≤ HWM − 0.5×ATR |
| PEP_CONFIRMATION | prior daily close < PEP level AND today's spot < prior day's low (1-bar delay on 2-ATR stop) |
| GAP_AND_CRAP | gap ≥ 5% AND price collapses within 3 candles |
| EARNINGS_WITHIN_5D | earnings_in_days ≤ 5 (force-close before report) |
| OVTLYR_SELL_SIGNAL | EMA10 < EMA20 AND price < EMA50 (Joe Ovtlyr proxy) |
| 10_20_BEARISH_CROSS | EMA10 crosses below EMA20 in last 3 bars |
| HIT_BLOCK_120D | price hits an OVTLYR Order Block from 120-day window |
| PRE_EXPIRY_NO_CREDIT_ROLL | contract DTE ≤ 7 AND no roll credit available (theta will burn it) |
continuation_enabled=truecontinuation_extra_exits = ["stop_-2ATR"]DUM244967 (paper)4003 (login jhermosillar; Deep ITM gateway lives on 4002)wl_ditm_trades.ib_order_id · status on ib_order_status2026-05-09 onward where ib_order_id IS NOT NULL (excludes stock-only fallbacks)/tmp/bt_earnings_v2.json, 437/443 = 98.6% coverage) — eliminates yfinance non-determinismg3_stack_earn2 — multi-strike rolls when SPY stack-aligned · earnings filter at 2 days · uncapped sizing · linear-scaling scenarios at $50K-$500K/api/wl/scenarios · KPI strip uses the same source · no hardcoded backtest numbers anywhere (consistency guardrail enforces this on every restart)sweep_results/g3_stack_earn2_aggregated.json + g3_stack_earn2_trades.jsonAll toggleable in trading_rules.json → plan_m. Live values shown.
| Filter | Trigger | Effect | Knob (= live value) |
|---|---|---|---|
| SPY EMA200 | SPY close < daily EMA200 | Block all entries | spy_regime_filter = true |
| Sector ETF EMA200 | Mapped sector ETF < EMA200 | Block ticker | sector_trend_filter = true |
| US-only | non-US ticker | Block ticker | us_only_filter = false |
| Disable V59 | alert_name contains "V59" | Block (44% WR drag) | disable_v59 = true |
| Disable 4H continuation | tf=240/4H or alert has CONTINUATION_4H | Block (low n, mostly −EV) | disable_cont_4h = true |
| Earnings filter | earnings_in_days < threshold | Block ticker | min_days_to_earnings = 2 |
| Losers per day | prior day with ≥ 2 losing exits | Pause new entries 5 days | losers_per_day_trigger / _pause_d |
| OB-cluster pause | last 10 exits ≥ 60% OB_HIT | Pause 3 days (chop) | ob_cluster_pause_enabled = true |
| Vol-spike sizing | SPY ATR(5)/ATR(30) > 1.3 | Halve risk_pct | vol_spike_reduce = true |
| Daily-loss circuit | today's net P&L ≤ −3% × account | Block remainder of day | daily_loss_circuit_pct = 0.03 |
| Multi-strike rolls | ATR-step crossed AND regime active | Roll up to 4× ATR per cycle | multi_strike_regime_mode = "stack" |
| Src | Ticker | Price | P&L | Upside% | bearOB% | Stack | Stage | Bot2 | RSI | Mkt | Sector | Exit | Act |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Click "Sync All" to load positions, then "Scan All" to analyze. | |||||||||||||