ライブラリ: MT4Orders - ページ 68

 
fxsaber #:
最新バージョンは常にここに あります。

ある人気ブローカーは、顧客の全取引口座から取引履歴の一部を削除しました。そのため、多くのユーザーが、取引サーバーの履歴が正しくないためにライブラリが警告を発するという問題に遭遇しています。


この問題は最新リリースで修正されています。

ロシア語のページから最新バージョンのライブラリをダウンロードしてください。

 
'DEAL_SL' - undeclared identifier       MT4Orders.mqh   1186    89
'DEAL_TP' - undeclared identifier       MT4Orders.mqh   1187    91
'MQL_HANDLES_USED' - undeclared identifier      MT4Orders.mqh   1345    104
'MQL_HANDLES_USED' - undeclared identifier      MT4Orders.mqh   1726    124

MT5は古いバージョンではビルドしない。

そして最新のリリースバージョンはバグだらけです https://www.mql5.com/ru/forum/380278/page31#comment_26286913

Новая версия платформы MetaTrader 5 build 3091: Улучшения в работе
Новая версия платформы MetaTrader 5 build 3091: Улучшения в работе
  • 2021.12.04
  • www.mql5.com
В пятницу 22 октября 2021 года будет выпущена обновленная версия платформы MetaTrader 5...
 
traveller00 #:

MT5の古いバージョンでは構築できません。

私は新しいバージョンでコンパイルし、b2958で使用しています。リリースビルドはベータと同じように扱います。

 

部分決済について質問があります。

MT4では、0.1ロットの注文の0.01ロットをクローズすると、元のチケットが0.01ロットサイズでクローズされ、その一部クローズされた注文の注文コメントが「to: xxxxxx」に変更されます。同時に、新しい0.09ロットの注文が開設され、コメントが「from: xxxxxx」に設定される。

MT5ではこのようなことは起こらないようなので(少なくとも、OrdersToString()は、オープンまたはクローズ部分の注文コメントテキストをリストしません)、通常のように部分クローズの連鎖を追うことはできません。

MT4Ordersと互換性のあるコードのスニペットをお持ちですか?

 

未決済ポジションの一部約定を表示する方法

#include <MT4Orders.mqh> //https://www.mql5.com/ja/code/16006

#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnStart()
{
  // オープンポジション
  const TICKET_TYPE Ticket  = OrderSend(_Symbol, OP_BUY, 0.1, Ask, 0, 0, 0, "Hello!");
  
  // パーシャルクローズ
  if (OrderSelect(Ticket, SELECT_BY_TICKET))
  {
    OrderClose(OrderTicket(), 0.01, OrderClosePrice(), 0);
    OrderClose(OrderTicket(), 0.02, OrderClosePrice(), 0);
  }
    
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      PrintFullOrder();
      
      Print("");
    }
}

#include <fxsaber\TradesID\TradesID.mqh> //https://www.mql5.com/ja/code/34173

void PrintFullOrder()
{
  static TRADESID TradesID;
  
  long Deals[];  
  const int Size = TradesID.GetDealsByID(OrderTicketID(), Deals);
  
  for (int i = 0; i < Size; i++)
    if (OrderSelect(Deals[i], SELECT_BY_TICKET))
      OrderPrint();  
}


結果

#50005051444 2021.12.20 21:22:29.566 buy 0.07 GBPUSD 1.32174 0.00000 0.00000 1.32169 0.00 0.00 -0.31 Hello! 0
#50004982892 2021.12.20 21:22:29.566 buy 0.01 GBPUSD 1.32174 0.00000 0.00000 2021.12.20 21:22:29.631 1.32169 0.00 0.00 -0.04 Hello! 0
#50004982893 2021.12.20 21:22:29.566 buy 0.02 GBPUSD 1.32174 0.00000 0.00000 2021.12.20 21:22:29.694 1.32169 0.00 0.00 -0.09 Hello! 0

#50005051217 2021.12.20 21:22:05.921 buy 0.09 USDCHF 0.92179 0.00000 0.00000 0.92179 0.00 0.00 0.00 Hello! 0
#50004982634 2021.12.20 21:22:05.921 buy 0.01 USDCHF 0.92179 0.00000 0.00000 2021.12.20 21:22:05.984 0.92174 0.00 0.00 -0.05 Hello! 0
 
SysFX 注文コメントが「to: xxxxxx」に変更されます。同時に、新しい0.09ロットの注文が開設され、コメントが「from: xxxxxx」に設定されます。

MT5ではこのようなことは起こらないようなので(少なくとも、OrdersToString()は、オープンまたはクローズ部分の注文コメントテキストをリストしません)、通常のように部分クローズの連鎖を追うことはできません。

MT4Ordersと互換性のあるコードのスニペットをお持ちですか?

 
fxsaber #:

