程序库: TypeToBytes

 

TypeToBytes:

结构和标准数据类型的逐字节操作。

作者: fxsaber

 
如何使用图书馆的一个简短示例

关于交易、自动交易系统和交易策略测试的论坛

两个相邻的 BookEvent 可以复制一个堆栈

fxsaber, 2016.09.14 16:29

EA 显示两个相邻的堆栈是彼此的副本时的情况

#include <TypeToBytes.mqh> //https://www.mql5.com/zh/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/zh/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/zh/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/zh/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);                // 将结构对象的值以零偏移写入 CloneTick Tick
_W(Color, 2, (uchar)230);              // 在偏移量 2 处写入值 (uchar)230。
而不是笨重的记录。
_W(Tick)[Offset] = 1.23456;             // 在找到的偏移量处写入数值 (double)1.23456
_W(CloneTick)[0] = Tick;                // 将结构对象的值以零偏移写入 CloneTick Tick
_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:
 
简明的非数字双重比较

交易、自动交易系统和交易策略测试论坛

如何快速比较 double 和 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
您更新了出版物中的源代码吗?