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
| Aspect | Pine Script (TradingView) | MQL5 (MetaTrader 5) |
|---|---|---|
| Execution | Series evaluated on chart updates | Event handlers with explicit buffers |
| Deployment | Runs in TradingView with alerts | Runs in the MT5 terminal or on a VPS |
| Broker access | Strategy orders are simulated; live automation needs a separate integration | Direct broker connectivity |
| Backtesting | Strategy Tester for strategy scripts | Strategy Tester for Expert Advisors |
| Code complexity | Simpler, functional syntax | C++-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.