我可以制作一个使用 RSI 值作为条件的 while 循环吗?

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

当我在 MQL4 中尝试 运行 这个 while 循环时,它似乎无法更新 rsi环形。它总是 returns 与 rsi 相同的值,因此处于一个永恒的循环中。我已经在 EA 和脚本上试过了。

我也试过使 rsi 成为全局定义的变量,但仍然没有用。

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
}

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

当然可以。

让我们移出碰撞元素。

给定代码 as-is,有几个严重的误解需要修复:

  • 如果代码在这样的循环“内部”花费一些时间,将永远不会听到来自市场的新传入 QUOTE-消息,因此您的 Close[0]-value 将保持“盲”来自市场的任何此类更新。
  • 如果第二个 double rsi = ... 声明发生在 while-loop-constructor 范围的“内部”,较新的版本(构建) MQL4 语言实际上将“屏蔽”较旧的(“外部”)变量,该变量仍在 loop-constructor 控制变量/条件中使用。结果?您将“新”值分配给“内部”变量,该变量恰好与“外部”变量同名(两者都命名为 rsi,但“inner" keeps-masking “外部”,所以“外部”永远不会得到任何更新,如果任何更新存储在循环内到“内部”中)

解决方案

  • 通过不声明任何 same-name 命名变量来避免屏蔽(总是,这是良好工程实践的标志)
  • 避免接收 deaf-loop-locking 的市场-QUOTE-更新 - 更喜欢 non-blocking 使用 if(){...} 而不是 while(){...}

MQL4 是一个 responsive-ecosystem,其中 OnTick() 会在新的 QUOTE 消息从 FX-Market 到达时自动调用,因此请设计您的算法以使这些 永不阻塞。

为了您的 learning-directed 灵感,您可以使用此模板尝试接下来的几个步骤:

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 ) );
}

只在循环外声明一次rsi,因为你已经有了它。要使其按您的预期工作,请从循环内变量 rsi 前面删除类型 double