← Chat Archive

Share:
Hermes session 20260428_230103_0f40ea
2026-04-28 17:33:23 13 messages hermes-20260428_2301...
USER (hermes, glm-5.1)
Read the unified strategy source code at /home/ubuntu/bots/Claude_bot/unified_strategy.py and extract the full entry/exit logic. I need to understand: 1. What SMMA crossover conditions trigger an entry (BUY/SELL)? 2. What RSI gap filter conditions are applied? 3. What are the exit conditions (SL, RSI exit, SMMA crossover exit, EOD square-off)? 4. What is the stop-loss / risk management logic? 5. How does MANUAL_EXIT flag work? 6. What lot size / quantity is used per symbol? 7. What are the exact symbol names and exchanges? Also read /home/ubuntu/bots/Claude_bot/config.py to understand: - Broker config and symbol mappings - Strategy parameters (SMMA period, RSI periods, etc.) Output a clear summary of all the entry/exit rules and parameters.
2026-04-28 17:33:23
ASSISTANT (hermes, glm-5.1)
2026-04-28 17:33:23
TOOL (hermes, glm-5.1)
{"content": " 1|#!/usr/bin/env python3\n 2|\"\"\"\n 3|╔═══════════════════════════════════════════════════════════════════════════════╗\n 4|║ CLAUDE_BOT — RSI + MONDAY SMMA STRATEGY ║\n 5|║ ═════════════════════════════════════════ ║\n 6|║ Strategy: SMMA(2) on 5-min candles vs fixed weekly SMMA + RSI gap filter ║\n 7|║ ║\n 8|║ ENTRY (dual trigger — either fires the trade): ║\n 9|║ • Trigger A: SMMA2(5-min) crosses weekly SMMA + RSI gap > 3 → BUY CALL/PUT ║\n 10|║ • Trigger B: RSI crosses direction + SMMA2 already on same side + gap > 3 ║\n 11|║ (handles case where SMMA2 crossed first with stale RSI, or RSI leads) ║\n 12|║ ║\n 13|║ EXIT: ║\n 14|║ • SMMA2 crosses back (priority) → exit, reentry threshold resets to 3 ║\n 15|║ • RSI gap ≤ 3 → exit, reentry threshold set to 4 (rsi_exit_pending) ║\n 16|║ ║\n 17|║ RE-ENTRY after RSI-gap exit: SMMA2 same side + gap > 4 at 15-min close ║\n 18|║ MANUAL exit detected: requires fresh SMMA2 crossover (gap > 3) ║\n 19|║ ║\n 20|║ Timing: SMMA2 on 5-min candle closes | RSI(15m) refresh every 15min ║\n 21|║ Friday 3:28 PM → close all positions ║\n 22|║ All orders: LIMIT + NRML only (MARKET/MIS not allowed on NFO) ║\n 23|╚═══════════════════════════════════════════════════════════════════════════════╝\n 24|\"\"\"\n 25|\n 26|# ─── Memory shim (MUST be first for VPS) ───\n 27|import os\n 28|os.environ['NUMBA_DISABLE_JIT'] = '1'\n 29|os.environ['NUMBA_CACHE_DIR'] = '/tmp/numba_cache'\n 30|\n 31|import datetime\n 32|import time\n 33|import threading\n 34|import json\n 35|import sys\n 36|import logging\n 37|import pathlib\n 38|\n 39|from openalgo import api\n 40|\n 41|# Our modules\n 42|from config import (\n 43| BROKERS, PROFILES, TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID,\n 44| TELEGRAM_HEARTBEAT_INTERVAL, TRADING_START_TIME, TRADING_END_TIME,\n 45| FRIDAY_SQUAREOFF_TIME, POLL_INTERVAL, RECONCILE_INTERVAL,\n 46| ORDER_VERIFY_RETRIES, ORDER_VERIFY_DELAY, WARMUP_DAYS,\n 47|)\n 48|from telegram_bot import TelegramBot\n 49|\n 50|# ═══════════════════════════════════════════════════════════════════════════════\n 51|# 📝 LOGGING\n 52|# ═══════════════════════════════════════════════════════════════════════════════\n 53|_script_dir = pathlib.Path(__file__).resol ... [27511 chars total, truncated]
2026-04-28 17:33:23
TOOL (hermes, glm-5.1)
{"content": " 1|\"\"\"\r\n 2|╔═══════════════════════════════════════════════════════════════════════════════╗\r\n 3|║ CLAUDE_BOT CONFIGURATION ║\r\n 4|║ ════════════════════════ ║\r\n 5|║ Monday SMMA Strategy — All settings in one place. ║\r\n 6|╚═══════════════════════════════════════════════════════════════════════════════╝\r\n 7|\"\"\"\r\n 8|import datetime\r\n 9|\r\n 10|# ═══════════════════════════════════════════════════════════════════════════════\r\n 11|# 📱 TELEGRAM SETTINGS\r\n 12|# ═══════════════════════════════════════════════════════════════════════════════\r\n 13|TELEGRAM_BOT_TOKEN=\"847022...cpAE\"\r\n 14|TELEGRAM_CHAT_ID = \"7894928895\"\r\n 15|TELEGRAM_HEARTBEAT_INTERVAL = 300 # seconds (5 minutes)\r\n 16|\r\n 17|# ═══════════════════════════════════════════════════════════════════════════════\r\n 18|# 🏦 BROKER CONFIGURATIONS\r\n 19|# ═══════════════════════════════════════════════════════════════════════════════\r\n 20|BROKERS = {\r\n 21| \"SHOONYA\": {\r\n 22| \"api_key\": \"8a5a9e...9b07\",\r\n 23| \"host\": \"https://shoonya.openalgo.theworkpc.com\",\r\n 24| },\r\n 25| \"FLATTRADE\": {\r\n 26| \"api_key\": \"bace7f...7b62\",\r\n 27| \"host\": \"https://flattrade.openalgo.theworkpc.com\",\r\n 28| },\r\n 29|}\r\n 30|\r\n 31|# ═══════════════════════════════════════════════════════════════════════════════\r\n 32|# 📊 SMMA MONDAY PROFILES\r\n 33|# ═══════════════════════════════════════════════════════════════════════════════\r\n 34|# Each profile = one symbol on one broker.\r\n 35|# Strategy: Monday SMMA — SMMA(2) locked on Monday 9:16 AM, Renko crossover.\r\n 36|# All profiles run concurrently (one thread per profile).\r\n 37|\r\n 38|PROFILES = [\r\n 39| # ──── Flattrade Profiles ────\r\n 40| {\r\n 41| \"name\": \"DLF_SMMA\",\r\n 42| \"broker\": \"FLATTRADE\",\r\n 43| \"symbol_fut\": \"DLF28APR26FUT\",\r\n 44| \"symbol_underlying\": \"DLF\",\r\n 45| \"expiry_date\": \"28APR26\",\r\n 46| \"exchange\": \"NFO\",\r\n 47| \"strategy_tag\": \"claude_dlf_smma\",\r\n 48| \"strategy_type\": \"RSI_SMMA\",\r\n 49|\r\n 50| # SMMA\r\n 51| \"smma_period\": 2,\r\n 52|\r\n 53| # Options\r\n 54| \"strike_step\": 10,\r\n 55| \"itm_offset\": 1, # 1 ITM\r\n 56| \"lot_size\": 825,\r\n 57| \"max_lots\": 1,\r\n 58| \"product_type\": \"NRML\",\r\n 59|\r\n 60| # Limits\r\n 61| \"max_trades_per_day\": 10,\r\n 62| },\r\n 63| {\r\n 64| \ ... [7008 chars total, truncated]
2026-04-28 17:33:23
ASSISTANT (hermes, glm-5.1)
2026-04-28 17:33:23
TOOL (hermes, glm-5.1)
{"content": " 501|\n 502| def verify_order_filled(self, symbol, expected_qty, action):\n 503| for attempt in range(ORDER_VERIFY_RETRIES):\n 504| time.sleep(ORDER_VERIFY_DELAY)\n 505| positions = self.get_broker_positions()\n 506| if positions is None:\n 507| continue\n 508| actual_qty = positions.get(symbol, 0)\n 509| if action == \"BUY\" and actual_qty >= expected_qty:\n 510| return True\n 511| if action == \"SELL\" and actual_qty == 0:\n 512| return True\n 513| self.log.info(f\"Verify attempt {attempt+1}/{ORDER_VERIFY_RETRIES}: got qty={actual_qty}\")\n 514| return False\n 515|\n 516| # ─────────────────────────────────────────\n 517| # RECONCILIATION\n 518| # ─────────────────────────────────────────\n 519|\n 520| def reconcile(self):\n 521| \"\"\"Reconcile bot state with broker.\"\"\"\n 522| positions = self.get_broker_positions()\n 523| if positions is None:\n 524| return\n 525|\n 526| my_sym = self.state[\"current_symbol\"]\n 527|\n 528| if my_sym:\n 529| actual_qty = positions.get(my_sym, 0)\n 530| if actual_qty == 0:\n 531| self.log.warning(f\"MISMATCH: Bot has {my_sym}, broker has NONE → resetting (manual exit detected)\")\n 532| self.telegram.alert(\n 533| f\"🚨 *{self.name}*: Position mismatch! `{my_sym}` not found — manual exit detected. Resetting.\"\n 534| )\n 535| self.state[\"current_symbol\"] = None\n 536| self.state[\"current_state\"] = self.STATE_WAITING\n 537| self.state[\"option_entry_price\"] = 0.0\n 538| self.manual_exit_detected = True\n 539| self.smma_crossover_pending = False\n 540| self.smma_crossover_pending_side = None\n 541| self.emergency_covered = False\n 542| self.emergency_cover_symbol = None\n 543| self.emergency_alert_time = None\n 544| self.save_persistent_state()\n 545| else:\n 546| self.log.info(f\"VERIFIED: {my_sym} qty={actual_qty}\")\n 547| else:\n 548| unexpected = {sym: qty for sym, qty in positions.items() if qty != 0}\n 549| if unexpected:\n 550| for sym, qty in unexpected.items():\n 551| if self.emergency_covered and sym == self.emergency_cover_symbol:\n 552| self.log.info(f\"NOTE: Emergency cover position {sym} qty={qty} — awaiting manual close\")\n 553| else:\n 554| self.log.warning(f\"UNEXPECTED position {sym} qty={qty} — not tracked by bot!\")\n 555| self.t ... [26813 chars total, truncated]
2026-04-28 17:33:23
ASSISTANT (hermes, glm-5.1)
2026-04-28 17:33:23
TOOL (hermes, glm-5.1)
{"content": " 1001| start_date = end_date - datetime.timedelta(days=WARMUP_DAYS + 7) # +7 to cover weekends\n 1002| hist = self.client.history(\n 1003| symbol=self.profile[\"symbol_fut\"],\n 1004| exchange=self.profile[\"exchange\"],\n 1005| interval=\"15m\",\n 1006| start_date=start_date.strftime(\"%Y-%m-%d\"),\n 1007| end_date=end_date.strftime(\"%Y-%m-%d\"),\n 1008| )\n 1009|\n 1010| def _parse_ts_open(h):\n 1011| \"\"\"Parse response into list of (timestamp, open_price) tuples.\"\"\"\n 1012| rows = []\n 1013| if hasattr(h, 'iterrows'):\n 1014| for idx, row in h.iterrows():\n 1015| try:\n 1016| ts = idx.timestamp() if hasattr(idx, 'timestamp') else float(idx)\n 1017| except Exception:\n 1018| ts = 0\n 1019| rows.append((ts, float(row.get(\"open\", 0))))\n 1020| elif isinstance(h, dict) and \"data\" in h:\n 1021| raw = h[\"data\"]\n 1022| if isinstance(raw, list):\n 1023| for c in raw:\n 1024| if isinstance(c, list) and len(c) >= 2:\n 1025| rows.append((float(c[0]), float(c[1])))\n 1026| elif isinstance(c, dict):\n 1027| rows.append((\n 1028| float(c.get(\"timestamp\", c.get(\"time\", 0))),\n 1029| float(c.get(\"open\", 0)),\n 1030| ))\n 1031| elif isinstance(raw, dict) and \"candles\" in raw:\n 1032| for c in raw[\"candles\"]:\n 1033| if isinstance(c, list) and len(c) >= 2:\n 1034| rows.append((float(c[0]), float(c[1])))\n 1035| elif isinstance(h, dict) and \"candles\" in h:\n 1036| for c in h[\"candles\"]:\n 1037| if isinstance(c, list) and len(c) >= 2:\n 1038| rows.append((float(c[0]), float(c[1])))\n 1039| elif isinstance(c, dict):\n 1040| rows.append((\n 1041| float(c.get(\"timestamp\", c.get(\"time\", 0))),\n 1042| float(c.get(\"open\", 0)),\n 1043| ))\n 1044| elif isinstance(h, list):\n 1045| for c in h:\n 1046| if isinstance(c, dict):\n 1047| rows.append((\n 1048| float(c.get(\"timestamp\", c.get(\"time\", 0))),\n 1049| float(c.get(\"open\" ... [28300 chars total, truncated]
2026-04-28 17:33:23
ASSISTANT (hermes, glm-5.1)
2026-04-28 17:33:23
TOOL (hermes, glm-5.1)
{"content": " 1501| # rsi_exit_futures_price kept — updated on next RSI gap exit if it fires\n 1502| self.save_persistent_state()\n 1503|\n 1504| # ── Phase 3: Trigger B — RSI direction crossover → fresh entry ───────\n 1505| new_rsi_state = \"ABOVE\" if self.current_rsi20 > self.current_rsi120 else \"BELOW\"\n 1506| old_rsi_state = self.prev_rsi_state\n 1507| rsi_just_crossed = (old_rsi_state is not None and new_rsi_state != old_rsi_state)\n 1508| self.prev_rsi_state = new_rsi_state\n 1509| if rsi_just_crossed:\n 1510| self.save_persistent_state()\n 1511|\n 1512| if (rsi_just_crossed\n 1513| and self.state[\"current_state\"] == self.STATE_WAITING\n 1514| and not self.manual_exit_detected\n 1515| and self.monday_smma is not None\n 1516| and self.smma2_value is not None):\n 1517| smma2 = self.smma2_value\n 1518| current_smma_side = \"ABOVE\" if smma2 > self.monday_smma else \"BELOW\"\n 1519| gap, gap_ok = self._rsi_directional_gap(new_rsi_state, RSI_ENTRY_GAP)\n 1520| self.log.info(\n 1521| f\"RSI CROSSOVER {old_rsi_state}→{new_rsi_state} | \"\n 1522| f\"SMMA2_side={current_smma_side} | gap={gap:.1f} > {RSI_ENTRY_GAP}: {gap_ok}\"\n 1523| )\n 1524| if current_smma_side == new_rsi_state and gap_ok:\n 1525| side = \"BUY_CALL\" if new_rsi_state == \"ABOVE\" else \"BUY_PUT\"\n 1526| self.log.info(f\"Trigger B: RSI crossover + SMMA2 agrees ({current_smma_side}) → {side}\")\n 1527| self.smma_crossover_pending = False\n 1528| self.smma_crossover_pending_side = None\n 1529| # Fresh entry via Trigger B — reset RSI re-entry counter\n 1530| self.rsi_reentry_count = 0\n 1531| self.rsi_exit_pending = False\n 1532| self.rsi_exit_futures_price = None\n 1533| self.rsi_exit_direction = None\n 1534| self.enter_position(side, ltp)\n 1535| return\n 1536|\n 1537| # ── Phase 4: Pending SMMA2 crossover — wait for RSI gap ──────────────\n 1538| if not self.smma_crossover_pending or self.smma_crossover_pending_side is None:\n 1539| return\n 1540|\n 1541| pending_side = self.smma_crossover_pending_side\n 1542| smma2 = self.smma2_value if self.smma2_value is not None else 0\n 1543| current_smma_side = \"ABOVE\" if smma2 > (self.monday_smma or 0) else \"BELOW\"\n 1544|\n 1545| # If SMMA2 has since flipped, cancel pending\n 1546| if current_smma_side != pending_side:\n 1547| self.smma_crossover_pending = False\n 1548| self.smma_crossover_pending_side = None\n 1549| self ... [28642 chars total, truncated]
2026-04-28 17:33:23
ASSISTANT (hermes, glm-5.1)
2026-04-28 17:33:23
TOOL (hermes, glm-5.1)
{"content": " 2001| and self.current_rsi20 is not None\n 2002| and self.current_rsi120 is not None):\n 2003| smma2_val = self.smma2_value if self.smma2_value else ltp\n 2004| smma_side = \"ABOVE\" if smma2_val > self.monday_smma else \"BELOW\"\n 2005| rsi_gap_call = (self.current_rsi20 - self.current_rsi120)\n 2006| rsi_gap_put = (self.current_rsi120 - self.current_rsi20)\n 2007| both_bullish = (smma_side == \"ABOVE\" and rsi_gap_call > RSI_ENTRY_GAP)\n 2008| both_bearish = (smma_side == \"BELOW\" and rsi_gap_put > RSI_ENTRY_GAP)\n 2009| self.log.info(\n 2010| f\"STARTUP (Mon/late-RSI): LTP={ltp:.2f} SMMA={self.monday_smma:.2f} \"\n 2011| f\"smma_side={smma_side} gap_call={rsi_gap_call:.1f} gap_put={rsi_gap_put:.1f}\"\n 2012| )\n 2013| if both_bullish and self.state[\"current_state\"] == self.STATE_WAITING:\n 2014| self.enter_position(\"BUY_CALL\", ltp)\n 2015| elif both_bearish and self.state[\"current_state\"] == self.STATE_WAITING:\n 2016| self.enter_position(\"BUY_PUT\", ltp)\n 2017| else:\n 2018| self.log.info(f\"STARTUP (Mon/late-RSI): Conditions not aligned — waiting\")\n 2019| self.monday_alignment_done = True\n 2020| self.save_persistent_state()\n 2021|\n 2022| last_candle_fetch = now\n 2023|\n 2024| # Heartbeat log\n 2025| rsi20_str = f\"{self.current_rsi20:.1f}\" if self.current_rsi20 else \"--\"\n 2026| rsi120_str = f\"{self.current_rsi120:.1f}\" if self.current_rsi120 else \"--\"\n 2027| smma_confirmed = (self.smma_week_number == now.isocalendar()[1])\n 2028| smma_str = (f\"{self.monday_smma:.2f}⚠\" if self.monday_smma and not smma_confirmed\n 2029| else f\"{self.monday_smma:.2f}\" if self.monday_smma\n 2030| else \"--\")\n 2031| smma2_str = f\"{self.smma2_value:.3f}\" if self.smma2_value else \"--\"\n 2032| pos = self.state[\"current_symbol\"] or \"NONE\"\n 2033| smma2_side = (\n 2034| \"↑\" if (self.smma2_value and self.monday_smma and self.smma2_value > self.monday_smma)\n 2035| else \"↓\" if (self.smma2_value and self.monday_smma)\n 2036| else \"?\"\n 2037| )\n 2038| ... [15447 chars total, truncated]
2026-04-28 17:33:23
ASSISTANT (hermes, glm-5.1)
Here is the complete summary of the entry/exit logic and parameters extracted from the source code: --- ## STRATEGY OVERVIEW **Name:** RSI + Monday SMMA Strategy (v4) **Symbol:** Trades options (CE/PE) on NSE futures underlyings **Order type:** LIMIT orders only, NRML product type, NFO exchange --- ## 1. SMMA CROSSOVER ENTRY CONDITIONS There are **two independent triggers** (either can fire a trade): **Trigger A — SMMA2 Crossover (checked on 5-min candle close):** - SMMA(2) is calculated on 5-min futures candle closes (rolling Wilder-style smoothing) - The "line in stone" is the **Monday SMMA(2)** calculated from daily OPEN prices, locked every Monday at 9:16 AM for the entire week - A **crossover** is detected when SMMA(2) on 5-min crosses from BELOW to ABOVE the Monday SMMA (bullish), or ABOVE to BELOW (bearish) - If crossover occurs AND RSI directional gap > 3 → immediate BUY_CALL (above) or BUY_PUT (below) - If crossover occurs but RSI gap <= 3 AND RSI is already in the same direction → sets `smma_crossover_pending=True`, waits for RSI gap to widen (checked on both 5-min and 15-min cycles) - If crossover occurs but RSI gap <= 3 AND RSI is NOT in same direction → no pending set, entry is blocked **Trigger B — RSI Direction Crossover (checked on 15-min candle close):** - When RSI20(closes of LOW prices) crosses RSI120(closes of HIGH prices) from one side to the other - AND SMMA(2) is already on the **same side** as the new RSI direction - AND RSI directional gap > 3 - → BUY_CALL (if ABOVE) or BUY_PUT (if BELOW) **Monday Startup Alignment:** - On Monday at startup, if both SMMA2 and RSI are already aligned (SMMA2 side matches, gap > 3), the bot auto-enters without waiting for a fresh crossover - If holding the wrong direction (e.g. bearish but now bullish aligned), it closes and reverses --- ## 2. RSI GAP FILTER CONDITIONS **RSI Calculation:** - RSI(20) computed on 15-min candle LOW prices (fast momentum) - RSI(120) computed on 15-min candle HIGH prices (slow trend) - Both use Wilder smoothing (exponential) **Directional Gap:** - For ABOVE (bullish): gap = RSI20 - RSI120 - For BELOW (bearish): gap = RSI120 - RSI20 **Thresholds:** - **Entry (fresh):** gap must be > **3** (`RSI_ENTRY_GAP = 3`) - **RSI gap exit:** gap drops to <= 3 (see below) - **RSI re-entry after RSI exit:** gap must be > **4** (stricter) - **SL re-entry:** gap must be > **3** (same as entry) --- ## 3. EXIT CONDITIONS **A. SMMA2 Cross-Back Exit (highest priority when in position):** - Checked on every 5-min candle close - If SMMA(2) crosses to the **wrong side** of Monday SMMA while in position (e.g., holding BULLISH but SMMA2 drops below Monday SMMA) → exit immediately - On exit: clears `manual_exit_detected`, clears `rsi_exit_pending`, resets `rsi_reentry_count` is NOT reset (stays as is) - Re-entry after this exit requires a **fresh SMMA2 crossover** (gap > 3) **B. RSI Gap Exit:** - Checked on every 15-min candle close while in position - If directional RSI gap drops to <= 3 → exit - Sets `rsi_exit_pending=True`, records `rsi_exit_futures_price` (futures LTP at exit time) and direction - Re-entry threshold is raised to gap > 4 (see re-entry below) - Max 2 re-entries per original SMMA2 crossover entry **C. Stop-Loss Exit:** - Checked **every poll cycle** (60 sec) while in position - If unrealized P&L < -INR 2200 (`STOP_LOSS_AMOUNT = 2200`) → exit - Sets `sl_exit_pending=True` with direction - SL re-entry fires **at most once** per session (`sl_reentry_used` flag) **D. Friday EOD Square-Off:** - Every Friday at 15:28 (`FRIDAY_SQUAREOFF_TIME = 15:28`), any open position is closed with reason "friday_eod" **E. Manual Telegram Square-Off:** - `/squareoff <name>` or `/squareoff ALL` closes positions immediately - Sets `manual_exit_detected = True` --- ## 4. STOP-LOSS / RISK MANAGEMENT LOGIC - **Stop-loss amount:** INR 2,200 per position (`STOP_LOSS_AMOUNT = 2200`) - Calculated as: `(current_option_LTP - option_entry_price) * quantity` - If P&L drops below -2200, position is exited cleanly - After SL exit, the bot watches for **SL re-entry**: if RSI gap re-expands > 3, SMMA2 still on correct side, and RSI hasn't flipped → re-enter (once per session max) - If RSI flips or SMMA2 crosses wrong side after SL exit, SL re-entry is cancelled - **2-lot cap:** Before entry, bot checks total positions for the underlying. If combined qty >= lot_size * 2, entry is blocked - **Max trades per day:** 10 per profile - **Post-exit cooldown:** Currently set to **0 minutes** (`POST_EXIT_COOLDOWN_MINUTES = 0`), effectively disabled - **Whipsaw threshold:** 7 minutes (`WHIPSAW_THRESHOLD_MINUTES = 7`) — but cooldown is 0, so it has no effect currently - **Emergency cover:** If an exit order fails to confirm, the bot buys an opposite-direction option as a hedge, then sends Telegram alerts for manual resolution --- ## 5. MANUAL_EXIT FLAG - `manual_exit_detected` is set to `True` when the **reconcile()** call discovers the bot thinks it has a position but the broker shows qty=0 (i.e., someone manually closed it) - Also set on Telegram `/squareoff` - When `manual_exit_detected = True`: - **RSI gap re-entry is blocked** (won't auto-re-enter) - **SL re-entry is blocked** - The bot requires a **fresh SMMA2 crossover** (gap > 3) to unlock trading again - When a fresh SMMA2 crossover fires, `manual_exit_detected` is cleared to `False` --- ## 6. LOT SIZE / QUANTITY PER SYMBOL | Profile | lot_size | max_lots | Quantity (lot_size x max_lots) | |---|---|---|---| | DLF_SMMA | 825 | 1 | **825** | | HAL_SMMA | 150 | 1 | **150** | | INFY_SMMA | 400 | 1 | **400** | | INDUSINDBK_SMMA | 700 | 1 | **700** | All profiles use `max_lots = 1`. Combined position cap is 2 * lot_size per underlying. Option strike selection: **1 ITM** (`itm_offset = 1`) for all profiles. --- ## 7. EXACT SYMBOL NAMES AND EXCHANGES | Profile | Broker | Futures Symbol | Underlying | Exchange | Expiry | |---|---|---|---|---|---| | DLF_SMMA | FLATTRADE | DLF28APR26FUT | DLF | NFO | 28APR26 | | HAL_SMMA | FLATTRADE | HAL28APR26FUT | HAL | NFO | 28APR26 | | INFY_SMMA | SHOONYA | INFY28APR26FUT | INFY | NFO | 28APR26 | | INDUSINDBK_SMMA | SHOONYA | INDUSINDBK28APR26FUT | INDUSINDBK | NFO | 28APR26 | Note: HAL_SMMA is **disabled** (`"enabled": False` in config). --- ## RE-ENTRY LOGIC SUMMARY | Exit Type | Re-entry Condition | Re-entry Threshold | Max Re-entries | Additional Checks | |---|---|---|---|---| | SMMA2 cross-back | Needs fresh SMMA2 crossover | gap > 3 | N/A (new sequence) | Resets rsi_reentry_count = 0 | | RSI gap exit | SMMA2 same side + gap widened + better price | gap > 4 | 2 per SMMA2 entry | Futures price must be more favorable than exit price (higher for CALL, lower for PUT) | | Stop-loss exit | SMMA2 same side + gap > 3 | gap > 3 | 1 per session | RSI must not have flipped | | Manual exit | Needs fresh SMMA2 crossover | gap > 3 | N/A | Clears manual_exit_detected flag | --- ## KEY STRATEGY PARAMETERS (constants) | Parameter | Value | Description | |---|---|---| | `SMMA2_PERIOD` | 2 | SMMA period on 5-min closes | | `RSI_ENTRY_GAP` | 3 | Min RSI directional gap for entry | | RSI exit gap | 3 (implicit) | Exit when gap <= 3 | | RSI re-entry gap | 4 (hardcoded) | Re-entry after RSI gap exit needs gap > 4 | | `STOP_LOSS_AMOUNT` | 2200 | INR stop-loss threshold | | `LIMIT_BUFFER` | 3.0 | INR buffer on LIMIT orders (buy: LTP+3, sell: LTP-3) | | `POLL_INTERVAL` | 60 sec | Main loop polling interval | | `SMMA2_CANDLE_INTERVAL` | 300 sec | 5-min candle interval | | `CANDLE_FETCH_INTERVAL` | 300 sec | How often to fetch new candles | | `CANDLE_DAYS_LOOKBACK` | 20 | Calendar days of history | | `MIN_CANDLES_FOR_RSI` | 122 | Minimum candles needed for RSI(120) calculation | | `WARMUP_DAYS` | 15 | Daily candle lookback for Monday SMMA | | `POST_EXIT_COOLDOWN_MINUTES` | 0 | Currently disabled | | `WHIPSAW_THRESHOLD_MINUTES` | 7 | Reference only (no effect with cooldown=0) | | `TRADING_START_TIME` | 09:16 | Market open | | `TRADING_END_TIME` | 15:30 | Market close | | `FRIDAY_SQUAREOFF_TIME` | 15:28 | Friday forced close | --- ## BROKER CONFIG - **SHOONYA**: OpenAlgo host at `https://shoonya.openalgo.theworkpc.com` - **FLATTRADE**: OpenAlgo host at `https://flattrade.openalgo.theworkpc.com` - Both use API keys defined in config (redacted in this summary)
2026-04-28 17:33:23