完璧だ!...迅速な対応に感謝します :)

 
// 変更リスト:
// 28.12.2021
// 修正: OrderSelect(Index, SELECT_BY_POS, MODE_TRADES)は、MT5側でもう1つの非同期を考慮します。
// 修正: OrderLots(true)はMT5側の別の同期ミスを考慮します。 


変更リストの最初の編集は、特に、2つのロジックを同一にすることを可能にした。

取引、自動取引システム、取引戦略のテストに関するフォーラム

ライブラリ: MT4Orders

fxsaber, 2021.05.12 18:24

一見したところ、これら2つのコードは同じ結果を与えるはずです。

while (OrdersTotal() <= 1)
  if (OrderSelect(0, SELECT_BY_POS))
    OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);
  else
    OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0);    


while (OrdersTotal() <= 1)
  if (!OrdersTotal())
    OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0);    
  else if (OrderSelect(0, SELECT_BY_POS))
    OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);


実際はそうではありません。その理由を考えてみましょう。

一般に、MT5における注文の障害という 特殊性から保護する方がさらに良いことが判明した。

 
// 変更リスト:
// 29.12.2021
// 修正: ByPass-modeにおける同期の改善。
 

MT4では、注文を検索する際に、注文テーブルの揺れによりバックトラック(二重カウント)が 発生する可能性があります。


MT4Orders では、特定の状況で注文テーブルのインデックスが変更されます。これは、MT5 マーレ注文が MT5 ポジションに変わるときに発生します。一部のサーバーでこの状況に遭遇しようとすると、アカウンティングに失敗することがあります。そのためのデモを書きました。

#define  MT4ORDERS_BYPASS_MAXTIME 1000000 // 取引環境の同期を待つ最大時間(単位:µs
#include <MT4Orders.mqh> //https://www.mql5.com/ja/code/16006

#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define  MinLot SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN)

double GetLots()
{
  double Lots = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--) // すべての注文を実行する。
    if (OrderSelect(i, SELECT_BY_POS))
      Lots += OrderLots();
      
  return(NormalizeDouble(Lots, 2));
}

void OnStart()
{
  MT4ORDERS::OrderSend_MaxPause = 0; // 組み込みの MT5-OrderSend 結果の修正を拒否します。

  const double NewLots = 0.11;
  
  while (!IsStopped())
  {
    const double Lots = NormalizeDouble(GetLots() + NewLots, 2); // 注文を出した後、合計で何ロットになるか。
    const TICKET_TYPE Ticket = OrderSend(_Symbol, OP_BUY, NewLots, Ask, 0, 0 ,0); // 成行注文が発注された。
    
    if (Ticket != -1)
    {
      while (!PositionSelectByTicket(Ticket)) // 成行注文がポジションに変わるのを待つ。
      {
        const double Lots2 = GetLots(); // 合計体積を計算する。
        
        if (Lots2 != Lots) // 合計体積が予備計算と一致しません。
          Alert((string)Lots + " " + (string)Lots2);                        
      }
    }
          
    if (OrderSelect(Ticket, SELECT_BY_TICKET) &&
        OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0)) // ポジションを決済するために成行注文を出す。
      while (PositionSelectByTicket(Ticket))                          // ポジションがクローズするのを待つ。
        ;      
  }
    
  Print(MT4ORDERS::ByPass.ToString()); // 同期の統計情報を表示する。
}


このようなEAは、いくつかの設定で動作します。ByPassモードはアラート値を安定させますが、それでもアラート値を取り除くことはできません。


ByPass-modeはMT5-surprisesをバイパスする非常に強力なものなので、私自身はByPass-modeなしでは取引しません。また、スナップショットなしでは取引しません。スナップショットのおかげで、オーバーインデックスから解放されるからです。


同じ例ではこんな感じです。

#define  VIRTUAL_SNAPSHOT_REFRESHTIME 1000 // 更新のためのスナップショットの有効期間。MT5では、MT4Orders.mqhに接続する必要があります。
#define  VIRTUAL_SNAPSHOT_WITHOUT_HISTORY // パフォーマンス向上のため、履歴スナップショットを破棄する
#include <fxsaber\Virtual\Virtual.mqh> //https://www.mql5.com/ja/code/22577

double GetLots()
{
  double Lots = 0;

  VIRTUAL::Snapshot(0, -1, false, ""); // Zasnepsholy実際の取引環境。
  
  for (int i = OrdersTotal() - 1; i >= 0; i--) // スナップショット・メカニズムにより、すべてのオーダーを安全に実行する。
    if (OrderSelect(i, SELECT_BY_POS))
      Lots += OrderLots();

  VIRTUAL::SnapshotDelete(); // スナップショットを削除。
      
  return(NormalizeDouble(Lots, 2));
}


ByPass+スナップショットのバンドルをお勧めします。落とし穴を回避できるだけでなく、計算リソースの消費を大幅に抑えることができます。特に、多通貨の注文/アドバイザーが多い場合です。