Complete .mq5 source code

NAS100 EA MT5: Opening-Range Code and Server-Time Limits

Inspect a NAS100-style opening-range Expert Advisor using complete M1 history, an M5 ATR threshold and a broker-day price-gap check. The session inputs are server time. The example has no earnings feed and makes no backtest or market-performance claim.

Strategy logic

Entry conditions

After the configured server-time range ends, require every M1 bar in that window and matching minute timestamps. Compare the first opening price with the prior broker D1 close for the gap threshold. Once ATR meets the point-based minimum, a live bid breakout permits one order attempt that day. There is no extra breakout buffer or candle-close confirmation.

Exit conditions

Requested SL and TP are 0.75 and 1.5 times the opening-range price width from the entry quote. At or after CloseHour, matching positions are closed by ticket with repeated attempts on later ticks. These are requested actions, not guaranteed prices or a cash-loss limit. No separate two-ATR emergency exit is implemented.

MQL5 Expert Advisor Code

#property strict
input int MagicNumber=789012;
input double Lots=0.01;
input int StartHour=9;
input int StartMinute=30;
input int RangeMinutes=5;
input double MinATRPoints=200;
input double MaxGapPct=0.5;
input int CloseHour=12; // Broker-server hour, not automatically New York.
int atrH=INVALID_HANDLE;
datetime lastDay=0;
bool ready=false,attempted=false,skip=false;
double high=0,low=0;
int CountMine()
{
   int count=0;
   for(int i=PositionsTotal()-1;i>=0;i--)
      if(PositionGetTicket(i)>0 && PositionGetString(POSITION_SYMBOL)==_Symbol
         && PositionGetInteger(POSITION_MAGIC)==MagicNumber) count++;
   return count;
}
void CloseAll()
{
   for(int i=PositionsTotal()-1;i>=0;i--)
   {
      ulong ticket=PositionGetTicket(i);
      if(ticket==0 || PositionGetString(POSITION_SYMBOL)!=_Symbol
         || PositionGetInteger(POSITION_MAGIC)!=MagicNumber) continue;
      MqlTradeRequest q={}; MqlTradeResult r={};
      q.action=TRADE_ACTION_DEAL; q.position=ticket; q.symbol=_Symbol; q.magic=MagicNumber;
      q.volume=PositionGetDouble(POSITION_VOLUME);
      q.type=PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY?ORDER_TYPE_SELL:ORDER_TYPE_BUY;
      q.price=SymbolInfoDouble(_Symbol,q.type==ORDER_TYPE_SELL?SYMBOL_BID:SYMBOL_ASK);
      q.type_filling=ORDER_FILLING_IOC;
      if(!OrderSend(q,r) || r.retcode!=TRADE_RETCODE_DONE)
         Print("Close unresolved or partial: ",r.retcode);
   }
}
int OnInit()
{
   if(MagicNumber<=0 || Lots<=0 || StartHour<0 || StartHour>23 || StartMinute<0
      || StartMinute>59 || RangeMinutes<=0 || RangeMinutes>120 || MinATRPoints<0
      || MaxGapPct<0 || CloseHour<0 || CloseHour>23
      || StartHour*60+StartMinute+RangeMinutes>=CloseHour*60)
      return INIT_PARAMETERS_INCORRECT;
   atrH=iATR(_Symbol,PERIOD_M5,14);
   return atrH==INVALID_HANDLE?INIT_FAILED:INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
   if(atrH!=INVALID_HANDLE) IndicatorRelease(atrH);
}
void OnTick()
{
   MqlTick tick; if(!SymbolInfoTick(_Symbol,tick) || tick.bid<=0 || tick.ask<=0) return;
   MqlDateTime dt; if(!TimeToStruct(tick.time,dt)) return;
   datetime today=StringToTime(TimeToString(tick.time,TIME_DATE));
   if(today!=lastDay)
   {
      lastDay=today; ready=false; attempted=false; skip=false; high=0; low=0;
   }
   if(dt.hour>=CloseHour) { CloseAll(); return; }
   datetime start=today+(long)StartHour*3600+(long)StartMinute*60;
   datetime finish=start+(long)RangeMinutes*60;
   if(tick.time<finish || skip || attempted) return;
   if(!ready)
   {
      MqlRates bars[]; ArraySetAsSeries(bars,false);
      if(CopyRates(_Symbol,PERIOD_M1,start,finish-1,bars)!=RangeMinutes) return;
      for(int i=0;i<RangeMinutes;i++)
         if(bars[i].time!=start+(long)i*60) return;
      double previous=iClose(_Symbol,PERIOD_D1,1);
      if(previous<=0) return;
      // Broker D1 prior close; not necessarily the U.S. cash-session close.
      if(MathAbs(bars[0].open-previous)/previous*100>MaxGapPct) { skip=true; return; }
      high=bars[0].high; low=bars[0].low;
      for(int i=1;i<RangeMinutes;i++) { high=MathMax(high,bars[i].high); low=MathMin(low,bars[i].low); }
      if(high<=low || low<=0) { skip=true; return; }
      ready=true;
   }
   if(CountMine()>0) return;
   double atr[1];
   if(CopyBuffer(atrH,0,1,1,atr)!=1 || atr[0]<=0 || atr[0]<MinATRPoints*_Point) return;
   // Compare bid to the historical price range, then request the executable side.
   bool buy=tick.bid>high, sell=tick.bid<low;
   if(!buy && !sell) return;
   attempted=true; // At most one request per server day, even when rejected.
   double range=high-low;
   MqlTradeRequest q={}; MqlTradeResult r={};
   q.action=TRADE_ACTION_DEAL; q.symbol=_Symbol; q.magic=MagicNumber; q.volume=Lots;
   q.type=buy?ORDER_TYPE_BUY:ORDER_TYPE_SELL; q.price=buy?tick.ask:tick.bid;
   q.sl=NormalizeDouble(q.price+(buy?-1:1)*range*0.75,_Digits);
   q.tp=NormalizeDouble(q.price+(buy?1:-1)*range*1.5,_Digits);
   q.type_filling=ORDER_FILLING_IOC;
   if(!OrderSend(q,r) || r.retcode!=TRADE_RETCODE_DONE)
      Print("Entry rejected or partial: ",r.retcode," ",r.comment);
}

Copy this code into MetaEditor, save it in the MQL5/Experts folder, and compile with F7.

Generate a custom NAS100 scalping EA

Describe the entry, exit, position, order, and risk rules you want. Pineify generates editable MQL5 source code that you can inspect and compile in MetaEditor.

Pine Script vs MQL5: Same Strategy, Different Platforms

AspectPine Script (TradingView)MQL5 (MetaTrader 5)
ExecutionSeries evaluated on chart updatesEvent handlers with explicit buffers
DeploymentRuns in TradingView with alertsRuns in the MT5 terminal or on a VPS
Broker accessStrategy orders are simulated; live automation needs a separate integrationDirect broker connectivity
BacktestingStrategy Tester for strategy scriptsStrategy Tester for Expert Advisors
Code complexitySimpler, functional syntaxC++-like, more powerful

The calculation can be implemented on either platform, but the runtime model and buffer APIs differ.

Frequently Asked Questions

Related MQL5 pages

Risk and testing note

These educational examples require independent compilation and testing. A compile pass or an illustrative setting does not establish execution correctness or profitability. Any reported performance must be supported by reproducible data and test settings; past results do not predict future returns. Trading involves significant risk of loss. This content is not financial advice.