記事"MQL5 標準ライブラリの拡張とコードの再利用"についてのディスカッション - ページ 2

 
Tango_X:


インジケータ・バッファ配列のインデックス方向が、ArraySetAsSeriesと同じように、ここでどのように設定さ れるかを理解する手助けをしてください。デフォルトの方向は現在から過去ですが、過去から現在にする必要があります。昨日からこの質問で悩んでいます! 助けてください!

標準のZigZagを使うので必要ありません。

//--- 作成
   m_handle=iCustom(symbol,period,"zigzag",depth,deviation_create,backstep);

このZigZagで 方向が設定されている場所を探してみてください。しかし、なぜそれが必要なのかはまだ不明です。https://www.mql5.com/ja/docs/series、インデックスの方向はいつでも自分で変更できます。

Документация по MQL5: Доступ к таймсериям и индикаторам
Документация по MQL5: Доступ к таймсериям и индикаторам
  • www.mql5.com
Доступ к таймсериям и индикаторам - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Rashid Umarov:

標準的なジグザグを使用しているので、これは必要ない。

このZigZagで 、方向が設定されている場所を探してください。しかし、なぜそれが必要なのかはまだ不明です。https://www.mql5.com/ja/docs/series、インデックスの方向はいつでも自分で変更できます。


情報をありがとう!

 
Rashid Umarov:

標準的なジグザグを使用しているため、その必要はありません。

このZigZagの 中で、方向が設定されている場所を探してください。 しかし、なぜそれが必要なのか、まだ明確ではありません - インデックスの方向はいつでも自分で変更できます -https://www.mql5.com/ja/docs/series。


申し訳ありませんが、Zigzagのソースにアクセスできない場合など、インデックスの方向を変更する方法がまだ明確ではありません。インデックスの方向は、ArraySetAsSeries() - 入力パラメータは参照配列 - によって設定されます、

しかし、我々はこの配列を持っておらず、インジケータ・バッファ配列へのポインタを

//--- バッファの作成
      ((CIndicatorBuffer*)At(0)).Name("ZIGZAG");
      ((CIndicatorBuffer*)At(1)).Name("HIGH");
      ((CIndicatorBuffer*)At(2)).Name("LOW");
 
//+------------------------------------------------------------------+
//|OOO_ZIGZAG.mq5
//| Copyright 2017, MetaQuotes Software Corp.
//|https://www.mql5.com
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#include <..\Include\Indicators\Indicator.mqh>


//--- 入力パラメータ
input ENUM_TIMEFRAMES   EAPeriod=PERIOD_CURRENT; //スケジュール期間
input string            CurrencyPair="EURUSD.m"; //シンボル

//+------------------------------------------------------------------+
//| CiZigZagクラス。|
//| 目的:ジグザグ・インジケータ・クラス。
//| CIndicatorクラスの出力。|
//+------------------------------------------------------------------+
class CiZigZag : public CIndicator
  {
protected:
   int               m_depth;
   int               m_deviation;
   int               m_backstep;

public:
                     CiZigZag(void);
                    ~CiZigZag(void);
   //--- 保護されたデータへのアクセス方法
   int               Depth(void)          const { return(m_depth);      }
   int               Deviation(void)      const { return(m_deviation);  }
   int               Backstep(void)       const { return(m_backstep);   }
   //--- 作成方法
   bool              Create(const string symbol,const ENUM_TIMEFRAMES period,
                            const int depth,const int deviation_create,const int backstep);
   //--- 指標データへのアクセス方法
   double            ZigZag(const int index) const;
   double            High(const int index) const;
   double            Low(const int index) const;
   //--- 識別方法
   virtual int       Type(void) const { return(IND_CUSTOM); }

protected:
   //--- カスタマイズ方法
   virtual bool      Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam &params[]);
   bool              Initialize(const string symbol,const ENUM_TIMEFRAMES period,
                                const int depth,const int deviation_init,const int backstep);
  };
//+------------------------------------------------------------------+
//| コンストラクタ|
//+------------------------------------------------------------------+
CiZigZag::CiZigZag(void) : m_depth(-1),
                         m_deviation(-1),
                         m_backstep(-1)
  {
  }
