程序库: MT4 订单快速报告 - 页 5

 
Forester #:

服务器:MetaQuotes-Demo Hedge
处理第二页上的第 99 票。

有点本地化。

#include <MT4Orders.mqh>

void OnTick ()
{
  static int Count = 0;
  
  if (Count > 6)
    return;
  
  MqlTick Tick;
  SymbolInfoTick(_Symbol, Tick);
  
  const double Offset = 5 * _Point;
  bool Buy =  false;
  bool Sell =  false;

  for (uint i = OrdersTotal(); (bool)i--;)
    if (OrderSelect(i, SELECT_BY_POS))         
    {
      if(OrderMagicNumber())
        switch (OrderType())
        {
        case OP_BUY:
          OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.bid + Offset, 0);
          Buy = true;
         
         break;
        case OP_SELL:
          OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.ask - Offset, 0);
          Sell = true;
         
         break;
        case OP_BUYLIMIT:
          OrderModify(OrderTicket(), Tick.ask - Offset, 0, 0, 0);
          Buy = true;
         
         break;
        case OP_SELLLIMIT:          
          OrderModify(OrderTicket(), Tick.bid + Offset, 0, 0, 0);
          Sell = true;
         
         break;
        }
      else
        OrderDelete(OrderTicket());
    }

  if (!Buy)
    OrderSend(_Symbol, OP_BUYLIMIT, 1, Tick.ask - Offset, 0, 0, 0, NULL, ++Count);

  if (!Sell)
    OrderSend(_Symbol, OP_SELLLIMIT, 1, Tick.bid + Offset, 0, 0, 0, NULL, ++Count);
  
  OrderSend(_Symbol, OP_BUYLIMIT, 1,  Tick.ask - Offset, 0, Tick.ask - Offset, Tick.ask - Offset);
  Count++;
}

string TimeToString( const long Time )
{
  return((string)(datetime)(Time / 1000) + "." + IntegerToString(Time % 1000, 3, '0'));
}

void OnDeinit( const int )
{
  if (HistorySelect(0, INT_MAX))
    for (uint i = HistoryOrdersTotal(); (bool)i--;)
    {
      const ulong Ticket = HistoryOrderGetTicket(i);
      
      Print((string)i + ": " + (string)Ticket + " " + TimeToString(HistoryOrderGetInteger(Ticket, ORDER_TIME_DONE_MSC)));
    }
}


EA 在做什么并不重要。最重要的是突出显示的代码,它只是显示交易历史中的 MT5 订单:订单的位置、票据和进入历史的时间。

11: 13 2023.05.29 23:54:39.425
10: 12 2023.05.29 00:04:25.870
 9: 11 2023.05.29 00:03:59.331
 8: 10 2023.05.29 00:03:59.430
 7: 9 2023.05.29 00:03:59.281
 6: 8 2023.05.29 00:03:59.281
 5: 7 2023.05.29 00:03:59.227
 4: 3 2023.05.29 00:03:59.331
 3: 6 2023.05.29 00:03:18.390
 2: 5 2023.05.29 00:03:18.390
 1: 4 2023.05.29 00:02:41.107
 0: 2 2023.05.29 00:02:41.107

在历史记录表格中,MT5 订单不按票据或时间排序。我不认为向开发人员报告 MQ-Tester 的这种行为有什么意义。毕竟,"任务过重"。

因此,我不会将 MQ-Tester 标准化。

 
fxsaber #:

有点局部性。


EA 做什么并不重要。最重要的是一个专用代码,它可以简单地从交易历史中输出 MT5 订单:订单位置、订单票据和进入历史的时间。

在历史记录表格中,MT5 订单不按票据或时间排序。我不认为向开发人员报告 MQ-Tester 的这种行为有什么意义。毕竟,"任务已经超额完成"。

因此,我不会将 MQ-Tester 标准化。

我认为,限价订单在关闭时有自己的队列转入历史记录。而不是在每个勾选时。
如果他们不需要修复首次测试交易和掉期中的明显错误(几周前我已对此打了折扣),那么这只是一个功能。混乱矩阵更重要....
 
有时候,知道这一点很好。
// 从设定时间开始缩减的最长持续时间。
int MaxLengthDD( datetime &BeginDD, datetime &EndDD, const datetime From = 0 )
{
  const int Total = OrdersHistoryTotal();
  
  double Profit = 0;
  double MaxProfit = 0;
  datetime Begin = 0;
  
  BeginDD = 0;
  EndDD = 0;
  
  for (int i = 0; i < Total; i++)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      if (!Begin && (OrderOpenTime() > From))
        Begin = OrderOpenTime();
        
      Profit += OrderProfit() + OrderSwap() + OrderCommission();
      
      if ((Profit > MaxProfit) || (i == Total - 1))
      {
        MaxProfit = Profit;
        
        const datetime End = OrderCloseTime();        
        
        if (Begin && (End - Begin > EndDD - BeginDD))
        {
          BeginDD = Begin;
          EndDD = End;
        }
        
        if (Begin)
          Begin = End;
      }
    }
    
  return((int)(EndDD - BeginDD));
}

