# Swing India

> Swing India — Self-Evolving Pipeline

- Skill: `rohitguta2432/swing-india` (Agent Skill)
- Install (CLI): `npx skillmds@latest add rohitguta2432/swing-india`
- Raw SKILL.md: https://api.skillmd.com/api/skills/rohitguta2432/swing-india/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: rohitguta2432 (https://skillmd.com/u/rohitguta2432)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/rohitguta2432/swing-india

---


# Swing India — Self-Evolving Pipeline

End-to-end India cash-equity swing trade workflow. Combines fundamental sanity check (Anthropic finance skills) with technical setup + risk sizing (Bhala NSE skills). Every run is logged. Learnings compile from full history and tighten future runs.

## Modes

| Trigger | Mode |
|---------|------|
| `/swing-india` (NO args) / `swing-india` / "suggest stocks" / "what to buy" | **dashboard** — DEFAULT mode. Runs DAILY (paper-trading progress report) THEN SCAN (new picks) THEN STATS (closed history) in single combined output. One invocation = full summary. |
| `/swing-india scan` | **scan-only** — skip daily report, just scan Nifty100 + rank top 10 |
| `/swing-india daily` / `progress` / `report` / "how are my swings doing" | **daily-only** — paper-trading progress report: live CMP per open, unrealized PnL, R-multiple, signal (EXIT/TRAIL/WATCH/HOLD), portfolio totals, prioritized action commands |
| `swing analyze <ticker>` / `/swing-india <ticker>` | **analyze** — single-ticker deep dive |
| `/swing-india review` | **review** — check open positions (quick, no portfolio aggregation) |
| `/swing-india close <ticker> <exit_price> <reason>` | **close** — log outcome |
| `/swing-india compile` | **compile** — rewrite learnings from raw log |
| `/swing-india stats` | **stats** — print W/L, R-multiple, etc. |

## Hard Rules (NEVER violate)

1. **Cash equity ONLY.** Refuse F&O / options / futures. SEBI FY25: 91% retail F&O traders lost.
2. **Min market cap ₹5,000 cr.** No microcaps.
3. **Min ADV ₹5 cr.** Skip illiquid.
4. **Skip if quarterly result < 7 days away.**
5. **Skip if stock in ASM/GSM/T2T surveillance.**
6. **Max 3 concurrent open positions.**
7. **Halt new entries if `month_pnl_pct < -3`.**
8. **Per-trade risk ≤ 1% of capital.**
9. **R:R minimum 1.5:1 to T1.**

## DASHBOARD Mode — DEFAULT (bare invocation)

**Triggered:** `/swing-india`, `swing-india`, "suggest stocks", "what to buy", "give me summary", "swing india", or any bare invocation with **NO** sub-command.

**Purpose:** Single invocation = full one-screen summary covering everything. No need to run separate commands for daily progress + scan + stats. User runs ONE thing, gets ALL info.

### Pipeline (run in order, single combined output)

1. **DAILY block** — run `python3 ~/.swing-india/daily_summary.py`:
   - Live CMP per `open[]` position
   - Per-position card: signal (EXIT/TRAIL/WATCH/HOLD+/HOLD), R-multiple, unrealized PnL ₹ + %, days held, distance to T1/stop
   - PORTFOLIO totals: invested, market value, unrealized PnL ₹ + %, % capital deployed
   - CLOSED HISTORY: trade count, W/L/BE breakdown, win rate, avg R, realized PnL
2. **SCAN block** — run `python3 ~/.swing-india/scanner.py 10 <capital> <risk_pct>`:
   - Top 10 ranked BUY picks from Nifty100 universe
   - Each: entry, stop, T1, T2, qty, %cap, RSI, ADX, DMA+%
   - Auto-persist new picks to `proposed[]` + log
3. **SUGGESTED ACTIONS block** — copy-paste commands:
   - `swing close <ticker> <exit> <reason>` for any EXIT signal
   - `swing analyze <ticker>` for top scan pick to deepen
   - Risk caveats if month_pnl_pct breached, slots full, etc.

### Output structure (one combined output)

```
═══ DAILY PROGRESS (live MTM on open paper trades) ═══
  [per-position cards sorted by signal priority]
  [portfolio totals]
  [closed history stats]

═══ NEW SCAN (Nifty100 top picks) ═══
  [ranked table of survivor candidates]

═══ ACTIONS ═══
  [prioritized copy-paste commands]
```

### Skip Toggle

