MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 - ページ 493

 
Roman Sharanov:
EAで開いた注文をシンボルで全て決済する機能が正しく実装されているか、ご教示いただけないでしょうか。

アーキテクチャ自体は正しいのです。エラーはチェック不足と一部の関数の使い回しにある。

bool OrderCloseAll()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
         if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)
            continue;

         if(OrderSymbol() !=Symbol() || OrderMagicNumber() != Magic)
            continue;
         
         if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slippage, clrWhite))
            return false;
   }

   return true;
}

  1. あなたの場合、最初の反復は失敗します - インデックス OrdersTotal() を持つオーダーが存在しないのです。
  2. OrderSelect関数の 結果に対するチェックはありません。
  3. 関数OrderCloseの結果に対するチェックはありません。注文の決済に失敗した場合、なぜ決済に失敗したのかを調べなければならないので、同じ関数にとどまっているわけにはいかないのです。そのためには、関数にfalseという結果を残しておき、次にどうするかを決めなければならない。
  4. すべての注文に同じ終値を使用することはできません。第一に、注文の種類が異なる可能性があること、第二に、前の注文を実行した時間(終値)に価格が変化している可能性があることです。MT4の機能を使って、使用する価格の推測を避けることができます。成行注文の終了前のOrderClosePrice()の値は、注文タイプに応じてBidまたはAsk価格となります。
 
Ihor Herasko:

アーキテクチャ自体は正しいのです。エラーはチェック不足と一部の関数の使い回しにある。

  1. あなたの場合、最初の反復は失敗します - インデックス OrdersTotal() を持つオーダーが存在しないのです。
  2. OrderSelect関数の 結果に対するチェックはありません。
  3. 関数OrderCloseの結果に対するチェックはありません。注文の決済に失敗した場合、なぜ決済に失敗したのかを調べなければならないので、同じ関数にとどまっているわけにはいかないのです。そのためには、関数にfalseという結果を残しておき、次にどうするかを決めなければならない。
  4. すべての注文に同じ終値を使用することはできません。第一に、注文の種類が異なること、第二に、前の注文の執行中(終値)に価格が変化している可能性があることです。どの価格を使用するかを推測することを避けるために、MT4の機能を使用することができます:成行注文の終了前のOrderClosePrice()の値は、注文の種類に応じてBidまたはAsk価格となります。

ありがとうございます、一番の問題は同じ値段のものを使っていたことでしょう

 

OrderSelectヘルプより「 SELECT_BY_POSパラメータを使用して注文を 連続的に選択 すると、情報は取引サーバーから来た順番に表示されます。得られたオーダーリストのソートを保証するものではありません」。

このフレーズが無駄にヘルプに挿入されたと思えば、OKなのです。もし、このリストが何らかの理由で存在すると考えるなら、ループがオーダーのリストを通過する間、このリストを変更しないようにしなければならない。サーバー上で注文の1つが削除され、OrdersTotalが小さくなった新しい現在のリストが到着した後、注文がどのように順番付けされるかは不明である。削除せずに、同じように変更されていないリストのコピーを実行し、削除する取引のチケット番号をすべて(配列で)収集する方がより確実である。そして、そのリストのことは忘れて、チケットで選択したトレードを削除します。

もちろん、順序のないリストの末尾からいくつかの順序を削除するこのケースに限っては、変更可能なリストにおける順序性が保たれていると信じたいところですが、開発者はそれに反対しています...。今はうまくいっていますが、もし新しいビルドが出たら、「警告したぞ」となります。

 
Vladimir:

OrderSelectヘルプより「 SELECT_BY_POSパラメータを使用して注文を 連続的に選択 すると、情報は取引サーバーから来た順番に表示されます。得られたオーダーリストのソートを保証するものではありません」。

このフレーズが無駄にヘルプに挿入されたと思えば、OKなのです。もし、このリストが何らかの理由で存在すると考えるなら、ループがオーダーのリストを通過する間、このリストを変更しないようにしなければならない。サーバー上で注文の1つが削除され、OrdersTotalが小さくなった新しい現在のリストが到着した後、注文がどのように順番付けされるかは不明である。削除せずに、同じように変更されていないリストのコピーを実行し、削除する取引のチケット番号をすべて(配列で)収集する方がより確実である。そして、そのリストのことは忘れて、チケットで選択したトレードを削除します。

もちろん、順序のないリストの末尾からいくつかの順序を削除するこのケースに限っては、変更可能なリストにおける順序性が保たれていると信じたいところですが、開発者はそれに反対しています...。今はうまくいっていますが、もし新しいビルドが出たら、「警告したぞ」となります。

そんな「アメリカ」は、約300年前から開かれていたのです :)

 
Artyom Trishkin:

こういう「アメリカ」は300年くらい前から開かれていたような気がします :)

新規参入者を代表してここで質問している人たちは、すでに自分で発見していないと思います。だから、書いているんです。司会者のためではなく、質問者のために。スレッドの名前を見てください。

追伸:この興味はどこから来たのか調べてみました。https://www.mql5.com/ru/forum/215783/page8 branch "Organising the Order Cycle "に掲載されたものであることがわかりました。結論から言うと、2017年10月、その300年はまだ終わっていない、まだ新しさが残っているのです。

