Strategy-gates-Pattern — Auto-Trading Rule
A detected harmonic pattern never opens a trade on its own. An enabled Strategy that matches the signal is the mandatory gate between pattern detection and trade execution in mi-casa’s auto-trading system.
The Rule
Pattern detected → no Strategy match → chart display only, no trade
Pattern detected → Strategy matches → one trade per matching Strategy
Pattern events are detected by ohlc-service and forwarded to mi-casa. The WebSocket broadcast to the frontend is strategy-gated via broadcastPatternEventToUsers.ts — a user only receives a pattern event if they have at least one enabled Strategy matching the event’s patternType, symbol, and timeframe. Strategies therefore govern both what appears on the chart and whether the auto-trade engine opens a paper trade.
Why the Gate Exists
A user may want to trade Gartley patterns on EURUSD 1h but explicitly not on GBPJPY 4h. Without a Strategy, there is no way to express that preference — the engine would have to either trade everything or nothing.
Each Strategy carries its own:
| Field | Purpose |
|---|---|
strategyType | Which harmonic pattern triggers this Strategy |
symbols | Allowlist of symbols (e.g. ['EURUSD', 'GBPUSD']) |
timeframes | Allowlist of timeframes (e.g. ['1h', '4h']) |
slMultiplier / tp1Multiplier / tp2Multiplier / tp3Multiplier | SL/TP pip-distance multipliers |
lotSize | Position sizing |
isEnabled | Master on/off switch — disabled strategies are never matched |
entryStrategy | Entry timing: emerging_prz, prz_touch, candle_close, swing_confirmation |
minSignalScore | Composite signal quality threshold (0–1); null = no filter |
minRR | Minimum R:R ratio (TP1/SL); null = no filter; applies to all strategy types |
abcdPrzEntry | ABCD only: PRZ edge for emerging_prz entries — '1.272' (near, default) or '1.618' (far) |
Multiple Strategies can match the same incoming signal — the engine opens one trade per matching Strategy, each tagged with its own strategyId.
Supported Strategy Types
All valid values for the strategyType enum are harmonic:
| Value | Description |
|---|---|
cypher | Cypher |
gartley | Gartley |
bat | Bat |
butterfly | Butterfly |
crab | Crab |
shark | Shark |
abcd | AB=CD |
The Auto-Trade Code Path
The harmonic strategy gate lives in backend/services/autoTradingEngine.ts.
Pattern Path — evaluateCandleClosePrz
Triggered by: ohlc:pattern:detected, ohlc:pattern:prz_touch
Event received
└─ strategyRepository.getEnabledForSignal(userId, patternType, symbol, timeframe)
└─ filter: entryLagCandles = 0 (D+0 immediate entry)
└─ for each matching Strategy:
├─ hasOpenStrategyTrade? → skip if true
├─ maxOpenTrades reached? → skip if true
└─ open trade with strategyId set
Pattern Display Is Strategy-Gated
Pattern events flow through broadcastPatternEventToUsers.ts, which applies the same strategy filter before sending data to each connected client:
ohlc-service detects pattern
├─ Emits event to mi-casa auto-trade engine (may or may not open a trade)
└─ Broadcasts to frontend via WebSocket (filtered per user — only sent
if the user has a matching
enabled Strategy)
Users without a matching enabled Strategy will not see the pattern on their chart. Strategies therefore govern both trade execution and chart visibility.
What Is NOT Strategy-Gated (by Design)
| Action | Why it bypasses the gate |
|---|---|
POST /api/trading/trades with entrySource: 'manual' | User-initiated — explicit intent, always allowed |
| Pending order creation | Created by the engine as a by-product of a matched Strategy with entryLagCandles > 0 |
| Pending order activation | Activation is triggered by price hitting the entry level, not a new signal |
Creating a Strategy for a Pattern
To automatically trade Gartley patterns on EURUSD and GBPUSD on the 1h and 4h timeframes:
- Create a Strategy with
strategyType: 'gartley' - Set
symbols: ['EURUSD', 'GBPUSD'] - Set
timeframes: ['1h', '4h'] - Configure
slPercent,tpPercent, andlotSize - Set
isEnabled: true
When ohlc-service next detects a Gartley on EURUSD 1h, the engine calls getEnabledForSignal, finds this Strategy, passes the dedup and cap checks, and opens one trade tagged with strategyId.
A second Strategy — say strategyType: 'gartley' for symbols: ['GBPJPY'] with isEnabled: false — will be found but skipped because it is disabled. The same Gartley signal on GBPJPY 4h with no matching Strategy produces no trade at all.