我可以创建一个使用 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 ) );
}