This repo turns a popular discretionary trading setup into an automated robot for MetaTrader 5, plus all the back-test and AI plumbing to actually trust it before you go live.
The trade idea (no jargon):
Price often makes a quick fake-out move just below a recent low (or just above a recent high) to trigger people's stop-losses, then snaps back in the other direction. If you can spot that fake-out as it happens — by recognising a candlestick that has a long thin tail in the direction of the fake-out (a hammer below, a shooting star above) — you have a high-probability, short-term reversal trade.
The robot in this repo:
- Watches every new bar on your chart for that exact pattern.
- Enters at the close of the fake-out bar.
- Stops out 1 pip past the tip of the wick (so the trade is wrong if price keeps going).
- Takes profit at either 1× or 2× the risk distance — your choice (this is the "1:1 or 1:2 RR" the issue asked for).
- Sizes the position so a stop-out only loses 1% of your account, regardless of how wide the stop is.
- Refuses to trade if the broader market regime says the trade direction is fighting the trend (this part is optional and uses ruflo's AI).
What you get in this repo:
| File | Plain-English purpose |
|---|---|
ea/HammerStarSweep.mq5 |
The MetaTrader 5 robot. Drag it onto a chart and it trades for you. |
bridge/strategy.mjs |
The same trading rules written in JavaScript so you can back-test them and prove they work before risking money. |
bridge/backtest.mjs |
A command-line back-tester. Feed it historical price data, see how the strategy would have performed. |
bridge/signal-bridge.mjs |
Optional: lets the smarter ruflo AI brain run alongside MT5, only sending trades that pass an extra "is this a sane trade right now?" check. |
bridge/ruflo-integration.mjs |
The glue between this strategy and ruflo's memory + neural-trader + learning systems. Every trade gets remembered so the system gets smarter over time. |
bridge/*.test.mjs |
26 automated tests that prove the strategy logic is correct. Run these first. |
Two ways to run it:
- Just the robot — Drop the
.mq5file into MetaTrader, compile it, attach it to a chart. No Node, no ruflo, no internet needed. The trading logic is fully self-contained. - Robot + ruflo AI — Same robot, but a Node process runs alongside it that (a) checks the current market regime via
neural-traderbefore letting any trade through, (b) saves every signal and back-test to ruflo's vector database for cross-session learning, and (c) feeds the win/loss outcomes back into ruflo's SONA neural network so future setups get better-quality entries.
What this is NOT:
- ❌ Not a "set and forget money printer." Fixed-RR strategies have losing streaks. You need to back-test on your own data and demo-trade for at least 2 weeks.
- ❌ Not financial advice. This is a reference implementation for a well-known technical setup. Trade your own account at your own risk.
- ❌ Not a black box. Every rule is in plain code you can read, change, and verify. The MQL5 robot and the JavaScript back-tester apply exactly the same rules so what you back-test is what you trade.
Built for issue #1720. Reference implementation, MIT-licensed, educational use.
cd v3/docs/examples/mt5-hammer-star-sweep/bridge
# 1) Validate the strategy core (zero deps, pure Node 20+)
npm test
# 2) Backtest on the bundled sample data
node backtest.mjs --csv sample-data.csv --lookback 10 --rr 2
# 3) Run as a live signal bridge that the MT5 EA consumes
node signal-bridge.mjs --csv your-broker-feed.csv \
--output ruflo_signals.json --interval 5000 --rr 2Then attach ea/HammerStarSweep.mq5 to a chart in MetaTrader 5.
The issue asked for an MT5 EA built around two well-understood ideas:
- Liquidity sweeps — price spikes through a recent swing high or low, taking out stops, then closes back inside the prior range. The "trapped" stop orders create short-term mean-reversion fuel.
- Hammer / shooting-star confirmation — the sweep bar itself is a hammer (long lower wick, body in upper portion) for longs, or a shooting star (long upper wick, body in lower portion) for shorts.
- Fixed RR exits — 1:1 or 1:2, no trailing, no break-even. Easy to reason about.
This repo gives you three artefacts that all implement the same rules:
| Artefact | Role | When you use it |
|---|---|---|
bridge/strategy.mjs |
Pure-JS strategy core | Backtesting, unit tests, signal generation |
bridge/ruflo-integration.mjs |
Ruflo memory + neural-trader + intelligence wrapper | Persist signals/backtests, regime gating, SONA learning |
ea/HammerStarSweep.mq5 |
MQL5 Expert Advisor | Direct execution inside MetaTrader 5 |
bridge/signal-bridge.mjs |
File-based bridge | Run ruflo logic in Node, execute in MT5 |
This isn't a write-up that mentions ruflo — the code calls it. With --ruflo:
memory initruns once per cwd (lazy, cached) so the AgentDB sql.js store is initialized.memory store(@claude-flow/cli) persists every emitted signal to namespacetrading-signalsand every backtest summary totrading-backtests, with 384-dim ONNX vector embeddings auto-generated.memory searchqueries prior backtests for the same symbol before running a new one — the bridge surfaces what previous runs found.neural-trader --signal scanis called viaRuflo.getRegime(symbol). Output is parsed intobull/bear/range/unknownand used to gate signals: longs are blocked in a bear regime, shorts are blocked in a bull regime.hooks post-taskrecords the backtest's expectancy verdict so SONA can learn from this trajectory across sessions.
When --ruflo is omitted, every integration call returns { ok: false, reason: 'disabled' } and the strategy core runs unchanged. There is no runtime dependency on ruflo for the pure backtest.
Two operating modes for the EA:
- Native (
InpUseBridge=false): the EA does its own pattern detection in MQL5. No external dependencies. Use this if you don't want to run a Node process alongside MT5. - Bridge (
InpUseBridge=true): the EA readsruflo_signals.jsonwritten bysignal-bridge.mjs. Use this when you want ruflo features (regime gating, neural prediction, memory persistence) on top of the bare strategy.
Both modes apply the same risk guardrails (min stop, fixed RR, 1% balance per trade).
Long entry (hammer-sweep-low):
- Identify the lowest low of the previous N bars (default
N=10). - Current bar wicks below that low —
current.low < prev_low. - Current bar closes back above that low —
current.close > prev_low. - Current bar is a hammer:
- lower wick / range ≥ 0.6
- upper wick / range ≤ 0.1
- body / range ≤ 0.4
If all four hold:
- Entry: at the close of the sweep bar
- Stop: 1 pip below the wick low
- Target: entry + (entry − stop) × RR
Short entry (star-sweep-high) is the mirror: sweep above prior swing high, close
back inside, shooting-star shape, stop above the wick.
Guardrails (apply to both directions):
- Min stop distance: 5 pips by default (rejects razor-thin wick stops that won't survive normal spread + slippage)
- Position size:
risk_amount / stop_distancewhererisk_amount = balance × 1% - One position per symbol/magic at a time — no martingale, no overlapping trades
mt5-hammer-star-sweep/
├── README.md # this file
├── bridge/
│ ├── package.json # zero deps, "test": "node --test"
│ ├── strategy.mjs # pattern detection + backtest core
│ ├── strategy.test.mjs # 14 unit + integration tests
│ ├── backtest.mjs # CLI: node backtest.mjs --csv FILE
│ ├── signal-bridge.mjs # CLI: writes ruflo_signals.json for the EA
│ └── sample-data.csv # 40-bar synthetic feed (1 hammer + 1 star)
└── ea/
└── HammerStarSweep.mq5 # MQL5 Expert Advisor (native + bridge modes)
cd bridge
npm testExpected:
# tests 14
# pass 14
# fail 0
The tests cover:
- candle classification (hammer, shooting star, doji, normal trend bar)
- sweep detection (low sweep, high sweep, no-sweep negative case)
- signal generation at both 1R and 2R, including the min-stop guardrail
- end-to-end backtest with both winning and losing outcomes
- CSV parsing
If any test fails, stop. The strategy logic is broken; do not deploy.
The included sample-data.csv is a 40-bar synthetic feed engineered to contain
exactly one bullish hammer-sweep (around bar 11) and one bearish shooting-star
sweep (around bar 31).
node backtest.mjs --csv sample-data.csv --lookback 10 --rr 2Output:
bars : 40
config : lookback=10, rr=2, minStopPips=5, pip=0.0001
trades : 1 (wins=1, losses=0)
win rate : 100.00%
expectancy : 2.000 R per trade
last 5 trades:
t=11 long hammer-sweep-low -> win entry=1.10560 stop=1.10090 target=1.11500
(At --rr 1 you'll see both setups close — try it.)
For real backtests, supply your own CSV with the header
time,open,high,low,close[,volume] exported from MetaTrader (File → Open Data Folder → MQL5/Files, then use a CSV-export utility script) or any vendor.
Acceptance criteria before going live:
- ≥ 200 trades in the test set
- expectancy > 0R per trade
- max consecutive losses < 8
- win-rate > 35% at RR=2 (≥ 60% at RR=1)
Add --ruflo --symbol EURUSD to either tool. The Node process now actually
calls the @claude-flow/cli and neural-trader CLIs.
# Backtest + auto-persist + record SONA trajectory:
npm run backtest:ruflo
# expands to:
node backtest.mjs --csv sample-data.csv --rr 2 --ruflo --symbol EURUSD --verboseWhat happens under the hood (verified end-to-end):
[ruflo] memory init # lazy, runs once per cwd
[ruflo] searchPriorBacktests EURUSD ok # surfaces prior runs from AgentDB
[ruflo] storeBacktest backtest-EURUSD-rr2-... ok
[ruflo] recordTrajectoryEnd ... win ok # hooks post-task for SONA
Confirm the entry actually persisted:
npx @claude-flow/cli@latest memory retrieve \
--key "backtest-EURUSD-rr2-$(date +%F)" \
--namespace trading-backtests
# -> JSON summary, 84 bytes, with auto 384-dim vector embeddingFor the live bridge:
npm run bridge:ruflo
# expands to:
node signal-bridge.mjs --csv sample-data.csv --output ruflo_signals.json \
--interval 5000 --ruflo --symbol EURUSD --verboseThe bridge calls neural-trader --signal scan --symbol EURUSD once per
candidate signal, classifies the output as bull / bear / range, and
blocks the signal if direction conflicts with regime:
[bridge] gated: 11-long-hammer-sweep-low (long blocked in bear regime)
Each emitted signal is also stored in AgentDB namespace trading-signals so
future ruflo sessions can recall the full signal history.
The liquidity-sweep skill in the ruflo-neural-trader plugin wraps these
steps end-to-end:
# Inside Claude Code:
/liquidity-sweep --symbol EURUSD --rr 2- Copy
ea/HammerStarSweep.mq5into MetaTrader 5'sMQL5/Experts/folder. - Open MetaEditor (F4 in MT5), open the file, press F7 to compile.
- In MT5, drag the EA onto a chart. Set inputs:
InpLookback = 10InpRR = 2.0(or 1.0)InpRiskPercent = 1.0InpMinStopPips = 5InpUseBridge = false
- Allow live trading (the smiley face must be 😊 in the top right).
- Watch the Experts tab for log lines like
BUY 0.10 @ 1.10560 sl=1.10090 tp=1.11500.
- Set up a process that writes a tailing OHLCV CSV for your symbol
(your broker probably has an export tool, or use MT5's
iCustomto stream to a file via a small helper EA). - Start the bridge:
node bridge/signal-bridge.mjs \ --csv /path/to/your/eurusd-m15.csv \ --output /path/to/MT5/Common/Files/ruflo_signals.json \ --interval 5000 --lookback 10 --rr 2
- In MT5, attach
HammerStarSweep.mq5withInpUseBridge = trueandInpBridgePath = "ruflo_signals.json". - The EA polls the file once per new bar; when a fresh signal id appears it places the order with the bridge-supplied SL/TP.
Common path for Common/Files:
- Windows:
C:\Users\<you>\AppData\Roaming\MetaQuotes\Terminal\Common\Files - macOS / Linux (under Wine):
~/.wine/drive_c/users/<you>/AppData/Roaming/MetaQuotes/Terminal/Common/Files
-
npm testis green (14/14) - Backtest on ≥ 6 months of M15 / M30 data shows positive expectancy
- EA compiles in MetaEditor without warnings
- Tested on a demo account for at least 2 weeks
- Spread on your broker for the symbol <
InpMinStopPips - Magic number is unique (default 17201) — no clashing EAs on the same account
- You understand that fixed-RR strategies have inherent drawdown periods (consecutive losses are normal, not a bug)
- Pattern false positives in strong trends — fix with regime gating (Step 3).
- Slippage on the sweep bar's close — use limit orders just inside the close
instead of market orders if your broker allows it (modify
g_trade.Buy→g_trade.BuyLimitin the EA). - News-driven sweeps — the strategy will happily trade the spike on an NFP release. Either disable the EA over high-impact news or add a calendar filter.
- Fixed RR ≠ optimal exits — this implementation matches the issue's spec.
Trailing stops or scale-out logic would change the risk profile. A future
variant lives in the
liquidity-sweepplugin skill if you want to extend it. - Bridge mode adds latency — at minimum one polling interval between bar close and order placement. Don't use sub-M5 timeframes with the bridge.
- Strategy core:
bridge/strategy.mjs - Tests:
bridge/strategy.test.mjs - Backtest CLI:
bridge/backtest.mjs - Live bridge:
bridge/signal-bridge.mjs - MT5 EA:
ea/HammerStarSweep.mq5 - Plugin skill:
plugins/ruflo-neural-trader/skills/liquidity-sweep/SKILL.md - Issue: ruvnet/ruflo#1720