Polytraders Dev Guide
internal
v3 spine Phase 1 · Shared contracts 9 demo-wired · 0 shadow-ready · 0 production-live · 100 pending · 109 total 15/33 infra tasks the plan status board
HomeBy LayerStrategy3.13 Breakout-Follower

3.13 Breakout-Follower

Strategy Alpha Strategy Trade PLANNED Spec started capital · Direct P8 · Additional strategies pending stub

Breakout-Follower is a momentum strategy that enters Polymarket binary markets when a high-confidence news event causes a price breakout beyond configurable Bollinger Band thresholds. It scales in across multiple steps and trails a stop using an ATR multiple, acting as the directional complement to Mean-Reversion Sniper.

v3 readiness

Docs27/27
donehow scored
Impl0/15
pendinghow scored
Backtest0/4
pendinghow scored
Runtime0/8
pendinghow scored

A bot is done when all four scores are. What does done mean?

1. Bot Identity

LayerStrategy  Strategy
Bot classAlpha Strategy
AuthorityTrade
StatusPLANNED
ReadinessSpec started
Runs beforeRisk guardrail pipeline
Runs afterNews materiality feed / Observation bus
Applies toPolymarket binary markets where a high-confidence news event has just landed and the price has broken out beyond the Bollinger Band threshold, indicating a sustained directional move
Default modeshadow_only
User-visibleAdvanced details only
Developer ownerPolytraders core — Strategy pod

2. Purpose

Breakout-Follower is a momentum strategy that enters Polymarket binary markets when a high-confidence news event causes a price breakout beyond configurable Bollinger Band thresholds. It scales in across multiple steps and trails a stop using an ATR multiple, acting as the directional complement to Mean-Reversion Sniper.

3. Why This Bot Matters

  • Low-confidence news signal

    Entering on weak or ambiguous news causes the trade to mean-revert rather than sustain, resulting in a loss on each scale-in step.

  • Trail stop too tight

    A trailing stop set too close to the current price gets triggered by normal volatility before the trend matures, cutting a profitable position prematurely.

  • No exit discipline on reversal

    Without an ATR-based stop, a breakout that fails can become a runaway adverse position as the market reverts toward its pre-news price.

No worked examples on this bot yet. Worked examples are optional but strongly recommended — they turn an abstract failure mode into something a developer can verify in a fixture.

4. Required Polymarket Inputs

InputSourceRequired?Use
CLOB price and depthws_marketYesDetect Bollinger Band breakout; compute entry price and available depth.
Market status (open, resolved)clob_publicYesSkip resolved or closed markets.

5. Required Internal Inputs

InputSourceRequired?Use
KillSwitch active flagKillSwitchYesAbort all intent emission if KillSwitch active.
News materiality signal (confidence, direction)internal (news feed adapter)YesGate entry on news_confidence_min; determine breakout direction.
ATR (average true range) per marketinternal (volatility model)YesCompute trailing stop distance as trail_atr_multiple * ATR.
Builder code bytes32internal configYesInjected into builder field on every signed V2 OrderIntent.

6. Parameter Guide

ParameterDefaultWarningHardWhat it controls
news_confidence_min0.80.650.5Minimum news materiality confidence score (0–1) required before the bot will consider a breakout trade.
bollinger_stdev2.01.51.0Number of standard deviations for the Bollinger Band; price must close beyond this band to trigger a breakout signal.
scale_in_steps345Number of equal-sized scale-in orders spread across the breakout move. Limits per-step size.
trail_atr_multiple1.51.00.5Trailing stop distance as a multiple of the market's ATR. Stops below this level trigger an exit OrderIntent.

7. Detailed Parameter Instructions

news_confidence_min

What it means

Minimum news materiality confidence score (0–1) required before the bot will consider a breakout trade.

Default

{ "news_confidence_min": 0.8 }

Why this default matters

0.80 ensures the news signal is high-quality before committing capital to a trend-following strategy.

Threshold logic

ConditionAction
>= 0.80Allow breakout evaluation
0.65–0.80WARN BREAKOUT_LOW_CONFIDENCE; halve scale-in size
< 0.50HARD_REJECT BREAKOUT_CONFIDENCE_BELOW_FLOOR

Developer check

if news_confidence < params.hard: return skip('BREAKOUT_CONFIDENCE_BELOW_FLOOR')

User-facing English

The news signal was not confident enough to justify a breakout trade.

bollinger_stdev

What it means

