私のアプローチコアはエンジンです。 - ページ 124

 
Andrey Barinov:

OrderOpenPriceの代わりにOrderOpenTime()を入れるからです。

そうですね。混ぜてしまいました。:)

 
Реter Konow:

正直なところ、このテスト結果には少し驚きました。

だからこそ、壁にぶつかるような既成の解決策を与えるのではなく、すべて自分でやってほしかったんです。
ピーターさん、関数へのポインタというのもあって、そのポインタの配列からポインタを取るだけで関数呼び出しが できるようになっているんですよ。これはあなたのタスクにとても役立つと思います。ただ、困ったことに、また授業に手を出さなければならない。
 
Nikolai Semko:
だから、既成の解決策を与えるのではなく、全部自分でやってほしい、壁に豆をぶつけるようなものだと思ったのです。
それに、ピーター、関数へのポインタというのがあってね、そのポインタの配列からポインタを取るだけで関数呼び出しが できるんだよ。これは、あなたの問題にとても役立つと思います。しかし、ここで困ったことに、また授業に対応しなければならないのです。

関数へのポインタというのは聞いたことがあります。でも、機能はほとんどないんです。スペースがなく、OOPを使う必要があるのは、このためです。

開発コンセプトが違う んです。小さな機能を集めた大きな複合体よりも、全体的な多機能ブロックの方が運用の効率は高いと思います。

メカニズム開発の観点からは、より期待できる。

それが私の意見です...。

大きなブロックはいくつか持っています。OOPを適用するには、小さな関数に分解し、クラスに整理し、さらにポインタなどを使う必要があります。

でも、それができなくなるんです。単純に考え方が違うからです。

OOPのコンセプトは、私の考え方のクセと一致しないので、その中で展開することができないのです。それが理由です。

 
Nikolai Semko:

なお、ニコライさん、プログラム開発に関しては、私は何の問題もありません。すべてが非常に速く発展しています。

同時に、メカも問題なく動きます。

私は今、ユニオンをマスターし、ある特定のタスク、つまりリソースに文字列を書き込むというタスクでその応用を実感しています。

テストEAで速度とCPU負荷を確認して、結果を投稿してみます。

もし良ければ、エンジンとEAの通信を再構築して、リソース上に作る予定です。

 

リソースを使って長さが不定な文字列を渡すには、これらの文字列をchar配列に書き込む必要があります。

しかし、そのサイズはユニオンの内部でのみ宣言され、その後は変更されないようです。

ArrayResizeで、ユニオンのchar配列のサイズを 変更してみましたが、効果がありません。

char配列のサイズをあらかじめ設定しておく必要があるようです。そして、最大サイズであること。


以下はそのコードです。

//+------------------------------------------------------------------+
//|                                                       TEST_2.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[4];
   uint    Uint[1];   
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   EventSetMillisecondTimer(1000);
   //----------------------------------------------
   if(!ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0))Print("Object is not created!  ",GetLastError());
   else Print("Object created!");
   //-------------------------------
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource"))Print("BMPFILE is not created!");
   else Print("BMPFILE created!");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Char_Uint u;
   string String = NULL;
   int q = MathRand();
   if(q > 10000)q = 10000;
   //-------------------------------------------------------
   //Формируем случайную строку.
   //-------------------------------------------------------
   for(int a1 = 0; a1 < q; a1++)String += (string)a1 + "^";
   //-------------------------------------------------------
   //Получаем размер собранной строки.
   //-------------------------------------------------------
   int StrSize = StringLen(String);
   //-------------------------------------------------------
   //Меняем размер массива из Char[] юниона. 
   //-------------------------------------------------------
   ArrayResize(u.Char,StrSize);
   //-------------------------------------------------------
   //Копируем строку в массив Char[].
   //-------------------------------------------------------
   //StringToCharArray(String,u.Char);
   //-------------------------------------------------------
   //
   //-------------------------------------------------------
   Print("StrSize  ",StrSize," Размер u.Char  ",ArraySize(u.Char));
  }
//+------------------------------------------------------------------+
 

これで、ユニオンのchar 配列のサイズを あらかじめ知っておく必要があることが明らかになった。ArrayResize(u.Char,StrSize)では変更 されないからです。

そこで、配列のサイズを最大文字列の長さと同じにする必要があるのですが......。

 

朗報です。すべてがうまくいっています。

その文字列はリソースに書き込まれ、別のチャート上の別のEAが読み取る。

プロセッサーに負荷がかからない。文字列を表示するAlertを呼び出すだけで負荷が発生します。

Expert Advisorのコードはこちらです。

1.Expert Advisorが文字列を形成し、リソースに書き込む。

