マジックナンバーの作成 - ページ 3

 
//|                                                      This_EA.mq4 |
//|                      Copyright © 2010, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+

#define This_EA  101
#define That_EA  102
#define Other_EA 103 // put this list of ea names to each of your ea's header, or...
                     // .. alternatively you can use a number suffix to your ea's file name 
                     // so it can be identified with --> StringSubstr(WindowExpertName(),x,y);
double This_EA_qty;
string magic_prefix;

int init()
  {

   if(GlobalVariableGet(This_EA_qty) >= 0.0){
            GlobalVariableSet("This_EA_qty", This_EA_qty + 1);
   }
   magic_prefix = StringConcatenate(This_EA, DoubleToStr(This_EA_qty,0));

   return(0);
  }

int deinit()
  {

      GlobalVariableSet("This_EA_qty", This_EA_qty - 1);
   
   return(0);
  }

int start()
  {
      double lots, SL, TP; int slip, time_stamp ;
      bool BuyCondition;
   
      if( BuyCondition == true )
      {
         time_stamp  = TimeCurrent(); 
         string magic_name = StringConcatenate(magic_prefix, time_stamp );
         int magic = StrToInteger(magic_name);
         
                                      // Integers range from -2147483648 to 2147483647
                                      // the resulting magic integer would most probably exceed that 
                                      // so we cut the number returned with TimeCurrent() short with 
                                      // MathMod(time_stamp,x) x being years, months not necessary for 
                                      // magic unique-ness. I don't include this calculation, 
                                      // since I'm short in time for testing it...
      
      
         OrderSend(Symbol(),0, lots, Ask, slip, SL, TP, NULL, magic, 0, CLR_NONE);
      }
//----
   return(0);
  }
//+------------------------------------------------------------------+
が思ったより時間がかかる.
edit : GVget condition != -1.0 to >= 0.0; edit
 
cameofx:
[...] 思ったより時間がかかる.

