Skip to content

feat(sl-hunting): v4d knowledge and crash-durable recovery - #115

Merged
DoRmAmMu1997 merged 4 commits into
chore/docs-and-tests-restructurefrom
feat/sl-hunting-knowledge-v4d
Aug 10, 2026
Merged

feat(sl-hunting): v4d knowledge and crash-durable recovery#115
DoRmAmMu1997 merged 4 commits into
chore/docs-and-tests-restructurefrom
feat/sl-hunting-knowledge-v4d

Conversation

@DoRmAmMu1997

@DoRmAmMu1997 DoRmAmMu1997 commented Aug 10, 2026

Copy link
Copy Markdown
Owner

What this PR now delivers

This PR combines the SL Hunting v4d knowledge update from the 10 Aug 2026 Intraday Hunter session with the crash-recovery work that the same trading day proved necessary.

SL Hunting v4d knowledge

Source: Intraday Hunter live session, 10 Aug 2026 (flhHzz87Of0, around 10:50).

  • Treat opening type as a participation/inventory read, not merely a momentum label.
  • Book just before a crowded round-number target rather than assuming the exact level will fill.
  • Include entry quality as a fourth target-sizing input.
  • Pre-commit the adverse move the thesis can tolerate before the thesis is invalid.
  • Clarify that the flat-open fade is the default, while the already-documented multi-day-down Variant B remains an explicit seller-hunt long exception.
  • Preserve the 11 Aug premarket context and existing prompt-size/schema guards.

Crash-durable session recovery

The 10 Aug machine hang exposed a separate runtime defect: the killed process had realized -?5,195.25, but its replacement process started with a fresh zero ledger and later produced the only EOD summary. This PR now prevents that class of loss-accounting reset.

  • Atomically persist trade events, realized-P&L rollups, and periodic open-position snapshots.
  • Archive the exact previous state file before a replacement run writes anything.
  • Always restore compatible same-day realized P&L and trade counts into matching workers, even when open-position resume is disabled, so a restart cannot reset a daily max-loss budget.
  • Keep open-position resume opt-in, paper-only, same-day, unclean-session-only, and restricted to a fully validated single-leg contract with valid direction, option right, quantity/lot geometry, entry, stop, target, expiry, segment, and identifiers.
  • Mark failed worker snapshots explicitly as unsafe so stale open-position data cannot become a ghost resume.
  • Preserve the last durable state for forensics if a fresh snapshot fails.
  • Record clean_shutdown separately from results_published; an orderly flat shutdown is not claimed as exported unless a real Google Sheet cell batch succeeds.
  • Keep local fsync durability explicit and warn if a state write takes at least 250 ms.
  • Gitignore timestamped recovery archives because they contain operational position and P&L data.

Safety boundaries

  • Live broker exposure is never reconstructed from the JSON file; the broker account and execution ledger remain authoritative.
  • Resume defaults to off and can only reconstruct eligible paper single-leg positions.
  • Corrupt, stale, incomplete, live, unsupported, or geometrically invalid position records fail closed and leave the worker flat.
  • Persistence failures are isolated from the trading loop and logged; no broker or model call was made during verification.

Review trail

The initial findings and rationale are recorded in this review comment. Commit c16e142 implements and tests the resolution.

Verification

  • python -m unittest Tests.test_nifty_multi_strategy_master ? 508 passed, 52 skipped
  • python -m unittest Tests.test_market_data_health ? 26 passed
  • python -m pytest "Tests/Signal Generators" "Tests/Dependencies" "Tests/Data Extractors" -q ? 1126 passed
  • Focused session-state suite ? 35 passed
  • Branch coverage ? 70.0%, all safety/broker module thresholds passed
  • Ruff, mypy (54 source files), compileall, exact CI Bandit, pre-commit, repository policy, and all four pinned dependency audits ? passed

Attribution

SL Hunting source research and original v4d prose were generated with Claude Code. The crash-recovery review, hardening, tests, and PR enhancement were completed with Codex; the implementation commit includes the Codex co-author trailer.

@DoRmAmMu1997
DoRmAmMu1997 force-pushed the feat/sl-hunting-knowledge-v4d branch from 8f14cdc to 49750be Compare August 10, 2026 14:07
@DoRmAmMu1997
DoRmAmMu1997 changed the base branch from main to chore/docs-and-tests-restructure August 10, 2026 14:07
Source: Intraday Hunter live session, 10 Aug 2026 (flhHzz87Of0, 10:50). A large
WIN on the put side from an ALMOST FLAT open, target deliberately enlarged and
then booked short of the round number.

