Advertisement IC Markets

News Spike Fade Scalping (Advanced, High Risk)

Discuss 1-minute to 15-minute price action setups, fading intraday momentum, key support/resistance zones, and proven short-term trading methodologies.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: News Spike Fade Scalping (Advanced, High Risk)

Post by PTScalper »

MetaTrader 4 (MQL4)

Save this as NewsFadeSpike.mq4 in your MQL4/Experts directory. It uses standard MQL4 order routing and tracking functions.

Code: Select all

//+------------------------------------------------------------------+
//|                                            NewsFadeSpike_MT4.mq4 |
//|                                  Copyright 2026, Quant Dev Lab   |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//--- Input Parameters
extern string  Separator1          = "=== Strategy Settings ===";
extern int     InpAtrPeriod        = 14;     // ATR Period
extern double  InpSpikeMultiplier  = 3.5;    // Spike Multiplier (x ATR)
extern int     InpMaxBarsToHold    = 3;      // Max Bars to Hold Position

extern string  Separator2          = "=== Risk Settings ===";
extern double  InpLotSize          = 0.10;   // Lot Size
extern int     InpStopLossPoints   = 1000;   // Stop Loss (Points)
extern int     InpTakeProfitPoints = 1500;   // Take Profit (Points)
extern int     InpMaxSpreadPoints  = 500;    // Max Allowed Spread (Points)
extern int     InpSlippage         = 50;     // Allowed Slippage (Points)
extern int     InpMagicNumber      = 102030; // Magic Number

//--- Global Variables
datetime lastBarTime = 0;

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // 1. Time-based exits run on tick
   ManageTimeExits();

   // 2. Bar-close execution check
   datetime currentBarTime = Time[0];
   if(currentBarTime == lastBarTime)
      return;

   lastBarTime = currentBarTime;

   // 3. Ensure no open position already exists
   if(HasOpenPosition())
      return;

   // 4. Spread filter
   long spread = (long)MarketInfo(Symbol(), MODE_SPREAD);
   if(spread > InpMaxSpreadPoints)
   {
      Print("Spread exceeds limit: ", spread, " points. Entry bypassed.");
      return;
   }

   // 5. Evaluate Completed Bar (Bar 1)
   double barAtr = iATR(Symbol(), 0, InpAtrPeriod, 1);
   double barOpen = Open[1];
   double barClose = Close[1];
   double bodySize = MathAbs(barClose - barOpen);
   double threshold = barAtr * InpSpikeMultiplier;

   // 6. Signal Evaluation
   // Bullish Spike -> SELL
   if(barClose > barOpen && bodySize > threshold)
   {
      double sl = (InpStopLossPoints > 0)   ? NormalizeDouble(Bid + InpStopLossPoints * Point, Digits) : 0;
      double tp = (InpTakeProfitPoints > 0) ? NormalizeDouble(Bid - InpTakeProfitPoints * Point, Digits) : 0;
      
      int ticket = OrderSend(Symbol(), OP_SELL, InpLotSize, Bid, InpSlippage, sl, tp, "Spike Fade Short", InpMagicNumber, 0, clrRed);
      if(ticket < 0)
         Print("OrderSend Sell Error: ", GetLastError());
   }
   // Bearish Spike -> BUY
   else if(barClose < barOpen && bodySize > threshold)
   {
      double sl = (InpStopLossPoints > 0)   ? NormalizeDouble(Ask - InpStopLossPoints * Point, Digits) : 0;
      double tp = (InpTakeProfitPoints > 0) ? NormalizeDouble(Ask + InpTakeProfitPoints * Point, Digits) : 0;
      
      int ticket = OrderSend(Symbol(), OP_BUY, InpLotSize, Ask, InpSlippage, sl, tp, "Spike Fade Long", InpMagicNumber, 0, clrGreen);
      if(ticket < 0)
         Print("OrderSend Buy Error: ", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Check open positions                                             |
//+------------------------------------------------------------------+
bool HasOpenPosition()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagicNumber)
            return true;
      }
   }
   return false;
}

//+------------------------------------------------------------------+
//| Manage Exits Based on Bar Duration                               |
//+------------------------------------------------------------------+
void ManageTimeExits()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagicNumber)
         {
            int barsHeld = iBarShift(Symbol(), 0, OrderOpenTime());
            if(barsHeld >= InpMaxBarsToHold)
            {
               bool closed = false;
               if(OrderType() == OP_BUY)
                  closed = OrderClose(OrderTicket(), OrderLots(), Bid, InpSlippage, clrGray);
               else if(OrderType() == OP_SELL)
                  closed = OrderClose(OrderTicket(), OrderLots(), Ask, InpSlippage, clrGray);

               if(closed)
                  Print("Closed trade #", OrderTicket(), " by time limit (Held ", barsHeld, " bars).");
            }
         }
      }
   }
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Recommended broker for automated trading & scalping IC Markets
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: News Spike Fade Scalping (Advanced, High Risk)

Post by PTScalper »

Critical Execution Differences Between Pine Script & MT4/MT5

Points vs. Pips: MT4 and MT5 use Points (the smallest fractional quote price, e.g., 0.00001 on 5-digit EURUSD). The default inputs are set in points (e.g., 1000 points = 100 pips). Adjust them according to your asset (forex vs. indices vs. crypto).

Bar Zero vs. Bar One: The EA waits for the spike bar to completely close (Bar 1) before calculating the ATR body ratio and executing at the exact open of Bar 0. This eliminates intra-bar repainting.

