A Predictive Stock Entry & Exit SystemBuilt on OVTLYR behavioral analytics
Sentiment data in; a regime call, an entry score, and five exit rules out. Everything below is measured on trades the rules never saw, and the places it breaks down have their own section.
Per-trade win rate
81.41%
780 trades on 500 unseen tickers × 2024-2026 holdout (Slice C, hardest test)
Mean return per trade
+6.43%
Median +8.59%. CAP losers (19.36%) avg -21.96%. Per-trade Sharpe 0.302.
Average hold
48 days
Variable hold (5-120 trading days). Exits at T1/T2/T3/T3_EXT or CAP timeout.
Generalization
4/4 slices
Train, unseen-tickers, unseen-time, both-unseen: WR 81.41-84.22% across all
Table of contents
Per-trade metrics validated on a permanently-locked 500-ticker holdout across 2024–2026. Methodology: rolling look-ahead-free classifier, purged k-fold Cross-Validation (CV) with embargo, Benjamini-Hochberg False Discovery Rate (BH-FDR) multiple-testing correction, block-bootstrap confidence intervals. Data spans 2020–2026. Not financial advice. OVTLYR links are referral links.
Headline
The system identifies the current market regime (Crisis / Normal / Extended) from SPY breadth, scores each stock with a regime-aware composite, and exits each trade via a five-rule policy (T1/T2/T3/T3_EXT/CAP). Universe filters (avg volume ≥ 1,000,000 AND current price ≥ $5) keep illiquid micro-caps and reverse-split-to-death stocks out of the candidate list. Each pick is independent; position sizing is the trader's call.
Per-trade results — four validation slices
500 tickers were held out of all training and rule-selection. Combined with the time split at 2024-01-01, this produces four independent test slices. Slice C (unseen tickers × unseen time) is the strictest test — tickers the rules were never tuned on, evaluated over time the rules were never fitted to.
| Slice | n trades | Win rate | Mean ret | Median | Avg hold |
|---|---|---|---|---|---|
| Train (2,029 tickers, 2020-2023) | 5,044 | 84.22% | +5.77% | +8.05% | 44d |
| Slice A (unseen tickers, 2020-2023) | 1,181 | 84.00% | +6.02% | +7.86% | 45d |
| Slice B (train tickers, 2024-2026) | 3,024 | 82.67% | +5.76% | +8.77% | 48d |
| Slice C (500 unseen tickers × 2024-2026) | 780 | 81.41% | +6.43% | +8.59% | 48d |
Generalization holds. Per-trade win rate stays in the 81.41–84.22% band across every slice. Slice C — 780 trades from 500 tickers the rules were never tuned on, evaluated on 2.4 years the rules were never fitted to — lands at 81.41% win rate / +6.43% mean / +8.59% median.
Exit distribution (Slice C — unseen-ticker holdout)
| Exit reason | % of trades | Win rate | Mean ret |
|---|---|---|---|
| T1 (F&G normalization) | 2.95% | 100.00% | +7.32% |
| T2 (deep-fear recovery) | 18.46% | 100.00% | +15.72% |
| T3 (Crisis profit-take) | 19.74% | 100.00% | +9.12% |
| T3_EXT (non-Crisis, peak-aware) | 39.49% | 100.00% | +14.60% |
| CAP (120-day timeout) | 19.36% | 3.97% | -21.96% |
The four profit-take exits (T1/T2/T3/T3_EXT) fire only on positive-P&L conditions, so they have 100% WR by construction. The CAP timeout is the failure mode: ~20% of trades never get a profit signal and exit at the 120-day cap with an average loss of -22%. Tested mechanical stop-losses (-15% to -25%), trailing stops, breadth-divergence early exits, and ML-discovered multi-feature rules — every variant reduced per-trade Sharpe or portfolio Sharpe (often per-trade-positive rules cluster correlated losses at the portfolio level and double drawdown). The current exit set is empirically near-optimal.
Win rate by validation slice
Per-trade first, portfolio second. The headline above and the slice table are per-trade metrics — what each independent trade looks like. Portfolio-level outcomes depend on how you deploy the rules; see Portfolio Deployment for bootstrap-simulated total return, Sharpe, and drawdown under two reasonable concurrency configurations.
What is OVTLYR?
OVTLYR (pronounced "outlier") is a behavioral analytics platform that quantifies investor sentiment for 3,300+ US-listed stocks. Its core output is the Fear & Greed oscillator — a 0–100 score per stock per day. Lower means more fear, higher means more greed.
The system on this page uses sentiment as the primary feature, with price-based signals (EMA deviations, sector breadth, order blocks) as confirmations.
Metrics are documented in the glossary.
Methodology
The pipeline
- Feature engineering. Process 481 development tickers across all 11 GICS sectors. Extract Fear & Greed (F&G), EMA50 deviations, sector breadth, F&G rate of change.
- Bottom identification. Find ~7,000 price bottoms using local-minima detection plus forward-return analysis.
- Stock classification. Label each ticker Mean-Reversion (MR), Momentum (MOM), or Mixed (MIX) based on how it historically responds to fear signals.
- Cross-ticker pattern mining. Find features that predict profitable entries regardless of ticker.
- Model building. Iterate scoring models per regime through 254 versions.
- Backtesting. 2024–2026 OOS, 2020–2023 IS. Skip-forward exit indexing after each trade prevents overlapping holds from being counted as separate trades.
- Consolidation and CV. Cross-validate any candidate rule across year, regime, and classification splits before shipping.
Scale
- 3,300+ stocks in the OVTLYR universe. Universe filters: vol ≥ 1M + price ≥ $5.
- 500 tickers held out of all training and rule-selection.
- 11 GICS sectors represented across the universe.
- 4,985 out-of-sample (OOS) trades across the three OOS slices (Slice A + Slice B + Slice C); 5,044 additional in-sample training trades for reference.
- Training: Jan 2020 – Dec 2023. Time holdout: Jan 2024 – May 2026.
- Rule discovery: ~1,000 candidate rules tested with BH-FDR multiple-testing correction (q=0.10). Composite-scoring entries, classification, and the F&G<70 ceiling hold across every slice; tested exit alternatives all reduced per-trade Sharpe.
The Three Regimes
The market is split into three modes — Crisis, Normal, and Extended — based on how broad the market's uptrend is. Each mode has its own buy criteria. The mode is detected from SPY breadth, the percentage of S&P 500 stocks currently in uptrends.
SPY breadth — the share of S&P 500 stocks in an uptrend
Crisis0–15%
Deep fear. Low F&G, sentiment still falling, price well under the 50-day average, weak sector.
~30 days a year · highest conviction
Normal15–50%
Stock-level fear starting to turn. Below-neutral F&G ticking up, price under the 50-day average.
Most of the year · the everyday playbook
Extended50–100%
No new entries. Over half the index is already in an uptrend, so this is late in the move — the weakest forward returns of any regime. Existing positions are held.
16% of days · no entries taken
| Mode | When it's active | What it buys | Frequency & conviction |
|---|---|---|---|
| CRISIS | SPY breadth < 15% | Stocks showing deep fear: low Fear & Greed score, sentiment dropping fast, price well below the 50-day average, weak sector. Stocks that historically bounce from extreme fear (MR) get the strongest preference. Full formula: Crisis score. | Rare (~30 days/year). Highest conviction — buy what everyone's panicking about. |
| NORMAL | SPY breadth 15–50% | Stocks with stock-level fear starting to recover: below-neutral Fear & Greed, price below the 50-day average, weak-to-neutral sector, sentiment ticking up. Full formula: Normal score. | Most of the year. Medium conviction — the everyday playbook. |
| EXTENDED | SPY breadth ≥ 50% | Nothing. More than half the index is already in an uptrend, so the move has largely happened. Existing positions are held; no new ones are opened. | 16.3% of days. The market's own forward 20-day return here is +0.51%, against +2.35% in Crisis. |
The strategy inverts across modes. In Crisis, panic-selling creates the best buying opportunities — everyone wants out, the stock is cheap, the recovery edge is largest. The mode is always checked first; everything downstream depends on it.
Why the third regime buys nothing — and why it used to be called Bull
The name was the problem. Extended means SPY breadth is at or above 50%: more than half the index is already trending up. That sounds like the best time to buy and measures the opposite — it is late in the move, and the market's own forward 20-day return is the weakest of the three regimes (+0.51%, against +2.35% in Crisis). Fear setups appear on 13.3% of stock-days here versus 43.6% in Crisis, so the setups this plan trades barely exist.
Nine entry variants were backtested against the full four-slice grid — buying fear, buying momentum names at fear, and riding greed with the F&G<70 ceiling lifted specifically for this regime. Every one tied or lost to taking nothing, and the holdout trade count was identical either way: the slots simply refill with better Crisis and Normal trades.
Taking no entries is not sitting out. Positions opened earlier are held straight through — 11.6% to 19.1% of all position-days happen while the market is in Extended.
The n810 Trading Plan
The system has three pieces: universe filters (vol ≥ 1M, current price ≥ $5), the entry filter (F&G < 70 ceiling across all regimes), and a five-rule exit policy. Two rule refinements: trend-aware T1 suppression (skip T1 when the OVTLYR trend overlay is up) and MOM-aware T3_EXT suppression (let MOM-classified stocks compound past the first peak). See stock classification for the MR/MOM/MIX definition.
The F&G=70 cliff
Below F&G=70 (fear-to-neutral zone), the win rate is 82-91% and only 8-20% of trades end in the 120-day timeout loss bucket. At F&G ≥ 70 (greed zone), the win rate drops to 65-73% and the timeout-loss rate doubles to 38-42%. Don't buy stocks that are already in greedy territory.
Universe filters (applied before any other rule)
| Filter | Trigger | Plain English |
|---|---|---|
| Liquidity | stkDetail.avgVolume < 1,000,000 → SKIP ticker | Don't consider tickers that trade fewer than 1M shares/day on average. Excludes illiquid micro-caps that produce the catastrophic -90% losses. |
| Current price | most-recent lst_h.close < $5 → SKIP ticker | Don't consider tickers currently trading under $5. OVTLYR's historical prices are forward-split-adjusted, so reverse-split-to-death stocks look high in history but are penny stocks today. This filter catches them via current price. |
| F&G ceiling | osc >= 70 at entry → SKIP entry | Don't initiate a position when the stock is already in greedy territory. The threshold sits on the F&G=70 CAP-rate cliff and holds across the four-slice holdout test. |
The system doesn't sell on OVTLYR's Sell flag.
OVTLYR also publishes its own Buy / Sell flag for each stock. The system ignores the Sell flag for exits. Instead, it reads the underlying Fear & Greed number directly and exits when it crosses 60 (back to greedy territory) while the trade is in profit. Reading the raw number gave a 14.5pp higher portfolio return and 4.7pp higher win rate when tested head-to-head against the Sell flag — OVTLYR's flag turns out to be a less-calibrated derivative of the same number.
The five exit rules
Each day after entry, these five rules are checked in order. The first one that matches sells the position. Four of them require the trade to be profitable; the fifth (CAP) is a hard 120-day deadline.
Each day a position is open, in this order
- T1Sentiment back in greed, trade up 5%+ — unless the trend is still confirmed→ sell
- T2Entered in deep fear, the bounce has faded, trade up 5%+→ sell
- T3Opened in Crisis, sentiment recovered to 40, trade up 5%+→ sell
- T3_EXTOpened outside Crisis, peaked at +10%, now fading — momentum names exempt→ sell
- CAPNone of the above fired within 120 trading days→ sell
No match — hold, and check the same five tomorrow.
| # | Name | What it's looking for | Technical trigger |
|---|---|---|---|
| T1 | Sentiment normalized | Fear & Greed has climbed back into greedy territory (≥60) and the trade is up at least 5% — unless OVTLYR's trend indicator says the stock is still in a confirmed uptrend, in which case we let it ride. | osc >= 60 AND P&L > +5% AND final_region != 1 |
| T2 | Deep-fear bounce is fading | Entered at deep fear (F&G < 50), F&G has recovered >60% of the way back to neutral and is now turning down, and the trade is up at least 5%. Lock in the bounce before it reverses. | entry F&G < 50 AND recovery > 60% AND F&G falling AND P&L > +5% |
| T3 | Crisis-entry profit-take | For trades opened in Crisis mode: sell when F&G recovers to 40 and the trade is up at least 5%. | regime@entry == CRISIS AND osc >= 40 AND P&L > +5% |
| T3_EXT | Non-Crisis, peaked-then-faded | For trades opened outside Crisis: if the trade ever peaked at +10% or more and F&G has reached 40, lock in remaining profit. Skipped for momentum stocks because those tend to keep running past the first peak. | regime@entry != CRISIS AND peak P&L >= +10% AND osc >= 40 AND P&L > 0 AND classification != MOMENTUM |
| CAP | 120-day deadline | If none of the above fired after 120 trading days, close the position regardless of P&L. This is where the losers live: about 19% of trades end here at an average -23%. Stop-losses and trailing stops were tested and every variant made overall results worse — fear-buys typically dip before recovering, so mechanical stops cut winners. | days held >= 120 |
The rule set is validated across the four-slice protocol (train / unseen-ticker / unseen-time / both-unseen). Per-trade WR holds 81–84% across all four slices. Seven alternative exit policies were tested on the actual price paths (stop-losses from -10% to -30%, trailing stops from peak-10% to peak-15%, profit targets, F&G-greed exits). Every variant reduced per-trade Sharpe versus the T1/T2/T3/T3_EXT/CAP set. A prior version of the rules used per-sector F&G thresholds (Communication/Industrials at 60, Energy at 50, others at 40); a 2026-05-15 audit found those non-default thresholds were below the project's n=50 minimum sample size on the holdout, and uniform F&G=40 across all sectors improved win rate and Sharpe on every slice. The per-sector logic was retired.
Why the exits resist improvement — the 120-day cap is also a cooldown
Every profitable exit gates on P&L > 5%, so a trade whose peak never reaches +5% cannot exit any way except CAP. That is arithmetic, not a forecast: 64.9% of holdout CAP trades never peak above +5%, and cutting on that condition removes zero winners, because none exist below the gate. Those trades are decided early and held for four more months.
Cutting them anyway fails — at every deadline tested (20 to 80 days), on all four slices, and it gets monotonically less bad the longer you wait. The reason is that nothing else in the rule set stops a re-entry. Exiting at day 30 frees the ticker, the entry rules immediately buy the same falling name, and holdout trade count goes 780 → 1,011 while total return falls 5,018 → 3,338. CAP count drops from 151 to 58 — the cut works — but the churn costs more than the CAP saved. Adding an explicit cooldown to isolate the two gave +0.10 per-trade mean on train and −0.58 on the holdout: fitting noise.
So MAX_HOLD = 120 has been quietly doing a second job as the only re-entry
cooldown in the system. That is the likely reason every exit alternative tested
here has lost: an earlier exit hands the name back to the entry rules, and they
buy it again. The CAP losses are the cost of the entry edge, not a defect
waiting to be engineered out.
Performance
By-year breakdown (Slice C: unseen tickers × 2024-2026)
| Year | n trades | WR | Mean ret | Median |
|---|---|---|---|---|
| 2024 (full year) | 330 | 80.91% | +6.30% | +8.59% |
| 2025 (full year) | 371 | 77.90% | +4.70% | +7.96% |
| 2026 (Jan-Aug, partial) | 79 | 100.00% | +15.14% | +10.27% |
The 2026 row reads as 100%, and it is not a result — it is an artifact of the window ending. A trade only enters this table once it has closed, and the exit rules close winners quickly while losers run to the 120-day cap. Positions opened in 2026 that are still open are therefore absent, and they are disproportionately the ones going badly. Marking those open positions to market pulls the 2026 win rate from 100% down to roughly 57%. Read the 2024 and 2025 rows, which have had time to resolve; treat any partial final year in this table as unfinished.
Why sector breadth carries more weight at its low tail
The entry score reads sector breadth — what fraction of the stock's own sector is in an uptrend. Until August 2026 that term paid a flat bonus anywhere at or below 20% and nothing more, which turned out to leave most of the signal on the table. Per-trade Sharpe keeps climbing all the way down:
| Sector breadth at entry | Train | Slice A | Slice B | Slice C |
|---|---|---|---|---|
| 0–2% | 0.772 | 0.563 | 1.275 | 2.311 |
| 2–5% | 0.401 | 0.522 | 0.469 | 0.555 |
| 5–8% | 0.307 | 0.236 | 0.381 | 0.476 |
| 8–12% | 0.325 | 0.379 | 0.346 | 0.160 |
| 12–16% | 0.164 | 0.083 | 0.314 | 0.245 |
| 16–20% | 0.232 | 0.169 | 0.231 | 0.267 |
| 20–30% | 0.215 | 0.467 | 0.156 | 0.227 |
| 30–50% | -0.001 | 0.066 | 0.222 | 0.299 |
It is a gradient rather than a cliff, and it is monotone on all four slices, so the boundary isn't a fitted artifact. It also isn't a proxy for something the score already knows: inside a single regime it roughly doubles Sharpe (Crisis holdout, breadth ≤5% versus 5–20%: 0.698 against 0.245), and it survives the same control against stock-level Fear & Greed. Per year, the bottom band beats the 5–20% band in ten of twelve comparable cells.
The score now grades the tail — an extra +1.5 below 2%, +1.0 below 5%, +0.5 below 10%. Across all four slices that raised per-trade Sharpe and surfaced more trades rather than fewer, which is the shape a real signal has: holdout Sharpe 0.287 → 0.302 on 705 → 780 trades.
What breadth did not do
Six other readings of the same feed were tested and none survived: breadth direction, acceleration, its own EMA20/EMA50 trend, a sector's rank against the other ten, 20-day sector rotation, and price-versus-breadth divergence. Rotation looked convincing — entering a sector whose rank was collapsing cost about 4pp of win rate on both holdout slices — until it was split by era, where it helped after 2024 and hurt before it. Using breadth as an exit was worse still: it nearly eliminates the CAP loser bucket, then fires on 36–40% of all trades at a 40% win rate, cutting winners short. Only the raw low tail earned a place.
Why the F&G<70 entry filter helps
Skipping new positions when F&G ≥ 70 is the single most consequential rule on the entry side. It blocks the "chasing greed" entries that produce most of the CAP-bucket loser tail. The threshold sits on the F&G=70 CAP-rate cliff: a sharp phase transition from 8-20% CAP-rate below 70 to 38-42% at or above 70.
Data Quality
The OVTLYR feed occasionally has bad-tick errors — a single-day price that's disconnected from the days around it and disagrees with other public sources. Without correction these produce fictional trades in the backtest. The pipeline scans every ticker at load time for spike-then-revert patterns, statistical outliers, and OHLC inconsistencies, and repairs high-confidence cases in-memory. Aggregate impact on the headline numbers is sub-0.1pp on win rate — the repair matters for correctness but barely moves the dial.
Portfolio Deployment
All numbers above are per-trade — what each independent trade looks like in isolation. A trader using The n810 Trading Plan still has to decide how to deploy it: how many concurrent positions, how much capital per slot. Those choices produce widely different portfolio outcomes from the same per-trade edge. The table below shows three operating points, run as 1,000-bootstrap simulations on the production trade list (within-date shuffle, 100% deployed, uniform sizing).
| Slots × Size | Total return (dev) | Sharpe (monthly) | Max drawdown | Std (variance) |
|---|---|---|---|---|
| 10 × 10% | +212% | +1.94 | -14.80% | 79% |
| 15 × 6.67% | +182% | +2.11 | -12.31% | 56% |
| 20 × 5% (current default) | +161% | +2.22 | -10.77% | 44% |
| 25 × 4% | +150% | +2.25 | -10.03% | 37% |
| 30 × 3.33% | +141% | +2.27 | -9.61% | 33% |
| 40 × 2.5% | +129% | +2.29 | -9.32% | 26% |
| 50 × 2% | +124% | +2.39 | -8.63% | 22% |
Every metric moves monotonically as slot count rises. More slots means lower headline return, higher risk-adjusted return, shallower max drawdown, and lower run-to-run variance. The 20 × 5% baseline returns +161% but with 44% std — one bootstrap might give +200%, another +118%. 50 × 2% gives +124% with 22% std, much steadier. Which point you pick is a risk-appetite question, not a correctness one.
Position sizing was removed in August 2026.
An earlier version of this page recommended scaling position size by a gradient-boosting model's estimate of each trade's win probability, and reported it as the default. That has been retired and the claim is withdrawn. Re-tested properly, the model's probability score separates winners from losers on tickers it trained on (AUC 0.578) and essentially not at all on tickers it has never seen (AUC 0.517, against 0.500 for a coin flip). Its confidence deciles are non-monotonic on the holdout, and it is badly calibrated — predicting 0.626 where the realised win rate is 80.9%. It had also never actually run in production: the scheduled job never installed the library it depends on, so every published pick was emitted at 1.00× regardless. Sizing is now the trader's call, and this page reports uniform sizing only.
Why deployment matters more than rule tweaks
We tested ~30 candidate rule changes — per-trade-Sharpe-positive exits, ML-discovered multi-feature stops, breadth-divergence triggers, regime-conditional entry filters. Most that improve per-trade Sharpe fail at the portfolio level: rules firing on market-wide signals (sector divergence, regime shifts) tend to fire on many positions simultaneously, clustering losses into single weeks and doubling drawdown. Per-trade Sharpe assumes trade independence, but a 20-position portfolio shares regimes, sectors, and calendars.
One lever survives portfolio validation cleanly: diversification. More slots mean structurally guaranteed correlation reduction, and the table above is monotone in it. The other candidate — ML-scaled sizing — did not survive re-testing, as above.
Caveats and known limitations
Caveat 1
Survivorship bias
Every ticker in the OVTLYR universe is one that still exists today. Delisted, bankrupt, or going-concern-failed stocks are absent from the dataset. The 81.41% holdout WR is conditional on "the stock survives long enough to be in the universe." Cannot be fixed without external delisting/bankruptcy data. Trader weighting: for any stock with known bankruptcy risk, discount the plan's signal accordingly.
Caveat 2
Short OOS window, one Crisis cycle
The 2.4-year holdout window (Jan 2024 to May 2026) contains one Crisis regime — the 2025 tariff shock and 2026 Iran/Middle East crisis. One crisis is a thin sample. Different regime mixes in future periods may shift the headline 81.41% WR up or down. Train-period validation (2020-2023) included COVID and the 2022 bear, so the plan has seen multiple Crisis types, but per-trade WR consistency depends on the next decade looking somewhat like the last.
Caveat 3
19% CAP-loser tail averages -22%
About 1 in 5 trades hit the 120-day timeout (CAP) with an average loss of -21.96%. Worst trade on holdout: -76.50%, after the vol ≥ 1M and price ≥ $5 filters. Tested stop-losses, trailing stops, breadth-divergence exits, and ML-discovered combinations — per-trade-positive rules systematically cluster correlated losses at the portfolio level, doubling drawdown. Trader risk management: if a trade is at -15% or worse after 60+ days with peak P&L below +5%, consider a manual close; but recognize you may exit some recoverable trades.
Caveat 4
Split-adjusted historical prices
OVTLYR's historical price series is forward-split-adjusted. A stock that did a 1:100 reverse split in late 2024 shows its 2024-01 close as $1,292 when it was actually $12.92 live. The $5 current-price filter catches stocks that are penny TODAY, but a stock that was penny in 2024 and reverse-split to above $5 today still passes. Trader workflow: manually check reverse-split history for any candidate before opening a position.
Caveat 5
Same-day-close fill assumption
The backtest exits trades at the close of the day an exit signal fires. Live execution typically fills at next-day open or after-hours, introducing slippage that the system doesn't model. The effect is small — typically under 0.5pp per trade — but real. Treat the +6.43% mean return as an upper bound.
Caveat 6
Sector classification gaps
The OVTLYR sector field has 28 nulls and 2 mistags across the universe. Sector-specific logic (CRISIS MR-bonus exclusions, sector-adaptive F&G exit thresholds) silently skips or mis-routes these tickers. An edge case — check sector manually if a candidate has unusual sector tagging.
Methodology
(1) 500 tickers were held out of all training and rule derivation. (2) The
stock classifier uses a strict as_of_date cutoff so it never reads future
records. (3) All rule thresholds are validated across the four-slice
generalization grid (train / ticker-holdout / time-holdout / both-holdout).
(4) Cross-validation is purged k-fold with embargo. (5) ~1,000 candidate rules
tested with Benjamini-Hochberg FDR correction at q=0.10.
(6) The live tool (analyze.py / scan.py) and backtest produce the same entry
decision for any (ticker, date).
Tools
Four production scripts (analyze.py, scan.py, portfolio.py, daily.py)
share the same entry/exit logic, universe filters, and rolling classifier. All
four surface per-ticker historical performance under The n810 Trading Plan, so
you can see how the plan has done on each name before you act on a new signal.
The live tool and the backtest produce the same entry decision for any given
(ticker, date).
regime.pyFetches SPY data and prints the current market regime in one line. Auto-selects Crisis / Normal / Extended and which playbook applies.
analyze.py TICKERUniversal ticker analysis. Buy / Wait / Avoid for new positions; Hold / Add /
Reduce / Sell for held positions (--owned ENTRY_PRICE). Applies universe
filters (vol ≥ 1M, price ≥ $5) and the entry/exit logic. Surfaces every prior
trade the plan would have taken on the ticker — entry date, exit date, days held,
prices, F&G in/out, peak/trough, exit reason. Each prior trade is a live
single-ticker backtest, so the history works even for tickers the plan has never
been tuned on.
portfolio.pyReads portfolio.json (or Google Sheets) with current holdings. Runs a full
health check on every position. Outputs hold / sell / add for each, plus the same
per-ticker historical performance summary so you can sanity-check whether the
plan has been right on that stock before.
scan.pyWeekly opportunity scanner. Checks regime first; if favorable, scores all cached tickers and prints top candidates. Adds a "Prior" column showing each candidate's historical record under The n810 Trading Plan (count / WR, with ! / + flags for poor / strong history). Multithreaded, so 200+ tickers stay fast.
Per-ticker history surfaces decision support, not auto-filters
When a candidate appears in scan.py or you pass a name to analyze.py, you see
how the plan has done on that exact ticker before — count, WR, average return,
and a full per-trade breakdown. If the plan has a poor record on a stock, you see
that immediately and can skip the trade. The system never auto-filters on
per-ticker history; judgment stays with the trader. The live single-ticker
simulator matches the production trade list exactly.
The daily list is a standing pool, not a day's worth of new ideas
A name that satisfies the entry condition keeps satisfying it, and is republished every session it does. So the headline pick count is a stock, not a flow: on 2026-08-12 the list showed 29 picks, of which 2 had not been picks the previous session. Over 2026-07-16 to 08-12, 549 pick-slots came from roughly 18 newly-qualifying names per session. Each pick now carries whether it is new and how many consecutive sessions it has qualified.
That raises a fair question — is a name that has been sitting on the list for three weeks a staler buy than a fresh one? Tested by delaying entry until the condition had held for N consecutive days:
| Entry | n (Slice C) | Win rate | Mean ret | CAP rate |
|---|---|---|---|---|
| Day 1 (production) | 780 | 81.41% | +6.43% | 19.36% |
| Day 10 of the run | 269 | 86.62% | +8.73% | 14.87% |
| Day 20 of the run | 98 | 86.73% | +9.15% | 13.27% |
Standing picks are better per trade, not worse — monotonically, on win rate, mean, Sharpe and CAP rate, replicated on Slice B. Persistent qualification selects for sustained fear, which is the setup the plan wants.
Two things stop that from being a strategy. Waiting forgoes 87% of the trades (holdout total return 5,018 → 897), and the comparison is not like for like: surviving to day 20 means the condition never broke, and it breaks on recovery, so late entry quietly excludes the names that recovered fast. Read it as the persistent subset is good, not waiting is free. The practical takeaway is narrow and useful: a pick that has been on the list a while is not damaged goods.