//+------------------------------------------------------------------+
//| デストラクタ|
//+------------------------------------------------------------------+
CiZigZag::~CiZigZag(void)
  {
  }
//+------------------------------------------------------------------+
//|| ジグザグ・インジケータの作成|
//+------------------------------------------------------------------+
bool CiZigZag::Create(const string symbol,const ENUM_TIMEFRAMES period,
                      const int depth,const int deviation_create,const int backstep)
  {
//--- 履歴をチェックする
   if(!SetSymbolPeriod(symbol,period))
      return(false);
//--- 作成
   m_handle=iCustom(symbol,period,"Examples\\ZigZag",depth,deviation_create,backstep);
//--- 結果をチェックする
   if(m_handle==INVALID_HANDLE)
      return(false);
//--- インジケータの作成に成功
   if(!Initialize(symbol,period,depth,deviation_create,backstep))
     {
      //--- 初期化エラー
      IndicatorRelease(m_handle);
      m_handle=INVALID_HANDLE;
      return(false);
     }
//--- OK
   return(true);
  }
//+------------------------------------------------------------------+
//| インジケーターをユニバーサル・パラメーターで初期化する。
//+------------------------------------------------------------------+
bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam &params[])
  {
   return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value));
  }
//+------------------------------------------------------------------+
//| 特別なパラメーターでインジケーターを初期化する。
//+------------------------------------------------------------------+
bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,
                        const int depth,const int deviation_init,const int backstep)
  {
   if(CreateBuffers(symbol,period,3))
     {
      //--- レンダリングステータス行
      m_name  ="ZigZag";
      m_status="("+symbol+","+PeriodDescription()+","+
               IntegerToString(depth)+","+IntegerToString(deviation_init)+","+
               IntegerToString(backstep)+") H="+IntegerToString(m_handle);
      //--- 設定を保存する
      m_depth=depth;
      m_deviation=deviation_init;
      m_backstep=backstep;       
      //--- バッファの作成
      ((CIndicatorBuffer*)At(0)).Name("ZIGZAG");
      ((CIndicatorBuffer*)At(1)).Name("HIGH");
      ((CIndicatorBuffer*)At(2)).Name("LOW");
      //--- OK
      return(true);
     }
//--- エラー
   return(false);
  }
