pekonoriブログ関連

Expert Advisor Programming for MetaTrader5【日本語訳 第五章】関数

  1. HOME >
  2. pekonoriブログ関連 >

Expert Advisor Programming for MetaTrader5【日本語訳 第五章】関数

関数 P49

関数 P49

関数は、注文の発注やポジションのストップロスの調整など、特定のタスクを実行するコードのブロックです。この本では、多くの取引関連のアクティビティを実行する独自の関数を作成します。さらに、MQL5には注文情報の取得から複雑な数学演算の実行まで、すべてを行う多数の組み込み関数があります。

関数は、柔軟で再利用できるように設計されています。注文など、特定のアクションを実行する必要があるときはいつでも、関数を呼び出してそのアクションを実行します。関数には、タスクを実行するために必要なすべてのコードとロジックが含まれています。必要な場合は、必要なパラメータを関数に渡し、関数によって返された値を処理するだけです。

例えば、注文を行うときは、注文発行関数を呼び出します。指定されたシンボルに、指定された価格、指定された注文量で注文するように指示するパラメータを関数に渡します。関数の実行が完了すると、注文確認などの値が返されます。

関数宣言は、戻り値の型、識別子、およびオプションのパラメータリストで構成されます。関数宣言の例を次に示します。

                  double BuyStopLoss(string pSymbol, int pStopPoints, double pOpenPrice)

{

    //関数本体

}

関数の名前はBuyStopLoss()です。この関数は買い注文のストップロスを計算します。戻り値の型はdoubleです。つまり、この関数はdouble型の値を計算し、その値をプログラムに返します。

この関数には、pSymbol、pStopPointsおよびpOpenPriceの3つのパラメータがあります。この本では、すべての関数パラメータ識別子の前に小文字の「p」を付けます。パラメータはコンマで区切られます。各パラメータには、型と識別子が必要です。パラメータにはデフォルト値を設定することもできます。デフォルト値については、後程詳しく説明します。

3つのパラメータはすべて必須です。つまり、関数が呼び出されるときに関数を渡す必要があります。最初のパラメータpSymbolは、楽器の記号を表す文字列値です。2番目のパラメータpStopPointsはポイント単位のストップロス値を表す整数値です。3番目のパラメータpOpenPriceは注文の始値を表すdouble値です。

これが関数全体です。この関数は、プログラムのグローバルスコープのどこかに配置されます。つまり、別の関数内に配置することはできません。インクルードファイルに配置することも、プログラムに含まれる別のプログラム内に配置することもできます。

                  double BuyStopLoss(string pSymbol, int pStopPoints, double pOpenPrice)

{

    double stopLoss = pOpenPrice – (pStopPoints * _Point);

    stopLoss = NormalizeDouble(stopLoss, _Digits);

    return(stopLoss);

}

この関数は、事前定義された変数_Point(通常は0.00001または0.001)で表されるシンボルのポイント値をpStopPointsに乗算しその値をpOpenPriceから減算することによってストップロスを計算します。結果は変数stopLossに割り当てられます。stopLossの値はNormalizeDouble()関数を使用して価格の桁数に正規化され、return演算子は正規化されたstopLossの値をプログラムに返します。

プログラムでこの関数を呼び出す方法の例を次に示します。

                  //入力変数

                  input int StopLoss = 500;

                  //OnTick()イベントハンドラ

                  double orderPrice = SymbolInDouble(_Symbol, SYMBOL_ASK);

                  double useStopLoss = BuyStopLoss(_symbol, StopLoss, orderPrice);

入力変数StopLossは、ポイント単位のストップロス値を含む入力変数です。これはプログラムの最初にあり、ユーザーが設定します。double変数orderPriceは注文の始値(この場合は現在の売値)を含むローカル変数です。

BuyStopLoss()関数を呼び出し、現在のチャートシンボル(_Symbol)、StopLoss変数、およびorderPrice変数を関数パラメータとして渡します。BuyStopLoss()関数はストップロスを計算し、戻り値をuseStopLoss変数に格納します。この変数は、現在開いているポジションを変更し、ストップロスを追加するために使用されます。

ディフォルト値 P50

関数が最初に宣言されたときに、関数パラメータにデフォルト値を割り当てることができます。パラメータにデフォルト値がある場合は、パラメータの最後に配置する必要があります。BuyStopLoss()関数のパラメータの1つにデフォルト値を追加しましょう。

                  double BuyStopLoss(string pSymbol, int pStopPoints, double pOpenPrice = 0)

{

double stopLoss = pOpenPrice – (pStopPoints * _Point);

stopLoss = NormalizeDouble(stopLoss, _Digits);

return(stopLoss);

}

