//+------------------------------------------------------------------+ //| HFS_NS92_EA.mq5 | //| Author: Santiago Cruz | //| https://www.mql5.com/en/users/algo-trader/ | //+------------------------------------------------------------------+ #property copyright "Santiago Cruz" #property link "https://www.mql5.com/en/users/algo-trader/" #property version "1.00" #include CTrade trade; CPositionInfo pos; COrderInfo ord; input group "=== Trading Profiles ===" enum SystemType{Forex=0, BitCoin=1, _Gold=2, US_Indices=3}; input SystemType SType = 0; int SysChoice; input group "=== Trading Inputs ===" input string TradeComment = "Scalping NS92 EA"; input int InpMagic = 922581; //EA Magic Number input double RiskPercent = 3; //Risk as % of Trading Capital input ENUM_TIMEFRAMES Timeframe = PERIOD_CURRENT; enum StartHour{Inactive=0, _0100=1, _0200=2, _0300=3, _0400=4, _0500=5, _0600=6, _0700=7,_0800=8,_0900=9, _1000=10, _1100=11, _1200=12}; input StartHour SHInput=0; //Start Hour enum EndHour{Inactive=0, _1300=13, _1400=14, _1500=15, _1600=16, _1700=17, _1800=18,_1900=19, _2000=20, _2100=21, _2200=22, _2300=23}; input EndHour EHInput=0; //End Hour int SHChoice; int EHChoice; int BarsN = 5; int ExpirationBars = 100; double OrderDistPoints = 100; double Tppoints, SLPoints, TslTriggerPoints, TslPoints; int handleRSI, handleMovAvg; input color ChartColorTradingOff = clrPink; input color ChartColorTradingOn = clrBlack; bool Tradingenabled = true; input bool HideIndicators = true; string TradingEnabledComm = ""; input group "=== Forex Trading Inputs ===" input int TppointsInput = 200; //Take Profit (10 Points = 1 Pip) input int SlPointsInput = 200; //Stop Loss Points (10 Points = 1 Pip) input int TslTriggerPointsInput = 15; //Points in Profits before Trailing SL is activated (10 Points = 1 Pip) input int TslPointsInput = 10; //Trailing Stop Loss (10 Points = 1 Pip) input group "=== Crypto ===" input double TPasPct = 0.4; //TP as % of Price input double SLasPct = 0.4; //SL as % of Price input double TSLasPctofTP = 5; //Trail SL as % of TP input double TSLTgrasPctofTP = 7; //Trigger of Trail SL % of TP input group "=== Commodities/Gold ===" input double TPasPctGold = 0.2; //TP as % of Price input double SLasPctGold = 0.2; //SL as % of Price input double TSLasPctofTPGold = 5; //Trail SL as % of TP input double TSLTgrasPctofTPGold = 7; //Trigger of Trail SL % of TP input group "=== US Indices ===" input double TPasPctIndices = 0.2; //TP as % of Price input double SLasPctIndices = 0.2; //SL as % of Price input double TSLasPctofTPIndices = 5; //Trail SL as % of TP input double TSLTgrasPctofTPIndices = 7; //Trigger of Trail SL % of TP input group "=== News Filter ===" input bool NewsFilterOn = true; //Filter For News enum sep_dropdown{comma=0,semicolon=1}; input sep_dropdown separator = 0; //Separator to Separate News Keywords input string KeyNews = "BCB,NFP,JOLTS,Nonfarm,PMI,Retail,GDP,Confidence,Interest Rate"; //Keywords in News to avoid (separated by separator) input string NewsCurrencies = "USD,GBP,EUR,JPY"; //Currencies for News LookUp input int DaysNewsLookup = 100; // No of Days to look up News input int StopBeforeMin = 15; //Stop Trading Before (in minutes) input int StartTradingMin = 15; //Start Trading After (in minutes) bool TrDisabledNews = false; //Variable to store if Trading is disabled due to News ushort sep_code; string NewstoAvoid[]; datetime LastNewsAvoided; input group "=== RSI Filter ===" input bool RSIFilterOn = false; //Filter for RSI Extremes input ENUM_TIMEFRAMES RSITimeFrame = PERIOD_H1; //Timeframe for RSI Filter input int RSIlowerlvl = 20; //RSI Lower Level to Filter input int RSIUpperlvl = 80; //RSI Upper Level to Filter input int RSI_MA = 14; //RSI Period input ENUM_APPLIED_PRICE RSI_AppPrice = PRICE_MEDIAN; //RSI Applied Price input group "=== Moving Average Filter===" input bool MAFilterOn = false; //Filter for MA Extremes input ENUM_TIMEFRAMES MATimeFrame = PERIOD_H4; //Timeframe for MA Filter input double PctPricefromMA = 3; //% Price is away from MA to be Extreme input int MA_Period = 200; //MA Period input ENUM_MA_METHOD MA_Mode = MODE_EMA; //MA Mode/Method input ENUM_APPLIED_PRICE MA_AppPrice = PRICE_MEDIAN; //MA Applied Price //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { trade.SetExpertMagicNumber(InpMagic); ChartSetInteger(0,CHART_SHOW_GRID,false); SHChoice = SHInput; EHChoice = EHInput; if(SType==0) SysChoice=0; if(SType==1) SysChoice=1; if(SType==2) SysChoice=2; if(SType==3) SysChoice=3; Tppoints = TppointsInput; SLPoints = SlPointsInput; TslTriggerPoints = TslTriggerPointsInput; TslPoints = TslPointsInput; if(HideIndicators==true) TesterHideIndicators(true); handleRSI = iRSI(_Symbol,RSITimeFrame,RSI_MA,RSI_AppPrice); handleMovAvg = iMA(_Symbol,MATimeFrame,MA_Period,0,MA_Mode,MA_AppPrice); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- TrailStop(); //We want to check TS before any bar if(IsRSIFilter() || IsUpcomingNews() || IsMAFilter()) { CloseAllOrders(); Tradingenabled=false; ChartSetInteger(0,CHART_COLOR_BACKGROUND,ChartColorTradingOff); if(TradingEnabledComm!="Printed") Print(TradingEnabledComm); TradingEnabledComm="Printed"; return; } Tradingenabled=true; if(TradingEnabledComm!="") { Print("Trading is enabled again"); TradingEnabledComm = ""; } ChartSetInteger(0,CHART_COLOR_BACKGROUND,ChartColorTradingOn); if(!IsNewBar()) return; MqlDateTime time; TimeToStruct(TimeCurrent(),time); int Hournow = time.hour; if(Hournow=EHChoice && EHChoice!=0){CloseAllOrders(); return;} if(SysChoice==1) { double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK); Tppoints = ask * TPasPct; SLPoints = ask * SLasPct; OrderDistPoints = Tppoints/2; TslPoints = Tppoints * TSLasPctofTP/100; TslTriggerPoints = Tppoints * TSLTgrasPctofTP/100; } if(SysChoice==2) { double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK); Tppoints = ask * TPasPctGold; SLPoints = ask * SLasPctGold; OrderDistPoints = Tppoints/2; TslPoints = Tppoints * TSLasPctofTPGold/100; TslTriggerPoints = Tppoints * TSLTgrasPctofTPGold/100; } if(SysChoice==3) { double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK); Tppoints = ask * TPasPctIndices; SLPoints = ask * SLasPctIndices; OrderDistPoints = Tppoints/2; TslPoints = Tppoints * TSLasPctofTPIndices/100; TslTriggerPoints = Tppoints * TSLTgrasPctofTPIndices/100; } int BuyTotal = 0; int SellTotal = 0; for(int i=PositionsTotal()-1; i>=0; i--) { pos.SelectByIndex(i); if(pos.PositionType()==POSITION_TYPE_BUY && pos.Symbol()==_Symbol && pos.Magic()==InpMagic) BuyTotal++; if(pos.PositionType()==POSITION_TYPE_SELL && pos.Symbol()==_Symbol && pos.Magic()==InpMagic) SellTotal++; } for(int i=OrdersTotal()-1; i>=0; i--) { pos.SelectByIndex(i); if(ord.OrderType()==ORDER_TYPE_BUY_STOP && ord.Symbol()==_Symbol && ord.Magic()==InpMagic) BuyTotal++; if(ord.OrderType()==ORDER_TYPE_SELL_STOP && ord.Symbol()==_Symbol && ord.Magic()==InpMagic) SellTotal++; } if(BuyTotal <=0) { double high = findHigh(); if(high > 0) { SendBuyOrder(high); } } if(SellTotal <=0) { double low = findLow(); if(low > 0) { SendSellOrder(low); } } } //+------------------------------------------------------------------+ //|Finding High Points in Bars | //+------------------------------------------------------------------+ double findHigh() { double highestHigh = 0; for(int i=0; i<200; i++) { double high = iHigh(_Symbol,Timeframe,i); if(i > BarsN && iHighest(_Symbol,Timeframe,MODE_HIGH,BarsN*2+1,i-BarsN) == i) { if(high > highestHigh) { return high; } } highestHigh = MathMax(high,highestHigh); } return -1; } //+------------------------------------------------------------------+ //|Finding Low Points in Bars | //+------------------------------------------------------------------+ double findLow() { double lowestLow = DBL_MAX; for(int i=0; i<200; i++) { double low = iLow(_Symbol,Timeframe,i); if(i > BarsN && iLowest(_Symbol,Timeframe,MODE_HIGH,BarsN*2+1,i-BarsN) == i) { if(low < lowestLow) { return low; } } lowestLow = MathMin(low,lowestLow); } return -1; } //+------------------------------------------------------------------+ //|Checking for New Bars | //+------------------------------------------------------------------+ bool IsNewBar() { static datetime previousTime = 0; datetime currentTime = iTime(_Symbol,PERIOD_CURRENT,0); if(previousTime!=currentTime) { previousTime=currentTime; return true; } return false; } //+------------------------------------------------------------------+ //|Sending Buy Orders | //+------------------------------------------------------------------+ void SendBuyOrder(double entry){ double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK); if(ask > entry - OrderDistPoints * _Point) return; double tp = entry + Tppoints * _Point; double sl = entry - SLPoints * _Point; double lots = 0.01; if(RiskPercent > 0) lots = calcLots(entry-sl); datetime expiration = iTime(_Symbol,Timeframe,0) + ExpirationBars * PeriodSeconds(Timeframe); trade.BuyStop(lots,entry,_Symbol,sl,tp,ORDER_TIME_SPECIFIED,expiration); } //+------------------------------------------------------------------+ //|Sending Sell Orders | //+------------------------------------------------------------------+ void SendSellOrder(double entry){ double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); if(bid < entry + OrderDistPoints * _Point) return; double tp = entry - Tppoints * _Point; double sl = entry + SLPoints * _Point; double lots = 0.01; if(RiskPercent > 0) lots = calcLots(sl-entry); datetime expiration = iTime(_Symbol,Timeframe,0) + ExpirationBars * PeriodSeconds(Timeframe); trade.SellStop(lots,entry,_Symbol,sl,tp,ORDER_TIME_SPECIFIED,expiration); } //+------------------------------------------------------------------+ //|Calculation of Lot Size | //+------------------------------------------------------------------+ double calcLots(double slPoints){ double risk = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent /100; double ticksize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE); double tickvalue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); double lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP); double minvolume = SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN); double maxvolume = SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX); double volumelimit = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_LIMIT); double moneyPerLotstep = slPoints / ticksize * tickvalue * lotstep; double lots = MathFloor(risk/moneyPerLotstep) * lotstep; if(volumelimit!=0) lots = MathMin(lots,volumelimit); if(maxvolume!=0) lots = MathMin(lots,SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX)); if(minvolume!=0) lots = MathMax(lots,SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN)); lots = NormalizeDouble(lots,2); return lots; } //+------------------------------------------------------------------+ //|Closing All Orders | //+------------------------------------------------------------------+ void CloseAllOrders(){ for(int i=OrdersTotal()-1;i>=0;i--) { ord.SelectByIndex(i); ulong ticket = ord.Ticket(); if(ord.Symbol()==_Symbol && ord.Magic()==InpMagic) { trade.OrderDelete(ticket); } } } //+------------------------------------------------------------------+ //|Trailing StopLoss | //+------------------------------------------------------------------+ void TrailStop(){ double sl = 0; double tp = 0; double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK); double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); for(int i=PositionsTotal()-1; i>=0; i--) { if(pos.SelectByIndex(i)) { ulong ticket = pos.Ticket(); if(pos.Magic()==InpMagic && pos.Symbol()==_Symbol) { if(pos.PositionType()==POSITION_TYPE_BUY) { if(bid-pos.PriceOpen()>TslTriggerPoints*_Point) //If the current price is bigger than 15, then we activated the TS { tp = pos.TakeProfit(); sl = bid - (TslPoints * _Point); if(sl > pos.StopLoss() && sl!=0) { trade.PositionModify(ticket,sl,tp); } } } else if(pos.PositionType()==POSITION_TYPE_SELL) { if(ask+(TslTriggerPoints*_Point)", values[i].time); if(values[i].time - TimeCurrent() < StopBeforeMin*PeriodSeconds(PERIOD_M1)) { LastNewsAvoided = values[i].time; TrDisabledNews = true; if(TradingEnabledComm=="" || TradingEnabledComm!="Printed") { TradingEnabledComm = "Trading is disabled due to upcoming news: " + event.name; } return true; } return false; } } return false; } bool IsRSIFilter(){ if(RSIFilterOn==false) return(false); double RSI[]; CopyBuffer(handleRSI,MAIN_LINE,0,1,RSI); ArraySetAsSeries(RSI,true); double RSInow = RSI[0]; Comment("RSI = ",RSInow); if(RSInow>RSIUpperlvl || RSInow MAnow * (1 + PctPricefromMA/100) || ask < MAnow * (1 - PctPricefromMA/100)) { if(TradingEnabledComm=="" || TradingEnabledComm!="Printed") { TradingEnabledComm = "Trading is disabled due to Mov Avg Filter"; } return true; } return false; } //+------------------------------------------------------------------+