mql5言語の特徴、微妙なニュアンスとテクニック - ページ 147

 
Igor Makanu:

IsInf()、IsNaN()は動作しています。

IsEqual()とIsZerro()は、「ダブルのトリック」として、いくつかの情報源からググってみると、疑問が残る。

IsNan()は動作するが、IsInf()は動作しない

IsInf( DBL_MIN_DENORM) == true

いつから非正規化数が無限大になったんだ?

そして、これらすべてのε-εでの比較は、オペランドに比例して増加させる必要があります。とにかく、普遍的なレシピはなく、私はPointをイプシロンとして(オペランドを丸めて)使っており、DBL_EPSILONとの 差分を比較したくない(する必要がない)のです。

 
Vict:

そして、これらすべてのε-εでの比較は、オペランドに比例して増加させる必要があります。一般的には、普遍的なレシピはなく、私はPointをイプシロンとして(オペランドを丸めて)使用し、DBL_EPSILONとの 差を比較したくない(する必要がない)です。

昨日読んだTVhttps://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ の記事を発見。

はい、比較精度を指定する必要がある別の例を使用する必要があります。

ビクト

IsNan()は動作するが、IsInf()は動作しない

いつから非正規化数が無限大になったんだ?

MQLは8桁まで正規化するようで、IsInf()にNormalizeDouble()を追加しても、結果は変わらない。

 
Igor Makanu:

MQLの正規化は8桁目までのようです。つまり、IsInf()にNormalizeDouble()を追加しても、結果は良くなりません

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。

 
CTRL+1、CTRL+2、......でブックマークが作れることを偶然にもMEで発見してしまいました。そして、ALT+1, ALT+2, ...で切り替えができます。
 
// Количество успешных OrderSend.
int GetOrderSendSucceeded()
{
  MqlTradeRequest Request = {0};
  MqlTradeResult Result;

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

ターミナルで発生した同期取引注文(OrderSend)および非同期注文の成功件数を合計(開始以降)して表示します。

テスターで(最後に)注文の修正回 数を確認するために使っています。

 
例えば、独自のOn-eventを持つ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 Macroの使用例(わかりにくい型は気にしないでください。Vectorは動的な配列 です)。

例えば、こんな感じです。

   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...()のために、vectorが定義されているが空であるという状況を防ぎ、誤った結果を与えることを防ぐために、定義と対応する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. Market Watchからすべてのチャートを削除する。
  2. フレームEA(例えばこれ)の最適化を数学モードで開始。
  3. Optimizationを停止し、Null-symbolチャートからフレームEAを削除します。
このようなチャートは、おそらく資源節約のために有用である。
 
このクセに遭遇したことがあります。
class A
{
  static int i;
} a; // unresolved static variable 'A::i'

static int A::i = 0;

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


クラス定義中に、すぐにstaticフィールドを持つクラスを作成した場合、コンパイル時にエラーが 発生します。

理由: