ForexBestRobots.comCompare EAs →
EN

Forex scalping · Forex strategy

Limit-Order Forex Scalping Strategy: First Retest, Timed Cancellation and Execution Races

A complete M1 limit-order scalping model: a fixed range, first retest, two-minute expiry, net-risk sizing and explicit cancellation-versus-fill rules.

One fixed M1 range, one first-retest limit order and a finite waiting window. Fictional observations and supplied reports; no live orders.
One fixed M1 range, one first-retest limit order and a finite waiting window. Fictional observations and supplied reports; no live orders.

A limit price does not turn a chart touch into a confirmed trade. This educational M1 strategy fixes one range, allows only the next breakout close and places one pending order for the first return. The order has a finite lifetime, while actual account state comes from verified broker reports. The examples distinguish a Bid-only touch, an unfilled first retest, confirmed expiry and a fill that races a cancellation.

1. Define a complete first-retest hypothesis

This strategy studies a first return after a small completed range and its immediate breakout. Its main question is execution: whether a pending order was accepted, filled, expired or cancelled. That differs from a market entry after two pullback legs or a failed-breakout re-entry. No EMA, RSI, SAR, ADX, ATR or future-confirmed swing is part of this model.

This is a reproducible educational specification, not an installable EA or a validated live system. The candle counts, distances and time limits are declared hypotheses. All paired quotes and broker reports are invented. A finite waiting intention does not guarantee that the account becomes flat at that exact instant.

2. Fix the contract, UTC clock and account guard

Use completed EURUSD M1 Bid OHLC with pip=0.0001; point=tick=0.00001; contract=EUR100,000/lot; pip_value=$10/lot in a USD account. All formation-bar openings and closes, plus placement, must satisfy 09:00<=UTC<12:00. Before searching, verify account-wide flatness: no position, pending order, other exposure or unresolved request. Require known contract, margin and support for attached initial protection and server expiry.

Use a verified mapping between UTC and the broker's server clock, including any offset change. The fixtures explicitly assume server_UTC_offset=0; known_event_list=[]. A predeclared known event blocks placement during [event−15 min,event+15 min]; this interval is an assumed research policy. Unknown clock, calendar or data blocks a new order. An existing pending order or unresolved response continues to guard the account.

The main fictional cycle freezes five M1 bars, confirms only the next breakout, and then distinguishes pending, supplied fill and fixed exits.
The main fictional cycle freezes five M1 bars, confirms only the next breakout, and then distinguishes pending, supplied fill and fixed exits. On small screens, scroll the chart horizontally to keep labels readable.

3. Freeze the first disjoint five-bar range

After a verified release, take the first five consecutive actually completed M1 intervals whose openings are at or after that release. Freeze H=max(High1..High5); L=min(Low1..Low5); 6<=(H−L)/pip<=10. Consume that block before testing its width. Do not slide an already consumed block to find a better range; missing intervals or an invalid block require a fresh start after the failure is observed.

The sixth bar is the only breakout slot B. In the main fixture the range covers 09:00–09:05 UTC; H=1.20080; L=1.20000; width=8 pip. These are already known extrema, not later pivots. A clock boundary alone does not prove completion: verify the interval when the terminal receives the next bar's data. After rejection, verified exit, hold release or restored data, clear the old range and require wholly new bar openings.

4. Allow only the immediately next breakout close

For BUY require Close(B)>Open(B); 0.5<=(Close(B)−H)/pip<=4.0. SELL mirrors this with Close(B)<Open(B); 0.5<=(L−Close(B))/pip<=4.0. B is exactly the next interval; do not wait for a later close. Equality at the range edge, a doji, an opposite body or an excessive distance consumes this cycle without an order.

The main BUY has B=k5; close_time=09:06 UTC; Close=1.20110; distance=3.0 pip. A separate case closes at 1.20080=H and fails. Its next candle closes at 1.20110, but cannot replace B. A genuinely new range can later create a different cycle; it cannot rescue the earlier one retrospectively.

