Khanna, Videh Rakesh Rakesh Claude Sonnet 4.6 commited on
Commit
f2b12cb
Β·
1 Parent(s): 36199b8

chore: clean up stale docs, add db_backtest script and updated research data

Browse files

- Remove 8 stale planning/fix docs (loophole coverage, deploy guides, AI unavailable fix, etc.)
- Update CLAUDE.md with latest architecture notes
- Add research/db_backtest.py and db_backtest_report.md
- Update ai_prompt_accuracy_trades.csv and confidence_calibration.json with latest results
- Remove outdated backtest CSVs (3d, claude-haiku, gpt-4o-mini, old .bak)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

API_LOOPHOLE_COVERAGE.md DELETED
@@ -1,162 +0,0 @@
1
- # Loophole Checking β€” API Coverage
2
-
3
- ## All Prediction Endpoints Enhanced
4
-
5
- βœ… **Loophole checking now included in ALL prediction APIs**
6
-
7
- ### 1. `/api/predict` (POST)
8
- - Audits each prediction for loopholes
9
- - Adds `loopholes` field to each result if found
10
- - Handles 1–20 stocks per request
11
-
12
- ### 2. `/api/rank` (POST)
13
- - Ranks universe by profit score
14
- - Audits top predictions for loopholes
15
- - Flags risky picks before ranking
16
-
17
- ### 3. `/api/top5` (GET)
18
- - Returns top 5 weekly picks
19
- - Audits each pick for loopholes
20
- - Includes specialist recommendations
21
- - Loopholes added to both fresh + stale results
22
-
23
- ### 4. `/api/watchlist-picks` (GET)
24
- - Predicts all watchlist stocks (INTRADAY/1D/3D/5D)
25
- - Audits primary prediction per stock
26
- - Adds loopholes to response when found
27
-
28
- ### 5. `/api/watchlist-pick/<ticker>` (GET)
29
- - Single stock watchlist prediction
30
- - Audits for loopholes
31
- - Shows loopholes in response
32
-
33
- ### 6. `/api/watchlist-pick/<ticker>/<tf>` (GET)
34
- - Single timeframe prediction
35
- - Inherits loophole checking from parent call
36
-
37
- ### 7. `/api/watchlist-picks` (GET)
38
- - Batch watchlist predictions (all TFs)
39
- - Audits each pick
40
- - Adds loopholes field when needed
41
-
42
- ---
43
-
44
- ## Loophole Fields in Responses
45
-
46
- Each prediction with loopholes now includes:
47
-
48
- ```json
49
- {
50
- "ticker": "STAR.NS",
51
- "direction": "BULLISH",
52
- "confidence": "MEDIUM",
53
- "loopholes": {
54
- "loophole_count": 2,
55
- "critical_count": 0,
56
- "warning_count": 2,
57
- "conviction_score": 80,
58
- "recommendation": "CAUTION",
59
- "summary": "0 critical, 2 warnings β€” caution",
60
- "loopholes": [
61
- {
62
- "category": "conflicting_signals",
63
- "flag": "RSI_OVERBOUGHT",
64
- "severity": "WARNING",
65
- "detail": "Bullish call but RSI 68 > 60 (overbought, lacks pullback)"
66
- },
67
- {
68
- "category": "weak_conviction",
69
- "flag": "UNCERTAIN_ML",
70
- "severity": "WARNING",
71
- "detail": "ML probability 0.51 near 50% (uncertain directional lean)"
72
- }
73
- ]
74
- }
75
- }
76
- ```
77
-
78
- ---
79
-
80
- ## Loophole Audit Endpoints
81
-
82
- ### POST /api/prediction-loopholes
83
- Manually audit any prediction dict:
84
- ```bash
85
- curl -X POST http://localhost:5000/api/prediction-loopholes \
86
- -H "Content-Type: application/json" \
87
- -d '{prediction_dict}'
88
- ```
89
-
90
- ### GET /api/specialist-stocks
91
- Find Intraday vs 1D specialists:
92
- ```bash
93
- curl http://localhost:5000/api/specialist-stocks?min_samples=10
94
- ```
95
-
96
- ### GET /api/specialist-stocks/<ticker>
97
- Get recommended TF for one stock:
98
- ```bash
99
- curl http://localhost:5000/api/specialist-stocks/STAR.NS
100
- ```
101
-
102
- ---
103
-
104
- ## Implementation Details
105
-
106
- ### Backend Logic
107
- - **5 loophole checks** applied automatically in `predictor_core.py`:
108
- 1. NO_STRATEGY_SIGNALS (CRITICAL)
109
- 2. RSI_OVERBOUGHT (WARNING)
110
- 3. BELOW_EMA50 (CRITICAL)
111
- 4. BEARISH_NEWS_CONFLICT (WARNING)
112
- 5. UNCERTAIN_ML (WARNING)
113
-
114
- - **Loophole auditing** via `_audit_prediction()` in `app.py`:
115
- - Detects conflicting signals
116
- - Checks news sentiment alignment
117
- - Flags weak conviction patterns
118
- - Validates fundamentals consistency
119
-
120
- ### Response Behavior
121
- - Only includes `loopholes` field if loopholes found (loophole_count > 0)
122
- - Conditional includes avoid bloating responses
123
- - Conviction score provided for client-side filtering
124
-
125
- ---
126
-
127
- ## Testing Endpoints
128
-
129
- ```bash
130
- # Test /api/predict with loopholes
131
- curl -X POST http://localhost:5000/api/predict \
132
- -H "Content-Type: application/json" \
133
- -d '{"stocks": ["STAR.NS"], "timeframe": "1D"}' | jq '.predictions[0].loopholes'
134
-
135
- # Test /api/top5 with loopholes
136
- curl http://localhost:5000/api/top5 | jq '.picks[].loopholes'
137
-
138
- # Test /api/watchlist-picks with loopholes
139
- curl http://localhost:5000/api/watchlist-picks | jq '.picks[].loopholes'
140
-
141
- # Test /api/specialist-stocks
142
- curl http://localhost:5000/api/specialist-stocks | jq '.specialists'
143
- ```
144
-
145
- ---
146
-
147
- ## Coverage Summary
148
-
149
- | Endpoint | Loopholes | Specialists | Status |
150
- |----------|-----------|-------------|--------|
151
- | /api/predict | βœ… | - | Enhanced |
152
- | /api/rank | βœ… | - | Enhanced |
153
- | /api/top5 | βœ… | βœ… | Enhanced |
154
- | /api/watchlist-picks | βœ… | - | Enhanced |
155
- | /api/watchlist-pick/<ticker> | βœ… | - | Enhanced |
156
- | /api/watchlist-pick/<ticker>/<tf> | βœ… | - | Enhanced |
157
- | /api/prediction-loopholes | βœ… | - | New |
158
- | /api/specialist-stocks | - | βœ… | New |
159
-
160
- ---
161
-
162
- **All prediction APIs now provide loophole detection and specialist recommendations.**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
CLAUDE.md CHANGED
@@ -114,7 +114,12 @@ The deeper capacity fix is the two extra providers (Gemini/SambaNova) above β€”
114
 
115
  **Production vs tight_test ranges** β€” In production (`tight_test=False`), the AI's own range output is used directly. The `_BULL_RANGE`/`_BEAR_RANGE`/`_NEUT_RANGE` calibrated tables are ONLY applied when `tight_test=True` (backtest accuracy measurement mode). This ensures UI shows realistic AI-predicted targets, not hardcoded tiny ranges.
116
 
117
- **ATR clamp + directional-sign enforcement (`ai_forecast._atr_clamp_range`)** — production-only safety net (no-op when `tight_test=True`) applied in all three range-finalize paths (fast-mode, Ollama-only, debate). Keyed to the stock's own ATR%: (0) **directional-sign** — a BULLISH band must be entirely above entry (`0 < lo < hi`), BEARISH entirely below (`lo < hi < 0`); (1) reins in an over-shot midpoint toward entry; (2) caps band WIDTH tight (`_ATR_MAX_WIDTH`); (3) enforces the per-TF hard %-cap in code. **Why (0) matters:** `_apply_trigger_guardrails` can flip the LLM's direction (e.g. NEUTRAL→BULLISH via T4/T6 oversold triggers), but the LLM's original *straddle* range is left behind — producing a "bullish" band centred on entry that hits trivially. When the sign is inconsistent, the band is re-anchored to the SAME ATR multipliers the synthesis prompt uses (`_ATR_TARGET_MULT`, must stay in sync with `_build_synthesis_prompt`'s `_lo_mult`/`_hi_mult`).
 
 
 
 
 
118
 
119
  **`backtest_stats` field** β€” computed in `predictor_core._calc_expected_return()` and added to the prediction dict, but intentionally NOT forwarded to watchlist or top5 API responses. Internal use only.
120
 
@@ -432,8 +437,40 @@ BACKTEST_LLM_PACE_SECS Seconds between LLM calls in backtest (default: 12). Set
432
  | NEUTRAL | lo=-0.90, hi=+0.90% | lo=-5.1, hi=+5.1% | lo=-5.1, hi=+5.1% | lo=-6.3, hi=+6.3% |
433
 
434
  > INTRADAY values are starting points β€” tune via `research/validate_on_trades.py` (now reports a Today/INTRADAY column) until the INTRADAY column β‰₯ 90%, then lock the final values into both `ai_forecast._BULL/_BEAR/_NEUT_RANGE["INTRADAY"]` and `database._SNAP_*["INTRADAY"]` (they must match).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
 
436
- ### Trigger-based direction rules (implemented 2026-06-29)
 
 
 
 
 
437
 
438
  The synthesis prompt uses explicit trigger lists β€” commit to a directional call whenever ANY trigger fires. Replaced the prior guardrail-based approach which blocked BULLISH too often.
439
 
@@ -449,10 +486,12 @@ The synthesis prompt uses explicit trigger lists β€” commit to a directional cal
449
  - `[B1]` BB > 95% AND RSI > 64 AND 10D momentum > +8% `[extreme overbought reversal]`
450
  - `[B2]` Below EMA50 AND MACD < 0 AND 10D momentum < -5% AND RSI > 50 AND BB > 40% `[confirmed downtrend, not oversold]`
451
 
452
- **BEARISH GUARD:** If RSI < 46 AND BB < 40% β†’ call BULLISH not BEARISH (oversold stocks bounce intraday even in downtrends).
453
 
454
  **NEUTRAL:** Only when no trigger fires AND momentum is genuinely flat.
455
 
 
 
456
  ### New indicators added to context (2026-06-29)
457
 
458
  In `research/backtest.py` `_compute_indicators()` and displayed via `ai_forecast.py` `_build_context_block()`:
 
114
 
115
  **Production vs tight_test ranges** β€” In production (`tight_test=False`), the AI's own range output is used directly. The `_BULL_RANGE`/`_BEAR_RANGE`/`_NEUT_RANGE` calibrated tables are ONLY applied when `tight_test=True` (backtest accuracy measurement mode). This ensures UI shows realistic AI-predicted targets, not hardcoded tiny ranges.
116
 
117
+ **ATR clamp + directional-sign enforcement (`ai_forecast._atr_clamp_range`)** β€” rewritten 2026-07-17. Production-only safety net (no-op when `tight_test=True`), keyed to the stock's own ATR%, but now **fully rebuilds** the BULLISH/BEARISH/NEUTRAL band from a day-scaled power-law formula instead of just clamping the LLM's own range β€” the model's own lo/hi are discarded entirely; only its DIRECTION and CONFIDENCE still come from the LLM. This is a deliberate, explicitly-requested accuracy/informativeness trade-off (see `research/PRODUCTION_DELTA.md` 2026-07-17 section and `memory/repo` notes for the full discussion):
118
+ - **NEUTRAL** (`_neutral_half_width_pct`): rebuilt as a clean symmetric band straddling zero. Bugfix: previously NEUTRAL had NO directional-sign check at all, so the LLM could return an all-positive or all-negative "NEUTRAL" band with zero protection against the other direction.
119
+ - **BULLISH/BEARISH**: `near` bound (`_easy_near_bound_pct`) = `BASE Γ— window_days^EXP Γ— ATR%`, clamped to a floor/ceiling derived from the same formula; `far` bound (`_far_bound_pct`) is its own day-scaled formula (not a flat ratio of near β€” an earlier flat-ratio version measurably hurt INTRADAY/3D). `window_days` matches `predictor_core.TIMEFRAME_DAYS` (1D=1, 3D=3, 5D=5); INTRADAY uses its own fitted "equivalent day count" per formula since it has no calendar-day length.
120
+ - Old constants removed as dead code: `_ATR_MID_CEILING`, `_ATR_MAX_WIDTH`, `_ATR_TARGET_MULT`, `_NEUT_ATR_HALF_WIDTH` (flat per-TF dicts) β€” all superseded by the formulas above.
121
+
122
+ Validated via `research/validate_on_trades.py`: `graded_hit_for_tf` 66.7%β†’96.3%, `target_hit_for_tf` (strict midpoint) 63.0%β†’83.3%, direction-hit 92.6% (6 tickers Γ— 3 dates Γ— 3 TFs, 54 rows).
123
 
124
  **`backtest_stats` field** β€” computed in `predictor_core._calc_expected_return()` and added to the prediction dict, but intentionally NOT forwarded to watchlist or top5 API responses. Internal use only.
125
 
 
437
  | NEUTRAL | lo=-0.90, hi=+0.90% | lo=-5.1, hi=+5.1% | lo=-5.1, hi=+5.1% | lo=-6.3, hi=+6.3% |
438
 
439
  > INTRADAY values are starting points β€” tune via `research/validate_on_trades.py` (now reports a Today/INTRADAY column) until the INTRADAY column β‰₯ 90%, then lock the final values into both `ai_forecast._BULL/_BEAR/_NEUT_RANGE["INTRADAY"]` and `database._SNAP_*["INTRADAY"]` (they must match).
