【问题标题】:Can I make a while-loop that uses RSI value as the condition?我可以制作一个使用 RSI 值作为条件的 while 循环吗?
【发布时间】:2020-08-24 06:22:19
【问题描述】:

当我尝试在 MQL4 中运行这个 while-循环时,它似乎无法从循环内更新 rsi。它总是返回与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
}

【问题讨论】:

    标签: mql4 algorithmic-trading metatrader4 forex mt4


    【解决方案1】:

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

    哦,当然可以。

    让我们移出碰撞的元素。

    鉴于代码原样,有几个残酷的误解需要修复:

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

    解决方案

    • 通过不声明任何同名命名变量来避免屏蔽(始终,这是良好工程实践的标志)
    • 避免通过 deaf-loop-locking 接收 market-QUOTE-updates - 更喜欢非阻塞使用 if(){...} 而不是 while(){...}

    MQL4 是一个响应式生态系统,每当有新的QUOTE-消息从 FX-Market 到达时,OnTick() 就会被自动调用,因此请设计您的算法以使这些永远不会阻塞。

    为了获得以学习为导向的灵感,您可以使用此模板尝试接下来的几个步骤:

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

    【讨论】:

    • 您好,非常感谢您,我更接近于解决这个问题,但仍然没有成功。我不想让你认为我对你非常详细和有教育意义的回答不感激,但你能帮我系鞋带,给我一个例子吗>.
    • 哦,顺便说一句,我基本上已经在我的 EA 代码中使用了一堆 if 语句,在它们之后是 while 循环作为我认为在我的情况下实际需要的最终条件。我认为没有它我就无法逃脱,并且仍然可以从代码中得到我想要的东西......
    • 是的,没错,你是对的,我也学到了更多。我很感激你给我的这份礼物,我会尝试融入和试验。谢谢你教我,你也是一位了不起的老师!!
    • 这需要我很长时间才能理解,但我会逐行阅读并分解。感谢您的时间 。有什么我能为你做的吗??
    • 您好 user3666197,好久没说话了。我希望你一切都好。只是快速提醒一下,帖子不应该提供提问建议 - 欢迎您提供,但最好在 cmets 中(在问题或答案下,如这里)。答案本身应该针对广泛的受众,而不是陷入元评论。 (不过这是个好建议)。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-03
      • 2019-11-01
      • 2015-03-02
      • 2015-09-08
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多