编码帮助 - 页 39

 

我写了这行代码。

int TriggerChart = PERIOD_H4;

int FastMACDPeriod = 12;

int SlowMACDPeriod = 26 ;

int SignalPeriod = 9;

MacdCurrent = iMACD(Symbol(), TriggerChart, FastMACDPeriod,SlowMACDPeriod,SignalPeriod, PRICE_CLOSE, MODE_MAIN, 1)。

插入这些变量后,我想知道EA是否能够识别TriggerChart是 "int timeframe",而其他的用于int periods?会不会是在它们都在一起的情况下,它看到TriggerChart和FastMACDPeriod,认为它们都与int时间框架有关而感到困惑?在什么情况下,EA会识别哪个变量适用于iMACD的哪个部分?

 

...

简而言之:不,它不会混淆(计算机在这方面很好,它们不思考,但它们反复执行同样的事情而不进行解释),只有编码员会不时地混淆。

当你调用一个函数 时,它按一定的顺序(位置)接受参数(例如:第一个参数是符号,第二个是时间范围,等等)。当你调用一个函数时,你如何声明(类型)变量是完全相关的:它们被严格使用取决于它们在参数调用列表中的位置

crsnape@btinternet.com:
我写了这行代码。

int TriggerChart = PERIOD_H4;

int FastMACDPeriod = 12;

int SlowMACDPeriod = 26 ;

int SignalPeriod = 9;

MacdCurrent = iMACD(Symbol(), TriggerChart, FastMACDPeriod,SlowMACDPeriod,SignalPeriod, PRICE_CLOSE, MODE_MAIN, 1);

插入这些变量后,我想知道EA是否能够识别TriggerChart是 "int timeframe",而其他变量用于int periods?会不会是在它们都在一起的情况下,它看到TriggerChart和FastMACDPeriod,认为它们都与int时间框架有关而感到困惑?在什么情况下,EA会识别哪个变量适用于iMACD的哪个部分?
 

谢谢mladen。听起来很合乎逻辑。

在这段代码中,我在int init()函数 中声明BarsGV为0。但是,正如你说的那样,如果我得到一个错误,它仍然返回错误。我在想,与其在int init()中声明为0,不如将其重置为1。你怎么看?我有一个200SMA,如果Bars小于200,无论如何都会出现错误。

所以用这个代替。

int init()

{

//---

GlobalVariableSet(BarsGV,0)。

//---

return(0);

}

这是在int start()下

如果((GlobalVariableGet (BarsGV) == 0)|| (GlobalVariableGet (BarsGV) < Bars))

{

GlobalVariableSet(HasOrderedGV, false)。

GlobalVariableSet(BarsGV, Bars)。

}

//--- 检查多头头寸(BUY)的可能性

如果(GlobalVariableGet (HasOrderedGV) == false)