440
+ >
441
+ > **Scope note (2026-07-17):** the table above is the `tight_test=True` calibration table, unchanged by the 2026-07-17 rewrite. Production (`tight_test=False`) no longer uses `_BULL_RANGE`/`_BEAR_RANGE`/`_NEUT_RANGE` at all β€” see the "ATR clamp + directional-sign enforcement" section above for the day-scaled formula that now fully owns the production range.
442
+
443
+ ### Trigger-based direction rules (rewritten 2026-07-17, supersedes the 2026-06-29 version below)
444
+
445
+ **Root cause fixed 2026-07-17:** the prior version's `_apply_trigger_guardrails` (Python re-evaluation layer) silently kept the LLM's raw direction whenever no trigger fired, instead of forcing NEUTRAL β€” combined with a self-contradictory B2 threshold (RSI>50 AND 10D<-5%, which almost never co-occur), this meant BEARISH essentially never fired: a real backtest run showed 54/54 predictions were BULLISH. Fixed in `ai_forecast._apply_trigger_guardrails`:
446
+ - **No trigger fires β†’ forced NEUTRAL** (previously only downgraded confidence, kept the LLM's direction).
447
+ - **B2 relaxed**: RSI>50β†’42, momentum threshold -5%β†’-4%.
448
+ - **New B3 trigger**: `crash_exhausted` (10D<-6% OR 20D<-8%) AND MACD<0 β€” a "falling knife" bearish signal independent of RSI/BB.
449
+ - **`crash_exhausted` flag** suppresses the oversold-bounce triggers (T4/T6) and **`overbought_extreme`** (RSI>70) suppresses the lagging-MACD trigger (T1) β€” both were firing false BULLISH on stocks already in a confirmed multi-day decline.
450
+ - **BEARISH GUARD now routes to NEUTRAL, not BULLISH** (see below) β€” matches the documented preference to avoid forcing weak bears directly into BULLISH.
451
+ - Conflicting triggers (both bull and bear fire) β†’ NEUTRAL.
452
+
453
+ Validated: direction-hit accuracy went from effectively broken (single-direction bias) to 92.6% on `research/validate_on_trades.py`.
454
+
455
+ **BULLISH triggers (ANY one is sufficient), 1D example (see `_build_synthesis_prompt` for the 4 TF-specific variants):**
456
+ - `[T1]` Price above EMA50 AND MACD > 0 AND RSI <= 70 (blocked when extremely overbought β€” lagging confirmation often fires right before a reversal)
457
+ - `[T2]` Price above EMA50 AND 10D momentum > +3% AND BB < 85%
458
+ - `[T3]` Price above EMA50 AND 3+ consecutive up days AND 20D momentum > 0%
459
+ - `[T4]` RSI < 50 AND BB < 45% AND 10D momentum > -2% (suppressed when `crash_exhausted`)
460
+ - `[T5]` 10D momentum > +7% AND BB < 80%
461
+ - `[T6]` RSI < 44 AND BB < 35% (suppressed when `crash_exhausted`)
462
+ - `[T7]` Price above EMA50 AND 20D momentum between +1% and +5% AND RSI < 62
463
+
464
+ **BEARISH triggers (ANY one is sufficient):**
465
+ - `[B2]` Below EMA50 AND MACD < 0 AND 10D momentum < -4% AND RSI > 42 AND BB > 40%
466
+ - `[B3]` 10D momentum < -6% OR 20D momentum < -8% (sustained decline) AND MACD < 0
467
 
468
+ **BEARISH GUARD:** If RSI < 50 AND BB < 45% (mildly oversold, insufficient evidence either way) β†’ call **NEUTRAL**, not BEARISH β€” and NOT forced BULLISH either (2026-07-17 fix; previously forced BULLISH, which was an unjustified directional overshoot).
469
+
470
+ **NEUTRAL:** No trigger fires, OR triggers conflict (both bull and bear fire) β†’ NEUTRAL.
471
+
472
+ <details>
473
+ <summary>Historical: 2026-06-29 trigger rules (superseded, kept for reference)</summary>
474
 
475
  The synthesis prompt uses explicit trigger lists β€” commit to a directional call whenever ANY trigger fires. Replaced the prior guardrail-based approach which blocked BULLISH too often.
476
 
 
486
  - `[B1]` BB > 95% AND RSI > 64 AND 10D momentum > +8% `[extreme overbought reversal]`
487
  - `[B2]` Below EMA50 AND MACD < 0 AND 10D momentum < -5% AND RSI > 50 AND BB > 40% `[confirmed downtrend, not oversold]`
488
 
489
+ **BEARISH GUARD:** If RSI < 46 AND BB < 40% β†’ call BULLISH not BEARISH (oversold stocks bounce intraday even in downtrends). *(This exact behavior was the bug fixed 2026-07-17 β€” it caused an unjustified BULLISH bias.)*
490
 
491
  **NEUTRAL:** Only when no trigger fires AND momentum is genuinely flat.
492
 
493
+ </details>
494
+
495
  ### New indicators added to context (2026-06-29)
496
 
497
  In `research/backtest.py` `_compute_indicators()` and displayed via `ai_forecast.py` `_build_context_block()`:
DEPLOY_HF_SPACES.md DELETED
@@ -1,285 +0,0 @@
1
- # Deploy to Hugging Face Spaces
2
-
3
- **Status**: βœ… Code is HF Spaces-ready (persistent database, secrets management, Docker support)
4
-
5
- ---
6
-
7
- ## What's Already in Place
8
-
9
- ### βœ… Dockerfile
10
- - **Location**: `./Dockerfile`
11
- - **Base**: Python 3.11-slim-bookworm
12
- - **Port**: 7860 (HF Spaces default)
13
- - **Command**: `python app.py`
14
- - All dependencies compiled from `requirements.txt`
15
-
16
- ### βœ… Requirements
17
- - **Location**: `./requirements.txt`
18
- - **75+ packages** including Flask, yfinance, pandas, numpy, scikit-learn, huggingface_hub
19
- - Compatible with HF Spaces environment
20
-
21
- ### βœ… Database Persistence
22
- - **Location**: `database.py` β†’ `setup_hf_persistence()`
23
- - **Auto-restore**: On startup, downloads latest DB from HF Hub dataset
24
- - **Auto-backup**: Background thread uploads DB every 5 min
25
- - **Storage**: `/data/paper_trading.db` (HF Spaces persistent volume)
26
- - **Fallback**: Graceful degradation if HF Hub unavailable
27
-
28
- ### βœ… Secrets Management
29
- - **Location**: `export_env_secrets.py`
30
- - **Integration**: Pushes `.env` secrets to HF Spaces Secrets tab
31
- - **Usage**: `python export_env_secrets.py`
32
- - Environment variables automatically loaded at runtime
33
-
34
- ### βœ… Code Compatibility
35
- - All paths use `os.path.dirname(__file__)` (not `pathlib.Path`)
36
- - SQLite caches (not file-based β€” survive container restarts)
37
- - Inline CSS/JS (no CDN β€” complies with HF CSP)
38
-
39
- ---
40
-
41
- ## 3-Step Deployment
42
-
43
- ### Step 1: Create HF Spaces Repository
44
-
45
- ```bash
46
- # Create a new Space on Hugging Face
47
- # https://huggingface.co/new-space
48
-
49
- # Settings:
50
- # - Owner: Your account (or org)
51
- # - Name: PaperTrade (or your choice)
52
- # - License: MIT (or your choice)
53
- # - Space SDK: Docker
54
- # - Visibility: Private (recommended for trading app)
55
- ```
56
-
57
- ### Step 2: Push Code to HF Spaces
58
-
59
- ```bash
60
- # Navigate to your project
61
- cd /Users/videkhanna/Documents/Projects/PaperTrade
62
-
63
- # Add HF Spaces remote (replace USERNAME/SPACE_ID)
64
- git remote add huggingface https://huggingface.co/spaces/USERNAME/PaperTrade
65
-
66
- # Push code to HF Spaces
67
- git push huggingface main
68
- ```
69
-
70
- ### Step 3: Upload Secrets to HF Spaces
71
-
72
- ```bash
73
- # Export environment variables from local .env to HF Spaces
74
- python export_env_secrets.py
75
-
76
- # This uploads all .env variables to HF Spaces' Secrets tab
77
- # Verify in HF Spaces UI: Settings β†’ Secrets
78
- ```
79
-
80
- ---
81
-
82
- ## After Deployment
83
-
84
- ### Build & Start
85
- HF Spaces automatically:
86
- 1. Reads `Dockerfile`
87
- 2. Downloads `requirements.txt`
88
- 3. Runs `python app.py` on port 7860
89
- 4. Mounts persistent `/data/` volume
90
- 5. Loads secrets as environment variables
91
-
92
- ### Database
93
- - **First startup**: Downloads DB from HF Hub dataset (if exists)
94
- - **Every 5 min**: Uploads current DB to HF Hub for backup/sync
95
- - **Local testing**: Same SQLite DB used locally & on HF Spaces
96
-
97
- ### Access App
98
- ```
99
- https://huggingface.co/spaces/USERNAME/PaperTrade
100
- Direct URL: https://username-papertrade.hf.space
101
- ```
102
-
103
- ---
104
-
105
- ## Environment Variables
106
-
107
- **Required** (set via `export_env_secrets.py`):
108
-
109
- | Variable | Example | Source |
110
- |---|---|---|
111
- | `HF_TOKEN` | `hf_xxxxxxxxxxxx` | Hugging Face API token |
112
- | `OPENROUTER_API_KEY` | `sk-or-xx...` | OpenRouter for LLM fallback |
113
- | `GROQ_API_KEY` | `gsk_...` | Groq for LLM fallback |
114
- | `FRED_API_KEY` | `xxxxx` | FRED for macro data (optional) |
115
- | `SPACE_URL` | Auto-injected | HF Spaces URL |
116
-
117
- **Optional** (LLM fallbacks):
118
- - `CEREBRAS_API_KEY` β€” Cerebras inference
119
- - `HF_TOKEN` for HuggingFace Router
120
-
121
- All values read from:
122
- 1. HF Spaces Secrets tab (production)
123
- 2. `.env` file (local dev)
124
-
125
- ---
126
-
127
- ## Persistent Storage
128
-
129
- ### What Persists Automatically
130
- - `paper_trading.db` β€” full trading history, predictions, validation
131
- - `/data/` mount β€” survives container restarts on HF Spaces
132
- - Background upload thread syncs DB to HF Hub every 5 minutes
133
-
134
- ### What Gets Recreated
135
- - Runtime caches (5-min OHLCV cache) β€” cached in SQLite, survives
136
- - Prediction cache β€” session-only, OK to lose
137
- - Log files β€” written to stdout (HF captures logs)
138
-
139
- ### Manual Backups
140
- To create a persistent HF Hub dataset for DB backups:
141
- ```bash
142
- # Create dataset on HF Hub
143
- # https://huggingface.co/datasets/new
144
-
145
- # Name it: username/PaperTrade-DB
146
- # Then update database.py _HF_REPO_ID = "username/PaperTrade-DB"
147
- ```
148
-
149
- ---
150
-
151
- ## Testing Deployment
152
-
153
- ### Local Test Before Pushing
154
- ```bash
155
- # Run exact Docker image HF will use
156
- docker build -t papertrade:latest .
157
- docker run -p 7860:7860 -e HF_TOKEN=hf_xxx papertrade:latest
158
-
159
- # Visit http://localhost:7860
160
- ```
161
-
162
- ### Verify on HF Spaces
163
- ```bash
164
- # Check Space health
165
- curl https://username-papertrade.hf.space/api/portfolio
166
-
167
- # Check watchlist
168
- curl https://username-papertrade.hf.space/api/watchlist
169
-
170
- # Check top5 picks
171
- curl https://username-papertrade.hf.space/api/top5
172
- ```
173
-
174
- ---
175
-
176
- ## Space Settings (Recommended)
177
-
178
- | Setting | Recommended | Reason |
179
- |---|---|---|
180
- | **Visibility** | Private | Protect trading signals |
181
- | **Persistent storage** | Enabled | Preserve DB between restarts |
182
- | **Resources** | CPU (t4 if available) | For parallel predictions |
183
- | **Sleep time** | Never (paid tier) | Always available for trading |
184
- | **Persistent disk size** | 10 GB | Room for OHLCV caches |
185
-
186
- ---
187
-
188
- ## Troubleshooting
189
-
190
- ### Space won't start
191
- 1. Check build logs: Space Settings β†’ Build status
192
- 2. Verify `requirements.txt` (no conflicts)
193
- 3. Check `Dockerfile` syntax
194
-
195
- ### DB not persisting
196
- 1. Verify HF_TOKEN in Secrets
197
- 2. Check Space has persistent storage enabled
198
- 3. Logs: `cat /proc/1/fd/1` in terminal
199
-
200
- ### App runs but crashes
201
- 1. Check app logs (HF captures stderr)
202
- 2. Verify all required env vars in Secrets
203
- 3. Test locally with `docker run` first
204
-
205
- ### Secrets not loading
206
- 1. Verify you ran `export_env_secrets.py`
207
- 2. Check HF Spaces Secrets tab (Settings)
208
- 3. Restart Space: Space Settings β†’ Restart
209
-
210
- ---
211
-
212
- ## Continuous Deployment
213
-
214
- ### Via GitHub Actions (Optional)
215
- ```yaml
216
- name: Deploy to HF Spaces
217
- on:
218
- push:
219
- branches: [main]
220
- jobs:
221
- deploy:
222
- runs-on: ubuntu-latest
223
- steps:
224
- - uses: actions/checkout@v3
225
- - run: |
226
- git remote add hf https://huggingface.co/spaces/${{ secrets.HF_SPACE_ID }}
227
- git push hf main
228
- ```
229
-
230
- ### Manual Redeploy
231
- ```bash
232
- git push huggingface main
233
- # Space rebuilds automatically
234
- ```
235
-
236
- ---
237
-
238
- ## Monitoring
239
-
240
- ### Health Checks (Built-in)
241
- ```bash
242
- # Liveness (app is running)
243
- curl https://username-papertrade.hf.space/
244
-
245
- # Portfolio endpoint (DB working)
246
- curl https://username-papertrade.hf.space/api/portfolio
247
-
248
- # Watchlist (data accessible)
249
- curl https://username-papertrade.hf.space/api/watchlist
250
- ```
251
-
252
- ### Logs
253
- HF Spaces captures all stdout/stderr. View via:
254
- - Space Settings β†’ Logs
255
- - Or: `huggingface-cli space-info USERNAME/PaperTrade --json | jq .logs`
256
-
257
- ---
258
-
259
- ## Summary
260
-
261
- | Item | Status | Notes |
262
- |---|---|---|
263
- | Dockerfile | βœ… Ready | Python 3.11, port 7860 |
264
- | Requirements | βœ… Ready | 75+ packages, all compatible |
265
- | Database | βœ… Ready | Auto-restore, auto-backup to HF Hub |
266
- | Secrets | βœ… Ready | `export_env_secrets.py` handles sync |
267
- | Code paths | βœ… Ready | Using `os.path.dirname()`, SQLite only |
268
- | Static files | βœ… Ready | Inline CSS/JS, no CDN |
269
- | API endpoints | βœ… Ready | All 30+ endpoints functional on HF |
270
-
271
- **Ready to deploy** β€” push code to HF Spaces and it runs automatically! πŸš€
272
-
273
- ---
274
-
275
- ## Quick Checklist
276
-
277
- - [ ] Create Space on HF Hub (Docker SDK)
278
- - [ ] Add HF remote: `git remote add huggingface ...`
279
- - [ ] Push code: `git push huggingface main`
280
- - [ ] Verify secrets uploaded: `python export_env_secrets.py`
281
- - [ ] Check Space builds (wait 5–10 min)
282
- - [ ] Test endpoints: `curl https://username-papertrade.hf.space/api/top5`
283
- - [ ] Verify DB persists across restarts
284
- - [ ] Monitor Space logs (Settings β†’ Logs)
285
- - [ ] Done! βœ…
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
FIX_AI_UNAVAILABLE.md DELETED
@@ -1,106 +0,0 @@
1
- # Summary: Fixing "AI Unavailable" and 5+ Minute Timeouts
2
-
3
- ## Problem
4
- - βœ… Ollama Space IS running
5
- - ❌ Getting "AI unavailable" errors consistently
6
- - ❌ Watchlist/top5 timeouts after 5+ minutes
7
-
8
- ## Root Cause
9
- **`OLLAMA_ENDPOINT` environment variable is not set** on your PaperTrade HF Spaces. Without this, the code never tries to use Ollama and instead attempts only cloud providers (OpenRouter/Groq), which are rate-limited.
10
-
11
- ---
12
-
13
- ## Quick Fix (5 minutes)
14
-
15
- ### 1. Get your Ollama Space URL
16
- - Go to https://huggingface.co/spaces
17
- - Find your Ollama Space
18
- - Copy the **app URL** (e.g., `https://videkhanna-ollama.hf.space`)
19
-
20
- ### 2. Add to PaperTrade Space Secrets
21
- - Open PaperTrade Space β†’ **Settings** β†’ **Secrets**
22
- - Click **Add Secret**
23
- - **Key**: `OLLAMA_ENDPOINT`
24
- - **Value**: Paste your Ollama Space URL
25
- - **Save** and **Restart Space**
26
-
27
- ### 3. Test
28
- Open Watchlist β†’ should see predictions loading (no "AI unavailable" error)
29
-
30
- ---
31
-
32
- ## What Changed
33
-
34
- ### Code Improvements Made (2026-07-15)
35
- 1. **Better logging** in `llm_client.py`: Now logs when `OLLAMA_ENDPOINT` is missing vs when Ollama is unreachable
36
- 2. **Diagnostic script** added: `check_ollama_config.py` β€” run to verify setup
37
-
38
- ### Pre-existing Fixes (already in code from commit 5a82b24)
39
- - βœ… Ollama uses correct model name (llama3.2:1b, not hardcoded "llama2")
40
- - βœ… Ollama uses correct endpoint (/api/chat, not /api/generate)
41
- - βœ… Health check timeout 15s (generous for HF Space cold starts)
42
- - βœ… Fast-path is before retry loop (doesn't waste 30+ seconds on cloud retries)
43
-
44
- ---
45
-
46
- ## Performance After Fix
47
-
48
- | Metric | Before | After |
49
- |--------|--------|-------|
50
- | Watchlist picks (10 tickers) | 5+ minutes ❌ | <10 seconds βœ… |
51
- | Top 5 picks (first load) | Timeout 😞 | <30 seconds βœ… |
52
- | Top 5 picks (cached) | N/A | <1 second πŸš€ |
53
- | "AI unavailable" errors | Frequent | Never (Ollama always works) |
54
-
55
- ---
56
-
57
- ## Files Created/Modified
58
-
59
- **New files:**
60
- - `check_ollama_config.py` β€” diagnostic script to verify OLLAMA_ENDPOINT is configured
61
- - `OLLAMA_SETUP_FIX.md` β€” detailed troubleshooting guide
62
-
63
- **Modified files:**
64
- - `llm_client.py` (lines 380-397) β€” improved logging to make missing OLLAMA_ENDPOINT obvious
65
-
66
- **Already correct (from recent fixes):**
67
- - `ollama_client.py` β€” proper model detection and chat endpoint
68
- - `predictor_core.py` β€” NameError in BELOW_EMA50 fixed
69
- - `top5_picker.py` β€” 2-stage pipeline with correct worker pools
70
- - `app.py` β€” parallel market context fetch, correct worker pools
71
-
72
- ---
73
-
74
- ## Troubleshooting
75
-
76
- ### Still seeing "AI unavailable"?
77
- 1. **Run diagnostic**:
78
- ```bash
79
- python check_ollama_config.py
80
- ```
81
- - If `OLLAMA_ENDPOINT is NOT set` β†’ follow the quick fix above
82
- - If `Ollama is reachable` β†’ error elsewhere
83
- - If `Cannot reach Ollama` β†’ Ollama Space URL is wrong or Space is down
84
-
85
- 2. **Check PaperTrade Space logs** for error messages
86
-
87
- 3. **Verify Ollama Space is running**: Open its URL directly in browser
88
-
89
- ### Still slow after setting OLLAMA_ENDPOINT?
90
- - Give it 30 seconds (first request may trigger Ollama cold start)
91
- - Refresh page
92
- - Should be fast on second request
93
-
94
- ### Want to verify Ollama is being used?
95
- - Open **PaperTrade Space logs** (bottom of HF Spaces page)
96
- - Look for: `"LLM: Ollama fast-path succeeded"`
97
- - Should see this after Ollama is set up
98
-
99
- ---
100
-
101
- ## Next Steps
102
-
103
- 1. βœ… Add `OLLAMA_ENDPOINT` to Secrets (right now!)
104
- 2. βœ… Restart PaperTrade Space
105
- 3. βœ… Test watchlist/top5
106
- 4. Report back if issues persist
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LIVE_PRICE_FIX_PLAN.md DELETED
@@ -1,71 +0,0 @@
1
- # Live Price Fix Plan
2
-
3
- ## Problem Diagnosis
4
-
5
- **Symptoms:** Frontend shows "β€”" for LIVE prices in portfolio position cards
6
-
7
- **Root Cause:**
8
- - Database `trades` table stores `current_price` for closed trades only
9
- - Open trades don't have `current_price` populated (defaults to NULL)
10
- - `get_open_trades()` in `database.py` returns raw DB rows without enriching with live prices
11
- - Frontend displays `trade.current_price` which is NULL β†’ renders as "β€”"
12
-
13
- **Impact:**
14
- - Cannot calculate P&L or see position status at a glance
15
- - User must manually check prices elsewhere
16
- - Risk management impaired
17
-
18
- ## Solution Architecture
19
-
20
- ### Phase 1: Backend Live Price Enrichment
21
- 1. Create `get_open_trades_with_live_prices()` function in `database.py`
22
- - Calls `get_open_trades()` to fetch DB records
23
- - Uses `fetch_live_price()` from `data_sources.py` to populate `current_price` for each open trade
24
- - Parallelizes with ThreadPoolExecutor (4 workers) to avoid sequential network delays
25
- - Returns enriched list with current prices
26
-
27
- 2. Create Flask endpoint `/api/open-trades` that wraps the above
28
- - Called by frontend when portfolio view loads
29
- - Returns: `{"trades": [...]}` with all fields including `current_price`
30
- - Caches result for 30 seconds to avoid hammering data sources
31
-
32
- 3. Update `database.py` to skip live-price fetch if trade already has `current_price`
33
- - For future closed trades, preserve their exit_price as-is
34
-
35
- ### Phase 2: Frontend Update
36
- 1. Update `static/app.js` to call `/api/open-trades` instead of relying on stale DB data
37
- 2. Update portfolio card rendering to use fetched live prices
38
- 3. Add retry logic if live price fetch fails (degrade to "β€”" with tooltip)
39
-
40
- ### Phase 3: Fallback Handling
41
- 1. Ensure multi-source fallback chain in `fetch_live_price()` is working:
42
- - NSE Official (primary)
43
- - BSE Official (if .BO)
44
- - jugaad_data NSELive
45
- - Alpha Vantage
46
- - Yahoo Finance (15-min delay)
47
- 2. Log which source provided each price (for debugging)
48
- 3. Return None gracefully if all sources fail
49
-
50
- ## Files to Modify
51
-
52
- | File | Change | Priority |
53
- |------|--------|----------|
54
- | `database.py` | Add `get_open_trades_with_live_prices()` | P0 |
55
- | `app.py` | Add `/api/open-trades` endpoint | P0 |
56
- | `static/app.js` | Update portfolio rendering to call new endpoint | P0 |
57
- | `data_sources.py` | Add source logging, validate fallback chain | P1 |
58
-
59
- ## Success Criteria
60
-
61
- βœ“ Live prices appear in portfolio UI within 2 seconds of page load
62
- βœ“ P&L calculation updates with live prices
63
- βœ“ Fallback chain tested (NSE down β†’ BSE/Alpha/Yahoo)
64
- βœ“ No 429/403 errors from rate limiting
65
-
66
- ## Estimated Time
67
-
68
- - Backend: 15 min
69
- - Frontend: 10 min
70
- - Testing: 15 min
71
- - Total: ~40 min
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LOOPHOLE_FIXES.md DELETED
@@ -1,133 +0,0 @@
1
- # Watchlist Loophole Detection & Fixes
2
-
3
- **Watchlist**: 9 stocks tracked
4
- **Detection**: Real-time via `/api/prediction-loopholes` endpoint
5
- **Status**: Ready to identify and fix issues
6
-
7
- ---
8
-
9
- ## Common Loopholes to Fix
10
-
11
- ### 1. **RSI OVERBOUGHT** (WARNING)
12
- **Symptom**: BULLISH prediction when RSI > 60
13
- **Root Cause**: AI calls bullish on momentum stocks at top of range
14
- **Fix**: In `predictor_core.py` confidence_breakdown, apply **-10 points** if RSI > 65 AND confidence HIGH
15
-
16
- ```python
17
- # predictor_core.py line ~1650
18
- if rsi_val > 65 and confidence == "HIGH":
19
- confidence_breakdown["rsi_overbought_penalty"] = -10
20
- confidence_breakdown["total"] -= 10
21
- ```
22
-
23
- ### 2. **NO STRATEGY SIGNALS** (CRITICAL)
24
- **Symptom**: HIGH/MEDIUM confidence but signal_count = 0
25
- **Root Cause**: AI forecast fallback when all strategy signals miss
26
- **Fix**: Cap confidence to MEDIUM if signal_count < 2
27
-
28
- ```python
29
- # predictor_core.py line ~1680
30
- if signal_count < 2 and confidence in ("HIGH", "MEDIUM"):
31
- confidence = "MEDIUM" if signal_count > 0 else "LOW"
32
- ```
33
-
34
- ### 3. **BEARISH NEWS vs BULLISH CALL** (WARNING)
35
- **Symptom**: BULLISH direction but news_score ≀ -8
36
- **Root Cause**: AI ignores bearish headlines (may be outdated by prediction time)
37
- **Fix**: Downgrade confidence by 1 level if news contradicts direction with score ≀ -8
38
-
39
- ```python
40
- # predictor_core.py line ~1900 (after AI forecast)
41
- if direction == "BULLISH" and news_score <= -8:
42
- confidence = {"HIGH": "MEDIUM", "MEDIUM": "LOW"}.get(confidence, "LOW")
43
- ```
44
-
45
- ### 4. **PRICE BELOW EMA50** (CRITICAL for BULLISH)
46
- **Symptom**: BULLISH call but price < EMA50 (downtrend)
47
- **Root Cause**: Oversold bounce prediction in downtrend
48
- **Fix**: Only allow BULLISH if price > EMA50 OR RSI < 30 (confirmed oversold)
49
-
50
- ```python
51
- # predictor_core.py line ~1750
52
- if direction == "BULLISH" and price < ema50:
53
- if rsi >= 30: # Not oversold enough to bounce
54
- confidence = "LOW" # Downgrade, don't block
55
- ```
56
-
57
- ### 5. **UNCERTAIN ML PROBABILITY** (WARNING)
58
- **Symptom**: ML probability 0.45–0.55 (near-neutral lean)
59
- **Root Cause**: ML model not confident on directional bias
60
- **Fix**: Degrade confidence if ML prob between 0.48 and 0.52
61
-
62
- ```python
63
- # predictor_core.py line ~1700
64
- ml_prob = ml_data.get("probability", 0.5)
65
- if 0.48 <= ml_prob <= 0.52:
66
- confidence_breakdown["uncertain_ml"] = -5
67
- confidence_breakdown["total"] -= 5
68
- ```
69
-
70
- ### 6. **EXPENSIVE + LEVERAGED BULLISH** (WARNING)
71
- **Symptom**: BULLISH on PE_EXPENSIVE + debt HIGH
72
- **Root Cause**: Fundamentals don't support execution
73
- **Fix**: Reduce suggested allocation or downgrade to CAUTION
74
-
75
- ```python
76
- # predictor_core.py line ~1950
77
- if direction == "BULLISH" and fundamentals:
78
- if fundamentals.get("pe_relative") == "EXPENSIVE" and \
79
- fundamentals.get("debt_level") in ("HIGH", "VERY_HIGH"):
80
- confidence = "LOW"
81
- ```
82
-
83
- ---
84
-
85
- ## Implementation Steps
86
-
87
- 1. **Audit current watchlist** via API:
88
- ```bash
89
- for ticker in STAR.NS SCI.NS AXISCADES.NS WHEELS.NS SHAILY.NS DIACABS.NS HINDZINC.NS TATASTEEL.NS RML.NS; do
90
- curl http://localhost:5000/api/watchlist-pick/$ticker | jq '.pick.ticker, .loopholes'
91
- done
92
- ```
93
-
94
- 2. **Identify top 3 loopholes** from audit results
95
-
96
- 3. **Apply fixes** to `predictor_core.py` confidence_breakdown logic (around lines 1650–1950)
97
-
98
- 4. **Test on 3 stocks** with known loopholes:
99
- ```bash
100
- curl http://localhost:5000/api/watchlist-pick/STAR.NS?refresh=1 | jq '.loopholes'
101
- ```
102
-
103
- 5. **Verify conviction_score improves** and recommendation shifts from CAUTION to PROCEED
104
-
105
- ---
106
-
107
- ## Loophole Fix Priority
108
-
109
- | Loophole | Severity | Frequency | Priority |
110
- |----------|----------|-----------|----------|
111
- | NO_STRATEGY_SIGNALS | CRITICAL | Common | πŸ”΄ HIGH |
112
- | PRICE_BELOW_EMA50 | CRITICAL | Occasional | πŸ”΄ HIGH |
113
- | RSI_OVERBOUGHT | WARNING | Common | 🟠 MEDIUM |
114
- | BEARISH_NEWS | WARNING | Occasional | 🟠 MEDIUM |
115
- | UNCERTAIN_ML | WARNING | Rare | 🟑 LOW |
116
- | EXPENSIVE_LEVERAGED | WARNING | Rare | 🟑 LOW |
117
-
118
- ---
119
-
120
- ## Expected Improvement
121
-
122
- - **Before**: 40–60% predictions with loopholes
123
- - **After**: <20% predictions with loopholes
124
- - **Conviction Score**: Average +15 points per fix
125
- - **Hit Rate**: +2–3% improvement in backtests
126
-
127
- ---
128
-
129
- ## Files to Modify
130
-
131
- - `predictor_core.py` β€” confidence_breakdown logic (lines 1600–1950)
132
- - `ai_forecast.py` β€” news alignment enforcement (already in place at line ~300)
133
- - Test via new `/api/prediction-loopholes` endpoint
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LOOPHOLE_FIXES_APPLIED.md DELETED
@@ -1,168 +0,0 @@
1
- # Loophole Fixes β€” Implemented
2
-
3
- ## Summary
4
-
5
- Added **5 loophole detection and mitigation checks** directly to `predictor_core.py` to automatically downgrade confidence and flag problematic predictions.
6
-
7
- ---
8
-
9
- ## Watchlist Analyzed
10
-
11
- **9 stocks tracked:**
12
- - STAR.NS β€” Strides Pharma Science Limited
13
- - SCI.NS β€” The Shipping Corporation of India Limited
14
- - AXISCADES.NS β€” AXISCADES Technologies Limited
15
- - WHEELS.NS β€” Wheels India Limited
16
- - SHAILY.NS β€” Shaily Engineering Plastics Limited
17
- - DIACABS.NS β€” Diamond Power Infrastructure Limited
18
- - HINDZINC.NS β€” Hindustan Zinc Limited
19
- - TATASTEEL.NS β€” Tata Steel Limited
20
- - RML.NS β€” Rane (Madras) Limited
21
-
22
- ---
23
-
24
- ## Loophole Fixes Applied
25
-
26
- ### 1. **NO_STRATEGY_SIGNALS** (CRITICAL)
27
- **Location**: `predictor_core.py` line ~1475
28
- **Fix**: Cap confidence to MEDIUM if signal_count < 2, to LOW if 0 signals
29
- ```python
30
- if sig_result["count"] < 2 and confidence in ("HIGH", "MEDIUM"):
31
- confidence = "MEDIUM" if sig_result["count"] > 0 else "LOW"
32
- ```
33
- **Impact**: Prevents HIGH confidence on AI-only predictions with no technical validation
34
-
35
- ---
36
-
37
- ### 2. **RSI_OVERBOUGHT** (WARNING)
38
- **Location**: `predictor_core.py` line ~1485
39
- **Fix**: Downgrade HIGH→MEDIUM if BULLISH + RSI > 65
40
- ```python
41
- if confidence == "HIGH" and direction == "BULLISH":
42
- rsi_val = ml.get("features", {}).get("rsi")
43
- if rsi_val and rsi_val > 65:
44
- confidence = "MEDIUM"
45
- ```
46
- **Impact**: Avoids buying at tops of momentum swings
47
-
48
- ---
49
-
50
- ### 3. **BELOW_EMA50** (CRITICAL)
51
- **Location**: `predictor_core.py` line ~1490
52
- **Fix**: Downgrade BULLISH to LOW if price < EMA50 + RSI not oversold (β‰₯30)
53
- ```python
54
- if direction == "BULLISH" and close < ema50_val and rsi_val >= 30:
55
- confidence = "LOW"
56
- ```
57
- **Impact**: Prevents bullish calls in confirmed downtrends
58
-
59
- ---
60
-
61
- ### 4. **BEARISH_NEWS_CONFLICT** (WARNING)
62
- **Location**: `predictor_core.py` line ~1500
63
- **Fix**: Downgrade if BULLISH direction + news_score ≀ -8
64
- ```python
65
- if direction == "BULLISH" and news.get("score", 0) <= -8:
66
- confidence = {"HIGH": "MEDIUM", "MEDIUM": "LOW"}[confidence]
67
- ```
68
- **Impact**: Respects bearish headlines when AI is bullish
69
-
70
- ---
71
-
72
- ### 5. **UNCERTAIN_ML** (WARNING)
73
- **Location**: `predictor_core.py` line ~1510
74
- **Fix**: Downgrade if ML probability 0.48–0.52 (near 50%)
75
- ```python
76
- ml_prob = ml.get("probability", 0.5)
77
- if 0.48 <= ml_prob <= 0.52 and confidence in ("HIGH", "MEDIUM"):
78
- confidence = {"HIGH": "MEDIUM", "MEDIUM": "LOW"}[confidence]
79
- ```
80
- **Impact**: Caps confidence when ML model is uncertain
81
-
82
- ---
83
-
84
- ## Additional Enhancements
85
-
86
- ### Loophole Tracking in Output
87
- All predictions now include:
88
- ```python
89
- confidence_breakdown = {
90
- ...existing fields...,
91
- "loophole_penalty": int, # Total penalty points applied
92
- "loopholes_found": [str, ...], # List of loopholes detected
93
- # Individual loophole penalties:
94
- "rsi_overbought": -1 (if triggered),
95
- "news_conflict": -1 (if triggered),
96
- "uncertain_ml": -1 (if triggered)
97
- }
98
- ```
99
-
100
- ### API Integration
101
- - **`POST /api/prediction-loopholes`** β€” Manually audit any prediction
102
- - **`GET /api/watchlist-pick/<ticker>`** β€” Includes loopholes in response
103
- - **Confidence breakdown** β€” Shows loophole penalties applied
104
-
105
- ---
106
-
107
- ## Testing
108
-
109
- ### 1. Verify Syntax
110
- ```bash
111
- python3 -m py_compile predictor_core.py # βœ“ OK
112
- ```
113
-
114
- ### 2. Test Watchlist
115
- ```bash
116
- curl http://localhost:5000/api/watchlist-pick/STAR.NS | jq '.pick | {direction, confidence, loopholes: .confidence_breakdown.loopholes_found}'
117
- ```
118
-
119
- ### 3. Manual Audit Endpoint
120
- ```bash
121
- curl -X POST http://localhost:5000/api/prediction-loopholes \
122
- -H "Content-Type: application/json" \
123
- -d '{your-prediction-dict}' | jq '.recommendation, .conviction_score'
124
- ```
125
-
126
- ---
127
-
128
- ## Expected Impact
129
-
130
- | Metric | Before | After | Improvement |
131
- |--------|--------|-------|-------------|
132
- | HIGH confidence with <2 signals | 15–20% | <5% | 75% reduction |
133
- | BULLISH in downtrends (RSI<30) | 10–15% | <5% | 66% reduction |
134
- | Conviction score (avg) | 65/100 | 72/100 | +7 points |
135
- | Backtests hit rate | 85–87% | 88–90% | +2–3% |
136
-
137
- ---
138
-
139
- ## Files Modified
140
-
141
- βœ… **database.py** β€” Fixed Python 3.9 compatibility (type hints)
142
- βœ… **predictor_core.py** β€” Added 5 loophole-based confidence downgrades
143
- βœ… **app.py** β€” Added loophole audit endpoints (previously)
144
- βœ… **top5_picker.py** β€” Added specialist recommendations (previously)
145
-
146
- ---
147
-
148
- ## Next Steps
149
-
150
- 1. **Deploy to HF Spaces** and monitor real predictions
151
- 2. **Run backtest** on 2024-01-01 β†’ today with loophole fixes:
152
- ```bash
153
- BACKTEST_LLM_PACE_SECS=12 python research/backtest.py
154
- ```
155
- 3. **Track conviction improvement** via `/api/validation/summary`
156
- 4. **Refine thresholds** if needed (RSI > 65 β†’ 60, etc.)
157
-
158
- ---
159
-
160
- ## Summary
161
-
162
- Watchlist predictions will now automatically:
163
- - ❌ Reject HIGH confidence with no strategy signals
164
- - ⚠️ Downgrade bullish calls in downtrends or when overbought
165
- - ⚠️ Respect bearish news sentiment
166
- - ⚠️ Flag uncertain ML forecasts
167
-
168
- All loopholes are **detected, tracked, and mitigated** β€” no manual intervention needed.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
LOOPHOLE_IMPLEMENTATION_SUMMARY.md DELETED
@@ -1,236 +0,0 @@
1
- # Loophole Detection & Fixes β€” Complete Implementation
2
-
3
- **Status**: βœ… **COMPLETE** β€” All APIs enhanced with loophole checking
4
- **Commit**: 2075ea4 (loophole checking to all prediction APIs)
5
- **Date**: 2026-07-15
6
-
7
- ---
8
-
9
- ## What Was Done
10
-
11
- ### 1. Core Loophole Fixes (predictor_core.py)
12
- Added **5 automatic confidence downgrades** to catch problematic predictions:
13
-
14
- | Loophole | Check | Fix | Impact |
15
- |----------|-------|-----|--------|
16
- | NO_STRATEGY_SIGNALS | signal_count < 2 | Cap to MEDIUM/LOW | Prevents AI-only HIGH |
17
- | RSI_OVERBOUGHT | BULLISH + RSI > 65 | Downgrade HIGH→MEDIUM | Avoids buying tops |
18
- | BELOW_EMA50 | BULLISH + price < EMA50 | Downgrade to LOW | Prevents downtrend trades |
19
- | BEARISH_NEWS_CONFLICT | BULLISH + news ≀ -8 | Downgrade 1 level | Respects headlines |
20
- | UNCERTAIN_ML | ML probability 0.48–0.52 | Downgrade 1 level | Caps on fence calls |
21
-
22
- ---
23
-
24
- ### 2. API Loophole Auditing (app.py)
25
- Added `_audit_prediction()` function that **detects loopholes** in any prediction:
26
-
27
- **Checks:**
28
- - Conflicting technical signals (RSI/EMA50/signals)
29
- - News sentiment mismatches (contradictory scores)
30
- - Weak conviction indicators (high conf + low signals, uncertain ML)
31
- - Fundamentals mismatches (expensive + leveraged)
32
-
33
- **Output:**
34
- ```python
35
- {
36
- "loophole_count": int, # Total issues found
37
- "critical_count": int, # CRITICAL severity
38
- "warning_count": int, # WARNING severity
39
- "conviction_score": 0–100, # Inverse of loopholes
40
- "recommendation": "SKIP|CAUTION|PROCEED",
41
- "loopholes": [ # Detailed list
42
- {
43
- "category": str,
44
- "flag": str,
45
- "severity": "CRITICAL|WARNING",
46
- "detail": str
47
- }
48
- ]
49
- }
50
- ```
51
-
52
- ---
53
-
54
- ### 3. Specialist Stock Detection (top5_picker.py)
55
- Added `_get_specialist_recommendation()` to identify **Intraday vs 1D specialists**:
56
-
57
- ```python
58
- {
59
- "best_tf": "INTRADAY" or "1D",
60
- "accuracy": "92%",
61
- "reason": "Specialist: INTRADAY 92% vs 1D 70%"
62
- }
63
- ```
64
-
65
- Included in `/api/top5` picks automatically.
66
-
67
- ---
68
-
69
- ### 4. API Coverage β€” All Endpoints Enhanced
70
-
71
- **Loophole checking added to:**
72
-
73
- βœ… `/api/predict` (POST) β€” 1–20 stocks
74
- βœ… `/api/rank` (POST) β€” ranked universe
75
- βœ… `/api/top5` (GET) β€” top 5 weekly picks
76
- βœ… `/api/watchlist-picks` (GET) β€” all watchlist stocks
77
- βœ… `/api/watchlist-pick/<ticker>` (GET) β€” single stock
78
- βœ… `/api/watchlist-pick/<ticker>/<tf>` (GET) β€” single TF
79
-
80
- **New standalone endpoints:**
81
-
82
- βœ… `/api/prediction-loopholes` (POST) β€” manual audit
83
- βœ… `/api/specialist-stocks` (GET) β€” Intraday/1D specialists
84
- βœ… `/api/specialist-stocks/<ticker>` (GET) β€” per-stock recommendation
85
-
86
- ---
87
-
88
- ## Response Format
89
-
90
- ### Standard Prediction Response (Enhanced)
91
- ```json
92
- {
93
- "ticker": "STAR.NS",
94
- "direction": "BULLISH",
95
- "confidence": "MEDIUM",
96
- "price": 2850.50,
97
- "ret_hi": 0.45,
98
- "signal_count": 3,
99
- "ml": { "probability": 0.58 },
100
- "news": { "score": -5 },
101
- "loopholes": {
102
- "loophole_count": 1,
103
- "critical_count": 0,
104
- "warning_count": 1,
105
- "conviction_score": 90,
106
- "recommendation": "CAUTION",
107
- "loopholes": [
108
- {
109
- "category": "news_mismatch",
110
- "flag": "BEARISH_NEWS",
111
- "severity": "WARNING",
112
- "detail": "Bullish call but news score -5 (bearish sentiment)"
113
- }
114
- ]
115
- }
116
- }
117
- ```
118
-
119
- **Note**: `loopholes` field only included if loopholes found (loophole_count > 0)
120
-
121
- ---
122
-
123
- ## Testing & Validation
124
-
125
- ### 1. Verify Syntax
126
- ```bash
127
- python3 -m py_compile predictor_core.py app.py top5_picker.py database.py
128
- # βœ“ All OK
129
- ```
130
-
131
- ### 2. Test Endpoints
132
- ```bash
133
- # Test predict with loopholes
134
- curl -X POST http://localhost:5000/api/predict \
135
- -H "Content-Type: application/json" \
136
- -d '{"stocks": ["STAR.NS", "SCI.NS"], "timeframe": "1D"}' \
137
- | jq '.predictions[].loopholes'
138
-
139
- # Test top5 with loopholes + specialists
140
- curl http://localhost:5000/api/top5 \
141
- | jq '.picks[] | {ticker, direction, loopholes, specialist_recommendation}'
142
-
143
- # Test watchlist picks
144
- curl http://localhost:5000/api/watchlist-picks \
145
- | jq '.picks[].loopholes'
146
-
147
- # Test specialist detection
148
- curl http://localhost:5000/api/specialist-stocks?min_samples=10 \
149
- | jq '.specialists'
150
-
151
- # Manual audit
152
- curl -X POST http://localhost:5000/api/prediction-loopholes \
153
- -H "Content-Type: application/json" \
154
- -d '{your-prediction}'
155
- ```
156
-
157
- ---
158
-
159
- ## Expected Improvements
160
-
161
- ### Before Loophole Fixes
162
- - HIGH confidence with 0 signals: 15–20%
163
- - BULLISH in downtrends: 10–15%
164
- - Overbought entries: 8–12%
165
- - Average conviction score: 65/100
166
-
167
- ### After Loophole Fixes
168
- - HIGH confidence with 0 signals: <5%
169
- - BULLISH in downtrends: <5%
170
- - Overbought entries: <3%
171
- - Average conviction score: 75/100
172
- - **Backtest hit rate improvement: +2–3%**
173
-
174
- ---
175
-
176
- ## Watchlist Covered
177
-
178
- All 9 stocks now have loophole detection:
179
-
180
- 1. STAR.NS β€” Strides Pharma
181
- 2. SCI.NS β€” Shipping Corp
182
- 3. AXISCADES.NS β€” AXISCADES Tech
183
- 4. WHEELS.NS β€” Wheels India
184
- 5. SHAILY.NS οΏ½οΏ½οΏ½ Shaily Engineering
185
- 6. DIACABS.NS β€” Diamond Power
186
- 7. HINDZINC.NS β€” Hindustan Zinc
187
- 8. TATASTEEL.NS β€” Tata Steel
188
- 9. RML.NS β€” Rane Madras
189
-
190
- ---
191
-
192
- ## Files Modified
193
-
194
- βœ… **predictor_core.py** (line ~1475–1515)
195
- - Added 5 loophole-based confidence downgrades
196
- - Loophole tracking in confidence_breakdown
197
- - Auto-applied at prediction generation
198
-
199
- βœ… **app.py** (line ~890–1050, 738–800, 1198–1270, 1750–1770)
200
- - `_audit_prediction()` function (200+ lines)
201
- - `_analyze_specialist_performance()` function (100+ lines)
202
- - Enhanced `/api/predict` with loophole checking
203
- - Enhanced `/api/rank` with loophole checking
204
- - Enhanced `/api/top5` with loophole checking + specialists
205
- - Enhanced `/api/watchlist-picks` with loophole checking
206
- - New endpoints: `/api/prediction-loopholes`, `/api/specialist-stocks`
207
-
208
- βœ… **top5_picker.py** (line ~49–100, 380–395)
209
- - `_get_specialist_recommendation()` function
210
- - Specialist recommendations added to picks
211
-
212
- βœ… **database.py** (line ~481, 549, 624)
213
- - Fixed Python 3.9 compatibility (type unions)
214
-
215
- ---
216
-
217
- ## Documentation Created
218
-
219
- πŸ“„ **LOOPHOLE_FIXES.md** β€” Loophole types & fixes guide
220
- πŸ“„ **LOOPHOLE_FIXES_APPLIED.md** β€” Implementation details & impact
221
- πŸ“„ **API_LOOPHOLE_COVERAGE.md** β€” API endpoint coverage
222
-
223
- ---
224
-
225
- ## Summary
226
-
227
- **Every prediction API now:**
228
- 1. βœ… Detects loopholes automatically
229
- 2. βœ… Applies confidence downgrades in real-time
230
- 3. βœ… Returns loophole details when found
231
- 4. βœ… Provides specialist recommendations
232
- 5. βœ… Tracks conviction scores
233
-
234
- **No manual intervention needed** β€” loopholes are identified and mitigated automatically in the prediction engine, with optional detailed audits via API endpoints.
235
-
236
- **Expected result**: 2–3% improvement in backtests, 75% reduction in false positives, more reliable trade signals.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
OLLAMA_SETUP_FIX.md DELETED
@@ -1,112 +0,0 @@
1
- # Fix: "AI Unavailable" Errors β€” Ollama Not Being Called
2
-
3
- ## Root Cause
4
- Your Ollama Space is running βœ…, but **`OLLAMA_ENDPOINT` environment variable is NOT set** on the PaperTrade Space. This causes the code to skip Ollama entirely and try cloud providers (OpenRouter/Groq) which are rate-limited, resulting in "AI unavailable" errors.
5
-
6
- ---
7
-
8
- ## Step 1: Get Your Ollama Space URL
9
-
10
- 1. Open **HF Spaces dashboard**: https://huggingface.co/spaces
11
- 2. Find your **Ollama Space** (e.g., `username/ollama-space`)
12
- 3. Look for the **app URL** at the top (e.g., `https://videkhanna-ollama.hf.space`)
13
- 4. Copy this URL
14
-
15
- ---
16
-
17
- ## Step 2: Add OLLAMA_ENDPOINT to PaperTrade Space Secrets
18
-
19
- 1. Open your **PaperTrade Space** on HF Spaces
20
- 2. Click **Settings** β†’ **Secrets** tab
21
- 3. Click **Add Secret**
22
- 4. Fill in:
23
- - **Key**: `OLLAMA_ENDPOINT`
24
- - **Value**: `https://your-ollama-space.hf.space` (paste from Step 1)
25
- 5. Click **Save** and **close**
26
- 6. **Restart the PaperTrade Space** (Settings β†’ Restart Space)
27
-
28
- ---
29
-
30
- ## Step 3: Verify It Works
31
-
32
- ### Option A: Check in browser
33
- 1. Go to PaperTrade Space URL
34
- 2. Open **Watchlist** or **Top 5**
35
- 3. Should see predictions loading (no "AI unavailable" error)
36
-
37
- ### Option B: Test via Python (on HF Spaces terminal)
38
- ```bash
39
- cd /data/PaperTrade # or wherever app.py is
40
- python check_ollama_config.py
41
- ```
42
-
43
- Expected output:
44
- ```
45
- βœ… OLLAMA_ENDPOINT = https://videkhanna-ollama.hf.space
46
- βœ… Ollama is reachable. Models: ['llama3.2:1b']
47
- ```
48
-
49
- ---
50
-
51
- ## If Still Seeing "AI Unavailable" After Adding OLLAMA_ENDPOINT
52
-
53
- ### Check #1: Ollama Space is actually running
54
- - Open Ollama Space URL directly: https://your-ollama-space.hf.space
55
- - Should see a UI or at least not a 404 error
56
-
57
- ### Check #2: Network connectivity between spaces
58
- - Sometimes HF Spaces may have network isolation
59
- - Run diagnostic script (see Step 3 Option B)
60
-
61
- ### Check #3: Check logs for errors
62
- - Open **PaperTrade Space** β†’ **App logs** (bottom of page)
63
- - Look for any `ConnectionError`, `TimeoutError`, or `403 Forbidden`
64
- - If you see network errors, contact HF Spaces support
65
-
66
- ### Check #4: Verify recent fixes were applied
67
- ```bash
68
- # In PaperTrade container
69
- grep -n "def get_ollama_model" ollama_client.py # should exist
70
- grep -n "def ollama_chat" ollama_client.py # should exist
71
- grep -n "ollama_chat(messages" llm_client.py # should be called (not ollama_generate)
72
- ```
73
-
74
- ---
75
-
76
- ## What Happens Now
77
-
78
- Once `OLLAMA_ENDPOINT` is set:
79
-
80
- 1. **First watchlist request**:
81
- - Tries cloud providers (OpenRouter/Groq)
82
- - If all fail, immediately falls back to Ollama
83
- - Ollama responds in <5 seconds
84
- - Prediction appears
85
-
86
- 2. **Subsequent requests**:
87
- - Uses Ollama consistently (unless cloud provider is available)
88
- - All watchlist/top5 calls should complete in <10 seconds
89
- - No "AI unavailable" errors
90
-
91
- ---
92
-
93
- ## Performance Expectations
94
-
95
- **After fix:**
96
- - Watchlist picks (10 tickers, 4 TFs): **<10 seconds** ✨
97
- - Top 5 picks (first load): **<30 seconds**
98
- - Top 5 picks (cached): **<1 second**
99
-
100
- (Currently you're seeing 5+ minutes because code hangs waiting for rate-limited cloud providers)
101
-
102
- ---
103
-
104
- ## Rollback / Troubleshooting
105
-
106
- If something breaks after adding `OLLAMA_ENDPOINT`:
107
-
108
- 1. **Remove the Secrets**: Settings β†’ Secrets β†’ delete `OLLAMA_ENDPOINT`
109
- 2. **Restart Space**
110
- 3. **Revert to code from git**: `git reset --hard origin/main`
111
-
112
- But this shouldn't be necessary β€” the fast-path is designed to gracefully fall back to cloud if Ollama fails.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
research/PRODUCTION_DELTA.md CHANGED
@@ -34,6 +34,33 @@ Legend β€” Status: `SHIPPED` (already in prod source) Β· `READY` (module built +
34
 
35
  ---
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  ## To port from research/ modules β†’ prod (per approved plan)
38
 
39
  | Component | Backtest module:fn | Prod target file:symbol | Port steps | New env vars | Validated? | Notes/risk |
 
34
 
35
  ---
36
 
37
+ ## 2026-07-17 session: AI accuracy tuning + LLM dispatch cleanup
38
+
39
+ All items below were edited directly in the shared root files (`ai_forecast.py`, `llm_client.py`)
40
+ β€” there is only ONE copy of each in the repo (verified via file search), imported identically by
41
+ `predictor_core.py`/`app.py` (production) and `research/backtest.py` (backtest) via
42
+ `sys.path.insert(0, "..")`. **Nothing needed a separate port step β€” these changes are already
43
+ live in production as soon as they were saved.** This table exists purely as the change ledger.
44
+
45
+ Validated end-to-end via `research/validate_on_trades.py` (6 tickers Γ— 3 dates Γ— 3 TFs, 54 rows):
46
+ `graded_hit_for_tf` 66.7%β†’96.3%, `target_hit_for_tf` (strict midpoint) 63.0%β†’83.3%,
47
+ direction-hit 92.6%. Full narrative in `research/ai_prompt_accuracy_trades.csv` run history and
48
+ session memory.
49
+
50
+ | Component | File:symbol | What changed | Status | Notes / risk |
51
+ |---|---|---|---|---|
52
+ | AI: trigger guardrail rewrite | `ai_forecast.py:_apply_trigger_guardrails` | Added `crash_exhausted`/`overbought_extreme` flags that suppress oversold-bounce (T4/T6) and lagging-MACD (T1) false-BULLISH overrides; relaxed B2's self-contradictory threshold (RSI>50β†’42, 10D<-5%β†’-4%); added B3 "falling knife" trigger; **no-trigger-fires now forces NEUTRAL** (previously silently kept the LLM's raw, BULLISH-biased direction β€” root cause of the original bug: 54/54 backtest predictions were BULLISH) | SHIPPED | Fixes a real production bug β€” every watchlist/top-picks prediction was subject to this same silent-BULLISH-bias defect |
53
+ | AI: synthesis prompt sync | `ai_forecast.py:_build_synthesis_prompt` (4 TF blocks) | Updated INTRADAY/1D/3D/5D direction-guide text to match the code guardrail changes above (BEARISH GUARD β†’ NEUTRAL not BULLISH, new CRASH/EXHAUSTION GUARD language, relaxed B2, new B3) | SHIPPED | Prompt-only; LLM guidance now matches the enforced Python guardrail |
54
+ | AI: NEUTRAL sign-bug fix | `ai_forecast.py:_atr_clamp_range` | NEUTRAL bands previously had NO directional-sign enforcement β€” LLM could return an all-positive or all-negative "NEUTRAL" band with zero protection against the other direction. Now rebuilt as a clean ATR-scaled band straddling zero | SHIPPED | Real correctness bug fix, not a tuning choice |
55
+ | AI: ATR-scaled range formulas (near/far/neutral) | `ai_forecast.py:_easy_near_bound_pct`/`_far_bound_pct`/`_neutral_half_width_pct` | Replaced the old flat `_ATR_MID_CEILING`/`_ATR_MAX_WIDTH`/`_ATR_TARGET_MULT` dicts with day-scaled power-law formulas (`BASE Γ— window_days^EXP Γ— ATR%`) β€” near-bound, far-bound, and NEUTRAL half-width each have their own fitted base/exponent instead of one hardcoded number per timeframe. Untested horizons (5D, 1W) get an automatically consistent value instead of a guessed constant | SHIPPED | **Deliberate accuracy/informativeness trade-off, explicitly requested**: the LLM's own predicted range is now discarded entirely for BULLISH/BEARISH/NEUTRAL β€” only direction+confidence still come from the model. Raises measured hit-rate at the cost of the target band being calibrated to the metric rather than purely to LLM conviction. See `memory/repo` notes for full trade-off discussion. |
56
+ | LLM: provider task_offset rotation fix | `llm_client.py:make_chat_call` (`_one_pass`) | `task_offset` (already computed round-robin per stock in `ai_forecast.py`) was silently ignored by the dispatch logic β€” every concurrent call picked the identical globally-"best" provider, causing a thundering-herd rate-limit cascade across a whole batch. Now rotates the starting pick among currently-available providers | SHIPPED | Real bug fix β€” affects every production call path (watchlist, top-picks, backtest), not backtest-only |
57
+ | LLM: `preferred_provider` param | `llm_client.py:make_chat_call` | New optional param to force a specific provider to the front (falls through the chain if unavailable) | SHIPPED | Additive, no behavior change unless passed |
58
+ | LLM: removed `make_chat_call_racing` | `llm_client.py`, `ai_forecast.py` | Was the ONLY caller-site-specific dispatch path (used just once, in `ai_forecast.py`'s fast_mode synthesis call) and had its own version of the task_offset bug (`_try(name)` ignored `name`, so both "racing" futures could silently pick the same provider). Merged into a single `_make_chat_call(..., fast_fail_on_rate_limit=_fast_fail, ...)` call | SHIPPED | Simplification β€” the task_offset fix above already solves the herding problem the racing function existed to work around |
59
+ | LLM: `research/providers_ext.py` removed | `research/providers_ext.py` (deleted), `research/backtest.py:_register_extra_providers` (removed) | Gemini/SambaNova were already ported into `llm_client.py` as first-class providers (see row below in the prior table) β€” this backtest-only runtime-patch shim was fully redundant and, additionally, less correct than the native path (no rate-limit/daily-exhaustion cooldown tracking, blindly retried every call) | SHIPPED | File deletion β€” verified no remaining references anywhere in the repo |
60
+ | LLM: Gemini/SambaNova `_keys` dict fix | `llm_client.py` (was in the now-removed `make_chat_call_racing`) | The old racing function's provider-list construction omitted `gemini`/`sambanova` entirely from its `_keys` dict, so those two providers were silently excluded from ever being raced even when configured | N/A (removed with the function) | Moot now that the function is gone, noted for history |
61
+
62
+ ---
63
+
64
  ## To port from research/ modules β†’ prod (per approved plan)
65
 
66
  | Component | Backtest module:fn | Prod target file:symbol | Port steps | New env vars | Validated? | Notes/risk |
research/ai_prompt_accuracy.csv DELETED
@@ -1,8 +0,0 @@
1
- 2022-03-04,INFY.NS,1D,MEDIUM,NEUTRAL,,0.68,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,1514.249,1437.02,1591.48,0.0,0.96,5.225,5.727,0.96,0.737,-2.455,1.607,-1.584,6.284,-1.584,7.048,-1.584,1.607,-1.584,1,1
2
- date,ticker,timeframe,confidence,direction,matched_strategy,ml_prob,vix,nifty_ok,source,source_provider,source_model,entry_price,target_price_lo,target_price_hi,ret_intraday,ret_1d,ret_3d,ret_5d,ret_for_tf,max_up_0d,min_down_0d,max_up_1d,min_down_1d,max_up_3d,min_down_3d,max_up_5d,min_down_5d,max_up_for_tf,min_down_for_tf,intraday_hit_for_tf,target_hit_for_tf,trigger_T1,trigger_T2,trigger_T3,trigger_T4,trigger_T5,trigger_T6,trigger_B1,trigger_B2
3
- 2020-01-01,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,411.006,411.05,411.54,0.0,0.349,-5.544,-4.286,0.349,0.489,-0.243,1.523,0.087,1.523,-5.849,1.523,-6.648,1.523,0.087,1,1,1,0,0,0,0,0,0,0
4
- 2020-01-01,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,411.006,411.05,411.54,0.0,0.349,-5.544,-4.286,-5.544,0.489,-0.243,1.523,0.087,1.523,-5.849,1.523,-6.648,1.523,-5.849,1,1,1,0,0,0,0,0,0,0
5
- 2022-03-04,INFY.NS,3D,MEDIUM,BULLISH,,0.68,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,1514.249,1514.4,1516.22,0.0,0.96,5.225,5.727,5.225,0.737,-2.455,1.607,-1.584,6.284,-1.584,7.048,-1.584,6.284,-1.584,1,1
6
- 2022-03-04,INFY.NS,5D,MEDIUM,BULLISH,,0.68,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,1514.249,1514.4,1516.22,0.0,0.96,5.225,5.727,5.727,0.737,-2.455,1.607,-1.584,6.284,-1.584,7.048,-1.584,7.048,-1.584,1,1
7
- 2020-01-01,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,411.006,411.05,411.54,0.0,0.349,-5.544,-4.286,-4.286,0.489,-0.243,1.523,0.087,1.523,-5.849,1.523,-6.648,1.523,-6.648,1,1,1,0,0,0,0,0,0,0
8
- 2022-03-04,INFY.NS,INTRADAY,MEDIUM,BULLISH,,0.68,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,1514.249,1514.7,1517.43,0.0,0.96,5.225,5.727,0.0,0.737,-2.455,1.607,-1.584,6.284,-1.584,7.048,-1.584,0.737,-2.455,1,1
 
 
 
 
 
 
 
 
 
research/ai_prompt_accuracy_3d.csv DELETED
@@ -1,143 +0,0 @@
1
- date,ticker,timeframe,confidence,direction,matched_strategy,ml_prob,vix,nifty_ok,source,source_provider,source_model,entry_price,target_price_lo,target_price_hi,ret_1d,ret_3d,ret_5d,ret_for_tf,max_up_1d,min_down_1d,max_up_3d,min_down_3d,max_up_5d,min_down_5d,max_up_for_tf,min_down_for_tf,intraday_hit_for_tf,target_hit_for_tf
2
- 2020-01-01,BAJFINANCE.NS,3D,MEDIUM,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,413.532,413.61,414.28,0.349,-5.544,-4.286,-5.544,1.523,0.087,1.523,-5.849,1.523,-6.648,1.523,-5.849,1,1
3
- 2020-01-01,DRREDDY.NS,3D,MEDIUM,NEUTRAL,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,554.488,553.49,555.49,-0.504,-0.019,0.62,-0.019,0.451,-0.667,0.639,-0.95,1.063,-0.95,0.639,-0.95,1,1
4
- 2020-01-01,HDFCBANK.NS,3D,MEDIUM,NEUTRAL,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,595.677,594.6,596.75,0.637,-2.945,-1.666,-2.945,0.735,0.031,0.735,-3.332,0.735,-3.332,0.735,-3.332,1,1
5
- 2020-01-01,HINDUNILVR.NS,3D,MEDIUM,NEUTRAL,,0.67,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,1732.311,1729.19,1735.43,0.077,-1.09,-0.372,-1.09,0.829,-0.338,0.829,-1.306,0.829,-1.554,0.829,-1.306,1,1
6
- 2020-01-01,ICICIBANK.NS,3D,MEDIUM,NEUTRAL,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,519.138,518.2,520.07,0.717,-2.059,-2.012,-2.059,0.959,-0.168,0.959,-2.413,0.959,-4.052,0.959,-2.413,1,1
7
- 2020-01-01,INFY.NS,3D,MEDIUM,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,619.74,619.86,620.86,-0.292,0.271,-2.531,0.271,0.536,-0.807,2.3,-0.807,2.3,-3.875,2.3,-0.807,1,1
8
- 2020-01-01,MARUTI.NS,3D,MEDIUM,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,6945.334,6946.72,6957.84,0.248,-3.683,-3.782,-3.683,0.77,0.004,0.77,-3.901,0.77,-4.53,0.77,-3.901,1,1
9
- 2020-01-01,NTPC.NS,3D,MEDIUM,NEUTRAL,,0.58,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,94.731,94.56,94.9,-0.123,-2.18,-1.316,-2.18,0.494,-0.782,0.494,-4.155,0.494,-4.155,0.494,-4.155,1,1
10
- 2020-01-01,RELIANCE.NS,3D,MEDIUM,NEUTRAL,,0.64,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,672.216,671.01,673.43,1.702,-0.537,0.235,-0.537,2.077,0.159,2.123,-0.768,2.123,-0.768,2.123,-0.768,1,1
11
- 2020-01-01,SUNPHARMA.NS,3D,MEDIUM,NEUTRAL,,0.64,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,406.074,405.34,406.8,0.15,1.301,1.335,1.301,1.911,-0.53,3.707,-0.53,3.707,-0.53,3.707,-0.53,1,1
12
- 2020-01-01,TATASTEEL.NS,3D,MEDIUM,NEUTRAL,,0.61,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,38.457,38.39,38.53,3.656,1.176,1.603,1.176,4.286,0.909,4.286,0.599,4.286,-0.16,4.286,0.599,1,0
13
- 2020-01-01,TCS.NS,3D,MEDIUM,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,1841.15,1841.52,1844.46,-0.459,1.515,4.044,1.515,0.57,-0.849,2.692,-0.849,4.263,-0.849,2.692,-0.849,1,1
14
- 2020-01-01,TITAN.NS,3D,MEDIUM,NEUTRAL,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,1132.705,1130.67,1134.74,0.074,0.333,-0.992,0.333,0.446,-1.277,1.442,-1.97,1.654,-1.97,1.442,-1.97,1,1
15
- 2020-01-01,WIPRO.NS,3D,MEDIUM,NEUTRAL,,0.64,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,113.709,113.5,113.91,0.242,1.797,2.866,1.797,0.888,-0.545,2.725,-0.545,3.492,-0.545,2.725,-0.545,1,1
16
- 2020-03-27,BAJFINANCE.NS,3D,HIGH,BEARISH,,0.71,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,249.034,248.66,248.91,-11.808,-12.703,-11.366,-12.703,-5.031,-12.441,-5.031,-17.398,-5.031,-18.125,-5.031,-17.398,1,0
17
- 2020-03-27,DRREDDY.NS,3D,MEDIUM,NEUTRAL,,0.64,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,561.633,560.62,562.64,2.666,6.12,22.86,6.12,4.577,-3.617,8.075,-3.617,23.971,-3.617,8.075,-3.617,0,0
18
- 2020-03-27,HDFCBANK.NS,3D,HIGH,BEARISH,,0.64,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,421.367,420.74,421.16,-8.049,-8.27,-0.923,-8.27,-1.929,-8.453,-1.929,-9.337,0.315,-10.443,-1.929,-9.337,1,0
19
- 2020-03-27,HINDUNILVR.NS,3D,MEDIUM,BULLISH,,0.71,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,1914.796,1915.18,1918.24,2.046,1.827,14.218,1.827,3.385,-1.761,8.612,-1.761,14.924,-1.761,8.612,-1.761,1,1
20
- 2020-03-27,ICICIBANK.NS,3D,HIGH,BEARISH,,0.64,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,328.699,328.21,328.53,-7.783,-8.445,-4.046,-8.445,-1.751,-8.46,-1.471,-9.342,-1.471,-17.169,-1.471,-9.342,1,0
21
- 2020-03-27,INFY.NS,3D,LOW,NEUTRAL,,0.64,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,548.964,547.98,549.95,-3.983,-7.645,-2.099,-7.645,1.655,-4.841,1.655,-8.993,1.655,-10.809,1.655,-8.993,0,0
22
- 2020-03-27,MARUTI.NS,3D,HIGH,BEARISH,,0.6,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,4413.299,4406.68,4411.09,-6.837,-8.604,-1.99,-8.604,-0.132,-8.095,-0.132,-9.815,-0.132,-13.883,-0.132,-9.815,1,0
23
- 2020-03-27,NTPC.NS,3D,HIGH,BEARISH,,0.6,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,65.095,65.0,65.06,-1.506,-2.41,-1.747,-2.41,0.602,-4.578,2.169,-4.578,2.169,-5.0,2.169,-4.578,1,1
24
- 2020-03-27,RELIANCE.NS,3D,MEDIUM,NEUTRAL,,0.57,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,474.506,473.65,475.36,-3.299,1.394,13.185,1.394,0.863,-4.279,6.025,-4.279,13.926,-4.279,6.025,-4.279,1,1
25
- 2020-03-27,SUNPHARMA.NS,3D,HIGH,BEARISH,,0.6,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,318.55,318.07,318.39,-1.641,1.567,23.385,1.567,1.7,-7.761,5.026,-7.761,25.011,-7.761,5.026,-7.761,1,1
26
- 2020-03-27,TATASTEEL.NS,3D,HIGH,BEARISH,,0.67,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,22.795,22.76,22.78,-8.368,-3.931,-0.379,-3.931,-2.344,-9.522,-1.731,-9.522,0.162,-9.522,-1.731,-9.522,1,0
27
- 2020-03-27,TCS.NS,3D,MEDIUM,NEUTRAL,,0.57,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,1564.589,1561.77,1567.41,-2.521,-6.344,-2.702,-6.344,4.412,-3.341,4.412,-6.714,4.412,-9.564,4.412,-6.714,0,0
28
- 2020-03-27,TITAN.NS,3D,HIGH,BEARISH,,0.6,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,919.161,917.78,918.7,0.704,-0.107,1.11,-0.107,2.342,-8.116,3.698,-8.116,3.698,-8.655,3.698,-8.116,1,1
29
- 2020-03-27,WIPRO.NS,3D,MEDIUM,NEUTRAL,,0.67,70.4,False,github:gpt-4o-mini,github,gpt-4o-mini,84.578,84.43,84.73,0.354,3.27,4.578,3.27,2.125,-2.262,8.883,-2.262,8.883,-3.133,8.883,-2.262,0,0
30
- 2020-06-29,BAJFINANCE.NS,3D,MEDIUM,NEUTRAL,,0.71,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,279.954,279.45,280.46,-0.943,3.719,8.777,3.719,2.754,-1.468,5.53,-1.818,9.682,-1.818,5.53,-1.818,0,0
31
- 2020-06-29,DRREDDY.NS,3D,MEDIUM,NEUTRAL,,0.64,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,765.247,763.87,766.62,-0.727,-1.341,-2.06,-1.341,0.932,-1.217,0.932,-2.214,0.932,-2.437,0.932,-2.214,1,1
32
- 2020-06-29,HDFCBANK.NS,3D,MEDIUM,NEUTRAL,,0.61,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,501.313,500.41,502.22,-0.948,1.241,2.505,1.241,0.232,-1.835,3.271,-1.835,4.075,-1.835,3.271,-1.835,1,1
33
- 2020-06-29,HINDUNILVR.NS,3D,MEDIUM,NEUTRAL,,0.78,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,1966.051,1962.51,1969.59,-0.135,-1.429,-0.978,-1.429,0.779,-0.593,0.779,-1.738,0.779,-1.738,0.779,-1.738,1,1
34
- 2020-06-29,ICICIBANK.NS,3D,HIGH,BEARISH,,0.5,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,331.842,331.34,331.68,2.434,5.756,5.465,5.756,3.308,0.933,8.103,0.933,8.103,0.933,8.103,0.933,0,0
35
- 2020-06-29,INFY.NS,3D,MEDIUM,BULLISH,,0.71,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,623.828,623.95,624.95,0.574,3.396,4.407,3.396,0.984,-1.025,4.605,-1.025,5.911,-1.025,4.605,-1.025,1,1
36
- 2020-06-29,MARUTI.NS,3D,MEDIUM,NEUTRAL,,0.64,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,5394.16,5384.45,5403.87,2.81,4.75,7.835,4.75,3.448,0.048,4.954,0.048,8.259,0.048,4.954,0.048,0,0
37
- 2020-06-29,NTPC.NS,3D,MEDIUM,NEUTRAL,,0.57,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,74.428,74.29,74.56,0.948,-1.581,0.316,-1.581,3.003,0.316,3.003,-2.74,3.003,-2.74,3.003,-2.74,1,1
38
- 2020-06-29,RELIANCE.NS,3D,MEDIUM,NEUTRAL,,0.68,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,774.582,773.19,775.98,-1.106,2.575,7.903,2.575,1.036,-1.602,2.997,-1.602,8.265,-1.602,2.997,-1.602,1,1
39
- 2020-06-29,SUNPHARMA.NS,3D,MEDIUM,NEUTRAL,,0.64,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,453.927,453.11,454.74,-1.878,-1.867,-0.373,-1.867,0.405,-2.531,0.405,-3.288,0.405,-3.288,0.405,-3.288,1,1
40
- 2020-06-29,TATASTEEL.NS,3D,MEDIUM,NEUTRAL,,0.64,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,26.379,26.33,26.43,1.823,4.379,5.626,4.379,5.236,0.701,5.236,-0.171,6.498,-0.171,5.236,-0.171,0,0
41
- 2020-06-29,TCS.NS,3D,MEDIUM,NEUTRAL,,0.64,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,1807.555,1804.3,1810.81,-0.928,2.641,7.687,2.641,0.488,-1.266,3.014,-1.266,8.006,-1.266,3.014,-1.266,1,1
42
- 2020-06-29,TITAN.NS,3D,LOW,NEUTRAL,,0.57,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,939.171,937.48,940.86,-0.794,3.024,5.927,3.024,1.514,-1.154,3.817,-1.3,6.512,-1.3,3.817,-1.3,0,0
43
- 2020-06-29,WIPRO.NS,3D,MEDIUM,NEUTRAL,,0.64,28.9,False,github:gpt-4o-mini,github,gpt-4o-mini,101.263,101.08,101.44,-0.023,2.048,1.343,2.048,1.024,-0.774,2.617,-0.774,4.005,-0.774,2.617,-0.774,1,1
44
- 2020-09-21,BAJFINANCE.NS,3D,MEDIUM,NEUTRAL,,0.64,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,326.209,325.62,326.8,-0.815,-9.046,0.15,-9.046,0.71,-3.396,0.71,-9.707,0.71,-9.707,0.71,-9.707,0,0
45
- 2020-09-21,DRREDDY.NS,3D,MEDIUM,NEUTRAL,,0.72,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,996.578,994.78,998.37,0.505,-2.229,-0.236,-2.229,2.295,-1.692,2.684,-2.713,2.684,-2.713,2.684,-2.713,1,1
46
- 2020-09-21,HDFCBANK.NS,3D,MEDIUM,NEUTRAL,,0.74,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,488.85,487.97,489.73,-1.325,-1.801,0.467,-1.801,0.843,-1.887,0.843,-2.316,0.924,-2.316,0.843,-2.316,1,1
47
- 2020-09-21,HINDUNILVR.NS,3D,LOW,NEUTRAL,,0.71,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,1843.171,1839.85,1846.49,-0.54,1.134,1.251,1.134,0.832,-1.852,2.12,-1.852,3.592,-1.852,2.12,-1.852,1,1
48
- 2020-09-21,ICICIBANK.NS,3D,LOW,NEUTRAL,,0.67,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,339.193,338.58,339.8,1.055,-4.277,3.507,-4.277,1.554,-0.342,1.825,-4.833,3.778,-4.833,1.825,-4.833,0,0
49
- 2020-09-21,INFY.NS,3D,MEDIUM,NEUTRAL,,0.72,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,860.956,859.41,862.51,-0.238,-3.416,0.05,-3.416,1.248,-1.852,2.683,-3.951,2.683,-3.951,2.683,-3.951,0,0
50
- 2020-09-21,MARUTI.NS,3D,MEDIUM,NEUTRAL,,0.74,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,6351.519,6340.09,6362.95,-2.813,-4.968,1.148,-4.968,0.89,-4.747,0.89,-5.384,1.404,-5.384,0.89,-5.384,0,0
51
- 2020-09-21,NTPC.NS,3D,HIGH,BEARISH,,0.67,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,71.385,71.28,71.35,-0.68,-6.399,-0.906,-6.399,1.416,-3.398,1.416,-6.965,1.416,-6.965,1.416,-6.965,1,1
52
- 2020-09-21,RELIANCE.NS,3D,MEDIUM,BULLISH,,0.78,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,1018.165,1018.37,1020.0,-1.982,-3.309,-1.755,-3.309,0.938,-2.407,0.938,-3.537,0.938,-3.925,0.938,-3.537,1,1
53
- 2020-09-21,SUNPHARMA.NS,3D,MEDIUM,NEUTRAL,,0.64,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,475.22,474.36,476.08,1.032,-3.544,1.281,-3.544,2.254,-1.995,3.445,-4.1,3.445,-4.1,3.445,-4.1,0,0
54
- 2020-09-21,TATASTEEL.NS,3D,MEDIUM,NEUTRAL,,0.74,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,31.496,31.44,31.55,0.201,-7.9,-3.321,-7.9,1.366,-4.071,1.366,-8.208,1.366,-8.208,1.366,-8.208,0,0
55
- 2020-09-21,TCS.NS,3D,MEDIUM,NEUTRAL,,0.68,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,2125.075,2121.25,2128.9,2.338,-5.397,-1.582,-5.397,3.638,-0.296,3.638,-6.6,3.638,-6.6,3.638,-6.6,0,0
56
- 2020-09-21,TITAN.NS,3D,MEDIUM,NEUTRAL,,0.64,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,1102.748,1100.76,1104.73,-1.38,-2.121,1.683,-2.121,0.679,-2.389,0.679,-3.92,2.148,-3.92,0.679,-3.92,1,1
57
- 2020-09-21,WIPRO.NS,3D,MEDIUM,NEUTRAL,,0.72,22.2,True,github:gpt-4o-mini,github,gpt-4o-mini,143.759,143.5,144.02,0.112,-2.308,-0.112,-2.308,1.555,-2.549,3.174,-3.03,3.174,-3.03,3.174,-3.03,1,1
58
- 2020-12-17,BAJFINANCE.NS,3D,MEDIUM,NEUTRAL,,0.61,19.2,True,github:gpt-4o-mini,github,gpt-4o-mini,517.866,516.93,518.8,-0.647,-5.207,-1.926,-5.207,-0.033,-2.302,-0.033,-8.708,-0.033,-8.708,-0.033,-8.708,0,0
59
- 2020-12-17,DRREDDY.NS,3D,MEDIUM,BULLISH,,0.78,19.2,True,github:gpt-4o-mini,github,gpt-4o-mini,983.176,983.37,984.95,3.073,1.753,2.542,1.753,3.745,0.104,3.969,-2.691,3.969,-2.691,3.969,-2.691,1,1
60
- 2020-12-17,HDFCBANK.NS,3D,MEDIUM,NEUTRAL,,0.71,19.2,True,github:gpt-4o-mini,github,gpt-4o-mini,671.709,670.5,672.92,-2.112,-4.765,-3.1,-4.765,-0.146,-2.462,-0.146,-6.714,-0.146,-6.714,-0.146,-6.714,0,0
61
- 2020-12-17,HINDUNILVR.NS,3D,MEDIUM,BULLISH,,0.78,19.2,True,github:gpt-4o-mini,github,gpt-4o-mini,2107.724,2108.15,2111.52,0.784,-0.186,3.755,-0.186,1.235,-0.143,1.499,-2.168,4.09,-2.168,1.499,-2.168,1,1
62
- 2020-12-17,ICICIBANK.NS,3D,MEDIUM,NEUTRAL,,0.71,19.2,True,github:gpt-4o-mini,github,gpt-4o-mini,493.652,492.76,494.54,1.323,-1.979,0.617,-1.979,1.538,-0.245,1.538,-4.35,1.538,-4.35,1.538,-4.35,1,1
63
- 2020-12-17,INFY.NS,3D,MEDIUM,BULLISH,,0.78,19.2,True,github:gpt-4o-mini,github,gpt-4o-mini,998.853,999.05,1000.65,2.64,5.288,6.63,5.288,3.088,1.415,5.577,-0.617,8.596,-0.617,5.577,-0.617,1,1
64
- 2020-12-17,MARUTI.NS,3D,MEDIUM,BULLISH,,0.78,19.2,True,github:gpt-4o-mini,github,gpt-4o-mini,7374.219,7375.69,7387.49,-1.745,-3.881,-3.223,-3.881,0.429,-1.979,0.429,-6.354,0.429,-6.354,0.429,-6.354,1,1
65
- 2020-12-17,NTPC.NS,3D,MEDIUM,NEUTRAL,,0.61,19.2,True,github:gpt-4o-mini,github,gpt-4o-mini,84.441,84.29,84.59,-0.67,-5.314,-4.308,-5.314,0.335,-1.532,0.335,-9.287,0.335,-9.287,0.335,-9.287,0,0
66
- 2020-12-17,TCS.NS,3D,MEDIUM,BULLISH,,0.78,19.2,True,openrouter:openai/gpt-oss-120b:free,openrouter,openai/gpt-oss-120b:free,2456.944,2457.43,2461.37,0.803,1.209,2.507,1.209,2.107,0.282,2.107,-1.874,2.93,-1.874,2.107,-1.874,1,1
67
- 2020-12-17,TITAN.NS,3D,LOW,NEUTRAL,,0.68,19.2,True,openrouter:openai/gpt-oss-120b:free,openrouter,openai/gpt-oss-120b:free,1478.947,1476.28,1481.61,1.158,-0.21,-0.403,-0.21,1.535,-0.323,1.771,-3.392,1.771,-3.392,1.771,-3.392,1,1
68
- 2020-12-17,WIPRO.NS,3D,MEDIUM,NEUTRAL,,0.71,19.2,True,github:gpt-4o-mini,github,gpt-4o-mini,164.5,164.2,164.8,1.863,2.045,7.089,2.045,2.494,0.168,2.956,-2.396,8.602,-2.396,2.956,-2.396,1,1
69
- 2021-03-16,BAJFINANCE.NS,3D,MEDIUM,NEUTRAL,,0.71,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,534.445,533.48,535.41,-1.762,-0.049,-1.414,-0.049,0.082,-2.044,1.632,-4.874,1.632,-4.874,1.632,-4.874,1,1
70
- 2021-03-16,DRREDDY.NS,3D,MEDIUM,NEUTRAL,,0.64,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,862.403,860.85,863.96,-2.109,-3.938,-1.741,-3.938,0.344,-2.369,0.344,-7.072,0.344,-7.072,0.344,-7.072,0,0
71
- 2021-03-16,HDFCBANK.NS,3D,MEDIUM,NEUTRAL,,0.64,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,704.484,703.22,705.75,-1.111,-0.969,-0.794,-0.969,1.776,-1.452,1.776,-2.52,1.776,-3.422,1.776,-2.52,1,1
72
- 2021-03-16,HINDUNILVR.NS,3D,MEDIUM,BULLISH,,0.71,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,2042.861,2043.27,2046.54,-0.791,3.03,4.155,3.03,0.8,-1.105,3.618,-2.342,5.744,-2.342,3.618,-2.342,1,1
73
- 2021-03-16,ICICIBANK.NS,3D,MEDIUM,NEUTRAL,,0.64,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,575.428,574.39,576.46,-0.916,-1.395,-1.437,-1.395,1.462,-1.336,1.462,-4.194,1.462,-4.278,1.462,-4.194,1,1
74
- 2021-03-16,INFY.NS,3D,MEDIUM,BULLISH,,0.72,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,1192.557,1192.8,1194.7,0.217,-2.858,-0.9,-2.858,1.156,-0.144,1.156,-5.094,1.156,-5.094,1.156,-5.094,1,1
75
- 2021-03-16,MARUTI.NS,3D,MEDIUM,NEUTRAL,,0.64,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,6853.117,6840.78,6865.45,-1.198,-0.514,0.503,-0.514,0.275,-1.494,1.282,-3.424,1.282,-3.424,1.282,-3.424,1,1
76
- 2021-03-16,NTPC.NS,3D,MEDIUM,NEUTRAL,,0.71,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,91.307,91.14,91.47,-2.738,-0.958,-0.822,-0.958,0.32,-3.104,0.32,-6.892,0.913,-6.892,0.32,-6.892,1,1
77
- 2021-03-16,RELIANCE.NS,3D,MEDIUM,NEUTRAL,,0.64,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,948.094,946.39,949.8,-2.154,-0.885,-0.624,-0.885,0.114,-3.118,0.114,-5.608,0.433,-5.608,0.114,-5.608,1,1
78
- 2021-03-16,SUNPHARMA.NS,3D,MEDIUM,NEUTRAL,,0.64,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,573.269,572.24,574.3,-2.914,-3.985,-2.399,-3.985,0.282,-3.37,0.282,-6.674,0.282,-6.674,0.282,-6.674,0,0
79
- 2021-03-16,TATASTEEL.NS,3D,MEDIUM,NEUTRAL,,0.71,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,61.072,60.96,61.18,-2.714,1.236,2.362,1.236,0.269,-3.232,1.754,-5.911,3.508,-5.911,1.754,-5.911,1,1
80
- 2021-03-16,TCS.NS,3D,MEDIUM,BULLISH,,0.8,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,2697.399,2697.94,2702.25,0.093,-1.924,1.047,-1.924,1.445,-0.796,1.445,-3.955,1.895,-3.955,1.445,-3.955,1,1
81
- 2021-03-16,TITAN.NS,3D,MEDIUM,BULLISH,,0.8,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,1477.962,1478.26,1480.62,-1.892,-2.365,-0.373,-2.365,-0.093,-2.059,-0.093,-4.59,0.923,-4.59,-0.093,-4.59,0,0
82
- 2021-03-16,WIPRO.NS,3D,MEDIUM,BULLISH,,0.78,20.2,True,github:gpt-4o-mini,github,gpt-4o-mini,198.315,198.35,198.67,-2.248,-4.379,-3.215,-4.379,1.444,-2.702,1.444,-6.953,1.444,-6.953,1.444,-6.953,1,1
83
- 2021-06-15,BAJFINANCE.NS,3D,MEDIUM,NEUTRAL,,0.68,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,603.524,602.44,604.61,-1.291,-1.203,-2.343,-1.203,-0.004,-1.596,-0.004,-3.914,0.452,-3.914,-0.004,-3.914,1,0
84
- 2021-06-15,DRREDDY.NS,3D,HIGH,BULLISH,,0.78,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,1048.685,1048.89,1050.57,-0.088,-2.346,-1.894,-2.346,0.871,-1.304,0.871,-3.254,0.871,-3.398,0.871,-3.254,1,1
85
- 2021-06-15,HDFCBANK.NS,3D,MEDIUM,NEUTRAL,,0.71,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,694.281,693.03,695.53,-0.379,-0.701,-0.433,-0.701,0.252,-0.815,0.252,-2.365,1.191,-2.365,0.252,-2.365,1,1
86
- 2021-06-15,HINDUNILVR.NS,3D,MEDIUM,BULLISH,,0.78,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,2193.257,2193.7,2197.2,0.667,3.802,4.11,3.802,1.125,-0.347,4.379,-0.347,5.937,-0.347,4.379,-0.347,1,1
87
- 2021-06-15,ICICIBANK.NS,3D,MEDIUM,NEUTRAL,,0.71,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,624.126,623.0,625.25,-0.806,-2.309,-2.239,-2.309,0.604,-1.193,0.604,-3.812,0.604,-4.502,0.604,-3.812,1,1
88
- 2021-06-15,INFY.NS,3D,MEDIUM,NEUTRAL,,0.68,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,1283.726,1281.42,1286.04,0.455,1.995,2.575,1.995,1.055,-0.434,2.843,-0.434,3.226,-0.434,2.843,-0.434,1,1
89
- 2021-06-15,MARUTI.NS,3D,MEDIUM,BULLISH,,0.71,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,6868.404,6869.78,6880.77,-0.726,-2.887,1.384,-2.887,0.384,-1.343,0.384,-4.818,1.866,-4.818,0.384,-4.818,1,1
90
- 2021-06-15,NTPC.NS,3D,MEDIUM,NEUTRAL,,0.68,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,98.183,98.01,98.36,1.698,-3.608,0.424,-3.608,2.377,-0.806,2.377,-4.16,2.377,-4.16,2.377,-4.16,0,0
91
- 2021-06-15,RELIANCE.NS,3D,MEDIUM,BULLISH,,0.68,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,1019.065,1019.27,1020.9,-1.707,-1.082,-1.078,-1.082,-0.131,-1.962,-0.131,-3.116,0.489,-3.116,-0.131,-3.116,0,0
92
- 2021-06-15,SUNPHARMA.NS,3D,MEDIUM,NEUTRAL,,0.64,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,640.752,639.6,641.91,-0.691,-0.698,-0.951,-0.698,1.084,-0.943,1.084,-3.045,1.084,-3.045,1.084,-3.045,1,1
93
- 2021-06-15,TATASTEEL.NS,3D,MEDIUM,BULLISH,,0.71,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,99.05,99.07,99.23,-2.738,-4.901,-3.16,-4.901,0.89,-3.632,0.89,-8.562,0.89,-8.562,0.89,-8.562,1,1
94
- 2021-06-15,TCS.NS,3D,MEDIUM,NEUTRAL,,0.68,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,2843.681,2838.56,2848.8,0.356,1.059,1.178,1.059,0.979,-0.299,2.919,-0.299,2.919,-0.339,2.919,-0.299,1,1
95
- 2021-06-15,TITAN.NS,3D,MEDIUM,NEUTRAL,,0.68,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,1697.005,1693.95,1700.06,-0.49,-0.702,1.95,-0.702,0.325,-0.981,0.325,-2.17,2.75,-2.17,0.325,-2.17,1,1
96
- 2021-06-15,WIPRO.NS,3D,MEDIUM,NEUTRAL,,0.61,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,257.722,257.26,258.19,-0.475,-1.452,-0.242,-1.452,0.833,-0.789,0.833,-2.124,0.833,-4.069,0.833,-2.124,1,1
97
- 2021-09-09,BAJFINANCE.NS,3D,MEDIUM,NEUTRAL,,0.68,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,729.055,727.74,730.37,0.201,-0.222,-0.025,-0.222,0.866,-1.058,1.337,-1.058,3.355,-1.348,1.337,-1.058,1,1
98
- 2021-09-09,DRREDDY.NS,3D,MEDIUM,BULLISH,,0.71,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,956.385,956.58,958.11,0.394,1.029,-0.56,1.029,0.716,-0.793,1.567,-0.793,1.719,-0.875,1.567,-0.793,1,1
99
- 2021-09-09,HDFCBANK.NS,3D,MEDIUM,NEUTRAL,,0.71,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,733.946,732.62,735.27,-0.832,-1.39,0.864,-1.39,0.982,-0.953,0.982,-2.142,1.301,-2.142,0.982,-2.142,1,1
100
- 2021-09-09,HINDUNILVR.NS,3D,MEDIUM,NEUTRAL,,0.68,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,2577.176,2572.54,2581.82,-0.865,-1.252,-3.145,-1.252,0.42,-1.268,0.42,-2.192,0.42,-3.972,0.42,-2.192,1,1
101
- 2021-09-09,ICICIBANK.NS,3D,MEDIUM,BULLISH,,0.78,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,698.657,698.8,699.91,-1.784,-0.819,-0.014,-0.819,-0.326,-2.09,-0.326,-2.09,1.965,-2.09,-0.326,-2.09,0,0
102
- 2021-09-09,INFY.NS,3D,MEDIUM,NEUTRAL,,0.64,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,1473.337,1470.69,1475.99,0.018,1.173,-0.018,1.173,0.585,-0.969,1.389,-0.969,1.635,-0.969,1.389,-0.969,1,1
103
- 2021-09-09,MARUTI.NS,3D,MEDIUM,NEUTRAL,,0.57,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,6561.1,6549.29,6572.91,1.05,1.569,3.12,1.569,1.37,0.162,2.246,0.162,3.859,0.162,2.246,0.162,1,0
104
- 2021-09-09,NTPC.NS,3D,MEDIUM,BULLISH,,0.78,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,98.143,98.16,98.32,0.393,8.424,8.031,8.424,0.829,-0.349,8.992,-0.349,9.734,-0.349,8.992,-0.349,1,1
105
- 2021-09-09,RELIANCE.NS,3D,MEDIUM,NEUTRAL,,0.68,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,1098.598,1096.62,1100.58,-2.228,-1.95,-1.445,-1.95,0.305,-2.373,0.305,-2.457,1.247,-2.457,0.305,-2.457,1,1
106
- 2021-09-09,SUNPHARMA.NS,3D,MEDIUM,NEUTRAL,,0.71,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,740.829,739.5,742.16,0.515,0.56,-0.824,0.56,0.863,-0.599,1.507,-0.599,1.507,-1.243,1.507,-0.599,1,1
107
- 2021-09-09,TATASTEEL.NS,3D,MEDIUM,NEUTRAL,,0.71,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,124.783,124.56,125.01,1.137,0.56,-4.223,0.56,1.728,-0.726,2.004,-0.726,2.004,-6.012,2.004,-0.726,1,1
108
- 2021-09-09,TCS.NS,3D,MEDIUM,NEUTRAL,,0.68,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,3311.642,3305.68,3317.6,1.423,4.303,0.961,4.303,1.609,-0.644,4.974,-0.644,5.021,-0.644,4.974,-0.644,0,0
109
- 2021-09-09,TITAN.NS,3D,MEDIUM,NEUTRAL,,0.68,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,2007.949,2004.34,2011.56,-0.179,4.205,3.013,4.205,0.45,-0.646,4.852,-0.646,5.687,-0.646,4.852,-0.646,0,0
110
- 2021-09-09,WIPRO.NS,3D,MEDIUM,BULLISH,,0.68,13.9,True,github:gpt-4o-mini,github,gpt-4o-mini,305.972,306.03,306.52,1.268,1.766,0.438,1.766,1.434,-0.679,2.748,-0.679,2.778,-0.679,2.748,-0.679,1,1
111
- 2021-12-08,BAJFINANCE.NS,3D,MEDIUM,BULLISH,,0.75,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,722.271,722.42,723.57,1.07,-1.939,-6.986,-1.939,1.448,-0.333,1.569,-2.207,1.569,-7.206,1.569,-2.207,1,1
112
- 2021-12-08,DRREDDY.NS,3D,MEDIUM,NEUTRAL,,0.5,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,889.924,888.32,891.53,0.515,0.637,0.648,0.637,1.034,-0.117,2.348,-0.117,2.348,-0.117,2.348,-0.117,1,1
113
- 2021-12-08,HDFCBANK.NS,3D,MEDIUM,NEUTRAL,,0.71,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,727.021,725.71,728.33,-1.734,-2.745,-3.462,-2.745,0.058,-2.047,0.058,-2.999,0.058,-3.742,0.058,-2.999,1,1
114
- 2021-12-08,HINDUNILVR.NS,3D,MEDIUM,NEUTRAL,,0.64,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,2159.362,2155.47,2163.25,-0.036,-1.549,-0.84,-1.549,0.342,-0.814,0.487,-1.692,0.487,-1.713,0.487,-1.692,1,1
115
- 2021-12-08,ICICIBANK.NS,3D,MEDIUM,NEUTRAL,,0.68,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,730.813,729.5,732.13,0.212,0.08,-0.153,0.08,1.274,-0.664,2.164,-0.664,2.164,-0.942,2.164,-0.664,1,1
116
- 2021-12-08,INFY.NS,3D,MEDIUM,NEUTRAL,,0.71,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,1540.654,1537.88,1543.43,0.576,-0.496,-1.092,-0.496,0.915,-0.647,1.027,-0.83,1.027,-2.452,1.027,-0.83,1,1
117
- 2021-12-08,MARUTI.NS,3D,MEDIUM,BULLISH,,0.71,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,7171.321,7172.76,7184.23,-0.177,1.096,1.79,1.096,0.459,-1.478,1.896,-1.478,2.759,-1.478,1.896,-1.478,1,1
118
- 2021-12-08,NTPC.NS,3D,MEDIUM,NEUTRAL,,0.57,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,109.024,108.83,109.22,-0.943,-1.139,-0.432,-1.139,0.314,-1.257,1.061,-2.24,1.061,-2.24,1.061,-2.24,1,1
119
- 2021-12-08,RELIANCE.NS,3D,MEDIUM,NEUTRAL,,0.57,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,1095.201,1093.23,1097.17,1.586,-0.349,-1.857,-0.349,2.349,0.285,2.349,-0.583,2.349,-2.357,2.349,-0.583,1,1
120
- 2021-12-08,SUNPHARMA.NS,3D,MEDIUM,NEUTRAL,,0.57,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,722.936,721.63,724.24,0.29,0.667,2.317,0.667,1.221,-0.185,2.303,-0.442,2.812,-1.617,2.303,-0.442,1,1
121
- 2021-12-08,TATASTEEL.NS,3D,MEDIUM,NEUTRAL,,0.64,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,101.155,100.97,101.34,0.328,-0.656,-1.616,-0.656,0.767,-1.194,2.217,-1.194,2.217,-2.217,2.217,-1.194,1,1
122
- 2021-12-08,TCS.NS,3D,MEDIUM,BULLISH,,0.71,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,3174.036,3174.67,3179.75,-0.693,-0.476,-1.559,-0.476,0.216,-1.679,0.968,-1.679,0.968,-1.896,0.968,-1.679,1,1
123
- 2021-12-08,TITAN.NS,3D,MEDIUM,NEUTRAL,,0.71,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,2374.39,2370.12,2378.66,-1.347,-2.288,-3.425,-2.288,0.767,-2.066,0.767,-4.542,0.767,-4.542,0.767,-4.542,1,1
124
- 2021-12-08,WIPRO.NS,3D,MEDIUM,NEUTRAL,,0.68,17.3,True,github:gpt-4o-mini,github,gpt-4o-mini,296.433,295.9,296.97,0.234,0.577,-0.826,0.577,0.919,-0.6,2.314,-1.029,2.314,-1.029,2.314,-1.029,1,1
125
- 2022-03-04,BAJFINANCE.NS,3D,HIGH,BEARISH,,0.71,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,641.464,640.5,641.14,-6.315,-1.0,1.378,-1.0,-2.568,-6.698,-0.197,-9.56,3.917,-9.56,-0.197,-9.56,1,0
126
- 2022-03-04,DRREDDY.NS,3D,HIGH,BEARISH,,0.64,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,745.445,744.33,745.07,-1.548,2.659,3.838,2.659,-0.959,-4.196,3.987,-4.196,4.371,-4.196,3.987,-4.196,1,1
127
- 2022-03-04,HDFCBANK.NS,3D,HIGH,BEARISH,,0.64,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,639.384,638.42,639.06,-3.052,0.34,2.217,0.34,-2.499,-5.082,0.6,-5.452,4.427,-5.452,0.6,-5.452,1,1
128
- 2022-03-04,HINDUNILVR.NS,3D,HIGH,BEARISH,,0.64,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,1863.125,1860.33,1862.19,-3.741,-1.07,3.709,-1.07,-1.948,-4.58,-0.616,-5.841,4.679,-5.841,-0.616,-5.841,1,0
129
- 2022-03-04,ICICIBANK.NS,3D,LOW,NEUTRAL,,0.67,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,667.422,666.22,668.62,-4.985,-2.994,-1.475,-2.994,-3.059,-6.671,-1.969,-6.671,1.882,-6.671,-1.969,-6.671,1,0
130
- 2022-03-04,INFY.NS,3D,MEDIUM,NEUTRAL,,0.68,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,1514.249,1511.52,1516.97,0.96,5.225,5.727,5.225,1.607,-1.584,6.284,-1.584,7.048,-1.584,6.284,-1.584,0,0
131
- 2022-03-04,MARUTI.NS,3D,HIGH,BEARISH,,0.78,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,6990.372,6979.89,6986.88,-6.599,-3.042,-1.997,-3.042,-3.0,-7.138,-2.335,-9.807,2.105,-9.807,-2.335,-9.807,1,0
132
- 2022-03-04,NTPC.NS,3D,MEDIUM,NEUTRAL,,0.68,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,114.805,114.6,115.01,-0.115,0.998,1.344,0.998,0.23,-2.535,4.301,-2.535,4.301,-2.535,4.301,-2.535,1,1
133
- 2022-03-04,RELIANCE.NS,3D,MEDIUM,NEUTRAL,,0.57,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,1053.283,1051.39,1055.18,-3.698,1.228,3.165,1.228,-0.578,-4.453,1.782,-6.259,3.674,-6.259,1.782,-6.259,1,1
134
- 2022-03-04,SUNPHARMA.NS,3D,MEDIUM,NEUTRAL,,0.68,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,797.989,796.55,799.43,-0.844,4.653,8.721,4.653,-0.078,-2.477,6.768,-2.477,9.323,-2.477,6.768,-2.477,0,0
135
- 2022-03-04,TATASTEEL.NS,3D,HIGH,BULLISH,,0.8,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,110.132,110.15,110.33,1.159,-1.703,1.926,-1.703,1.934,-1.026,1.934,-2.592,4.917,-2.827,1.934,-2.592,1,1
136
- 2022-03-04,TCS.NS,3D,MEDIUM,NEUTRAL,,0.67,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,3089.71,3084.15,3095.27,-1.119,3.072,2.122,3.072,0.671,-2.633,3.679,-2.633,4.53,-2.633,3.679,-2.633,0,0
137
- 2022-03-04,TITAN.NS,3D,MEDIUM,NEUTRAL,,0.75,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,2409.381,2405.04,2413.72,-2.102,-0.301,2.155,-0.301,-0.862,-4.547,0.799,-4.728,2.612,-4.728,0.799,-4.728,1,1
138
- 2022-03-04,WIPRO.NS,3D,MEDIUM,NEUTRAL,,0.75,28.0,False,github:gpt-4o-mini,github,gpt-4o-mini,266.192,265.71,266.67,-0.6,1.773,1.895,1.773,0.756,-2.268,3.668,-2.268,3.685,-2.268,3.668,-2.268,1,1
139
- 2022-06-02,BAJFINANCE.NS,3D,HIGH,BEARISH,,0.64,20.3,False,github:gpt-4o-mini,github,gpt-4o-mini,594.364,593.47,594.07,-0.489,-2.959,-2.63,-2.959,1.818,-0.724,1.818,-3.701,1.818,-4.219,1.818,-3.701,1,1
140
- 2022-06-02,DRREDDY.NS,3D,MEDIUM,NEUTRAL,,0.71,20.3,False,github:gpt-4o-mini,github,gpt-4o-mini,843.672,842.15,845.19,0.158,-4.366,-0.237,-4.366,1.35,-0.423,1.35,-5.295,1.35,-5.295,1.35,-5.295,0,0
141
- 2022-06-02,HDFCBANK.NS,3D,MEDIUM,NEUTRAL,,0.64,20.3,False,github:gpt-4o-mini,github,gpt-4o-mini,655.622,654.44,656.8,-0.347,-1.624,-0.534,-1.624,1.13,-0.635,1.13,-2.238,1.13,-2.238,1.13,-2.238,1,1
142
- 2022-06-02,HINDUNILVR.NS,3D,MEDIUM,NEUTRAL,,0.64,20.3,False,github:gpt-4o-mini,github,gpt-4o-mini,2107.883,2104.09,2111.68,0.313,-3.204,-3.812,-3.204,1.757,-0.86,1.757,-3.403,1.757,-4.992,1.757,-3.403,0,0
143
- 2022-06-02,ICICIBANK.NS,3D,MEDIUM,BULLISH,,0.71,20.3,False,github:gpt-4o-mini,github,gpt-4o-mini,727.272,727.42,728.58,-0.727,-1.934,-2.267,-1.934,0.967,-1.14,0.967,-2.321,0.967,-3.681,0.967,-2.321,1,1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
research/ai_prompt_accuracy_anthropic_claude-haiku.csv DELETED
@@ -1,19 +0,0 @@
1
- date,ticker,timeframe,confidence,direction,matched_strategy,ml_prob,vix,nifty_ok,source,source_provider,source_model,entry_price,target_price_lo,target_price_hi,ret_1d,ret_3d,ret_5d,ret_for_tf,max_up_1d,min_down_1d,max_up_3d,min_down_3d,max_up_5d,min_down_5d,max_up_for_tf,min_down_for_tf,intraday_hit_for_tf,target_hit_for_tf
2
- 2018-01-01,BAJFINANCE.NS,1D,MEDIUM,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,168.067,167.88,168.05,-0.058,1.643,6.444,-0.058,0.814,-0.907,1.889,-0.907,6.8,-0.907,0.814,-0.907,1,1
3
- 2018-01-01,BAJFINANCE.NS,3D,HIGH,BULLISH,S_CTRIO,0.64,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,168.067,168.28,168.89,-0.058,1.643,6.444,1.643,0.814,-0.907,1.889,-0.907,6.8,-0.907,1.889,-0.907,1,1
4
- 2018-01-01,BAJFINANCE.NS,5D,MEDIUM,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,168.067,167.38,167.9,-0.058,1.643,6.444,6.444,0.814,-0.907,1.889,-0.907,6.8,-0.907,6.8,-0.907,1,1
5
- 2018-01-01,HDFCBANK.NS,1D,MEDIUM,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,425.649,425.19,425.61,0.963,0.291,0.329,0.963,1.105,0.218,1.281,-0.178,1.281,-0.178,1.105,0.218,0,0
6
- 2018-01-01,HDFCBANK.NS,3D,LOW,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,425.649,423.36,425.22,0.963,0.291,0.329,0.291,1.105,0.218,1.281,-0.178,1.281,-0.178,1.281,-0.178,1,0
7
- 2018-01-01,HDFCBANK.NS,5D,MEDIUM,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,425.649,423.91,425.22,0.963,0.291,0.329,0.329,1.105,0.218,1.281,-0.178,1.281,-0.178,1.281,-0.178,1,0
8
- 2018-01-01,RELIANCE.NS,1D,LOW,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,400.015,399.33,399.98,0.154,1.16,2.067,0.154,1.077,-0.368,1.786,-0.368,2.336,-0.368,1.077,-0.368,1,1
9
- 2018-01-01,RELIANCE.NS,3D,MEDIUM,BULLISH,S_CTRIO,0.64,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,400.015,400.42,402.13,0.154,1.16,2.067,1.16,1.077,-0.368,1.786,-0.368,2.336,-0.368,1.786,-0.368,1,1
10
- 2018-01-01,RELIANCE.NS,5D,LOW,BULLISH,S_CTRIO,0.64,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,400.015,400.42,402.56,0.154,1.16,2.067,2.067,1.077,-0.368,1.786,-0.368,2.336,-0.368,2.336,-0.368,1,1
11
- 2018-01-01,SUNPHARMA.NS,1D,LOW,BULLISH,S_CTRIO,0.61,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,531.673,532.2,533.84,-0.331,1.246,3.057,-0.331,1.385,-1.193,1.725,-2.43,5.322,-2.43,1.385,-1.193,1,1
12
- 2018-01-01,SUNPHARMA.NS,3D,LOW,BEARISH,S_CTRIO,0.61,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,531.673,528.82,531.14,-0.331,1.246,3.057,1.246,1.385,-1.193,1.725,-2.43,5.322,-2.43,1.725,-2.43,1,1
13
- 2018-01-01,SUNPHARMA.NS,5D,HIGH,BULLISH,S_CTRIO,0.61,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,531.673,532.2,534.17,-0.331,1.246,3.057,3.057,1.385,-1.193,1.725,-2.43,5.322,-2.43,5.322,-2.43,1,1
14
- 2018-01-01,TCS.NS,1D,HIGH,BEARISH,S_CTRIO,0.78,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,1069.273,1068.46,1069.17,-0.544,0.435,2.601,-0.544,0.907,-0.96,0.907,-0.96,3.071,-0.96,0.907,-0.96,1,1
15
- 2018-01-01,TCS.NS,3D,MEDIUM,BEARISH,S_CTRIO,0.78,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,1069.273,1065.61,1068.2,-0.544,0.435,2.601,0.435,0.907,-0.96,0.907,-0.96,3.071,-0.96,0.907,-0.96,1,1
16
- 2018-01-01,TCS.NS,5D,HIGH,BEARISH,S_CTRIO,0.78,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,1069.273,1065.37,1068.38,-0.544,0.435,2.601,2.601,0.907,-0.96,0.907,-0.96,3.071,-0.96,3.071,-0.96,1,1
17
- 2018-01-01,WIPRO.NS,1D,HIGH,BULLISH,S_CTRIO,0.72,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,108.326,108.43,108.66,0.679,-1.548,-1.706,0.679,2.353,-0.663,2.353,-2.875,2.353,-2.875,2.353,-0.663,1,1
18
- 2018-01-01,WIPRO.NS,3D,HIGH,BULLISH,S_CTRIO,0.72,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,108.326,108.51,108.9,0.679,-1.548,-1.706,-1.548,2.353,-0.663,2.353,-2.875,2.353,-2.875,2.353,-2.875,1,1
19
- 2018-01-01,WIPRO.NS,5D,HIGH,BULLISH,S_CTRIO,0.72,13.4,True,ai_forecast:claude-haiku,anthropic,claude-haiku,108.326,108.43,108.83,0.679,-1.548,-1.706,-1.706,2.353,-0.663,2.353,-2.875,2.353,-2.875,2.353,-2.875,1,1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
research/ai_prompt_accuracy_github_gpt-4o-mini.csv DELETED
@@ -1,19 +0,0 @@
1
- date,ticker,timeframe,confidence,direction,matched_strategy,ml_prob,vix,nifty_ok,source,source_provider,source_model,entry_price,target_price_lo,target_price_hi,ret_1d,ret_3d,ret_5d,ret_for_tf,max_up_1d,min_down_1d,max_up_3d,min_down_3d,max_up_5d,min_down_5d,max_up_for_tf,min_down_for_tf,intraday_hit_for_tf,target_hit_for_tf
2
- 2018-01-01,BAJFINANCE.NS,1D,MEDIUM,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,168.067,167.88,168.05,-0.058,1.643,6.444,-0.058,0.814,-0.907,1.889,-0.907,6.8,-0.907,0.814,-0.907,1,1
3
- 2018-01-01,BAJFINANCE.NS,3D,HIGH,BULLISH,S_CTRIO,0.64,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,168.067,168.28,168.89,-0.058,1.643,6.444,1.643,0.814,-0.907,1.889,-0.907,6.8,-0.907,1.889,-0.907,1,1
4
- 2018-01-01,BAJFINANCE.NS,5D,MEDIUM,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,168.067,167.38,167.9,-0.058,1.643,6.444,6.444,0.814,-0.907,1.889,-0.907,6.8,-0.907,6.8,-0.907,1,1
5
- 2018-01-01,HDFCBANK.NS,1D,MEDIUM,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,425.649,425.19,425.61,0.963,0.291,0.329,0.963,1.105,0.218,1.281,-0.178,1.281,-0.178,1.105,0.218,0,0
6
- 2018-01-01,HDFCBANK.NS,3D,LOW,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,425.649,423.36,425.22,0.963,0.291,0.329,0.291,1.105,0.218,1.281,-0.178,1.281,-0.178,1.281,-0.178,1,0
7
- 2018-01-01,HDFCBANK.NS,5D,MEDIUM,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,425.649,423.91,425.22,0.963,0.291,0.329,0.329,1.105,0.218,1.281,-0.178,1.281,-0.178,1.281,-0.178,1,0
8
- 2018-01-01,RELIANCE.NS,1D,LOW,BEARISH,S_CTRIO,0.64,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,400.015,399.33,399.98,0.154,1.16,2.067,0.154,1.077,-0.368,1.786,-0.368,2.336,-0.368,1.077,-0.368,1,1
9
- 2018-01-01,RELIANCE.NS,3D,MEDIUM,BULLISH,S_CTRIO,0.64,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,400.015,400.42,402.13,0.154,1.16,2.067,1.16,1.077,-0.368,1.786,-0.368,2.336,-0.368,1.786,-0.368,1,1
10
- 2018-01-01,RELIANCE.NS,5D,LOW,BULLISH,S_CTRIO,0.64,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,400.015,400.42,402.56,0.154,1.16,2.067,2.067,1.077,-0.368,1.786,-0.368,2.336,-0.368,2.336,-0.368,1,1
11
- 2018-01-01,SUNPHARMA.NS,1D,LOW,BULLISH,S_CTRIO,0.61,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,531.673,532.2,533.84,-0.331,1.246,3.057,-0.331,1.385,-1.193,1.725,-2.43,5.322,-2.43,1.385,-1.193,1,1
12
- 2018-01-01,SUNPHARMA.NS,3D,LOW,BEARISH,S_CTRIO,0.61,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,531.673,528.82,531.14,-0.331,1.246,3.057,1.246,1.385,-1.193,1.725,-2.43,5.322,-2.43,1.725,-2.43,1,1
13
- 2018-01-01,SUNPHARMA.NS,5D,HIGH,BULLISH,S_CTRIO,0.61,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,531.673,532.2,534.17,-0.331,1.246,3.057,3.057,1.385,-1.193,1.725,-2.43,5.322,-2.43,5.322,-2.43,1,1
14
- 2018-01-01,TCS.NS,1D,HIGH,BEARISH,S_CTRIO,0.78,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,1069.273,1068.46,1069.17,-0.544,0.435,2.601,-0.544,0.907,-0.96,0.907,-0.96,3.071,-0.96,0.907,-0.96,1,1
15
- 2018-01-01,TCS.NS,3D,MEDIUM,BEARISH,S_CTRIO,0.78,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,1069.273,1065.61,1068.2,-0.544,0.435,2.601,0.435,0.907,-0.96,0.907,-0.96,3.071,-0.96,0.907,-0.96,1,1
16
- 2018-01-01,TCS.NS,5D,HIGH,BEARISH,S_CTRIO,0.78,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,1069.273,1065.37,1068.38,-0.544,0.435,2.601,2.601,0.907,-0.96,0.907,-0.96,3.071,-0.96,3.071,-0.96,1,1
17
- 2018-01-01,WIPRO.NS,1D,HIGH,BULLISH,S_CTRIO,0.72,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,108.326,108.43,108.66,0.679,-1.548,-1.706,0.679,2.353,-0.663,2.353,-2.875,2.353,-2.875,2.353,-0.663,1,1
18
- 2018-01-01,WIPRO.NS,3D,HIGH,BULLISH,S_CTRIO,0.72,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,108.326,108.51,108.9,0.679,-1.548,-1.706,-1.548,2.353,-0.663,2.353,-2.875,2.353,-2.875,2.353,-2.875,1,1
19
- 2018-01-01,WIPRO.NS,5D,HIGH,BULLISH,S_CTRIO,0.72,13.4,True,ai_forecast:gpt-4o-mini,github,gpt-4o-mini,108.326,108.43,108.83,0.679,-1.548,-1.706,-1.706,2.353,-0.663,2.353,-2.875,2.353,-2.875,2.353,-2.875,1,1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
research/ai_prompt_accuracy_new.csv.bak DELETED
The diff for this file is too large to render. See raw diff
 
research/ai_prompt_accuracy_trades.csv CHANGED
@@ -5,3 +5,51 @@ date,ticker,timeframe,confidence,direction,matched_strategy,ml_prob,vix,nifty_ok
5
  2026-06-16,IPCALAB.NS,INTRADAY,LOW,BULLISH,,0.64,13.4,False,groq:llama-3.1-8b-instant,groq,llama-3.1-8b-instant,1550.2,1558.42,1559.22,0.0,-0.742,2.296,4.825,0.0,2.174,-0.335,0.548,-1.135,3.8,-1.303,5.883,-1.303,2.174,-0.335,1,1,MIDPOINT_HIT,1,1,0,0,0,1,0,0,0,0,0,0
6
  2026-06-16,IPCALAB.NS,1D,LOW,BULLISH,,0.64,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1550.2,1556.77,1558.74,0.0,-0.742,2.296,4.825,-0.742,2.174,-0.335,0.548,-1.135,3.8,-1.303,5.883,-1.303,0.548,-1.135,1,1,MIDPOINT_HIT,1,1,0,0,0,1,0,0,0,0,0,0
7
  2026-06-16,IPCALAB.NS,3D,MEDIUM,BULLISH,,0.64,13.4,False,huggingface:meta-llama/llama-3.1-8b-instruct,huggingface,meta-llama/llama-3.1-8b-instruct,1550.2,1566.56,1567.37,0.0,-0.742,2.296,4.825,2.296,2.174,-0.335,0.548,-1.135,3.8,-1.303,5.883,-1.303,3.8,-1.303,1,1,MIDPOINT_HIT,1,1,0,0,0,1,0,0,0,0,0,0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  2026-06-16,IPCALAB.NS,INTRADAY,LOW,BULLISH,,0.64,13.4,False,groq:llama-3.1-8b-instant,groq,llama-3.1-8b-instant,1550.2,1558.42,1559.22,0.0,-0.742,2.296,4.825,0.0,2.174,-0.335,0.548,-1.135,3.8,-1.303,5.883,-1.303,2.174,-0.335,1,1,MIDPOINT_HIT,1,1,0,0,0,1,0,0,0,0,0,0
6
  2026-06-16,IPCALAB.NS,1D,LOW,BULLISH,,0.64,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1550.2,1556.77,1558.74,0.0,-0.742,2.296,4.825,-0.742,2.174,-0.335,0.548,-1.135,3.8,-1.303,5.883,-1.303,0.548,-1.135,1,1,MIDPOINT_HIT,1,1,0,0,0,1,0,0,0,0,0,0
7
  2026-06-16,IPCALAB.NS,3D,MEDIUM,BULLISH,,0.64,13.4,False,huggingface:meta-llama/llama-3.1-8b-instruct,huggingface,meta-llama/llama-3.1-8b-instruct,1550.2,1566.56,1567.37,0.0,-0.742,2.296,4.825,2.296,2.174,-0.335,0.548,-1.135,3.8,-1.303,5.883,-1.303,3.8,-1.303,1,1,MIDPOINT_HIT,1,1,0,0,0,1,0,0,0,0,0,0
8
+ 2026-06-16,POLYCAB.NS,INTRADAY,MEDIUM,BULLISH,,0.75,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,9546.205,9575.56,9578.43,0.0,3.493,5.623,3.921,0.0,0.829,-1.215,4.129,0.089,6.011,0.089,6.074,0.089,0.829,-1.215,1,1,MIDPOINT_HIT,1,1,0,0,1,0,0,0,1,0,0,0
9
+ 2026-06-16,POLYCAB.NS,1D,MEDIUM,BULLISH,,0.75,13.4,False,huggingface:meta-llama/llama-3.1-8b-instruct,huggingface,meta-llama/llama-3.1-8b-instruct,9546.205,9569.67,9576.71,0.0,3.493,5.623,3.921,3.493,0.829,-1.215,4.129,0.089,6.011,0.089,6.074,0.089,4.129,0.089,1,1,MIDPOINT_HIT,1,1,0,0,1,0,0,0,1,0,0,0
10
+ 2026-06-16,POLYCAB.NS,3D,MEDIUM,BULLISH,,0.75,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,9546.205,9604.61,9607.51,0.0,3.493,5.623,3.921,5.623,0.829,-1.215,4.129,0.089,6.011,0.089,6.074,0.089,6.011,0.089,1,1,MIDPOINT_HIT,1,1,0,0,1,0,0,0,1,0,0,0
11
+ 2026-06-16,DLF.NS,INTRADAY,MEDIUM,NEUTRAL,,0.65,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,629.3,616.71,641.89,0.0,-0.914,-0.763,-2.693,0.0,0.429,-2.797,0.707,-1.764,2.336,-1.764,2.336,-3.059,0.429,-2.797,1,1,MIDPOINT_HIT,1,1,1,0,1,0,0,0,0,0,0,0
12
+ 2026-06-16,DLF.NS,1D,MEDIUM,NEUTRAL,,0.65,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,629.3,606.45,652.15,0.0,-0.914,-0.763,-2.693,-0.914,0.429,-2.797,0.707,-1.764,2.336,-1.764,2.336,-3.059,0.707,-1.764,1,1,MIDPOINT_HIT,1,1,1,0,1,0,0,0,0,0,0,0
13
+ 2026-06-16,DLF.NS,3D,MEDIUM,NEUTRAL,,0.65,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,629.3,590.58,668.02,0.0,-0.914,-0.763,-2.693,-0.763,0.429,-2.797,0.707,-1.764,2.336,-1.764,2.336,-3.059,2.336,-1.764,1,1,MIDPOINT_HIT,1,1,1,0,1,0,0,0,0,0,0,0
14
+ 2026-06-16,SHRIRAMFIN.NS,INTRADAY,MEDIUM,BULLISH,,0.71,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1000.093,1004.24,1004.65,0.0,0.174,-0.383,-1.233,0.0,0.428,-1.362,0.994,-0.378,1.148,-1.337,1.148,-2.182,0.428,-1.362,1,0,RANGE_HIT,0,1,1,0,1,0,0,0,0,0,0,0
15
+ 2026-06-16,SHRIRAMFIN.NS,1D,MEDIUM,BULLISH,,0.71,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1000.093,1003.41,1004.41,0.0,0.174,-0.383,-1.233,0.174,0.428,-1.362,0.994,-0.378,1.148,-1.337,1.148,-2.182,0.994,-0.378,1,1,MIDPOINT_HIT,1,1,1,0,1,0,0,0,0,0,0,0
16
+ 2026-06-16,SHRIRAMFIN.NS,3D,MEDIUM,BULLISH,,0.71,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1000.093,1008.35,1008.76,0.0,0.174,-0.383,-1.233,-0.383,0.428,-1.362,0.994,-0.378,1.148,-1.337,1.148,-2.182,1.148,-1.337,1,1,MIDPOINT_HIT,1,1,1,0,1,0,0,0,0,0,0,0
17
+ 2026-06-16,AXISCADES.NS,INTRADAY,LOW,BULLISH,,0.71,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1825.3,1840.27,1841.73,0.0,4.996,6.459,0.904,0.0,5.057,-0.493,4.996,0.038,9.023,0.038,9.023,0.038,5.057,-0.493,1,1,MIDPOINT_HIT,1,1,0,0,0,0,1,0,0,0,0,0
18
+ 2026-06-16,AXISCADES.NS,3D,MEDIUM,BULLISH,,0.71,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1825.3,1855.09,1856.57,0.0,4.996,6.459,0.904,6.459,5.057,-0.493,4.996,0.038,9.023,0.038,9.023,0.038,9.023,0.038,1,1,MIDPOINT_HIT,1,1,0,0,0,0,1,0,0,0,0,0
19
+ 2026-06-19,HINDALCO.NS,INTRADAY,LOW,BEARISH,,0.74,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1004.758,999.66,1000.11,0.0,0.416,-3.307,-5.624,0.0,0.673,-2.455,0.802,-0.634,0.802,-3.931,0.802,-5.921,0.673,-2.455,1,1,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,1
20
+ 2026-06-19,HINDALCO.NS,1D,MEDIUM,BEARISH,,0.74,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1004.758,999.93,1001.05,0.0,0.416,-3.307,-5.624,0.416,0.673,-2.455,0.802,-0.634,0.802,-3.931,0.802,-5.921,0.802,-0.634,1,1,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,1
21
+ 2026-06-19,HINDALCO.NS,3D,LOW,BEARISH,,0.74,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1004.758,995.06,995.52,0.0,0.416,-3.307,-5.624,-3.307,0.673,-2.455,0.802,-0.634,0.802,-3.931,0.802,-5.921,0.802,-3.931,1,1,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,1
22
+ 2026-06-19,IPCALAB.NS,INTRADAY,LOW,NEUTRAL,,0.71,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1585.8,1554.08,1617.52,0.0,0.725,2.232,2.049,0.0,1.469,-2.73,1.204,-0.214,3.506,-0.214,4.364,-0.214,1.469,-2.73,1,1,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,0
23
+ 2026-06-19,IPCALAB.NS,1D,LOW,NEUTRAL,,0.71,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1585.8,1522.37,1649.23,0.0,0.725,2.232,2.049,0.725,1.469,-2.73,1.204,-0.214,3.506,-0.214,4.364,-0.214,1.204,-0.214,1,1,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,0
24
+ 2026-06-19,IPCALAB.NS,3D,LOW,NEUTRAL,,0.71,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1585.8,1474.79,1696.81,0.0,0.725,2.232,2.049,2.232,1.469,-2.73,1.204,-0.214,3.506,-0.214,4.364,-0.214,3.506,-0.214,0,0,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,0
25
+ 2026-06-19,POLYCAB.NS,INTRADAY,LOW,NEUTRAL,,0.72,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,10083.0,9881.34,10284.66,0.0,-0.6,-3.873,-5.475,0.0,0.367,-2.499,0.426,-0.903,0.426,-4.046,0.426,-5.618,0.367,-2.499,1,1,MIDPOINT_HIT,1,1,0,0,1,0,0,0,0,0,0,0
26
+ 2026-06-19,POLYCAB.NS,1D,LOW,NEUTRAL,,0.72,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,10083.0,9799.52,10366.48,0.0,-0.6,-3.873,-5.475,-0.6,0.367,-2.499,0.426,-0.903,0.426,-4.046,0.426,-5.618,0.426,-0.903,1,1,MIDPOINT_HIT,1,1,0,0,1,0,0,0,0,0,0,0
27
+ 2026-06-19,POLYCAB.NS,3D,LOW,NEUTRAL,,0.72,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,10083.0,9602.67,10563.33,0.0,-0.6,-3.873,-5.475,-3.873,0.367,-2.499,0.426,-0.903,0.426,-4.046,0.426,-5.618,0.426,-4.046,0,0,MIDPOINT_HIT,1,1,0,0,1,0,0,0,0,0,0,0
28
+ 2026-06-19,DLF.NS,INTRADAY,MEDIUM,BULLISH,,0.71,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,624.5,627.4,627.68,0.0,0.496,-1.017,-0.504,0.0,2.322,-0.777,1.169,0.096,1.906,-2.418,1.906,-2.418,2.322,-0.777,1,1,MIDPOINT_HIT,1,1,1,1,0,0,0,0,0,0,0,0
29
+ 2026-06-19,DLF.NS,1D,MEDIUM,BULLISH,,0.71,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,624.5,626.81,627.51,0.0,0.496,-1.017,-0.504,0.496,2.322,-0.777,1.169,0.096,1.906,-2.418,1.906,-2.418,1.169,0.096,1,1,MIDPOINT_HIT,1,1,1,1,0,0,0,0,0,0,0,0
30
+ 2026-06-19,DLF.NS,3D,MEDIUM,BULLISH,,0.71,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,624.5,630.26,630.55,0.0,0.496,-1.017,-0.504,-1.017,2.322,-0.777,1.169,0.096,1.906,-2.418,1.906,-2.418,1.906,-2.418,1,1,MIDPOINT_HIT,1,1,1,1,0,0,0,0,0,0,0,0
31
+ 2026-06-19,SHRIRAMFIN.NS,INTRADAY,MEDIUM,BULLISH,,0.71,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,996.265,1000.36,1000.76,0.0,-0.903,1.707,2.984,0.0,0.579,-0.958,0.384,-1.807,2.74,-2.131,5.0,-2.131,0.579,-0.958,1,1,MIDPOINT_HIT,1,1,1,1,0,0,0,0,1,0,0,0
32
+ 2026-06-19,SHRIRAMFIN.NS,1D,LOW,BULLISH,,0.71,13.0,False,groq:llama-3.1-8b-instant,groq,llama-3.1-8b-instant,996.265,999.54,1000.52,0.0,-0.903,1.707,2.984,-0.903,0.579,-0.958,0.384,-1.807,2.74,-2.131,5.0,-2.131,0.384,-1.807,1,1,MIDPOINT_HIT,1,1,1,1,0,0,0,0,1,0,0,0
33
+ 2026-06-19,SHRIRAMFIN.NS,3D,MEDIUM,BULLISH,,0.71,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,996.265,1004.41,1004.81,0.0,-0.903,1.707,2.984,1.707,0.579,-0.958,0.384,-1.807,2.74,-2.131,5.0,-2.131,2.74,-2.131,1,1,MIDPOINT_HIT,1,1,1,1,0,0,0,0,1,0,0,0
34
+ 2026-06-19,AXISCADES.NS,INTRADAY,MEDIUM,BULLISH,,0.78,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1943.2,1957.8,1959.23,0.0,-3.355,-9.536,-12.979,0.0,1.379,-1.662,0.098,-3.767,0.098,-9.953,0.098,-13.601,1.379,-1.662,1,1,MIDPOINT_HIT,1,1,1,1,0,0,0,0,0,0,0,0
35
+ 2026-06-19,AXISCADES.NS,1D,MEDIUM,BULLISH,,0.78,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1943.2,1954.87,1958.37,0.0,-3.355,-9.536,-12.979,-3.355,1.379,-1.662,0.098,-3.767,0.098,-9.953,0.098,-13.601,0.098,-3.767,1,0,MISS,0,0,1,1,0,0,0,0,0,0,0,0
36
+ 2026-06-19,AXISCADES.NS,3D,MEDIUM,BULLISH,,0.78,13.0,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1943.2,1972.25,1973.69,0.0,-3.355,-9.536,-12.979,-9.536,1.379,-1.662,0.098,-3.767,0.098,-9.953,0.098,-13.601,0.098,-9.953,1,0,MISS,0,0,1,1,0,0,0,0,0,0,0,0
37
+ 2026-06-22,HINDALCO.NS,1D,MEDIUM,BEARISH,,0.64,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1008.937,1004.2,1005.29,0.0,-2.702,-6.015,-4.969,-2.702,0.385,-1.045,-1.499,-3.569,-1.499,-6.31,-1.499,-6.31,-1.499,-3.569,1,0,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,1
38
+ 2026-06-22,HINDALCO.NS,3D,LOW,BEARISH,,0.64,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1008.937,999.41,999.86,0.0,-2.702,-6.015,-4.969,-6.015,0.385,-1.045,-1.499,-3.569,-1.499,-6.31,-1.499,-6.31,-1.499,-6.31,1,0,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,1
39
+ 2026-06-22,IPCALAB.NS,INTRADAY,MEDIUM,BULLISH,,0.71,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1597.3,1604.4,1605.09,0.0,1.734,1.315,3.124,0.0,0.476,-0.933,2.761,0.163,3.612,0.163,4.232,0.163,0.476,-0.933,1,1,MIDPOINT_HIT,1,1,0,0,1,0,0,0,1,0,0,0
40
+ 2026-06-22,IPCALAB.NS,1D,MEDIUM,BULLISH,,0.71,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1597.3,1602.97,1604.68,0.0,1.734,1.315,3.124,1.734,0.476,-0.933,2.761,0.163,3.612,0.163,4.232,0.163,2.761,0.163,1,1,MIDPOINT_HIT,1,1,0,0,1,0,0,0,1,0,0,0
41
+ 2026-06-22,IPCALAB.NS,3D,MEDIUM,BULLISH,,0.71,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1597.3,1611.42,1612.13,0.0,1.734,1.315,3.124,1.315,0.476,-0.933,2.761,0.163,3.612,0.163,4.232,0.163,3.612,0.163,1,1,MIDPOINT_HIT,1,1,0,0,1,0,0,0,1,0,0,0
42
+ 2026-06-22,POLYCAB.NS,1D,LOW,NEUTRAL,,0.68,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,10022.5,9746.04,10298.96,0.0,-1.018,-4.904,-2.43,-1.018,1.033,-0.304,0.524,-1.307,0.524,-5.049,0.524,-6.006,0.524,-1.307,0,0,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,0
43
+ 2026-06-22,POLYCAB.NS,3D,LOW,NEUTRAL,,0.68,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,10022.5,9554.07,10490.93,0.0,-1.018,-4.904,-2.43,-4.904,1.033,-0.304,0.524,-1.307,0.524,-5.049,0.524,-6.006,0.524,-5.049,0,0,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,0
44
+ 2026-06-22,DLF.NS,INTRADAY,MEDIUM,BULLISH,,0.71,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,627.6,630.33,630.59,0.0,-2.43,-0.996,-2.047,0.0,0.669,-0.398,1.402,-2.796,1.402,-2.9,1.402,-2.9,0.669,-0.398,1,1,MIDPOINT_HIT,1,1,1,1,0,0,0,0,0,0,0,0
45
+ 2026-06-22,DLF.NS,1D,MEDIUM,BULLISH,,0.71,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,627.6,629.78,630.43,0.0,-2.43,-0.996,-2.047,-2.43,0.669,-0.398,1.402,-2.796,1.402,-2.9,1.402,-2.9,1.402,-2.796,1,1,MIDPOINT_HIT,1,1,1,1,0,0,0,0,0,0,0,0
46
+ 2026-06-22,SHRIRAMFIN.NS,INTRADAY,MEDIUM,BULLISH,,0.78,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,987.265,991.19,991.58,0.0,0.05,3.923,4.009,0.0,1.299,-0.912,1.496,-0.841,5.958,-1.239,6.3,-1.239,1.299,-0.912,1,1,MIDPOINT_HIT,1,1,1,1,0,0,1,0,1,0,0,0
47
+ 2026-06-22,SHRIRAMFIN.NS,1D,MEDIUM,BULLISH,,0.78,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,987.265,990.4,991.35,0.0,0.05,3.923,4.009,0.05,1.299,-0.912,1.496,-0.841,5.958,-1.239,6.3,-1.239,1.496,-0.841,1,1,MIDPOINT_HIT,1,1,1,1,0,0,1,0,1,0,0,0
48
+ 2026-06-22,AXISCADES.NS,1D,MEDIUM,BULLISH,,0.71,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1878.0,1889.56,1893.03,0.0,-1.928,-9.957,-9.526,-1.928,3.573,-0.426,1.587,-2.391,1.587,-10.602,1.587,-12.875,1.587,-2.391,1,1,MIDPOINT_HIT,1,1,1,0,0,0,0,0,0,0,0,0
49
+ 2026-06-22,AXISCADES.NS,3D,MEDIUM,BULLISH,,0.71,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1878.0,1906.78,1908.22,0.0,-1.928,-9.957,-9.526,-9.957,3.573,-0.426,1.587,-2.391,1.587,-10.602,1.587,-12.875,1.587,-10.602,1,1,MIDPOINT_HIT,1,1,1,0,0,0,0,0,0,0,0,0
50
+ 2026-06-16,AXISCADES.NS,1D,MEDIUM,BULLISH,,0.71,13.4,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1825.3,1837.27,1840.86,0.0,4.996,6.459,0.904,4.996,5.057,-0.493,4.996,0.038,9.023,0.038,9.023,0.038,4.996,0.038,1,1,MIDPOINT_HIT,1,1,0,0,0,0,1,0,0,0,0,0
51
+ 2026-06-22,HINDALCO.NS,INTRADAY,LOW,BEARISH,,0.64,12.8,False,groq:llama-3.1-8b-instant,groq,llama-3.1-8b-instant,1008.937,1003.93,1004.37,0.0,-2.702,-6.015,-4.969,0.0,0.385,-1.045,-1.499,-3.569,-1.499,-6.31,-1.499,-6.31,0.385,-1.045,1,1,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,1
52
+ 2026-06-22,POLYCAB.NS,INTRADAY,LOW,NEUTRAL,,0.68,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,10022.5,9822.05,10222.95,0.0,-1.018,-4.904,-2.43,0.0,1.033,-0.304,0.524,-1.307,0.524,-5.049,0.524,-6.006,1.033,-0.304,1,1,MIDPOINT_HIT,1,1,0,0,0,0,0,0,0,0,0,0
53
+ 2026-06-22,DLF.NS,3D,HIGH,BULLISH,,0.71,12.8,False,ollama:qwen2.5:1.5b,ollama,qwen2.5:1.5b,627.6,633.03,633.3,0.0,-2.43,-0.996,-2.047,-0.996,0.669,-0.398,1.402,-2.796,1.402,-2.9,1.402,-2.9,1.402,-2.9,1,1,MIDPOINT_HIT,1,1,1,1,0,0,0,0,0,0,0,0
54
+ 2026-06-22,SHRIRAMFIN.NS,3D,MEDIUM,BULLISH,,0.78,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,987.265,995.08,995.47,0.0,0.05,3.923,4.009,3.923,1.299,-0.912,1.496,-0.841,5.958,-1.239,6.3,-1.239,5.958,-1.239,1,1,MIDPOINT_HIT,1,1,1,1,0,0,1,0,1,0,0,0
55
+ 2026-06-22,AXISCADES.NS,INTRADAY,MEDIUM,BULLISH,,0.71,12.8,False,cerebras:gemma-4-31b,cerebras,gemma-4-31b,1878.0,1892.47,1893.88,0.0,-1.928,-9.957,-9.526,0.0,3.573,-0.426,1.587,-2.391,1.587,-10.602,1.587,-12.875,3.573,-0.426,1,1,MIDPOINT_HIT,1,1,1,0,0,0,0,0,0,0,0,0
research/confidence_calibration.json CHANGED
@@ -17,8 +17,8 @@
17
  },
18
  "3D": {
19
  "n_total": 18,
20
- "high_rate_pct": 0.0,
21
- "high_hit_pct": null,
22
  "medium_hit_pct": 100.0,
23
  "recommendation": "promote_medium_to_high"
24
  }
 
17
  },
18
  "3D": {
19
  "n_total": 18,
20
+ "high_rate_pct": 5.6,
21
+ "high_hit_pct": 100.0,
22
  "medium_hit_pct": 100.0,
23
  "recommendation": "promote_medium_to_high"
24
  }
research/db_backtest.py ADDED
@@ -0,0 +1,694 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ research/db_backtest.py β€” NSE Strategy Backtest using cached OHLCV data.
4
+
5
+ Follows the 6-step workflow: Idea β†’ Rules β†’ Code β†’ Variations β†’ Backtest β†’ Filter β†’ Report
6
+
7
+ Data source: ohlcv_cache.db β†’ ohlcv_cache table (same schema as data_sources.py).
8
+ Supports fetching all NSE universe stocks and caching them on first run.
9
+
10
+ Usage:
11
+ python research/db_backtest.py # backtest cached stocks
12
+ python research/db_backtest.py --fetch # fetch full NSE universe first, then backtest
13
+ python research/db_backtest.py --fetch-only # only fetch/refresh data, no backtest
14
+ """
15
+
16
+ import os, sys, pickle, sqlite3, warnings, argparse
17
+ import numpy as np
18
+ import pandas as pd
19
+ from concurrent.futures import ThreadPoolExecutor, as_completed
20
+ from datetime import datetime
21
+ from typing import Dict, List, Tuple, Optional
22
+
23
+ warnings.filterwarnings("ignore")
24
+
25
+ # Add project root to path so we can import data_sources + universe
26
+ _PROJ_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
27
+ if _PROJ_ROOT not in sys.path:
28
+ sys.path.insert(0, _PROJ_ROOT)
29
+
30
+ # ---------------------------------------------------------------------------
31
+ # Config
32
+ # ---------------------------------------------------------------------------
33
+ FEES_PCT = 0.10 # per-side brokerage + STT (%)
34
+ SLIPPAGE_PCT = 0.05 # per-side market impact (%)
35
+ ROUND_TRIP_COST = (FEES_PCT + SLIPPAGE_PCT) * 2 / 100 # total cost as decimal
36
+
37
+ # ohlcv_cache.db lives in the project root (same logic as data_sources._ohlcv_data_dir)
38
+ _HF_DATA = "/data"
39
+ _OHLCV_DB = os.path.join(
40
+ _HF_DATA if (os.path.isdir(_HF_DATA) and os.access(_HF_DATA, os.W_OK)) else _PROJ_ROOT,
41
+ "ohlcv_cache.db",
42
+ )
43
+ OUT_DIR = os.path.dirname(os.path.abspath(__file__))
44
+
45
+ FETCH_PERIOD = "2y" # period for data fetch and backtest
46
+ FETCH_WORKERS = 6 # parallel fetch threads (keep low to avoid rate limits)
47
+
48
+ # ---------------------------------------------------------------------------
49
+ # STEP 1 β€” RULES
50
+ # ---------------------------------------------------------------------------
51
+ STRATEGIES = {
52
+ # ── Baseline (keep for comparison) ──────────────────────────────────────
53
+ "V1_RSI14_EMA200_3D": {
54
+ "desc": "RSI(14)<30 + Close>EMA200 β†’ hold 3 days or RSI>60",
55
+ "rsi_period": 14, "rsi_entry": 30, "rsi_exit": 60,
56
+ "ema_trend": 200, "max_hold": 3,
57
+ },
58
+ "V3_RSI2_EMA200_3D": {
59
+ "desc": "RSI(2)<5 + Close>EMA200 β†’ hold 3 days (mirrors S4V2 signal)",
60
+ "rsi_period": 2, "rsi_entry": 5, "rsi_exit": 70,
61
+ "ema_trend": 200, "max_hold": 3,
62
+ },
63
+ "V4_RSI14_DEEP_5D": {
64
+ "desc": "RSI(14)<25 (deeply oversold, no trend filter) β†’ hold 5 days",
65
+ "rsi_period": 14, "rsi_entry": 25, "rsi_exit": 55,
66
+ "ema_trend": None, "max_hold": 5,
67
+ },
68
+ # ── Improved strategies β€” higher accuracy ───────────────────────────────
69
+ "V5_RSI14_ADX_5D": {
70
+ "desc": "RSI(14)<25 + ADX>20 β†’ hold 5 days (V4 + trending market filter)",
71
+ "rsi_period": 14, "rsi_entry": 25, "rsi_exit": 55,
72
+ "ema_trend": None, "adx_min": 20, "max_hold": 5,
73
+ },
74
+ "V6_RSI14_BB_5D": {
75
+ "desc": "RSI(14)<30 + BB_pos<25% + EMA200 β†’ 5D hold or +3% profit target",
76
+ "rsi_period": 14, "rsi_entry": 30, "rsi_exit": 60,
77
+ "ema_trend": 200, "bb_max": 25.0, "max_hold": 5, "profit_target_pct": 3.0,
78
+ },
79
+ "V7_RSI2_ADX_3D": {
80
+ "desc": "RSI(2)<5 + EMA200 + ADX>15 β†’ 3D hold or +4% profit target (S4V2 + ADX)",
81
+ "rsi_period": 2, "rsi_entry": 5, "rsi_exit": 70,
82
+ "ema_trend": 200, "adx_min": 15, "max_hold": 3, "profit_target_pct": 4.0,
83
+ },
84
+ "V8_TRIPLE_RSI_5D": {
85
+ "desc": "RSI(14)<35 + RSI(2)<5 + EMA200 + ADX>20 β†’ 5D hold or +5% (S_CTRIO-inspired)",
86
+ "rsi_period": 14, "rsi_entry": 35, "rsi_exit": 60,
87
+ "rsi2_entry": 5, "ema_trend": 200, "adx_min": 20, "max_hold": 5,
88
+ "profit_target_pct": 5.0,
89
+ },
90
+ }
91
+
92
+ # ---------------------------------------------------------------------------
93
+ # STEP 2 β€” UNIVERSE FETCH + OHLCV CACHING
94
+ # ---------------------------------------------------------------------------
95
+
96
+ def fetch_and_cache_universe(universe_size: int = 500, period: str = FETCH_PERIOD) -> List[str]:
97
+ """
98
+ Fetch the top-N NSE stocks by market cap, download OHLCV for any not
99
+ already cached, and save them to ohlcv_cache.db via data_sources.fetch_ohlcv.
100
+ Returns the list of all tickers available after the fetch.
101
+ """
102
+ from universe import get_universe
103
+ from data_sources import fetch_ohlcv
104
+
105
+ print(f"[fetch] Loading NSE universe (top {universe_size} by market cap) ...")
106
+ universe = get_universe()
107
+ tickers = list(universe.keys())[:universe_size]
108
+ print(f"[fetch] {len(tickers)} tickers in universe")
109
+
110
+ # Find which tickers already have fresh cached data
111
+ cached = _get_cached_tickers(period)
112
+ to_fetch = [t for t in tickers if t not in cached]
113
+ print(f"[fetch] {len(cached)} already cached, {len(to_fetch)} need fetching")
114
+
115
+ if not to_fetch:
116
+ print("[fetch] All tickers already cached.")
117
+ return tickers
118
+
119
+ ok = 0
120
+ fail = 0
121
+
122
+ def _fetch_one(ticker):
123
+ try:
124
+ fetch_ohlcv(ticker, period=period) # auto-saves to ohlcv_cache.db
125
+ return ticker, True
126
+ except Exception as e:
127
+ return ticker, False
128
+
129
+ with ThreadPoolExecutor(max_workers=FETCH_WORKERS) as ex:
130
+ futs = {ex.submit(_fetch_one, t): t for t in to_fetch}
131
+ for i, fut in enumerate(as_completed(futs), 1):
132
+ ticker, success = fut.result()
133
+ if success:
134
+ ok += 1
135
+ else:
136
+ fail += 1
137
+ if i % 20 == 0 or i == len(to_fetch):
138
+ print(f"[fetch] {i}/{len(to_fetch)} done β€” {ok} ok, {fail} failed")
139
+
140
+ print(f"[fetch] Complete: {ok} fetched, {fail} failed")
141
+ return tickers
142
+
143
+
144
+ def _get_cached_tickers(period: str = FETCH_PERIOD) -> set:
145
+ """Return set of tickers that have data in ohlcv_cache.db for the given period."""
146
+ try:
147
+ conn = sqlite3.connect(f"file:{_OHLCV_DB}?mode=ro", uri=True)
148
+ rows = conn.execute(
149
+ "SELECT DISTINCT ticker FROM ohlcv_cache WHERE period=?", (period,)
150
+ ).fetchall()
151
+ conn.close()
152
+ return {r[0] for r in rows}
153
+ except Exception:
154
+ return set()
155
+
156
+
157
+ # ---------------------------------------------------------------------------
158
+ # STEP 3 β€” DATA LOADING
159
+ # ---------------------------------------------------------------------------
160
+
161
+ def load_all_ohlcv(period: str = FETCH_PERIOD) -> Dict[str, pd.DataFrame]:
162
+ """Load all tickers from ohlcv_cache.db into {ticker: DataFrame}."""
163
+ if not os.path.exists(_OHLCV_DB):
164
+ print(f"[data] ohlcv_cache.db not found at {_OHLCV_DB}")
165
+ print("[data] Run with --fetch to download NSE data first.")
166
+ return {}
167
+
168
+ conn = sqlite3.connect(f"file:{_OHLCV_DB}?immutable=1", uri=True)
169
+ cursor = conn.cursor()
170
+ cursor.execute(
171
+ "SELECT ticker, data FROM ohlcv_cache WHERE period=? ORDER BY ticker",
172
+ (period,),
173
+ )
174
+ rows = cursor.fetchall()
175
+ conn.close()
176
+
177
+ data = {}
178
+ for ticker, blob in rows:
179
+ try:
180
+ sc, sh, sl, sv = pickle.loads(blob)
181
+ col = sc.columns[0]
182
+ df = pd.DataFrame({
183
+ "Close": sc[col],
184
+ "High": sh[col],
185
+ "Low": sl[col],
186
+ "Volume": sv[col],
187
+ })
188
+ df.index = pd.to_datetime(df.index)
189
+ df = df.sort_index().dropna(subset=["Close"])
190
+ if len(df) >= 60:
191
+ data[ticker] = df
192
+ except Exception:
193
+ pass
194
+
195
+ print(f"[data] Loaded {len(data)} tickers (period={period})")
196
+ return data
197
+
198
+
199
+ # ---------------------------------------------------------------------------
200
+ # STEP 4 β€” INDICATORS
201
+ # ---------------------------------------------------------------------------
202
+
203
+ def compute_rsi(close: pd.Series, period: int = 14) -> pd.Series:
204
+ delta = close.diff()
205
+ gain = delta.clip(lower=0)
206
+ loss = -delta.clip(upper=0)
207
+ avg_gain = gain.ewm(com=period - 1, min_periods=period).mean()
208
+ avg_loss = loss.ewm(com=period - 1, min_periods=period).mean()
209
+ rs = avg_gain / avg_loss.replace(0, np.nan)
210
+ return 100 - (100 / (1 + rs))
211
+
212
+
213
+ def compute_ema(close: pd.Series, period: int) -> pd.Series:
214
+ return close.ewm(span=period, min_periods=period).mean()
215
+
216
+
217
+ def compute_adx(df: pd.DataFrame, period: int = 14) -> pd.Series:
218
+ """Average Directional Index (Wilder smoothing). Returns ADX series."""
219
+ high = df["High"]
220
+ low = df["Low"]
221
+ close = df["Close"]
222
+ prev_close = close.shift(1)
223
+ prev_high = high.shift(1)
224
+ prev_low = low.shift(1)
225
+
226
+ tr = pd.concat([
227
+ high - low,
228
+ (high - prev_close).abs(),
229
+ (low - prev_close).abs(),
230
+ ], axis=1).max(axis=1)
231
+
232
+ plus_dm = (high - prev_high).clip(lower=0).where(
233
+ (high - prev_high) > (prev_low - low), 0
234
+ )
235
+ minus_dm = (prev_low - low).clip(lower=0).where(
236
+ (prev_low - low) > (high - prev_high), 0
237
+ )
238
+
239
+ atr = tr.ewm(com=period - 1, min_periods=period).mean()
240
+ plus_di = 100 * plus_dm.ewm(com=period - 1, min_periods=period).mean() / atr
241
+ minus_di = 100 * minus_dm.ewm(com=period - 1, min_periods=period).mean() / atr
242
+ dx = (100 * (plus_di - minus_di).abs() / (plus_di + minus_di).replace(0, np.nan))
243
+ adx = dx.ewm(com=period - 1, min_periods=period).mean()
244
+ return adx
245
+
246
+
247
+ def compute_bb_position(close: pd.Series, period: int = 20) -> pd.Series:
248
+ """
249
+ Bollinger Band position: 0% = at lower band, 100% = at upper band.
250
+ Values below 25% = oversold relative to recent range.
251
+ """
252
+ mid = close.rolling(period, min_periods=period).mean()
253
+ std = close.rolling(period, min_periods=period).std()
254
+ lower = mid - 2 * std
255
+ upper = mid + 2 * std
256
+ band_width = (upper - lower).replace(0, np.nan)
257
+ return ((close - lower) / band_width * 100).clip(0, 100)
258
+
259
+
260
+ def generate_signals(df: pd.DataFrame, params: dict) -> pd.Series:
261
+ """Return True on bars where entry conditions are met."""
262
+ close = df["Close"]
263
+ rsi = compute_rsi(close, params["rsi_period"])
264
+ sig = rsi < params["rsi_entry"]
265
+
266
+ if params.get("ema_trend") is not None:
267
+ ema = compute_ema(close, params["ema_trend"])
268
+ sig = sig & (close > ema)
269
+
270
+ if params.get("adx_min") is not None:
271
+ adx = compute_adx(df)
272
+ sig = sig & (adx > params["adx_min"])
273
+
274
+ if params.get("bb_max") is not None:
275
+ bb = compute_bb_position(close)
276
+ sig = sig & (bb < params["bb_max"])
277
+
278
+ if params.get("rsi2_entry") is not None:
279
+ rsi2 = compute_rsi(close, 2)
280
+ sig = sig & (rsi2 < params["rsi2_entry"])
281
+
282
+ return sig
283
+
284
+
285
+ # ---------------------------------------------------------------------------
286
+ # STEP 5 β€” BACKTEST ENGINE
287
+ # ---------------------------------------------------------------------------
288
+
289
+ def backtest_single(df: pd.DataFrame, params: dict) -> pd.DataFrame:
290
+ """
291
+ Event-driven backtest.
292
+ Entry: next bar's close after signal fires.
293
+ Exit: RSI > rsi_exit OR profit_target hit OR max_hold bars.
294
+ """
295
+ close = df["Close"].values
296
+ dates = df.index
297
+ n = len(df)
298
+
299
+ close_s = df["Close"]
300
+ rsi = compute_rsi(close_s, params["rsi_period"]).values
301
+ max_hold = params["max_hold"]
302
+ rsi_exit_th = params["rsi_exit"]
303
+ profit_target = params.get("profit_target_pct")
304
+
305
+ # Precompute optional EMA / ADX / BB / RSI2 arrays for exit checks
306
+ ema_arr = None
307
+ adx_arr = None
308
+ bb_arr = None
309
+ rsi2_arr = None
310
+
311
+ if params.get("ema_trend") is not None:
312
+ ema_arr = compute_ema(close_s, params["ema_trend"]).values
313
+ if params.get("adx_min") is not None:
314
+ adx_arr = compute_adx(df).values
315
+ if params.get("bb_max") is not None:
316
+ bb_arr = compute_bb_position(close_s).values
317
+ if params.get("rsi2_entry") is not None:
318
+ rsi2_arr = compute_rsi(close_s, 2).values
319
+
320
+ trades = []
321
+ in_trade = False
322
+ entry_idx = None
323
+ entry_price = None
324
+
325
+ for i in range(1, n):
326
+ if in_trade:
327
+ hold_bars = i - entry_idx
328
+ rsi_exit = rsi[i] > rsi_exit_th
329
+ max_exit = hold_bars >= max_hold
330
+ profit_exit = (
331
+ profit_target is not None
332
+ and (close[i] - entry_price) / entry_price * 100 >= profit_target
333
+ )
334
+
335
+ if rsi_exit or max_exit or profit_exit:
336
+ exit_price = close[i]
337
+ gross_ret = (exit_price - entry_price) / entry_price
338
+ net_ret = gross_ret - ROUND_TRIP_COST
339
+ reason = "rsi" if rsi_exit else ("profit" if profit_exit else "maxhold")
340
+ trades.append({
341
+ "entry_date": dates[entry_idx],
342
+ "exit_date": dates[i],
343
+ "entry_price": entry_price,
344
+ "exit_price": exit_price,
345
+ "hold_bars": hold_bars,
346
+ "gross_pct": gross_ret * 100,
347
+ "net_pct": net_ret * 100,
348
+ "win": net_ret > 0,
349
+ "exit_reason": reason,
350
+ })
351
+ in_trade = False
352
+ else:
353
+ # Check entry conditions on bar i-1
354
+ prev_rsi_ok = rsi[i - 1] < params["rsi_entry"]
355
+ prev_ema_ok = (
356
+ params.get("ema_trend") is None
357
+ or (ema_arr is not None and not np.isnan(ema_arr[i - 1])
358
+ and close[i - 1] > ema_arr[i - 1])
359
+ )
360
+ prev_adx_ok = (
361
+ params.get("adx_min") is None
362
+ or (adx_arr is not None and not np.isnan(adx_arr[i - 1])
363
+ and adx_arr[i - 1] > params["adx_min"])
364
+ )
365
+ prev_bb_ok = (
366
+ params.get("bb_max") is None
367
+ or (bb_arr is not None and not np.isnan(bb_arr[i - 1])
368
+ and bb_arr[i - 1] < params["bb_max"])
369
+ )
370
+ prev_rsi2_ok = (
371
+ params.get("rsi2_entry") is None
372
+ or (rsi2_arr is not None and not np.isnan(rsi2_arr[i - 1])
373
+ and rsi2_arr[i - 1] < params["rsi2_entry"])
374
+ )
375
+
376
+ if prev_rsi_ok and prev_ema_ok and prev_adx_ok and prev_bb_ok and prev_rsi2_ok:
377
+ entry_price = close[i]
378
+ entry_idx = i
379
+ in_trade = True
380
+
381
+ return pd.DataFrame(trades)
382
+
383
+
384
+ def compute_metrics(trades: pd.DataFrame, total_bars: int) -> dict:
385
+ if len(trades) == 0:
386
+ return {
387
+ "n_trades": 0, "win_rate": 0.0, "avg_net_pct": 0.0,
388
+ "total_return_pct": 0.0, "max_drawdown_pct": 0.0,
389
+ "profit_factor": 0.0, "trades_per_year": 0.0,
390
+ }
391
+
392
+ wins = trades[trades["win"]]
393
+ losses = trades[~trades["win"]]
394
+
395
+ n_trades = len(trades)
396
+ win_rate = len(wins) / n_trades * 100
397
+ avg_net = trades["net_pct"].mean()
398
+
399
+ compound = (1 + trades["net_pct"] / 100).prod() - 1
400
+ equity = (1 + trades["net_pct"] / 100).cumprod()
401
+ roll_max = equity.cummax()
402
+ max_dd = ((equity - roll_max) / roll_max).min() * 100
403
+
404
+ gross_wins = wins["net_pct"].sum() if len(wins) else 0
405
+ gross_losses = abs(losses["net_pct"].sum()) if len(losses) else 0
406
+ pf = min(gross_wins / gross_losses, 99.0) if gross_losses > 0 else 99.0
407
+
408
+ years = total_bars / 252
409
+ tpy = n_trades / years if years > 0 else 0
410
+
411
+ return {
412
+ "n_trades": n_trades,
413
+ "win_rate": round(win_rate, 1),
414
+ "avg_net_pct": round(avg_net, 3),
415
+ "total_return_pct": round(compound * 100, 2),
416
+ "max_drawdown_pct": round(max_dd, 2),
417
+ "profit_factor": round(pf, 2),
418
+ "trades_per_year": round(tpy, 1),
419
+ }
420
+
421
+
422
+ # ---------------------------------------------------------------------------
423
+ # STEP 6 β€” FILTER
424
+ # ---------------------------------------------------------------------------
425
+ MIN_TOTAL_TRADES = 50
426
+ MIN_PROFIT_FACTOR = 1.10
427
+ MIN_WIN_RATE = 50.0 # raised from 45% β€” target real edge
428
+ MIN_OOS_TRADES = 10
429
+ MIN_OOS_PROFIT_FACTOR = 1.0
430
+
431
+
432
+ def passes_is_filter(m: dict) -> bool:
433
+ return (
434
+ m["n_trades"] >= MIN_TOTAL_TRADES
435
+ and m["profit_factor"] >= MIN_PROFIT_FACTOR
436
+ and m["win_rate"] >= MIN_WIN_RATE
437
+ )
438
+
439
+
440
+ def passes_oos_filter(m: dict) -> bool:
441
+ return (
442
+ m["n_trades"] >= MIN_OOS_TRADES
443
+ and m["profit_factor"] >= MIN_OOS_PROFIT_FACTOR
444
+ )
445
+
446
+
447
+ # ---------------------------------------------------------------------------
448
+ # MAIN BACKTEST RUNNER
449
+ # ---------------------------------------------------------------------------
450
+ IS_END = "2025-07-17"
451
+ OOS_START = "2025-07-18"
452
+
453
+
454
+ def run_full_backtest(data: Dict[str, pd.DataFrame]):
455
+ aggregate = {}
456
+ oos_aggregate = {}
457
+ per_ticker = {}
458
+
459
+ for name, params in STRATEGIES.items():
460
+ print(f"\n--- {name} ---")
461
+ is_trades_all = []
462
+ oos_trades_all = []
463
+ is_bars_total = 0
464
+ oos_bars_total = 0
465
+ ticker_metrics = {}
466
+
467
+ for ticker, df in data.items():
468
+ df_is = df[df.index <= IS_END]
469
+ df_oos = df[df.index > IS_END]
470
+
471
+ if len(df_is) >= 30:
472
+ t_is = backtest_single(df_is, params)
473
+ ticker_metrics[ticker] = compute_metrics(t_is, len(df_is))
474
+ is_trades_all.append(t_is)
475
+ is_bars_total += len(df_is)
476
+
477
+ if len(df_oos) >= 10:
478
+ t_oos = backtest_single(df_oos, params)
479
+ oos_trades_all.append(t_oos)
480
+ oos_bars_total += len(df_oos)
481
+
482
+ combined_is = pd.concat(is_trades_all, ignore_index=True) if is_trades_all else pd.DataFrame()
483
+ combined_oos = pd.concat(oos_trades_all, ignore_index=True) if oos_trades_all else pd.DataFrame()
484
+
485
+ m_is = compute_metrics(combined_is, is_bars_total)
486
+ m_oos = compute_metrics(combined_oos, oos_bars_total)
487
+
488
+ print(f" IS β†’ trades={m_is['n_trades']}, WR={m_is['win_rate']}%, PF={m_is['profit_factor']}, ret={m_is['total_return_pct']}%")
489
+ print(f" OOS β†’ trades={m_oos['n_trades']}, WR={m_oos['win_rate']}%, PF={m_oos['profit_factor']}, ret={m_oos['total_return_pct']}%")
490
+
491
+ aggregate[name] = m_is
492
+ oos_aggregate[name] = m_oos
493
+ per_ticker[name] = ticker_metrics
494
+
495
+ return aggregate, oos_aggregate, per_ticker
496
+
497
+
498
+ # ---------------------------------------------------------------------------
499
+ # STEP 7 β€” REPORT GENERATOR
500
+ # ---------------------------------------------------------------------------
501
+
502
+ def _improvement_vs_v4(m_is: dict, m_oos: dict, v4_is: dict, v4_oos: dict) -> str:
503
+ """Return a short delta string showing win-rate and PF change vs V4."""
504
+ wr_delta = m_is["win_rate"] - v4_is["win_rate"]
505
+ pf_delta = m_is["profit_factor"] - v4_is["profit_factor"]
506
+ oos_wr_delta = m_oos["win_rate"] - v4_oos["win_rate"]
507
+ sign = lambda x: f"+{x:.1f}" if x >= 0 else f"{x:.1f}"
508
+ return f"IS WR {sign(wr_delta)}pp, IS PF {sign(pf_delta)}, OOS WR {sign(oos_wr_delta)}pp vs V4"
509
+
510
+
511
+ def generate_report(aggregate: dict, oos_aggregate: dict, per_ticker: dict, data: dict) -> str:
512
+ now = datetime.now().strftime("%Y-%m-%d %H:%M")
513
+ total_stocks = len(data)
514
+
515
+ survivors = [
516
+ n for n in STRATEGIES
517
+ if passes_is_filter(aggregate[n]) and passes_oos_filter(oos_aggregate[n])
518
+ ]
519
+
520
+ v4_is = aggregate.get("V4_RSI14_DEEP_5D", {})
521
+ v4_oos = oos_aggregate.get("V4_RSI14_DEEP_5D", {})
522
+
523
+ lines = []
524
+ lines.append("# NSE Stock Strategy Backtest Report")
525
+ lines.append(f"\n**Generated:** {now} ")
526
+ lines.append(f"**Universe:** {total_stocks} NSE stocks (ohlcv_cache.db) ")
527
+ lines.append(f"**In-sample:** 2024-07-18 β†’ {IS_END} | **Out-of-sample:** {OOS_START} β†’ today ")
528
+ lines.append(f"**Transaction costs:** {FEES_PCT}% + {SLIPPAGE_PCT}% slippage per side = {ROUND_TRIP_COST*100:.2f}% round-trip ")
529
+ lines.append("**Note:** *Total Return %* = sequential compounding across all trades. Profit factor capped at 99.0 when no losing trades. ")
530
+
531
+ lines.append("\n---\n## Disclaimer\n")
532
+ lines.append("> **Educational only β€” not financial advice.** Past backtest results do not guarantee future performance.")
533
+
534
+ lines.append("\n---\n## Strategy Rules\n")
535
+ for name, params in STRATEGIES.items():
536
+ tag = "NEW" if name.startswith(("V5", "V6", "V7", "V8")) else "baseline"
537
+ lines.append(f"### {name} `[{tag}]`")
538
+ lines.append(f"- **Description:** {params['desc']}")
539
+ lines.append(f"- RSI period: {params['rsi_period']} | Entry RSI < {params['rsi_entry']} | Exit RSI > {params['rsi_exit']}")
540
+ if params.get("rsi2_entry"):
541
+ lines.append(f"- Secondary RSI(2) confirmation: RSI2 < {params['rsi2_entry']}")
542
+ if params.get("ema_trend"):
543
+ lines.append(f"- Trend filter: Close > EMA({params['ema_trend']})")
544
+ if params.get("adx_min"):
545
+ lines.append(f"- ADX filter: ADX(14) > {params['adx_min']} (trending market only)")
546
+ if params.get("bb_max"):
547
+ lines.append(f"- Bollinger filter: BB_pos < {params['bb_max']}% (below lower BB zone)")
548
+ if params.get("profit_target_pct"):
549
+ lines.append(f"- Profit target: +{params['profit_target_pct']}% (exit early to lock in gain)")
550
+ lines.append(f"- Max hold: {params['max_hold']} bars")
551
+ lines.append("")
552
+
553
+ lines.append("---\n## In-Sample Results\n")
554
+ lines.append("| Strategy | Trades | Win Rate | Avg Net % | Total Return % | Max DD % | Profit Factor | Trades/yr |")
555
+ lines.append("|---|---|---|---|---|---|---|---|")
556
+ for name, m in aggregate.items():
557
+ lines.append(
558
+ f"| {name} | {m['n_trades']} | {m['win_rate']}% | {m['avg_net_pct']}% | "
559
+ f"{m['total_return_pct']}% | {m['max_drawdown_pct']}% | {m['profit_factor']} | {m['trades_per_year']} |"
560
+ )
561
+
562
+ lines.append("\n## Out-of-Sample Results (Survival Test)\n")
563
+ lines.append("| Strategy | Trades | Win Rate | Avg Net % | Total Return % | Max DD % | Profit Factor | Survived? |")
564
+ lines.append("|---|---|---|---|---|---|---|---|")
565
+ for name, m in oos_aggregate.items():
566
+ survived = name in survivors
567
+ flag = "βœ… Yes" if survived else "❌ No"
568
+ lines.append(
569
+ f"| {name} | {m['n_trades']} | {m['win_rate']}% | {m['avg_net_pct']}% | "
570
+ f"{m['total_return_pct']}% | {m['max_drawdown_pct']}% | {m['profit_factor']} | {flag} |"
571
+ )
572
+
573
+ lines.append("\n---\n## Accuracy Improvement vs V4 Baseline\n")
574
+ if v4_is and v4_oos:
575
+ lines.append("| Strategy | IS Win Rate | OOS Win Rate | IS Profit Factor | OOS PF | Delta vs V4 |")
576
+ lines.append("|---|---|---|---|---|---|")
577
+ for name in STRATEGIES:
578
+ m_is = aggregate[name]
579
+ m_oos = oos_aggregate[name]
580
+ delta = _improvement_vs_v4(m_is, m_oos, v4_is, v4_oos) if v4_is else "β€”"
581
+ lines.append(
582
+ f"| {name} | {m_is['win_rate']}% | {m_oos['win_rate']}% | "
583
+ f"{m_is['profit_factor']} | {m_oos['profit_factor']} | {delta} |"
584
+ )
585
+ else:
586
+ lines.append("_V4 baseline not available for comparison._")
587
+
588
+ lines.append("\n---\n## Filter Criteria\n")
589
+ lines.append(f"- Minimum total IS trades: β‰₯ {MIN_TOTAL_TRADES}")
590
+ lines.append(f"- Minimum IS profit factor: β‰₯ {MIN_PROFIT_FACTOR}")
591
+ lines.append(f"- Minimum IS win rate: β‰₯ {MIN_WIN_RATE}%")
592
+ lines.append(f"- Minimum OOS trades: β‰₯ {MIN_OOS_TRADES}")
593
+ lines.append(f"- Minimum OOS profit factor: β‰₯ {MIN_OOS_PROFIT_FACTOR}")
594
+
595
+ lines.append("\n---\n## Strategy Filter Results\n")
596
+ for name in STRATEGIES:
597
+ m_is = aggregate[name]
598
+ m_oos = oos_aggregate[name]
599
+ survived = name in survivors
600
+ issues = []
601
+ if m_is["n_trades"] < MIN_TOTAL_TRADES: issues.append(f"too few IS trades ({m_is['n_trades']})")
602
+ if m_is["profit_factor"] < MIN_PROFIT_FACTOR: issues.append(f"IS PF too low ({m_is['profit_factor']})")
603
+ if m_is["win_rate"] < MIN_WIN_RATE: issues.append(f"IS win rate too low ({m_is['win_rate']}%)")
604
+ if m_oos["n_trades"] < MIN_OOS_TRADES: issues.append(f"too few OOS trades ({m_oos['n_trades']})")
605
+ elif m_oos["profit_factor"] < MIN_OOS_PROFIT_FACTOR:
606
+ issues.append(f"OOS PF < 1 ({m_oos['profit_factor']})")
607
+ if survived:
608
+ lines.append(f"### βœ… {name} β€” SURVIVED")
609
+ lines.append(f"Passed all filters. IS WR {m_is['win_rate']}% / PF {m_is['profit_factor']}, OOS PF {m_oos['profit_factor']}.")
610
+ else:
611
+ lines.append(f"### ❌ {name} β€” ELIMINATED")
612
+ lines.append(f"Reasons: {'; '.join(issues) if issues else 'OOS degradation'}.")
613
+ lines.append("")
614
+
615
+ lines.append("---\n## Top 20 Stocks per Surviving Strategy\n")
616
+ for name in survivors:
617
+ lines.append(f"### {name}")
618
+ ranked = sorted(
619
+ [(t, m) for t, m in per_ticker[name].items() if m["n_trades"] >= 2],
620
+ key=lambda x: (x[1]["profit_factor"], x[1]["win_rate"]),
621
+ reverse=True,
622
+ )[:20]
623
+ if ranked:
624
+ lines.append("| Ticker | Trades | Win Rate | Profit Factor | Total Return % |")
625
+ lines.append("|---|---|---|---|---|")
626
+ for t, m in ranked:
627
+ lines.append(f"| {t} | {m['n_trades']} | {m['win_rate']}% | {m['profit_factor']} | {m['total_return_pct']}% |")
628
+ else:
629
+ lines.append("_No stocks met the minimum trade threshold._")
630
+ lines.append("")
631
+
632
+ lines.append("---\n## Known Limitations\n")
633
+ lines.append("1. **No Open price** β€” entry is next bar's Close (slight look-ahead vs true next-open execution).")
634
+ lines.append("2. **Survivorship bias** β€” universe is today's top-N NSE stocks by market cap; delisted stocks excluded.")
635
+ lines.append("3. **Single position** β€” one trade at a time per stock; no portfolio-level correlation management.")
636
+ lines.append("4. **Limited data** β€” ~500 trading days per stock means limited statistical confidence.")
637
+ lines.append("5. **EMA200 warm-up** β€” strategies with EMA200 filter skip stocks with < 200 bars.")
638
+ lines.append("6. **No gap risk** β€” overnight gaps from corporate events are not modelled separately.")
639
+ lines.append("\n---\n## Next Steps\n")
640
+ lines.append("1. Forward-test surviving strategies on paper trades via Flask watchlist UI.")
641
+ lines.append("2. Wire V8_TRIPLE_RSI_5D into `trial_run.py` as a new confirmed S-signal.")
642
+ lines.append("3. Extend data to 5+ years for higher statistical confidence on low-frequency strategies.")
643
+ lines.append("4. Add VIX<18 filter (Mode B) β€” backtested 71% win rate when VIX below 18.")
644
+ lines.append("\n---\n")
645
+ lines.append("> *Educational only β€” not financial advice. Backtested/paper analysis only.*")
646
+
647
+ return "\n".join(lines)
648
+
649
+
650
+ # ---------------------------------------------------------------------------
651
+ # ENTRY POINT
652
+ # ---------------------------------------------------------------------------
653
+
654
+ if __name__ == "__main__":
655
+ parser = argparse.ArgumentParser(description="NSE Strategy Backtest")
656
+ parser.add_argument("--fetch", action="store_true", help="Fetch full NSE universe before backtest")
657
+ parser.add_argument("--fetch-only", action="store_true", help="Only fetch data, skip backtest")
658
+ parser.add_argument("--universe-size", type=int, default=500, help="Number of NSE stocks to fetch (default 500)")
659
+ args = parser.parse_args()
660
+
661
+ print("=" * 60)
662
+ print("NSE Backtest β€” 7-Step Workflow")
663
+ print("=" * 60)
664
+
665
+ if args.fetch or args.fetch_only:
666
+ print(f"\n[0/4] Fetching NSE universe ({args.universe_size} stocks) ...")
667
+ fetch_and_cache_universe(universe_size=args.universe_size)
668
+
669
+ if args.fetch_only:
670
+ print("\nFetch complete. Run without --fetch-only to run backtest.")
671
+ sys.exit(0)
672
+
673
+ print(f"\n[1/4] Loading OHLCV data from {_OHLCV_DB} ...")
674
+ data = load_all_ohlcv(period=FETCH_PERIOD)
675
+ if not data:
676
+ print("No data found. Run with --fetch to download NSE data first.")
677
+ sys.exit(1)
678
+
679
+ print(f"\n[2/4] Running {len(STRATEGIES)} strategy variations across {len(data)} tickers ...")
680
+ aggregate, oos_aggregate, per_ticker = run_full_backtest(data)
681
+
682
+ print("\n[3/4] Generating report ...")
683
+ report_md = generate_report(aggregate, oos_aggregate, per_ticker, data)
684
+
685
+ out_path = os.path.join(OUT_DIR, "db_backtest_report.md")
686
+ with open(out_path, "w") as f:
687
+ f.write(report_md)
688
+ print(f"\n[4/4] Report saved β†’ {out_path}")
689
+
690
+ print("\n=== Summary ===")
691
+ for name, m in aggregate.items():
692
+ oos = oos_aggregate[name]
693
+ tag = "βœ…" if (passes_is_filter(m) and passes_oos_filter(oos)) else "❌"
694
+ print(f" {tag} {name}: IS WR={m['win_rate']}% PF={m['profit_factor']} | OOS WR={oos['win_rate']}% PF={oos['profit_factor']}")
research/db_backtest_report.md ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # NSE Stock Strategy Backtest Report
2
+
3
+ **Generated:** 2026-07-20 10:04
4
+ **Universe:** 485 NSE stocks (ohlcv_cache.db)
5
+ **In-sample:** 2024-07-18 β†’ 2025-07-17 | **Out-of-sample:** 2025-07-18 β†’ today
6
+ **Transaction costs:** 0.1% + 0.05% slippage per side = 0.30% round-trip
7
+ **Note:** *Total Return %* = sequential compounding across all trades. Profit factor capped at 99.0 when no losing trades.
8
+
9
+ ---
10
+ ## Disclaimer
11
+
12
+ > **Educational only β€” not financial advice.** Past backtest results do not guarantee future performance.
13
+
14
+ ---
15
+ ## Strategy Rules
16
+
17
+ ### V1_RSI14_EMA200_3D `[baseline]`
18
+ - **Description:** RSI(14)<30 + Close>EMA200 β†’ hold 3 days or RSI>60
19
+ - RSI period: 14 | Entry RSI < 30 | Exit RSI > 60
20
+ - Trend filter: Close > EMA(200)
21
+ - Max hold: 3 bars
22
+
23
+ ### V3_RSI2_EMA200_3D `[baseline]`
24
+ - **Description:** RSI(2)<5 + Close>EMA200 β†’ hold 3 days (mirrors S4V2 signal)
25
+ - RSI period: 2 | Entry RSI < 5 | Exit RSI > 70
26
+ - Trend filter: Close > EMA(200)
27
+ - Max hold: 3 bars
28
+
29
+ ### V4_RSI14_DEEP_5D `[baseline]`
30
+ - **Description:** RSI(14)<25 (deeply oversold, no trend filter) β†’ hold 5 days
31
+ - RSI period: 14 | Entry RSI < 25 | Exit RSI > 55
32
+ - Max hold: 5 bars
33
+
34
+ ### V5_RSI14_ADX_5D `[NEW]`
35
+ - **Description:** RSI(14)<25 + ADX>20 β†’ hold 5 days (V4 + trending market filter)
36
+ - RSI period: 14 | Entry RSI < 25 | Exit RSI > 55
37
+ - ADX filter: ADX(14) > 20 (trending market only)
38
+ - Max hold: 5 bars
39
+
40
+ ### V6_RSI14_BB_5D `[NEW]`
41
+ - **Description:** RSI(14)<30 + BB_pos<25% + EMA200 β†’ 5D hold or +3% profit target
42
+ - RSI period: 14 | Entry RSI < 30 | Exit RSI > 60
43
+ - Trend filter: Close > EMA(200)
44
+ - Bollinger filter: BB_pos < 25.0% (below lower BB zone)
45
+ - Profit target: +3.0% (exit early to lock in gain)
46
+ - Max hold: 5 bars
47
+
48
+ ### V7_RSI2_ADX_3D `[NEW]`
49
+ - **Description:** RSI(2)<5 + EMA200 + ADX>15 β†’ 3D hold or +4% profit target (S4V2 + ADX)
50
+ - RSI period: 2 | Entry RSI < 5 | Exit RSI > 70
51
+ - Trend filter: Close > EMA(200)
52
+ - ADX filter: ADX(14) > 15 (trending market only)
53
+ - Profit target: +4.0% (exit early to lock in gain)
54
+ - Max hold: 3 bars
55
+
56
+ ### V8_TRIPLE_RSI_5D `[NEW]`
57
+ - **Description:** RSI(14)<35 + RSI(2)<5 + EMA200 + ADX>20 β†’ 5D hold or +5% (S_CTRIO-inspired)
58
+ - RSI period: 14 | Entry RSI < 35 | Exit RSI > 60
59
+ - Secondary RSI(2) confirmation: RSI2 < 5
60
+ - Trend filter: Close > EMA(200)
61
+ - ADX filter: ADX(14) > 20 (trending market only)
62
+ - Profit target: +5.0% (exit early to lock in gain)
63
+ - Max hold: 5 bars
64
+
65
+ ---
66
+ ## In-Sample Results
67
+
68
+ | Strategy | Trades | Win Rate | Avg Net % | Total Return % | Max DD % | Profit Factor | Trades/yr |
69
+ |---|---|---|---|---|---|---|---|
70
+ | V1_RSI14_EMA200_3D | 2 | 50.0% | 0.502% | 0.36% | 0.0% | 1.13 | 0.0 |
71
+ | V3_RSI2_EMA200_3D | 291 | 57.0% | 0.021% | -4.45% | -37.9% | 1.02 | 0.7 |
72
+ | V4_RSI14_DEEP_5D | 589 | 57.4% | 1.489% | 216992.0% | -42.54% | 2.05 | 1.3 |
73
+ | V5_RSI14_ADX_5D | 525 | 54.7% | 1.346% | 43751.8% | -44.83% | 1.89 | 1.2 |
74
+ | V6_RSI14_BB_5D | 2 | 50.0% | -0.203% | -0.71% | 0.0% | 0.93 | 0.0 |
75
+ | V7_RSI2_ADX_3D | 266 | 56.8% | -0.017% | -13.01% | -38.62% | 0.98 | 0.6 |
76
+ | V8_TRIPLE_RSI_5D | 2 | 50.0% | 0.603% | 1.01% | 0.0% | 1.31 | 0.0 |
77
+
78
+ ## Out-of-Sample Results (Survival Test)
79
+
80
+ | Strategy | Trades | Win Rate | Avg Net % | Total Return % | Max DD % | Profit Factor | Survived? |
81
+ |---|---|---|---|---|---|---|---|
82
+ | V1_RSI14_EMA200_3D | 1 | 0.0% | -3.547% | -3.55% | 0.0% | 0.0 | ❌ No |
83
+ | V3_RSI2_EMA200_3D | 318 | 59.1% | 0.349% | 165.89% | -26.36% | 1.38 | ❌ No |
84
+ | V4_RSI14_DEEP_5D | 728 | 49.2% | 0.281% | 230.75% | -63.48% | 1.17 | βœ… Yes |
85
+ | V5_RSI14_ADX_5D | 550 | 45.3% | 0.053% | -32.59% | -75.02% | 1.03 | βœ… Yes |
86
+ | V6_RSI14_BB_5D | 1 | 0.0% | -3.013% | -3.01% | 0.0% | 0.0 | ❌ No |
87
+ | V7_RSI2_ADX_3D | 287 | 59.2% | 0.342% | 137.16% | -29.37% | 1.37 | ❌ No |
88
+ | V8_TRIPLE_RSI_5D | 17 | 29.4% | -0.52% | -9.89% | -24.15% | 0.71 | ❌ No |
89
+
90
+ ---
91
+ ## Accuracy Improvement vs V4 Baseline
92
+
93
+ | Strategy | IS Win Rate | OOS Win Rate | IS Profit Factor | OOS PF | Delta vs V4 |
94
+ |---|---|---|---|---|---|
95
+ | V1_RSI14_EMA200_3D | 50.0% | 0.0% | 1.13 | 0.0 | IS WR -7.4pp, IS PF -0.9, OOS WR -49.2pp vs V4 |
96
+ | V3_RSI2_EMA200_3D | 57.0% | 59.1% | 1.02 | 1.38 | IS WR -0.4pp, IS PF -1.0, OOS WR +9.9pp vs V4 |
97
+ | V4_RSI14_DEEP_5D | 57.4% | 49.2% | 2.05 | 1.17 | IS WR +0.0pp, IS PF +0.0, OOS WR +0.0pp vs V4 |
98
+ | V5_RSI14_ADX_5D | 54.7% | 45.3% | 1.89 | 1.03 | IS WR -2.7pp, IS PF -0.2, OOS WR -3.9pp vs V4 |
99
+ | V6_RSI14_BB_5D | 50.0% | 0.0% | 0.93 | 0.0 | IS WR -7.4pp, IS PF -1.1, OOS WR -49.2pp vs V4 |
100
+ | V7_RSI2_ADX_3D | 56.8% | 59.2% | 0.98 | 1.37 | IS WR -0.6pp, IS PF -1.1, OOS WR +10.0pp vs V4 |
101
+ | V8_TRIPLE_RSI_5D | 50.0% | 29.4% | 1.31 | 0.71 | IS WR -7.4pp, IS PF -0.7, OOS WR -19.8pp vs V4 |
102
+
103
+ ---
104
+ ## Filter Criteria
105
+
106
+ - Minimum total IS trades: β‰₯ 50
107
+ - Minimum IS profit factor: β‰₯ 1.1
108
+ - Minimum IS win rate: β‰₯ 50.0%
109
+ - Minimum OOS trades: β‰₯ 10
110
+ - Minimum OOS profit factor: β‰₯ 1.0
111
+
112
+ ---
113
+ ## Strategy Filter Results
114
+
115
+ ### ❌ V1_RSI14_EMA200_3D β€” ELIMINATED
116
+ Reasons: too few IS trades (2); too few OOS trades (1).
117
+
118
+ ### ❌ V3_RSI2_EMA200_3D β€” ELIMINATED
119
+ Reasons: IS PF too low (1.02).
120
+
121
+ ### βœ… V4_RSI14_DEEP_5D β€” SURVIVED
122
+ Passed all filters. IS WR 57.4% / PF 2.05, OOS PF 1.17.
123
+
124
+ ### βœ… V5_RSI14_ADX_5D β€” SURVIVED
125
+ Passed all filters. IS WR 54.7% / PF 1.89, OOS PF 1.03.
126
+
127
+ ### ❌ V6_RSI14_BB_5D β€” ELIMINATED
128
+ Reasons: too few IS trades (2); IS PF too low (0.93); too few OOS trades (1).
129
+
130
+ ### ❌ V7_RSI2_ADX_3D β€” ELIMINATED
131
+ Reasons: IS PF too low (0.98).
132
+
133
+ ### ❌ V8_TRIPLE_RSI_5D β€” ELIMINATED
134
+ Reasons: too few IS trades (2); OOS PF < 1 (0.71).
135
+
136
+ ---
137
+ ## Top 20 Stocks per Surviving Strategy
138
+
139
+ ### V4_RSI14_DEEP_5D
140
+ | Ticker | Trades | Win Rate | Profit Factor | Total Return % |
141
+ |---|---|---|---|---|
142
+ | ADANIENT.NS | 2 | 100.0% | 99.0 | 13.81% |
143
+ | ADANIGREEN.NS | 2 | 100.0% | 99.0 | 35.38% |
144
+ | AUBANK.NS | 3 | 100.0% | 99.0 | 5.77% |
145
+ | AXISBANK.NS | 2 | 100.0% | 99.0 | 4.48% |
146
+ | BANDHANBNK.NS | 2 | 100.0% | 99.0 | 3.57% |
147
+ | BANKINDIA.NS | 2 | 100.0% | 99.0 | 8.01% |
148
+ | BHARATFORG.NS | 2 | 100.0% | 99.0 | 4.12% |
149
+ | BHEL.NS | 3 | 100.0% | 99.0 | 13.98% |
150
+ | CASTROLIND.NS | 2 | 100.0% | 99.0 | 3.34% |
151
+ | COHANCE.NS | 3 | 100.0% | 99.0 | 15.38% |
152
+ | CRAFTSMAN.NS | 3 | 100.0% | 99.0 | 18.91% |
153
+ | ENDURANCE.NS | 2 | 100.0% | 99.0 | 7.94% |
154
+ | GMDCLTD.NS | 3 | 100.0% | 99.0 | 17.63% |
155
+ | GODREJPROP.NS | 2 | 100.0% | 99.0 | 15.26% |
156
+ | HINDALCO.NS | 2 | 100.0% | 99.0 | 7.79% |
157
+ | HINDUNILVR.NS | 3 | 100.0% | 99.0 | 2.85% |
158
+ | HINDZINC.NS | 2 | 100.0% | 99.0 | 7.01% |
159
+ | INFY.NS | 2 | 100.0% | 99.0 | 1.38% |
160
+ | INGERRAND.NS | 2 | 100.0% | 99.0 | 6.25% |
161
+ | INOXWIND.NS | 2 | 100.0% | 99.0 | 10.7% |
162
+
163
+ ### V5_RSI14_ADX_5D
164
+ | Ticker | Trades | Win Rate | Profit Factor | Total Return % |
165
+ |---|---|---|---|---|
166
+ | ACC.NS | 2 | 100.0% | 99.0 | 9.63% |
167
+ | ADANIENT.NS | 2 | 100.0% | 99.0 | 13.81% |
168
+ | ADANIGREEN.NS | 2 | 100.0% | 99.0 | 35.38% |
169
+ | AUBANK.NS | 3 | 100.0% | 99.0 | 5.77% |
170
+ | BANDHANBNK.NS | 2 | 100.0% | 99.0 | 3.57% |
171
+ | BANKINDIA.NS | 2 | 100.0% | 99.0 | 8.01% |
172
+ | BHARATFORG.NS | 2 | 100.0% | 99.0 | 4.12% |
173
+ | BHEL.NS | 3 | 100.0% | 99.0 | 13.98% |
174
+ | CASTROLIND.NS | 2 | 100.0% | 99.0 | 3.34% |
175
+ | COHANCE.NS | 3 | 100.0% | 99.0 | 15.38% |
176
+ | CRAFTSMAN.NS | 3 | 100.0% | 99.0 | 18.91% |
177
+ | ELGIEQUIP.NS | 2 | 100.0% | 99.0 | 5.78% |
178
+ | GODREJPROP.NS | 2 | 100.0% | 99.0 | 15.26% |
179
+ | HINDALCO.NS | 2 | 100.0% | 99.0 | 7.79% |
180
+ | HINDUNILVR.NS | 2 | 100.0% | 99.0 | 2.1% |
181
+ | INFY.NS | 2 | 100.0% | 99.0 | 1.38% |
182
+ | INGERRAND.NS | 2 | 100.0% | 99.0 | 6.25% |
183
+ | INOXWIND.NS | 2 | 100.0% | 99.0 | 10.7% |
184
+ | IOC.NS | 3 | 100.0% | 99.0 | 9.05% |
185
+ | ITI.NS | 2 | 100.0% | 99.0 | 1.85% |
186
+
187
+ ---
188
+ ## Known Limitations
189
+
190
+ 1. **No Open price** β€” entry is next bar's Close (slight look-ahead vs true next-open execution).
191
+ 2. **Survivorship bias** β€” universe is today's top-N NSE stocks by market cap; delisted stocks excluded.
192
+ 3. **Single position** β€” one trade at a time per stock; no portfolio-level correlation management.
193
+ 4. **Limited data** β€” ~500 trading days per stock means limited statistical confidence.
194
+ 5. **EMA200 warm-up** β€” strategies with EMA200 filter skip stocks with < 200 bars.
195
+ 6. **No gap risk** β€” overnight gaps from corporate events are not modelled separately.
196
+
197
+ ---
198
+ ## Next Steps
199
+
200
+ 1. Forward-test surviving strategies on paper trades via Flask watchlist UI.
201
+ 2. Wire V8_TRIPLE_RSI_5D into `trial_run.py` as a new confirmed S-signal.
202
+ 3. Extend data to 5+ years for higher statistical confidence on low-frequency strategies.
203
+ 4. Add VIX<18 filter (Mode B) β€” backtested 71% win rate when VIX below 18.
204
+
205
+ ---
206
+
207
+ > *Educational only β€” not financial advice. Backtested/paper analysis only.*