1

When I try to run this while-loop in MQL4, it can not seem to update the rsi from within the loop. It always returns the same value of the rsi and thus stays in an eternal loop. I have tried it on an EA as well as a script.

I have also tried making rsi a globally defined variable too but still did not work.

void OnTick()
{

     double rsi = iRSI(NULL,0,14,PRICE_CLOSE,0);        // defining rsi
                 
     while( rsi < 50 )
     {
            double rsi = iRSI(NULL,0,14,PRICE_CLOSE,0); // update rsi 
            Sleep(10000);                               // slow down loop 
            Alert("this is from inside while loop rsi is "+rsi); 
     }
        
     Alert("While loop exited, condition met");         // now code goes
     Alert("opening an order now " );                   //     to place an order
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Nak1987
  • 25
  • 1
  • 6

2 Answers2

1

Can I make a while-loop that uses RSI value as the condition?

Oh sure you can.

Let's move out the colliding elements.

Given the code as-is, there are several brutal misconceptions to repair:

  • if a code spends some time "inside" such a loop, there will never be heard a new incoming QUOTE-message from market, so your Close[0]-value will remain "blind" to any such update from Market.
  • if a second double rsi = ... declaration takes place "inside" a scope of a while-loop-constructor, the newer versions ( Builds ) of the MQL4 language will actually "mask" the older ( "outer" ) variable, that is yet still used in the loop-constructor control variables / conditions. Result? You assign "new" values to an "inner"-variable, that bears just by coincidence a same name as the "outer"-variable ( both are named rsi, yet the "inner" keeps-masking the "outer", so the "outer" never gets any update(s), if any such were stored inside the loop into the "inner" )

Solution

  • avoid masking by not declaring any same-name named variables (always, it is a sign of good engineering practice)
  • avoid receiving market-QUOTE-updates by deaf-loop-locking - prefer the non-blocking use of if(){...} instead of while(){...}

MQL4 is a responsive-ecosystem, where OnTick() is automatically called whenever a new QUOTE-message arrives from FX-Market, so design your algorithms so as these never block.

For your learning-directed inspiration, you may try your next few steps using this template :

string MASK  = "[%s]_INF:: "                           // DEF. & INIT...
             + "This is a QUOTE# %5d "
             + "Having arrived at [%s]_FX-MarketTIME\n"
             + "|Ask %16.8f\n"
             + "|Bid %16.8f\n"
             + "|Vol %16d\n"
             + "|RSI %16.8f";
double rsi   = EMPTY;                                  // DEF. & INIT...
int   nTicks = 0;                                      // DEF. & INIT...

void OnDeinit( const int aDeinitReason )
{    EventKillTimer();
}

int  OnInit()
{    EventSetTimer( 1 );
     Comment( "------------------------------------------------------\n ",
                    "WAITING for a first QUOTE-arrival from FX-Market\n",
              "------------------------------------------------------"
               );
     return( 0 );
}

void OnTick()
{     nTicks++;                                        // update COUNTER
     rsi = iRSI( NULL, 0, 14, PRICE_CLOSE, 0 );        // update rsi
     Comment( SetupComment() );                        // update GUI

  // -------------------------------- FIRST 50 FX-Market Ticks delivered
     if ( nTicks < 50 ) return;

  // -------------------------------- AFTER 50 FX-Market Ticks delivered
  // --------------------------------       BE WARNED, THIS IS AN AWFUL ANTI-PATTERN
     while( True )
     {
            rsi = iRSI( NULL, 0, 14, PRICE_CLOSE, 0 ); // update rsi
            Comment( SetupComment() );                 // update GUI
            Sleep( 10000 );
     }
  // --------------------------------       NEVER GETS HERE
     Alert( "?" );
}

string SetupComment()
{      return( StringFormat( MASK,
                             TimeToStr( TimeLocal(),
                                        TIME_DATE|TIME_MINUTES|TIME_SECONDS
                                        ),
                             nTicks,
                             TimeToStr( TimeCurrent(),
                                        TIME_DATE|TIME_MINUTES|TIME_SECONDS
                                        ),
                             NormalizeDouble( Ask, 8 ),
                             NormalizeDouble( Bid, 8 ),
                             Volume[0],
                             NormalizeDouble( rsi, 8 )
                             )
               );
}

void OnTimer()
{    Comment( ChartGetString( 0, CHART_COMMENT ),
              "\n",
              TimeToStr( TimeLocal(),
                         TIME_DATE|TIME_MINUTES|TIME_SECONDS
                         )
              );
     Print(   ChartGetString( 0, CHART_COMMENT ) );
}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user3666197
  • 1
  • 6
  • 50
  • 92
  • Hello and thank you very much, I am closer to figuring this out but have still been unsuccessful. I don't want to make you think I am ungrateful for your very detailed and educational answer but can you tie my shoe for me and give me an example please >.< . – Nak1987 Aug 27 '20 at 03:03
  • Oh by the way, I have basically already used a bunch of if statements in my EA's code and after them comes the while loop as a final condition which I think its actually needed in my situation. I don't think I can get away without it and still get what I want out of the code .... – Nak1987 Aug 27 '20 at 03:06
  • Yes , so true , you are right and I have learned more too. I appreciate this gift from you that I will try to incorporate and experiment with . Thank you for teaching me and a wonderful teacher you are too!! – Nak1987 Aug 27 '20 at 16:57
  • This is going to take me a good while to understand but I will go through it line by line and break it down . Thank you for your time . Anything I can do for you going forward ?? – Nak1987 Aug 27 '20 at 18:08
  • Hi user3666197, long time no speak. I hope you are well. Just a quick reminder that posts should not give question-asking advice - you are welcome to give it, but it's best in the comments (under the question or under the answer, as here). Answers themselves should address a broad audience and not get bogged down in meta-commentary. (It's good advice though). – halfer Aug 27 '20 at 20:53
-1

Declare rsi only once, outside the loop, as you already have it. To make it work as you intend REMOVE the type double from in front of variable rsi inside the loop.

jps
  • 20,041
  • 15
  • 75
  • 79
Tex
  • 1