指定
Detailed Technical Specification
1. Project Summary
Build a MetaTrader 5 Expert Advisor (EA), named "Midnight Venus
", trading XAU/USD using Smart Money Concepts: market structure shifts, order blocks, supply/demand zones, liquidity sweeps, and ICT kill zones. Priorities, in order: capital preservation → consistency → automation reliability → growth.
Internal EA name/comment string, log file prefix, and magic-number label should all reference "Midnight Venus" for identification across multiple chart instances/accounts.
No overnight positions. The EA must not hold trades open past a configurable daily cutoff time (see §5.1) — this is a hard constraint alongside the prohibited risk matrix in §7, not a soft preference.
2. Symbol & Pricing Engine
Read SYMBOL_DIGITS, SYMBOL_POINT, SYMBOL_TRADE_TICK_SIZE, and SYMBOL_TRADE_TICK_VALUE at OnInit() rather than hardcoding pip = $0.10 or $1, since brokers differ (3-digit vs 2-digit gold quoting).
Define a PipSize() helper: for 2-digit gold, 1 pip = 0.1; for 3-digit, 1 pip = 0.01. Detect automatically via SYMBOL_DIGITS rather than a fixed input, with a manual override input as fallback.
All distance-based logic (stop-loss, zone height, displacement thresholds) must be computed in price, then converted to pips only for display/logging — this avoids rounding drift across broker configurations.
Validate SYMBOL_TRADE_STOPS_LEVEL and SYMBOL_TRADE_FREEZE_LEVEL before placing orders; reject/adjust orders that violate broker minimum distance.
3. SMC Structure Detection Engine
3.1 Swing Point Identification
Use a fractal-based method: a swing high/low is confirmed when N bars on each side have lower/higher highs or lows respectively (make N an input, default 2).
Maintain a rolling array of confirmed swing highs/lows per timeframe, invalidated/replaced as new fractals form.
3.2 BOS (Break of Structure)
A bullish BOS is confirmed when candle close (not wick) exceeds the most recent confirmed swing high in an existing uptrend context. Bearish BOS is the mirror case on swing lows.
Require a minimum displacement filter: the breaking candle's body size must exceed X × ATR(14) (input-adjustable) to avoid false breaks on low-momentum candles.
3.3 CHoCH (Change of Character)
A CHoCH is a BOS that occurs against the prevailing trend direction (as tracked by an internal trend-state variable: Bullish / Bearish / Ranging), i.e., the first structural break signaling potential reversal.
Update internal trend-state only after a CHoCH is confirmed by candle close, not by wick, to reduce whipsaw.
3.4 Liquidity Sweeps
Detect a sweep as: price wicks beyond a prior swing high/low by at least Y points, then closes back inside the prior range within Z bars (both inputs). This is the pre-condition many entry setups require before a valid CHoCH/BOS is considered tradeable (i.e., "sweep then shift").
3.5 Order Blocks (OB)
Identify the last opposite-colored candle immediately preceding the displacement candle that causes a BOS/CHoCH.
OB zone = high/low (or open/close, expose as input toggle) of that identified candle.
Validity rules (all input-adjustable):
Zone invalidated after price closes fully through it (mitigation).
Optional: invalidate after being "tapped" N times without reaction.
Optional: only count OBs formed with a Fair Value Gap (FVG) immediately after them as "high-probability."
3.6 Fair Value Gaps (FVG)
Detect 3-candle imbalance: gap between candle 1's high/low and candle 3's low/high with no overlap. Store as a zone; treat as confluence, not a standalone entry trigger, unless configured otherwise.
3.7 Supply/Demand Zones
Broader than OBs: base-and-breakout pattern (consolidation range followed by strong displacement away from it). Store as zones with a decay/expiry input (max bars/age before a zone is dropped from consideration).
4. Multi-Timeframe (MTF) Bias Logic
HTF (e.g., H4/H1, both configurable) trend-state (from §3.3) sets a directional bias flag: Long-only, Short-only, or No-trade.
LTF (e.g., M15, configurable) entries are only permitted in the direction of HTF bias — this must be a hard gate, not a scoring weight, unless the user disables MTF filtering via input.
Poll HTF structure on each new HTF bar close (OnTick bar-close detection via iTime comparison), not every tick, to avoid recalculating unnecessarily.
5. Session / Kill Zone Filters
Inputs: start/end hour+minute for up to 3 named sessions (Asian, London, New York), each independently toggleable.
Convert broker server time to a reference timezone (e.g., UTC) using TimeGMTOffset() or a manual broker-GMT-offset input, since brokers vary and DST shifts differently across regions — this must not be hardcoded to server time alone.
Entries blocked outside active kill zones; optionally allow trade management (SL/TP/BE adjustments) to continue outside zones even if new entries are blocked.
5.1 No Overnight Trades (Hard Constraint)
Input: DailyFlatTime (hour+minute, reference timezone per §5's GMT-offset logic) — the point by which all positions must be closed for the day.
Input: NoNewEntriesBeforeFlat (minutes) — block new entries within this window before DailyFlatTime, so a fresh position can't open moments before forced closure.
At DailyFlatTime, force-close any open position(s) at market, regardless of current P/L or in-progress trailing/partial-TP state.
This check must run independent of the kill-zone entry filters in §5 — it is a closeout rule, not a session window, and applies every trading day (weekday) without exception.
Weekend handling: if DailyFlatTime combined with typical session end would otherwise leave a position open into Friday close/rollover, the Friday flat time should be enforced at least as strict as (or earlier than) weekday DailyFlatTime — expose a separate FridayFlatTime input if the developer anticipates broker rollover/swap timing differing from weekdays.
Log every forced flat-close distinctly from strategy-driven exits (e.g., "[Midnight Venus] EOD forced close") so backtest reports can separate the two exit types when evaluating strategy performance.
5.2 News / Volatility Spike Protection
High-impact news (NFP, CPI, FOMC rate decisions, etc.) causes spread widening and erratic wicking on gold that can blow through structural stops or trigger false SMC signals. This must be filtered, not traded through blindly.
Economic calendar filter: integrate MT5's built-in CalendarValueHistory() (Calendar API) to pull scheduled high-impact events for USD/XAU-relevant currencies. Input: impact level to filter on (High only, or High+Medium).
Blackout window: input MinutesBeforeNews / MinutesAfterNews — block new entries inside this window around any filtered event. Default suggestion: 15 min before / 15 min after, adjustable.
Existing-position handling during blackout: input toggle — either (a) tighten/widen SL to a safe structural level ahead of the event, (b) close the position ahead of the event, or (c) leave it but suspend trailing/BE logic until the window passes. Expose all three as a selectable mode rather than hardcoding one behavior.
Real-time spread/volatility circuit breaker (catches unscheduled spikes the calendar doesn't list): input MaxSpreadPoints and MaxATRMultiple — if current spread or a fast-volatility measure (e.g., 1-min ATR vs its recent average) exceeds these thresholds, suspend new entries until conditions normalize, independent of the calendar filter. This protects against flash moves, low-liquidity broker gaps, and unlisted geopolitical shocks.
Slippage guard: reject/re-evaluate order fills where actual slippage exceeds a MaxSlippagePoints input rather than accepting any fill price.
6. Risk Engine & Position Sizing
6.1 Core Formula
Code
StopDistancePoints = |EntryPrice - StopLossPrice| / SYMBOL_POINT
TickValue = SymbolInfoDouble(SYMBOL_TRADE_ TICK_VALUE)
TickSize = SymbolInfoDouble(SYMBOL_TRADE_ TICK_SIZE)
MoneyPerPoint = (TickValue / TickSize) * SYMBOL_POINT
RiskMoney = AccountBalance * (RiskPercent / 100) // or Equity/FreeMargin per input toggle
LotSize = RiskMoney / (StopDistancePoints * MoneyPerPoint)
Round LotSize down to nearest valid SYMBOL_VOLUME_STEP.
Reject trade (log + alert, do not silently resize) if computed lot < SYMBOL_VOLUME_MIN or > SYMBOL_VOLUME_MAX.
Cap max lot at a separate hard input regardless of the above formula, as a second safety layer.
6.2 Stop-Loss Placement
SL derived structurally: beyond the invalidation point of the triggering OB/zone, plus a small buffer (input, in points or ATR fraction) — never a fixed-pip SL disconnected from structure.
6.3 Daily/Weekly Drawdown Limits
Track starting balance/equity at day/week open (server time).
If floating + realized loss exceeds the daily or weekly limit input, disable new entries until the next reset period; existing positions still managed normally.
Persist this state across EA restarts (e.g., via GlobalVariable or file) so a terminal restart mid-day can't bypass the limit.
7. Explicitly Prohibited Logic (Hard Constraints)
The following must not appear anywhere in the codebase, and the developer should structure risk code so these are structurally impossible, not just "unused":
No martingale/grid multipliers on lot size after a loss.
No averaging into an existing losing position (adding volume to a position currently in drawdown).
No unbounded scaling-in without a hard maximum position count/exposure input.
No "recovery mode" that increases risk-per-trade after a losing streak.
Single risk-per-trade % must be the only lever that determines size — never trade history.
No positions carried overnight — see §5.1 for the enforced daily flat-close rule.
8. Trade Management
Partial take-profit: input array or up to 3 TP levels with % of position to close at each.
Structural trailing stop: move SL to the most recent confirmed swing point in the trade's favor (not a fixed-pip trail), recalculated on each new confirmed swing.
Break-even trigger: move SL to entry (+ small buffer) once floating R-multiple ≥ input threshold (e.g., 1R).
9. Architecture
OOP, one class per concern: CStructureEngine, CZoneManager, CRiskManager, CSessionFilter, CTradeManager, CSignalEngine (composes the others).
Entry signal generation must be decoupled from execution — CSignalEngine emits a signal struct; CTradeManager decides whether/how to act on it. This lets filters/confirmations be added without touching execution code.
All magic numbers (thresholds, buffers) as named input variables with sensible defaults and comments — no hardcoded constants inside logic functions.
10. Inputs Checklist
Category
Inputs
SMC
Fractal N, min displacement (×ATR), OB mitigation rule, FVG required (bool), zone max age
MTF
HTF timeframe, LTF timeframe, bias filter on/off
Sessions
Start/end per session ×3, GMT offset, per-session enable
Overnight Rule
DailyFlatTime, NoNewEntriesBeforeFlat (min), FridayFlatTime (optional override)
Risk
Risk % per trade, basis (Balance/Equity/Free margin), max lot cap, daily loss limit %, weekly loss limit %
Management
TP levels + %, BE trigger (R), trailing mode on/off
11. Deliverables
.mq5 source — fully commented, unencrypted.
Compiled .ex5.
Install + user guide + full parameter reference.
Change log across test iterations.
ears XAU/USD data, multiple broker spread/slippage assumptions).
Note: this spec defines trading logic and riskBefore final delivery, I require:
-
Full MQ5 source code file.
-
Compiled EX5 file.
-
Full ownership rights to the completed EA upon final payment.
-
Rights to modify, maintain, update, or hire another developer to modify the code in the future.
-
The source code must be readable, organized, and properly commented.
-
No code locking, hidden restrictions, licensing limitations, or disabled functionality after delivery.
Intellectual Property Protection
Developer agrees that:
-
The trading strategy, concepts, logic, and specifications supplied for this project are proprietary.
-
The completed EA may not be resold, redistributed, copied, leased, licensed, shared, reused, reverse-engineered for resale, or incorporated into another commercial product without my written permission.
-
Developer shall not create derivative versions of this EA based on the proprietary strategy provided.
-
All intellectual property rights relating to the completed project transfer to me upon final payment.
Testing & Acceptance Requirements
Prior to final acceptance:
-
Developer must provide a testing version of the EA.
-
I require a minimum of five (5) trading days of live demo testing under actual market conditions.
-
Any bugs, glitches, execution errors, logic flaws, or platform compatibility issues discovered during testing must be corrected.
-
Final acceptance will only occur after successful completion of the testing period.
-
A change log documenting all modifications and fixes must be provided.