Trade Placement Issue for RSI EA

 

EA only places one trade with the correct sl and tp but it never opens another trade


#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade/Trade.mqh>
#include <Trade/PositionInfo.mqh>

CPositionInfo m_position;
CTrade m_trade;

input int InpRSIPeriods = 14; //RSI Periods
input ENUM_APPLIED_PRICE inpRSIPrice = PRICE_CLOSE; //RSI APPLIED PRICE
input ENUM_TIMEFRAMES inpRSITime = PERIOD_CURRENT; //Timeframe

input double inpOversoldLevel = 20.0; //Oversold Level
input double inpOverboughtLevel = 80.0; //Overbought Level

input double inpTakeProfit = 0.01; //Take Profit in currency value
input double inpStopLoss = 0.01; //Stop Loss in currency value

input double inpOrderSize = 0.10;
input string inpTradeComment = "RSI";
MqlTradeRequest requestmql;
MqlTradeResult resultmql;
MqlTradeTransaction order;

bool isBuyTradeExecuted = false;
bool isSellTradeExecuted = false;
bool ShouldCloseSellTrade = false;
bool ShouldCloseBuyTrade = false;

bool PositionClose( 
      const string   symbol,
      ulong          deviation=ULONG_MAX
   );


bool PositionClose( 
      const string   symbol,
      ulong          deviation /*=ULONG_MAX*/
   )
{
   // code goes here
   return true;
}


CTrade trade;
   static bool oversold = false;
   static bool overbought = false;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ENUM_INIT_RETCODE succsess = INIT_SUCCEEDED;
   
   succsess = CheckInput();
   if (succsess!=INIT_SUCCEEDED) return(succsess); // exit if inputs were bad
//---
   return(INIT_SUCCEEDED);
   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of current position
      if(m_position.SelectByIndex(i))     // selects the position by index for further access to its properties
         if(m_position.Symbol()==Symbol())
            m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol
   
  }

void OnDeinit(const int reason)
  {
//---

  }
void OnTick()
  {

  
   
   
   double rsi =iRSI(Symbol(), Period(), InpRSIPeriods, inpRSIPrice);

   
   double direction = iClose(Symbol(), Period(), 1)-iOpen(Symbol(), Period(), 1);
   
   if (rsi>80) {
      overbought = true;
      } else
      if (rsi<20) {
      oversold = true;
      }  
    if (rsi < inpOversoldLevel && !oversold && !isBuyTradeExecuted)
    {
        double lotSize = inpOrderSize;
        double stopLoss = SymbolInfoDouble(Symbol(), SYMBOL_ASK) - 0.01; 
        double takeProfit = SymbolInfoDouble(Symbol(), SYMBOL_ASK) + 0.01; 
        int magicNumber = 154831; 
        ZeroMemory(requestmql);
        ZeroMemory(resultmql);

        requestmql.action = TRADE_ACTION_DEAL;
        requestmql.symbol = Symbol();
        requestmql.volume = lotSize;
        requestmql.type = ORDER_TYPE_BUY;
        requestmql.price = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
        requestmql.sl = stopLoss;
        requestmql.tp = takeProfit;
        requestmql.comment = inpTradeComment;
        requestmql.magic = magicNumber;

       if (OrderSend(requestmql, resultmql))
        {
            Print("Buy order opened");
            oversold = true; 
            isBuyTradeExecuted = true;
        }
        else
        {
            Print("Failed to open buy order. Error:", resultmql.retcode);
        }
    }
    else if (rsi > inpOverboughtLevel && !overbought && !isSellTradeExecuted)
    {
        
        double lotSize = inpOrderSize;
        double stopLoss = SymbolInfoDouble(Symbol(),SYMBOL_ASK) + 0.1; 
        double takeProfit = SymbolInfoDouble(Symbol(), SYMBOL_ASK) - 0.1; 
        int magicNumber = 145937; 

        ZeroMemory(requestmql);
        ZeroMemory(resultmql);

        requestmql.action = TRADE_ACTION_DEAL;
        requestmql.symbol = Symbol();
        requestmql.volume = lotSize;
        requestmql.type = ORDER_TYPE_SELL;
        requestmql.price = SymbolInfoDouble(Symbol(), SYMBOL_BID);
        requestmql.sl = stopLoss;
        requestmql.tp = takeProfit;
        requestmql.comment = inpTradeComment;
        requestmql.magic = magicNumber;
          if (OrderSend(requestmql, resultmql))
        {
            Print("Sell order opened");
            overbought = true; 
            isSellTradeExecuted = true;
        }
        else
        {
            Print("Failed to open sell order. Error:", resultmql.retcode);
        }
        
    }


    if (!isSellTradeExecuted)
    {
        if (ShouldCloseSellTrade) 
        {
                     if(trade.PositionClose(resultmql.order))
                     {
                        Print("Sell trade closed");
                        isSellTradeExecuted = true;
                }
            }
            else
            {
                Print("Failed to close sell trade. Error:", resultmql.retcode);
            }
        }
    

   if (!isBuyTradeExecuted)
   {
    if (ShouldCloseBuyTrade)
    {
        if (trade.PositionClose(resultmql.order))
        {
                  Print("Buy Trade Closed");
                  isBuyTradeExecuted = true;
            }
        }
        else
        {
            Print("Failed to close buy trade. Error:", resultmql.retcode);

        }
    }
}