The same frozen range has one immediate breakout slot. The accepted close and the failed equality case share the same price scale; a later candle cannot replace B.
The same frozen range has one immediate breakout slot. The accepted close and the failed equality case share the same price scale; a later candle cannot replace B. On small screens, scroll the chart horizontally to keep labels readable.
UTC timeRoleOpenHighLowClose
09:01 UTCR11.200201.200451.200001.20035
09:02 UTCR21.200351.200701.200251.20060
09:03 UTCR31.200601.200801.200401.20050
09:04 UTCR41.200501.200651.200201.20030
09:05 UTCR51.200301.200751.200251.20070
09:06 UTCB1.200701.201201.200651.20110

5. Set a pending price and frozen protection

At the qualifying B close choose P_buy=H+0.1 pip; P_sell=L−0.1 pip. BUY fixes S_bid=P_buy−3.5 pip; T_bid=P_buy+8.0 pip; SELL fixes S_ask=P_sell+3.5 pip; T_ask=P_sell−8.0 pip. All prices must align to the declared tick. The offsets are explicit model assumptions; they are not optimised distances or reconstructed historical Ask candles.

The main BUY is P=1.20081; S_bid=1.20046; T_bid=1.20161. SELL is P=1.19919; S_ask=1.19954; T_ask=1.19839. Leave these absolute levels unchanged after placement or fill. There is no trailing, break-even move, averaging, partial exit, opposite position or market-order fallback. If the broker cannot support both initial exits and the required expiry, skip this event.

6. Consume one first post-breakout quote

Inspect only the first pair received after B's scheduled close, also verifying that B is actually complete. Require arrival<=B_close+1.000 s; 0<=quote_age<=250 ms; 0<=spread<=0.6 pip. The pair must be positive, noncrossed and tick-aligned. Require Ask>P_buy for BUY; Bid<P_sell for SELL: the proper-side first return must not already have passed. Recheck the UTC window, flatness, context, current broker distances, volume, available margin, clock and accepted protection/expiry support.

The main pair is 09:06:00.100 quote; 09:06:00.120 arrival; Bid/Ask=1.20110/1.20116. If it passes every gate, allow one placement request with the frozen levels and expiry. A bad, stale or expired first pair consumes permission; do not substitute a later pair. A local zero stop-level reading does not promise acceptance. The terminal's slippage argument does not guarantee the price of a pending execution.

The first post-B pairs remain beyond the pending prices on the correct side: Ask above Buy Limit and Bid below Sell Limit. Acceptance and execution remain separate.
The first post-B pairs remain beyond the pending prices on the correct side: Ask above Buy Limit and Bid below Sell Limit. Acceptance and execution remain separate. On small screens, scroll the chart horizontally to keep labels readable.

7. Keep the complete SELL price-side mirror

SELL freezes the lower range edge, requires the immediate bearish close below it, and places Sell Limit below that edge while current Bid remains below P. Its first proper-side return is Bid>=P_sell; BUY uses Ask<=P_buy. On confirmation of a fill, BUY exits are tested on Bid and SELL exits on Ask. Bid OHLC alone cannot reveal past Ask touches or fill priority.

The SELL example fills at 1.19919. A later pair Bid/Ask=1.19948/1.19954 reaches the Ask stop although Bid remains below it. The supplied worse exit is Ask=1.19964; net=−$28.56. This exceeds the planned budget. The report, not a convenient chart price, determines the illustrated cash result; chosen Ask triggers from Bid geometry are not historical Ask OHLC.

8. Separate waiting expiry from confirmed flatness

The pending-order deadline is D_wait=min(B_close+120 s,12:00 UTC). Request that explicit server expiry using the verified UTC-to-server conversion, and verify it in the acceptance report. Also withdraw the waiting intention at D_wait through a connected, calibrated timer. A deadline or delete request does not prove that no fill occurred just before it. Reconcile the ticket, positions and history before releasing the guard.

