commit 32f17bc9499cb5795ec9e116491b8a77166f7c10 Author: kingstonebridge2032 Date: Wed May 20 22:32:26 2026 +0300 Add files via upload diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a5d917a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,83 @@ +FROM python:3.11-slim-bookworm + +USER root + +ENV DEBIAN_FRONTEND=noninteractive +ENV DISPLAY=:1 +ENV WINEPREFIX=/root/.wine +ENV WINEARCH=win64 +ENV WINEDEBUG=-all + +RUN dpkg --add-architecture i386 && apt-get update && apt-get install -y --no-install-recommends \ + wine wine64 wine32:i386 winbind xvfb fluxbox x11vnc novnc websockify \ + wget curl procps cabextract unzip dos2unix xdotool \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +RUN pip install --no-cache-dir mt5linux rpyc + +RUN wget -q https://download.mql5.com/cdn/web/metaquotes.software.corp/mt5/mt5setup.exe \ + -O /root/mt5setup.exe + +# Copy EA files +COPY ["Volatility_Breakout_Pro_News_Filter.mq5", "/root/Volatility_Breakout_Pro_News_Filter.mq5"] +COPY ["InstitutionalTickHybridNewsFilter.mq5", "/root/InstitutionalTickHybridNewsFilter.mq5"] +COPY ["Tick_Reversion_Pro_NEWS_FILTER.mq5", "/root/Tick_Reversion_Pro_NEWS_FILTER.mq5"] + + + +RUN cat > /entrypoint.sh < + +CTrade trade; + +//==================================================== +// INPUTS +//==================================================== +input ulong MagicNumber = 880001; + +input double ForexLot = 0.01; +input double GoldLot = 0.01; + +input int EMAFastPeriod = 20; +input int EMATrendPeriod = 200; +input int ATRPeriod = 14; +input double ATRMultiplierSL = 2.0; +input double ATRTrailingMultiplier = 1.5; + +input int TickBufferSize = 30; +input double ZScoreThreshold = 1.3; +input int CooldownSeconds = 10; +input int MaxPositionsPerSymbol = 3; + +input double MaxSpreadPoints = 40; +input double MinATRPointsForex = 15; +input double MinATRPointsGold = 150; + +input double ProfitTargetPerLot = 20.0; +input bool UseBreakeven = true; +input double BreakevenOffsetPoints = 10; +input bool EnableDebug = true; + +//==================================================== +// NEWS FILTER +//==================================================== +input bool UseNewsFilter = true; +input int NewsPauseBeforeMin = 60; +input int NewsPauseAfterMin = 60; + +//==================================================== +// GLOBALS +//==================================================== +double TickBuffer[]; +datetime LastTradeTime = 0; + +int emaFastHandle; +int emaTrendHandle; +int atrHandle; + +//==================================================== +// INIT +//==================================================== +int OnInit() +{ + ArrayResize(TickBuffer, TickBufferSize); + + emaFastHandle = iMA(_Symbol,_Period,EMAFastPeriod,0,MODE_EMA,PRICE_CLOSE); + emaTrendHandle = iMA(_Symbol,_Period,EMATrendPeriod,0,MODE_EMA,PRICE_CLOSE); + atrHandle = iATR(_Symbol,_Period,ATRPeriod); + + if(emaFastHandle==INVALID_HANDLE || emaTrendHandle==INVALID_HANDLE || atrHandle==INVALID_HANDLE) + { + Print("Indicator init failed"); + return INIT_FAILED; + } + + Print("EA WITH NEWS FILTER INITIALIZED"); + return INIT_SUCCEEDED; +} + +//==================================================== +// DEINIT +//==================================================== +void OnDeinit(const int reason) +{ + IndicatorRelease(emaFastHandle); + IndicatorRelease(emaTrendHandle); + IndicatorRelease(atrHandle); +} + +//==================================================== +// ON TICK +//==================================================== +void OnTick() +{ + UpdateTickBuffer(); + + //================================================ + // HIGH IMPACT NEWS FILTER + //================================================ + if(UseNewsFilter && IsHighImpactNewsTime()) + { + CloseAllPositions(); + Debug("Trading paused due to HIGH IMPACT NEWS"); + return; + } + + ManagePositions(); + + if(!CanTrade()) + return; + + if(CountPositionsBySymbol() >= MaxPositionsPerSymbol) + return; + + double z = CalculateZScore(); + double emaFast = GetEMA(emaFastHandle); + double emaTrend = GetEMA(emaTrendHandle); + double atr = GetATR(); + + double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); + + bool bullish = bid > emaTrend; + bool bearish = bid < emaTrend; + + bool reversalBuy = (z < -1.0); + bool reversalSell = (z > 1.0); + + if(bullish && reversalBuy) + OpenBuy(atr); + + if(bearish && reversalSell) + OpenSell(atr); +} + +//==================================================== +// NEWS FILTER FUNCTION +//==================================================== +//==================================================== +// NEWS FILTER FUNCTION +//==================================================== +bool IsHighImpactNewsTime() +{ + MqlCalendarValue values[]; + + datetime now = TimeCurrent(); + datetime from = now - 60; + datetime to = now + (NewsPauseBeforeMin * 60); + + int count = CalendarValueHistory(values, from, to); + + if(count <= 0) + return false; + + string symbolCurrency1 = StringSubstr(_Symbol,0,3); + string symbolCurrency2 = StringSubstr(_Symbol,3,3); + + for(int i=0; i USD NEWS ONLY + if(StringFind(_Symbol,"XAU") >= 0 || + StringFind(_Symbol,"GOLD") >= 0) + { + if(currency == "USD") + relevant = true; + } + else + { + if(currency == symbolCurrency1 || + currency == symbolCurrency2) + relevant = true; + } + + if(!relevant) + continue; + + datetime eventTime = values[i].time; + + datetime blockStart = + eventTime - (NewsPauseBeforeMin * 60); + + datetime blockEnd = + eventTime + (NewsPauseAfterMin * 60); + + if(now >= blockStart && now <= blockEnd) + { + Debug("High impact news detected"); + return true; + } + } + + return false; +} + +//==================================================== +// CLOSE ALL POSITIONS +//==================================================== +void CloseAllPositions() +{ + for(int i=PositionsTotal()-1;i>=0;i--) + { + ulong ticket=PositionGetTicket(i); + + if(ticket==0) + continue; + + if(!PositionSelectByTicket(ticket)) + continue; + + if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber) + continue; + + if(PositionGetString(POSITION_SYMBOL)!=_Symbol) + continue; + + trade.PositionClose(ticket); + } +} + +//==================================================== +// UPDATE TICKS +//==================================================== +void UpdateTickBuffer() +{ + for(int i=TickBufferSize-1;i>0;i--) + TickBuffer[i]=TickBuffer[i-1]; + + TickBuffer[0]=SymbolInfoDouble(_Symbol,SYMBOL_BID); +} + +//==================================================== +// Z SCORE +//==================================================== +double CalculateZScore() +{ + double sum=0; + + for(int i=0;i MaxSpreadPoints) + { + Debug("Spread too high"); + return false; + } + + double atrPoints = GetATR()/_Point; + + string sym=_Symbol; + StringToUpper(sym); + + double minATR = MinATRPointsForex; + + if(StringFind(sym,"XAU")>=0 || StringFind(sym,"GOLD")>=0) + minATR = MinATRPointsGold; + + if(atrPoints < minATR) + { + Debug("ATR too low: " + DoubleToString(atrPoints,1)); + return false; + } + + if(TimeCurrent()-LastTradeTime < CooldownSeconds) + return false; + + return true; +} + +//==================================================== +// OPEN BUY +//==================================================== +void OpenBuy(double atr) +{ + double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK); + double sl=ask-(atr*ATRMultiplierSL); + + AdjustStopsForBroker(sl,true); + + double lot=GetLotSize(); + + trade.SetExpertMagicNumber(MagicNumber); + + if(trade.Buy(lot,_Symbol,ask,sl,0,"BUY WITH NEWS FILTER")) + LastTradeTime=TimeCurrent(); +} + +//==================================================== +// OPEN SELL +//==================================================== +void OpenSell(double atr) +{ + double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID); + double sl=bid+(atr*ATRMultiplierSL); + + AdjustStopsForBroker(sl,false); + + double lot=GetLotSize(); + + trade.SetExpertMagicNumber(MagicNumber); + + if(trade.Sell(lot,_Symbol,bid,sl,0,"SELL WITH NEWS FILTER")) + LastTradeTime=TimeCurrent(); +} + +//==================================================== +// LOT SIZE +//==================================================== +double GetLotSize() +{ + string s=_Symbol; + StringToUpper(s); + + if(StringFind(s,"XAU")>=0 || StringFind(s,"GOLD")>=0) + return GoldLot; + + return ForexLot; +} + +//==================================================== +// POSITION COUNT +//==================================================== +int CountPositionsBySymbol() +{ + int c=0; + + for(int i=PositionsTotal()-1;i>=0;i--) + { + ulong t=PositionGetTicket(i); + + if(t==0) + continue; + + if(!PositionSelectByTicket(t)) + continue; + + if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber) + continue; + + if(PositionGetString(POSITION_SYMBOL)!=_Symbol) + continue; + + c++; + } + + return c; +} + +//==================================================== +// POSITION MANAGEMENT +//==================================================== +void ManagePositions() +{ + for(int i=PositionsTotal()-1;i>=0;i--) + { + ulong t=PositionGetTicket(i); + + if(t==0) + continue; + + if(!PositionSelectByTicket(t)) + continue; + + if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber) + continue; + + if(PositionGetString(POSITION_SYMBOL)!=_Symbol) + continue; + + double vol=PositionGetDouble(POSITION_VOLUME); + double sl=PositionGetDouble(POSITION_SL); + double profit=PositionGetDouble(POSITION_PROFIT); + + double atr=GetATR(); + double target=vol*ProfitTargetPerLot; + + if(profit>=target) + { + trade.PositionClose(t); + continue; + } + + ENUM_POSITION_TYPE type= + (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); + + if(type==POSITION_TYPE_BUY) + { + double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID); + double newSL=bid-(atr*ATRTrailingMultiplier); + + if(newSL>sl) + trade.PositionModify(t,newSL,0); + } + + if(type==POSITION_TYPE_SELL) + { + double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK); + double newSL=ask+(atr*ATRTrailingMultiplier); + + if(sl==0 || newSL + +input double ForexLotSize=0.10; +input double OtherLotSize=0.01; +input int LookbackTicks=50; +input double DeviationThreshold=1.5; +input int ATRPeriod=14; +input double ATRMultiplier=2.5; +input double RiskReward=4.0; +input int MaxPositionsPerSymbol=2; +input bool UseEMA200=true; +input double ProfitTargetPerLot=100.0; +input ulong MagicNumber=777777; + +//==================================================== +// NEWS FILTER +//==================================================== +input bool UseNewsFilter=true; +input int NewsPauseBeforeMin=60; +input int NewsPauseAfterMin=60; + +double TickBuffer[]; +int atrHandle; +int emaHandle; +CTrade trade; + +//==================================================== +// LOT SIZE +//==================================================== +double GetLotSize() +{ + string s=_Symbol; + + if(StringFind(s,"XAU")>=0 || StringFind(s,"XAG")>=0 || + StringFind(s,"BTC")>=0 || StringFind(s,"ETH")>=0 || + StringFind(s,"US30")>=0 || StringFind(s,"NAS")>=0 || + StringFind(s,"GER")>=0) + return OtherLotSize; + + return ForexLotSize; +} + +//==================================================== +// POSITION COUNT +//==================================================== +int CountPositionsForSymbol() +{ + int count=0; + + for(int i=PositionsTotal()-1;i>=0;i--) + { + ulong ticket=PositionGetTicket(i); + + if(!PositionSelectByTicket(ticket)) + continue; + + if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber) + continue; + + if(PositionGetString(POSITION_SYMBOL)!=_Symbol) + continue; + + count++; + } + + return count; +} + +//==================================================== +// TREND FILTER +//==================================================== +bool TrendFilter(ENUM_ORDER_TYPE type) +{ + if(!UseEMA200) + return true; + + double ema[1]; + + if(CopyBuffer(emaHandle,0,1,1,ema)<1) + return false; + + double close=iClose(_Symbol,_Period,1); + + if(type==ORDER_TYPE_BUY) + return close>ema[0]; + + return close=0;i--) + { + ulong ticket=PositionGetTicket(i); + + if(!PositionSelectByTicket(ticket)) + continue; + + if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber) + continue; + + if(PositionGetString(POSITION_SYMBOL)!=_Symbol) + continue; + + double profit=PositionGetDouble(POSITION_PROFIT); + double volume=PositionGetDouble(POSITION_VOLUME); + + if(profit>=volume*ProfitTargetPerLot) + trade.PositionClose(ticket); + } +} + +//==================================================== +// MANAGE TRAILING +//==================================================== +void ManageTrailing() +{ + double dist=DynamicStopDistance(); + + for(int i=PositionsTotal()-1;i>=0;i--) + { + ulong ticket=PositionGetTicket(i); + + if(!PositionSelectByTicket(ticket)) + continue; + + if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber) + continue; + + if(PositionGetString(POSITION_SYMBOL)!=_Symbol) + continue; + + ENUM_POSITION_TYPE pos=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); + + double sl=PositionGetDouble(POSITION_SL); + double tp=PositionGetDouble(POSITION_TP); + + double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID); + double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK); + + if(pos==POSITION_TYPE_BUY) + { + double newSL=NormalizeDouble(bid-dist,_Digits); + + if(newSL>sl) + trade.PositionModify(ticket,newSL,tp); + } + else + { + double newSL=NormalizeDouble(ask+dist,_Digits); + + if(sl==0 || newSL=0;i--) + { + ulong ticket=PositionGetTicket(i); + + if(ticket==0) + continue; + + if(!PositionSelectByTicket(ticket)) + continue; + + if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber) + continue; + + if(PositionGetString(POSITION_SYMBOL)!=_Symbol) + continue; + + trade.PositionClose(ticket); + } +} + +//==================================================== +// NEWS FILTER +//==================================================== +bool IsHighImpactNewsTime() +{ + MqlCalendarValue values[]; + + datetime now = TimeCurrent(); + datetime from = now - 60; + datetime to = now + (NewsPauseBeforeMin * 60); + + int count=CalendarValueHistory(values,from,to); + + if(count<=0) + return false; + + string symbolCurrency1=StringSubstr(_Symbol,0,3); + string symbolCurrency2=StringSubstr(_Symbol,3,3); + + for(int i=0;i USD NEWS + if(StringFind(_Symbol,"XAU")>=0 || + StringFind(_Symbol,"XAG")>=0 || + StringFind(_Symbol,"BTC")>=0 || + StringFind(_Symbol,"ETH")>=0 || + StringFind(_Symbol,"US30")>=0 || + StringFind(_Symbol,"NAS")>=0 || + StringFind(_Symbol,"GER")>=0) + { + if(currency=="USD") + relevant=true; + } + else + { + if(currency==symbolCurrency1 || + currency==symbolCurrency2) + relevant=true; + } + + if(!relevant) + continue; + + datetime eventTime=values[i].time; + + datetime blockStart= + eventTime-(NewsPauseBeforeMin*60); + + datetime blockEnd= + eventTime+(NewsPauseAfterMin*60); + + if(now>=blockStart && now<=blockEnd) + return true; + } + + return false; +} + +//==================================================== +// EXECUTE DEAL +//==================================================== +void ExecuteDeal(ENUM_ORDER_TYPE type) +{ + double dist=DynamicStopDistance(); + + double price=(type==ORDER_TYPE_BUY) + ? SymbolInfoDouble(_Symbol,SYMBOL_ASK) + : SymbolInfoDouble(_Symbol,SYMBOL_BID); + + double sl=(type==ORDER_TYPE_BUY) ? price-dist : price+dist; + double tp=(type==ORDER_TYPE_BUY) ? price+dist*RiskReward : price-dist*RiskReward; + + trade.PositionOpen( + _Symbol, + type, + GetLotSize(), + price, + NormalizeDouble(sl,_Digits), + NormalizeDouble(tp,_Digits), + "TickReversionProNews" + ); +} + +//==================================================== +// INIT +//==================================================== +int OnInit() +{ + ArrayResize(TickBuffer,LookbackTicks); + ArrayInitialize(TickBuffer,0); + + atrHandle=iATR(_Symbol,_Period,ATRPeriod); + emaHandle=iMA(_Symbol,_Period,200,0,MODE_EMA,PRICE_CLOSE); + + trade.SetExpertMagicNumber(MagicNumber); + + return(INIT_SUCCEEDED); +} + +//==================================================== +// ON TICK +//==================================================== +void OnTick() +{ + double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID); + + for(int i=LookbackTicks-1;i>0;i--) + TickBuffer[i]=TickBuffer[i-1]; + + TickBuffer[0]=bid; + + //================================================ + // NEWS FILTER + //================================================ + if(UseNewsFilter && IsHighImpactNewsTime()) + { + CloseAllPositions(); + return; + } + + ManageProfitTarget(); + ManageTrailing(); + + if(TickBuffer[LookbackTicks-1]==0) + return; + + if(CountPositionsForSymbol()>=MaxPositionsPerSymbol) + return; + + double sum=0; + + for(int i=0;i=DeviationThreshold && TrendFilter(ORDER_TYPE_SELL)) + ExecuteDeal(ORDER_TYPE_SELL); +} +//+------------------------------------------------------------------+ \ No newline at end of file diff --git a/Volatility_Breakout_Pro_News_Filter.mq5 b/Volatility_Breakout_Pro_News_Filter.mq5 new file mode 100644 index 0000000..b35d4fb --- /dev/null +++ b/Volatility_Breakout_Pro_News_Filter.mq5 @@ -0,0 +1,300 @@ +//+------------------------------------------------------------------+ +//| Volatility_Breakout_Pro.mq5 | +//| WITH HIGH IMPACT NEWS FILTER | +//+------------------------------------------------------------------+ +#property strict +#include + +input double ForexLotSize=0.01; +input double OtherLotSize=0.01; +input int ATRPeriod=14; +input int EMAFast=50; +input int EMASlow=200; +input double ATRMultiplierSL=2.5; +input double RiskReward=3.0; +input double ProfitTargetPerLot=20.0; +input int MaxPositionsPerSymbol=10; +input ulong MagicNumber=888888; + +//==================================================== +// NEWS FILTER +//==================================================== +input bool UseNewsFilter=true; +input int NewsPauseBeforeMin=60; +input int NewsPauseAfterMin=60; + +CTrade trade; +int atrHandle, fastHandle, slowHandle; + +//==================================================== +// LOT SIZE +//==================================================== +double GetLotSize() +{ + string s=_Symbol; + + if(StringFind(s,"XAU")>=0 || StringFind(s,"XAG")>=0 || + StringFind(s,"BTC")>=0 || StringFind(s,"ETH")>=0 || + StringFind(s,"US30")>=0 || StringFind(s,"NAS")>=0) + return OtherLotSize; + + return ForexLotSize; +} + +//==================================================== +// POSITION COUNT +//==================================================== +int CountPositionsForSymbol() +{ + int count=0; + + for(int i=PositionsTotal()-1;i>=0;i--) + { + ulong ticket=PositionGetTicket(i); + + if(!PositionSelectByTicket(ticket)) continue; + if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber) continue; + if(PositionGetString(POSITION_SYMBOL)!=_Symbol) continue; + + count++; + } + + return count; +} + +//==================================================== +// DYNAMIC STOP +//==================================================== +double DynamicStop() +{ + double atr[1]; + + if(CopyBuffer(atrHandle,0,0,1,atr)<1) + return 100*_Point; + + double stopLevel=SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL)*_Point; + double freezeLevel=SymbolInfoInteger(_Symbol,SYMBOL_TRADE_FREEZE_LEVEL)*_Point; + double spread=SymbolInfoDouble(_Symbol,SYMBOL_ASK)-SymbolInfoDouble(_Symbol,SYMBOL_BID); + + return MathMax(atr[0]*ATRMultiplierSL, + MathMax(stopLevel,freezeLevel)+spread*10.0); +} + +//==================================================== +// MANAGE POSITIONS +//==================================================== +void ManagePositions() +{ + for(int i=PositionsTotal()-1;i>=0;i--) + { + ulong ticket=PositionGetTicket(i); + + if(!PositionSelectByTicket(ticket)) continue; + if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber) continue; + if(PositionGetString(POSITION_SYMBOL)!=_Symbol) continue; + + double profit=PositionGetDouble(POSITION_PROFIT); + double volume=PositionGetDouble(POSITION_VOLUME); + + if(profit>=volume*ProfitTargetPerLot) + { + trade.PositionClose(ticket); + continue; + } + + double tp=PositionGetDouble(POSITION_TP); + double sl=PositionGetDouble(POSITION_SL); + double dist=DynamicStop(); + + ENUM_POSITION_TYPE pos=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); + + if(pos==POSITION_TYPE_BUY) + { + double newSL=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID)-dist,_Digits); + + if(newSL>sl) + trade.PositionModify(ticket,newSL,tp); + } + else + { + double newSL=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK)+dist,_Digits); + + if(sl==0 || newSL=0;i--) + { + ulong ticket=PositionGetTicket(i); + + if(ticket==0) + continue; + + if(!PositionSelectByTicket(ticket)) + continue; + + if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber) + continue; + + if(PositionGetString(POSITION_SYMBOL)!=_Symbol) + continue; + + trade.PositionClose(ticket); + } +} + +//==================================================== +// NEWS FILTER +//==================================================== +bool IsHighImpactNewsTime() +{ + MqlCalendarValue values[]; + + datetime now = TimeCurrent(); + datetime from = now - 60; + datetime to = now + (NewsPauseBeforeMin * 60); + + int count = CalendarValueHistory(values,from,to); + + if(count<=0) + return false; + + string symbolCurrency1=StringSubstr(_Symbol,0,3); + string symbolCurrency2=StringSubstr(_Symbol,3,3); + + for(int i=0;i USD NEWS + if(StringFind(_Symbol,"XAU")>=0 || + StringFind(_Symbol,"XAG")>=0 || + StringFind(_Symbol,"BTC")>=0 || + StringFind(_Symbol,"ETH")>=0 || + StringFind(_Symbol,"US30")>=0 || + StringFind(_Symbol,"NAS")>=0) + { + if(currency=="USD") + relevant=true; + } + else + { + if(currency==symbolCurrency1 || + currency==symbolCurrency2) + relevant=true; + } + + if(!relevant) + continue; + + datetime eventTime=values[i].time; + + datetime blockStart= + eventTime-(NewsPauseBeforeMin*60); + + datetime blockEnd= + eventTime+(NewsPauseAfterMin*60); + + if(now>=blockStart && now<=blockEnd) + return true; + } + + return false; +} + +//==================================================== +// INIT +//==================================================== +int OnInit() +{ + trade.SetExpertMagicNumber(MagicNumber); + + atrHandle=iATR(_Symbol,_Period,ATRPeriod); + fastHandle=iMA(_Symbol,_Period,EMAFast,0,MODE_EMA,PRICE_CLOSE); + slowHandle=iMA(_Symbol,_Period,EMASlow,0,MODE_EMA,PRICE_CLOSE); + + return(INIT_SUCCEEDED); +} + +//==================================================== +// ON TICK +//==================================================== +void OnTick() +{ + //================================================ + // NEWS FILTER + //================================================ + if(UseNewsFilter && IsHighImpactNewsTime()) + { + CloseAllPositions(); + return; + } + + ManagePositions(); + + if(CountPositionsForSymbol()>=MaxPositionsPerSymbol) + return; + + double fast[2], slow[2]; + + if(CopyBuffer(fastHandle,0,0,2,fast)<2) return; + if(CopyBuffer(slowHandle,0,0,2,slow)<2) return; + + double high=iHigh(_Symbol,_Period,1); + double low=iLow(_Symbol,_Period,1); + + double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK); + double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID); + + double slDist=DynamicStop(); + + bool upTrend=fast[0]>slow[0]; + bool downTrend=fast[0]high) + { + trade.Buy(GetLotSize(), + _Symbol, + ask, + ask-slDist, + ask+slDist*RiskReward, + "BreakoutBuyNews"); + } + + if(downTrend && bid