User can opt out of either block:
- `/swing-india scan` → SCAN only (skip daily)
- `/swing-india daily` → DAILY only (skip scan)
- Bare `/swing-india` → both

## SCAN Mode — Suggest Stocks From Universe

**Triggered:** "swing scan", "/swing-india scan", "find swing setups", "scan for swings", "which stocks today". (Bare `/swing-india` runs DASHBOARD, which calls this internally.)

**User does NOT specify ticker.** Skill scans pre-defined Nifty100 universe + applies all swing-india filters + learnings + ranks survivors.

### Pipeline

1. Run `python3 ~/.swing-india/scanner.py [top_n=10] [capital=500000] [risk_pct=1.0]`
2. Scanner internally:
   - Loads `~/wiki/swing-india-learnings.md` (skip list, thresholds)
   - Iterates 50 Nifty tickers (extensible to Nifty100/200)
   - Fetches yfinance 2y OHLCV per ticker (parallel safe)
   - Computes DMA50, DMA200, RSI14, MACD hist, ATR14, ADX14
   - Hard rejects: skip-list, below 200DMA, ADX < min, RSI > cap, barely above DMA, MACD fading
   - Sizes: entry = CMP + 0.5×ATR, stop = CMP - 1.5×ATR, qty = (capital × risk%) / risk_per_share
   - Filters R:R T2 ≥ 2.5, position ≤ 35% capital
   - **Scores each survivor 0-100:**
     - RSI 40-50 = +30 (best per backtest), 50-60 = +22, 60-65 = +12
     - ADX 35-50 = +25 (strong trend), 25-35 = +18, 50+ = +12
     - 2-5% above 200DMA = +20 (sweet spot), 5-10% = +12, 10-20% = +5
     - MACD accelerating = +15, just above 0 = +8
     - Favor-list ticker = +10 bonus
   - Sorts by score desc, returns top N

3. Print ranked table + JSON.
4. Append summary YAML to `~/wiki/raw/swing-india-log.md` (type: scan).
5. **Do NOT auto-add to proposed[].** User picks which to deepen via `analyze <ticker>`.

### Output Card

```
SCAN — 2026-MM-DD HH:MM IST
Universe: 50 Nifty100 | Capital: ₹X | Risk: Y%
Learnings active: yes (N=Z trades) | Skip list: 4 auto-rejected
Scanned: 50 | Filtered: 43 | Candidates: 7

#  TICKER         SCORE  CMP      RSI   ADX   DMA+%  ENTRY    STOP     T1       T2       QTY  %CAP
1  ASIANPAINT.NS  72     2599     61.7  46.6  3.0    2628     2514     2799     2970     43   22.6
2  SHRIRAMFIN.NS  65     1007     40.9  30.5  20.1   1022     963      1110     1198     85   17.4
...

NEXT: pick 1-3, run "swing analyze <ticker>" for deep card + add to proposed[]
```

### When to Use Scan vs Analyze

- **Scan** = "what should I trade today?" — discovery
- **Analyze** = "is THIS ticker a setup?" — validation of your idea

## ANALYZE Mode — Full Pipeline

### Stage 0 — Read Learnings + Pre-flight

1. Read `~/wiki/swing-india-learnings.md`. If file empty / doesn't exist, fall back to defaults.
2. Apply learned overrides ONLY IF `closed_trade_count >= 10` (else log "learnings active=false: insufficient sample (N=<x>/10)").
3. Read `~/.swing-india/positions.json`. Refuse if:
   - `len(open) >= 3` → list current positions
   - `month_pnl_pct < -3` → advise pause
   - ticker already in `open` → suggest review

### Stage 1 — Fundamental Filter

Invoke skills:
1. **`comps-analysis`** — P/E, EV/EBITDA, P/B, ROCE vs sector peers.
2. **`dcf-model`** — intrinsic value. Capture upside %.

**Reject (SKIP):**
- Comps premium > 30% AND DCF upside < 5%
- ROCE < 8% AND debt/equity > 1.5
- DCF intrinsic < CMP by > 15%

**Pass:** DCF upside ≥ 8% OR (comps fair ±15% AND ROCE > sector median).

Save `dcf_intrinsic` for T2 target.

### Stage 2 — Technical Setup

Invoke Bhala skills:
1. `nse-multi-timeframe-analysis` — weekly bias, daily setup, 4H/1H entry timing.
2. `nse-rsi-divergence` — bearish divergence check.
3. `nse-fibonacci-trading` — support/resistance Fib levels.
4. `nse-technical-analysis` — 50DMA, 200DMA, MACD, ADX.