In the main cycle B_close=09:06; D_wait=09:08 UTC. The late-retest fixture supplies server_expired=09:08:00.000; verified_flat_observed=09:08:00.060; its first Ask return is 09:08:00.100. No replacement is allowed. Unknown or unsupported expiry blocks placement. A definite expiry-denied response error=147 ends this cycle; never remove the expiry and retry the same event.

The waiting window ends at the stated server expiry. A confirmed no-fill report precedes the later first Ask return; no replacement order is created.
The waiting window ends at the stated server expiry. A confirmed no-fill report precedes the later first Ask return; no replacement order is created. On small screens, scroll the chart horizontally to keep labels readable.

9. Size from net room, with P as a planning price

The plan uses P, not an assumed fill reconstructed from a touch. With c=0.3 exit reserve+0.6 linear round-trip commission=0.9 pip, BUY has L=(P−S_bid)/pip+c; W=(T_bid−P)/pip−c; SELL has L=(S_ask−P)/pip+c; W=(P−T_ask)/pip−c. Require positive L and W and W/L>=1.50. Proper entry and exit sides already incorporate spread; do not add it twice. No financing or other fees are assumed.

Use equity=$10,000; risk_fraction=0.25%; budget=$25; lot_min=lot_step=0.01; lot_max=1.00 and lots=floor_step(25/(L×10),0.01). The main plan gives L=4.4; W=7.1; W/L=1.6136364; lots=0.56; planned_loss=$24.64; planned_net_target=$39.76. Reject incompatible volume or margin. P is a planning assumption, not a promised fill, and smaller volume cannot fix an inadequate linear net ratio. Gaps or other execution terms can exceed the planned budget.

ObservationPending priceStopTargetLoss, pipsNet target, pipsNet W/LPlan lotsPlanned loss, USDPlanned net target, USD
BUY1.200811.200461.201614.47.11.61363640.5624.6439.76
SELL1.199191.199541.198394.47.11.61363640.5624.6439.76
New independent setup / BUY1.201311.200961.202114.47.11.61363640.5624.6439.76

10. Distinguish a Bid touch, a proper retest and a fill

For BUY, the pair 09:06:30.000; Bid/Ask=1.20081/1.20087 touches P only on Bid. The actual Ask return is 09:06:40.000; Bid/Ask=1.20075/1.20081. These are distinct paired observations. In the main fixture the supplied fill at P is known at 09:06:40.010, before the return quote is received at 09:06:40.020; the position is therefore managed as filled, without a delete request.

Reconcile available reports before acting on each observation. If the first proper-side touch arrives while the latest verified state is still pending, withdraw this event and request cancellation once; do not leave it waiting for a second touch. The unfilled fixture requests deletion at 09:06:40.020 and supplies confirmed cancellation plus flatness at 09:06:40.080. If a return occurs before placement acknowledgement, record withdrawal intent and reconcile first; cancel once only when a pending ticket is known. A later confirmed fill after withdrawal needs the emergency rule below.

Bid reaches the Buy Limit price first while Ask remains above it. The later Ask equality is the first proper-side return; a touch alone still does not establish a fill.
Bid reaches the Buy Limit price first while Ask remains above it. The later Ask equality is the first proper-side return; a touch alone still does not establish a fill. On small screens, scroll the chart horizontally to keep labels readable.
UTC timeBid / AskPending priceStatus
09:06:30.000 UTC1.20081 / 1.200871.20081Bid-only touch
09:06:40.000 UTC1.20075 / 1.200811.20081Ask return

11. Cancel an invalidated pending idea once

While the order is known pending, withdraw at expiry, unavailable data/calendar, the declared news hold, an invalid pair, or spread>0.8 pip. Also withdraw if the proper exit-side quote reaches the target before a fill, or if an actually observed completed M1 bar closes back through the range edge: Close<=H for BUY; Close>=L for SELL. These are declared cancellation policies, not promises that a request can beat the server's next execution.