THE OPENING TYPE IS A PARTICIPATION READING, NOT A STRENGTH READING. The clearest
new idea, and it inverts how a flat open usually gets read:

  "This market could only have gone up if we had got a direct gap-up -- that
   would have made the structure different. But we got flat... opening flat, the
   chances of it going up are LOW."
  "In a gap-up the market gives nobody a chance, it just runs."

A gap RUNS because it denied everyone entry. A flat open GRANTS entry, the crowd
positions in the first minutes, and that positioning is the inventory that caps
the move. GAP -> nobody positioned -> nothing overhead -> follow it. FLAT ->
everybody positioned -> inventory overhead -> fade the attempt rather than chase.
Added to OPENING_DRIVE beside the gap-up long branch, because it is that branch
stated from the other end.

Three more:

- BOOK BEFORE THE ROUND NUMBER, NOT AT IT, WHEN ALL THREE INDICES ARE RUNNING.
  "It has the courage to go to the 500. But we should get out a little BEFORE,
  because there is continuous momentum in all three indices, so other people will
  get greedy too." A strong three-index move recruits the late crowd, and their
  take-profits plus the operator's reversal both sit at the round figure. Flip
  side of v4c's ROUND NUMBERS AMPLIFY RECRUITMENT.
- YOUR ENTRY PRICE IS THE FOURTH TARGET INPUT, and the first about YOU rather
  than the crowd. v4a sized by recency, v4b by averaging, v4c by crowd size --
  this is the quality of your fill. "We got the chance to sell from ABOVE... if
  the market had started falling directly we might have had to take a coverage
  target." Practical form: a poor or late fill SHRINKS the target rather than
  being compensated for by holding longer.
- PRE-COMMIT THE ADVERSE MOVE YOUR THESIS TOLERATES. "If it breaks out we will
  look for 60-70 points. The market might go further, to 160 -- and that could be
  wrong." Distinct from the stop: this is how much movement against you is still
  CONSISTENT with the read, and it gives v4a's rejection-is-noise rule a
  measurable boundary rather than a feeling.

A second test asserts all FOUR target-sizing inputs coexist. Each arrived in a
different version and they pull in different directions, so a later edit could
drop one and quietly change how every target is sized without failing anything.

ALSO RECORDED IN THE DOC -- a data-integrity problem from today's session, not a
knowledge item. The runner was restarted four times (08:18, 08:21, 09:13, 10:37)
and the 09:13 instance was killed WITHOUT a clean shutdown: no Result summary
exists anywhere between 09:13 and 10:37. SL Hunting's real day lived in that
instance -- three baskets, net -Rs.5,195.25 -- while the only summary for the day
is 11:00:01 from the new instance reading Trades=0 | RealizedPnL=0.00.

That is a DIFFERENT failure from 2026-08-03. There a restart logged Trades=0 over
real figures and the trades-count guard was added to stop it. Here the figures
never got a summary at all, so the guard has nothing to prefer: every SL Hunting
summary for the day reads zero and the Sheet will record 0.00 against a real
-Rs.5,195.25. The guard stops the wrong number winning; it cannot invent one that
was never logged.

All prose; no executable behaviour changes. Prompt grows 92,678 -> 96,319 chars
against a 120,000 cap.

Gates: 487 unittest, 1091 pytest (171 SL Hunting), ruff, mypy 53 files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@DoRmAmMu1997
DoRmAmMu1997 force-pushed the feat/sl-hunting-knowledge-v4d branch from 49750be to 832ae91 Compare August 10, 2026 15:43
DoRmAmMu1997 and others added 2 commits August 11, 2026 00:19
…sion

Per-strategy results only reach the Google Sheet at the END of a clean
session. On 2026-08-10 the machine hung mid-session: the 09:13 instance
died without writing a summary, so the morning's realized P&L (-10,661.75
across nine strategies) had to be rebuilt by hand from the log, and the
thirteen positions still open had to be marked out separately from real
Dhan candles (-4,735.25). The trades-count guard cannot help there -- it
stops a Trades=0 summary OVERWRITING real figures, but a crash writes no
summary at all.