Number of standard deviations for the Bollinger Band; price must close beyond this band to trigger a breakout signal.

Default

{ "bollinger_stdev": 2.0 }

Why this default matters

2.0 standard deviations filters routine price noise and only signals genuine breakouts.

Threshold logic

ConditionAction
>= 2.0Strong breakout signal
1.5–2.0WARN BREAKOUT_WEAK_BAND; reduce size
< 1.0Reject config — too many false breakouts

Developer check

if params.bollinger_stdev < params.hard: raise ConfigError('PARAMETER_CHANGE_REQUIRES_APPROVAL')

User-facing English

The price movement did not clearly exceed the breakout threshold.

scale_in_steps

What it means

Number of equal-sized scale-in orders spread across the breakout move. Limits per-step size.

Default

{ "scale_in_steps": 3 }

Why this default matters

3 steps provides staged entry without over-committing on the initial signal.

Threshold logic

ConditionAction
<= 3 stepsStandard scale-in
> 5 stepsReject config — PARAMETER_CHANGE_REQUIRES_APPROVAL

Developer check

if params.scale_in_steps > params.hard: raise ConfigError('PARAMETER_CHANGE_REQUIRES_APPROVAL')

User-facing English

The trade is entered in equal stages to limit risk on each step.

trail_atr_multiple

What it means

Trailing stop distance as a multiple of the market's ATR. Stops below this level trigger an exit OrderIntent.

Default

{ "trail_atr_multiple": 1.5 }

Why this default matters

1.5× ATR provides a stop wide enough to survive normal volatility while protecting against trend reversals.

Threshold logic

ConditionAction
>= 1.5×Standard trail stop
1.0–1.5×WARN BREAKOUT_TIGHT_TRAIL
< 0.5×Reject config — stop too tight

Developer check

if params.trail_atr_multiple < params.hard: raise ConfigError('PARAMETER_CHANGE_REQUIRES_APPROVAL')

User-facing English

A trailing stop will exit the position if the price reverses by more than the configured amount.

8. Default Configuration

{
  "bot_id": "strat.breakout_follower",
  "version": "0.1.0",
  "mode": "shadow_only",
  "defaults": {
    "news_confidence_min": 0.8,
    "bollinger_stdev": 2.0,
    "scale_in_steps": 3,
    "trail_atr_multiple": 1.5
  },
  "locked": {
    "news_confidence_min": {
      "min": 0.5
    },
    "bollinger_stdev": {
      "min": 1.0
    },
    "scale_in_steps": {
      "max": 5
    },
    "trail_atr_multiple": {
      "min": 0.5
    }
  }
}

9. Implementation Flow

  1. Check KillSwitch; if active, emit no OrderIntents.
  2. FETCH news materiality signal; if confidence < hard (0.50), skip BREAKOUT_CONFIDENCE_BELOW_FLOOR.
  3. FETCH ws_market book; compute Bollinger Band from recent price history.
  4. IF price NOT outside bollinger_stdev bands: skip (no breakout).
  5. Determine breakout direction from news signal.
  6. Compute per-step size = max_position_pUSD / scale_in_steps.
  7. For step 1: EMIT IOC OrderIntent in breakout direction.
  8. Store entry price and current ATR in state; compute initial trail_stop = entry - trail_atr_multiple * ATR.
  9. On each subsequent tick: check if trail_stop triggered; if so, EMIT exit IOC OrderIntent.
  10. On new ticks in trend direction: update trail_stop upward (ratchet-only).
  11. EMIT DecisionReport with intent_emitted=true, reason=BREAKOUT_ENTRY or BREAKOUT_TRAIL_STOP.

10. Reference Implementation

Pseudocode is language-agnostic. FETCH = read input. EMIT = produce output. IF/THEN/ELSE = decision. Translate directly to TypeScript, Python, Go, or Rust.