//+------------------------------------------------------------------+
//| ジグザグ・インジケータのジグザグ・バッファにアクセスする。
//+------------------------------------------------------------------+
double CiZigZag::ZigZag(const int index) const
  {
   CIndicatorBuffer *buffer=At(0);
//--- チェック
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+
//| ジグザグ・インジケータのHighバッファへのアクセス。
//+------------------------------------------------------------------+
double CiZigZag::High(const int index) const
  {
   CIndicatorBuffer *buffer=At(1);
   //--- チェック
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+
//| ジグザグ・インジケータのLowバッファへのアクセス。
//+------------------------------------------------------------------+
double CiZigZag::Low(const int index) const
  {
   CIndicatorBuffer *buffer=At(2);
//--- チェック
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
//+------------------------------------------------------------------+



CiZigZag *Zig;
//+------------------------------------------------------------------+
//| カスタムインジケータ初期化関数
//+------------------------------------------------------------------+
int OnInit()
  {
//--- インジケータ・バッファのマッピング
   Zig=new CiZigZag;
   Zig.Create(CurrencyPair,EAPeriod,12,5,3);
//---
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   delete(Zig);
  }  
//+------------------------------------------------------------------+
//| カスタム・インジケータ反復関数
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int limit;
   if(prev_calculated==0)limit=0;
   else
     limit=prev_calculated-1; 
     
   for(int i=limit;i<rates_total && !IsStopped();i++)
      {
       Zig.Refresh();
       if (Zig.ZigZag(i)!=0) Print(Zig.ZigZag(i)," ",time[i]);  
      }
//--- 次の呼び出しのためにprev_calculatedの値を返す
   return(rates_total);
  }
//+------------------------------------------------------------------+

以下にインジケーターの完全なコードを示す。インジケーターの値の出力は現在から過去へ、そしてその逆も必要である。

 
Tango_X:

申し訳ありませんが、例えば、ソース・ジグザグへのアクセスがない場合、インデックスの方向を変更する方法はまだ明確ではありません。インデックスの方向は、ArraySetAsSeries() - 入力パラメータは参照配列 - によって設定されます、

しかし、私たちはこの配列を持っておらず、インジケータ・バッファ配列へのポインタを

CIndicator 基底クラスにはGetData メソッドがあり、これを使用してインジケータ・バッファからデータを取得することができます。

開始位置と番号でインジケータ・バッファからデータを取得する

int GetData(
const intstart_pos, // 位置
const intcount, // 数
const int buffer_num, // バッファ番号
double&buffer[]// 配列
) const



その後、ArraySetAsSeries を使用して、配列のインデックス方向を設定します。

 
Rashid Umarov:

CIndicator 基本クラスには、インジケータ・バッファからデータを取得するために使用できるGetData メソッドがあります。

インジケータ・バッファから、開始位置と

int GetData(
const intstart_pos, // 位置
const intcount, // 数
const int buffer_num, // バッファ番号
double&buffer[]// 配列
) const



その後、配列のインデックスの方向を設定します。

つまり、インジケータ・バッファに2回アクセスすることになりますが、異なる方法でアクセスすることになります。結局のところ、ここではすでにインジケータ・バッファの値にアクセスしているのですね。我々は中間配列double &buffer[]を取得します。

//+------------------------------------------------------------------+
//| ジグザグ・インジケータのジグザグ・バッファにアクセスする。
//+------------------------------------------------------------------+
double CiZigZag::ZigZag(const int index) const
  {
   CIndicatorBuffer *buffer=At(0);
//--- チェック
   if(buffer==NULL)
      return(EMPTY_VALUE);
//---
   return(buffer.At(index));
  }
 
Rashid Umarov:

CIndicator 基本クラスには、インジケータ・バッファからデータを取得するために使用できるGetData メソッドがあります。

インジケータ・バッファから、開始位置と

int GetData(
const intstart_pos, // 位置
const intcount, // 数
const int buffer_num, // バッファ番号
double&buffer[]// 配列
) const



その後、ArraySetAsSeriesを使用して配列のインデックス方向を設定します。

正しく理解できましたか?

CiZigZag *Zig;
double ArrZig[];
//+------------------------------------------------------------------+
//| カスタムインジケータ初期化関数
//+------------------------------------------------------------------+
int OnInit()
  {
//--- インジケータ・バッファのマッピング
   Zig=new CiZigZag;
   Zig.Create(CurrencyPair,EAPeriod,12,5,3);

   SetIndexBuffer(0,ArrZig,INDICATOR_CALCULATIONS);
   ArraySetAsSeries(ArrZig,false);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   delete(Zig);
  }
//+------------------------------------------------------------------+
//| カスタム・インジケータ反復関数
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int limit;
   if(prev_calculated==0) limit=0;
   else
      limit=prev_calculated-1;

   Zig.Refresh();
   Zig.GetData(0,rates_total-1,0,ArrZig);

   for(int i=limit;i<rates_total-1 && !IsStopped();i++)
     {

      //if (Zig.ZigZag(i)!=0) Print(Zig.ZigZag(i),"",time[i]); 
      if(ArrZig[i]!=0) Print(ArrZig[i]," ",time[i]);
     }
//--- 次の呼び出しのためにprev_calculatedの値を返す
   return(rates_total);
  }
//+------------------------------------------------------------------+
各ティックで履歴全体をコピーする必要があることがわかりますか?
 
Tango_X:

私の理解は正しいですか?

それは各ティックで履歴全体をコピーする必要があることがわかりましたか?

1.新しいバーの 開始時にそれを行うことができます。

2.なぜすべての指標の値を毎回取得する必要があり、同時にインデックスの方向の世話をするのですか? 全く何のタスクですか?

 

単純なインジケーターを、後でチャートで使うか、iCustomで使うのであれば、なぜクラスにラッピングするのでしょうか?

Второе решение лучше, потому что является объектно-ориентированным

OOPのためのOOPだ。

 
Rashid Umarov:

1.新しいバーを 開くことは可能です。

2.なぜ毎回すべてのインジケータの値を取得する必要があり、同時にインデックスの方向を気にする必要があるのでしょうか? まったく何のタスクなのでしょうか?


ループ条件によって問題は解決しました!