"ダミー "からの質問 - ページ 62

 
x100intraday:
例を挙げると...

こんな感じ(もちろん構造ではなく、クラスです)。

class TBuffer
{
public:
  double  MABuffer[ ];
};

//---------------------------------------------------------------------
TBuffer*  Buffer_Array[ ];
//---------------------------------------------------------------------

//---------------------------------------------------------------------
  ArrayResize( Buffer_Array, NUMBER );
  for( int i = 0; i < NUMBER; i++ )
  {
    Buffer_Array[ i ] = new TBuffer;
    SetIndexBuffer( i, Buffer_Array[ i ].MABuffer, INDICATOR_DATA );
  }

どこに何を置くかは、明確だと思います。

最後に忘れてはいけないことがあります。

  for( int i = 0; i < NUMBER; i++ )
  {
    delete( Buffer_Array[ i ] );
  }
 
Yedelkin:

言い直します。関数を定義するときに、それが可能かどうか疑問に思っているのでしょう。

構造体の正式なパラメータとして、構造体そのものの名前を無視して、構造体型の変数だけを指定するのですか?例えば、void funcName(MqlTradeRequest & req)ではなく、void funcName(& req)と指定すればいいのでしょうか。

メソッドやディン、アレイなど、単純な 構造であれば普遍的な関数が必要です。--- 純粋に特定のデータ型のシーケンスです。

脚本の構成は私があらかじめ決めているので、扱うべき構造の数を明示的に指定することができます。

struct Data1
  {
   double param[1000000];
  };
struct Data2
  {
   int    temp;
   double k;
  };
struct Data3
  {
   int    temp;
   double k;
  };

しかし、これらの構造体を 1つの名前で 関数に渡すには、オーバーロードを使用しなければなりません。

void funWrite(Data1 &dd[])
  {
    .....
    Один тип обработки для всех структур
    .....
    FileWriteArray(1, dd);
  }
void funWrite(Data2 &dd[])
  {
    .....
    Один тип обработки для всех структур
    .....
    FileWriteArray(1, dd);
  }
void funWrite(Data3 &dd[])
  {
    .....
    Один тип обработки для всех структур
    .....
    FileWriteArray(1, dd);
  }

ここには、いくつかの困難があります。

1.要素数が多くなるとオーバーロードが遅くなるため、構造体の数を制限しています。

2.私自身、オーバーロード関数をコピーする際にミスをすることがあります。

PS//funWrite() 関数は、ある計算を行い、あるシーケンスと計算されたパラメータ(どのインデックスから書き込むか、いくつ読み込むか)でFileWriteArray() を実行するものである。

 
rlx:

メソッドやディン、アレイなど、単純な 構造であれば普遍的な関数が必要です。--- 純粋に特定のデータ型のシーケンスです。

スクリプトの構成はあらかじめ私が決めているので、扱う構造の数を明示的に指定することができます。

しかし、これらの構造体のいずれかを1つの名前の 関数に渡すには、オーバーロードを使用しなければなりません。

なるほど。少し前に、関数を定義する際に配列の型を指定しない ことは可能か、という同様の質問をしたことがあります。そのすぐ下に、ロシュはオーバーロードを勧めている。

そこで、FileWriteArray() のように、void型で何らかのパラメータを指定する「組み込み」関数は、それ自体がオーバーロードされた関数であるという結論に至ったのです。ただ、その実装が見えていないだけです。

 
Yedelkin:

なるほど。以前、関数定義の際に配列の型を指定しない ことは可能か、という似たような質問をしたことがあります。そのすぐ下に、ロシュはオーバーロードを勧めている。

そこで、FileWriteArray() のように、void型で何らかのパラメータを指定する「組み込み」関数は、それ自体がオーバーロードされた関数であるという結論に至ったのです。ただ、その実装が見えないだけなのです。

内蔵関数は完全なプログラミング言語で書かれています。

例えばC言語では、変数をいくつでも渡すことができ、すでに関数内で渡されたパラメータのリストを取得し、それらを調べることができます。

void fun(...)
  {
}

MQL5では、そのような可能性はありません。特に、単純なデータ型や構造体へのリンクやポインタが欠けている...。

 

