Jump to content

Component:Market State Analysis

From PlusEV Wiki Page

Market State Analysis

[edit]

Purpose

[edit]

"What kind of market are we in right now?"

This component classifies current market regime using 7 detection algorithms. All 7 algorithms answer "what's happening RIGHT NOW" using recent bars.

  • Is this a railroad (strong one-sided move) or a creeper (grinding sideways)?
  • Are we in early, middle, or late phase of the trend?
  • Is there institutional activity (accumulation, fighting, breakouts)?

Trading Market Principle

[edit]

"Trade what you see, not what you think. Trading is an in-the-moment business."

  • Railroad = strong conviction, ride the wave → aggressive entries allowed
  • Creeper = grinding, no conviction → skip or reduce size
  • Two-day trend confirms direction → same direction both days = high probability
  • Institutional fight = big players battling → stay out until resolution
  • MIDDLE phase is optimal → EARLY too risky, LATE trend exhausted

Seven Detection Algorithms

[edit]

Algorithm 1: Railroad Trend

[edit]

Detects strong one-sided moves where market moves like a train on tracks.

Input:  Last 5 bars (open, close)
Output: is_railroad (bool), consistency (float)

Logic:
  1. Count bullish bars (close > open)
  2. Count bearish bars (close < open)
  3. Count strong bars (body > 0.3% of price)

  consistency = max(bullish, bearish) / 5
  is_railroad = (consistency > 80%) AND (strong_bars >= 3)

Example: 5 bars: [+1.2%, +0.8%, +0.5%, +0.9%, +0.6%] → 100% bullish, 4 strong bars → Railroad

Algorithm 2: Creeper Move

[edit]

Detects slow grinding price action with no clear direction.

Input:  Last 7 bars (high, low)
Output: is_creeper (bool), avg_range (float)

Logic:
  FOR each of last 7 bars:
      range = (high - low) / high

  avg_range = average of all ranges
  is_creeper = (avg_range < 0.5%)

Note: Uses 1-HOUR data (not 5-minute) to avoid false positives.

Algorithm 3: Volatility

[edit]

Calculates market volatility from price changes.

Input:  Close values
Output: volatility (float)

Logic:
  changes = [|close[i] - close[i-1]| / close[i-1] for each bar]
  volatility = average(changes)

Classification:
  HIGH    = volatility > 1.0%
  NORMAL  = 0.3% to 1.0%
  LOW     = volatility < 0.3%

Algorithm 4: Market State Classification

[edit]

Combines signals into overall market state.

Input:  is_railroad, is_creeper, trend_direction, volatility
Output: MarketState enum

Logic:
  IF railroad AND direction="up"    → TRENDING_UP
  IF railroad AND direction="down"  → TRENDING_DOWN
  IF creeper                        → CREEPER_MOVE
  IF volatility > 1%                → MOMENTUM_MOVE
  IF volatility < 0.3%              → NARROW_LOW_VOLUME
  ELSE                              → RANGE_BOUND

Algorithm 5: Two-Day Trend

[edit]

Checks if last 2 daily bars agree on direction.

Input:  Daily OHLC (last 2 bars)
Output: has_two_day_trend (bool), direction (str)

Logic:
  day1_bullish = close[-2] > open[-2]  // Yesterday
  day2_bullish = close[-1] > open[-1]  // Today

  IF both bullish  → True, "up"
  IF both bearish  → True, "down"
  ELSE             → False, "mixed"

Algorithm 6: Trend Phase

[edit]

Determines if trend is EARLY, MIDDLE, or LATE.

Input:  Close, MA21 (50+ bars history)
Output: TrendPhase enum

Logic:
  1. Find where price crossed MA21 (trend start)
  2. Count bars since crossover = trend_length

  IF trend_length < 10   → EARLY (trend just started, risky)
  IF trend_length > 40   → LATE (trend exhausted)
  ELSE                   → MIDDLE (optimal zone)

Algorithm 7: Institutional Behavior

[edit]

Detects signs of big player activity.

7a. Institutional Fight:

High volume (>150% average) + Narrow range (<0.5%) = Fight in progress

7b. Accumulation:

High volume bars (2+) + Price stable (<0.2% movement) = Accumulation

7c. Break of Structure (BOS):

Close breaks above swing high (bullish BOS)
Close breaks below swing low (bearish BOS)
Requires confirmation bars to avoid fakeouts

Configuration

[edit]
Parameter Value Algorithm Description
railroad_threshold 0.80 #1 80% bars same direction
railroad_analysis_bars 5 #1 Bars to analyze
strong_bar_threshold 0.003 #1 0.3% = strong bar
min_strong_bars_required 3 #1 Need 3+ strong bars
creeper_range_threshold 0.005 #2 <0.5% avg range = creeper
creeper_analysis_bars 7 #2 Bars to analyze
high_volatility_threshold 0.010 #3 >1% = high volatility
low_volatility_threshold 0.003 #3 <0.3% = low volatility
early_phase_max_length 10 #6 <10 bars = EARLY
late_phase_min_length 40 #6 >40 bars = LATE
volume_fight_multiplier 1.50 #7 150% avg = high volume
bos_confirmation_bars 1 #7c Bars to confirm BOS

Output

[edit]

MarketStateResult:

Field Type Description
market_state Enum TRENDING_UP, TRENDING_DOWN, CREEPER_MOVE, MOMENTUM_MOVE, NARROW_LOW_VOLUME, RANGE_BOUND
trend_phase Enum EARLY, MIDDLE, LATE, UNDETERMINED
trend_direction str "up", "down", "sideways"
is_railroad_trend bool Strong one-sided move detected
is_creeper_move bool Grinding sideways detected
has_two_day_trend bool Both days same direction
volatility float Calculated volatility
institutional_fight_in_progress bool Big players fighting
accumulation_detected bool Accumulation pattern
bos_detected bool Break of structure

How Setup Quality Uses This

[edit]

setup_quality_detection.py applies penalties based on market state:

Detection Impact
is_creeper_move = True -50 penalty (major)
has_two_day_trend = False -30 penalty
trend_phase != MIDDLE -25 penalty
is_railroad_trend = True +15 bonus
institutional_fight = True 0.7x multiplier (30% reduction)

Dependencies

[edit]

Input Data:

  • 1-HOUR data for creeper/railroad detection
  • DAILY data for two-day trend analysis
  • 5-MIN data as fallback

Upstream:

Downstream: