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

 
Artyom Trishkin #:

多布罗。让我用简单的俄语来说说吧。

你要去钓鱼。

  1. 你在家里打开茶水间,挠挠头,然后关上它。
  2. 你去钓鱼,你需要一个鱼竿。
  3. 你回家到储藏室去拿鱼竿。
  4. 去钓鱼,抛出你的鱼线,钓到一条鱼,你需要一个网。
  5. 回家后到贮藏室取网
  6. 去钓鱼,拿起你钓到的鱼,用网子浮在钩上,你需要一个容器来储存你钓到的鱼。
  7. 回家吧!.....我可以继续吗?

或者你可以直接从储藏室(OnInit)拿你需要的所有东西,不用跑来跑去就可以捕鱼,当你回到家时,把所有东西放在储藏室和冰箱里(OnDeinit)。

你可能已经知道,在论坛上。你只需要听一听,有时候听听别人怎么说。

否则,你得到一个问题,得到一个答案,说 "废话",然后按照你的想法去做。

你必须首先思考问题,提出问题,然后开始编辑。

你是否知道,编程中最简单的事情就是打印代码?而发展的大头是对逻辑的思考。

这是个可笑的比喻。在这种情况下,让我们把所有的变量、类对象等都变成全局的,而不是按需创建,或者说图形对象是别的东西(当然不是钓竿或网:)?因此,我的做法是相当理性和合理的,只是mql或metatrader搞砸了。

 
MakarFX #:
这样一来,信号就会被错过

要么是我糊涂了,要么是如果有未平仓的订单,而且有信号,并且条形图已经是新的,那就没有条件。

如果信号很长,超过一个柱状体的倍数,它也会在柱状体的第一个刻度上发挥作用。

唯一的问题是何时开立订单,是在信号出现时还是在下一个条形图的第一个点上。
 
Valeriy Yastremskiy #:

要么是我糊涂了,要么是如果有未平仓的订单,而且有信号,并且条形图已经是新的,那就没有条件。

如果信号很长,超过一个柱状体的倍数,它也会在柱状体的第一个刻度上发挥作用。

唯一的问题是订单应该在什么时候打开,是在信号出现的那一刻还是在下一个柱状图的第一个刻度。
我要求你在每个酒吧开设一个订单
 
законопослушный гражданин Sleep() 来解决这个问题,但Makar说最好不要停止进程。


现在的代码看起来像这样。

在开盘前,要检查这个蜡烛上是否有未平仓的头寸。如果没有,就打开它。

 
законопослушный гражданин #:

原则上,未平仓订单通常会在已平仓的条形图上关闭。MakarFX和Artem已经正确地指出。因此,正确的做法是这样做。

void OnTick()
  {
  datetime cTime;
  static datetime time = 0;
  int nOrders;

  cTime = iTime(NULL, PERIOD_CURRENT, 0);

  nOrders = CountOrders();

  if (time != cTime && nOrders == 0)
    time = cTime;
  else
    return;

// Получим значение индикатора
   dMA = iMA(Symbol(), 0,PeriodMA, MovingShift, MODE_SMA, PRICE_CLOSE, 0); // MODE_SMA - простое усреднение , значение 0. PRICE_CLOSE- цена закрытия, значение 0.

// Если нет открытых ордеров, то входим в условие
      if(nOrders == 0) // теперь это условие можно убрать
     {
// Если появился сигнал на покупку, то откроем ордер на покупку
      if(bSignalBuy() == true)
         vOrderOpenBuy();

// Если появился сигнал на продажу, то откроем ордер на продажу
      if(bSignalSell() == true)
         vOrderOpenSell();
     }
   }
 
Mihail Matkovskij #:

原则上,未平仓订单通常会在已平仓的条形图上关闭。MakarFX和Artem已经正确地指出。因此,正确的做法是这样的。

Artem是对的,应该是这样的

//+-----------------------------------------------------------------------------------------------+
void OnTick()
  {
// Получим значение индикатора
   dMA = iMA(Symbol(), 0,PeriodMA, MovingShift, MODE_SMA, PRICE_CLOSE, 0); // MODE_SMA - простое усреднение , значение 0. PRICE_CLOSE- цена закрытия, значение 0.

// Если нет открытых ордеров и появился сигнал на покупку, то откроем ордер на покупку
   if(CountOrders()==0&&bSignalBuy())
     {
      vOrderOpenBuy();
     }
// Если нет открытых ордеров и появился сигнал на продажу, то откроем ордер на продажу
   if(CountOrders()==0&&bSignalSell())
     {
      vOrderOpenSell();
     }
   }
 
MakarFX #:

你是对的,Artem,它应该是这样的。

这里的结果也将是一样的。只是代码更加复杂。你在两个不同的函数中写同样的代码,而且可读性也会降低。 虽然,每个人都按照自己的喜好或感觉来写...

 

这里发生了很多事情。

一个开放的职位有一个开放时间。开仓时间可以与蜡烛的时间相比较--找出开仓的时间 是否在蜡烛内(而这是当前的蜡烛)。

还有,为什么你总是在所有的例子中找出订单的数量?而如果有0个订单,那么你就打开它们。这大大限制了可能性。

一般来说,我们应该只关注一个非常狭窄的策略方向的订单/仓位数量。

 
Mihail Matkovskij #:

这里的结果将是一样的。只是代码更令人困惑。你在两个不同的函数中写同样的代码,而且可读性也会降低。 虽然,每个人都按照自己的喜好或感觉来写...

您的代码

  if (time != cTime && nOrders == 0)
    time = cTime;

(一个酒吧已经开张,没有下订单)

检查了信号 - 没有信号

...我们等待着下一次的酒吧。

你重复了上次的错误

P.S.

这就是

 time = cTime;
必须在订单开启后进行
 
MakarFX #:

你是对的,Artem,它应该是这样的

在你的代码中,如果一个仓位打开了,另一个仓位就不会被相反的信号打开。即,首先,当信号进来时,你需要检查是否有一个相反的位置并关闭它。

但同样,这一切大大限制了改进策略的可能性。

我们应该避免对订单的存在/不存在进行约束(特别是在四个方面--挂单(这是正确的)和头寸(这是错误的))。

不,手头有按类型划分的订单和头寸数量是正确和必要的。但仅仅依靠没有任何命令的信号是不对的。

一般来说,正确的方法是有计算订单和头寸的函数(当订单和头寸数量发生变化时,有一个函数填充结构)、开仓/平仓的函数、设置订单的函数和报警函数。各种拖网的功能和从指标中获取数据。另外--能够将一个头寸的数据(开仓或平仓)与一些数值进行比较。

任何战略都可以从这套方案中构建出来。