ライブラリ: MT4Orders QuickReport - ページ 5

 
Forester #:

Server: MetaQuotes-Demo Hedge
2ページ目のチケット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)
好きじゃないんだ。1日は25時間ではなく、24時間ある。
 

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

誰でもいい。

何が間違っているのか?

Print用の文字列がどのような順序で形成されるかは明確ではない。もし右から左へなら、結果は意図したものとは異なるものになる。

    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 #:

的確なアドバイスをありがとう!残念ながら、「簡潔な」スタイルから正しいスタイルに無理やり移行するのは難しい。間違った」コードがたくさん書かれ、使われている。

私はほとんどいつも、関数やその他のコードを1行にまとめてしまう。スペースを節約するためだ。
また、1つの画面ですべてを見ることができれば、前後にスクロールすることなくコードを読むことができて便利だ。特に、ハイライトされた単語を強調表示するエディターでは(残念ながらMetaeditorはそのようなエディターではない)。
 
Forester #:
関数やその他のコードは、作業/テストが済んでいて戻る予定がなければ、ほとんどいつも1行にまとめる。スペースを節約するためだ。また、1つの画面ですべてを見ることができれば、前後にスクロールすることなくコードを読むことができて便利だ。特に、ハイライトされた単語を強調表示するエディターでは(残念ながらMetaeditorはそのようなエディターではない)。

残念なことに、このやり方はコンパイラを変えたときに非常に見づらいエラーにつながる可能性がある。

しかし、コンパイラで設定された順序を使わなければならない状況もある。その場合、UBがないように回避する方法を私は知らない。

 
fxsaber #:

誰からでも。

最大ロング・ドローダウンに関する情報は興味深い。文字列の配列全体に対して作ったんだ。
でも、何のための日付なのかがよくわからない。もし(私が提案したように)バックテストとフォワードテストに分割するポイントを作るなら、2つのテーブルで別々に統計情報を計算する必要がある(最大ドローダウン期間もそこにある)。
また、1つの日付だけではなんだか特殊すぎて理解できない。