Организация цикла перебора ордеров
Организация цикла перебора ордеров
  • 2017.09.16
  • www.mql5.com
MQL4 и MetaTrader 4: Организация цикла перебора ордеров
 
Vladimir:

新規参入者を代表してここで質問している人たちは、すでに自分で発見していないと思います。だから、書いているんです。司会者のためではなく、質問者のために。スレッドの名前を見てください。

P.S. この興味はどこから来るのか調べてみました。https://www.mql5.com/ru/forum/215783/page8 branch "Organising the order cycle "に掲載されていることが判明しました。結論から言うと、2017年10月、その300年はまだ終わっていない、まだ新しさがあるのです。

また間違えた :)300年はmql4.comから始まった--そこで活発に議論された時期があったのだ。そして、「今は動いているけど、新しいビルドが出るよ~"警告した"」で紹介されていたような瞬間もありましたね。警告がないだけに、何度か - それは依存する、それはソートに依存しない...。

そうそう、そういう回答のための専用スレッドもあるんですよ。

Особенности языка mql4, тонкости и приёмы работы
Особенности языка mql4, тонкости и приёмы работы
  • 2017.02.24
  • www.mql5.com
В данной теме будут обсуждаться недокументированные приёмы работы с языком mql4, примеры решения тех, или иных задач...
 
Vladimir:

OrderSelectヘルプより「 SELECT_BY_POSパラメータを使用して注文を 連続的に選択 すると、情報は取引サーバーから来た順番に表示されます。得られたオーダーリストのソートを保証するものではありません」。

このフレーズが無駄にヘルプに挿入されたと思えば、OKなのです。もし、このリストが何らかの理由で存在すると考えるなら、ループがオーダーのリストを通過する間、このリストを変更しないようにしなければならない。サーバー上で注文の1つが削除され、OrdersTotalが小さくなった新しい現在のリストが到着した後、注文がどのように順番付けされるかは不明である。削除せずに、同じように変更されていないリストのコピーを実行し、削除する取引のチケット番号をすべて(配列で)収集する方がより確実である。そして、そのリストのことは忘れて、チケットで選択したトレードを削除します。

もちろん、少なくともこのような順序のないリストの末尾からいくつかの順序を削除するようなケースでは、変更可能なリストにおける順序が保存されると信じたいのですが、開発者はそれに反対しています...。今はうまくいっていますし、新しいビルドが出ても「警告しましたよ」となります。

良いアイデアとして、(複数のExpert Advisor + トレーダーが並行してアカウントで作業できることを考慮し)ループでトレードを実行することは一切できません。必要な注文を受け、操作を実行し、OnTick()全体を再度実行します(新しいティックが到着するとは限りません)。そして、必要な操作がすべて実行されるまで続けます。

従って、オーダーを削除するために配列を形成することは、ループ内でオーダーを削除することと同じである。

 

停止」ボタンがありますが、一度押したら「開始」に変更するにはどうしたらよいですか?

bool stop;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//Closed at Profit
   ObjectCreate(0,"Stop",OBJ_BUTTON,0,0,0);
   ObjectSetInteger(0,"Stop",OBJPROP_XDISTANCE,10);
   ObjectSetInteger(0,"Stop",OBJPROP_YDISTANCE,105);
   ObjectSetInteger(0,"Stop",OBJPROP_XSIZE,100);
   ObjectSetInteger(0,"Stop",OBJPROP_YSIZE,25);

   ObjectSetString(0,"Stop",OBJPROP_TEXT,"Stop");

   ObjectSetInteger(0,"Stop",OBJPROP_COLOR,White);
   ObjectSetInteger(0,"Stop",OBJPROP_BGCOLOR,Green);
   ObjectSetInteger(0,"Stop",OBJPROP_BORDER_COLOR,Green);
   ObjectSetInteger(0,"Stop",OBJPROP_BORDER_TYPE,BORDER_FLAT);
   ObjectSetInteger(0,"Stop",OBJPROP_HIDDEN,true);
   ObjectSetInteger(0,"Stop",OBJPROP_STATE,false);
   ObjectSetInteger(0,"Stop",OBJPROP_FONTSIZE,12);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
if(sparam=="Stop")
     {
      ObjectSetInteger(0,"Stop",OBJPROP_STATE,false);
      CloseAtProfit();
      stop=true;
     }
     }
 
lil_lil: 停止」ボタンがありますが、一度押したら「開始」に変更するにはどうしたらよいですか?

私の専門家の例を参照してください

ファイル:
ToFile.mq4  11 kb
 
STARIJ:

Expert Advisorの例をご覧ください。

ありがとうございます、ちょうど私が必要としていたものです。

知っておくと便利かもしれませんが、ポジション不足のエラーがあります--- ToFile EURUSD,H1: 'ToFile.mq4' (62,39) にゼロディバイドがあります。

/*62*/  Строка=DoubleToStr(AccountEquity()/AccountMargin()*100,2)+"%"; // Уровень=Средства/Залог
テスターでテキストが変更されない、そのようなオプションはないのですか?