Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/deniszidbaev-cmyk/polyclaw-trading/llms.txt

Use this file to discover all available pages before exploring further.

The PolyClaw Trading engine recognizes sixteen deterministic candlestick patterns implemented in src/polyclaw_engine/patterns.py. Patterns are detected on completed candles only ("complete": true) using the 5m series for execution and evaluated against configurable thresholds sourced from EngineConfig. Each pattern is assigned a fixed strength score used to rank and tiebreak competing signals. All threshold comparisons use epsilon-guarded inclusive boundaries (EPSILON = 1e-12).
All boundary comparisons are inclusive. The engine adds EPSILON = 1e-12 to one side of every >= and <= comparison to guard against floating-point rounding at exact boundary values. These guards are unit-tested at every documented threshold.

Pattern summary table

PatternDirectionKey threshold
Bullish EngulfingYESCurrent body >= 2.00× previous body
Bearish EngulfingNOCurrent body >= 2.00× previous body
Bullish HaramiYESCurrent body <= 0.60× previous body
Bearish HaramiNOCurrent body <= 0.60× previous body
Tweezer BottomYESRelative extreme difference <= 10%
Tweezer TopNORelative extreme difference <= 10%
Morning StarYESThird candle retraces >= 60%; strong >= 70%; middle body <= 40%
Evening StarNOThird candle retraces >= 60%; strong >= 70%; middle body <= 40%
Three White SoldiersYESExactly 3; body >= 0.20× ATR; counter-wick <= 0.75× body
Three Black CrowsNOExactly 3; body >= 0.20× ATR; counter-wick <= 0.75× body
Bullish Shadow BreakoutYESLower wick >= 1.50× ATR; close location >= 65%
Bearish Shadow BreakoutNOUpper wick >= 1.50× ATR; close location <= 35% (inverse of 65%)
Bullish Order-Block SweepYESExcursion below 20-candle support >= 2%; close recovers above support
Bearish Order-Block SweepNOExcursion above 20-candle resistance >= 2%; close falls below resistance
Bullish ImpulsecontextBody >= 2.00× prior 20-candle average body (current excluded)
Bearish ImpulsecontextBody >= 2.00× prior 20-candle average body (current excluded)
POC Contextcontext|close − poc| / poc <= 1%

Pattern strength scores

Each pattern has a fixed strength score. When multiple patterns fire simultaneously, the strongest compatible pattern takes priority, and the score for the patterns confidence component is boosted by 0.05 per additional compatible pattern (clamped to [0, 1]):
pattern_score = strengths[strongest] + 0.05 * max(0, count - 1)
PatternStrength
Bullish / Bearish Engulfing0.90
Morning / Evening Star0.90
Three White Soldiers / Three Black Crows0.85
Bullish / Bearish Order-Block Sweep0.85
Bullish / Bearish Shadow Breakout0.80
Bullish / Bearish Impulse0.75
Tweezer Bottom / Top0.70
Bullish / Bearish Harami0.60

Configurable thresholds

