组织订单周期 - 页 14

 
Andrey Khatimlianskii:

OrderClose是否保证关闭交易?

不保证,但代码中对此有一个检查。每个OnTick调用都是独立于前一个的。

 
fxsaber:

不保证,但代码中对这种情况有一个检查。每个OnTick调用都是独立于前一个的。

好的,在下一次打勾时关闭就可以了。

 
@Artyom Trishkin,@Andrey Khatimlianskii, 感谢你们的参与!很遗憾,没有人对MT5的代码 进行评论。显然,他们认为一切都很好。
 
fxsaber:
@Artyom Trishkin,@Andrey Khatimlianskii, 感谢您的参与!很遗憾,没有人对MT5的代码 进行评论。显然,他们认为一切都很好。

当然,举这个例子是为了回答,MT5中的一切都不太妙。显示问题的例子

// Пример неправильного считывания торгового окружения на каждом тике
// Скрипт эмулирует два тика ТС, которая должна открыть одну позицию, если ее нет.

#include <Trade/Trade.mqh>

// Возвращает количество позиций по символу
int GetAmountPositions( const string Symb )
{
  int Res = 0;
  
  // Этот MQL5-код с ошибкой
  for (int i = PositionsTotal() - 1; i >= 0; i--)
    if (PositionGetSymbol(i) == Symb)
      Res++;

/*
  // В MT4 такой код выполняется без ошибки
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (OrderSymbol() == Symb))
      Res++;
*/      
  return(Res);
}

// Пример OnTick
void ExampleOnTick()
{
  static CTrade Trade;
  
  // Если нет позиции, открываем
  if (!GetAmountPositions(_Symbol))
    Trade.Buy(1);    
}

// Эмуляция прихода двух Tick-событий
void OnStart()
{
  ExampleOnTick(); 
  
  Sleep(10); // Между двумя тиками ~10 мс.
  
  ExampleOnTick();
}

你认为,如果你在一个没有位置的符号上运行这个脚本,最后会发生什么?

正确的答案是,将开设一个或两个职位

 
fxsaber:

当然,举这个例子是为了回答,MT5中的一切都不太妙。显示问题的例子

你认为,如果你在一个没有位置的符号上运行这个脚本,最后会发生什么?

正确的答案是,将开设一个或两个职位

因此,Kodobase中的绝大多数MT5专家顾问都没有被正确地编写出来

 
fxsaber:
很少有人会反驳这种说法

这是一个普遍的规则。但没有多少人想到它在MT5中的实施。这就是为什么我写了一个最简单的TS模板(在kodobase中,几乎所有的TS都是这样的)。

由于某些原因,有些人为了同样的TS写了更多的代码。但事实上,这段代码做得同样好。大多数TC只需要写BuySignal和SellSignal。不需要其他任何东西。

该模板的例子是专门用SB写的。所以问一下MT5专家,这个代码是否正确?

我是无意中来到这个话题的,其实是想开个话题来讨论策略模板。你的模板足够接近我认为正确的东西(对我来说是可读的),但我仍然不喜欢在OnTick中插入一个函数的调用,这隐藏了整个采矿厂。

我甚至一度写过《MetaEditor: Relying on the power of templates。 从那时起,语言就变了,没有模板编辑器讨论这个问题会很有趣(可以在一个单独的主题中),也可以得到一篇关于这个问题的文章。我认为,在写代码时,应该尽量使策略一目了然,而不必深入到类或宏方法中去。

 
fxsaber:

结果是--Kodobaz中的绝大多数MT5专家顾问都没有被正确地编写出来

像往常一样--断然地。不可能,虽然我还没有读过你的代码。

 
Rashid Umarov:

我一直想开一个讨论策略模板的话题,已经很久了。你的模板足够接近我认为正确的东西(对我来说是可读的),但我还是不喜欢在OnTick中插入一个函数的调用,这隐藏了整个采矿厂。

如果你让OnTick == Strategy,模板会缩小/收缩到一个令人讨厌的大小。

有一次,我甚至写了一篇文章MetaEditor: Building on the power of templates. 从那时起,语言就变了,没有模板编辑器。讨论这个问题会很有趣(可以在一个单独的主题中),也可以得到一篇关于这个问题的文章。我认为,在写代码时,应该尽量使策略一目了然,而不必深入到类或宏方法中去。

这两个平台的模板是这样显示的。它是如此简单,以至于很难讨论它,尽管对于MT5来说,它从根本上是错误的。但你有CExpert。我自己没有看过那里--那是很可怕的。

 
Rashid Umarov:

像往常一样--断然的。不可能,虽然我还没有读过你的代码

你读了,你的意见很有意思。

 
fxsaber:

当然,举这个例子是为了回答MT5中的一切都不尽人意。显示问题的例子

你认为,如果你在一个没有位置的符号上运行这个脚本,最后会发生什么?

正确的答案是,将开设一个或两个职位

如果我们用标准的OnTradeTransaction 取代GetAmountPositions?

大约是这样的。

#include <Trade/Trade.mqh>
  int Res = 0;

// Возвращает количество позиций по символу
/*********************TradeTransaction function*********************/
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
{
  if(trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.symbol == _Symbol)
   {
    /******************** Если открылась позиция********************/
    if(PositionSelectByTicket(trans.position))
     Res++;
    /******************** Если закрылась позиция********************/
    if(!PositionSelectByTicket(trans.position))
     Res--;
   }
}/*******************************************************************/

// Пример OnTick
void ExampleOnTick()
{
  static CTrade Trade;
  
  // Если нет позиции, открываем
  if (Res == 0)
    Trade.Buy(1);    
}

// Эмуляция прихода двух Tick-событий
void OnStart()
{
  ExampleOnTick(); 
  
  Sleep(10); // Между двумя тиками ~10 мс.
  
  ExampleOnTick();
}