これは、すでに述べた前のトピック(https://www.mql5.com/en/forum/1200 34)の焼き直しになりつつあります(駄洒落ですみません) グローバル変数を含むものは、バックアップと災害復旧の問題を引き起こします。もし、取引を新しいサーバーに急いで移さなければならない場合、gvariables.datの最近のバックアップが利用可能であるか、ユーザーが手動でグローバル変数を再作成できる状態である必要があります。

あなたのコードを詳しく研究したわけではありませんが、EAのコピーが複数あり、その後MT4が再起動された場合に何が起こるのかもよくわかりません。このコードは、EAが元々手動でロードされたのと同じ順序で自動的に再ロードされることを想定しているように見えます。言い換えれば、複数のEAのコピーが再起動にわたって異なるThis_EA_qty値を取得する可能性があり、その後、MT4のリストでそれらの履歴注文を正しく識別する方法を見ることはできません。しかし、私はこれに関して間違っている可能性があります。

 
cameofx:
は思ったより時間がかかる.
edit : GVget条件 != -1.0 から >= 0.0 に変更。
// TimeCurrent() in seconds since 1970 would most probably exceed that 

TimeCurrent()は32ビットの整数を返します。datatime型はint型の別名で、intも32ビットの整数である。


このコードで理解できないもう一つのことは、なぜオープンしたトレードごとに異なるMNを使用しているのか、ということです。これはMNが意図するところとは正反対です。MNのアイデアは、MNを見るだけで、特定のEAによるすべてのトレードを識別できることです。MNのランダムな部分の理由は何ですか?このEAのすべてのオープントレードをクローズする、あるいはこのEAのすべてのストップをトレールするEA内のコードはどのように見えるでしょうか?
 
もし私の理解が正しければ、2人のエキスパートが偶然同じIDを持っている場合の解決策は、すべてのエキスパートIDを各エキスパートのヘッダーに置くことです。それはちょっと面倒ですね...。仮にその部分をインクルードファイルに記述したとしても、新しいエキスパートを作るたびにすべてのエキスパートを再コンパイルする必要があります。

永続性の問題が残っています。ターミナルを再起動したり、まったく別のターミナルに切り替えたりしたときに、どうすれば正常に動作するのかがわからない......。
 
jjc:

これは、すでに述べた前のトピックhttps://www.mql5.com/en/forum/120034 の焼き直しになりつつあります(駄洒落ですみません)。グローバル変数を含むものは、バックアップと災害復旧の問題を引き起こします。もし、取引を新しいサーバーに急いで移さなければならない場合、gvariables.datの最近のバックアップが利用可能であるか、ユーザーが手動でグローバル変数を再作成できる状態である必要があります。

あなたのコードを詳しく研究したわけではありませんが、EAのコピーが複数あり、その後MT4が再起動された場合に何が起こるのかもよくわかりません。このコードは、EAが元々手動でロードされたのと同じ順序で自動的に再ロードされることを想定しているように見えます。言い換えれば、複数のEAのコピーが再起動にわたって異なるThis_EA_qty値を取得する可能性があり、その後、MT4のリストでそれらの履歴注文を正しく識別する方法を見ることはできません。しかし、私はこれに関して間違っている可能性があります。

このようなフィードバックを期待しているのですが、gordonさん、7bitさん、jjcさん、ありがとうございます。

あなたの回答は、いくつかの熟考を必要とします...しかし、迅速に答えるために:

- もし、This_EAエキスパートがすでに他のチャートで一度アタッチされている場合、magic_numberの値は...となります。101-1-time_stamp (わかりやすいようにダッシュ)

- 101 - エキスパートID; 1 - 現時点でのThis_EAの数量; time_stamp - オーダー送信の時間

- これをStringSubStrでスキャンすると、ある注文がThis_EAによって出され、他に1つのThis_EAが接続されていることがわかる。

 
7bit:

TimeCurrent() は32ビットの整数を返します。datatime型はint型の別名で、intも32ビットの整数です。


このコードで理解できないもう一つのことは、なぜオープンしたトレードごとに異なるMNを使用しているのか、ということです。これはMNが意図するところとは正反対です。MNのアイデアは、MNを見るだけで、特定のEAによるすべてのトレードを識別できることです。MNのランダムな部分の理由は何ですか?このEAのすべてのオープントレードをクローズする、あるいはこのEAのすべてのストップをトレールするEA内のコードはどのように見えるでしょうか?

すみません、私が言いたかったのは、結果として得られるint magic_nameが その割り当てを越えてしまうということです。それに応じてコード内のコメントを移動します。

私たちの認識を同じにするために私はこの'自動化された'magic_numberにこの要件を提案します。MNは次のようなものでしょう。

- このMNを持つ特定の注文が、どのEAでオープンされたかを特定できる。

- この手法を含むEAは、多数の(1つ以上の)EAに接続されている場合、そのEAが1秒のスパン以外で同時に注文を出すと、同じマジックナンバーを生成しないでしょう。

- このため、注文処理に矛盾は生じないが、同時にMNの発生元を追跡することができる。

- 私のリストが完全でない場合は、追加してください。

 
cameofx:
- 含まれる情報は、101 - エキスパートID、1 - 現時点でのThis_EAの数量、time_stamp - OrderSendの時間です。

- これをStringSubStrでスキャン すると、ある注文がThis_EAで出され、他のThis_EAが1つ付いていることが分かる。

しかし、MNのtimeの部分は何のためにあるのでしょうか?なぜ、EA番号だけを使って、substrを使わないのでしょうか?substrを使うと、intを文字列に変換し、文字列操作と文字列比較を行う必要があるが、MNの時刻の部分は必要ないので捨てられる。なぜなら、ほとんどの場合、32ビットワードの異なるビットに情報をエンコードして、ビット演算で操作したりチェックしたりした方が、桁違いに速く、エレガントだからです。

なぜ、(EA-instance-unique) int 値を mn に使用し、単純な整数比較で全体または特定のビットを比較しないのでしょうか?

例えば、最初の28ビットをID、最後の4ビットを0から15までの数字とし、異なるタイプの取引を識別する(例えば、イニシャル、レベル1、レベル2、ヘッジの3種類の注文を 出すことができるとする)。

ID = hash & 0xFFFFFFF0  // this has the 4 low bits always zero


// generate the mn for level 1 trades
MN = (ID + 1);
OrderSend(..., MN, "level 1");


// generate the mn for hedge trades
MN = (ID + 15);
OrderSend(..., MN, "hedge the whole mess");


// this strategy may not make any sense, only to illustrate the code:
// close the hedge trades and trail the stops of all levels
for(...){
   if (OrderMagicNumber() & 0xFFFFFFF0 == ID){  // this trade belongs to us
      if (OrderMagicNumber() & 0x0000000F == 15){ // this is a hedge trade
         OrderClose(...)
      }else{ // this is one of the other levels
         Trail(OrderTicket());
      }
   }
}

// or even easier:
MN = (ID + 15); // all our hedge trades have this MN
for(...){
   if (OrderMagicNumber() == MN){
      OrderClose(...)
   }
}
 
gordon:
2つのエキスパートが偶然に同じIDを持つことに対するあなたの解決策は、すべてのエキスパートIDを各エキスパートのヘッダーに置くことです。それはちょっとめんどくさいな...。仮にその部分をインクルードファイルに記述したとしても、新しいエキスパートを作るたびにすべてのエキスパートを再コンパイルする必要があります。

永続性の問題が残っています。ターミナルを再起動したり、まったく別のターミナルに切り替えたりしたときに、どうすれば正常に動作するのかがわからない......。

いいえ、そうではありません :) WindowExpertName()に関するコードのコメントを読んでください。

エキスパートから呼び出された場合、エキスパート/スクリプト/インジケータのファイル名を".mq4 "や".ex4 "なしで取得するため、インクルードする必要はなく、EAに適切な名前を付けるだけです。

PS : スパムのような返信で申し訳ありません :)

 
7bit:

しかし、MNのtimeの部分は何のためにあるのでしょうか?なぜ、EA番号だけを使って、substrを使わないのだろうか?substrを使うと、intを文字列に変換して、文字列操作と文字列比較をする必要があるが、MNのtimeの部分は必要ないので捨てられる。なぜなら、ほとんどの場合、32ビットワードの異なるビットに情報をエンコードして、ビット演算で操作したりチェックしたりした方が、桁違いに速く、エレガントだからです。

mnに(EA-instance-unique)int値を使い、単純な整数比較で全体か特定のビットを比較するのはどうでしょう?

例えば、最初の28ビットをIDとし、最後の4ビットを0から15までの数字にして、異なるタイプのトレードを識別する(例えば、初期、レベル1、レベル2、ヘッジという3種類の注文を開くことができる場合)。


うーん、、、。時間軸の部分は、EAが出した注文のMNが、同じEAで同じ時間に出した他の注文に対して、異なるチャートでユニーク でなければならないと思ったからです。

ということは、あるEAが同じマジックナンバーで2つ(以上)の注文を同時に出した場合、同じMNを持つことはできないし、そうでなければOrder handlingやOrder identificationで衝突することになる。

注文の識別...もしかしたら、OrderTicketの取得と勘違いしていたかもしれません(?)

- MNにストラテジーを組み込むのは、当然次のステップでしょう。

- あなたのスキルは私より何光年も上なんですね:))。私はまだ演算を最適化する能力がないので、このような投稿になりました。ビット演算でチェックした 方が早いということがわかりました。

ありがとうございました。後でハウツーの解説をお願いすることになるかもしれません :)))

 
cameofx:

うーん...。EAが出した注文のMNは、他の注文に対してユニーク でなければならないと思っていたので、時間の部分を使いました。

コメントと同じように、ある種の数値コメントと捉えてください。通常のMT4ユーザーインターフェースで開いたすべての手動取引は、マジックナンバー0を持つので、例えば、すべての注文をループオーバーして、すべてのEA取引をそのままにして、すべての手動取引と注文をクローズ/削除することができます。

私のすべてのEAは、(EA名+シンボル+時間枠)に固有の番号を作成します。そのため、この番号を作成するための優れた簡単なハッシュ関数を 見つけるのに非常に多くの労力を費やしました。このハッシュはとても優れているので、(必要であれば)サブナンバーのためのスペースを作るためにこのハッシュの最後の数ビットを簡単にカットすることができ、それはまだ衝突に対して非常に安全です。

しかし、私のEAのほとんどはハッシュを直接使っており、サブナンバーを付けていません。なぜなら、彼らは1種類のトレードしか持っておらず、すべてのトレードを同一に扱っているからです。

ある特定の注文だけを一意に識別するためには、常にチケット番号があります。