{

改为这样。

int init()

{

//---

GlobalVariableSet(BarsGV,1)。

//---

返回(0)。

}

这是在int start()下

如果(GlobalVariableGet (BarsGV) == 0)。

{

Print("全局变量BarsGV的错误", GetLastError())。

return(0);

}

如果(GlobalVariableGet (BarsGV) < Bars)

{

GlobalVariableSet(HasOrderedGV, false)。

GlobalVariableSet(BarsGV, Bars)。

}

//--- 检查多头头寸(BUY)的可能性

如果(GlobalVariableGet (HasOrderedGV) == false)

{

你怎么看?

 

...

把它改成这样。

int BarsGV;

bool HasOrderedGV;

int init()

{

//---

BarsGV=0;

HasOrderedGV=false;

//---

return(0);

}

THIS IS UNDER INT START()

if (BarsGV < Bars)

{

HasOrderedGV=false;

BarsGV=Bars;

}

//--- Check for long position (BUY) possibility

if (HasOrderedGV == false)

{[/PHP]

That way you are going to avoid other EA interference and you will keep the variables to only one instance of Ea (they can not mix at all). Much better to do it that way (even from the speed of execution point of view). But you still risk of opening a new order on a same bar this way. The best way is to use a function to count orders opened at the current bar and then allow or disallow ner order opening

Here is a function that can do that (it will check currently opened as well as already closed orders if they have been opened on a current bar) :

bool uniqueOnBar(int MagicNumber)

{

datetime startTime = Time[0];

datetime endTime = startTime+60*Period();

for (int i=OrdersTotal()-1; i>=0; i--)

{

if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;

if (OrderSymbol() != Symbol()) continue;

if (OrderMagicNumber() != MagicNumber) continue;

if (OrderOpenTime()endTime) continue;

return(false);

}

for (i=OrdersHistoryTotal()-1; i>=0; i--)

{

if (!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) continue;

if (OrderSymbol() != Symbol()) continue;

if (OrderMagicNumber() != MagicNumber) continue;

if (OrderOpenTime()endTime) continue;

return(false);

}

return(true);

}

Checking would be very simple :

[PHP]if (uniqueOnBar(MagicNumber)) .... you can open an a new order

这样你就不会依赖任何变量,而只依赖订单,这是唯一100%可靠的方法。

crsnape@btinternet.com:
谢谢mladen。听起来很合乎逻辑。

在这段代码中,我已经在int init()函数中声明BarsGV为0。但是,正如你说的那样,如果我得到一个错误,它仍然返回错误。我在想,与其在int init()中声明为0,不如将其重置为1。你怎么看?我有一个200SMA,如果Bars小于200,无论如何都会在这里出错。

所以用这个代替。

int init()

{

//---

GlobalVariableSet(BarsGV,0)。

//---

return(0);

}

这是在int start()下

如果((GlobalVariableGet (BarsGV) == 0)|| (GlobalVariableGet (BarsGV) < Bars))

{

GlobalVariableSet(HasOrderedGV, false)。

GlobalVariableSet(BarsGV, Bars)。

}

//--- 检查多头头寸(BUY)的可能性

如果(GlobalVariableGet (HasOrderedGV) == false)

{

改为这样。

int init()

{

//---

GlobalVariableSet(BarsGV,1)。

//---

返回(0)。

}

这是在int start()下

如果(GlobalVariableGet (BarsGV) == 0)。

{

Print("全局变量BarsGV的错误", GetLastError())。

return(0);

}

如果(GlobalVariableGet (BarsGV) < Bars)

{

GlobalVariableSet(HasOrderedGV, false)。

GlobalVariableSet(BarsGV, Bars)。

}

//--- 检查多头头寸(BUY)的可能性

如果(GlobalVariableGet (HasOrderedGV) == false)

{

你怎么看?
 

超级明星。谢谢。

 

你好,mladen。

这一部分。

datetime EndTime = StartTime + 60 * Period();

Period()是指图表中的时间框架。所以说H4(240)*60,因为EndTime是以秒为单位记录的,所以将240分钟转换为秒,以对应Period(240)的分钟数?

我的理解对吗?

是不是也可以这样写。

datetime EndTime = (StartTime / 60) + Period(); ?

 

...

是的,你没看错

至于其他的形式:你不能使用,因为OrderOpenTime()是标准的日期时间格式,这意味着在EndTime中你必须有自1970年1月1日以来的秒数,而你写的方式将包含分钟--metatrader会认为这些是秒,它将给出所有错误的结果。

crsnape@btinternet.com:
嗨,mladen。

这一部分。

datetime EndTime = StartTime + 60 * Period();

Period()是指图表中的时间框架。所以说H4(240)*60,因为EndTime是以秒为单位记录的,所以要把240分钟转换为秒来对应Period(240)的分钟数?

我的理解对吗?

是不是也可以这样写。

datetime EndTime = (StartTime / 60) + Period(); ?
 

你好mladen,这里的for循环是选择最后开仓的还是挂单 的?

bool UniqueOnBar (int MagicNumber)

{

datetime StartTime = Time[0];

datetime EndTime = StartTime + 60 * Period (TriggerChart);

for (int i = OrdersTotal() - 1; i >= 0; i--)

{

if (!OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) 继续。

如果(OrderSymbol() != Symbol())继续。

如果(OrderMagicNumber() != MagicNumber)继续。

如果(OrderOpenTime() endTime)继续。

返回(false)。

}

所以在感叹号被解释为'不'的地方,我想这是不对的,因为我想。

- 选择最新的开仓或挂单,所以删除!留下OrderSelect?

- OrderSymbol()与Symbol()相同。

- OrderMagicNumber()等于MagicNumber,所以......留下这个。

intTriggerChart= PERIOD_H4;

int MagicNumber = 42;

bool UniqueOnBar (int MagicNumber)

{

datetime StartTime = Time[0];

datetime EndTime = StartTime + 60 * Period(TriggerChart);

for (int i = OrdersTotal() - 1; i >= 0; i--)

{

如果(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))继续。

如果(OrderSymbol() == Symbol() )继续。

如果(OrderMagicNumber() == MagicNumber)继续。

如果(OrderOpenTime() endTime)继续。

返回(false)。

}

 

我的疏忽,我现在意识到,当表达式返回 "真 "时,在当前栏中没有开仓的订单被拾起。

 

...

是的,它是这样的。因此,如果它的返回值为 "true",你就可以打开一个新的订单。

另外,如果你想测试与当前时间 段不同的时间段,如果订单在目标时间段的当前条上被打开,那么这个函数可以改成像这样。

bool UniqueOnBar (int MagicNumber, int timeFrame=0)

{

if (timeFrame==0) timeFrame=Period();

datetime StartTime = iTime(NULL,timeFrame,0);

datetime EndTime = StartTime + 60*timeFrame;

for (int i=OrdersTotal()-1; i>=0; i--)

{

if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;

if (OrderSymbol() == Symbol()) continue;

if (OrderMagicNumber() == MagicNumber) continue;

if (OrderOpenTime() EndTime) continue;

return(false);

}

return(true);

}

[/PHP]

And then the call to it would be for your example 2 posts ago

[PHP]if (UniqueOnBar(MagicNumber,TriggerChart) ... open an order

PS: 你从例子中删除了对关闭订单的检查。如果你也想检查已关闭的订单,也可以使用原函数的第二部分。

crsnape@btinternet.com:
我的疏忽,我现在意识到,当表达式返回 "真 "时,在当前条形图上没有开仓的订单被选中。