//+------------------------------------------------------------------+
ENUM_INIT_RETCODE CheckInput() {
   if (InpRSIPeriods<=0) return(INIT_PARAMETERS_INCORRECT);
   
   return(INIT_SUCCEEDED);
}
bool NewBar(){
   datetime currentTime= iTime(Symbol(), Period(), 0); //Gets the opening time of bar 0
   static datetime priorTime=currentTime; //Initialised to prevent trading on the first bar after
   bool time = (currentTime!=priorTime); //Time has changed
   return(time);
}
Discover new MetaTrader 5 opportunities with MQL5 community and services
Discover new MetaTrader 5 opportunities with MQL5 community and services
  • 2023.05.28
  • www.mql5.com
MQL5: language of trade strategies built-in the MetaTrader 5 Trading Platform, allows writing your own trading robots, technical indicators, scripts and libraries of functions
 
void OnTick()
  {
   double rsi =iRSI(Symbol(), Period(), InpRSIPeriods, inpRSIPrice);
  1. iRSI does not return a double. Perhaps you should read the manual, especially the examples.
       How To Ask Questions The Smart Way. (2004)
          How To Interpret Answers.
             RTFM and STFW: How To Tell You've Seriously Screwed Up.

    They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick/OnCalculate (after the indicator has updated its buffers), you use the handle, shift and count to get the data.
              Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
              Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
              How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 (2020)
              How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 (2020)
              MQL5 for Newbies: Guide to Using Technical Indicators in Expert Advisors - MQL5 Articles (2010)
              How to call indicators in MQL5 - MQL5 Articles (2010)

  2.    static datetime priorTime=currentTime; //Initialised to prevent trading on the first bar after

    That is not an assignment; it's initialization of a common (globally declared), or static variable(s) with a constant. They work exactly the same way in MT4/MT5/C/C++.

    1. They are initialized once on program load.

    2. They don't update unless you assign to them.

    3. In C/C++ you can only initialize them with constants, and they default to zero. In MTx you should only initialize them with constants. There is no default in MT5, or MT4 with strict (which you should always use).

      MT4/MT5 actually compiles with non-constants, but the order that they are initialized is unspecified and Don't try to use any price (or indicator) or server related functions in OnInit (or on load or in OnTimer before you've received a tick), as there may be no connection/chart yet:

      1. Terminal starts.
      2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
      3. OnInit is called.
      4. For indicators OnCalculate is called with any existing history.
      5. Human may have to enter password, connection to server begins.
      6. New history is received, OnCalculate called again.
      7. A new tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

    4. Unlike indicators, EAs are not reloaded on chart change, so you must reinitialize them, if necessary.
                external static variable - MQL4 programming forum #2 (2013)

 
William Roeder #:
  1. iRSI does not return a double. Perhaps you should read the manual, especially the examples.
       How To Ask Questions The Smart Way. (2004)
          How To Interpret Answers.
             RTFM and STFW: How To Tell You've Seriously Screwed Up.

    They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick/OnCalculate (after the indicator has updated its buffers), you use the handle, shift and count to get the data.
              Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
              Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
              How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 (2020)
              How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 (2020)
              MQL5 for Newbies: Guide to Using Technical Indicators in Expert Advisors - MQL5 Articles (2010)
              How to call indicators in MQL5 - MQL5 Articles (2010)

  2. That is not an assignment; it's initialization of a common (globally declared), or static variable(s) with a constant. They work exactly the same way in MT4/MT5/C/C++.

    1. They are initialized once on program load.

    2. They don't update unless you assign to them.

    3. In C/C++ you can only initialize them with constants, and they default to zero. In MTx you should only initialize them with constants. There is no default in MT5, or MT4 with strict (which you should always use).

      MT4/MT5 actually compiles with non-constants, but the order that they are initialized is unspecified and Don't try to use any price (or indicator) or server related functions in OnInit (or on load or in OnTimer before you've received a tick), as there may be no connection/chart yet:

      1. Terminal starts.
      2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
      3. OnInit is called.
      4. For indicators OnCalculate is called with any existing history.
      5. Human may have to enter password, connection to server begins.
      6. New history is received, OnCalculate called again.
      7. A new tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

    4. Unlike indicators, EAs are not reloaded on chart change, so you must reinitialize them, if necessary.
                external static variable - MQL4 programming forum #2 (2013)

Noted, Thanks!