ArrayCopy

配列を別の配列に複製します。

int  ArrayCopy(
  void&        dst_array[],        // 複製先の配列
  const void&  src_array[],        // ソース配列
  int          dst_start=0,        // 複製先の配列の開始インデックス
  int          src_start=0,        // ソース配列の開始インデックス
  int          count=WHOLE_ARRAY   // 要素の数
  );

パラメータ

dst_array[]

[out]  複製先の配列。

src_array[]

[in]  ソース配列。

dst_start=0

[in] 複製先の配列の開始インデックス。デフォルトでは、開始インデックスは 0。

src_start=0

[in]  ソース配列の開始インデックス。デフォルトでは、開始インデックスは 0。

count=WHOLE_ARRAY

[in]  複製する必要がある要素数。デフォルトでは配列全体(count=WHOLE_ARRAY)。

戻り値

複製された要素の数

注意事項

count<0 や count>src_size-src_start の場合、配列の全ての残り部分が複製されます。配列は、左から右に複製されます。シリーズ配列の場合、開始位置は左から右のコピーのために調整されて、正確に定義されます。

配列のタイプが異なる場合は、複製中に、複製元配列の各要素の複製先の要素タイプへの変換が試みられます。文字列配列は文字列配列のみに複製することが出来ます。初期化を必要とするオブジェクトを含むクラスと構造の配列は複製されません。構造体の配列は同じ型の配列のみに複製することが出来ます。

時系列をインデックスとする動的配列では(もしデータサイズのほうが大きければ)複製先の配列のサイズが自動的に複製されたデータサイズに合わせて増加されます。複製先の配列のサイズは自動的に減少しません。

例:

#property description "The indicator highlights the candlesticks that are local"
#property description "highs and lows. Interval length for finding"
#property description "extreme values should be found using an input parameters."
//--- 指標の設定
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots   1
//---- プロット
#property indicator_label1 "Extremums"
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1 clrLightSteelBlue,clrRed,clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1  1
//--- 定義済み定数
#define INDICATOR_EMPTY_VALUE 0.0
//--- 入力パラメータ
input int InpNum=4; // 区間の半分の長さ
//--- 指標バッファ
double ExtOpen[];
double ExtHigh[];
double ExtLow[];
double ExtClose[];
double ExtColor[];
//--- グローバル変数
int    ExtStart=0; // 極値ではない最初のローソク足のインデックス
int    ExtCount=0; // 区間内の非極値の数
//+------------------------------------------------------------------+
//| 非極値のローソク足に値を入れる                                           |
//+------------------------------------------------------------------+
void FillCandles(const double &open[],const double &high[],
                const double &low[],const double &close[])
 {
//--- ローソク足に値を入れる  
  ArrayCopy(ExtOpen,open,ExtStart,ExtStart,ExtCount);
  ArrayCopy(ExtHigh,high,ExtStart,ExtStart,ExtCount);
  ArrayCopy(ExtLow,low,ExtStart,ExtStart,ExtCount);
  ArrayCopy(ExtClose,close,ExtStart,ExtStart,ExtCount);
 }
//+------------------------------------------------------------------+
//| カスタム指標を初期化する関数                                            |
//+------------------------------------------------------------------+
int OnInit()
 {
//--- 指標バッファマッピング
  SetIndexBuffer(0,ExtOpen);
  SetIndexBuffer(1,ExtHigh);
  SetIndexBuffer(2,ExtLow);
  SetIndexBuffer(3,ExtClose);
  SetIndexBuffer(4,ExtColor,INDICATOR_COLOR_INDEX);
//--- 値を指定するが表示しない
  PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE);
//--- データウィンドウに表示するために指標バッファの名称を指定する
  PlotIndexSetString(0,PLOT_LABEL,"Open;High;Low;Close");
//---
  return(INIT_SUCCEEDED);
 }
//+------------------------------------------------------------------+
//| カスタム指標の反復関数                                                |
//+------------------------------------------------------------------+
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[])
 {
//--- 時系列にストレート索引付けを設定する
  ArraySetAsSeries(open,false);
  ArraySetAsSeries(high,false);
  ArraySetAsSeries(low,false);
  ArraySetAsSeries(close,false);
//--- バー計算開始の変数
  int start=prev_calculated;
//--- 最初の InpNum*2 のバーは計算されない
  if(start==0)
    {
     start+=InpNum*2;
     ExtStart=0;
     ExtCount=0;
    }
//--- バーがちょうど形成した場合、次の潜在的な極値をチェックする
  if(rates_total-start==1)
     start--;
//--- 極値チェックが行われるバーのインデックス
  int ext;
//--- 指標算出ループ
  for(int i=start;i<rates_total-1;i++)
    {
    //--- 初めは i 番目のバーに指標は描画されない
     ExtOpen[i]=0;
     ExtHigh[i]=0;
     ExtLow[i]=0;
     ExtClose[i]=0;
    //--- チェックする極値インデックス
     ext=i-InpNum;
    //--- 極大をチェック
    if(IsMax(high,ext))
       {
        //--- 極値であるローソク足を強調表示する
        ExtOpen[ext]=open[ext];
        ExtHigh[ext]=high[ext];
        ExtLow[ext]=low[ext];
        ExtClose[ext]=close[ext];
        ExtColor[ext]=1;
        //---極値まで他のローソク足を中間色で強調表示する
        FillCandles(open,high,low,close);
        //--- 変数の色を変更
        ExtStart=ext+1;
        ExtCount=0;
        //--- 次の反復に渡す
        continue;
       }
    //--- 極小をチェック
    if(IsMin(low,ext))
       {
        //--- 極値であるローソク足を強調表示する
        ExtOpen[ext]=open[ext];
        ExtHigh[ext]=high[ext];
        ExtLow[ext]=low[ext];
        ExtClose[ext]=close[ext];
        ExtColor[ext]=2;
        //---極値まで他のローソク足を中間色で強調表示する
        FillCandles(open,high,low,close);
        //--- 変数の値を変更
        ExtStart=ext+1;
        ExtCount=0;
        //--- 次の反復に渡す
        continue;
       }
    //--- 区間内の非極値の数を増やす
     ExtCount++;
    }
//--- 次の呼び出しのために prev_calculated の値を返す
  return(rates_total);
 }
//+------------------------------------------------------------------+
//| 現在の配列要素が極大かどうかを確認する                                    |
//+------------------------------------------------------------------+
bool IsMax(const double &price[],const int ind)
 {
//--- 区間開始の変数
  int i=ind-InpNum;
//--- 区間終了期間
  int finish=ind+InpNum+1;
//--- 区間の前半をチェックする
  for(;i<ind;i++)
    {
    if(price[ind]<=price[i])
        return(false);
    }
//--- 区間の後半をチェックする
  for(i=ind+1;i<finish;i++)
    {
    if(price[ind]<=price[i])
        return(false);
    }
//--- 極値を発見
  return(true);
 }
//+------------------------------------------------------------------+
//| 現在の配列要素が極小かどうかを確認する                                    |
//+------------------------------------------------------------------+
bool IsMin(const double &price[],const int ind)
 {
//--- 区間開始の変数
  int i=ind-InpNum;
//--- 区間終了の変数
  int finish=ind+InpNum+1;
//--- 区間の前半をチェックする
  for(;i<ind;i++)
    {
    if(price[ind]>=price[i])
        return(false);
    }
//--- 区間の後半をチェックする
  for(i=ind+1;i<finish;i++)
    {
    if(price[ind]>=price[i])
        return(false);
    }
//--- 極値を発見
  return(true);
 }