void PrintMaxLengthDD( const datetime &From[] )
{
  const int Size = ArraySize(From);
  
  datetime BeginDD, EndDD;
  
  for (int i = 0; i < Size; i++)
    Print("From " + TimeToString(From[i], TIME_DATE) + " MaxLengthDD = " + (string)(MaxLengthDD(BeginDD, EndDD, From[i]) / (25 * 3600)) + " days: " +
          (string)BeginDD + " - " + (string)EndDD);  
}
 

fxsaber #:
Иногда полезно знать.

Print("From " + TimeToString(From[i], TIME_DATE) + " MaxLengthDD = " + (string)(MaxLengthDD(BeginDD, EndDD, From[i]) / (25 * 3600)) + " days: " +
          (string)BeginDD + " - " + (string)EndDD);

最好不要写得太紧凑、太轻浮(不仅在这里,在其他资料中也是如此)。具有相同优先级的操作数的计算顺序并不是硬性规定的--编译器可以根据自己的考虑进行优化,这样就会产生不同的副作用。现在能用,并不意味着以后就不能用了,因为编译器的内部实现一直在变化。

 
Stanislav Korotky #:

最好不要写得太紧凑和轻浮(不仅在这里,在其他资料中也是如此)。具有相同优先级的操作数的计算顺序并不是硬性规定的--编译器可以根据自己的考虑进行优化,这样就会产生不同的副作用。现在能用,并不意味着以后就不能用了,因为编译器的内部实现一直在变化。

谢谢你的建议!不幸的是,我很难强迫自己放弃 "简洁 "的风格,转而采用正确的风格。有很多 "错误 "的代码被编写和使用。

 
fxsaber #:
// 从给定时间开始的最长缩编时间。
从远期开始日期起?
Stanislav Korotky#:

最好不要以这种打包和轻率的方式编写(不仅在这里,在其他资料中也是如此)。具有相同优先级的操作数的计算顺序并不是硬性规定的--编译器可以根据自己的考虑进行优化,这样就会产生不同的副作用。现在能用,并不意味着以后就不能用了,因为编译器的内部实现一直在变化。

有什么问题吗?

我只是

/ (25 * 3600)
我不喜欢。一天有 24 小时,而不是 25 小时。
 

Forester #:
C даты начала форварда?

有人吗?

有什么问题吗?

打印字符串的排列顺序并不明确。如果从右向左,结果就会与预期的不同。

    Print("From " + TimeToString(From[i], TIME_DATE) + " MaxLengthDD = " + (string)(MaxLengthDD(BeginDD, EndDD, From[i]) / (25 * 3600)) + " days: " +
          (string)BeginDD + " - " + (string)EndDD);  


我希望在这种情况下能有明确的顺序。

int MaxLengthDD( const datetime &BeginDD, const datetime &EndDD, const datetime From = 0 )
 
fxsaber #:

感谢您的合理建议!遗憾的是,我很难强迫自己放弃 "简洁 "的风格,转而采用正确的风格。有很多 "错误 "的代码被编写和使用。

如果代码已经运行/测试过,而且我不打算再用它,我几乎总是把函数和其他代码合并成一行。这样做只是为了节省空间。
而且,如果能在一个屏幕上看到所有内容,阅读代码时就不用来回滚动了,会更方便。尤其是在能高亮显示高亮单词的编辑器中(不幸的是,Metaeditor 并不具备这种功能)。
 
Forester #:
如果代码已经运行/测试过,而且我不打算再用它,我几乎总是将函数和其他代码合并成一行。这样做只是为了节省空间。而且,如果能在一个屏幕上看到所有内容,阅读代码时就不用来回滚动了,会更方便。尤其是在能高亮显示高亮单词的编辑器中(不幸的是,Metaeditor 并不具备这种功能)。

遗憾的是,这种做法可能会在更换编译器时导致难以察觉的错误。

不过,在有些情况下,您只需要使用编译器中设置的顺序。在这种情况下,我不知道如何避免出现 UB。

 
fxsaber #:

从任何人。

关于最大长期缩减的信息很有意思。我是为整个字符串数组做的。我还没有更新网站上的代码。
但还不太清楚日期的用途。如果我们将其分为前后测试(如我所建议的),那么我们就需要在两个表格中分别计算它们的统计数据(最大平仓期也会在其中)。
而仅针对一个日期则过于具体,难以理解。