**Reject:**
- Weekly trend down (below 200-week MA)
- Daily below 200DMA
- Bearish RSI divergence on daily
- ADX < 20

**Pass outputs:** `entry_trigger`, `stop_loss`, `t1` (1.5R), `t2` (DCF intrinsic capped at next major resistance).

### Stage 3 — Risk + Sizing

1. `nse-position-sizing` — fixed-fractional. Reject if position > 35% of capital.
2. `nse-risk-reward-ratio` — verify R:R T1 ≥ 1.5, T2 ≥ 2.5.
3. `nse-trailing-stops` — trail logic post-T1 (default ATR(14) × 1.5).
4. `nse-stop-loss-strategies` — hard invalidation rule.

### Stage 4 — Output Card

```
TICKER: <SYMBOL>.NS
VERDICT: BUY | WAIT | SKIP
REASON: <one-line>

LEARNINGS APPLIED: <yes (active rules: 1,3,7) | no (N=4/10 sample)>

FUNDAMENTAL
  CMP:           ₹<x>
  DCF intrinsic: ₹<y>  (upside +<z>%)
  Comps:         <fair|premium|discount>
  ROCE:          <a>%

TECHNICAL
  Trend (W/D/4H): <up|sideways|down>
  Trigger:       <entry condition>
  Stop:          ₹<s>
  T1 (1.5R):     ₹<t1>
  T2 (DCF):      ₹<t2>

POSITION
  Capital:       ₹<cap>
  Risk:          ₹<r> (<x>% of capital)
  Quantity:      <n> shares
  Value:         ₹<v> (<%> of capital)
  R:R T1 / T2:   <a> / <b>

INVALIDATION
  - Hard stop hit
  - Below <invalidation_level> on close
  - Quarterly miss > 10%

HORIZON: 3-15 days (or learning override)
TRAIL:   ATR(14) × 1.5 post T1
```

### Stage 5 — Persist + Log

**A. Update positions.json:** append to `proposed[]` (NOT `open[]` until user confirms entry filled).

**B. Append run YAML to `~/wiki/raw/swing-india-log.md`:**

```yaml
---
type: run
timestamp: <ISO-8601 UTC>
ticker: <SYMBOL>.NS
mode: analyze
verdict: BUY|WAIT|SKIP
reason: <one-line>
capital: <inr>
fundamentals:
  cmp: <num>
  dcf_intrinsic: <num>
  upside_pct: <num>
  comps_premium_pct: <num>
  roce_pct: <num>
  debt_equity: <num>
technical:
  weekly_trend: up|sideways|down
  daily_above_200dma: true|false
  rsi_daily: <num>
  macd: bull_cross|bear_cross|neutral
  adx: <num>
  fib_support: <num>
  fib_resistance: <num>
  setup: <pattern_name>
position:
  entry: <num>
  stop: <num>
  t1: <num>
  t2: <num>
  qty: <num>
  position_pct_capital: <num>
  rr_t1: <num>
  rr_t2: <num>
rules_applied:
  - <rule_id_or_name>
notes: <free text>
---
```

End BUY verdict with reminder:

> Paper trade 2 months minimum before real capital. SEBI FY25: 91% retail derivatives traders lost. Cash equity edge requires discipline + 50+ trades for statistical significance.

## REVIEW Mode

Triggered: "review swings" / "/swing-india review".

1. Read `open[]` from positions.json.
2. For each: fetch CMP (Groww MCP > Live-NSE-BSE MCP > yfinance fallback > WebFetch NSE).
3. Flag per position:
   - Stop hit → suggest close
   - T1 reached → suggest trail activation
   - T2 reached → suggest exit
   - Time stop (held > `max_holding_days` from learnings, default 15) → suggest exit
   - Drawdown > 50% of risk amount → flag
4. Recommend trail-stop adjustments.
5. NEVER auto-modify state. User must confirm any close.

## CLOSE Mode

Triggered: `/swing-india close <ticker> <exit_price> <reason>`.

Reasons: `t1_hit | t2_hit | stop_hit | trail_hit | time_stop | discretionary | invalidation`.

1. Find ticker in `open[]`. Compute:
   - `r_multiple = (exit - entry) / (entry - stop)` (negative = loss)
   - `days_held = today - opened`
   - `pnl_inr = (exit - entry) * qty`
   - `outcome = win|loss|breakeven` (R > 0.2 / R < -0.2 / else)
