Swing Trading Rules — Tactical Entry and Exit Framework

"Swing trading is not prediction. It is defined risk on intermediate moves inside the primary trend."

Learning Objectives

After reading this chapter, you will be able to:

  • Define swing trading vs intraday and long-term investing on NSE/BSE
  • Apply the six-factor entry score (≥ 80 for strict ENTER) with regime-aware E4 bands
  • Apply Nifty regime overlay (bull/bear/sideways) via NIFTYBEES proxy
  • Apply the eight-rule exit checklist (X1–X8), including active vs advisory exits
  • Distinguish strict ENTER (backtest / orders) from SETUP+ (universe research list)
  • Size positions using R-multiple ≥ 1.0 and portfolio risk limits
  • Interpret gross vs net backtest results (slippage + STT + charges)
  • Use Stock Verifier Swing Trading, Positions, and Screener as one CFA workflow

Introduction

Swing trading captures moves over 2–40 trading sessions. CFA discipline requires:

  1. Fundamental hygiene first — screener before chart entry.
  2. Defined risk — stop and target written before the order.
  3. Trend alignment — long swings only when intermediate trend supports upside.
  4. Honest backtests — cost-adjusted, out-of-sample, sufficient trade count.

The live engine is in tools/stock-verifier/includes/SwingTradingRules.php (UI: swing-trading.php).

Data source

ItemSourceNotes
Scan / backtest priceYahoo daily close (2Y default; 5Y for CFA verify)Same series as indicators
Positions “Now”Yahoo live quoteExit rules still use daily TA
SymbolSYMBOL.NS, .BO fallbackSame as screener TA
52-week %Rolling 252-session range from barsNot quote-summary fields
Liquidity (E6)Avg daily value ≥ ₹8 cr (20 sessions)
Cache TTL24hRefresh daily closes before session
CFA rule: One OHLCV series for price and indicators. Mixing feeds invalidates the signal.

Core Concepts

Sample portfolio (SwingSamplePortfolio)

ItemValue
Universe12 validated Tier-A NSE names (TCS, RELIANCE, BHARTIARTL, …)
Universe idswing_tier_a — use in scanner, strategies, and verify-swing-cfa.php
Default verificationLive Yahoo replay on 12-name Tier-A sample book
Demo modephp verify-swing-cfa.php --demo (~40% illustrative NAV sample)
Live NAV deploy40% NAV sim (cap ₹100k) · gates 35% (cap ₹90k) · bull ×1.80
Current live replay23.3% cash-realistic annual (legacy sequential 30.3%)
Benchmark alpha+13.5%/yr vs NIFTYBEES (cash-realistic NAV)
Aspirational target30–50% — sequential model hits 30%; cash-realistic is below

Engine parameters — Dynamic EMA Swing (v3.7-cash)

ParameterValueRole
Engine IDv3.7-cashCash/exposure-aware NAV + decoupled gate deploy
Profit target3.0R + up to 8% boostGolden cross / volume surge extends target (max +18%)
Effective stopEMA-21 / EMA-9 / SMA-50 / ATRMin risk floor 2.75% — avoids churn from ultra-tight EMA
Entry E9Dynamic momentum gateBlocks weak momentum; hourly EMA bearish blocks live strict
Entry E10EMA-21 extension guard≤4.5% above EMA-21 unless golden cross / volume surge
NAV regime scaleBull ×1.80 / bear ×0.80Walk-forward P&L scaling on top of NAV deploy
Gate deploy35% / cap ₹90kPortfolio heat gates — unchanged from v3.5
NAV deploy40% / cap ₹100kReinvestment sizing (decoupled from gates)
Cash/exposure tracknav_exposure_awareLocks deploy on entry; daily equity curve for DD
Live chop guideisDiscoveryChopRegime()UI warning; live chop scale ×0.70 (not in backtest)
Exit X3EMA-21 + weak momentumActive without waiting for full bear regime
Exit X6High trail or EMA-9 trailTrails below daily EMA-9 after 50% of target
Exit X9Hourly EMA bearishEMA-9 < EMA-21 with partial gain (live only — not in 5Y daily replay)
Breakeven win rate~25% gross / ~30% net1÷(1+3) + charge buffer
Entry score≥ 88 bull / 90 sidewaysUnchanged strict floor
Net edgeTarget − 1.25% charges ≥ 4%Only trades with real 3R payoff
Strict liquidity≥ ₹12 crUnchanged