The invalidation case has k6 Close=1.20078<H=1.20080, observed after the next interval begins. It requests cancellation at 09:07:00.120 and supplies verified flatness at 09:07:00.180. A later proper retest at 09:07:20.000 creates no new order. Send at most one cancellation request for a known ticket. A refusal, freeze restriction, connection failure or timeout retains the guard; reconcile instead of repeatedly deleting, replacing or widening the order.

An unfilled first retest and a later closed-bar invalidation are different withdrawal reasons. Confirmed cancellation consumes each event before any later return.
An unfilled first retest and a later closed-bar invalidation are different withdrawal reasons. Confirmed cancellation consumes each event before any later return. On small screens, scroll the chart horizontally to keep labels readable.

12. Handle a fill that races the cancellation

In the race fixture a wide quote causes a delete request at 09:06:30.020. The server then fills at 09:06:30.030; P=1.20081, observed at 09:06:30.040. The attempted deletion has not erased this position. The refusal is observed at 09:06:30.080. Broker freeze rules and message timing can prevent the intended cancellation; only the supplied report establishes the state in this example.

A fill confirmed after withdrawal intent keeps its attached protection and permits one emergency close on the first reliable proper-side quote after confirmation. Here that request is 09:06:30.050, with supplied exit Bid=1.20074; net=−$7.28. Keep the guard until verified closure; an uncertain close response stays unresolved. Unexpected missing initial protection uses the same emergency handling. Never move the frozen levels to force acceptance, and never treat cancellation intent as a zero-result trade.

The cancellation request precedes a server fill. Known execution triggers one protected emergency close; the later delete refusal cannot erase that fill.
The cancellation request precedes a server fill. Known execution triggers one protected emergency close; the later delete refusal cannot erase that fill. On small screens, scroll the chart horizontally to keep labels readable.

13. Manage a normally filled position to a fixed time cap

After an accepted, normally filled first retest, keep the original protection and use D_position=min(B_close+10 min,12:00 UTC). This is anchored to B, not to a later fill or to the waiting expiry. If no protective exit has occurred, send one close request on the first reliable available proper-side quote at or after that deadline. Protection takes priority on the same quote and remains active while a close answer is pending.

The time-exit fixture uses D_position=09:16 UTC; first_quote=09:16:00.100; arrival=09:16:00.120. Its supplied BUY exit is Bid=1.20076; net=−$6.16. No quote at the deadline does not mean flatness, and a stale last quote is not a boundary fill. Verify actual account state after closure. A close timeout does not permit another position or a second close request based only on assumption.

14. Keep unknown replies unknown and restart from fresh bars

Separate placement_permission=B_close+1 s; pending_expiry=B_close+120 s; ack_timeout=request_time+2 s. A missing placement answer leaves acceptance and execution unknown. A missing cancellation answer leaves the pending/filled status unresolved. A later reference price reaching the target proves neither a fill nor a profit. Keep fill, exit and P&L blank until authoritative evidence resolves them; never retry the same event.

After a definite rejection or confirmed flatness, clear the old setup. In the independent restart fixture, failed B is observed at 09:06:00.120; only new openings from 09:07 form the next five-bar range. Its own B=k12; close=09:13; P=1.20131; S_bid=1.20096; T_bid=1.20211 produces one request, definitively rejected with error=130. The old failed B and its later attractive candle remain rejected. Uncertain account state cannot release a fresh search merely because enough minutes passed.

The failed old B stays rejected. Five wholly new range bars and their own B create one independent request, which the supplied server report rejects.
The failed old B stays rejected. Five wholly new range bars and their own B create one independent request, which the supplied server report rejects. On small screens, scroll the chart horizontally to keep labels readable.

15. Reproduce the fictional observations and supplied outcomes