FUNCTION onNewsTick(market_id, newsSignal):
  ks = FETCH internal.killswitch.status
  IF ks.active: RETURN

  // Gate on news confidence
  IF newsSignal.confidence < params.news_confidence_min_hard:  // 0.50
    EMIT DecisionReport(intent_emitted=false, reason='BREAKOUT_CONFIDENCE_BELOW_FLOOR')
    RETURN

  mkt = FETCH clob_public.GET('/markets/' + market_id)
  IF mkt.closed OR mkt.resolved: RETURN

  // Check Bollinger Band breakout
  book = FETCH ws_market.book(market_id)
  price = book.last_trade_price
  bbUpper, bbLower = computeBollingerBands(market_id, params.bollinger_stdev)
  IF price <= bbUpper AND price >= bbLower: RETURN  // No breakout

  // Size computation
  sizeMultiplier = 0.5 IF newsSignal.confidence < params.news_confidence_min_warn ELSE 1.0
  IF sizeMultiplier < 1.0: WARN('BREAKOUT_LOW_CONFIDENCE')
  stepSize = toPusdUnits(params.max_position_usd / params.scale_in_steps * sizeMultiplier)

  // Emit step 1 entry
  direction = newsSignal.direction
  EMIT OrderIntent(market=market_id, outcome=direction, side='buy', price=book.best_ask,
                   size_pUSD=stepSize, tif='IOC', builder=internalBuilderCode)

  atr = FETCH internal.volatilityModel.ATR(market_id)
  trailStop = book.last_trade_price - params.trail_atr_multiple * atr
  STORE state.position(market_id, {step:1, trail_stop:trailStop, entry_price:price})
  EMIT DecisionReport(intent_emitted=true, reason='BREAKOUT_ENTRY', step=1)

SDK calls used

  • ws_market.subscribe('book', [market_id])
  • fetchClobPublic('/markets/' + market_id)
  • internal.newsAdapter.signal(market_id)
  • internal.volatilityModel.ATR(market_id)
  • buildOrderTypedData(orderParams, {name:'CTFExchange', version:'2', chainId:137})

Complexity: O(1) per news tick per market; O(open_positions) per book tick for trail-stop evaluation

11. Wire Examples

Input — what arrives on the wire

News signal — high confidence breakoutinternal (news adapter)

{
  "market_id": "0xbf00000000000000000000000000000000000000000000000000000000000001",
  "news_confidence": 0.88,
  "direction": "YES",
  "bollinger_stdev_actual": 2.3,
  "atr": 0.03,
  "received_at_ms": 1746790800000
}

Output — what the bot emits

OrderIntent — breakout step 1 IOC buy YES

{
  "intent_id": "oi_01HBF0000001A",
  "market_id": "0xbf00000000000000000000000000000000000000000000000000000000000001",
  "outcome": "YES",
  "side": "buy",
  "price": "0.720",
  "size_pUSD": "150.00",
  "tif": "IOC",
  "builder": {
    "code": "0x706f6c7974726164657273000000000000000000000000000000000000000000",
    "fee_bps": 25
  },
  "decision": {
    "step": 1,
    "reasons": [
      "BREAKOUT_ENTRY"
    ]
  }
}

12. Decision Logic

APPROVE

news_confidence >= 0.80, price outside Bollinger Bands, market open, KillSwitch inactive.

RESHAPE_REQUIRED

Not applicable — reshaping handled by downstream Risk guardrail.

REJECT

news_confidence < 0.50; no breakout signal; market closed; KillSwitch active.

WARNING_ONLY

news_confidence 0.65–0.80 triggers warning and halved scale-in size.

13. Standard Decision Output

This bot returns a OrderIntent object. See OrderIntent schema.

{
  "intent_id": "oi_01HBF0000001A",
  "trace_id": "tr_01HBF000TR001",
  "market_id": "0xbf00000000000000000000000000000000000000000000000000000000000001",
  "outcome": "YES",
  "side": "buy",
  "price": "0.720",
  "size_pUSD": "150.00",
  "tif": "IOC",
  "post_only": false,
  "builder": {
    "code": "0x706f6c7974726164657273000000000000000000000000000000000000000000",
    "fee_bps": 25
  },
  "negrisk_aware": false,
  "decision": {
    "news_confidence": 0.88,
    "bollinger_stdev_actual": 2.3,
    "step": 1,
    "trail_stop": 0.68,
    "reasons": [
      "BREAKOUT_ENTRY"
    ]
  },
  "comment": "fees are operator-set at match time in V2 \u2014 feeRateBps is NOT on the signed order"
}

14. Reason Codes

CodeSeverityMeaningActionUser-facing message
BREAKOUT_ENTRYINFONews confidence >= min, price beyond Bollinger Band. Scale-in step 1 OrderIntent emitted.Emit IOC OrderIntent step 1.A breakout was detected and a trade was entered.
BREAKOUT_TRAIL_STOPINFOPrice reversed beyond trail_atr_multiple * ATR from peak. Exit OrderIntent emitted.Emit exit IOC OrderIntent.The trailing stop was triggered and the position was closed.
BREAKOUT_LOW_CONFIDENCEWARNNews confidence between 0.65 and 0.80; scale-in size halved.Emit at 50% size; log warning.The news signal was moderate; a reduced-size trade was placed.
BREAKOUT_CONFIDENCE_BELOW_FLOORHARD_REJECTNews confidence below 0.50 hard floor.Skip; no OrderIntent.The news signal was too weak for a breakout trade.
KILL_SWITCH_ACTIVEHARD_REJECTGlobal kill switch is active.Skip all markets; no OrderIntents emitted.Trading is currently paused.

