#property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include //+------------------------------------------------------------------+ //| Input | //+------------------------------------------------------------------+ static input long InpMagicnumber = 778973; //magicnumber static input double InpLotSize = 0.01; // lot size input int InpRSIPeriod = 21; // rsi period input int InpRSILevel = 70; //rsi level (upper) input int InpMAPeriod = 21; // ma period input ENUM_TIMEFRAMES InpMATimeframe = PERIOD_H1; // ma timeframe input int InpStopLoss = 200; // stop loss in point (0 = off) input int InpTakeProfit = 100; // take profit in points (0=off) input bool InpCloseSignal = false; // close trades by opposite signal //+------------------------------------------------------------------+ //| Global variable | //+------------------------------------------------------------------+ int handleRSI; int handleMA; double bufferRSI[]; double bufferMA[]; MqlTick currentTick; CTrade trade; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){ // check user input if(InpMagicnumber <= 0){ Print("Failed to use the MagicNumber because it is below 0"); return INIT_PARAMETERS_INCORRECT; } if(InpLotSize <= 0 || InpLotSize > 10 ){ Print("Failed to use the Lotsize"); return INIT_PARAMETERS_INCORRECT; } if(InpRSIPeriod <= 1 ){ Print("Failed to use the RSI Period"); return INIT_PARAMETERS_INCORRECT; } if(InpRSILevel >= 100 || InpRSILevel <=50){ Print("Wrong input of RSI LEVEL"); return INIT_PARAMETERS_INCORRECT; } if(InpMAPeriod <= 1 ){ Print("Failed to use the RSI Period"); return INIT_PARAMETERS_INCORRECT; } if(InpStopLoss < 0 ){ Print("Wrong input of Stoploss"); return INIT_PARAMETERS_INCORRECT; } if(InpTakeProfit < 0 ){ Print("Wrong input of TakeProfit"); return INIT_PARAMETERS_INCORRECT; } if(InpStopLoss <= 0 && InpCloseSignal ){ Print("stoploss and close signal are 0 at the same time!! really big risk!!"); return INIT_PARAMETERS_INCORRECT; } // set Magic number trade.SetExpertMagicNumber(InpMagicnumber); // create rsi handleRSI handleRSI = iRSI(_Symbol,PERIOD_CURRENT,InpRSIPeriod,PRICE_OPEN); if(handleRSI == INVALID_HANDLE){ Print("failed to create indicator handleRSI"); return INIT_FAILED ; } handleMA = iMA(_Symbol,InpMATimeframe,PRICE_OPEN,0,MODE_SMA,PRICE_OPEN); if(handleRSI == INVALID_HANDLE){ Print("failed to create indicator handleMA"); return INIT_FAILED ; } //set buffer as series ## for setting the series , it makes the latest data placed in [0] ArraySetAsSeries(bufferRSI,true); ArraySetAsSeries(bufferMA,true); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason){ // release indicator handleRSI if(handleRSI!=INVALID_HANDLE){IndicatorRelease(handleRSI);} if(handleMA!=INVALID_HANDLE){IndicatorRelease(handleMA);} } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick(){ //check if current tick is a new bar open tick if(!IsNewBar()){return;} //get current tick if(!SymbolInfoTick(_Symbol,currentTick)){ Print("Failed to get current tick"); return; } //get rsi values and copy the array to bufferRSI int values = CopyBuffer(handleRSI,0,0,2,bufferRSI); if(values!=2){ Print("Failed to get RSI values"); return; } //get rsi values and copy the array to bufferRSI values = CopyBuffer(handleMA,0,0,1,bufferMA); if(values!=1){ Print("Failed to get MA values"); return; } Comment("bufferRSI[0]:", bufferRSI[0], "\nbufferRSI[1]" , bufferRSI[1], "\nbufferMA[0]:", bufferMA[0]); //count open psoitions int cntBuy, cntSell; if(!CountOpenPositions(cntBuy,cntSell)){return;} //check for buy position if(cntBuy==0 && bufferRSI[1]>=(100-InpRSILevel) && bufferRSI[0]<(100-InpRSILevel) && currentTick.ask>bufferMA[0]){ if(InpCloseSignal){if(!ClosePositions(2)){return;}} double sl = InpStopLoss==0 ? 0 : currentTick.bid - InpStopLoss * _Point; double tp = InpTakeProfit==0 ? 0 : currentTick.bid + InpTakeProfit * _Point; if(!NormalizePrice(sl)){return;} if(!NormalizePrice(tp)){return;} trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,InpLotSize,currentTick.ask,sl,tp,"RSI MA filter EA"); } //check for sell position if(cntSell==0 && bufferRSI[1]<=InpRSILevel && bufferRSI[0]>InpRSILevel && currentTick.bid=0; i--){ ulong ticket = PositionGetTicket(i); if(ticket<=0){Print("Failed to get position ticket"); return false;} if(!PositionSelectByTicket(ticket)){Print("Failed to select position"); return false;} long magic; if(!PositionGetInteger(POSITION_MAGIC,magic)) {Print("Failed to get position magicnumber"); return false;} if(magic==InpMagicnumber){ long type; if(!PositionGetInteger(POSITION_TYPE,type)) {Print("Failed to get position type"); return false;} if(type==POSITION_TYPE_BUY) {cntBuy++ ;} if(type==POSITION_TYPE_SELL) {cntSell++ ;} } } return true; } // normalize price bool NormalizePrice(double &price){ double tickSize=0; if(!SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE,tickSize)){ Print("Failed to get tick size"); return false; } price = NormalizeDouble((MathRound(price/tickSize)*tickSize),_Digits); return true; } //close positions bool ClosePositions(int all_buy_sell){ int total = PositionsTotal(); for(int i = total-1; i>=0; i--){ ulong ticket = PositionGetTicket(i); if(ticket<=0){Print("Failed to get position ticket"); return false;} if(!PositionSelectByTicket(ticket)){Print("Failed to select position"); return false;} long magic; if(!PositionGetInteger(POSITION_MAGIC,magic)) {Print("Failed to get position magicnumber"); return false;} if(magic==InpMagicnumber){ long type; if(!PositionGetInteger(POSITION_TYPE,type)){Print("Failed to get position type"); return false;} if(all_buy_sell==1 && type==POSITION_TYPE_SELL){continue;} //1 = buy position if(all_buy_sell==2 && type==POSITION_TYPE_BUY){continue;} //2 = sell position trade.PositionClose(ticket); if(trade.ResultRetcode()!=TRADE_RETCODE_DONE){ Print("Failed to close position. Ticket:", (string)ticket," result:",(string)trade.ResultRetcode(),":",trade.CheckResultRetcodeDescription()); } } } return true; }