[アーカイブ!】どんなルーキーの質問でも、フォーラムを散らかさないように。プロフェッショナルの皆さん、通り過ぎないでください。あなたなしではどこにも行けない - 2. - ページ 294

 
CreAndr:
トロールについて質問があるのですが、どなたか教えてください。ブレークイーブンに適したトロールのようですが、うまくいきません。

以下は、トロールです。https://www.mql5.com/ru/forum/131859

テキストにコードを挿入するには、テキスト入力フィールドの上にあるSRC ボタンを押します。

 
DhP:

以下は、トロールです。https://www.mql5.com/ru/forum/131859

テキストにコードを挿入するには、テキスト入力フィールドの上にあるSRC ボタンを押します。


ありがとうございます。
 
CreAndr:
トロールについて質問があるのですが、どなたか教えてください。トロールからブレイクイーブンまでが正しいようですが、うまくいきません。


重要度の高い順に理由を列挙。

1.コンピュータの電源が入っていない

2.メタトレーダーが起動しない。

3.チャート上のスクリプトがインストールされていない

4.Expert Advisorsが有効でない

5.トロールするものがない。

6.コードのどこかが間違っているのです。

 
Roger:


重要度の高い順に理由を列挙する。

1.コンピュータの電源が入っていない

2.メタトレーダーが起動しない。

3.チャート上のスクリプトがインストールされていない

4.Expert Advisorsが有効でない

5.トロールするものがない。

6.コードのどこかが間違っているのです。

しかし、コンピュータの電源が入っていて、メタトレーダーも入っていて、EAがチャートに取り付けられていて、EAが有効になっていて、トレードが開始されているので、トラブるものがあるのです!!ロジャー、素晴らしい答えです。しかし、コードのどこが悪いのか、それが問題だったのです。
 
artmedia70:
Use OrderOpenTime() For - Why do we need it then?


そうそう、でも注文番号だと結構短くなったんだけど、OrderOpenTimeだとどうしたらいいのかわからない、オープンタイムを どこかに入れて、リストの次の注文と比較して、時間が長ければ変数を書き換える、などなど。まだアルゴリズムが理解できていない。


bool DeleteOrders()
{
   for(int i=0 ; i <=OrdersTotal() ; i++)
      {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         {
         if(Symbol()==OrderSymbol())
            {
            if(OrderType()!= OP_SELL)
               {
               int ticket=OrderTicket();
               OrderDelete(ticket);
               return(true);
               }
            }
         }
      }
return(false);
} 
 
CreAndr:
しかし、コンピュータは有効であり、MetaTraderも有効であり、EAがチャートに接続され、EAが有効であり、取引が開始され、したがって、トラブるものがあるのです。しかし、コードのどこが悪いのか、それが問題だったのです。


最初はコードがなく、後から付けましたね。

おそらく、注文の開始関数に末尾を付けているため、注文を開始するための条件が来て、注文は開始されますが、それ以上進まない可能性があります。

 
Pyro:

そうそう、でも注文番号だと結構短くなったんだけど、OrderOpenTimeだとどうしたらいいかわからない、オープンタイムをどこかに入れて、リストの次の注文と比較して、時間が長ければ変数を書き換える、などなど、必要。アルゴリズムはまだ理解していない。


シリアルナンバーは信頼性が低く、このナンバリングでは何も保証されない、テスター用のみ。数ページ前に、最後に閉じた注文を検索するコードを書きました。非常にシンプルで、チケットに目を通した上で、チケットによって順番や ポジションを選んでいる、それだけです。

  int lastclosetime=-1;
  int lastcloseticket=-1;
  int lastdealtype=0;

  for (int i=0; i<OrdersHistoryTotal(); i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue; 
    if (OrderSymbol()==symbol || OrderMagicNumber()==magic) 
    {
      if (lastclosetime<OrderCloseTime()) 
      {
        lastclosetime=OrderCloseTime();
        lastcloseticket=OrderTicket();
      }
    }
  }

  if (OrderSelect(lastcloseticket, SELECT_BY_TICKET, MODE_HISTORY)) 
  {
    if (OrderType()==OP_BUY) lastdealtype=1;
    if (OrderType()==OP_SELL) lastdealtype=-1;   
  }
 
Figar0:


オーダーナンバーは信頼できない、このナンバリングでは誰も何も保証しない、テスターのためだけだ。数ページ前に、最後のクローズド・オーダーを見つけるコードを書きましたが、オープン・オーダーについても同じです。すべてがシンプルで、一通り見て、チケットを覚えて、あとはチケットにしたがって順番やポジションを決めていく、それだけです。

ありがとうございます!本当にシンプルですね。調べてみます。
 
Roger:


最初はコードがなく、後から追加したんですね。

おそらく、注文開始関数に末尾を付けているため、注文開始の条件が発生し、注文が開始されるものの、それ以上進まないことがあります。

なるほど、ありがとうございます。
 
Figar0:


オーダーナンバーは信頼できない、このナンバリングでは誰も何も保証しない、テスターのためだけだ。数ページ前に、最後のクローズド・オーダーを見つけるコードを書きましたが、オープン・オーダーについても同じです。非常にシンプルで、チケットに目を通した後、チケットによって注文やポジションを選択し、それで終わりです。

コードが間違っている。

まず、これです。

if (OrderSymbol()==symbol || OrderMagicNumber()==magic) 

オーダーシンボルがシンボル 変数で与えられたシンボルと等しい場合、または オーダーマジックがマジックと 等しい場合...そのため、シンボルの あるオーダーが選ばれても、マジックの内容が異なっていたり、欠けていたりすると、条件を満たすことになる。なぜなら、これか それのどちらか だからです。ループが速くなり、最適化のために重要です。

さらに...Pick by ticket:pool パラメータは無視されます、つまりここに書いても意味がありません。

if (OrderSelect(lastcloseticket, SELECT_BY_TICKET, MODE_HISTORY)) 

チケットで注文が正常に選択された後、注文が成行とクローズドのどちらのリストから選択されたかを確認する必要があります。そのためには、注文が終了した時刻を確認し、それがゼロより高ければ、間違いなく注文は終了している。このパラメータは、オープンポジションの場合、常にゼロに等しい。IMHOでは、最後のオーダーが選ばれた後、すぐにその型をチェックして変数に書き込むべきと考えます。

これで、関数は次のようになります。

int   GetTypeLastClosePos(int symbol, int magic)   // Функция возвращает 0 если последний закрытый Бай, 1 - если Селл и -1 при ошибке
{
int   i, lastclosetime=0, 
         lastdealtype=-1;

   for (i=0; i<OrdersHistoryTotal(); i++) {
      if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { // Если выбрали ордер в истории
         if (OrderSymbol()!=symbol)          continue;   // Если его символ не равен переданному в функцию - идём к следующему
         if (OrderMagicNumber()!=magic)      continue;   // Если его магик не равен переданному в функцию - идём к следующему
         if (OrderType()>1)                  continue;   // Если ищем только Бай и Селл, значит если больше единицы - к следующему
         // ... теперь выбранный ордер соответствует критериям поиска по символу, магику и типу
         if (lastclosetime<OrderCloseTime()) {           // Посмотрим время его закрытия и если оно больше предыдущего, то...
            lastclosetime=OrderCloseTime();              // ... запишем его как предыдущее
            lastdealtype=OrderType();                    // Тип текущего закрытого ордера: 0 для Бай, 1 для Селл
            }
         }
      else if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { // Иначе, если не удалось выбрать ордер в истории
         Print ("Func: GetTypeLastClosePos, Ошибка выбора ордера - ",GetLastError());  // Посмотрим номер ошибки
         break;                                                // Выходим из цикла перебора ордеров
         }
      }
   return(lastdealtype);
}

さて、もし現在のチャートの買いと売りだけをチェックし、最後に閉じたのがどちらかを調べたい場合は、この関数をこのように呼び出します。

int LastPoseType=GetTypeLastClosePos(Symbol(), Magic);
if (LastPoseType==OP_BUY) {
   // ... код, если последний закрытый Buy ...
   }
if (LastPoseType==OP_SELL) {
   // ... код, если последний закрытый Sell ...
   }
else {// ... код обработки ошибки ... }

エラー処理のために、原則的には、グローバル変数、例えばint errを作成し、 関数本体でこの変数にエラー番号を格納することができる。

else if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { // Иначе, если не удалось выбрать ордер в истории
         err=GetLastError();                                                     // Посмотрим номер ошибки
         Print ("Func: GetTypeLastClosePos, Ошибка выбора ордера - ",err);       // Сообщим об ошибке и в какой ф-ции она произошла
         break;                                                                  // Выходим из цикла перебора ордеров
         }

そして、関数を呼び出した後のエラー処理に ...

GetTypeLastClosePos(Symbol(), Magic);

...とエラーが発生した場合、その番号が変数errに 格納され、処理ブロック内でこの番号が処理される。

else {
   if (err==???) {
      // обработка этой ошибки
      }
   if (err==???) {
      // обработка этой ошибки
      }
// ... и т.д. ...
   }

より良い方法は、スイッチを 使用することです。