我可以制作一个使用 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
。
当我在 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
。