End-to-End Flow
1
Select ticker and timeframe
Only configured ticker/timeframe pairs build bars and run strategy checks.
2
Build completed bars
Live trade ticks update OHLC, volume, bar VWAP, and session VWAP.
3
Choose Bar 1 and Bar 2
The latest two completed, consecutive bars become the candidate pair.
4
Apply setup rules
Momentum, VWAP, inside-bar, range, volume, and midpoint checks must all pass.
5
Create trade levels
Entry trigger, stop, target, quantity, and risk are calculated before Bar 3 begins.
6
Watch Bar 3 ticks
Enter on trigger, reject on invalidation, or expire at the exact Bar 3 boundary.
1. Ticker and Timeframe Selection
Selected timeframe
- Each ticker may have zero, one, or several selected timeframes.
- The strategy independently builds and evaluates only the timeframes selected for that ticker.
- A ticker with no selected timeframe does not build bars and does not run the three-bar strategy.
Strategy direction
- Long-list tickers run only the long setup test.
- Short-list tickers run only the short setup test.
- A ticker in both lists can pass either direction, but only one active Bar 3 watch may own that ticker.
2. How Each Bar Is Built
- The tick timestamp is converted to New York time.
- The timestamp is floored to the timeframe boundary. The first tick in that bucket sets Open.
- Each later tick updates High, Low, Close, volume, price-volume, and session VWAP.
- The first tick in a later bucket finalizes the previous bar. Partial bars are never checked.
- Only completed bars are sent to the two-bar detector. An unfinished current bar is never evaluated.
Open = first tick price · High = maximum tick price · Low = minimum tick price · Close = latest tick price · Volume = sum of tick sizes
Bar VWAP = Σ(price × tick size) ÷ Σ(tick size)
Session VWAP = cumulative Σ(price × tick size) ÷ cumulative Σ(tick size), beginning when collection starts or is restored
Average bar volume = mean volume of completed bars for that ticker and timeframe, including the newly finalized bar
Market-open alignment: every timeframe is anchored to 09:30:00 New York time. For example, 2m produces 09:30–09:32 and 09:32–09:34; 4m produces 09:30–09:34 and 09:34–09:38.
Bar finalization: a bar closes when the first tick belonging to a later time bucket arrives.
3. Selecting Bar 1 and Bar 2
The detector reads the latest two completed bars for the same ticker and timeframe. They are accepted only when:
Bar 2 start time − Bar 1 start time = exactly one timeframe
- If either bar is missing, no setup check runs.
- If there is a time gap, the pair is rejected.
- Each Bar 2 is checked only once per ticker/timeframe.
4. Bar 1 and Bar 2 Rules
Long setup
- Bar 1 must be green:
close > open. - Bar 1 range must meet the timeframe expansion threshold.
- Bar 1 close must be at or above session VWAP.
- Bar 2 must remain inside Bar 1, with the configured tolerance.
- Bar 2 range must not exceed the configured fraction of Bar 1 range.
- Bar 2 volume must not exceed average bar volume × volume ratio.
- Bar 2 low must remain at or above the midpoint of Bar 1.
Short setup
- Bar 1 must be red:
close < open. - Bar 1 range must meet the timeframe expansion threshold.
- Bar 1 close must be at or below session VWAP.
- Bar 2 must remain inside Bar 1, with the configured tolerance.
- Bar 2 range must not exceed the configured fraction of Bar 1 range.
- Bar 2 volume must not exceed average bar volume × volume ratio.
- Bar 2 high must remain at or below the midpoint of Bar 1.
Bar 1 expansion passes when (high₁ − low₁) ≥ bar1_range × high₁
Inside limits: high₂ ≤ high₁ × (1 + inside_tol), and low₂ ≥ low₁ × (1 − inside_tol)
Bar 2 size: range₂ ≤ max_bar2_range_ratio × range₁
Volume pause: volume₂ ≤ avg_bar_volume₂ × volume_ratio
Bar 1 midpoint = low₁ + 0.5 × range₁
Implementation note:
daily_avg_vwap is loaded into the check function but is not currently used as a pass/fail condition. The actual VWAP rule uses session VWAP.Current Timeframe Parameters
| Timeframe | bar1_range | inside_tol | max_bar2_range_ratio | volume_ratio |
|---|---|---|---|---|
| Loading parameters... | ||||
5. Trade-Level Decision
Long levels
Entry trigger = max(Bar 1 high, Bar 2 high)
Stop loss = Bar 2 low × 0.992
Target = entry trigger + risk multiple × risk per share
Short levels
Entry trigger = min(Bar 1 low, Bar 2 low)
Stop loss = Bar 2 high × 1.008
Target = entry trigger − risk multiple × risk per share
Risk per share = |entry trigger − stop loss|
Quantity = max(1, floor(current risk dollars ÷ risk per share))
Loading trade parameters...
Loading trade-level parameters...
6. Bar 3 Live-Tick Watch
- Signals are processed from shortest timeframe to longest.
- If the ticker already has an active Bar 3 watch, every later signal for that ticker is rejected. Signals are not queued.
- The watch ends at
Bar 2 end time + one timeframe, which is the exact end of Bar 3. - Long enters when a live tick is at or above the entry trigger.
- Short enters when a live tick is at or below the entry trigger.
- Long invalidates if a tick falls below
Bar 2 low × (1 − invalidation tolerance). - Short invalidates if a tick rises above
Bar 2 high × (1 + invalidation tolerance). - If no trigger occurs before the end time, the watch expires with no entry.
Loading Bar 3 parameters...
Bar 3 is not evaluated as a completed candle. It is a live-tick window whose duration equals the selected timeframe.
7. Order Finalization and Limits
- The triggering tick becomes the observed entry price.
- The internal entry trigger is rounded to cents.
- A long limit is placed above the trigger by the entry buffer; a short limit is placed below it.
- The long target is forced to at least 0.5% above the triggering tick; the short target is forced to at least 0.5% below it.
- The code builds a LIMIT OTOCO order with entry, target, and stop-loss legs.
- Execution is blocked or converted to dry run when execution switches or daily limits do not permit a new order.
Long entry limit = round(raw setup trigger × (1 + entry limit buffer), 2)
Short entry limit = round(raw setup trigger × (1 − entry limit buffer), 2)
Final long target = round(max(setup target, triggering tick × 1.005), 2)
Final short target = round(min(setup target, triggering tick × 0.995), 2)
Loading entry buffer parameter...
8. Skip Conditions and Daily Limits
- A setup is not created unless two completed consecutive bars exist.
- The same ticker/timeframe/Bar 2 combination is checked only once.
- Before starting Bar 3, the per-stock submitted-order count is checked. A ticker at its daily limit is skipped.
- A second Bar 3 signal for a ticker already being watched is rejected, even if it came from another timeframe.
- At execution, total daily trade count,
EXECUTE_ORDERS,NEW_ENTRY, and the per-stock limit are checked again. - The order count increments only after Webull returns HTTP 200 for submission.
Loading execution limits...
9. Post-Submission Stop Management
- This watch begins only after status
SUBMITTEDand only when a stop-loss client order ID exists. - The code does not wait for a confirmed entry fill before registering this post-submission price watch.
- Risk is recalculated from the submitted entry limit to the original stop loss.
- Every later tick tracks the most favorable high for long trades or low for short trades.
- When price reaches the configured favorable R trigger, the stop-loss order is changed to the configured locked-in R level.
Long stop update
Update trigger = submitted entry limit + risk per share × STOP_UPDATE_R_TRIGGER
New stop = submitted entry limit + risk per share × STOP_UPDATE_R_LOCK
Short stop update
Update trigger = submitted entry limit − risk per share × STOP_UPDATE_R_TRIGGER
New stop = submitted entry limit − risk per share × STOP_UPDATE_R_LOCK
Loading stop-update parameters...