pOpenPriceパラメータには、デフォルト値のゼロが割り当てられています。デフォルト値を持つすべてのパラメータはパラメータリストの最後にある必要があります。関数を呼び出すときにデフォルト値を使用している場合は、パラメータを省略できます。

                  BuyStopLoss(_Symbol, StopLoss);

上記の例では、デフォルト値の0がpOpenPriceパラメータに使用されます。

デフォルト値を持つ複数のパラメータを持つことができますがそれらはすべてパラメータリストの最後にある必要があります。関数にデフォルト値を持つ複数のパラメータがあり、デフォルト値を持つパラメータに値を渡す場合、その前のすべてのパラメータにも渡される必要があります。次に例を示します。

int MyFunction(string pSymbol, int pDefault1 = 0, int pDefault2 = 0)

{

    //関数本体

}

MyFunction()には、デフォルト値を持つ2つのパラメータ(pDefault1pとDefault2)があります。デフォルト以外の値をpDefault2に渡す必要があるが、pDefault1には渡さない場合は、pDefault1にも値を渡す必要があります。

int nonDefault = 5;

MyFunction(_Symbol, 0, nonDefault);

パラメータpDefault1にはデフォルト値の0が渡され、pDefault2には値5が渡されます。残りのすべてのパラメータがデフォルト値を使用していない限り、関数を呼び出すときにパラメータをスキップすることはできません。もちろん、pDefault1とpDefault2、またはpDefault2に値を渡す必要が無い場合は、関数呼び出しから省略できます。

                  int point = 5;

                  MyFunction(_Symbol, point);

この例では、pDefault1に値5が渡されますが、pDefault2はデフォルト値の0を使用します。pDefault1にもデフォルト値を使用する場合、指定する必要があるパラメータはpSymbolだけです。

要約すると、デフォルト値を持つすべての関数パラメータは、パラメータリストの最後にある必要があります。関数の呼び出し時にパラメータをスキップすることはできないため、関数の呼び出し時に既定値を持つパラメータに別の値が渡される場合、その前のパラメータにも値が渡される必要があります。

return演算子 P52

値を返す関数には、少なくとも1つのreturn演算子が必要です。return演算子には、呼び出しプログラムに返す変数または式が含まれます。式の型は、関数の戻り値の型と一致する必要があります。通常、return演算子は関数の最後の行ですが、要件によっては、関数に複数のreturn演算子を含めることもできます。

関数の戻り値の型は、構造体や列挙型を含む任意の型にすることができます。配列から要素を返すことはできますが、関数から配列を返すことはできません。配列を返す関数が必要な場合は、参照によって配列を関数に渡すことができます。参照渡しについては後程説明します。

これがBuyStopLoss()関数です。この関数はdouble型の値を返します。関数に対してローカルなdouble変数stoplossの値はreturn演算子を使用して呼び出しプログラムに返されます。

                  double BuyStopLoss(string pSymbol, int pStopPoints, double pOpenPrice = 0)

{

    double stopLoss = pOpenPrice – (pStopPoints * _Point);

    stopLoss = NormalizeDouble(stopLoss, _Digits);

    return(stopLoss);

}

void型 P52

すべての関数が値を返す必要がありません。値を返さない関数を指定するvoidという特殊な型があります。Void関数はパラメータを受け入れることができますが、return演算子を持つ必要はありません。パラメータのないvoid型の関数の例を次に示します。

                  void TradeEmail()

{

    string subject = “Trade placed”;

    string text = “A trade was placed on ” + _Symbol;

    SendMail(subject, text);

}

この関数は【ツール】メニュー>【設定】>【電子メール】タブで指定されたメール設定を使用して電子メールを送信します。関数はvoid型であるためreturn演算子が無いことに注意してください。

パラメータの参照渡し P53

通常、関数にパラメータを渡す場合、パラメータは値によって渡されます。これは、パラメータの値が関数に渡され、元の変数が変更されないことを意味します。

パラメータを参照渡しすることもできます。関数内の変数に加えられた変数は、元の変数に反映されます。これは、配列または構造体を変更する関数が必要な場合に役立ちます。MQL5関数への参照により、配列と構造体を頻繁に渡します。

SymbolInfoTick()関数を使用して構造体を参照渡しする例を次に示します。以下は、MQL5リファレンスからのSymbolInfoTick()関数の定義です。

                  bool SymbolInfoTick(

String     symbol,    // シンボル名

Mqltick&  tick        //構造体への参照

);

tickパラメータの前のアンパサンド(&)は、このパラメータが参照によって渡されることを意味します。コードでSymbolInfoTick()関数を使用する方法は次の通りです。

                  MqlTick myTick;

                  SymbolInfoTick(_Symbol, myTick);

                  Print(myTick.bid);

