mt4 (MetaTrader4)使い倒シストレ

メタトレーダー、自作インジケータ、自作EAで完全自動売買。使えるものは何でも使え。
インジケーター、EA(自動売買システム)製作のご依頼はこちらへ
Googolyen FX Factory
スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


にほんブログ村 為替ブログ FX システムトレード派へ
--/--/--(--) --:--:-- | スポンサー広告 | Trackback(-) | Comment(-)
参照渡しは、とても便利かも!その2
さて、前回に続いて
今回は、『参照渡しの便利な使い方』をご紹介します。

「参照渡しを使えば、関数の引数の値をその関数内で変更した場合
変数の値を変更することがでる
」んでしたね。

便利な使い方として

1.複数の値を返すような関数を作ることができる
2.配列を返り値にするような関数を作ることができる


でしょうか。

1.複数の値を返すような関数を作ることができる
関数を実行した結果を、呼び出し元に返すことを「値を返す」といいますが
この時返される値のことを「返り値」と言います。
MQL4の仕様上、返り値は「0個」、もしくは「1個」と決まっています。

例えば以下のコードを見てください。
これは期間20、偏差3、2、1のそれぞれのボリンジャーバンドの幅を
表示するプログラムです。


/**
* 3つの値を画面に表示する
*/
void Display(int value1, int value2, int value3)
{
Comment(DoubleToStr(value1, 0), "\n", DoubleToStr(value2, 0), "\n", DoubleToStr(value3, 0));

return ;
}

/**
* 現在のBBand(20, 3)の幅をポイント数で返す。
*/
int BBandsDev3Points()
{
double bb_upper, bb_lower;
int points;

bb_upper = iBands(Symbol(), Period(), 20, 3, 0, PRICE_CLOSE, MODE_UPPER, 0);
bb_lower = iBands(Symbol(), Period(), 20, 3, 0, PRICE_CLOSE, MODE_LOWER, 0);

points = NormalizeDouble((bb_upper-bb_lower)/Point, 0);

return (points);
}

/**
* 現在のBBand(20, 2)の幅をポイント数で返す。
*/
int BBandsDev2Points()
{
double bb_upper, bb_lower;
int points;

bb_upper = iBands(Symbol(), Period(), 20, 2, 0, PRICE_CLOSE, MODE_UPPER, 0);
bb_lower = iBands(Symbol(), Period(), 20, 2, 0, PRICE_CLOSE, MODE_LOWER, 0);

points = NormalizeDouble((bb_upper-bb_lower)/Point, 0);

return (points);
}

/**
* 現在のBBand(20, 1)の幅をポイント数で返す。
*/
int BBandsDev1Points()
{
double bb_upper, bb_lower;
int points;

bb_upper = iBands(Symbol(), Period(), 20, 1, 0, PRICE_CLOSE, MODE_UPPER, 0);
bb_lower = iBands(Symbol(), Period(), 20, 1, 0, PRICE_CLOSE, MODE_LOWER, 0);

points = NormalizeDouble((bb_upper-bb_lower)/Point, 0);

return (points);
}

//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
int dev3points, dev2points, dev1points;
dev3points = BBandsDev3Points();
dev2points = BBandsDev2Points();
dev1points = BBandsDev1Points();

Display(dev3points, dev2points, dev1points);

return (0);
}


各関数の返り値の個数は
関数名返り値の個数
Display0
BBandsDev3Points1
BBandsDev2Points1
BBandsDev1Points1


です。
しかし「BBandsDev3Points、BBandsDev2Points、BBandsDev1Points」の3つの関数は
機能としてはかなり似ているので、できれば一つにまとめたいものです。

偏差3、2、1のボリンジャーバンドの幅を返すような関数を作れば
この願望を満たすことができます。

しかし、返り値は2つ以上返すことができない。

ん~~~困った困った。


そこで『参照渡し』という機能の登場です。
『参照渡し』をした場合、引数の値を変更すれば、変数の値も変更されるのでしたね。

上記のコードを『参照渡し』を用いて書き直したものが以下になります。

/**
* 3つの値を画面に表示する
*/
void Display(int value1, int value2, int value3)
{
Comment(DoubleToStr(value1, 0), "\n", DoubleToStr(value2, 0), "\n", DoubleToStr(value3, 0));

return ;
}

/**
* 今のBBand(20, 3)、BBand(20, 2)、BBand(20, 1)の幅のポイント数を計算する
*/
void BBandsDev321Points(int &dev3, int &dev2, int &dev1)
{
double bb_upper, bb_lower;

// Deviation 3
bb_upper = iBands(Symbol(), Period(), 20, 3, 0, PRICE_CLOSE, MODE_UPPER, 0);
bb_lower = iBands(Symbol(), Period(), 20, 3, 0, PRICE_CLOSE, MODE_LOWER, 0);
dev3 = NormalizeDouble((bb_upper-bb_lower)/Point, 0);

// Deviation 2
bb_upper = iBands(Symbol(), Period(), 20, 2, 0, PRICE_CLOSE, MODE_UPPER, 0);
bb_lower = iBands(Symbol(), Period(), 20, 2, 0, PRICE_CLOSE, MODE_LOWER, 0);
dev2 = NormalizeDouble((bb_upper-bb_lower)/Point, 0);

// Deviation 1
bb_upper = iBands(Symbol(), Period(), 20, 1, 0, PRICE_CLOSE, MODE_UPPER, 0);
bb_lower = iBands(Symbol(), Period(), 20, 1, 0, PRICE_CLOSE, MODE_LOWER, 0);
dev1 = NormalizeDouble((bb_upper-bb_lower)/Point, 0);

return ;
}


//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
int dev3points, dev2points, dev1points;
string disp_str;
BBandsDev321Points(dev3points, dev2points, dev1points);

Display(dev3points, dev2points, dev1points);

return (0);
}

Display関数は全く変更していません。

「BBandsDev3Points、BBandsDev2Points、BBandsDev1Points」の機能を一つにまとめた関数が
BBandsDev321Points関数です(参照渡しをするために、引数の名前の前に「&」が付いています)。

start関数内で、偏差3、2、1のボリンジャーバンドの幅を代入する為の変数
「dev3points, dev2points, dev1points」を用意し、

BBandsDev321Points(dev3points, dev2points, dev1points);

のようにBBandsDev321Points関数を呼び出します。
BBandsDev321Points関数の処理が終わる頃には、
「dev3points, dev2points, dev1points」に適切な値が代入されています。


これで
1.複数の値を返すような関数を作ることができる

というイメージが湧いたでしょうか?


2.配列を返り値にするような関数を作ることができる

これに関しては、例えば

"This is a pen."
という文字列を半角スペースで分け、それぞれの結果を文字列配列に格納するStringSplit関数を作る

ことができます。
StringSplit関数の使い方のイメージとしては

string str;
string splited[20];

str = "This is a pen."

StringSplit(splited, str, " ");

//結果
//splited[0] : "This"
//splited[1] : "is"
//splited[2] : "a"
//splited[3] : "pen."


こんな感じでしょうか。

是非ご自身で実装してみてください。


2回に渡って『参照渡し』を説明しましたが、
イメージはできたでしょうか?

にほんブログ村 為替ブログ FX システムトレード派へ
Comment
≪この記事へのコメント≫
コメントを投稿する
URL:
Comment:
Pass:
Secret: 管理者にだけ表示を許可する
 
Trackback
この記事のトラックバックURL
≪この記事へのトラックバック≫
Designed by aykm.
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。