All pattern thresholds are sourced from EngineConfig and can be overridden via environment variables. The defaults reflect the values documented in btc_strategy_engine.md and enforced by the config validator:
Env varDefaultControls
ENGULFING_BODY_MULTIPLIER2.0Minimum ratio of current body to previous body for engulfing patterns
HARAMI_BODY_MAX_RATIO0.60Maximum ratio of current body to previous body for harami patterns
TWEEZER_WICK_DIFFERENCE_PCT0.10Maximum relative difference between the two extreme wicks
STAR_MIN_RETRACE_RATIO0.60Minimum retrace ratio for morning/evening star (standard)
STAR_STRONG_RETRACE_RATIO0.70Minimum retrace ratio for a strong morning/evening star
STAR_MIDDLE_BODY_MAX_RATIO0.40Maximum middle-candle body as a fraction of the first candle’s body
THREE_CANDLE_PATTERN_LENGTH3Fixed length for three-candle patterns (not user-adjustable in practice)
THREE_CANDLE_MIN_BODY_ATR_RATIO0.20Minimum body size as a multiple of ATR14 for each soldier/crow candle
THREE_CANDLE_MAX_COUNTER_WICK_BODY_RATIO0.75Maximum counter-direction wick as a fraction of the body
SHADOW_BREAKOUT_ATR_MULTIPLIER1.5Minimum wick size as a multiple of ATR14 for shadow breakout
SHADOW_CLOSE_LOCATION_MIN0.65Minimum close-location ratio for bullish shadow breakout (must be > 0.5)
ORDER_BLOCK_SWEEP_PCT0.02Minimum excursion beyond the 20-candle support/resistance level (2%)
ORDER_BLOCK_LOOKBACK20Number of prior candles used to compute support/resistance
IMPULSE_BODY_MULTIPLIER2.0Minimum body size as a multiple of the 20-candle average body
IMPULSE_BODY_LOOKBACK20Lookback window for average body (current candle excluded)
POC_CONTEXT_DISTANCE_PCT0.01Maximum distance from POC as a fraction of POC (1%)

Detailed pattern specifications

Engulfing (Bullish / Bearish)

A two-candle reversal pattern. The current candle completely covers the prior candle’s body in both directions.
# Bullish Engulfing
previous.bearish
and current.bullish
and previous.body > EPSILON
and current.body_low  <= previous.body_low   # inclusive
and current.body_high >= previous.body_high  # inclusive
and current.body >= ENGULFING_BODY_MULTIPLIER * previous.body
The bearish version requires previous.bullish and current.bearish with the same size and coverage conditions.

Harami (Bullish / Bearish)

A two-candle inside-bar pattern. The current candle’s body fits entirely within the prior candle’s body and is at most HARAMI_BODY_MAX_RATIO times as large.
# Bullish Harami
previous.bearish
and current.close >= current.open           # doji or bullish
and previous.body > EPSILON
and current.body_low  >= previous.body_low  # inside, inclusive
and current.body_high <= previous.body_high # inside, inclusive
and current.body <= HARAMI_BODY_MAX_RATIO * previous.body
The bearish version requires previous.bullish and current.close <= current.open.
A lone harami is a blocking reason. If the only compatible candle pattern for the current direction is a single harami (strength 0.60), the engine forces a HOLD regardless of other signals.

Tweezer Bottom / Top

A two-candle pattern where both candles share nearly identical lows (bottom) or highs (top).
# Tweezer Bottom
relative_difference(previous.low, current.low) <= TWEEZER_WICK_DIFFERENCE_PCT
and previous.lower_wick + current.lower_wick > EPSILON  # at least one real lower wick
and current.bullish
and current.close_location >= 0.50

# Tweezer Top
relative_difference(previous.high, current.high) <= TWEEZER_WICK_DIFFERENCE_PCT
and previous.upper_wick + current.upper_wick > EPSILON
and current.bearish
and current.close_location <= 0.50
relative_difference(a, b) = |a - b| / max(|a|, |b|, EPSILON)

Morning / Evening Star

A three-candle reversal pattern. The middle candle must be small; the third candle must retrace a significant portion of the first candle’s body.
# Morning Star: bars = [first, middle, third]
first.bearish and third.bullish and first.body > EPSILON
retrace = (third.close - first.close) / first.body
middle.body <= STAR_MIDDLE_BODY_MAX_RATIO * first.body
retrace    >= STAR_MIN_RETRACE_RATIO
STAR_STRONG_RETRACE_RATIO (0.70) is documented for classification purposes (strong vs. standard confirmation) but the execution gate uses STAR_MIN_RETRACE_RATIO (0.60). The evening star mirrors this with first.bullish, third.bearish, and retrace = (first.close - third.close) / first.body.

Three White Soldiers / Three Black Crows