最初の行は、組み込みのMqlTick構造体を型として使用して、myTickという名前のオブジェクトを宣言します。MqlTick構造体は、サーバーからの現在の価格情報を格納します。SymbolInfoTick()関数は、MqlTickオブジェクトに指定された銘柄の現在の価格情報を入力します。SymbolInfoTick()関数呼び出しの2番目のパラメータであるmyTickは参照によって渡されます。関数によってmyTick構造が変更され、取引サーバーからの現在の価格情報が入力されます。Print()関数は、myTickオブジェクトの入札変数を参照して、現在の入札価格をログに出力します。

配列を使用した参照渡しの別の例を次に示します。この例では、動的配列を参照によって関数に渡します。識別子の前にアンパサンド(&)を付けて、パラメータが参照渡しであることを指定します。

                  void FillArray(int &array[])

{

ArrayResize(array, 3);

    array[0] = 1;

    array[1] = 2;

    array[2] = 3;

}

FillArray()関数の唯一のパラメータである &array[]は、参照によって渡されます。&array[]パラメータに渡される動的配列は関数によって変更されます。プログラムからこの関数を呼び出す方法は次の通りです。

                                   int fill[];

                                   FillArray(fill);

                                   Print(fill[0]);      //出力 : 1

配列FillArray()関数内で変更された値が含まれるようになりました。

関数のオーバーロード P54

基本的に同じタスクを実行する複数の関数を作成する必要がある場合があります。これらの関数はそれぞれ異なる入力パラメータを持ちますが、最終的な結果は同じです。以前のMQL4では、これらの関数に異なる識別子を与える必要がありました。MQL5は関数のオーバーロードを導入し、同じ名前の複数の関数を持つことができます。

同じ名前の各関数には、数または型のいずれかで異なるパラメータが必要です。この本の後半で作成する2つのトレーリングストップ関数を使用して説明しましょう。どちらの関数も同じ名前で、基本的に同じことを行います。違いは、最初の関数にはpTrailPointsという名前の整数パラメータがあり、2番目の関数にはpTrailPriceという名前のdoubleパラメータがあることです。

                  bool TrailingStop(string, pSymbol, int pTrailPoins, int pMinProfit = 0, int pStep = 10 );

                  bool TrailingStop(string, pSymbol, double pTrailPrice, int pMinProfit = 0, int pStep = 10 );

最初の関数pTrailPointsのintパラメータは、ポイント単位のトレーリングストップ値を受け入れます。これは、現在のbidまたはask価格に対するトレーリングストップ価格を計算するために使用されます。2番目の関数pTrailPriceのdoubleパラメータはトレーリングストップ価格として使用される価格を受け入れます。

異なるパラメータを持つ2つの同じ名前の関数を使用することで、取引システムに応じてトレーリングストップを管理する方法についてある程度の柔軟性が得られます。両方の関数が同じ名前を共有しているため、プログラマは2つ(またはそれ以上)の異なる関数名を覚えておく必要はありません。結局、これは単にプログラマの生活を楽にするだけです。

コンパイラは、一意のパラメータシグネチャに基づいて、使用する関数を認識します。最初の関数には文字列パラメータがあり、その後に3つの整数パラメータが続きます。2番目には、文字列パラメータがあり、その後にdoubleパラメータと2つの整数パラメータが続きます。関数の最初のバリアントを呼び出す方法は次の通りです。

                  //入力変数

                  intput int TrailingPoints = 500;

                  //OnTick()イベントハンドラ

                  TrailingStop(_Symbol, TrailingPoints);

TrailingPointsという名前のint入力変数を使用すると、ユーザーはトレーリングストップをポイント単位で設定できます。この値は、TrailingStop()関数呼び出しの2番目のパラメータとして使用されます。TrailingPoints変数はint型であるため、コンパイラは関数の最初のバリアントを使用することを認識しています。pMinProfitおよびpStepパラメータのデフォルト値を使用しているため、関数呼び出しからそれらを省略しました。

関数の2番目のバリアントを呼び出す方法は次の通りです。

                  //入力変数

                  input int TrailingPoints = 500;

                  //OnTick()イベントハンドラ

                  double TrilingPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK) – (TrailingPoints * _Point);

                  TrailingSpot(_Symbol, trailingPrice);

ローカルdouble変数TrailingPriceにはトレーリングストップとして使用する価格が含まれます。TrailingStop()関数呼び出しの2番目のパラメータはdouble型であるため、コンパイラは関数の2番目のバリアントを使用することを認識しています。

≪≪【日本語訳 第四章】条件&ループ演算子

【日本語訳 第六章】オブジェクト指向プログラミング≫≫

-pekonoriブログ関連