Latest CFA Evidence (v3.7-cash)

Cash-realistic NAV (locks deploy while positions are open) is the primary replay metric. The legacy sequential model (assumes full NAV always deployable) is shown for comparison.

ModelAnnual NAVMax DDAlpha/yr
Cash-realistic23.3%7.7%+13.5%
Legacy sequential30.3%14.0%+20.5%

Yearly cash-realistic NAV returns:

YearNAV returnTrades exited
2022+15.3%22
2023+31.5%32
2024+44.3%47
2025−4.0%21
2026+10.3%15

CFA interpretation: exposure tracking reveals the prior 30.3% headline assumed unlimited overlapping deploy. With realistic cash locks, CAGR is 23.3% (still positive alpha, PF 2.35). Peak deploy hit 100% with up to 5 concurrent positions — size new entries only when cash is available.

Formula:

Risk (₹)     = Entry − max(hard, structural EMA stop)   (floor 2.75%)
Target (₹)   = Entry + 3 × Risk   (+8% if strong momentum + golden/volume)
Reject ENTER if achieved R < 3.0 after cap

Prior tune — 1:3 R:R Swing (v2.2-3r, reference)

ParameterValueRole
Engine IDv2.2-3rFixed % stops; target 1:3 reward:risk
Profit target3.0RMin +6%, max +18%

Prior tune — v2.1-cfa (reference)

ParameterValue
Profit target2.0R, min +5%, max +12%
Min R≥ 2.0
Entry score≥ 85 bull / 88 sideways

Nifty regime overlay (SwingMarketRegime)

Proxy: NIFTYBEES daily chart (Nifty 50 ETF).

RegimeDetection (summary)E4 52w bandExit overlay
BullPrice ≥ SMA-200, SMA-50 ≥ SMA-200, 20d return > 025–75%X3 advisory
BearPrice < SMA-200 or SMA-50 < SMA-20020–55%X3 active; blocks strict ENTER
SidewaysFlat 60d return30–65%X7 active at 12 sessions
NeutralFallback32–68%Standard exits

High vol (ATR% ≥ 2.5): entry score −5. Bear regime: entry score −15.

Verdict tiers (v2)

VerdictUseCriteria (summary)
Strict ENTERBacktest, live ordersScore ≥ regime floor + E1/E6/E7/E8 + quality + net edge + R ≥ 3.0
Discovery ENTERUniverse scanScore ≥ 80 + E1 + relaxed PA + E6
SETUPResearch watchlistScore ≥ 70 + E1 + pullback forming
WATCHMonitorScore ≥ 70 or 4+ rules + E1

Universe filter default: SETUP+ (not strict ENTER only).

Six-factor entry score (0–100)

FactorMax ptsSource
Trend (E1+E7)25SMA + EMA alignment
Momentum (E2+E3+HL)20Pullback + MACD
Volume (E6)15Avg daily value tiers
Price action (E8)20HL / reversal candle (10 neutral if no bars)
Volatility (E4+E5)1052w band + not extended
Risk (R-multiple)10R ≥ 1.75

Tiers: Strong Buy ≥ 90 · Buy ≥ 80 · Watchlist ≥ 70 · Reject < 70

CFA proficiency audit (v2.0 → v2.1)

Metricv2-regime (Nifty 50, 5Y)v2.1-cfa (same)
Closed trades631222 (−65%)
Net win %49.4%45.5%
Profit factor1.071.20
Net compounded−85%−15%
Net P&L (₹15k/trade)−₹18,932+₹692
Total charges₹29,871₹10,410

Root cause (CFA): Gross edge was ~symmetric (+3.9% / −3.7%) while fixed CNC charges (~₹47/trade) and X4 scratch exits destroyed net expectancy. Fix: fewer, higher-quality entries (R≥2, net-edge gate, ₹12 cr+ liquidity) and deferred partial exits.


The prior engine used a 7/8 rule count for strict ENTER. v2 keeps the same E1–E8 rules but gates orders on score + mandatory E6/E8 + regime. Backtests without regime data use neutral bands (32–68%).


