mql5言語の特徴、微妙なニュアンスとテクニック - ページ 185

 
もうひとつ、バグがあるんです。現在の 価格で指値注文を設定し、それが徐々に満たされていくのを見る。全てのポジションと注文の総ロットを毎ステップごとに確認します。これは、OrderSend に送信されたものと同じでなければならない。
// Демонстрация потери данных во время торговли.

template <typename T>
T MyPrint( const T Value, const string Str )
{
  Print(Str + " = " + (string)Value);

  return(Value);
}

#define _P(A) MyPrint(A, ": " + #A)

sinput double inLots = 100;

int OnInit()
{
  MqlTradeResult Result = {0};
  MqlTradeRequest Request = {0};
  
  Request.action = TRADE_ACTION_PENDING;
  Request.symbol = _Symbol;
  Request.volume = inLots;
  Request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
  Request.type = ORDER_TYPE_BUY_LIMIT;
  
  return(OrdersTotal() || PositionsTotal() || !OrderSend(Request, Result)); // Работаем, когда ничего не открыто.
}

// Возвращает сумму лотов всех позиций и ордеров.
double GetSumLots()
{
  double Lots = 0;
  
  for (int i = _P(OrdersTotal()) - 1; i >= 0; i--)
    if (_P(OrderGetTicket(_P(i))))
      Lots += _P(OrderGetDouble(ORDER_VOLUME_CURRENT));
    
  for (int i = _P(PositionsTotal()) - 1; i >= 0; i--)
    if (_P(PositionGetTicket(_P(i))))
      Lots += _P(PositionGetDouble(POSITION_VOLUME));

  return(Lots);
}

void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
{
  Print("---------");
    
  // Проверяем, что сумма лотов всех позиций и ордеров совпадает с заданной.
  if (NormalizeDouble(_P(GetSumLots()) - inLots, _Digits))
    Alert("BUG!");
}


結果

2020.08.21 01:18:13.375 : OrdersTotal() = 1
2020.08.21 01:18:13.375 : i = 0
2020.08.21 01:18:13.375 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.375 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 68.59999999999999
2020.08.21 01:18:13.375 : PositionsTotal() = 1
2020.08.21 01:18:13.375 : i = 0
2020.08.21 01:18:13.375 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.375 : PositionGetDouble(POSITION_VOLUME) = 31.4
2020.08.21 01:18:13.375 : GetSumLots() = 100.0
2020.08.21 01:18:13.377 ---------
2020.08.21 01:18:13.377 : OrdersTotal() = 1
2020.08.21 01:18:13.377 : i = 0
2020.08.21 01:18:13.377 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.377 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 68.59999999999999
2020.08.21 01:18:13.377 : PositionsTotal() = 1
2020.08.21 01:18:13.377 : i = 0
2020.08.21 01:18:13.377 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.377 : PositionGetDouble(POSITION_VOLUME) = 31.4
2020.08.21 01:18:13.377 : GetSumLots() = 100.0
2020.08.21 01:18:13.389 ---------
2020.08.21 01:18:13.389 : OrdersTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 41.4
2020.08.21 01:18:13.389 : PositionsTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : PositionGetDouble(POSITION_VOLUME) = 31.4
2020.08.21 01:18:13.389 : GetSumLots() = 72.8
2020.08.21 01:18:13.389 Alert: BUG!
2020.08.21 01:18:13.389 ---------
2020.08.21 01:18:13.389 : OrdersTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 41.4
2020.08.21 01:18:13.389 : PositionsTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : PositionGetDouble(POSITION_VOLUME) = 31.4
2020.08.21 01:18:13.389 : GetSumLots() = 72.8
2020.08.21 01:18:13.389 Alert: BUG!
2020.08.21 01:18:13.389 ---------
2020.08.21 01:18:13.389 : OrdersTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 41.4
2020.08.21 01:18:13.389 : PositionsTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : PositionGetDouble(POSITION_VOLUME) = 31.4
2020.08.21 01:18:13.389 : GetSumLots() = 72.8
2020.08.21 01:18:13.389 Alert: BUG!
2020.08.21 01:18:13.389 ---------
2020.08.21 01:18:13.389 : OrdersTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : OrderGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.389 : OrderGetDouble(ORDER_VOLUME_CURRENT) = 41.4
2020.08.21 01:18:13.389 : PositionsTotal() = 1
2020.08.21 01:18:13.389 : i = 0
2020.08.21 01:18:13.389 : PositionGetTicket(MyPrint(i,: +i)) = 1197440
2020.08.21 01:18:13.390 : PositionGetDouble(POSITION_VOLUME) = 58.6
2020.08.21 01:18:13.390 : GetSumLots() = 100.0

100ロット置いたのに、ある時点で72.8ロットになった。明らかに、このような状況では取引アルゴリズムが混乱する可能性があります。

検索文字列:Oshibka 011.
 

fxsaber:
Он должен быть неизменным - равным тому, что был отправлен в OrderSend.

実は、いや、タイミングの不具合で、こうなる可能性もあるのですが、簡単な解決策はまったくないのです

 
Andrei Trukhanovich:

実はそうではなく、タイミングがずれてしまう可能性があり、そうなってしまうと、簡単には解決できないのです

簡単な解決策もないんです。ある実行中のスクリプトで非同期があることを確認する方法は、まったく不明です。

 
fxsaber:

複雑な解決策もないんです。実行中のスクリプトで非同期であることを確認する方法は、まったく不明です。

合計ロットが変更された場合は、注文とポジションのロットが2回同じになるまでカウントし続けます。

端数やほんの数パーセントの確率なので、性能に影響はありません。

__________

プリントを拝見しましたが、もしかしたらバグかもしれませんね、非同期の場合、間違った金額を何度も同じように計算することはないはずです

 
Andrei Trukhanovich:

合計ロットが変更された場合、注文とポジションのロットが2回同じになるまでカウントを続けます。

非同期の確率は数分の一か数%なので、性能にはほとんど影響がありません。

上のログでは、3回連続で間違った計算結果が表示されています。スリープは必要ですが、これでは貿易の注文 が出たときに対応する時間がなく、遅れが出る可能性があります。

これは決して楽しい状況ではない。

 
fxsaber:

上のログでは、3回連続で間違った計算結果が表示されています。

はい、見ました、トップに追加しました

 
 
Alexey Viktorov:

気を悪くしないことです。最も確率が高いのは、コードのエラーです。2位は、法外なスプレッドです。しかし、あなた以外の誰が、コードを見ることなく、最初の選択肢を捨て、2番目の選択肢を検討し始めることができるでしょうか。司会者が間違ったトピックに移動してくれることを望みます。

適切な回答ありがとうございました。悪気はないんです、動揺しているんです))。すでに遭遇している人がいるかもしれないので、手っ取り早い解決策を探そうと思い書き込みました。コードは全く標準的なもので、totalprofitループの合計と与えられた値との比較、さらにコードは2つの異なるアカウントで2ヶ月間失敗することなく動いています。良い一日をお過ごしください。

 
Evgeny Vlasov:

十分な対応をしていただき、ありがとうございました。悪気はないんです、悲しんでいるんです))。もしかしたら、すでに遭遇された方がいらっしゃるかもしれないので、手っ取り早い解決策を探そうと思い、書き込みました。コードは全く標準的なもので、totalprofitループの合計と与えられた値との比較、さらにコードは2つの異なるアカウントで2ヶ月間失敗することなく動いています。良い一日をお過ごしください。

これは機能の話ではない。
 
Artyom Trishkin:
これは、機能の話ではない。

私もそう思います。

理由: