diff --git a/Signal Generators/SL Hunting AI Agent/premarket_note.json b/Signal Generators/SL Hunting AI Agent/premarket_note.json index cf5c272..53871bb 100644 --- a/Signal Generators/SL Hunting AI Agent/premarket_note.json +++ b/Signal Generators/SL Hunting AI Agent/premarket_note.json @@ -1,30 +1,27 @@ { - "for_date": "2026-08-14", - "source": "Intraday Hunter, 'Prediction For 14 AUG 2026' (MhmlrlUEUGI, uploaded 2026-08-13)", - "context": "No decisive crowd anywhere. BankNIFTY made little momentum with buyers and sellers at the SAME price level; Sensex ran both ways. The market held its round number and recovered, so sellers are unlikely to have carried overnight.", + "for_date": "2026-08-17", + "source": "Intraday Hunter, 'Prediction For 17 AUG 2026' (4xfMmQW6x5I, uploaded 2026-08-16)", + "context": "All three indices recovered after sellers were removed or stopped out, leaving buyers as the likely seated crowd. The sell-side plan targets those buyers, but a gap-down can recruit fresh sellers and increase risk.", "plan": [ - "FLAT to GAP-DOWN: identify SELL-side setups. On Sensex the reason is explicit -- target the BUYERS, since the market has sat on support since yesterday and the sellers did not hold.", - "GAP-UP: go WITH the market and identify BUY-side setups. On BankNIFTY 'the buyer becomes safe' there, so there is nothing left to hunt on that side.", - "NOBODY IS DECISIVELY SEATED -- on BankNIFTY 'buyers and sellers would be sitting at the SAME price level', and on Sensex claiming either side is seated 'would be WRONG'. This is the empty-book condition.", - "His mechanism for that condition, worth keeping: 'where the crowd is THIN, that is where the market tries to make momentum.' Thin is not dead -- the move goes where there is least resistance.", - "He PREFERS a gap to a flat open: 'better it is not flat -- either a gap-up or a gap-down.' A flat open 'extracts a small momentum and goes away', producing nothing worth trading.", - "There is little pressure on BankNIFTY's sellers, so the market cannot target them directly. The flat/gap-down branch is therefore a FOLLOW of the drift, not a seller hunt." + "GAP-UP or FLAT: identify confirmed SELL-side setups targeting the buyers left seated after the prior recovery.", + "GAP-DOWN: retain the SELL-side search, but risk is higher because fresh sellers may participate; the gap alone is not confirmation.", + "GAP-DOWN WITH POSITIVE MOMENTUM: a large recovery weakens the short plan. Retain it only if the recovery stays limited and the normal setup confirms." ], "levels": [ { "index": "NIFTY", "resistance": [24440, 24540], - "support": [24275, 24176] + "support": [24300, 24210] }, { "index": "BANKNIFTY", - "resistance": [57890, 58000], - "support": [57500, 57320] + "resistance": [57720, 57890], + "support": [57280, 57154] }, { "index": "SENSEX", - "resistance": [78145, 78500], - "support": [77500, 77200] + "resistance": [78300, 78500], + "support": [77700, 77400] } ] } diff --git a/Signal Generators/SL Hunting AI Agent/sl_hunting_doc.md b/Signal Generators/SL Hunting AI Agent/sl_hunting_doc.md index 063e694..66ce1f8 100644 --- a/Signal Generators/SL Hunting AI Agent/sl_hunting_doc.md +++ b/Signal Generators/SL Hunting AI Agent/sl_hunting_doc.md @@ -3465,3 +3465,109 @@ Test updated: `test_shipped_note_matches_august_14_intraday_hunter_plan` replaces the 13 Aug equivalent and asserts both branch directions plus the thin-crowd mechanism and the gap-over-flat preference, because those two are what a summarising edit would drop first. + +--- + +## Video addendum - the 14 Aug LIVE SESSION (v4h) + +**Source:** Intraday Hunter live session `H7RXIw5xbZk` (14 Aug 2026, 12:18). + +A WIN, and unusually it is a win **held through a full drawdown** rather than one +that went straight to target. That is what makes it useful: every previous +version in this series learned from either a clean win or a clean loss, so the +prompt had no worked example of a correct trade that looked wrong in the middle. + +### The two rules that shipped + +**ENTRY QUALITY AND DIRECTION ARE SEPARATE JUDGEMENTS.** A trade that ends green +does not retroactively make its entry good, and a trade that goes immediately +against you was not necessarily the wrong side. Without this split, the journal +teaches the agent to grade its reads by their P&L, which is exactly the feedback +loop that produces revenge entries after a stopped-out correct call. + +**THE LOSS LIMIT IS A PERMISSION TO WAIT.** This one is the reason the version +exists, and it is also the most dangerous line in the prompt if read alone - +"permission to wait" one careless paraphrase away from "hold losers". It is +bounded on both sides in the prose and both bounds are test-asserted: the limit +licenses patience *toward* the stop, never *past* it, and it forbids cutting +inside it on feel. It explicitly names v4e's `DISCIPLINE IS ASYMMETRIC` as the +rule it refines rather than overrides. + +The one thing allowed to override that patience is elapsed time, so v4g's +time-shrinks-the-target rule was extended rather than left to contradict it: +time does not merely shrink the payoff, it **EXPIRES THE PREMISE**. IH, booking +out: "time has become quite a lot, gradually other people will start +participating." Waiting to the limit is right while the premise holds; elapsed +time can retire the premise before price ever reaches the limit. +`test_v4h_entry_and_direction_and_the_loss_limit_pair_with_their_neighbours` +asserts the reconciliation in both directions. + +### One rule was cut for budget, not for merit + +A third rule - **A SEATED CROWD IS WARNED BEFORE IT IS HUNTED, SO NO WARNING +MEANS NO CROWD** - was written, tested, and then removed to fit the cap. IH: +"if sellers WERE seated, the market would go up to target them - especially to +give a WARNING... because the market kept making no momentum, sellers will not +be seated, so it will not go up to warn." The mechanism is that an early adverse +spike is the market shaking a seated crowd, so its *absence* confirms an empty +book. It is the sharpest new idea in the session and it should be the first +thing restored once a pruning pass frees room. + +### Knowledge changes (v4h, all prose) + +- `RISK`: ENTRY QUALITY AND DIRECTION ARE SEPARATE JUDGEMENTS; THE LOSS LIMIT IS + A PERMISSION TO WAIT. +- `RISK` (extended): TIME SPENT IN THE TRADE ... now also EXPIRES THE PREMISE. +- **Pruned:** v4e's `A SHARP FIRST SLIDE BAITS; A SLOW ONE MEANS IT` - superseded + by v4f's confirmation rule, which covers the same tell with a checkable trigger. +- Prompt size 111,283 -> 112,730 chars. **Assembled 114,021 against a 114,140 + budget - 119 chars of headroom.** The cap is now the binding constraint on this + series: v4i cannot ship anything without pruning first. See below. + +### The budget is now the design constraint + +Worst-case runtime additions (12 lessons x 280 + a 2,500-char note) are already +reserved, so the true ceiling for static prose is 114,140 assembled. At 119 chars +of slack, the append-only rhythm this series has used since v3 is finished. +Before v4i, someone should do a dedicated pruning pass over `OPENING_DRIVE` and +`RISK` - both have accumulated rules that later versions restated with better +triggers - and re-measure. That is a knowledge-quality task and deserves its own +change, not a rushed trim at the end of a version. + +### How our agent traded the same session + +Realized: **-3,854.50** across 47 legs. + +| Strategy | Legs | Realized | +|---|---|---| +| SL Hunting AI | 2 | **+2,866.50** | +| **Total** | **47** | **-3,854.50** | + +**SL Hunting was the best strategy on the board for the second consecutive day**, +cross-checked against its own `Result summary` (+2,866.50, Trades=2). + +| Time | Decision | Reason | +|---|---|---| +| 10:04 | ENTER_LONG | `flush_reversal_hammer_confirmed` | +| 10:07 | EXIT | `double_top_rejection_premise_fade` | +| 10:20 | ENTER_SHORT | `double_top_bearish_engulfing_breakdown` | + +**Agent vs IH.** Both finished on the same side - IH put-side/short, the agent +short from 10:20 - and both booked on a partial rather than a full target. The +agent got there by a different route: it took a long first, released it three +minutes later on a premise fade, and reversed. That reversal is the behaviour +v4f's confirmation rule was written to produce, and it is worth noting that the +10:07 exit was a *premise* exit on a trade that was not yet losing - which is the +disciplined half of the rule v4h now bounds from the other side. + +Two trades is again a small sample, and the basket was negative regardless. The +signal worth keeping is narrower than "the agent is good now": across 12, 13 and +14 Aug, every SL Hunting exit had a **nameable** reason, and the two profitable +days are the two where that was true. + +### Operational note + +The supervisor heartbeat shipped in the session-state work is confirmed working +in production: **65 heartbeat lines** in the 14 Aug log. The 2026-08-12 failure +mode - snapshot writes stopping silently at 12:30 while trading continued to +15:10 - would now be visible within five minutes. diff --git a/Signal Generators/SL Hunting AI Agent/sl_hunting_knowledge.py b/Signal Generators/SL Hunting AI Agent/sl_hunting_knowledge.py index 906d44d..dfeed78 100644 --- a/Signal Generators/SL Hunting AI Agent/sl_hunting_knowledge.py +++ b/Signal Generators/SL Hunting AI Agent/sl_hunting_knowledge.py @@ -565,14 +565,15 @@ v4c's WHEN THE TRAPPED INVENTORY IS SPENT, THE MARKET MANUFACTURES MORE: manufacturing is what the market does over time, but it may not complete inside your holding period, and you cannot bank on being early to it. -- A SHARP FIRST SLIDE BAITS; A SLOW ONE MEANS IT (v4e). IH's read of the opening - move, stated as a prior: "if it had fallen SLOWLY I would even have accepted that - the market might produce a big move. But the selling was SHARP — the market - suddenly offered greed", i.e. an abrupt drop looks engineered to recruit sellers, - whereas a grinding one looks like genuine supply. Treat this as a weak prior and - nothing more: on the very session that produced it, the sharp slide was followed - by continuous selling and the bait read was WRONG. Use it to break a tie between - two otherwise-equal reads, never as the premise of a trade on its own. +- ENTRY QUALITY AND DIRECTION ARE SEPARATE JUDGEMENTS (v4h). IH, entering a fall + he knew might reverse: "if the market turns it could go much higher — then we + would be wrong ACCORDING TO DIRECTION. We would NOT be wrong according to + ENTRY... if it is going to go up anyway, you could enter here, or here, or here + — in all three there would be a loss." + A loss decomposes into two independent errors needing different fixes: a bad + ENTRY means a better price existed and was missed (timing); a bad DIRECTION + means no entry price would have helped (read). Score them separately, and never + let a good entry launder a wrong read, or a wrong read condemn a good entry. - THE CHART DOES NOT REPEAT TWO DAYS RUNNING (v4f). When today's open reproduces yesterday's shape — same flat open, same immediate drop, same indices — that SAMENESS is itself the tell, and it argues AGAINST the continuation everyone @@ -1110,6 +1111,17 @@ Operationally: an exit needs a NAMED, checkable reason — stop, target, the profit rate falling, the premise invalidated, the round number crossed, the time cutoff. "It might turn" is not on that list. +- THE LOSS LIMIT IS A PERMISSION TO WAIT, NOT ONLY A PLACE TO STOP (v4h). Read + this WITH v4e's DISCIPLINE IS ASYMMETRIC, not against it: that rule says cut a + loser mechanically, this one says cut it AT the limit and not before, because + cutting early is its own error. IH, deep in a drawdown that later paid: "in ANY + situation, do NOT cut the trade where you feel your position can still be saved. + If the position has gone wrong but the loss LIMIT is still pending, we wait... + many traders, when the opposite momentum comes, cut the loss BEFORE the limit." + Its two shapes: running after the breakout because surely nothing falls now, and + holding the first adverse leg but running on the SECOND. Same error, different + depths. So the limit is two-sided — it forbids holding past it, AND forbids + cutting inside it on feel. Only the rule below legitimately overrides it. - TIME SPENT IN THE TRADE SHRINKS THE ACHIEVABLE TARGET (v4g). Elapsed time is a cost in its own right, separate from price. A trade that stalls and round-trips does not merely return to where it started — it returns with less of the @@ -1121,6 +1133,13 @@ So when a trade consumes materially more time than the read assumed, SHRINK the target rather than extending the wait — especially on an expiry session, where premium is draining while you wait. + Extended (v4h): time does not merely shrink the payoff, it EXPIRES THE PREMISE. + "With more time the STRUCTURE changes — the seller/buyer situation changes", and + later, booking out: "time has become quite a lot, gradually other people will + start participating." The crowd you entered against is not the crowd still there + an hour on. This is what overrides the loss-limit patience above: waiting to the + limit is right while the premise holds, and elapsed time can retire the premise + before price ever reaches the limit. - NEVER EXIT AT ZERO AFTER A GOOD PROFIT HAS PRINTED (v4g). Once meaningful open profit has actually appeared on the screen, the floor for that trade stops being breakeven and becomes "some profit". IH, booking a reduced winner: "we diff --git a/Tests/Signal Generators/SL Hunting AI Agent/test_sl_hunting_premarket.py b/Tests/Signal Generators/SL Hunting AI Agent/test_sl_hunting_premarket.py index 88c7409..0e46e9f 100644 --- a/Tests/Signal Generators/SL Hunting AI Agent/test_sl_hunting_premarket.py +++ b/Tests/Signal Generators/SL Hunting AI Agent/test_sl_hunting_premarket.py @@ -201,17 +201,15 @@ def test_shipped_note_targets_the_next_TRADING_day_not_the_next_calendar_day(): ) -def test_shipped_note_matches_august_14_intraday_hunter_plan(): - """The committed advisory must match the hand-checked 13 Aug transcript. +def test_shipped_note_matches_august_17_intraday_hunter_plan(): + """The committed advisory must match the hand-checked 16 Aug transcript. This catches a stale prior-session note, an inverted gap plan, or a mistyped chart level before the dated note is injected into the live prompt. - What distinguishes this one is that NEITHER side is seated -- he says so for - both BankNIFTY ("the same price level") and Sensex ("would be WRONG" to - claim either). That is the empty-book condition v4f describes, so the note - carries his own mechanism for it (thin crowd -> that is where momentum - goes) rather than letting the agent infer a seated crowd that is not there. + What distinguishes this session is the same sell-side search across gap-up, + flat, and gap-down opens, with an explicit extra-risk test for a gap-down: + fresh sellers or a large positive recovery can make the buyer hunt unsafe. """ import os @@ -220,37 +218,33 @@ def test_shipped_note_matches_august_14_intraday_hunter_plan(): note = load_premarket_note(shipped) assert note is not None - assert note.for_date == "2026-08-14" - assert "MhmlrlUEUGI" in note.source - # The distinguishing fact: no decisive crowd on either side. - assert "SAME price level" in note.context - assert note.plan[0].startswith("FLAT to GAP-DOWN: identify SELL-side setups") - assert note.plan[1].startswith("GAP-UP: go WITH the market") - assert any("NOBODY IS DECISIVELY SEATED" in line for line in note.plan) - # The thin-crowd mechanism and the explicit preference for a gap over a flat - # open are the two ideas a summarising edit would drop first. - assert any("where the crowd is THIN" in line for line in note.plan) - assert any("PREFERS a gap to a flat open" in line for line in note.plan) - assert len(note.plan) == 6 + assert note.for_date == "2026-08-17" + assert "4xfMmQW6x5I" in note.source + assert "buyers as the likely seated crowd" in note.context + assert note.plan == [ + "GAP-UP or FLAT: identify confirmed SELL-side setups targeting the " + "buyers left seated after the prior recovery.", + "GAP-DOWN: retain the SELL-side search, but risk is higher because fresh " + "sellers may participate; the gap alone is not confirmation.", + "GAP-DOWN WITH POSITIVE MOMENTUM: a large recovery weakens the short plan. " + "Retain it only if the recovery stays limited and the normal setup confirms.", + ] assert [level.model_dump() for level in note.levels] == [ { "index": "NIFTY", - # 24176 was READ OFF THE CHART, not inferred. The auto-caption - # rendered it "2476" on both 13 and 14 Aug; a 1080p frame at 2:04 - # shows the teal support line labelled 24,176.20, alongside - # 24,275.25 and resistances at 24,443.85 / 24,540.85 -- every one - # matching what he speaks. Prefer this method over omitting a level. "resistance": [24440.0, 24540.0], - "support": [24275.0, 24176.0], + "support": [24300.0, 24210.0], }, { "index": "BANKNIFTY", - "resistance": [57890.0, 58000.0], - "support": [57500.0, 57320.0], + # The auto-caption garbles the second support. The chart frame at + # 0:44 labels the two selected teal levels 57,280 and 57,154. + "resistance": [57720.0, 57890.0], + "support": [57280.0, 57154.0], }, { "index": "SENSEX", - "resistance": [78145.0, 78500.0], - "support": [77500.0, 77200.0], + "resistance": [78300.0, 78500.0], + "support": [77700.0, 77400.0], }, ] diff --git a/Tests/Signal Generators/SL Hunting AI Agent/test_sl_hunting_schema.py b/Tests/Signal Generators/SL Hunting AI Agent/test_sl_hunting_schema.py index dc32cb2..701ae54 100644 --- a/Tests/Signal Generators/SL Hunting AI Agent/test_sl_hunting_schema.py +++ b/Tests/Signal Generators/SL Hunting AI Agent/test_sl_hunting_schema.py @@ -878,7 +878,10 @@ def test_system_prompt_has_v4e_recruitment_and_losing_session_knowledge(): prompt = build_system_prompt() assert "WHICH CROWD THE OPEN RECRUITS DECIDES HOW BIG THE TRAP IS" in prompt assert "A FORECAST OF WHO WILL ARRIVE IS NOT EVIDENCE OF WHO IS SEATED" in prompt - assert "A SHARP FIRST SLIDE BAITS; A SLOW ONE MEANS IT" in prompt + # v4e's A SHARP FIRST SLIDE BAITS was PRUNED in v4h: it shipped as a weak + # prior with its own counter-example attached, and v4h's warning-move rule + # covers the same ground with an observable mechanism. See the v4h addendum. + assert "A SHARP FIRST SLIDE BAITS" not in prompt assert "NAME THE LAST POINT, NOT ONLY THE STOP" in prompt assert "DISCIPLINE IS ASYMMETRIC BETWEEN WINNERS AND LOSERS" in prompt # The recruitment distinction is the point; both halves must be present. @@ -901,11 +904,34 @@ def test_v4e_empty_book_is_a_no_trade_not_a_forecasting_licence(): # It must also reconcile with v4c rather than silently contradicting it. assert "MANUFACTURES MORE" in section - # And the bait prior must stay a tie-breaker, never a standalone premise. - bait = prompt[prompt.index("A SHARP FIRST SLIDE BAITS"):] - bait = bait[: bait.index("\n- ")] if "\n- " in bait else bait - assert "weak prior" in bait - assert "never as the premise of a trade on its own" in bait + +def test_v4h_entry_and_direction_and_the_loss_limit_pair_with_their_neighbours(): + """v4h (14 Aug live session): a win held through a full drawdown. + + Two of its rules sit directly on top of earlier ones and would be dangerous + read alone, so both reconciliations are asserted here. + """ + prompt = build_system_prompt() + # The prose is hard-wrapped, so a phrase this test cares about can straddle a + # line break. Collapse whitespace before asserting on wording -- otherwise the + # test breaks on a re-wrap that changed nothing about what the agent reads. + flat = " ".join(prompt.split()) + assert "ENTRY QUALITY AND DIRECTION ARE SEPARATE JUDGEMENTS" in flat + assert "THE LOSS LIMIT IS A PERMISSION TO WAIT" in flat + + # The loss-limit rule must not read as "hold losers": it is bounded on BOTH + # sides, and it has to name the v4e rule it refines rather than contradict. + limit = prompt[prompt.index("THE LOSS LIMIT IS A PERMISSION TO WAIT"):] + limit = " ".join((limit[: limit.index("\n- ")] if "\n- " in limit else limit).split()) + assert "DISCIPLINE IS ASYMMETRIC" in limit + assert "not against it" in limit + assert "forbids holding past it" in limit + assert "forbids" in limit and "cutting inside it" in limit + + # Elapsed time is the one thing allowed to override that patience, and the + # time rule has to say so or the two become contradictory advice. + assert "EXPIRES THE PREMISE" in flat + assert "retire the premise before price ever reaches the limit" in flat def test_system_prompt_has_v4f_repeat_chart_and_confirmation_knowledge():