Entry rules (E1–E8)

IDRuleCriterion
E1TrendPrice ≥ SMA-50 ≥ SMA-200 (200+ bars)
E2PullbackRSI 40–56 or within 3% of SMA-50 / EMA-21
E3MomentumMACD histogram ≥ 0 or turning up
E452w bandRegime band (bull 25–75%, bear 20–55%, default 32–68%)
E5Not extendedRSI < 65, BB %B < 85
E6LiquidityAvg daily value ≥ ₹8 cr
E7EMA stackPrice ≥ EMA-50 ≥ EMA-200; EMA-9 > EMA-21 > EMA-50
E8Price actionHigher low + (HH or bullish reversal / support rejection candle)

Strict ENTER additionally requires: entry score ≥ 80, E6 liquidity, E8 when OHLC bars exist, R ≥ 1.75, and regime not bear-blocked.


Exit rules (X1–X8)

IDRuleActive?Criterion
X1Stop-lossYesmin(−5%, 1.2×ATR%) hard / breakeven active stop
X2Profit targetYesFrozen 1.75R target (min +4%)
X3Trend breakBear: activeSMA-50 − 1.5% buffer
X4RSI exitYesRSI > 65 and gain ≥ 65% of target (min +2.5%)
X5MACD lossAdvisoryNo standalone exit (avoids churn)
X6Trailing stopYes−2.5% from high after 50% of target progress
X7Time stopSideways: active≥ 12 sessions flat (15 advisory otherwise)
X8Price actionYesLH/LL or bearish engulfing and gain ≥ partial threshold

Exit when any active rule triggers.


Formula & Explanation

Position size

Position size (₹) = (Portfolio × Risk%) ÷ Stop-loss%

Example: ₹10,00,000 portfolio, 1% risk, 4% stop → risk ₹10,000 → max exposure ₹2,50,000.

R-multiple

Risk (₹) = Entry − Effective stop
Target (₹) = Entry + (MIN_R × Risk)     MIN_R = 1.75
Target % = clamp(Risk% × 1.75, 4%, 12%)   frozen at entry for X2
Effective stop = max(Entry × (1 − min(5%, 1.2×ATR%)), SMA-50 × 0.99, EMA-21 × 0.99)  — for R sizing only
Active X1 stop = ATR-aware hard OR breakeven (entry + 0.35%) after 50% of target

Strict ENTER requires R ≥ 1.75 after the target band is applied.

Cost-adjusted backtest

Adjusted entry = Entry × (1 + slippage%)
Adjusted exit  = Exit × (1 − slippage%)
Net P&L        = Gross − STT − stamp − exchange − GST − DP

Report net win rate and net compounded return — not gross only.


Visual Guide

CFA workflow

[Screener quality preset] → [Swing SETUP+ scan] → [Symbol strict ENTER] → [Positions tracker]

Entry flow (strict ENTER)

[Funda OK?] ──No──► Do not swing
     │ Yes
     ▼
[E1 trend + E7 EMA stack] ──No──► AVOID / WATCH
     │ Yes
     ▼
[Pullback + MACD + 52w band + liquidity] ──No──► WATCH
     │ Yes
     ▼
[E8 price action + score ≥ 80 + R ≥ 1.75] ──No──► WATCH / SETUP
     │ Yes
     ▼
        STRICT ENTER

Worked Example — Indian Market

Stock: INFY (illustrative)

FieldValue
Entry₹1,520
Stop (−4%)₹1,459
Target (+4%)₹1,581
R-multiple(1581−1520) ÷ (1520−1459) = 1.0R
E8Higher low + hammer at EMA-21

Real World Example

Large-cap banks (HDFCBANK, ICICIBANK): Liquid, respect SMA-50; suitable for rule practice.

Mid-cap metals: Wider gaps — same 4% stop may be too tight; reduce size or skip.


Case Study

Strict ENTER backtest (10 Nifty large caps, 2Y, cost-adjusted, v2-regime):

  • Run php benchmark-swing-rules.php for a quick 10-name replay (NIFTYBEES regime walk-forward).
  • Run php verify-swing-cfa.php --symbols TCS,INFY,... or --universe nifty500 --max 50 for CFA verification.
  • Do not cite win rate without trade count and net returns.
  • CFA standard: ≥ 30 trades per regime before trusting win %.