//+------------------------------------------------------------------+
//|                                                       TEST_2.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[32000];
   uint    Uint[8000];   
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   EventSetMillisecondTimer(16);
   //----------------------------------------------
   if(!ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0))Print("Object is not created!  ",GetLastError());
   else Print("Object created!");
   //-------------------------------
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource"))Print("BMPFILE is not created!");
   else Print("BMPFILE created!");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Char_Uint u;
   string String = NULL;
   int q = MathRand(),width,height;
   if(q > 1000)q = 1000;
   //-------------------------------------------------------
   //Формируем случайную строку.
   //-------------------------------------------------------
   for(int a1 = 0; a1 < q; a1++)String += (string)a1 + "^";
   //-------------------------------------------------------
   //Получаем размер собранной строки.
   //-------------------------------------------------------
   int StrSize = StringLen(String);
   //-------------------------------------------------------
   //Копируем строку в массив Char[].
   //-------------------------------------------------------
   StringToCharArray(String,u.Char);
   //-------------------------------------------------------
   //Cохраняем строку переведенную в байты в ресурсе.
   //-------------------------------------------------------
   if(!ResourceCreate("::Resource",u.Uint,8000,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA))Print("Resource is not created!");
   //-------------------------------------------------------
  }
//+------------------------------------------------------------------+
 

他のチャートの資料からラインを読み取るアドバイザー。

//+------------------------------------------------------------------+
//|                                              Resource reader.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//+------------------------------------------------------------------+
union Char_Uint
  {
   uchar   Char[32000];
   uint    Uint[8000];   
  };
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   EventSetMillisecondTimer(16); 
   
   if(!ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"\\Experts\\TEST_2.ex4::Resource"))Print("Resource is not connected!");
   else Print("Resource connected!");
//---
   return(INIT_SUCCEEDED);
  }


//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   Char_Uint u;   
   uint width,height;
   //string Message; 
   //-----------------------------
   if(!ResourceReadImage("\\Experts\\TEST_2.ex4::Resource",u.Uint,width,height))Print("Failed to read resource!  ",GetLastError());
   //-----------------------------
   string String = CharArrayToString(u.Char);
   //-----------------------------
   Alert("  String  ",String);
   //-----------------------------
  }
//+------------------------------------------------------------------+


コミュニケーションのためのリソースを活用する。唯一の欠点は、ユニオンに最大文字配列サイズを 設定する必要があることです。しかし、文字列の大きさやMTオブジェクトの数を考える必要はない。

この方法は、MT-objectのリンク方法より遅いですが、問題ありません。

 
Реter Konow:

私の実験結果と全く一致しないのですが、面白い理論ですね、これから下に投稿します。

テストでもわかるように、CPUに最も負荷がかかるのは画素配列の初期化です。

以下、テスト用EAをご確認ください。

課題を読み直す。

ワシリー・ソコロフ

ピーター、これが課題だ。MT4で現在の注文受付を表示するパネルを作る。システムパネルの完全なコピーを作成する必要はなく、未決済注文の基本的なプロパティ(未決済価格、方向、利益)を含む簡単なテーブルを作成するだけでよいのです。あとは、あなた次第です。注文が締め切られると、テーブルの表示も消えます。また、その逆も然りで、新しいオーダーが開かれるとこのテーブルに表示されることになります。

ここでは、画面上で表が変わったときに再描画するために必要な操作として、1.取引終了時、2.取引開始時、の2つを挙げています。なぜ、それ以外のタイミングで画素を再描画するのか?

何か別の問題を解決しているのでしょうか?

 
Vladimir:

問題を読み直してください。

ワシリー・ソコロフ

ここでは、画面上でテーブルが変化する際に必要な再描画の操作を、1.取引終了時、2.取引開始時の2つについて見ています。なぜ、それ以外のタイミングで画素を再描画するのか?

何か別の問題を解決しているのでしょうか?

まあ、おっしゃるとおりに描き直されていますね。

アニメーション 中にプロセッサの負荷が表示されます。

画素配列の値は常に再初期化されます。16ミリ秒ごと。これにより、プロセッサに最大40%の負荷がかかります。

具体的にどのような負荷がかかっているのか、考えてみました。リソースを保存したり、読んだりすることだと思いました。描画ループ内の配列の再初期化が原因であることが判明しました。


また、ObjectSetInteger(0, "MT object",OBJPROP_SELECTED,1); の定数呼び出し(16 ms毎)でもプロセッサをロードすることが判明した。約10%の差で。

この呼び出しを使って、別のEAにアニメーションデータの入ったリソースを読み込むように指示するのです。

アニメーション中はトータルで+〜50%のCPU負荷がかかります。