15. Metrics & Logs

Metrics emitted

MetricTypeUnitLabelsMeaning
polytraders_strat_breakoutfollower_decisions_totalcountercountverdict, reason_codeTotal evaluation cycles by verdict and reason.
polytraders_strat_breakoutfollower_intents_emitted_totalcountercountstep, outcomeTotal OrderIntents by scale-in step and outcome.
polytraders_strat_breakoutfollower_news_confidencehistogramscoreDistribution of news confidence scores at entry.
polytraders_strat_breakoutfollower_eval_latency_mshistogrammillisecondsLatency from news signal to OrderIntent emit.

Alerts

AlertConditionSeverityRunbook
BreakoutFollowerStaleFeedrate(polytraders_strat_breakoutfollower_decisions_total{reason_code='STALE_MARKET_DATA'}[5m]) > 0.1warn#runbook-breakout-stale
BreakoutFollowerKillSwitchrate(polytraders_strat_breakoutfollower_decisions_total{reason_code='KILL_SWITCH_ACTIVE'}[1m]) > 0page#runbook-killswitch
BreakoutFollowerLowConfidencerate(polytraders_strat_breakoutfollower_decisions_total{reason_code='BREAKOUT_CONFIDENCE_BELOW_FLOOR'}[10m]) > 0.5warn#runbook-breakout-confidence

16. Developer Reporting

{
  "bot_id": "strat.breakout_follower",
  "market_id": "0xbf00000000000000000000000000000000000000000000000000000000000001",
  "news_confidence": 0.88,
  "bollinger_stdev_actual": 2.3,
  "step": 1,
  "trail_stop": 0.68,
  "intent_emitted": true,
  "reason": "BREAKOUT_ENTRY",
  "emitted_at_ms": 1746790800000
}

17. Plain-English Reporting

SituationUser-facing explanation
Breakout trade enteredA high-confidence news event caused the market to break out of its normal range. The strategy entered in the direction of the move.
Trail stop triggeredThe market reversed beyond the trailing stop level. The position was closed to protect against further loss.
News confidence too lowThe news signal was not strong enough to justify a breakout trade.

18. Failure-Mode Block

main_failure_modeFalse breakout: news signal causes a short-lived price spike that reverts before all scale-in steps execute, trapping the position at an unfavorable average entry.
false_positive_riskLow-quality news signal misidentified as high-confidence produces a breakout entry on a market that subsequently mean-reverts.
false_negative_risknews_confidence_min set too high filters out genuine breakouts on medium-confidence events.
safe_fallbackIf ws_market feed is stale or news signal unavailable, skip without emitting any OrderIntent.
required_dependenciesws_market, clob_public, internal news feed adapter, internal volatility model (ATR), KillSwitch, internal builder code

19. Failure-Injection Recipes

ScenarioHow to injectExpected behaviourRecovery
NEWS_SIGNAL_UNAVAILABLECut news feed adapter connectionAutomatic when adapter reconnects.
CONFIDENCE_BELOW_FLOORInject news signal with confidence=0.30Automatic on next high-confidence signal.
KILL_SWITCH_ONSet killswitch.active=trueAutomatic on manual KillSwitch reset.

20. State & Persistence

Cold-start recovery

On cold start, active positions re-read from exec layer; trail stop recomputed from current ATR.

21. Concurrency & Idempotency

AspectSpecification
Execution modelactor-per-market
Max in-flight25
Idempotency keyintent_id
Per-call timeout (ms)250
Backpressure strategydrop oldest tick per market_id when queue > 3
Locking / mutual exclusionper-market_id mutex for trail-stop state

22. Dependencies

Depends on (must run first)

BotWhyContract
risk.kill_switchChecked first; blocks all intent emission when active.

Emits to (downstream consumers)

External services

ServiceEndpointSLA assumedOn failure
Polymarket CLOB WebSocket (ws_market)best-effort
Internal news feed adapterinternal SLA

23. Security Surfaces

Abuse vectors considered

  • News signal injection to induce false breakout trades
  • ATR manipulation to force trail-stop triggers

Mitigations

  • News signals sourced from authenticated internal adapter only
  • ATR computed from internal volatility model using CLOB tick history
  • Trail stop ratchets only in trend direction — cannot be loosened programmatically

24. Polymarket V2 Compatibility

AspectValue
CLOB versionv2
Collateral assetpUSD
EIP-712 Exchange domain version2
Aware of builderCode fieldyes
Aware of negative-risk marketsno
Multi-chain readyno
SDK usedpy-clob-client-v2
Settlement contractCTFExchangeV2
NotesBot not yet implemented; designed against V2 schema (pUSD, builder codes, V2 EIP-712 domain). feeRateBps not present on any signed OrderIntent.

API surfaces declared

clob_publicclob_authws_marketinternal

Networks supported

polygon

25. Versioning & Migration

FieldValue
spec2.0.0
implementation0.1.0
schema2
releasedNone
planned_releaseQ3-2026

Migration history

DateFromToReasonAction taken
2026-04-28n/av2-specSpec drafted post-CLOB-V2 cutover; bot not yet implementedDesigned against V2 schema (pUSD, builder codes, V2 EIP-712 domain)

26. Acceptance Tests

Unit Tests

TestSetupExpected result
Enter step 1 when news_confidence=0.88, price beyond 2.0 Bollinger bandsbollinger_stdev=2.0, scale_in_steps=3IOC OrderIntent step=1; reason=BREAKOUT_ENTRY
Skip when news_confidence=0.40 (< hard 0.50)news_confidence=0.40No OrderIntent; reason=BREAKOUT_CONFIDENCE_BELOW_FLOOR
Trail stop triggers exit when price reverts beyond ATR multipletrail_atr_multiple=1.5, ATR=0.03Exit IOC OrderIntent emitted; reason=BREAKOUT_TRAIL_STOP

Integration Tests

TestExpected result
Full cycle: news signal → breakout → scale-in on Polygon testnetOrder has builder.code, no feeRateBps, EIP-712 domain v2

Property Tests

PropertyRequired behaviour
Trail stop only ratchets in trend direction, never loosensAlways true
feeRateBps never present on any signed OrderIntentAlways true

27. Operational Runbook

Breakout-Follower incidents are typically stale news feeds (blocking new entries) or kill-switch activations. Trail-stop triggers are expected normal behavior and do not require escalation.

On-call actions

AlertFirst stepDiagnosisMitigationEscalate to
BreakoutFollowerStaleFeed
BreakoutFollowerKillSwitch
BreakoutFollowerLowConfidence

Manual overrides

Healthcheck

GET /internal/health/breakout-follower -> 200 if News feed age < 5s; ATR model active; KillSwitch inactive.. Red: News adapter down or KillSwitch active..

28. Promotion Gates

A bot does not advance to the next readiness state until every gate below is green. Gates are observable from production data — no subjective sign-off.

Promote to Shadow

GateHow measuredThreshold
Unit tests pass including trail-stop trigger and low-confidence blockCI test run100% pass

Promote to Limited live

GateHow measuredThreshold
p99 eval latency < 250ms over 24h shadow runpolytraders_strat_breakoutfollower_eval_latency_ms histogramp99 < 250ms

Promote to General live

GateHow measuredThreshold
E2E: news signal → breakout → scale-in OrderIntent on Polygon testnet with builder.code and no feeRateBpsE2E testPass

29. Developer Checklist

Ready-to-ship score: 27/27 sections complete · 100%

RequirementStatus
Purpose defined✓ done
Required inputs listed✓ done
Parameters defined✓ done
Defaults defined✓ done
Warning thresholds defined✓ done
Hard thresholds defined✓ done
Safe fallback defined✓ done
Structured output defined✓ done
Developer log defined✓ done
Plain-English explanation✓ done
Unit tests defined✓ done
Integration tests defined✓ done
Property tests defined✓ done
Failure-mode block complete✓ done
Reference implementation pseudocode✓ done
Wire examples (input + output)✓ done
Reason codes listed✓ done
Metrics & logs defined✓ done
State & persistence defined✓ done
Concurrency & idempotency defined✓ done
Dependencies declared✓ done
Security surfaces declared✓ done
Polymarket V2 compatibility declared✓ done
Version & migration history declared✓ done
Operational runbook defined✓ done
Promotion gates defined✓ done
Failure-injection recipes defined✓ done