Dependencies/session_state.py keeps an atomically-written JSON file
current DURING the session:

- every trade event is written immediately, hooked at the runner's single
  publish_trade_event choke point (25 call sites, already exception-
  isolated) rather than at the seven per-family realized_pnl sites, so a
  new worker family is covered automatically;
- open positions are snapshotted every 30s from the supervisor loop with
  entry fill price, stop, target, quantity, contract ids and a
  last_mark_ltp read from the LTP CACHE only (a broker call there would
  stall shutdown supervision);
- clean_shutdown is stamped after results publish, so its absence is the
  crash signal.

Writes are tmp + flush + fsync + os.replace, so a reader or a crash only
ever sees a complete document. Every entry point swallows and logs: a
failing disk degrades reporting, never trading.

Resume is opt-in (SESSION_STATE_RESUME_ENABLED, default false) and
deliberately narrow -- today's date, an unclean shutdown, PAPER, and a
single-leg PaperPosition. Live positions are never restored: the broker
account is the authority there and the runner already reconciles against
it. Resume also carries realized_pnl/completed_trades forward so a
restarted worker inherits the loss it already took rather than getting a
fresh full-size risk budget for the same day.

Gates: master 504 OK, market-data-health 26 OK, pytest 1123 passed,
coverage 71.7% local (floor 68) with session_state.py at 94.6% against
its 90% data-safety budget, ruff/mypy/compileall/bandit clean, check-env
reports zero undocumented keys.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ideo

Source: Intraday Hunter, "Prediction For 11 AUG 2026" (cOvPKZFervw,
uploaded 2026-08-10, 1:55). Transcript pulled from YouTube's transcript
panel -- the signed timedtext URL returned empty, so the UI panel was the
working path this time.

The gap conditional INVERTS overnight, which is the whole content of this
note. 10 Aug wanted sells on a flat open and buys on a gap-up; 11 Aug
wants buys on flat-to-gap-up and sells on a gap-down.

The cause is one event: NIFTY sold, BROKE DOWN, and then turned straight
back up and held above. A failed breakdown leaves sellers turned around
rather than paid, so they are the trapped inventory carried in -- hence
following the market up rather than fading it.