Slippage & Re-quotes: In live trading during high-tier news (NFP, CPI, interest rate decisions), brokers may reject market orders with Re-quote errors if InpSlippage is too low. Keep your slippage buffer realistic for the volatility window.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: News Spike Fade Scalping (Advanced, High Risk)

Post by PTScalper »

Here is the cBot implementation for cTrader (C#).

cTrader's API is excellent for this type of strategy because it handles Stop Losses and Take Profits directly in Pips natively, and its execution speed is generally very well-suited for volatile conditions.

Save this code in cTrader Automate by creating a new cBot and pasting the script.

Code: Select all

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewsFadeSpike : Robot
    {
        // =========================================================================
        // ⚠️ WARNING: This strategy fades massive volatility spikes. 
        // Highly risky in live markets due to slippage and widened spreads.
        // =========================================================================

        [Parameter("ATR Period", DefaultValue = 14, Group = "Strategy Logic")]
        public int AtrPeriod { get; set; }

        [Parameter("Spike Multiplier (x ATR)", DefaultValue = 3.5, Group = "Strategy Logic")]
        public double SpikeMultiplier { get; set; }

        [Parameter("Max Bars to Hold", DefaultValue = 3, Group = "Strategy Logic", MinValue = 1)]
        public int MaxBarsToHold { get; set; }

        [Parameter("Volume (Units)", DefaultValue = 10000, Group = "Risk Management", MinValue = 1)]
        public double VolumeInUnits { get; set; }

        [Parameter("Stop Loss (Pips)", DefaultValue = 10.0, Group = "Risk Management")]
        public double StopLossPips { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 15.0, Group = "Risk Management")]
        public double TakeProfitPips { get; set; }

        [Parameter("Max Spread (Pips)", DefaultValue = 5.0, Group = "Risk Management", Tooltip = "Aborts entry if spread is wider than this.")]
        public double MaxSpreadPips { get; set; }

        private AverageTrueRange _atr;
        private const string Label = "NewsFadeSpikeBot";

        protected override void OnStart()
        {
            // Initialize the Average True Range indicator
            _atr = Indicators.AverageTrueRange(AtrPeriod, MovingAverageType.Simple);
        }

        protected override void OnBar()
        {
            // 1. Manage Time-Based Exits first
            ManageTimeExits();

            // 2. Ensure we don't already have an open position for this bot
            var activePosition = Positions.Find(Label, SymbolName);
            if (activePosition != null)
                return;

            // 3. Spread Filter
            // Divide the raw price spread by PipSize to get the spread in Pips
            double currentSpreadPips = Symbol.Spread / Symbol.PipSize;
            if (currentSpreadPips > MaxSpreadPips)
            {
                // Un-comment the line below if you want to see how often it skips trades due to spread
                // Print("Spread too wide ({0} pips). Entry skipped.", Math.Round(currentSpreadPips, 1));
                return;
            }

            // 4. Retrieve data for the LAST COMPLETED bar
            // Bars.Count - 1 is the currently forming bar, Bars.Count - 2 is the last fully closed bar.
            int lastBarIndex = Bars.Count - 2;
            
            double barOpen = Bars.OpenPrices[lastBarIndex];
            double barClose = Bars.ClosePrices[lastBarIndex];
            double bodySize = Math.Abs(barClose - barOpen);
            
            double barAtr = _atr.Result[lastBarIndex];
            double spikeThreshold = barAtr * SpikeMultiplier;

            // 5. Spike Detection and Execution
            // Bullish Spike -> Fade with a SELL
            if (barClose > barOpen && bodySize > spikeThreshold)
            {
                ExecuteMarketOrder(TradeType.Sell, SymbolName, VolumeInUnits, Label, StopLossPips, TakeProfitPips);
                Print("Bullish Spike Detected. Entering Fade Short.");
            }
            // Bearish Spike -> Fade with a BUY
            else if (barClose < barOpen && bodySize > spikeThreshold)
            {
                ExecuteMarketOrder(TradeType.Buy, SymbolName, VolumeInUnits, Label, StopLossPips, TakeProfitPips);
                Print("Bearish Spike Detected. Entering Fade Long.");
            }
        }

        private void ManageTimeExits()
        {
            // Find all open positions managed by this specific cBot
            var positions = Positions.FindAll(Label, SymbolName);

            foreach (var position in positions)
            {
                // Calculate how many bars have passed since the entry
                int entryIndex = Bars.OpenTimes.GetIndexByTime(position.EntryTime);
                int currentBarIndex = Bars.Count - 1; 
                int barsHeld = currentBarIndex - entryIndex;

                if (barsHeld >= MaxBarsToHold)
                {
                    ClosePosition(position);
                    Print("Position {0} closed by time exit (Held for {1} bars).", position.Id, barsHeld);
                }
            }
        }
    }
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: News Spike Fade Scalping (Advanced, High Risk)

Post by PTScalper »

Key cTrader Differences You Should Know

Pips vs. Points: Unlike MT4/MT5 where you must calculate points based on digit length, cTrader automatically normalizes parameters using Pips. The default Stop Loss of 10.0 means exactly 10 pips, whether you apply this to EURUSD or a Yen pair.

Volume Measurement: cTrader standardizes sizing in Units, not Lots.

100,000 Units = 1 Standard Lot.

10,000 Units = 0.1 Lots (Mini).

1,000 Units = 0.01 Lots (Micro).

Execution Logic: The logic deliberately sits inside OnBar() rather than OnTick(). This guarantees the robot evaluates the closed news candle and enters on the exact first tick of the subsequent candle. Evaluating on every tick during a news event can overload the bot and result in false positives while a candle is violently painting up and down.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Post Reply