# Long Entry State Machine — Transition Reference

> Source: `long_entry 2026-03-18 050641.png`
>
> **AI-mapped indicators/guards** from `strategy_v7_0_2.py` (2026-03-19).
> States do not align 1:1 with the old 4-level state model — marked with ⚠ where mapping is approximate.

---

> **Version:** v2.12.0 | **Updated:** 2026-04-21 | **Change:** 20260420_TWM_long_hand_calc_comp c03: Document State05 same-bar entry prohibition — t_80 writes indicators_met_bar_no to context; State05.evaluate() returns early (no transition) when bar_no == indicators_met_bar_no.

<!-- Version: v2.12.0 | Updated: 2026-04-21 | Project: 20260420_TWM_long_hand_calc_comp -->

---

## States

- [**00 — long_00_IDLE**](#long_00_IDLE)
  - 0.01) [SESSION_OPEN](#t_40_session_open) (40) → [`01 — long_01_WAIT_BEAR_TREND`](#long_01_wait_bear_trend)

- [**01 — long_01_WAIT_BEAR_TREND**](#long_01_wait_bear_trend)
  - [[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_10_entry_window_closed (10)
  - 1.02) [BEAR_TREND_MET](#t_50_bear_trend_met) (50) → [`02 — long_02_WAIT_BULL_SHIFT`](#long_02_wait_bull_shift)
  - 1.05) [VELOCITY_ENTRY_S01](#t_51_velocity_entry_s01) (51) → [`07 — long_07_ENTRY_GATE`](#long_07_entry_gate) ⚠ new

- [**02 — long_02_WAIT_BULL_SHIFT**](#long_02_wait_bull_shift)
  - [[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_11_entry_window_closed (11)
  - 2.02) [BULL_SHIFT_MET](#t_60_bull_shift_met) (60) → [`03 — long_03_WAIT_MA_CROSS`](#long_03_wait_ma_cross)
  - 2.03) [BEAR_SETUP_RESET](#t_61_bear_setup_reset) (61) → [`01 — long_01_WAIT_BEAR_TREND`](#long_01_wait_bear_trend)

- [**03 — long_03_WAIT_MA_CROSS**](#long_03_wait_ma_cross)
  - [[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_12_entry_window_closed (12)
  - [[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_20_bull_setup_reset (20)
  - 3.03) [MA_BULL_CROSS](#t_70_ma_bull_cross) (70) → [`04 — long_04_WAIT_INDICATORS`](#long_04_wait_indicators)
  - 3.04) [VELOCITY_ENTRY_S03](#t_71_velocity_entry_s03) (71) → [`07 — long_07_ENTRY_GATE`](#long_07_entry_gate)

- [**04 — long_04_WAIT_INDICATORS**](#long_04_wait_indicators)
  - [[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_21_bull_setup_reset (21)
  - [[ST]](#st-setup_expired) SETUP_EXPIRED t_30_setup_expired (30)
  - 4.03) [ALL_INDICATORS_CONFIRMED](#t_80_all_indicators_confirmed) (80) → [`05 — long_05_WAIT_RETEST`](#long_05_wait_retest)
  - 4.04) [VELOCITY_ENTRY_S04](#t_81_velocity_entry_s04) (81) → [`07 — long_07_ENTRY_GATE`](#long_07_entry_gate) ⚠ new

- [**05 — long_05_WAIT_RETEST**](#long_05_wait_retest)
  - [[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_22_bull_setup_reset (22)
  - [[ST]](#st-setup_expired) SETUP_EXPIRED t_31_setup_expired (31)
  - 5.03) [MA_RETEST_TOUCHED](#t_90_ma_retest_touched) (90) → [`06 — long_06_WAIT_BREAKOUT`](#long_06_wait_breakout)
  - 5.04) [MIDBAR_RETEST_TOUCHED](#t_91_midbar_retest_touched) (91) → [`06 — long_06_WAIT_BREAKOUT`](#long_06_wait_breakout)
  - 5.05) [VELOCITY_ENTRY_S05](#t_92_velocity_entry_s05) (92) → [`07 — long_07_ENTRY_GATE`](#long_07_entry_gate) ⚠ new
    - 5.06) [LWR_High_bypass [LHP]](#t_93_lwr_high_bypass) (93) → [`07 — long_07_ENTRY_GATE`](#long_07_entry_gate) ⚠ new
  - 5.07) [SKIP_RETEST_MULTI_TF](#t_94_skip_retest_multi_tf) (94) → [`07 — long_07_ENTRY_GATE`](#long_07_entry_gate) ⚠ new

- [**06 — long_06_WAIT_BREAKOUT**](#long_06_wait_breakout)
  - [[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_13_entry_window_closed (80)
  - [[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_23_bull_setup_reset (23)
  - [[ST]](#st-setup_expired) SETUP_EXPIRED t_32_setup_expired (32)
  - ~~6.04) [BREAKOUT_SAME_BAR_DELETED](#t_DELETED_breakout_only_same) (DELETED)~~ **DELETED** — superseded by BREAKOUT_LEVEL_HIT (100). See transition 25.
  - 6.05) [BREAKOUT_LEVEL_HIT](#t_100_breakout_level_hit) (100) → [`07 — long_07_ENTRY_GATE`](#long_07_entry_gate)
  - 6.06) [VELOCITY_ENTRY_S06](#t_101_velocity_entry_s06) (101) → [`07 — long_07_ENTRY_GATE`](#long_07_entry_gate) ⚠ new
  - 6.07) [SKIP_BREAKOUT_MULTI_TF](#t_102_skip_breakout_multi_tf) (102) → [`07 — long_07_ENTRY_GATE`](#long_07_entry_gate) ⚠ new
  - 6.08) [BREAKOUT_LIMIT_ENTRY](#t_103_breakout_limit_entry) (103) → [`07 — long_07_ENTRY_GATE`](#long_07_entry_gate) ⚠ new

- [**07 — long_07_ENTRY_GATE**](#long_07_entry_gate)
  - [[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_14_entry_window_closed (22)
  - [[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_24_bull_setup_reset (DELETED)
  - [[ST]](#st-setup_expired) SETUP_EXPIRED t_33_setup_expired (33)
  - 7.04) [TRADE_ENTRY_SUBMITTED](#t_110_trade_entry_submitted) (110) → [`09 — long_09_YELLOW`](long_exit_state_machine_v1_2_1.md#long_09_yellow-initial-active-state)
  - 7.05) [ENTRY_BLOCKED](#t_111_entry_blocked) (111) → [`08 — long_08_ENTRY_BLOCKED`](#long_08_ENTRY_BLOCKED)

- [**08 — long_08_ENTRY_BLOCKED**](#long_08_ENTRY_BLOCKED)
  - [[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_15_entry_window_closed (31)
  - [[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_25_bull_setup_reset (100)
  - [[ST]](#st-setup_expired) SETUP_EXPIRED t_34_setup_expired (100)
  - 8.04) [ENTRY_BLOCK_CLEARED](#t_120_entry_block_cleared) (120) → [`09 — long_09_YELLOW`](long_exit_state_machine_v1_2_1.md#long_09_yellow-initial-active-state)

---

## Entry Confirmations (4-of-4)

Referenced as `entryCriteria` in transitions. All four must be met (`_check_confirmations()`):

1. **MA Position** — `MovingAverageArrayCalculator` — `ma_positions['3x5'] == 1`
2. **RSI > 50** — `calcVelocityRSI` — `flag50_RSI == 1`
3. **Cycle Long** — `calcCycleOscillator` — `cycle_long == 1`
4. **Shift Dot** — `calcShiftDotLevel` — `shiftDot_flag == 1`

---

## Intra-bar Evaluation Model

The state machine supports intra-bar chaining — multiple transitions can fire on the same bar when guards evaluate using only current-bar OHLC, prior-bar values, or pre-computed indicator values.

### Rule Categories

| Rule | Meaning |
|------|---------|
| `bar close only` | Transition evaluates only at bar close; cannot chain with other transitions |
| `chain OK` | Transition can fire intra-bar and chain with subsequent transitions in the same bar cycle |
| `terminal` | Position entry; exit FSM takes over — chain ends |

### Chain Constraints

- **One write per field per bar**: `setup_counter_start_bar` is written at t_70_ma_bull_cross (MA_BULL_CROSS); all other chain-OK transitions only read.
- **No forward data leaks**: chain-OK guards may only reference current-bar OHLC, prior-bar values, or pre-computed indicator values.
- **Safety guard**: maximum 10 chain evaluations per bar to prevent infinite loops.
- **Chain termination**: chain stops when (a) no transition fires, (b) a bar-close-only state is reached, (c) a terminal transition fires, or (d) max chain count is hit.
- **Retest/breakout same-bar prohibition**: States 05 (WAIT_RETEST) and 06 (WAIT_BREAKOUT) are evaluated on 1-second bars. When t_90 or t_91 (retest) fires, `retest_bar_no = bar_no` is written to context. t_100 (BREAKOUT_LEVEL_HIT) guards against `bar_no == retest_bar_no` — the breakout cannot claim the same 1-sec bar as the retest. The earliest a breakout can fire is the next 1-sec bar after the retest bar.
- **State05 same-bar entry prohibition**: State05 (WAIT_RETEST) transitions are evaluated on 1-second bars. When t_80 (ALL_INDICATORS_CONFIRMED) fires and enters State05, it writes `indicators_met_bar_no = bar_no` to context. `State05.evaluate()` returns early with no transition when `bar_no == indicators_met_bar_no`. The earliest any State05 outbound transition can fire is the next 1-sec bar after the bar that entered State05.

---

## Shared Transitions

The following transitions appear in multiple states. Each instance has a unique ID encoding the from-state (`t_TAG_{nn}_TO`). The full definition is here; each state section shows only a compact reference line.

### [SE] ENTRY_WINDOW_CLOSED

2) **ENTRY_WINDOW_CLOSED**
    - ID: `t_10_entry_window_closed` (10) | `t_11_entry_window_closed` (11) | `t_12_entry_window_closed` (12) | `t_13_entry_window_closed` (80) | `t_14_entry_window_closed` (22) | `t_15_entry_window_closed` (31)
    - From: `long_01_WAIT_BEAR_TREND` | `long_02_WAIT_BULL_SHIFT` | `long_03_WAIT_MA_CROSS` | `long_06_WAIT_BREAKOUT` | `long_07_ENTRY_GATE` | `long_08_ENTRY_BLOCKED`
    - To: `long_00_IDLE`
    - Name: `ENTRY_WINDOW_CLOSED`
    - Indicator: `calcTradingAuthorized`
    - Guard: `tradeEntry_isAuthorized == False`
    - Action: n/a
    - Comments: Applies to states 01, 02, 03, 06, 07, 08. `tradeEntry_isAuthorized` excludes `trade_4` window (entry closes at 15:45). ⚠ Not yet tested in pipeline.
    - Intra-bar Rule: `bar close only`

#### calcTradingAuthorized explanation

**Source:** `calcTradingAuthorized` class in indicator modules.

**Config references:**
- Primary timezone definitions: `config_3_time_zones_v5_0_0.json` — defines all 9 session zones, `approved_times`, `trade_approved_times`, and `entry_approved_times`
- Indicator properties: `config_2_indicators_v5_4_0.json` — `calcTradingAuthorized` section mirrors the zone definitions and lists the same approved-time arrays
- Timezone: `US/Eastern`

**All defined time zones:**

| Zone | Start | End | `isAuthorized` | In `trade_approved_times` | In `entry_approved_times` |
|------|-------|-----|:--------------:|:-------------------------:|:-------------------------:|
| `pre_session` | 18:00 | 09:30 | false | — | — |
| `open` | 09:30 | 09:50 | false | — | — |
| `trade_1` | 09:50 | 10:00 | true | ✓ | ✓ |
| `trade_2` | 10:00 | 12:05 | true | ✓ | ✓ |
| `lunch` | 12:05 | 12:35 | true | ✓ | ✓ |
| `trade_3` | 12:35 | 15:45 | true | ✓ | ✓ |
| `trade_4` | 15:45 | 15:56 | true | ✓ | — |
| `long_00_IDLE` | 15:56 | 17:00 | false | — | — |
| `closed` | 17:00 | 18:00 | false | — | — |

**Key distinction — two authorization levels:**
- `tradingTime_isAuthorized` — `True` in all 5 trade zones (including `trade_4`). Used by SESSION_OPEN/EXIT_SESSION_CLOSE transitions.
- `tradeEntry_isAuthorized` — `True` only in the 4 entry zones (`trade_4` **excluded**). Used by this [SE] transition.

**Step-by-step breakdown:**

1. `calcTradingAuthorized` evaluates the current bar timestamp against the zones in `config_3_time_zones_v5_0_0.json`.
2. `tradeEntry_isAuthorized` is set to `False` when the current time falls outside `entry_approved_times` (i.e., in `trade_4`, `long_00_IDLE`, `closed`, `pre_session`, or `open`). The entry window closes at **15:45**.
3. Guard fires → the machine exits the current state and returns to `long_00_IDLE`, abandoning all pre-position setup context.

**Plain English:** when the new-entry window closes at 15:45 (start of `trade_4`) or at any other non-entry time, all entry setup progress is abandoned and the machine returns to the after-hours idle state. `trade_4` is excluded from entry to prevent opening new positions in the final 11-minute close window.

#### long_00_IDLE

The initial idle state. The machine waits here until the next valid session start (`SESSION_OPEN` transition fires when `tradingTime_isAuthorized == True`). State00 evaluates at 1-minute bar closes regardless of the strategy timeframe — this ensures the transition fires at the exact minute trading becomes authorized (e.g., 09:50:00) rather than waiting for the next TF-N bar close.

### [BTB] BULL_SETUP_RESET

8) **BULL_SETUP_RESET**
    - ID: `t_20_bull_setup_reset` (20) | `t_21_bull_setup_reset` (21) | `t_22_bull_setup_reset` (22) | `t_23_bull_setup_reset` (23) | `t_24_bull_setup_reset` (DELETED) | `t_25_bull_setup_reset` (100)
    - From: `long_03_WAIT_MA_CROSS` | `long_04_WAIT_INDICATORS` | `long_05_WAIT_RETEST` | `long_06_WAIT_BREAKOUT` | `long_07_ENTRY_GATE` | `long_08_ENTRY_BLOCKED`
    - To: `long_01_WAIT_BEAR_TREND`
    - Name: `BULL_SETUP_RESET`
    - Indicator: `strategy`
    - Guard: `1 sec low < return_neutral_limit`
    - Action: reset `setup_counter_start_bar = None`
    - Comments: Applies to states 03, 04, 05, 06, 07, 08. `return_neutral_limit` is recorded at `BULL_SHIFT_MET` (transition 5).
    - Intra-bar Rule: `intra-bar (1-second low monitoring)`

#### strategy / return_neutral_limit explanation

**Source:** Strategy-level computation using `calcTrendCounter` output.

**Step-by-step breakdown:**

1. **`return_neutral_limit`** — set when `BULL_SHIFT_MET` fires (transition 5): the strategy records the lowest low from the `calcTrendCounter` lookback array at that moment. This level acts as an invalidation floor for the entire bullish setup.
2. **`1 sec low`** — the low of the current 1-second intra-bar price tick used for real-time monitoring. This allows the guard to fire intra-bar before the 2-hour bar closes.
3. **Guard fires** — when the 1-second low breaches below `return_neutral_limit`, the bullish setup is invalidated and the machine resets to `long_01_WAIT_BEAR_TREND`.

**Plain English:** if price drops below the lowest low seen during the bearish trend that triggered the setup, the bull setup is considered broken and the machine resets to neutral.

#### long_01_WAIT_BEAR_TREND

The neutral holding state. The machine waits here for either `BEAR_TREND_MET` (to restart a new setup) or `ENTRY_WINDOW_CLOSED` (session close).

### [ST] SETUP_EXPIRED

12) **SETUP_EXPIRED**
    - ID: `t_30_setup_expired` (30) | `t_31_setup_expired` (31) | `t_32_setup_expired` (32) | `t_33_setup_expired` (33) | `t_34_setup_expired` (100)
    - From: `long_04_WAIT_INDICATORS` | `long_05_WAIT_RETEST` | `long_06_WAIT_BREAKOUT` | `long_07_ENTRY_GATE` | `long_08_ENTRY_BLOCKED`
    - To: `long_01_WAIT_BEAR_TREND`
    - Name: `SETUP_EXPIRED`
    - Indicator: `strategy`
    - Guard: `setup_counter >= 4`
    - Action: reset `setup_counter_start_bar = None`
    - Comments: Applies to states 04, 05, 06, 07, 08. `setup_counter` = `current_bar_no − setup_counter_start_bar`; counter starts at `MA_BULL_CROSS` (transition 9).
    - Intra-bar Rule: `bar close only`

#### strategy / setup_counter explanation

**Source:** Strategy-level bar counter maintained since `MA_BULL_CROSS`.

**Step-by-step breakdown:**

1. **`setup_counter_start_bar`** — captured at `MA_BULL_CROSS` (transition 9): the bar number when the moving-average crossover was confirmed.
2. **`setup_counter`** — computed each bar as `current_bar_no - setup_counter_start_bar`. Represents the number of bars elapsed since the crossover.
3. **`setup_counter >= 4`** — if the setup has not progressed within 4 bars, the opportunity is considered stale.
4. **Guard fires** → the machine resets to neutral, discarding all setup context.

**Bar count example:**

| Bar no. | Event | `setup_counter_start_bar` | `setup_counter` | Guard `>= 4`? | State |
|---------|-------|--------------------------|-----------------|----------------|-------|
| 100 | `MA_BULL_CROSS` fires (t9). Sets `setup_counter_start_bar = 100`. | 100 | 0 | No | current |
| 101 | No qualifying transition fires. | 100 | 1 | No | current |
| 102 | No qualifying transition fires. | 100 | 2 | No | current |
| 103 | No qualifying transition fires. | 100 | 3 | No | current |
| 104 | `SETUP_EXPIRED` guard: `104 - 100 = 4 >= 4`. **Fires.** | 100 | 4 | **Yes** | → `long_01_WAIT_BEAR_TREND` |

**Key points:**
- Bar 100 is bar 0 (the crossover bar itself). The counter starts running on entry.
- If the setup advances (e.g., `ALL_INDICATORS_CONFIRMED`) on bars 101–103, the machine moves forward and this timeout no longer applies.
- The guard fires on bar 104 — **4 bars after** the crossover bar, not 4 bars inclusive of it.

**Plain English:** if the indicator chain is not confirmed within 4 bars of the MA crossover, the setup times out and the machine resets to neutral.

#### long_01_WAIT_BEAR_TREND

The neutral holding state. The machine waits here for either `BEAR_TREND_MET` (to restart a new setup) or `ENTRY_WINDOW_CLOSED` (session close).

---

### long_00_IDLE

<a id="t_40_session_open"></a>

1) **SESSION_OPEN**
    - ID: `t_40_session_open`
    - From: `long_00_IDLE`
    - To: `long_01_WAIT_BEAR_TREND`
    - Name: `SESSION_OPEN`
    - Indicator: `calcTradingAuthorized`
    - Guard: `tradingTime_isAuthorized == True`
    - Action: n/a
    - Comments: reviewed/approved 2026-03-21 10:28 EST
    - Intra-bar Rule: `bar close only (1-minute bars, regardless of strategy TF)`

#### calcTradingAuthorized explanation

**Source:** `calcTradingAuthorized` class in indicator modules.

**Config references:**
- Primary timezone definitions: `config_3_time_zones_v5_0_0.json` — defines all 9 session zones, `approved_times`, `trade_approved_times`, and `entry_approved_times`
- Indicator properties: `config_2_indicators_v5_4_0.json`
- Timezone: `US/Eastern`

**All defined time zones:**

| Zone | Start | End | `isAuthorized` | In `trade_approved_times` |
|------|-------|-----|:--------------:|:-------------------------:|
| `pre_session` | 18:00 | 09:30 | false | — |
| `open` | 09:30 | 09:50 | false | — |
| `trade_1` | 09:50 | 10:00 | true | ✓ |
| `trade_2` | 10:00 | 12:05 | true | ✓ |
| `lunch` | 12:05 | 12:35 | true | ✓ |
| `trade_3` | 12:35 | 15:45 | true | ✓ |
| `trade_4` | 15:45 | 15:56 | true | ✓ |
| `long_00_IDLE` | 15:56 | 17:00 | false | — |
| `closed` | 17:00 | 18:00 | false | — |

**Step-by-step breakdown:**

1. `calcTradingAuthorized` evaluates the current bar timestamp against the zones in `config_3_time_zones_v5_0_0.json`.
2. `tradingTime_isAuthorized` is set to `True` when the current time falls within `trade_approved_times` (`trade_1` through `trade_4`, inclusive).
3. Guard fires → the machine leaves `long_00_IDLE` and enters `long_01_WAIT_BEAR_TREND`, ready to begin evaluating entry setups.

**Plain English:** at the start of the first authorized trading bar of the session (09:50 ET), the machine wakes from the after-hours idle state and begins scanning for bearish trend setups.

#### long_01_WAIT_BEAR_TREND

The neutral holding state. The machine waits here for either `BEAR_TREND_MET` (to begin a new setup) or `ENTRY_WINDOW_CLOSED` (session closes before a setup forms).

---

### long_01_WAIT_BEAR_TREND

[[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_10_entry_window_closed (10)

<a id="t_50_bear_trend_met"></a>

3) **BEAR_TREND_MET**
    - ID: `t_50_bear_trend_met`
    - From: `long_01_WAIT_BEAR_TREND`
    - To: `long_02_WAIT_BULL_SHIFT`
    - Name: `BEAR_TREND_MET`
    - Indicator: `calcTrendCounter`
    - Guard: `bearCount_isMet == 1`
    - Action: n/a
    - Comments: `fast` and `slow` from `config_2_indicators_v5_4_0.json → MovingAverageArrayCalculator.tickers.tradeTicker.[ticker].[tf] = [fast, slow, exit]`. e.g. `@ES tf1: [3, 5, 8]` → key `"3x5"`. Approved 2026-03-21 12:15 EST. MA guard removed by c13 (2026-04-18).
    - Intra-bar Rule: `bar close only`

#### calcTrendCounter / bearCount_isMet explanation

**Source:** `calcTrendCounter` class in indicator modules.

**Step-by-step breakdown:**

1. **`calcTrendCounter`** — counts consecutive bearish candles in the recent look-back window. Produces `bearCount_isMet` flag when the count threshold for a confirmed bearish trend is reached.
2. **`bearCount_isMet == 1`** — the bearish trend count threshold has been reached; the prior trend is confirmed as bearish.
3. **MA alignment (removed):** The prior guard required `ma_positions[f"{fast}x{slow}"] == -1`. This condition has been removed — `bearCount_isMet == 1` alone is sufficient to confirm the trend.
4. **Condition met** — bearish trend is confirmed → the machine advances from neutral to the bear-trend-met state, beginning the search for a bullish reversal setup.

**Plain English:** when the trend counter confirms a sustained bearish trend AND the moving averages are bearishly aligned, the machine registers that a bear trend is in place and begins watching for a bull shift.

#### long_02_WAIT_BULL_SHIFT

Holding state indicating a confirmed bearish trend. The machine waits for either `BULL_SHIFT_MET` (setup progression), `BEAR_SETUP_RESET` (trend invalidated), or `ENTRY_WINDOW_CLOSED` (session ends).

<a id="t_51_velocity_entry_s01"></a>

37) **VELOCITY_ENTRY_S01**
    - ID: `t_51_velocity_entry_s01`
    - From: `long_01_WAIT_BEAR_TREND`
    - To: `long_07_ENTRY_GATE`
    - Name: `VELOCITY_ENTRY_S01`
    - Indicator: `MAAC` + `calcCandleCount`
    - Guard: `ma_velocity > 1.3 AND bullShift_isMet == 1 AND velocity_breakout_isProhibited == False`
    - Action: same as VELOCITY_ENTRY_S03 (SM #10) — submit long entry; `velocity_breakout_isProhibited = True`
    - Comments: New — no bear trend prerequisite; fires from dormant Neutral state when velocity and bull-shift conditions are simultaneously met.
    - Intra-bar Rule: `bar close only`

#### Guard explanation

**Two conditions must both be true:**

1. **`ma_velocity > 1.3`** — EMA fast/slow separation exceeds 1.3 pts, confirming strong upward momentum (same threshold as VELOCITY_ENTRY_S03, transitions 10/18/26).
2. **`bullShift_isMet == 1`** — `calcCandleCount` has detected the bull-shift candle pattern (same flag as `BULL_SHIFT_MET`, transition 5). No prior bear trend is required — the absence of a bear trend is not a disqualifier if price is already accelerating.

**Plain English:** when the strategy is sitting at neutral with no active setup chain, and both EMA velocity and the bull-shift pattern are simultaneously confirmed, the machine enters directly without requiring a prior bear trend.

---

### long_02_WAIT_BULL_SHIFT

[[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_11_entry_window_closed (11)

<a id="t_60_bull_shift_met"></a>

5) **BULL_SHIFT_MET**
    - ID: `t_60_bull_shift_met`
    - From: `long_02_WAIT_BULL_SHIFT`
    - To: `long_03_WAIT_MA_CROSS`
    - Name: `BULL_SHIFT_MET`
    - Indicator: `calcCandleCount`
    - Guard: `bullShift_isMet == 1`
    - Action: record the low of the calcTrendCounter look back array as `return_neutral_limit`; capture the first bullshift-array bar number for later structure-window calculations
    - Comments: Approved 2026-03-21 12:36 EST.
    - Intra-bar Rule: `bar close only`

#### calcCandleCount explanation

**Source:** `calcCandleCount` class in indicator modules.

**Step-by-step breakdown:**

1. **Candle pattern scan** — `calcCandleCount` scans the recent price bars within a lookback window (`lookbackPeriod: 3`) to identify a bullish shift pattern. Each bar in the window is recorded as its close price if green (close > open) or `-` if red. The bars do not need to be back-to-back in time — they simply need to be present as green bars within the 3-bar lookback array.
2. **`bullShift_isMet`** — set to `1` when at least `limitCount` (config value: `1`) green bars in the 3-bar array have a close that is **higher than a prior green close** also present in the same array. Bars do not need to be consecutive — only the comparison between any green close and any earlier green close in the array matters.
3. **Guard fires** — when `bullShift_isMet == 1`, the `BULL_SHIFT_MET` transition fires, advancing the machine from `long_02_WAIT_BULL_SHIFT` to `long_03_WAIT_MA_CROSS`.
4. **Action** — on firing, the strategy records `return_neutral_limit = min(calcTrendCounter_lookback_lows)` and captures the first bullshift-array bar number. That bar becomes the start of later c31 structure-reference windows used by retest and velocity bypass logic.

**Plain English:** when at least one green bar in the 3-bar lookback window has a higher close than a prior (non-consecutive) green close in that same window, the `BULL_SHIFT_MET` transition fires, the setup advances, and the bear-trend floor is recorded as the invalidation level.

#### long_03_WAIT_MA_CROSS

State `long_03_WAIT_MA_CROSS` has confirmed both the bearish trend (state 02) and the bullish reversal candle pattern. The machine now waits for the MA crossover (`MA_BULL_CROSS`) or a bypass directly to `long_07_ENTRY_GATE` via `VELOCITY_ENTRY_S03`.

<a id="t_61_bear_setup_reset"></a>

6) **BEAR_SETUP_RESET**
    - ID: `t_61_bear_setup_reset`
    - From: `long_02_WAIT_BULL_SHIFT`
    - To: `long_01_WAIT_BEAR_TREND`
    - Name: `BEAR_SETUP_RESET`
    - Indicator: `calcTrendCounter` + `MAAC`
    - Guard: `bullCount_isMet == 1`
    - Action: n/a
    - Comments: `t_05_02_03_BULL_SHIFT_MET` is a higher priority transition and must be processed first. Approved 2026-03-21 13:02 EST.
    - Intra-bar Rule: `bar close only`

#### Guard explanation

**One condition:**

1. **`bullCount_isMet == 1`** — `calcTrendCounter` has detected a sufficient count of bullish candles, indicating the bearish trend is no longer sustained.

**Priority rule:** `BULL_SHIFT_MET` (transition 5, `t_60_bull_shift_met`) must be evaluated before this transition. If both fire on the same bar, `BULL_SHIFT_MET` takes precedence and the machine advances to `long_03_WAIT_MA_CROSS` rather than resetting to neutral.

**Plain English:** when the trend counter shows bullish candles accumulating — without a qualifying bull shift pattern — the bearish setup is invalidated and the machine resets to neutral to wait for a fresh bear trend.

#### long_01_WAIT_BEAR_TREND

The neutral holding state. The machine waits here for either `BEAR_TREND_MET` (to restart a new setup) or `ENTRY_WINDOW_CLOSED` (session close).

---

### long_03_WAIT_MA_CROSS

[[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_12_entry_window_closed (12)

[[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_20_bull_setup_reset (20)

<a id="t_70_ma_bull_cross"></a>

9) **MA_BULL_CROSS**
    - ID: `t_70_ma_bull_cross`
    - From: `long_03_WAIT_MA_CROSS`
    - To: `long_04_WAIT_INDICATORS`
    - Name: `MA_BULL_CROSS`
    - Indicator: `strategy`
    - Guard: `ma_positions[f"{fast}x{slow}"] == 1`
    - Action: capture `setup_counter_start_bar = current_bar_no`; reset `setup_counter = 0`
    - Comments: Approved 2026-03-22.
    - Intra-bar Rule: `chain OK — writes setup_counter_start_bar; counter = 0 this bar; evaluated at bar close only`

#### MAAC / ma_positions explanation

**Source:** `MovingAverageArrayCalculator` (MAAC) in indicator modules.

**Step-by-step breakdown:**

1. **`MovingAverageArrayCalculator`** — computes EMAs for multiple period pairs from a price array. Each consecutive pair `(fast, slow)` produces derived metrics per bar.
2. **`ma_positions`** — a dict keyed by `"{fast}x{slow}"` strings. Each value is a per-bar integer flag: `1` (fast EMA > slow EMA — bullish), `-1` (fast < slow — bearish), `0` (equal).
3. **`ma_positions[f"{fast}x{slow}"] == 1`** — the fast-period EMA has crossed above the slow-period EMA, confirming upward short-term momentum.
4. **Period values** — periods are loaded per ticker and timeframe from `config_2_indicators_v5_4_0.json` under `MovingAverageArrayCalculator.tickers.tradeTicker.[ticker].[tf]` via `_get_ma_periods()`. The sorted list is unpacked as: `fastest_p = sorted_periods[0]` (fast EMA), `second_p = sorted_periods[1]` (slow/medium EMA), `slowest_p = sorted_periods[-1]` (exit EMA). In the strategy class these become `self._ma_fast_key = str(periods[0])`, `self._ma_medium_key = str(periods[1])`, and `self._ma_position_key = f"{periods[0]}x{periods[1]}"`. Example: `@ES tf1: [3, 5, 8]` → `_ma_fast_key='3'`, `_ma_medium_key='5'`, `_ma_position_key='3x5'`.
5. **Action** — on firing, `setup_counter_start_bar = current_bar_no` and `setup_counter = 0` are captured. These drive all subsequent [ST] timeout guards.

**Plain English:** the fast EMA has crossed above the slow EMA, confirming bullish momentum. From this point the setup timer starts; all subsequent states must complete within 4 bars.

#### long_04_WAIT_INDICATORS

State `long_04_WAIT_INDICATORS` has confirmed the bullish MA crossover. The machine waits here for the full indicator chain to confirm (`ALL_INDICATORS_CONFIRMED`), times out via `SETUP_EXPIRED`, or invalidates via `BULL_SETUP_RESET`.

<a id="t_71_velocity_entry_s03"></a>

10) **VELOCITY_ENTRY_S03**
    - ID: `t_71_velocity_entry_s03`
    - From: `long_03_WAIT_MA_CROSS`
    - To: `long_07_ENTRY_GATE`
    - Name: `VELOCITY_ENTRY_S03`
    - Indicator: `strategy`
    - Guard: `velocity_bypass == True AND setup_counter >= setup_counter_velocity_limit AND bar_high > max(high[first bullshift-array bar : current_bar_no - 1]) AND velocity_breakout_isProhibited == False`
    - Action: `velocity_breakout_isProhibited = True`
    - Comments:
    - Intra-bar Rule: `chain OK — reads counter (no write)`

#### Guard explanation

**Three conditions must all be true simultaneously:**

1. **`ma_velocity > 1.3`** — `ma_velocity` is computed as `MA(fast) - MA(slow)` per bar by `MovingAverageArrayCalculator` (MAAC). Measures the separation between the fast and slow EMAs; larger positive values indicate strong upward momentum. The threshold `1.3` is in price-point units for the instrument and is currently hardcoded (see ISSUE-002).
2. **`setup_counter >= setup_counter_velocity_limit`** — at least `setup_counter_velocity_limit` bars (config default: 3) have elapsed since `MA_BULL_CROSS`. The floor preserves the maturation intent (bars 0–2 excluded) while permitting the bypass on any bar from bar 3 up to the timeout limit. With the prior `== 3` equality guard and a 12-bar timeout window (shift_timeout_bars=6 × bar_seconds=2), the bypass was only reachable on 1 of 12 bars; bars 4–11 were silently blocked. The `>= setup_counter_velocity_limit` form makes the `bar_high > max(high[...])` new-highs check the primary discriminator — its comparison window grows with the counter, naturally filtering mid-window plateaus.
3. **`bar_high > max(high[first bullshift-array bar : current_bar_no - 1])`** — the current bar's high must exceed the highest high recorded from the first bullshift-array bar captured at `BULL_SHIFT_MET` through the bar immediately before the current one. This ensures the bypass is anchored to the full shift structure, not the later MA-cross timing window.

**Plain English:** when EMA momentum is strong enough AND `setup_counter` has matured to at least `setup_counter_velocity_limit` bars AND price is making new highs within the setup window. The setup leaps directly to the entry gate, bypassing the MA-cross, indicator-chain, retest, and breakout states.

#### long_07_ENTRY_GATE

The final entry gate state. The machine is ready to open a position — `TRADE_ENTRY_SUBMITTED` will fire if `prohibit_flag == 0`, otherwise `ENTRY_BLOCKED` holds in state 08.

---

### long_04_WAIT_INDICATORS

[[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_21_bull_setup_reset (21)
[[ST]](#st-setup_expired) SETUP_EXPIRED t_30_setup_expired (30)

<a id="t_80_all_indicators_confirmed"></a>

13) **ALL_INDICATORS_CONFIRMED**
    - ID: `t_80_all_indicators_confirmed`
    - From: `long_04_WAIT_INDICATORS`
    - To: `long_05_WAIT_RETEST`
    - Name: `ALL_INDICATORS_CONFIRMED`
    - Indicator: `strategy`
    - Guard: `ma_positions[f"{fast}x{slow}"] == 1 AND flag50_RSI == 1 AND cycle_long == 1 AND shiftDot_flag == 1`
    - Action: Write `indicators_met_bar_no = bar_no` to context (State05 same-bar prohibition; see Chain Constraints).
    - Comments:
    - Intra-bar Rule: `chain OK — pre-computed indicators; State05 outbound transitions blocked for this bar_no`

#### Entry Criteria (4-of-4) explanation

All four indicators must be `1` simultaneously (velocity is excluded from this check). No new confirmation-bar baseline is created here. Under c31, the structure-low and structure-high reference windows continue to start at the first bullshift-array bar captured at `BULL_SHIFT_MET`.

**Source:** `_check_confirmations()` in strategy. Uses MAAC, `calcVelocityRSI`, `calcCycleOscillator`, `calcShiftDotLevel`.

**Step-by-step breakdown:**

1. **`ma_positions[f"{fast}x{slow}"] == 1`** — `MovingAverageArrayCalculator`: fast EMA > slow EMA (bullish crossover). Key constructed from config: `@ES tf1: [3, 5, 8]` → key `"3x5"`.
2. **`flag50_RSI == 1`** — `calcVelocityRSI`: RSI is above the 50 midline, confirming upward momentum on the RSI axis.
3. **`cycle_long == 1`** — `calcCycleOscillator`: the cycle indicator is in the bullish phase (oscillator above zero or equivalent threshold).
4. **`shiftDot_flag == 1`** — `calcShiftDotLevel`: the shift dot plots a bullish dot at the current bar, confirming trend-direction alignment.
5. **All four must be `1` simultaneously** — this is the "4-of-4" entry-confirmation check referenced throughout the state machine.

**Plain English:** all four entry indicators simultaneously confirm bullish conditions — moving average alignment, RSI momentum, cycle phase, and shift dot — advancing the setup to the retest/bypass stage.

<a id="t_81_velocity_entry_s04"></a>

14) **VELOCITY_ENTRY_S04**
    - ID: `t_81_velocity_entry_s04`
    - From: `long_04_WAIT_INDICATORS`
    - To: `long_07_ENTRY_GATE`
    - Name: `VELOCITY_ENTRY_S04`
    - Indicator: `MAAC`
    - Guard: `skip_retest_1 == True AND setup_counter >= setup_counter_velocity_limit AND bar_high > max(high[first bullshift-array bar : current_bar_no - 1]) AND velocity_breakout_isProhibited == False`
    - Action: `velocity_breakout_isProhibited = True`
    - Comments: high velocity bypass — skip indicator confirmation, retest, and breakout path; identical guard to VELOCITY_ENTRY_S05 (t_92)
    - Intra-bar Rule: `chain OK — reads counter (no write)`

#### Guard explanation (identical to VELOCITY_ENTRY_S05 — see SM #18 for full detail)

1. **`skip_retest_1 == True`** — the strategy-level skip-retest velocity flag is active, indicating sufficiently strong upward momentum.
2. **`setup_counter >= setup_counter_velocity_limit`** — at least `setup_counter_velocity_limit` bars (default: 3) elapsed since `MA_BULL_CROSS` (when `setup_counter_start_bar` was set on S03 → S04 transition).
3. **`bar_high > max(high[first bullshift-array bar : current_bar_no - 1])`** — current bar's high exceeds all highs from the first bullshift-array bar through the bar immediately before the current one, confirming genuine new highs across the full shift structure.
4. **All three met** — indicator confirmation, retest, and breakout stages are skipped; machine transitions directly to entry gate.

#### long_05_WAIT_RETEST

State `long_05_WAIT_RETEST` has confirmed the full 4-of-4 entry indicator chain. The machine now waits for either a retest confirmation or one of the three skip-retest bypass paths.

---

### long_05_WAIT_RETEST

[[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_22_bull_setup_reset (22)
[[ST]](#st-setup_expired) SETUP_EXPIRED t_31_setup_expired (31)

<a id="t_90_ma_retest_touched"></a>

16) **MA_RETEST_TOUCHED**
    - ID: `t_90_ma_retest_touched`
    - From: `long_05_WAIT_RETEST`
    - To: `long_06_WAIT_BREAKOUT`
    - Name: `MA_RETEST_TOUCHED`
    - Indicator: `strategy`
    - Guard: `bar_low <= slow_MA(last tfxx minute bar)`
    - Action: capture `retest_bar_no = current_bar_no`; capture `limit_stop_loss = bar_low`
    - Comments: Breakout FSM state 1→2.
    - Intra-bar Rule: `chain OK — prior minute-bar snapshot (fixed per-bar)`

#### strategy / slow_MA(last tfxx minute bar) explanation

**Source:** Strategy-level computation using `MovingAverageArrayCalculator` output.

**Step-by-step breakdown:**

1. **`slow_MA(last tfxx minute bar)`** — the EMA value of the slow period (`second_p = sorted_periods[1]`, e.g., `5` for `@ES tf1`) snapshotted at the close of the most recently completed tfxx minute bar. Periods are loaded per ticker and timeframe from `config_2_indicators_v5_4_0.json` under `MovingAverageArrayCalculator.tickers.tradeTicker.[ticker].[tf]` via `_get_ma_periods()`. The value is captured once at each minute-bar close into `self._prior_bar_slow_ma` and held fixed for all 1-second ticks within the current minute — it does NOT update live on each 1-sec tick.
2. **`bar_low <= slow_MA(last tfxx minute bar)`** — the current 1-sec bar's low touches or dips below the slow moving average level from the last completed minute bar, confirming a retest of support at the MA level.
3. **Action on fire:**
   - `retest_bar_no = current_bar_no` — records the bar index on which the retest occurred. `current_bar_no` is an integer bar index into the price array, not a timestamp.
    - `pending_stop_loss = min(price[first bullshift-array bar to retest_event])` — the minimum price of the price structure beginning at the first bullshift-array bar captured at `BULL_SHIFT_MET` and ending at the retest event.
    - `pending_breakout = max(price[first bullshift-array bar to retest_event])` — the highest price of the same price structure, defining the breakout trigger level.
   - `breakout_limit = pending_breakout + breakout_offset` — the limit order price for the broker.
   - If `prohibit_flag == 0`: issue a broker limit buy order at `breakout_limit`.

**Plain English:** when price dips to or below the slow moving average (MA retest), a support touch is confirmed, the retest bar number and low are recorded, the pending stop loss and breakout levels are captured, and — if trade is not prohibited by the premarket limit — a broker limit buy order is issued at `breakout_limit`.

#### long_06_WAIT_BREAKOUT

State `long_06_WAIT_BREAKOUT` has confirmed a price retest (`retest_bar_no` and `pending_stop_loss` captured). The machine waits for a breakout bar or resets via BTB/ST/session-end. Two retest paths lead here: MA retest (this transition, 16) and median retest (transition 17).

<a id="t_91_midbar_retest_touched"></a>

17) **MIDBAR_RETEST_TOUCHED**
    - ID: `t_91_midbar_retest_touched`
    - From: `long_05_WAIT_RETEST`
    - To: `long_06_WAIT_BREAKOUT`
    - Name: `MIDBAR_RETEST_TOUCHED`
    - Indicator: `calcCandleCount`
    - Guard: `bar_low < median(prior bar_High_Low)`
    - Action: capture `retest_bar_no = current_bar_no`; capture `limit_stop_loss = bar_low`
    - Comments:
    - Intra-bar Rule: `chain OK — prior-bar value, no leak`

#### strategy / median(previous bar_High_Low) explanation

**Source:** Strategy-level computation using bar price arrays.

**Step-by-step breakdown:**

1. **`previous bar_High_Low`** — the high and low of the immediately preceding bar (the bar before the current intra-bar evaluation).
2. **`median(previous bar_High_Low)`** — the midpoint of that preceding bar's range: `(previous_bar_High + previous_bar_Low) / 2`.
3. **`intra-bar price < median(previous bar_High_Low)`** — at any point within the current bar, the traded price dips below the midpoint of the previous bar's range, signalling a retest penetration into the prior bar's body.
4. **Action on fire:**
   - `retest_bar_no = current_bar_no` — records the bar index on which the retest occurred.
    - `pending_stop_loss = min(price[first bullshift-array bar to retest_event])` — the minimum price of the price structure beginning at the first bullshift-array bar and ending at the retest event.
    - `pending_breakout = max(price[first bullshift-array bar to retest_event])` — the highest price of the same price structure.
   - `breakout_limit = pending_breakout + breakout_offset` — the limit order price for the broker.
   - If `prohibit_flag == 0`: issue a broker limit buy order at `breakout_limit`.

**Plain English:** when the current bar's intra-bar price dips below the midpoint of the previous bar's high/low range, a retest via the prior-bar median level is confirmed, the pending stop loss and breakout levels are captured, and — if trade is not prohibited by the premarket limit — a broker limit buy order is issued at `breakout_limit`.

#### long_06_WAIT_BREAKOUT

State `long_06_WAIT_BREAKOUT` has confirmed a price retest. The machine waits for a breakout bar or resets via BTB/ST/session-end. Two retest paths lead here: MA retest (transition 16) and median retest (this transition, 17).

<a id="t_92_velocity_entry_s05"></a>

18) **VELOCITY_ENTRY_S05**
    - ID: `t_92_velocity_entry_s05`
    - From: `long_05_WAIT_RETEST`
    - To: `long_07_ENTRY_GATE`
    - Name: `VELOCITY_ENTRY_S05`
    - Indicator: `MAAC`
    - Guard: `skip_retest_1 == True AND setup_counter >= setup_counter_velocity_limit AND bar_high > max(high[first bullshift-array bar : current_bar_no - 1]) AND velocity_breakout_isProhibited == False`
    - Action: `velocity_breakout_isProhibited = True`
    - Comments: high velocity bypass — skip retest/breakout path
    - Intra-bar Rule: `chain OK — reads counter (no write)`

#### MAAC / ma_velocity explanation

**Source:** `MovingAverageArrayCalculator` (MAAC) in indicator modules.

**Step-by-step breakdown:**

1. **`ma_velocity`** — `MA(fast) - MA(slow)` per bar. Positive values indicate the fast EMA is above the slow EMA; large values indicate strong separation (momentum).
2. **`ma_velocity > 1.3`** — the fast EMA is more than 1.3 price points above the slow EMA, signalling strong upward momentum.
3. **`setup_counter >= setup_counter_velocity_limit`** — at least `setup_counter_velocity_limit` bars (config default: 3) have elapsed since `MA_BULL_CROSS`. The floor preserves the maturation intent (bars 0–2 excluded) while permitting the bypass on any bar from bar 3 up to the timeout limit. With the prior `== 3` equality guard and a 12-bar timeout window (shift_timeout_bars=6 × bar_seconds=2), the bypass was only reachable on 1 of 12 bars; bars 4–11 were silently blocked. The `>= setup_counter_velocity_limit` form makes the `bar_high > max(high[...])` new-highs check the primary discriminator — its comparison window grows with the counter, naturally filtering mid-window plateaus.
4. **`bar_high > max(high[first bullshift-array bar : current_bar_no - 1])`** — the current bar's high must exceed the highest high recorded from the first bullshift-array bar through the bar immediately before the current one. This ensures price is making genuine new highs across the full shift structure.
5. **All three conditions met** — strong velocity at or after bar 3 of the window with new highs skips the retest and breakout path entirely.

**Plain English:** if the MA velocity is strong on bar 3 or later of the setup window and price is making new highs, the retest and breakout requirements are waived and the machine goes directly to the entry gate.

#### long_07_ENTRY_GATE

The final entry gate state. A position will be entered if `prohibit_flag == 0`, otherwise the machine waits in `long_08_ENTRY_BLOCKED`.

<a id="t_93_lwr_high_bypass"></a>

19) **LWR_High_bypass [LHP]**
    - ID: `t_93_lwr_high_bypass`
    - From: `long_01_WAIT_BEAR_TREND`, `long_02_WAIT_BULL_SHIFT`, `long_03_WAIT_MA_CROSS`, `long_04_WAIT_INDICATORS`, `long_05_WAIT_RETEST`, `long_06_WAIT_BREAKOUT`
    - To: `long_07_ENTRY_GATE`
    - Name: `LWR_High_bypass [LHP]`
    - Indicator: `LWR123Calculator`
    - Guard: `bar_high - prior_lwr_upper_channel >= lhp_threshold_points[@ticker]`
    - Action: n/a
    - Comments: thresholded new-high bypass using prior closed-minute LWR upper reference
    - Intra-bar Rule: `chain OK — current-bar OHLC, no leak`

#### LWR123Calculator / LHP threshold explanation

**Source:** `LWR123Calculator` class in indicator modules.

**Step-by-step breakdown:**

1. **`LWR123Calculator`** — computes a price channel based on Lowest Weighted Range (LWR) methodology. Produces upper and lower channel bands and a per-bar reading flag.
2. **`prior_lwr_upper_channel`** — upper LWR channel from the prior closed minute bar; held fixed during the current bar.
3. **`lhp_threshold_points[@ticker]`** — ticker-scoped threshold in points (e.g., `@ES: 1.0`, `@NQ: 1.0`).
4. **`bar_high - prior_lwr_upper_channel >= lhp_threshold_points[@ticker]`** — bypass fires only when the current high exceeds the prior closed reference by at least the configured threshold.

**Plain English:** when current price pushes at least the configured threshold above the prior closed-minute LWR upper channel, the machine bypasses retest/breakout and goes directly to the entry gate.

#### long_07_ENTRY_GATE

The final entry gate state. A position will be entered if `prohibit_flag == 0`, otherwise the machine waits in `long_08_ENTRY_BLOCKED`.

<a id="t_94_skip_retest_multi_tf"></a>

20) **SKIP_RETEST_MULTI_TF**
    - ID: `t_94_skip_retest_multi_tf`
    - From: `long_05_WAIT_RETEST`
    - To: `long_07_ENTRY_GATE`
    - Name: `SKIP_RETEST_MULTI_TF`
    - Indicator: `calcCombinedTfEntry`
    - Guard: `tf_2_5_entryFlag == 1`
    - Action: n/a
    - Comments: time-frame alignment bypass — full alignment across time frames
    - Intra-bar Rule: `chain OK — pre-computed flag`

#### calcCombinedTfEntry explanation

**Source:** `calcCombinedTfEntry` class in indicator modules.

**Step-by-step breakdown:**

1. **`calcCombinedTfEntry`** — evaluates entry conditions across multiple timeframes. The available timeframes are 1, 2, 3, 4, 5, and 6 minutes. Each timeframe that confirms a long entry contributes an individual flag.
2. **`tf_2_5_entryFlag`** — a combined flag that is set to `1` when both the 2-minute and 5-minute timeframe entry conditions are simultaneously confirmed. Only these two timeframes are used for this transition.
3. **`tf_2_5_entryFlag == 1`** — both the 2-minute and 5-minute timeframes agree on a long-entry signal, indicating meaningful short-term alignment. When this flag is set, the retest and breakout requirements are waived and the machine goes directly to the entry gate.

**Plain English:** when both the 2-minute and 5-minute timeframes simultaneously confirm the entry setup, the retest and breakout requirements are waived and the machine goes directly to the entry gate.

#### long_07_ENTRY_GATE

The final entry gate state. A position will be entered if `prohibit_flag == 0`, otherwise the machine waits in `long_08_ENTRY_BLOCKED`.

---

### long_06_WAIT_BREAKOUT

State `long_06_WAIT_BREAKOUT` has confirmed a price retest. The machine carries a two-level breakout model while it waits for a breakout bar or resets via BTB/ST/session-end:

- `pending_breakout` = structural trigger level captured from the bullshift-to-retest window max.
- `breakout_limit` = broker order baseline computed as `pending_breakout + breakout_offset`.
- `limit_breakout` = downstream order-price alias; for t_100 it equals `breakout_limit`, and for t_103 fills it becomes the actual stepped limit-fill price while `breakout_limit` remains the original baseline.

> **Cancel note:** If `prohibit_flag == 1` and a broker limit order is live (unfilled), cancel the limit order before continuing to wait or transitioning.

[[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_13_entry_window_closed (80)

[[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_23_bull_setup_reset (23)
[[ST]](#st-setup_expired) SETUP_EXPIRED t_32_setup_expired (32)

<a id="t_DELETED_breakout_only_same"></a>

24) ~~**BREAKOUT_SAME_BAR_DELETED**~~ — **DELETED** — was a back-test workaround requiring `close > open` on the breakout bar. Obsolete with 1-second data. Superseded by BREAKOUT_LEVEL_HIT (transition 25).

#### long_07_ENTRY_GATE

The final entry gate state. A position will be entered if `prohibit_flag == 0`, otherwise the machine waits in `long_08_ENTRY_BLOCKED`.

<a id="t_100_breakout_level_hit"></a>

25) **BREAKOUT_LEVEL_HIT**
    - ID: `t_100_breakout_level_hit`
    - From: `long_06_WAIT_BREAKOUT`
    - To: `long_07_ENTRY_GATE`
    - Name: `BREAKOUT_LEVEL_HIT`
    - Indicator: `strategy`
    - Guard: `high >= breakout_limit` where `breakout_limit = pending_breakout + breakout_offset` (offset-adjusted executable threshold, not raw structural level) AND `current_bar_no != retest_bar_no` (breakout cannot fire on the same 1-sec bar as the retest; see Retest/breakout same-bar prohibition in Chain Constraints).
    - Action: use `breakout_limit = pending_breakout + breakout_offset` as the broker order / recorded entry reference; persist `limit_breakout = breakout_limit` for downstream entry handling.
    - Comments: `pending_breakout` and `breakout_limit` must remain separate; do not overwrite either with raw `bar_high` on the decision bar.
    - Intra-bar Rule: `chain OK — current-bar high, no leak`

#### strategy / breakout condition explanation

**Source:** Strategy-level computation using `pending_breakout` and `breakout_limit` from the breakout FSM.

**Step-by-step breakdown:**

1. **`pending_breakout`** — the structural breakout trigger level computed from the bullshift-array price structure through the retest event.
2. **`breakout_limit = pending_breakout + breakout_offset`** — the broker order baseline derived from that trigger level.
3. **breakout hit signal** — the current bar's high reaches or exceeds the **offset-adjusted executable threshold** (`breakout_limit = pending_breakout + breakout_offset`); the entry reference is recorded as `limit_breakout = breakout_limit`.
4. **No `close > open` requirement** — indicators are recalculated every 1 second; the breakout path reacts intra-bar without requiring a bullish candle close.

**Plain English:** Price hit the structural breakout trigger, and the strategy uses the precomputed `breakout_limit` order price instead of replacing it with the breakout bar's raw high.

#### long_07_ENTRY_GATE

The final entry gate state. A position will be entered if `prohibit_flag == 0`, otherwise the machine waits in `long_08_ENTRY_BLOCKED`.

<a id="t_103_breakout_limit_entry"></a>

28) **BREAKOUT_LIMIT_ENTRY**
    - ID: `t_103_breakout_limit_entry`
    - From: `long_06_WAIT_BREAKOUT`
    - To: `long_07_ENTRY_GATE`
    - Name: `BREAKOUT_LIMIT_ENTRY`
    - Indicator: `strategy`
    - Guard: `t_103_breakout_limit_entry_isActive == True AND (limit_order_filled OR entry_offset == 0)`
    - Action: anchor the progressive order ladder to `breakout_limit = pending_breakout + breakout_offset`; if `entry_offset == 0`, submit market order; else, record limit fill price as `limit_breakout = breakout_limit - entry_offset`; reset `entry_timer = 0`
    - Config: `t_103_breakout_limit_entry_isActive` in `config_5_strategy_long_v1_7_3.json` → `transition_guards`; levels and increment in `config_7_limit_order_long_v1_0_0.json` → `entry_limit_config`
    - Comments: Alternative to BREAKOUT_LEVEL_HIT. Uses progressive limit entry below the same `breakout_limit` baseline. If both `t_100_breakout_level_hit_isActive` and `t_103_breakout_limit_entry_isActive` are true, BREAKOUT_LEVEL_HIT takes priority. `entry_timer` is managed internally within long_06_WAIT_BREAKOUT — see entry_timer internal management section below.
    - Intra-bar Rule: `chain OK — limit fill or market order`

#### entry_timer — Internal Management in long_06_WAIT_BREAKOUT

When `t_103_breakout_limit_entry_isActive == True`, the following per-bar logic runs inside `long_06_WAIT_BREAKOUT` before transition evaluation:

| Condition | Action |
|---|---|
| structural breakout hit signal is true | Increment `entry_timer` by 1 |
| structural breakout hit signal is false | Hold `entry_timer` and preserve the stored breakout baseline |
| `entry_timer` crosses new threshold | Re-issue limit order at `breakout_limit - entry_offset` (step down from the shared baseline) |
| `entry_offset == 0` (`entry_timer >= 25` with default config) | Issue market order; `BREAKOUT_LIMIT_ENTRY` condition fires |
| Transition fires (fill or market) | Reset `entry_timer = 0` |

**Threshold table (default config: increment=5):**

| `entry_timer` range | Level | Offset (@ES) | Offset (@NQ) |
|---|---|---|---|
| 0–4 | level_1 | 2.5 pts | 7.5 pts |
| 5–9 | level_2 | 2.0 pts | 6.0 pts |
| 10–14 | level_3 | 1.5 pts | 4.5 pts |
| 15–19 | level_4 | 1.0 pts | 3.0 pts |
| 20–24 | level_5 | 0.5 pts | 1.5 pts |
| ≥ 25 | level_6 | 0 → **market order** | 0 → **market order** |

**Priority rule:** if both `t_100_breakout_level_hit_isActive` and `t_103_breakout_limit_entry_isActive` are `true`, `BREAKOUT_LEVEL_HIT` (transition 25) fires first and `BREAKOUT_LIMIT_ENTRY` is bypassed.

#### long_07_ENTRY_GATE

The final entry gate state. A position will be entered if `prohibit_flag == 0`, otherwise the machine waits in `long_08_ENTRY_BLOCKED`.

<a id="t_101_velocity_entry_s06"></a>

26) **VELOCITY_ENTRY_S06**
    - ID: `t_101_velocity_entry_s06`
    - From: `long_06_WAIT_BREAKOUT`
    - To: `long_07_ENTRY_GATE`
    - Name: `VELOCITY_ENTRY_S06`
    - Indicator: `MAAC`
    - Guard: `skip_breakout_1 == True AND setup_counter >= setup_counter_velocity_limit AND bar_high > max(high[first bullshift-array bar : current_bar_no - 1]) AND velocity_breakout_isProhibited == False`
    - Action: capture `pending_stop_loss = min(low[retest_bar_no ... current_barNo])`; `velocity_breakout_isProhibited = True`
    - Comments: High velocity bypass from retest state — skips breakout confirmation. Analogous to VELOCITY_ENTRY_S05 (18) but from state 06.
    - Intra-bar Rule: `chain OK — reads counter (no write)`

#### MAAC / ma_velocity explanation

**Source:** `MovingAverageArrayCalculator` (MAAC) in indicator modules.

**Step-by-step breakdown:**

1. **`ma_velocity`** — `MA(fast) - MA(slow)` per bar. Positive values indicate the fast EMA is above the slow EMA; large values indicate strong separation (momentum).
2. **`skip_breakout_1 == True`** — the strategy-level skip-breakout velocity flag is active, indicating sufficiently strong upward momentum after retest.
3. **`setup_counter >= setup_counter_velocity_limit`** — at least `setup_counter_velocity_limit` bars (config default: 3) have elapsed since `MA_BULL_CROSS`. The floor preserves the maturation intent (bars 0–2 excluded) while permitting the bypass on any bar from bar 3 up to the timeout limit. With the prior `== 3` equality guard and a 12-bar timeout window (shift_timeout_bars=6 × bar_seconds=2), the bypass was only reachable on 1 of 12 bars; bars 4–11 were silently blocked. The `>= setup_counter_velocity_limit` form makes the `bar_high > max(high[...])` new-highs check the primary discriminator — its comparison window grows with the counter, naturally filtering mid-window plateaus.
4. **`bar_high > max(high[first bullshift-array bar : current_bar_no - 1])`** — the current bar's high must exceed the highest high recorded from the first bullshift-array bar through the bar immediately before the current one. This ensures price is making genuine new highs, not stalling at a velocity plateau.
5. **All three conditions met** — strong velocity at or after bar 3 of the setup window with new highs skips the breakout confirmation step entirely.
6. **State context** — the retest has already occurred (`retest_bar_no` and `limit_stop_loss = bar_low` are captured). This bypass fires when strong momentum with new highs makes waiting for a formal breakout bar unnecessary.

**Plain English:** if the MA velocity is strong on bar 3 or later of the setup window, price is making new highs, and the retest has already been confirmed, the breakout confirmation step is waived and the machine goes directly to the entry gate.

#### long_07_ENTRY_GATE

The final entry gate state. A position will be entered if `prohibit_flag == 0`, otherwise the machine waits in `long_08_ENTRY_BLOCKED`.

<a id="t_102_skip_breakout_multi_tf"></a>

27) **SKIP_BREAKOUT_MULTI_TF**
    - ID: `t_102_skip_breakout_multi_tf`
    - From: `long_06_WAIT_BREAKOUT`
    - To: `long_07_ENTRY_GATE`
    - Name: `SKIP_BREAKOUT_MULTI_TF`
    - Indicator: `calcCombinedTfEntry`
    - Guard: `tf_2_5_entryFlag == 1`
    - Action: capture `pending_stop_loss = min(low[retest_bar_no ... current_barNo])`
    - Comments: Time-frame alignment bypass from retest state — skips breakout confirmation. Analogous to SKIP_RETEST_MULTI_TF (20) but from state 06.
    - Intra-bar Rule: `chain OK — pre-computed flag`

#### calcCombinedTfEntry explanation

**Source:** `calcCombinedTfEntry` class in indicator modules.

**Step-by-step breakdown:**

1. **`calcCombinedTfEntry`** — evaluates entry conditions across multiple timeframes. The available timeframes are 1, 2, 3, 4, 5, and 6 minutes. Each timeframe that confirms a long entry contributes an individual flag.
2. **`tf_2_5_entryFlag`** — a combined flag that is set to `1` when both the 2-minute and 5-minute timeframe entry conditions are simultaneously confirmed. Only these two timeframes are used for this transition.
3. **`tf_2_5_entryFlag == 1`** — both the 2-minute and 5-minute timeframes agree on a long-entry signal, indicating meaningful short-term alignment. When this flag is set, the breakout confirmation step is waived.
4. **State context** — the retest has already occurred (`retest_bar_no` and `limit_stop_loss = bar_low` are captured). This bypass fires when timeframe alignment makes waiting for a formal breakout bar unnecessary.

**Plain English:** when both the 2-minute and 5-minute timeframes simultaneously confirm the entry setup and the retest has already been confirmed, the breakout confirmation step is waived and the machine goes directly to the entry gate.

#### long_07_ENTRY_GATE

The final entry gate state. A position will be entered if `prohibit_flag == 0`, otherwise the machine waits in `long_08_ENTRY_BLOCKED`.

---

### long_07_ENTRY_GATE

[[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_14_entry_window_closed (22)

[[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_24_bull_setup_reset (DELETED)
[[ST]](#st-setup_expired) SETUP_EXPIRED t_33_setup_expired (33)

<a id="t_110_trade_entry_submitted"></a>

31) **TRADE_ENTRY_SUBMITTED**
    - ID: `t_110_trade_entry_submitted`
    - From: `long_07_ENTRY_GATE`
    - To: `long_09_YELLOW`
    - Name: `TRADE_ENTRY_SUBMITTED`
    - Indicator: bar price
    - Guard: `prohibit_flag == 0`
    - Action: if the position has NOT already been entered via the broker limit order: capture `entry_price = bar_close`; submit entry order (market); compute `stop_loss = shift_event_low − sl_type_1_offset` (clamped to max distance) [Type 1 — Initial]; submit resting stop order at `stop_loss`; record `entry_price` + `stop_loss` + `stop_type = Type_1_Initial` in broker JSON; reset `setup_counter_start_bar = None`; compute `nearest_resistance = nearest_premarket_level_above(entry_price, session_levels)` [session levels checked in order: `session_high`, `session_open`, `market_open` — nearest above entry wins]; compute `premarket_profit_target = nearest_resistance - premarket_profit_target_offset` [offset from `config_5_strategy.profit_target_config.premarket_profit_target_offset[ticker][tf]`]; snapshot `ctx["premarket_profit_target"] = premarket_profit_target` (None if no resistance level exists above entry)
    - Comments:
    - Intra-bar Rule: `terminal — enters position; exit FSM takes over`

#### bar price / prohibit_flag explanation

**Source:** Strategy-level prohibition check (`calcTradingAuthorized` or PMC module).

**Step-by-step breakdown:**

1. **`prohibit_flag`** — a binary flag set by the strategy to block entry when a risk condition is active (e.g., proximity to premarket price levels, timezone restriction).
2. **`prohibit_flag == 0`** — no prohibition is active; the trade is authorized to execute.
3. **Competing transition** — `ENTRY_BLOCKED` (transition 32) fires if `prohibit_flag == 1` at the same bar, routing to the hold state `long_08_ENTRY_BLOCKED`.
4. **Action on fire (two paths):**
   - **Limit order filled**: position already entered at `limit_breakout` — no market order needed; use `limit_breakout` as `entry_price`.
   - **Limit order not filled**: submit market entry order; `entry_price = bar_close`.
   - Record `entry_price` in broker JSON for trade tracking.

**Plain English:** when no prohibition flag is active, the market entry order is submitted, the entry price is recorded, and the machine transfers to the active position state.

#### long_09_YELLOW (Initial Active State)

The initial active position state. The machine classifies velocity each bar and routes to `long_10_GREEN` (strong) or `long_11_RED` (moderate/weak) accordingly.

<a id="t_111_entry_blocked"></a>

32) **ENTRY_BLOCKED**
    - ID: `t_111_entry_blocked`
    - From: `long_07_ENTRY_GATE`
    - To: `long_08_ENTRY_BLOCKED`
    - Name: `ENTRY_BLOCKED`
    - Indicator: bar price
    - Guard: `prohibit_flag == 1`
    - Action: n/a
    - Comments:
    - Intra-bar Rule: `chain → 08 evaluates ENTRY_BLOCK_CLEARED same bar`


#### bar price / prohibit_flag explanation

**Source:** Strategy-level prohibition check (`calcTradingAuthorized` or PMC module).

**Step-by-step breakdown:**

1. **`prohibit_flag`** — set to `1` when the strategy detects a risk condition preventing entry (e.g., bar high near a premarket level within an exclusion zone, or a timezone-based blackout window).
2. **`prohibit_flag == 1`** — entry is blocked at this bar.
3. **Action** — n/a: no order is submitted. The machine holds in `long_08_ENTRY_BLOCKED`, waiting each bar for the flag to clear.
4. **Competing transition** — `TRADE_ENTRY_SUBMITTED` (transition 31) fires if `prohibit_flag == 0` on the same bar.

**Plain English:** when the trade would otherwise be entered but a prohibition risk condition is active, the machine pauses in the trading-prohibited hold state instead of submitting an order.

#### long_08_ENTRY_BLOCKED

Entry blocked by timezone or proximity to premarket level. The machine waits here until `prohibit_flag == 0` (`ENTRY_BLOCK_CLEARED`, transition 36), times out (`SETUP_EXPIRED`, transition 35), or the session ends (`ENTRY_WINDOW_CLOSED`, transition 33), or price fails (`BULL_SETUP_RESET`, transition 34).

---

### long_08_ENTRY_BLOCKED

Entry blocked by timezone or proximity to premarket level. Waits until restriction clears.

[[SE]](#se-entry_window_closed) ENTRY_WINDOW_CLOSED t_15_entry_window_closed (31)

[[BTB]](#btb-bull_setup_reset) BULL_SETUP_RESET t_25_bull_setup_reset (100)
[[ST]](#st-setup_expired) SETUP_EXPIRED t_34_setup_expired (100)

<a id="t_120_entry_block_cleared"></a>

36) **ENTRY_BLOCK_CLEARED**
    - ID: `t_120_entry_block_cleared`
    - From: `long_08_ENTRY_BLOCKED`
    - To: `long_09_YELLOW`
    - Name: `ENTRY_BLOCK_CLEARED`
    - Indicator: `calcTradingAuthorized`
    - Guard: `prohibit_flag == 0`
    - Action: capture `entry_price = bar_close`; submit entry order (market); compute `stop_loss = shift_event_low − sl_type_1_offset` (clamped to max distance) [Type 1 — Initial]; submit resting stop order at `stop_loss`; record `entry_price` + `stop_loss` + `stop_type = Type_1_Initial` in broker JSON; reset `setup_counter_start_bar = None`
    - Comments:
    - Intra-bar Rule: `terminal — enters position; exit FSM takes over`

#### calcTradingAuthorized / prohibit_flag explanation

**Source:** `calcTradingAuthorized` class in indicator modules.

**Step-by-step breakdown:**

1. **`prohibit_flag`** — set to `0` when all prohibition conditions clear: price is no longer near an exclusion zone (premarket level) and the timezone window is open.
2. **`prohibit_flag == 0`** — the restriction that held the machine in state 08 has cleared; entry is now authorized.
3. **Action on fire:**
   - `entry_price = bar_close` — records the fill price at the bar when the restriction clears.
   - Submit market entry order via broker interface.
   - Record `entry_price` in broker JSON.
4. **Context** — the machine may have waited one or more bars in `long_08_ENTRY_BLOCKED`. All entry criteria were already confirmed before state 08 was entered; no re-check of entry criteria is needed here.

**Plain English:** when the trade prohibition clears, the entry order is immediately submitted at the current bar close, and the machine transfers to the active position state.

#### long_09_YELLOW (Initial Active State)

The initial active position state. Classifies velocity each bar and routes to `long_10_GREEN` (strong) or `long_11_RED` (moderate/weak).

---

## Flag: velocity_breakout_isProhibited

| Property | Value |
|----------|-------|
| Type | bool, stored in `context` |
| Initial value | `False` (set in `LongStrategy.reset()`) |
| Set to `True` | Action of transitions 10 / 18 / 26 / 37 (all velocity bypass entries) |
| Reset to `False` | In `process_bar()` after evaluation loop, when `current_state` ∉ {State09, State10, State11} AND `bearCount_isMet == 1` |
| Purpose | Prevents consecutive velocity bypass entries before a fresh bear trend is confirmed |

---

## Cross-Reference — Active Position Management

Transitions `7.04 TRADE_ENTRY_SUBMITTED` (t_110_trade_entry_submitted) and `8.04 ENTRY_BLOCK_CLEARED` (t_120_entry_block_cleared) exit this state machine and enter `long_09_YELLOW` in the exit state machine.

See [`long_exit_state_machine_v1_2_2.md`](long_exit_state_machine_v1_2_2.md) for states 09–11 (Yellow / Green / Red).

---

## Change Log

| 2026-04-12 | v2.6.0 | 20260412_TWM_housekeeping | Task 1: Renamed all transitions to ALL_CAPS (ENTRY_WINDOW_CLOSED, BULL_SETUP_RESET, etc.); renumbered (10–120 entry, 200–262 exit); renamed states to descriptive uppercase suffixes. |

| Date | Version | Project | Change Summary |
|------|---------|---------|----------------|
| 2026-04-20 | v2.10.0 | 20260420_TWM_long_hand_calc_comp | c04 — Tighten t_100 guard: `high >= breakout_limit` (= `pending_breakout + breakout_offset`) replaces `high >= pending_breakout`. Update step-by-step breakout explanation. Aligns doc with runner v9.10.0 fix. |
| 2026-04-19 | v2.9.6 | 20260418_TWM_combine_Debug_higher_tf | c06 — clarify the State06 two-level breakout model so `pending_breakout` remains the structural trigger and `breakout_limit = pending_breakout + breakout_offset` remains the broker order baseline for t_100/t_103. |
| 2026-04-19 | v2.9.5 | 20260418_TWM_combine_Debug_higher_tf | c31 completion — sync doc windows and velocity guards to first bullshift-array bar baseline already implemented in long strategy lineage. |
| 2026-04-18 | v2.9.4 | 20260418_TWM_combine_Debug_higher_tf | c25 — Update MA_BULL_CROSS (t_70) Intra-bar Rule to enforce TF-boundary timing note: chain-OK write/reset behavior retained, with explicit bar-close-only evaluation language. |
| 2026-04-18 | v2.9.3 | 20260418_TWM_combine_Debug_higher_tf | c23 — Clarify State00 bar-close rule: t_40_session_open Intra-bar Rule now reads `bar close only (1-minute bars, regardless of strategy TF)`; long_00_IDLE description updated with 1-minute evaluation note. |
| 2026-04-18 | v2.9.2 | 20260418_TWM_combine_Debug_higher_tf | c16 — Rename transition 93 to `LWR_High_bypass [LHP]` (`t_93_lwr_high_bypass`), expand source states to 01-06, and update guard to thresholded prior closed-minute LWR upper reference (`bar_high - prior_lwr_upper_channel >= lhp_threshold_points[@ticker]`). |
| 2026-04-18 | v2.9.1 | 20260418_TWM_combine_Debug_higher_tf | c13 — Remove MA guard from BEAR_TREND_MET (t_50): guard is now `bearCount_isMet == 1` only. Indicator field updated (removed MAAC); step-by-step step 3 updated to note MA guard removal. |
| 2026-04-18 | v2.9.0 | 20260418_TWM_combine_Debug_higher_tf | Add VELOCITY_ENTRY_S04 (t_81, SM #14) in long_04_WAIT_INDICATORS — high-velocity bypass S04 → S07. |
| 2026-04-13 | v2.8.0 | 20260413_TWM_entry_optimization | Add BREAKOUT_LIMIT_ENTRY transition (103) in long_06_WAIT_BREAKOUT — progressive limit order entry with `entry_timer` stepping down `entry_offset` each increment bars via `entry_limit_config`. Both BREAKOUT_LEVEL_HIT and BREAKOUT_LIMIT_ENTRY always evaluated; only `_isActive` flag controls which fires. BREAKOUT_LEVEL_HIT priority if both active. Document `entry_timer` internal management. |
| 2026-04-12 | v2.5.2 | 20260411_TWM_1sec_debug_try_v9_trial2 | c07 — Add `velocity_breakout_isProhibited` flag: guards added to transitions 10/18/26/37; flag set True on velocity bypass entry; reset to False when not in trade and `bearCount_isMet == 1`. Added Flag section. |
| 2026-04-11 | v2.5.1 | 20260411_TWM_1sec_debug_try_v9_trial2 | t31 Action updated: document `premarket_profit_target` snapshot at TRADE_ENTRY_SUBMITTED (t_110_trade_entry_submitted). Computed as `nearest_premarket_resistance_above_entry - premarket_profit_target_offset`; stored in ctx for EXIT_PREMARKET guard. |
| 2026-04-11 | v2.5.0 | 20260411_TWM_1sec_debug_try_v9_trial2 | t10/t18/t26 Guard updated: `setup_counter == 3` → `setup_counter >= setup_counter_velocity_limit`; explanation text updated to reference timeout-relative window; Task-3: new transition 37 (VELOCITY_ENTRY_S01) added to S01 section. |
| 2026-04-10 | v2.4.0 | 20260409_TWM_1sec_debug_try_v9 | t16 Guard corrected: slow_MA source is last tfxx minute bar snapshot (`_prior_bar_slow_ma`) — was current 1 sec bar. Intra-bar Rule updated: `prior minute-bar snapshot (fixed per-bar)`. Explanation step 1 & 2 rewritten to match. |
| 2026-04-07 | v2.3.2 | 20260407_TWM_1sec_strategyLogic_Debug | 7 bug fixes: t6 guard rm MA==1; t10/18/26 'days'→'bars' + slice fix (current_bar_no-1); t16 slow_MA prior→current 1 sec bar; t20/27 guard fix (tf_2_5_entryFlag==1); State06 cancel-on-prohibit note added; t24 deleted + t25 renamed to BREAKOUT_LEVEL_HIT; t31 Action updated for limit-order-filled path |
| 2026-04-07 | v2.3.1 | 20260407_TWM_1sec_strategyLogic_Debug | Fix anchor blank-line rendering: insert blank line after each <a id> anchor (19 locations); individual transitions now render as structured sub-bullets |
| 2026-04-07 09:00 | v2.3.0 | 20260407_TWM_1sec_strategyLogic_Debug | Reformat shared transition definitions ([SE], [BTB], [ST]) to canonical Transition Definition table format; verify all 22 transitions |
| 2026-03-26 | v2.2.1 | 20260319_refactor_strategy | Fix transition 17 MIDBAR_RETEST_TOUCHED guard: `bar_low < median(prior bar_High_Low)` (was `median(confirmation_High_Low)`). |
| 2026-03-26 | v2.2.0 | 20260319_refactor_strategy | Reformat transitions to bullet layout; add Intra-bar Evaluation Model section + per-transition Intra-bar Rule; add "new highs" guard (`bar_high > max(high[...])`) to t_71_velocity_entry_s03, t_92_velocity_entry_s05, t_101_velocity_entry_s06; add intra-bar timing to shared transitions. |
| 2026-03-26 | v2.1.1 | 20260319_refactor_strategy | Fix t_71_velocity_entry_s03 VELOCITY_ENTRY_S03 guard: replace `combined_tf == 1` / 4-of-4 entry chain with `setup_counter == 3`. Guard now requires `ma_velocity > 1.3 AND setup_counter == 3`. |
| 2026-03-25 | v2.1.0 | 20260319_refactor_strategy | Add Action: reset `setup_counter_start_bar = None` to [BTB], [ST], t_110_trade_entry_submitted, t_120_entry_block_cleared. Fixes counter growing past 4 and persisting into subsequent cycles and active trades. |
| 2026-03-24 | v2.0.0 | 20260319_refactor_strategy | Split from `long_entry_state_machine_v1_2_15.md` — entry states 00–08 extracted; exit states 09–11 moved to `long_exit_state_machine_v1_0_0.md`. Prior history in archived v1.2.15. |