セキュリティと関係があるのでしょう。データへのアクセス砂場の 外に出ること。

しかし、やはりこれらの機能はMQL5で実装して欲しいですね。

 
rlx:

セキュリティと関係があるのでしょう。データへのアクセス砂場の 外に出ること。

しかし、やはりこれらの機能はMQL5で実装して欲しいですね。

サービスデスクに依頼するのがよいでしょう。そうでないと、すぐにフォーラムから消えてしまいます。
 
Dima_S:

こんな感じ(もちろん構造ではなく、クラスです)。

どこに何を入れればいいのかが明確になっていると思います。

最後に、忘れてはいけないことがあります。

これぞまさに「ヘルプ」と呼ぶにふさわしい、リアルで具体的なものです。ありがとうございます。プラス記号はどこだ?

ところで...私はそれで十分だと考えています。でも、形式主義にはなりたくない...。...そこで、興味本位で2次元の配列を整理してみても損はないだろうと思い立ちました。MQLは、この十数年で忘れてしまったC/C++のようなものを思い出させる。今、この方法でやってみました(ループなし・わざと簡略化しました)。

class TBuffer
{
public:
  double MABuffer[][1];
};

//---------------------------------------------------------------------
TBuffer* Buffer_Array[][1];
//---------------------------------------------------------------------
int OnInit()
  {
   ArrayResize(Buffer_Array,1);
   Buffer_Array[0][0] = new TBuffer;
   SetIndexBuffer(0,Buffer_Array[0][0].MABuffer,INDICATOR_DATA);
// --- [...]
   delete(Buffer_Array[0][0]);
   return(0);
  }

コンパイラは、「'MABuffer' - パラメータの変換が許可されていません」というエラーを発生させます。

何がいけないんだろう。私の記憶が間違っていなければ、多次元配列を 持つクラスを宣言するとき、測定の1つを数値で指定する必要があります。一方、ArrayResizeは最初の次元の新しいサイズを設定 します。

 

x100intraday:

何が悪いんだろう?

1)SetIndexBufferは、同じ次元のdoubleの配列で動作します。

2) TBuffer*を使う理由が不明です。つまり、必要ないところでダイナミクスを使うのでしょうか?

3) (TIP) この例では、クラスの代わりに構造体を使うことで、少しのメモリと数百クロックサイクルを節約することができました。

 

mql5:

3) (TIP) この例では、クラスではなく構造体を使うことで、少しのメモリと数百クロックサイクルを節約することができました。

これは確認されているのでしょうか?
 

エキスパートアドバイザーは、異なるタイムフレームでインジケータを使用します。Expert Advisor のテストでは、インジケータから間違ったデータが表示されます。

EA自体はM5で、インジケータはH4で動作します。同じタイムフレーム(M5)で呼び出された指標は、正しい値を返します。

返される値は、インジケータの値と似ていますが、価格チャートウィンドウにインジケータが適用されたときに見える実際の値とは異なります。

何が問題なのか?

インジケータ呼び出しの コード例です。

int W_handle;
int OnInit()
  {
   W_handle=iCustom(NULL, PERIOD_H4, "WW");
  }

void OnNewBar() // моя функция
{
 double wave[10];
 ArraySetAsSeries(wave, true);

 CopyBuffer(W_handle,0,0,2,wave);
 if (wave[1] > 0) Buy(); 
// по замыслу в wave[1] должно лежать значение индикатора на предыдущем баре H4
// но так получается только на нескольких первых обращениях, потом результат начинает расходиться с реальностью
}
Способы вызова индикаторов в MQL5
Способы вызова индикаторов в MQL5
  • 2010.03.09
  • KlimMalgin
  • www.mql5.com
C появлением новой версии языка MQL, не только изменился подход к работе с индикаторами, но и появились новые способы создания индикаторов. Кроме того, появилась дополнительная гибкость при работе с индикаторными буферами - теперь вы можете самостоятельно указать нужное направление индексации и получать ровно столько значений индикатора, сколько вам требуется. В этой статье рассмотрены базовые методы вызова индикаторов и получения данных из индикаторных буферов.