Recorded faithfully rather than smoothed:
- the gap-down branch is its own regime, not the up-case mirrored ("the
  structure can become different, traps can form differently there");
- he allows the trap may still be LOADING -- today may only have spun the
  sellers, with the next gap-down delivering the momentum;
- no stand-aside branch this time, unlike 10 Aug's large-gap-down veto.

It is also a Tuesday EXPIRY, which he flags in his opening sentence; that
gets its own plan line because expiry pinning sharpens v4d's BOOK BEFORE
THE ROUND NUMBER. Levels arrived clean -- no dropped-trailing-zero
artefacts, unlike 4/7/10 Aug.

test_shipped_note_matches_august_11_intraday_hunter_plan replaces the
10 Aug equivalent and asserts each branch's DIRECTION explicitly, because
an inverted plan is exactly what a copy-forward would produce.

Gates: SL Hunting pytest 171 passed, ruff clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@DoRmAmMu1997

Copy link
Copy Markdown
Owner Author

Codex review — crash-state hardening required

I reviewed the current PR head (947a77d) against its stated crash-durability and live-money safety contracts. The knowledge and focused tests are useful, but I found the following issues that should be fixed before merge:

  1. P1 — startup destroys the previous unclean recovery file. SessionStateStore starts with an empty document, then the forced startup snapshot replaces the old file. With resume off (the default), the first restart erases the trade journal and recorded P&L the feature exists to preserve. Even with resume on, the new store discards the old journal after restoring positions.
  2. P1 — same-day realized losses are not reliably restored. _resume_open_positions() returns when no open position is resumable and copies realized_pnl only inside a successful single-leg paper restore. Flat, live, unsupported, or disabled strategies therefore receive a fresh max-loss budget. The more current event-derived recorded_pnl is calculated but never applied.
  3. P1 — clean_shutdown=true does not prove results reached Sheets. Non-EOD shutdowns skip publication, and Sheet failures are non-fatal, but both paths are still marked clean. That makes unpublished P&L ineligible for recovery and vulnerable to the next startup overwrite.
  4. P2 — a failed worker snapshot can preserve a stale open_position. The worker is omitted, while incremental state updates leave its old position untouched; a later resume can invent a ghost paper position.
  5. P2 — resume validation accepts non-functional positions. Direction, symbol, segment, right, expiry, lot size, entry underlying, stop/target and directional geometry are not validated before an active position is created.
  6. P2 — publish_trade_event() is documented as non-blocking but synchronously performs JSON serialization, fsync, and os.replace on the trading worker. A slow filesystem can pause risk management; the durability/latency contract must be made explicit and bounded or moved to a dedicated writer.
  7. P2 — the v4d flat-open rule is phrased categorically, then the same section permits the existing flat-open seller-hunt long. Phrase the first as the default and name the exception so the agent does not nondeterministically prioritize contradictory instructions.
  8. CI — both quality jobs fail Bandit B112 at _position_leg_marks; the existing Ruff suppression does not suppress Bandit.

I reproduced the overwrite independently: an unclean file containing one -₹1,250 exit became an empty trade list with no recorded_pnl after the next store's startup snapshot. Current focused suites pass because they do not cover these lifecycle transitions.

I’m following this review with regression tests and a hardening commit on this PR branch. No broker or model call will be made during verification.

Archive prior session evidence before replacement, restore same-day P&L independently of position resume, validate paper recovery records fail closed, distinguish local shutdown from Sheet publication, and clarify the SL Hunting flat-open exception.

Co-authored-by: Codex <codex@openai.com>
@DoRmAmMu1997 DoRmAmMu1997 changed the title feat(sl-hunting): v4d knowledge from the 10 Aug live session feat(sl-hunting): v4d knowledge and crash-durable recovery Aug 10, 2026
@DoRmAmMu1997

Copy link
Copy Markdown
Owner Author

Implemented the follow-up hardening in c16e142 and pushed it directly onto this PR.

Resolution against the eight review findings:

  1. Prior crash evidence overwritten ? fixed by atomically rotating the exact old file to a timestamped *.recovery.json archive before creating the replacement session.
  2. Realized loss reset after restart ? fixed by restoring same-day event-derived P&L/trade counts into matching workers independently of the open-position resume switch.
  3. Clean shutdown conflated with Sheet publication ? fixed with separate clean_shutdown and results_published facts; publication is true only after a real Sheet cell batch succeeds.
  4. Stale snapshot could become a ghost resume ? fixed by persisting an explicit invalid-snapshot marker, retaining the old record for forensics, and making it ineligible for resume.
  5. Weak position validation ? fixed with fail-closed validation of direction/right pairing, symbol, quantity and lot geometry, entry/stop/target geometry, option identifiers, segment, strike, expiry, and price fields.
  6. fsync behavior contradicted the non-blocking contract ? corrected the contract/documentation and added a warning when a durable write takes at least 250 ms. Telegram remains non-blocking; local crash durability is intentionally synchronous.
  7. Flat-open prompt ambiguity ? clarified the ordinary flat-open fade as the default and explicitly preserved the separately scoped multi-day-down Variant B seller-hunt long exception.
  8. Bandit CI failure ? replaced the silent reporting exception with a DEBUG breadcrumb; the exact CI Bandit command now passes.

Additional regression coverage proves archive rollover, same-day bookkeeping carry, clean-vs-published state, invalid snapshot refusal, complete paper-position validation, Google Sheet result semantics, and both flat/live bookkeeping restoration.

Local publication evidence: 508 master tests + 52 skipped, 26 market-health tests, 1126 mirrored pytest tests, 35 focused session-state tests, 70.0% branch coverage with all safety thresholds green, Ruff, mypy, compileall, Bandit, pre-commit, policy checks, and four pinned dependency audits all passed. No broker or model call was made.

@DoRmAmMu1997

Copy link
Copy Markdown
Owner Author

Hosted verification is now complete on commit c16e142:

  • Python 3.12 quality checks ? ? passed
  • Python 3.13 quality checks ? ? passed
  • Python 3.12 broker dependency validation ? ? passed
  • Python 3.13 broker dependency validation ? ? passed

Workflow run: https://github.com/DoRmAmMu1997/My-Algo-Trading-Code/actions/runs/31423992393

@DoRmAmMu1997
DoRmAmMu1997 merged commit 78ee55d into main Aug 10, 2026
4 checks passed
@DoRmAmMu1997
DoRmAmMu1997 deleted the feat/sl-hunting-knowledge-v4d branch August 10, 2026 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant