mql5语言的特点、微妙之处以及技巧 - 页 147

 
Igor Makanu:

IsInf()和IsNaN()正在工作。

IsEqual()和IsZerro()是有问题的,从一些资料中搜到的是 "double的技巧"。

IsNan()可以工作,但IsInf()不可以。

IsInf( DBL_MIN_DENORM) == true

从什么时候开始,变性的数字变成了无穷大?

而所有这些与epsilon的比较--epsilon应该与操作数成比例地增加。总之,没有通用的配方,我用Point作为epsilon(用四舍五入的操作数),我不想(也不需要)用DBL_EPSILON 来比较差异。

 
Vict:

而所有这些与epsilon的比较--epsilon应该与操作数成比例地增加。一般来说,没有通用的配方,我用Point作为epsilon(用四舍五入的操作数),我不想用DBL_EPSILON 来比较其差异(也不需要)。

发现我昨天从电视上看到的一篇文章https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/

是的,你必须使用另一个例子,在那里你应该指定比较的准确性

胜利

IsNan()可以工作,但IsInf()不可以。

从什么时候开始,变性的数字变成了无穷大?

MQL似乎对8位数进行了归一化处理,也就是说,如果将NormalizeDouble()添加到IsInf()中,结果仍然不会更好。

 
Igor Makanu:

MQL中的规范化似乎只到第8位,即如果将NormalizeDouble()添加到IsInf()中,结果仍然没有好转。

MQL中的规范化完全不一样,我不知道他们为什么要这样命名这个函数。https://ru.wikipedia.org/wiki/%D0%94%D0%B5%D0%BD%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D0%B8%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5_%D1%87%D0%B8%D1%81%D0%BB%D0%B0

 
我在ME中无意中发现,你可以用CTRL+1、CTRL+2、..... 来创建书签。并用ALT+1、ALT+2、...在它们之间切换。
 
// Количество успешных OrderSend.
int GetOrderSendSucceeded()
{
  MqlTradeRequest Request = {0};
  MqlTradeResult Result;

  return(OrderSend(Request, Result) ? 0 : (int)Result.request_id + 1);
}

显示在终端产生的成功的同步交易订单(OrderSend)和异步订单的总数(自开始)。

我在测试器中使用它(在最后),看看订单被修改了多少次

 
例如,很少有人不知道如何用自己的On-events创建TC类。

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

OnTick()在类实例中不起作用?

fxsaber, 2019.10.31 23:45

class BASE
{  
private:
  static BASE* Objects[];
  
public:
  BASE()
  {
    BASE::Objects[::ArrayResize(BASE::Objects, ::ArraySize(BASE::Objects) + 1) - 1] = &this;
  }
  
  ~BASE()
  {
    const int Size = ::ArraySize(BASE::Objects);
    
    for (int i = Size - 1; i >= 0; i--)
      if (BASE::Objects[i] == &this)
      {
        for (int j = i; j < Size - 1; j++)
          BASE::Objects[j] = BASE::Objects[j + 1];
          
        ::ArrayResize(BASE::Objects, Size - 1);
        
        break;
      }
  } 
    
  virtual void OnTick() = 0;
  
  static void AllTick()
  {
    for (int i = ::ArraySize(BASE::Objects) - 1; i >= 0; i--)
      BASE::Objects[i].OnTick();
  }
};

static BASE* BASE::Objects[];


class A : BASE
{
  virtual void OnTick()
  {
    Print(__FUNCSIG__);
  }
};

class B : BASE
{
  virtual void OnTick()
  {
    Print(__FUNCSIG__);
  }
};

A a;
B b;

void OnTick()
{
  BASE::AllTick();
}


继承自BASE,那么类中的OnTick方法将被自动调用。

 

一个使用X宏的例子(不要介意这些晦涩的类型,我是从工作代码中扯出来的。向量是一个动态数组)。

比如说。

   vector_fund<upindex_t> seg2; vector_ref<vector_fund<upindex_t>> seg2_sub;
   vector_fund<upindex_t> seg3; vector_ref<vector_fund<upindex_t>> seg3_sub;
   vector_fund<upindex_t> seg4; vector_ref<vector_fund<upindex_t>> seg4_sub;
   for (uint i = 0;  i < 5114;  ++ i) {
      restore_image(seg2, "seg2"); restore_subimages(seg2_sub, "seg2");
      restore_image(seg3, "seg3"); restore_subimages(seg3_sub, "seg3");
      restore_image(seg4, "seg4"); restore_subimages(seg4_sub, "seg4");
      
      if (true) {} // тест №1, использует seg2 и seg2_sub
      if (true) {} // тест №2, использует seg3 и seg3_sub
      if (true) {} // тест №3, использует seg4 и seg4_sub
   }

1.我们要在循环后面定义向量,以防止恒定分配。

2.每个测试都可以关闭(实际上有很多)。

3.restore_image()和restore_subimages(),这是一个沉重且非常耗时的函数(从图形中读取图形对象)。

4.例如,如果没有一个测试使用seg2,我想在一个动作中同时删除定义和相应的restore...(),以防止出现这样的情况:由于注释了restore...(),向量被定义但却是空的,这将产生错误的结果。

该怎么做?

#define  DEFSEG_LIST    \
   DEFSEG_HELPER(seg2) \
   DEFSEG_HELPER(seg3) \
   DEFSEG_HELPER(seg4)
   
#define  DEFSEG_HELPER(SEG) vector_fund<upindex_t> SEG; vector_ref<vector_fund<upindex_t>> SEG##_sub;
    DEFSEG_LIST;
#undef  DEFSEG_HELPER
   
   for (uint i = 0;  i < 5114;  ++ i) {
#define  DEFSEG_HELPER(SEG) restore_image(SEG, #SEG);  restore_subimages(SEG##_sub, #SEG);
    DEFSEG_LIST;
#undef  DEFSEG_HELPER
      ...
   }

只需注释掉DEFSEG_LIST中不必要的segx。这将产生与第一段代码中相同的结果。其实很可惜,编译器不能显示处理器的输出(gcc -E的模拟)。

 

有时在遗传优化中,最初的几千次传递就足以让我们或多或少地了解结果。

当你自动运行大量的优化时,你希望它都能运行得更快。这就是为什么我们将需要一个机制来中断优化。

#include <fxsaber\MultiTester\MTTester.mqh>  // https://www.mql5.com/ru/code/26132

// Выключает Оптимизацию ( и одиночный проход)
bool OptimizationStop( void )
{
  return(!MTTESTER::IsReady() && MTTESTER::ClickStart(false));
}


使用方法。

// Демонстрация прерывания Оптимизации.

sinput int inAmountPasses = 20; // Через сколько проходов закончить
input int Range = 0; // 0..10000

double OnTester()
{
  int Data[];
  
  return(FrameAdd(NULL, 0, 0, Data)); // Сгенерировали TesterPass
}

void OnTesterPass()
{
  static int Amount = 0;
  
  ulong Pass;
  string Name;
  long ID;
  double Value;
  int Data[];

  while (FrameNext(Pass, Name, ID, Value, Data))
    if (++Amount > inAmountPasses)
    {
      OptimizationStop(); // Как достигли нужного количества проходов, выключили оптимизатор.
      
      break;
    }
}
 

打开一个带有Null字符的图表的说明。


  1. 从市场观察中删除所有图表。
  2. 在数学模式下开始优化一个框架EA(例如这个)。
  3. 停止优化,从无符号图表中删除框架EA。
这样的图表可能对节省资源很有帮助。
 
我遇到过这种奇特的情况。
class A
{
  static int i;
} a; // unresolved static variable 'A::i'

static int A::i = 0;

A b; // Надо прописывать после static


如果在定义类的时候立即创建了一个带有静态字段的类,将会出现一个编译时错误