2. Move from `open[]` to `closed[]`.
3. Update `month_pnl_pct` and `month_pnl_inr`.
4. Append outcome YAML to raw log:

```yaml
---
type: close
close_timestamp: <ISO>
ticker: <SYMBOL>.NS
entry: <num>
exit: <num>
stop: <num>
qty: <num>
exit_reason: t1_hit|t2_hit|stop_hit|trail_hit|time_stop|discretionary|invalidation
r_multiple: <num>
days_held: <num>
pnl_inr: <num>
outcome: win|loss|breakeven
postmortem: <free text — what worked, what didn't>
---
```

5. If new month, reset `month_pnl_pct` and `month_pnl_inr` to 0, update `current_month`.

## COMPILE Mode

Triggered: `/swing-india compile`. **Manual only** per user choice.

1. Read full `~/wiki/raw/swing-india-log.md`.
2. Count `closed[]` entries. If `< 10`, output: "Insufficient sample (N=<x>/10). Compile aborted. Returning current learnings unchanged." Exit.
3. Analyze closed trades. Compute per-pattern stats:
   - Win rate by setup (flag, breakout, pullback, etc.)
   - Win rate by RSI bucket (< 40, 40-50, 50-65, > 65)
   - Win rate by sector
   - Win rate by holding-day bucket
   - Avg R-multiple per outcome
   - Worst tickers (≥3 losses)
4. **Rewrite** `~/wiki/swing-india-learnings.md` (replace whole file):

```markdown
# Swing-India Learnings — compiled <date>

**Sample:** N=<x> closed trades | Win rate: <y>% | Avg R: <z>

## Confidence
<low (10-29) | medium (30-99) | high (100+)>

## Patterns That Win (≥60% W, N≥5)
- ...

## Patterns That Lose (<40% W, N≥5)
- ...

## Threshold Adjustments (applied at Stage 0 of analyze mode)
- `min_rr_t1`: <new value> (default 1.5)
- `rsi_max_entry`: <new value or null>
- `max_holding_days`: <new value> (default 15)
- `min_dcf_upside_pct`: <new value> (default 8)

## Skip List
- <ticker>: <reason>, lost N times

## Sector Tilts
- favor: <list>
- avoid: <list>

## Active Rule Overrides
1. <rule statement> — basis: <evidence>
2. ...

## Notes
- <free-form observations>

## Changelog
- <date>: <what changed from prior compile>
```

5. After write, summarize the diff vs prior learnings (which rules added/changed/removed).

## STATS Mode

Triggered: `/swing-india stats`.

Print:
- Closed trades count
- Win rate, avg win R, avg loss R, expectancy
- Best / worst trade
- Avg holding days
- Month PnL %
- Open positions count + unrealized PnL

## DAILY Mode — Paper-Trading Progress Report

**Triggered:** `/swing-india daily` / `/swing-india progress` / `/swing-india report` / "how are my swings doing" / "daily paper trade summary" / "paper trade progress".

**Purpose:** End-of-day check on every open paper position. Live CMP fetch, unrealized PnL, R-multiple, time-stop tracking, prioritized action commands. Use this every trading day to drive close decisions without manually inspecting positions.

### Pipeline

1. Run `python3 ~/.swing-india/daily_summary.py`.
2. Script internally:
   - Loads `~/.swing-india/positions.json`
   - For each `open[]` entry: fetch CMP via yfinance (fallback: cmp_at_scan with `(stale)` tag if quote fails)
   - Computes per-position:
     - `days_held` = today − opened_at
     - `unrealized_pnl_inr` = (cmp − entry) × qty
     - `unrealized_pnl_pct` = (cmp / entry − 1) × 100
     - `r_multiple` = (cmp − entry) / (entry − stop)
     - `dist_to_t1_pct`, `dist_to_stop_pct`
     - **signal**:
       - `EXIT` if cmp ≤ stop OR cmp ≥ t2 OR held ≥ horizon
       - `TRAIL` if cmp ≥ t1 (book 50%, raise stop to ATR×1.5 below CMP)
       - `WATCH` if r_multiple < −0.5 (half-stop warning)
       - `HOLD+` if r_multiple > +0.8 (approaching T1)
       - `HOLD` otherwise
   - Sorts rows by signal priority (EXIT → TRAIL → WATCH → HOLD+ → HOLD)
   - Aggregates portfolio: invested, market value, unrealized PnL ₹ and %, % of capital deployed
   - Aggregates closed history: count, win rate, avg R, total realized PnL