Three consecutive candles of the same direction, each closing higher (soldiers) or lower (crows) than the previous, with substantial bodies and minimal counter-direction wicks.
# Three White Soldiers
all(bar.bullish for bar in bars)
and all(bars[i].close > bars[i-1].close for i in [1, 2])
and all(
    bar.body >= THREE_CANDLE_MIN_BODY_ATR_RATIO * atr
    and bar.upper_wick <= THREE_CANDLE_MAX_COUNTER_WICK_BODY_RATIO * bar.body
    for bar in bars
)
Three Black Crows mirrors this, checking bar.bearish, bars[i].close < bars[i-1].close, and capping lower_wick instead of upper_wick.

Shadow Breakout (Bullish / Bearish)

The current candle’s wick spikes through the prior candle’s extreme, then the close recovers back inside.
# Bullish Shadow Breakout
atr > EPSILON
and current.lower_wick >= SHADOW_BREAKOUT_ATR_MULTIPLIER * atr
and current.low  <= previous.low         # spike below
and current.close > previous.low         # recovery above
and current.close_location >= SHADOW_CLOSE_LOCATION_MIN  # default 0.65

# Bearish Shadow Breakout
atr > EPSILON
and current.upper_wick >= SHADOW_BREAKOUT_ATR_MULTIPLIER * atr
and current.high >= previous.high        # spike above
and current.close < previous.high        # rejection below
and current.close_location <= 1.0 - SHADOW_CLOSE_LOCATION_MIN  # default 0.35
close_location = (close - low) / (high - low)0.0 is the session low, 1.0 is the session high.

Order-Block Sweep (Bullish / Bearish)

The current candle sweeps a key support or resistance level established over the prior ORDER_BLOCK_LOOKBACK candles, then closes back inside that level.
# Bullish Order-Block Sweep
support = min(bar.low for bar in prior[-lookback:])
depth   = (support - current.low) / support
depth >= ORDER_BLOCK_SWEEP_PCT          # default 0.02 (2%)
and current.close > support             # recovery above level

# Bearish Order-Block Sweep
resistance = max(bar.high for bar in prior[-lookback:])
depth = (current.high - resistance) / resistance
depth >= ORDER_BLOCK_SWEEP_PCT
and current.close < resistance

Impulse (Bullish / Bearish)

A single-candle momentum pattern where the current candle’s body is significantly larger than the recent average.
# Bullish Impulse
current.bullish
and average_body = mean(bar.body for bar in prior[-lookback:])  # current excluded
and average_body > EPSILON
and current.body >= IMPULSE_BODY_MULTIPLIER * average_body  # default 2.0x
Impulse patterns are labeled context direction in the summary table because they do not independently determine YES/NO outcome mapping — they amplify an existing trend signal.

POC Context

Not a candlestick pattern per se, but detected alongside patterns. If the latest close is within POC_CONTEXT_DISTANCE_PCT (default 1%) of the sample-density POC, the near_poc flag is set to True and the poc_context confidence component contributes 0.30 (weight 0.05) to the raw score.
near_poc = |close - poc| / poc <= POC_CONTEXT_DISTANCE_PCT
POC never creates a directional signal. It provides density context only.

Execution gate requirements

A compatible candle pattern is mandatory for execution. If no pattern aligns with the detected trend direction, the signal is forced to HOLD with the blocking reason "no compatible candle confirmation". A single lone harami is also insufficient — it adds the reason "only weak harami confirmation" and forces HOLD.
The following additional pattern-related conditions also force a HOLD:
  • High-strength collision — both bullish and bearish pattern lists are non-empty, and both sides have at least one pattern with strength >= 0.80. The blocking reason is "bullish and bearish high-strength pattern collision".
  • EMA-pattern conflict — the strongest incompatible pattern has a higher strength score than the strongest compatible pattern. The blocking reason is "EMA direction conflicts with the strongest candle pattern".
These rules ensure that ambiguous or contradictory pattern evidence always produces a non-executable HOLD record in runtime/manual_review.json rather than a low-confidence live order.

Build docs developers (and LLMs) love