CFA Exam Tip

Examiners reward process: written stop, R-multiple, sample size, and survivorship-free backtests. A high win rate with small average win and large average loss is negative skew — size down.


Common Mistakes

MistakeFix
Using SETUP+ as automatic buyOrders only on strict ENTER
Ignoring net P&L after STTUse Positions charge breakdown
Tuning rules to hit 70% winFreeze rules; validate on Nifty 500 × 5Y
Chasing 52w highsE4 band 32–68%
Skipping screenerscreener.php?preset=quality first


Enterprise workflow — picking best swing trades

CFA funnel (quality over quantity)

1. Strategies → Hybrid Quality→Swing (Nifty 100)
2. Sort by swing_rank — trade Tier A (score ≥ 70) only
3. Confirm strict ENTER on symbol page
4. R ≥ 1.75 · target ≥ +4% · liquidity ≥ ₹8 cr
5. Track in Swing Positions with frozen stop/target

Swing rank score (0–100) — v2

ComponentPoints
Entry score (six-factor)up to 65 (score × 0.65)
Strict ENTER+25
SETUP+12
R-multiple OK+8
Liquidity ≥ ₹8 cr+6
Bear regime−8
Stale chart−10

Tier A (≥70): order candidates · Tier B (50–69): watchlist · Tier C: research only

Portfolio heat (SwingPortfolioRisk)

Heat % = Σ (entry − stop) × shares ÷ portfolio NAV
Block new entries when heat ≥ 4% or open positions ≥ 10
Per-trade risk budget = 1% NAV (suggested shares auto-sized)

Performance (engineering)

  • Batch cache: DataCache::getJsonMulti() — one DB round-trip for TA closes on universe scans.
  • Parallel Yahoo: prefetchDailyCharts() — curl_multi for cache misses (12-wide batches).
  • Single TA pass per symbol via metricsFromBars() (no duplicate fetch).
  • Request-scoped chart memo on universe scans.
  • Background scan: 25+ symbols auto-queue via SwingScanJob (run-swing-scan-job.php).
  • Lazy history: symbol page loads scanHistory only on demand (not every page view).
  • Portfolio backtest: SwingTradingBacktest::applyPortfolioGates() — max 10 positions, 4% heat on ₹1.5L NAV.
  • Daily session: Walkthrough 98 — Swing Daily Session.

Key Takeaways

  1. Eight entry + eight exit rules with price action (E8/X8).
  2. Strict ENTER for execution; SETUP+ for discovery; swing_rank for prioritization.
  3. 1.75R target from stop (min +4%, max +12%), breakeven after 50% of target.
  4. Backtest reports gross and net metrics with slippage.
  5. Tools: strategies.php, swing-trading.php, swing-positions.php, verify-swing-cfa.php.

Practice Questions

  1. Difference between strict ENTER and SETUP?
  2. List all eight entry rules.
  3. Which exit rules are advisory only?
  4. Entry ₹1,000, stop ₹960, target ₹1,040 — calculate R.
  5. Why report net win rate, not gross?

Answer Key

  1. ENTER = full quality + PA for orders; SETUP = forming setup for research.
  2. E1–E8 as in table above.
  3. X3, X5, X7 — advisory; X1, X2, X4, X6, X8 active (with gain gates on X4/X8).
  4. Risk ₹40, reward ₹40 → R = 1.0.
  5. STT, stamp, DP, and slippage can turn gross wins into net losses on small positions.

FAQ

Does live price on Positions match backtest? Backtest uses closes; Positions uses live quote for P&L but daily TA for rules — expect minor divergence intraday.

How to run CFA verification?

cd tools/stock-verifier
php verify-swing-cfa.php --universe nifty500 --max 50 --range 5y

  • Position Sizing
  • Risk Management Pro
  • Tool: tools/stock-verifier/strategies.php — swing / positional / hybrid filters
  • Tool: tools/stock-verifier/swing-trading.php
  • Tool: tools/stock-verifier/swing-positions.php
  • Tool: tools/stock-verifier/screener.php — fundamental hygiene