3. Print per-position card + portfolio totals + closed-history block + suggested-actions block with copy-paste `swing close <ticker> <exit> <reason>` commands for any EXIT signal.
4. Do **NOT** auto-close any position. User must run `swing close` manually to log outcome.

### Output Card

```
╔══════════════════════════════════════════════════════════════════════╗
║  SWING-INDIA — DAILY PAPER-TRADING REPORT                            ║
║  YYYY-MM-DD HH:MM IST  |  Capital: ₹X  |  Mode: paper               ║
╚══════════════════════════════════════════════════════════════════════╝
  Open: N  |  Closed: M  |  Proposed (queued): K

┌─ [SIGNAL] TICKER  [SIG ]  held Xd/Yd ─────────────────────────────
│  CMP:    ₹...      Entry: ₹...      Qty: ...
│  Stop:   ₹... (X%) T1: ₹... (X%)
│  T2:     ₹...      Unrealized: ₹... (X%)  R=...
│  → <reason>
└────────────────────────────────────────────────────────────────────

  ┌─ PORTFOLIO ──────────────────────────────────────────────────┐
  │  Invested: ₹... (X% of cap)                                   │
  │  Market val: ₹...                                             │
  │  Unrealized: ₹... (X% on inv / Y% on cap)                     │
  └───────────────────────────────────────────────────────────────┘

  ┌─ CLOSED HISTORY ─────────────────────────────────────────────┐
  │  Trades: N (W:x L:y BE:z) Win-rate: P%                        │
  │  Avg R: ±R  Realized PnL: ₹...                                │
  └───────────────────────────────────────────────────────────────┘

  ┌─ SUGGESTED ACTIONS (priority order) ─────────────────────────┐
  │  [EXIT ] TICKER → swing close TICKER <exit> <reason>          │
  │  [TRAIL] TICKER → # book 50%, raise stop ATR×1.5 below CMP   │
  │  [WATCH] TICKER → # half-stop, no new add                     │
  └───────────────────────────────────────────────────────────────┘
```

### When to Use Daily vs Review

- **daily** = full progress dashboard, every trading day, with portfolio totals + closed stats + action list
- **review** = quick scan of open positions for stop/T1/T2/time-stop hits, no portfolio aggregation

### Optional Scheduling

If user wants automated daily run without manual trigger, suggest cron OR `/schedule` skill:

```
# cron (weekdays 10:30 IST, post-market-open)
30 10 * * 1-5 python3 ~/.swing-india/daily_summary.py >> ~/.swing-india/daily.log 2>&1
```

But default = manual trigger via skill phrase.

## Data Source Order

1. Groww MCP (if configured) — live NSE quote, ATR, depth
2. Live-NSE-BSE MCP — quotes, news
3. Python yfinance with `.NS` suffix — historical OHLCV
4. WebFetch NSE/BSE official pages — last resort

## Refusal Triggers

Refuse + cite SEBI 91% loss stat for:
- F&O / options / futures swing
- Intraday scalping
- Penny stocks (< ₹5,000 cr)
- Tips / sure-shot calls / guaranteed returns

## File Map

| Path | Purpose | Mutation |
|------|---------|----------|
| `~/.swing-india/positions.json` | Live state (proposed/open/closed/PnL) | mutated every analyze + close |
| `~/wiki/raw/swing-india-log.md` | Append-only run + close history | append-only (immutable) |
| `~/wiki/swing-india-learnings.md` | Distilled rules from log | rewritten on `/swing-india compile` |
| `~/.swing-india/scanner.py` | Universe scanner | read-only (called by scan mode) |
| `~/.swing-india/analyze.py` | Single-ticker deep-dive engine | read-only (called by analyze mode) |
| `~/.swing-india/daily_summary.py` | Daily paper-trading progress report (live CMP, MTM, signals, actions) | read-only (called by daily mode) |
| `~/.swing-india/dashboard.py` | DEFAULT dashboard wrapper — runs daily_summary.py + scanner.py back-to-back | read-only (called by bare `/swing-india`) |
| `~/.swing-india/compile.py` | Learnings rewrite engine | read-only (called by compile mode) |

## Self-Evolution Loop Summary

```
analyze → reads learnings → applies rules → logs run YAML
   ↓ (later)
close   → logs outcome YAML
   ↓ (after ≥10 closes)
compile → reads full log → rewrites learnings
   ↓ (next analyze)
analyze → reads UPDATED learnings → tighter rules → better filter
```

Compounds over time. 50+ trades = real edge or proof of no edge.