The downloads contain 14 independent cases; 24 closed bars/case; 336 Bid bars; 15 declared formation windows; 1,375 paired quotes; 1,419 ledger rows. Each fixture observes one declared cycle, except the restart fixture with two. Later quotes describe that cycle's context, not a new exhaustive search. The ledger separates 12 simulated placements; 4 cancel requests; 2 close requests; 4 supplied fills; 0 live orders. Quote timestamps and receipt timestamps are separate; a next-forming quote confirms the final closed interval without adding another closed bar.

The invented feed is piecewise constant between its listed updates. Its pairs reproduce the exported Bid OHLC; they do not recover a historical Ask path, queue or execution priority. Supplied closed results after the stated commission are target +$41.44; gap stop −$28.56; time exit −$6.16; cancellation race −$7.28. No-fill and unresolved cases have blank execution results. Recompute the complete declared windows, first paired touches, supplied state transitions, volume and cash outcomes; these four closed examples are not performance statistics.

Download fictional M1 Bid observations (CSV)

Download declared formation windows and outcomes (CSV)

Download paired quotes, requests and supplied reports (CSV)

StatusPlacement requestsReported fillReported exitFictional net P&L, USD
CLOSED_TARGET11.200811.20161+41.44 USD
CLOSED_STOP11.199191.19964-28.56 USD
CLOSED_TIME11.200811.20076-6.16 USD
CLOSED_CANCEL_RACE11.200811.20074-7.28 USD
CANCELLED_NO_FILL1———
PLACEMENT_UNCERTAIN1———
CANCELLATION_UNCERTAIN1———

16. Test the complete protocol on unseen chronological data

Freeze the range definition, breakout slot, price sides, costs, deadlines and cancellation rules before research. Retain every eligible window and failed first pair, not only the fills. Reliable paired quotes are needed to distinguish Bid-only touches from an Ask return. Real acceptance, rejection, cancellation and execution evidence is needed to measure order outcomes; OHLC cannot provide a pending-order fill model by itself.

Evaluate news holds, spread changes, missed quotes, server expiry, freeze restrictions, delayed replies and race fills under the same account assumptions. Record any change to the eligible event calendar when altering a rule. Use unseen chronological periods and realistic broker terms. The goal is a bounded, testable first-retest hypothesis; the invented mechanics do not establish an edge or live suitability.

Frequently asked questions

Does a Bid candle touching P prove that Buy Limit filled?

No. Buy Limit uses Ask for its proper-side return, while the normal chart contains Bid. Even an Ask touch is an observation; actual execution requires a broker report.

Can I replace an expired order or chase the return with a market order?

No. This model permits one placement for this first-return cycle. Confirm expiry or cancellation and account-wide flatness, then require a completely new range and its own immediate breakout.

Should I remove the expiry if the server returns error 147?

No. Server expiry is part of the defined model. A definite expiry-denied response consumes this cycle; unsupported or unknown expiry blocks placement.

Does sending a cancellation mean that the account is flat?

No. A fill can race the request, and freeze restrictions or delayed answers can prevent deletion. Verify the ticket, positions and history. A confirmed fill after withdrawal uses the protected emergency-close rule.

What does an unknown placement or cancellation response mean?

It means the order state is unresolved. Retain the account guard and leave execution results blank. A timeout or later target quote does not prove rejection, cancellation or profit, and does not license another order.

Do these examples prove that limit-order scalping is profitable?

No. They are invented paired observations and supplied reports used to audit mechanics. Four closed cash outcomes cannot establish a win rate, expectancy or a robust trading advantage.

Sources and research notes

Official references document order sides, pending-order expiry, deletion and broker restrictions. The range, thresholds, deadlines and fictional reports here are teaching assumptions. They do not establish optimal settings, historical execution or profitability. This specification does not call a trading API.

Educational limit-order specification. Invented paired quotes and supplied reports; no live orders, historical backtest or measured profitability.