新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 - 页 248

 
STARIJ:

互联网恢复了!我可以给邮局写信吗?


是的,我正在联系。给我发短信。

 

帮助完善EA 我是一个程序员新手,描述。

该顾问在两个货币对EURUSD和USDCHF上工作,它只在出现10pp背离时开启两个买入交易(基本上是一个标准的仲裁者)。

这里是条件:如果((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point)|(ind2<ind1-impulse*Point && ind3>ind4+impulse*Point))。

而当总利润/亏损达到一定数值时,它就会关闭。如果((AccountProfit()>=10)|(AccountProfit()<=20))


问题:它并不总是打开两个交易,有时会打开三个。或者它开出两笔相同货币的交易。它需要:总是在不同的货币上打开2个交易(一个--欧元兑美元;另一个--美元兑瑞士法郎)。



下面是代码本身。


外部双脉冲 = 10; //全局变量

外来的双倍Lots = 1;


int start()

{

double ind2=iClose("EURUSD",PERIOD_M1,0)。

double ind1=iOpen("EURUSD",PERIOD_M1,0)。


double ind3=iClose("USDCHF",PERIOD_M1,0)。

double ind4=iOpen("USDCHF",PERIOD_M1,0);


double oper1=ind2-ind1。

double EUR=(int)DoubleToStr(oper1*100000,0);


双重操作2=ind3-ind4。

double CHF=(int)DoubleToStr(oper2*100000,0);


Comment(StringFormat("Output data\nEUR = %G\nCHF =%G",EUR,CHF))。

如果((AccountProfit()>=10)|(AccountProfit()<=20))// 结案条件

Alert3()。

如果((ind2>ind1+impulse*Point &&ind3<ind4-impulse*Point) ||(ind2<ind1-impulse*Point &&ind3>ind4+impulse*Point)//开放条件

如果(OrdersTotal() == 0)

Alert1()。

如果(OrdersTotal() == 1)

Alert2()。

return(0);

}


int Alert1()

{

如果(OrdersTotal() == 0)

int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0)。

return(0);

}


int Alert2()

{

如果(OrdersTotal() == 1)

int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0)。

return(0);

}


int Alert3()

{

while (OrdersTotal()>0)

如果(OrderSelect(0, SELECT_BY_POS, MODE_TRADES))//关闭

int cl1=OrderClose (OrderTicket(),OrderLots(), Bid,3);

int cl1=OrderClose (OrderTicket(),OrderLots(),Ask,3)。

return(0);

}

 

Alexey Belyakov:  CУТЬ ПРОБЛЕММЫ: Не всегда открывает 2 сделки, а бывает открывает 3. Или открывает две сделки по одной валюте. Нужно чтобы: открывал всегда 2 сделки по разным валютам ( одна - по EURUSD; другая- по USDCHF)

服务器被命令打开欧元。当它到达服务器时,当服务器 ...到目前为止,还没有订单。在下一个嘀嗒声中,该条件再次得到满足,并再次下单开出欧元。服务器已经打开了第一个订单。由于有1个订单,所以发送了打开第二个(已经是第三个了!)订单的命令。

我已经使所有的功能无效,并删除了返回。这里是程序的这一部分(我们按了SRC按钮来插入它)。

  if((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) ||
     (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point))   // Условие открытия
     if(OrdersTotal() == 0) Alert1();
     if(OrdersTotal() == 1) Alert2();
}

void Alert1()
{
  if (OrdersTotal() == 0)  // Перед вызовом этой функции уже проверялось количество ордеров
  int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0);
}

void Alert2()
{
  if(OrdersTotal() == 1)  // Перед вызовом этой функции уже проверялось количество ордеров
  int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0);
}

并将其替换为(有点粗糙,但IMHO认为它比原来的好)。

  if((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) ||
     (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point))   // Условие открытия
     if(OrdersTotal() == 0)
  {
    int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0); 
    int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0);
    Sleep(60); // Дождаться следующего бара, а то еще пооткрывает
  }
}

