ライブラリ: TypeToBytes

 

TypeToBytes:

構造体と標準データ型のバイト単位の操作。

作者: fxsaber

 
ライブラリーの簡単な使用例

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

隣り合う2つのBookEventがスタックを複製できる

fxsaber, 2016.09.14 16:29

EAは、隣り合う2つのスタックが互いにコピーである場合を示しています。

#include <TypeToBytes.mqh> //https://www.mql5.com/ja/code/16280

template <typename T>
bool ArrayEqual( const T &Array1[], const T &Array2[] )
{
  const int Amount = ArraySize(Array1);
  bool Res = (Amount == ArraySize(Array2));

  if (Res)
    for (int i = 0; i < Amount; i++)
      if (_R(Array1[i]) != Array2[i]) //https://www.mql5.com/ja/code/16280
      {
        Res = false;

        break;
      }

  return(Res);
}

template <typename T>
bool ArrayClone( const T &Source[], T &Target[] )
{
  ArrayFree(Target);

  return(ArrayCopy(Target, Source) >= 0);
}

void OnInit( void )
{
  MarketBookAdd(_Symbol);
}

void OnDeinit( const int Reason )
{
  MarketBookRelease(_Symbol);
}

void OnBookEvent( const string &symbol )
{
  static MqlBookInfo PrevBook[];
  MqlBookInfo Book[];

  if ((symbol == _Symbol) && MarketBookGet(symbol, Book))
  {
    if (ArrayEqual(Book, PrevBook))
    {
      if (ArraySize(PrevBook) > 0)
        Alert("Book == PrevBook");
    }
    else
      ArrayClone(Book, PrevBook);
  }
}

結果

2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:29.406 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:23.151 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:23.151 Test2 (Si-9.16,M1)      Book == PrevBook
このような状況には多くの理由が考えられます。MT5がいくつかのスタックをスキップすることから、取引所自体が二重のスタックを生成することまで。

 
別の例

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

CopyTicks」のテスト

fxsaber, 2016.09.15 10:07 AM

他の人がCopyTicksをどのように使っているのか私には理解できない。残念ながら信頼はありません。非常に生々しい。

アドバイザー

#include <TypeToBytes.mqh> //https://www.mql5.com/ja/code/16280

void OnTick( void )
{
  static MqlTick PrevTick;  
  static int Amount = 0;
  
  MqlTick Ticks[];
  
  if (Amount > 0)
  {
    Amount = CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, PrevTick.time_msc);
    
    int i;
    
    for (i = 0; i < Amount; i++)
      if (_R(Ticks[i]) == PrevTick) //https://www.mql5.com/ja/code/16280
        break;
        
    if (i == Amount)
      Print(「物語の中で(長さ=" + (string)Amount + ")前のイベントにあった目盛りはない。");
  }
  else
    Amount = CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, TimeCurrent() * 1000);
    
  if (Amount > 0)
    PrevTick = Ticks[Amount - 1];  
}

結果

2016.09.15 11:04:02.810 Test2 (RTS-9.16,M1)     В истории (length = 2) нет тика, что был на предыдущем Event.
2016.09.15 11:03:59.312 Test2 (RTS-9.16,M1)     В истории (length = 13) нет тика, что был на предыдущем Event.
2016.09.15 11:03:59.290 Test2 (RTS-9.16,M1)     В истории (length = 1) нет тика, что был на предыдущем Event.

履歴に残っていたTickが、次のTickイベントで履歴から消えてしまう!

開発者の皆さん、CopyTicksを使える状態にしてください。簡単なテストでさえ失敗します。


 
私は、そのような面倒なエントリーを、そのようなかさばる記録の代わりに置き換えることができる抜け道を見つけた
_W(Tick, Offset, (double)1.23456);     // 見つかったオフセットに値 (double)1.23456 を書き込む。
_W(CloneTick, 0, Tick);                // 構造オブジェクトTickの値をゼロオフセットでCloneTickに書き込む。
_W(Color, 2, (uchar)230);              // オフセット 2 に値 (uchar)230 を書き込む。
つまり、標準的な型や単純な構造体を配列のように扱うことができるのだ。
_W(Tick)[Offset] = 1.23456;             // 見つかったオフセットに値 (double)1.23456 を書き込む。
_W(CloneTick)[0] = Tick;                // 構造オブジェクトTickの値をゼロオフセットでCloneTickに書き込む。
_W(Color)[2] = (uchar)230;              // オフセット 2 に値 (uchar)230 を書き込む。

つまり、標準的な型や単純な構造体を 配列のように、読み込みモードだけでなく書き込みモードでも使える可能性があるのだ!
 
fxsaber:
私は、このような面倒なエントリーを置き換えることができる抜け道を見つけた。
通常の

つまり、標準的な型や単純な構造体を 配列のように、読み込みモードだけでなく書き込みモードでも扱うことができる本当の可能性があるのだ!

公開された。これで、どんな変数(構造体や標準型)でも、配列のように読み込みだけでなく、書き込みもできるようになった:

_W(AnyVariable)[Pos] = AnyValue; // バイトオフセット Pos の AnyValue 値を AnyVariable 変数に書き込みます。

実装前に推測するのは簡単ではなかった。平均的なOOPマスターの良いテストになったと思う。

もし同じようなことを知っている人がいたら、教育のためにリンクをシェアしてほしい。

 
変数のバイト内容を表示する例
#include <TypeToBytes.mqh>

#define  TOSTRING(A) " " + #A + " = " + (string)A

string BytesToString( const uchar &Bytes[] )
{  
  string Str = "";

  const int Amount = ArraySize(Bytes);
  
  for (int i = 0; i < Amount; i++)
    Str += TOSTRING(i) + "," + TOSTRING(Bytes[i]) + "\n";
    
  return(Str);
}

#define  VALUETOSTRING(A) typename(A) + TOSTRING(A) + ":\n" + BytesToString(_R(A).Bytes)

void OnStart()
{
  int Tmp = 1;  
  Print(VALUETOSTRING(Tmp));
  
  Tmp = -1;
  Print(VALUETOSTRING(Tmp));
}
表示結果
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 3, Bytes[i] = 255
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 2, Bytes[i] = 255
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 1, Bytes[i] = 255
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 0, Bytes[i] = 255
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)     int Tmp = -1:
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)     
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 3, Bytes[i] = 0
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 2, Bytes[i] = 0
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 1, Bytes[i] = 0
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 0, Bytes[i] = 1
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)     int Tmp = 1:
 
簡潔な非数値二重比較

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

ダブルとQNaNを素早く比較するには?

fxsaber, 2016.10.11.11:14 pm.

それはすごいですね、知りませんでした!ではこの方法で
#include <TypeToBytes.mqh>

double Nan(long bit_value)
  {
   struct L { long   x; } l; l.x=bit_value;
   struct D { double x; } d=(D)l;
   return(d.x);
  }

double QNaN   =Nan(0x7FF7000000000000);  

void OnStart()
{
   if (_R(QNaN)==QNaN) {
      Alert("QNaN is QNaN");
   } else {
      Alert("Ooops");
   }   
}

 
ノット・ア・ナンバー・ダブルの 作成例
#include <TypeToBytes.mqh>

void OnStart()
{
  double QNaN = 0;
  
  _W(QNaN) = 0x7FF7000000000000;
  
  Print(QNaN);
}

 
新機能の例は、直接ライブラリに触れることはありませんが、間接的に触れる - 構造のトピックについて

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

MetaEditorビルド1463

fxsaber, 2016.11.10:42 AM

class PRINTCLASS
{
public:  
  template <typename T>
  static void MyPrint( const T &Value )
  {
    T Array[1];
    
    Array[0] = Value;
    
    ::ArrayPrint(Array);
  }
  
  template <typename T>
  static void MyPrint( const T Value )
  {
    ::Print(Value);
  }
};

#define Print(A) PRINTCLASS::MyPrint(A)

void OnStart()
{
  MqlTick Tick;
  
  SymbolInfoTick(_Symbol, Tick);

  Print(Tick);
  
  int i = 5;
  
  Print(i);
}
単純な構造も印刷できるようになりました。
 
fxsaber:
数字ではないダブルの 作成例
#include <TypeToBytes.mqh>

void OnStart()
{
  double QNaN = 0;
  
  _W(QNaN) = 0x7FF7000000000000;
  
  Print(QNaN);
}

では、別の方法を紹介しよう。

#include <TypeToBytes.mqh>

void OnStart()
{
  double Number = (double)"01.23_example";
  double Nan = (double)"nan";
  
  Print(Number);
  Print(Nan);
  
  ArrayPrint(_R(Nan).Bytes); // バイトを印刷する
  
  ulong Num = 0;
  
  _W(Num) = Nan; // NanからNumへのバイト単位のコピー
    
  PrintFormat("%I64X", Num);
}

結果

1.23
nan
255 255 255 255 255 255 255 127
7 F FFFFFFFFFFFFFF
 
fxsaber:

今なら違うやり方ができる

#include <TypeToBytes.mqh>

void OnStart()
{
  double Number = (double)"01.23_example";
  double Nan = (double)"nan";
  
  Print(Number);
  Print(Nan);
  
  ArrayPrint(_R(Nan).Bytes); // バイトを印刷する
  
  ulong Num = 0;
  
  _W(Num) = Nan; // NanからNumへのバイト単位のコピー
    
  PrintFormat("%I64X", Num);
}

結果

1.23
nan
255 255 255 255 255 255 255 127
7 F FFFFFFFFFFFFFF
出版物のソースコードを更新しましたか?