Alert3函数 中,有一个额外的行

  int cl1=OrderClose (OrderTicket(),OrderLots(),Ask,3);
而不是double CHF=(int)DoubleToStr(oper2*100000,0); try int CHF=oper2/_Point;
 
STARIJ:

取而代之的是(粗制滥造,但比原来的好)。

并不粗鲁,但会有错误的工作。如果只是因为这两份命令都是由相同性质的阿斯克来执行。
 
Alexey Kozitsyn:   并不粗鲁,但会有错误的工作。如果只是因为这两个订单都是通过询问同一个符号。

当然,你是完全正确的。此外,这个错误就在源代码中,但它是通过使用作者和你以及我这个罪人的函数来伪装的。在我删除了这些功能之后,这个错误变得很明显。我认为,只有在EA所在的图表上的符号才会被开仓。对吗?

 
STARIJ:

当然,你是完全正确的。而这个错误包含在源代码中,但它被作者、你和有罪的我使用的函数所掩盖。在我删除了这些功能之后,这个错误变得很明显。我认为,只有在EA所在的图表上的符号才会被开仓。对吗?

是的,当然,如果开放的条件得到满足。第二个符号的询问应单独获得。
 
大家好。这个问题很幼稚,它涉及函数OrdersTotal()。很明显,它返回的是订单的数量,而订单的编号是从0到N。但如果从历史上新开的条形图开始编号,即 "新 "条形图的编号是0,"旧 "条形图的编号是N。而在函数OrdersTotal()中,我理解一切都发生在相反的地方--最古老的未结订单被编号为0,而 "新 "的订单被编号为N。我说对了吗?
 
Youri Lazurenko:
大家好。这个问题很幼稚,它涉及函数OrdersTotal()。很明显,它返回的是订单的数量,而订单的编号是从0到N。但如果从历史上新开的条形图开始编号,即一个 "新 "条形图被编号为0,而一个旧条形图被编号为N。而在函数OrdersTotal()中,我理解一切都发生在相反的地方--最古老的未结订单被编号为0,而 "新 "的订单被编号为N。我说对了吗?

是的,但有一些细微的差别。

曾几何时,分拣工作依赖于终端的分拣。没有用户可以肯定地说,如果那个时间会 "突然 "回来,那时的排序将再次取决于终端的排序。这就是为什么在一个数组中收集订单并按其开/关时间排序更可靠的原因 - 然后你将确定你的排序取决于时间,而不是 "突然 "在终端中进行排序。

 
Artyom Trishkin:

是的,但有一些细微的差别。

曾几何时,分拣工作依赖于终端的分拣。没有用户可以肯定地说,如果那个时间会 "突然 "回来,那时的排序将再次取决于终端的排序。这就是为什么最好在数组中收集订单,并按打开/关闭时间进行排序 - 然后你将确定你的排序取决于时间,而不是 "突然 "在终端中进行排序。


你好。谢谢你的答复。首先我想回到你之前对我问题的回答,关于逆向循环。昨天,在我去上班之前,我写了一个回复,而今天,我完全找不到我(和你)的帖子。据我所知,我在一个错误的分支中问了这个问题。反向循环是i--?

"这就是为什么把订单收集在一个数组中并按开/关时间 排序更可靠"--这非常有趣,我认为这更可靠和正确(在我看来,当你定义最后一个订单时,它并不总是能得到你所需要的)。如果这不难,我怎么做(按开放时间创建一个阵列)?

还有一件事。我还没有试过。我们有一个盈利的和亏损(锁定)的订单。盈利订单使用拖曳止损进行平仓。我希望有一个订单被关闭的说明,以便将其总利润与亏损的订单进行比较,如果余额为正数,则关闭亏损的订单。我感兴趣的是到底有哪些订单被关闭了。

 
STARIJ:

我认为仓位只会在EA所在图表的符号上打开。对吗?

如果你的专家顾问正在操作欧元兑美元,但你想在美元兑瑞郎上下买入订单

那么在OrderSend 中你应该使用MarketInfo("USDCHF",MODE_ASK);而不是Ask(它将用于EURUSD)。

原因: