-<PR>-
当サイトでは以下のFX業者をおススメいたします。
—————————————————————
前回は、新たにOriginalCPositionsというクラスを宣言し、アクセスレベルがprotected,publicそれぞれのメンバ変数・メンバ関数も併せて宣言しました。そしてアクセスレベル₌protectedカテゴリーの関数である、GetPosInfo関数の処理実装記述について解説しました。
GetPosInfo関数は、必要なポジション情報を、これから作っていくpublicカテゴリーの関数に受け渡す処理を担う内部関数となります。
GetPosInfo関数の処理記述内には、ChangeArraySize関数という、アクセスレベル₌protectedの関数が使われていますが、ChangeArraySize関数は前回の時点ではまだ宣言しただけで、処理実装記述は完了していません。
今回はまずChangeArraySize関数の処理実装記述から行っていきたいと思います。
ChangeArraySize関数について
ChangeArraySize関数は、ポジション情報が格納された配列の、配列サイズ変更を担う内部関数となります。
ChangeArraySize関数の戻り値と引数構成
ChangeArraySize関数の戻り値と引数構成は、以下の通りです。
int OriginalCPositions::ChangeArraySize(ulong &parArray[])
仮引数のparArray[]にはポジション番号情報を格納する配列が記述される想定です。
戻り値がint型なのは、配列「parArray」のインデックスを返す想定だからです。
ChangeArraySize関数の処理実装記述
ChangeArraySize関数の処理実装記述は以下の通りです。
//配列サイズを変更し、配列インデックスを返す関数
int OriginalCPositions::ChangeArraySize(ulong &parArray[])
{
int arrayIndex = 0;//配列のインデックスを格納する変数
//配列サイズが1より大きいとき
if(ArraySize(parArray) > 1)
{//配列要素に+1したサイズにリサイズして、その値を変数「newSize」に格納
int newSize = ArrayResize(parArray, ArraySize(parArray) + 1);
//変数「newSize」の値に-1することによって、インデックス値に変換。その値を変数「arrayIndex」に格納
arrayIndex = newSize - 1;
}
//変数「arrayIndex」の値を戻り値として返す
return arrayIndex;
}//int OriginalCPositions::ChangeArraySize(ulong &parArray[])
一つ一つ順を追って見ていきましょう
配列のインデックスを格納する変数「arrayIndex」を宣言
int arrayIndex = 0;//配列のインデックスを格納する変数
まずは、配列のインデックスを格納する変数「arrayIndex」を宣言し、初期値を0とします。
インデックスというのは、配列の「通し番号」ともいうべきもので、常に配列の数よりマイナス1分少なくなっています。1番目の配列のインデックスは0、2番目の配列のインデックスは1・・・という具合です。
最終的に、この変数「arrayIndex」の値をreturn演算子によって戻り値として返すように設計します。
ポジション数が増えたときに、配列サイズを変更する記述
配列のインデックスを格納する変数を宣言した後は、ポジション数が増えたときに、配列サイズを変更する記述を行います。
//配列サイズが1より大きいとき
if(ArraySize(parArray) > 1)
{//配列要素に+1したサイズにリサイズして、その値を変数「newSize」に格納
int newSize = ArrayResize(parArray, ArraySize(parArray) + 1);
//変数「newSize」の値に-1することによって、インデックス値に変換。その値を変数「arrayIndex」に格納
arrayIndex = newSize - 1;
}
//変数「arrayIndex」の値を戻り値として返す
return arrayIndex;
↑という記述は配列「parArray」の配列数が、1より大きい時 という意味ですからEAの注文によって、複数のポジションを持ったことを意味します。
ArraySize関数について
ArraySize関数は引数に指定した配列の要素数を返す関数です。
配列とは言い換えれば、「変数という箱が連なったもの」です。ArraySize関数によって、その配列が「何個の箱を今持っているのか」を返してくれるという訳です。
if文の条件がtrueの時、すなわち配列サイズが1より大きいときはArrayResize関数によって、配列「parArray」の配列サイズを1増やします。
今までの配列サイズが1であったのであれば2に、配列サイズが2であったのであれば3に・・・と言った具合です。
ArrayResize関数によってリサイズした配列サイズを変数「newSize」に格納します。
先ほども書いたように、配列のインデックスは配列サイズ-1の関係にありますから、
変数「newSize」-1という計算をする事によって、インデックスが求まります。
結果を変数「arrayIndex」に格納し、return演算子によって戻り値として返せばこの関数の処理実装記述は終了です。
ChangeArraySize関数が完成することによって、前回82回で作ったGetPosInfo関数も晴れて完成しました。
アクセスレベル=protectedの関数2つが完成したので、後はアクセスレベル=publicの6つの関数を完成させれば、ポジション数やポジション番号の情報がメインプログラムから取得できる準備が整います。
GetBuyPosCount関数について
GetBuyPosCount関数は、買いポジションの数を取得して返す関数です。
GetBuyPosCount関数の引数構成と戻り値
GetBuyPosCount関数の引数構成と戻り値は以下の通りです
//買いポジションの数を取得する関数
int OriginalCPositions::GetBuyPosCount(ulong parMagicNum)
買いポジションの数を戻り値として返すので必然的にデータ型はint型になります。
GetBuyPosCount関数の処理実装記述
GetBuyPosCount関数の処理実装記述は以下の通りです。極めてシンプルです。
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
//protected変数の「BuyPosCount」を呼び出し、戻り値として返す
return BuyPosCount;
}
{}内の冒頭で、GetPosInfo関数を呼び出します。
GetPosInfo関数はvoid型の関数なので、戻り値を受け取る変数を用意する必要はありません。
関数を呼び出した時点で、ポジション数を格納するメンバ変数や、ポジション番号を格納するメンバ配列に値の振り分けを行ってくれているので、ここでは買いポジションの数を格納している変数の「BuyPosCount」を呼び出し、戻り値として返せばそれで処理実装記述は終了です。
GetSellPosCount関数について
GetSellPosCount関数は、売りポジションの数を取得して返す関数です。
GetSellPosCount関数の引数構成と戻り値
GetSellPosCount関数の引数構成と戻り値は以下の通りです
//買いポジションの数を取得する関数
int OriginalCPositions::GetSellPosCount(ulong parMagicNum)
売りポジションの数を戻り値として返すので、データ型はint型になります。
GetSellPosCount関数の処理実装記述
GetSellPosCount関数の処理実装記述は以下の通りです。
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
//protected変数の「SellPosCount」を呼び出し、戻り値として返す
return SellPosCount;
}
GetBuyPosCount関数と同様に{}内の冒頭で、GetPosInfo関数を呼び出します。
GetPosInfo関数がポジション数を格納するメンバ変数や、ポジション番号を格納するメンバ配列に値の振り分けを行ってくれているので、ここでは売りポジションの数を格納している変数の「SellPosCount」を呼び出し、戻り値として返します。
GetTotalPosCount関数について
GetTotalPosCount関数は、買いと売り、合計のポジション数を取得して返す関数です。
GetTotalPosCount関数の引数構成と戻り値
GetTotalPosCount関数の引数構成と戻り値は以下の通りです
//買いポジションの数を取得する関数
int OriginalCPositions::GetTotalPosCount関数(ulong parMagicNum)
買いと売り、合計のポジション数を戻り値として返すので、データ型はint型になります。
GetTotalPosCount関数の処理実装記述
GetTotalPosCount関数の処理実装記述は以下の通りです。
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
//protected変数の「SellPosCount」を呼び出し、戻り値として返す
return TotalPosCount;
}
やはり同じように{}内の冒頭で、GetPosInfo関数を呼び出します。
しつこいようですが、GetPosInfo関数がポジション数を格納するメンバ変数や、ポジション番号を格納するメンバ配列に値の振り分けを行ってくれています。
今回のGetTotalPosCount関数の場合は、売りと買い合計のポジション数を格納している変数「TotalPosCount」を戻り値として返すだけです。
GetBuyPosNum関数について
GetBuyPosNum関数は、買いポジションのポジション番号情報を取得する関数です。
GetBuyPosNum関数の引数構成と戻り値
GetBuyPosNum関数の引数構成と戻り値は以下の通りです
void OriginalCPositions::GetBuyPosNum(ulong parMagicNum,ulong &parTickets[])
第1引数にはマジックナンバー、第2引数にはメインプログラムでポジション番号を格納する配列が記述される想定です。returnで配列情報を返すことができないので、戻り値はvoid型です。
<復習用リンク>
マジックナンバー、引数、仮引数、配列、ポジション番号、void型、return演算子
GetBuyPosNum関数の処理実装記述
GetBuyPosNum関数の処理実装記述は以下の通りです
void OriginalCPositions::GetBuyPosNum(ulong parMagicNum,ulong &parTickets[])
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
ArrayCopy(parTickets,BuyPosNum);
return;
}
ポジション数を取得する関数と同様に、GetPosInfo関数を呼び出します。GetPosInfo関数の呼び出しにより、ポジション番号が格納されているBuyPosNum[]、SellPosNum[]、PosNum[]等のprotectedセクション配列にもアクセスできますから、買いポジションのポジション番号であればBuyPosNum[]配列の情報をメインプログラムに返す記述を行います。
繰り返しになりますが、return演算子で配列情報を返すことは出来ません。
ここではArrayCopy関数を使って実現します。
ArrayCopy関数について
ArrayCopy関数は第2引数に指定した配列を第1引数の配列に複製する関数です。
複製したい情報は買いポジションのポジション番号が格納されているBuyPosNum[]配列ですから、これを第2引数に記述します。第1引数のparTickets[]配列にBuyPosNum[]配列の情報が格納されます。
従って、第1引数のparTickets[]配列部分には、メインプログラムにてBuyPosNum[]配列に格納される情報を受け取る配列名が記述される想定です。
ArrayCopy関数によって、ポジション番号情報が第1引数の配列にコピーされたので、GetBuyPosNum関数の処理はここで終了です。
GetSellPosNum関数について
GetSellPosNum関数は、売りポジションのポジション番号情報を取得する関数です。
GetSellPosNum関数の引数構成と戻り値
GetSellPosNum関数の引数構成と戻り値は以下の通りです
void OriginalCPositions::GetSellPosNum(ulong parMagicNum,ulong &parTickets[])
第1引数にはマジックナンバー、第2引数にはメインプログラムでポジション番号を格納する配列が記述される想定です。returnで配列情報を返すことができないので、戻り値はvoid型です。
引数構成と戻り値に関しては、GetBuyPosNum関数と全く同じです。
<復習用リンク>
マジックナンバー、引数、仮引数、配列、ポジション番号、void型、return演算子
GetSellPosNum関数の処理実装記述
GetSellPosNum関数の処理実装記述は以下の通りです
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
ArrayCopy(parTickets,SellPosNum);
return;
}
GetBuyPosNum関数と同様に、GetPosInfo関数を呼び出します。GetPosInfo関数の呼び出しにより、protectedセクション配列であるSellPosNum[]にもアクセスできるようになりますから、後はArrayCopy関数を使って、SellPosNum[]配列の情報を第1引数に記述した配列にコピーします。これでGetSellPosNum関数の処理記述は終了です。
GetTotalPosNum関数について
GetTotalPosNum関数は、買いと売り両方のポジションの、ポジション番号情報を取得する関数です。
GetTotalPosNum関数の引数構成と戻り値
GetTotalPosNum関数の引数構成と戻り値は以下の通りです
void OriginalCPositions::GetTotalPosNum(ulong parMagicNum,ulong &parTickets[])
第1引数にはマジックナンバー、第2引数にはメインプログラムでポジション番号を格納する配列が記述される想定です。returnで配列情報を返すことができないので、戻り値はvoid型です。
引数構成と戻り値に関しては、GetBuyPosNum関数、GetSellPosNum関数と全く同じです。
GetTotalPosNum関数の処理実装記述
GetTotalPosNum関数の処理実装記述は以下の通りです
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
ArrayCopy(parTickets,PosNum);
return;
}
GetTotalPosNum関数も、冒頭でGetPosInfo関数を呼び出します。
これで、売りと買いのポジションを合計したポジション番号を格納しているPosNum[]配列にアクセスできるようになっていますから、あとは後はArrayCopy関数を使って、PosNum[]配列の情報を第1引数に記述した配列にコピーします。GetTotalPosNum関数の処理記述は以上になります。
「OriginalCPositions」クラスの全体記述
今回の記事では、以下の関数の処理実装記述を解説しました
- ChangeArraySize関数(ポジション情報が格納された配列の、配列サイズ変更を担うアクセスレベル=protectedの内部関数)
- GetBuyPosCount関数(買いポジションの数を取得して返すアクセスレベル=publicの関数)
- GetSellPosCount関数(売りポジションの数を取得して返すアクセスレベル=publicの関数)
- GetTotalPosCount関数(買いと売り、合計のポジション数を取得して返すアクセスレベル=publicの関数)
- GetBuyPosNum関数(買いポジションのポジション番号情報を取得するアクセスレベル=publicの関数)
- GetSellPosNum関数(売りポジションのポジション番号情報を取得するアクセスレベル=publicの関数)
- GetTotalPosNum関数(買いと売り両方のポジションの、ポジション番号情報を取得するアクセスレベル=publicの関数)
「OriginalCPositions」クラスの全体記述は以下の通りです。
//ポジション情報を管理するクラス------------------------------
class OriginalCPositions
{
protected:
ulong BuyPosNum[];
ulong SellPosNum[];
ulong PosNum[];
int BuyPosCount;
int SellPosCount;
int TotalPosCount;
void GetPosInfo(ulong parMagicNum = 0);
int ChangeArraySize(ulong &parArray[]);
public:
int GetBuyPosCount(ulong parMagicNum);
int GetSellPosCount(ulong parMagicNum);
int GetTotalPosCount(ulong parMagicNum);
void GetBuyPosNum(ulong parMagicNum,ulong &parTickets[]);
void GetSellPosNum(ulong parMagicNum,ulong &parTickets[]);
void GetTotalPosNum(ulong parMagicNum,ulong &parTickets[]);
};
// ポジション情報を取得・振り分けする関数
void OriginalCPositions::GetPosInfo(ulong parMagicNumber = 0)
{
//ポジション数を格納する変数の初期化
BuyPosCount = 0;
SellPosCount = 0;
TotalPosCount = 0;
//ポジション番号格納配列の初期化とリサイズ
ArrayResize(BuyPosNum, 1);
ArrayInitialize(BuyPosNum, 0);
ArrayResize(SellPosNum, 1);
ArrayInitialize(SellPosNum, 0);
ArrayResize(PosNum, 1);
ArrayInitialize(PosNum, 0);
for(int i = 0; i < PositionsTotal(); i++)//未決済ポジション内を一番古いポジからチェック
{
ulong posNumber = PositionGetTicket(i);//ポジションプール内からインデックス順にポジション番号を取得
PositionSelectByTicket(posNumber);//ポジション選択
if(PositionGetInteger(POSITION_MAGIC) != parMagicNumber && parMagicNumber > 0) continue;
//当該EAからの注文でなければスキップ
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
{ //買いポジションの数を1増加させる
BuyPosCount++;
int arrayIndex = ChangeArraySize(BuyPosNum);//配列をリサイズし、インデックスを戻り値として返す
BuyPosNum[arrayIndex] = PositionGetInteger(POSITION_TICKET);//Buy ポジション番号情報を配列に格納
}
else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
{ ////売りポジションの数を1増加させる
SellPosCount++;
int arrayIndex = ChangeArraySize(SellPosNum);//配列をリサイズし、インデックスを戻り値として返す
SellPosNum[arrayIndex] = PositionGetInteger(POSITION_TICKET);//Sell ポジション番号情報を配列に格納
}
//全体のポジション数を1増加させる
TotalPosCount++;
int arrayIndex = ChangeArraySize(PosNum);//配列をリサイズし、インデックスを戻り値として返す
PosNum[arrayIndex] = PositionGetInteger(POSITION_TICKET);//全てのポジションの ポジション番号情報を配列に格納
}// for(int i = 0; i < PositionsTotal(); i++)の終端
//各種ポジカウント変数とポジション番号格納配列に必要な情報を振り分けて作業を終える
}
//配列サイズを変更し、配列インデックスを返す関数
int OriginalCPositions::ChangeArraySize(ulong &parArray[])
{
int arrayIndex = 0;//配列のインデックスを格納する変数
//配列サイズが1より大きいとき
if(ArraySize(parArray) > 1)
{//配列要素に+1したサイズにリサイズして、その値を変数「newSize」に格納
int newSize = ArrayResize(parArray, ArraySize(parArray) + 1);
//変数「newSize」の値に-1することによって、インデックス値に変換。その値を変数「arrayIndex」に格納
arrayIndex = newSize - 1;
}
//変数「arrayIndex」の値を戻り値として返す
return arrayIndex;
}//int OriginalCPositions::ChangeArraySize(ulong &parArray[])
//買いポジションの数を取得する関数
int OriginalCPositions::GetBuyPosCount(ulong parMagicNum)
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
//protected変数の「BuyPosCount」を呼び出し、戻り値として返す
return BuyPosCount;
}
//売りポジションの数を取得する関数
int OriginalCPositions::GetSellPosCount(ulong parMagicNum)
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
//protected変数の「BuyPosCount」を呼び出し、戻り値として返す
return SellPosCount;
}
//買いと売りの合計ポジションの数を取得する関数
int OriginalCPositions::GetTotalPosCount(ulong parMagicNum)
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
//protected変数の「BuyPosCount」を呼び出し、戻り値として返す
return TotalPosCount;
}
void OriginalCPositions::GetBuyPosNum(ulong parMagicNum,ulong &parTickets[])
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
ArrayCopy(parTickets,BuyPosNum);
return;
}
void OriginalCPositions::GetSellPosNum(ulong parMagicNum,ulong &parTickets[])
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
ArrayCopy(parTickets,SellPosNum);
return;
}
void OriginalCPositions::GetTotalPosNum(ulong parMagicNum,ulong &parTickets[])
{
GetPosInfo(parMagicNum);//各種ポジカウント変数とポジション番号格納配列に、必要な情報を振り分けるprotected関数
ArrayCopy(parTickets,PosNum);
return;
※「OriginalCPositions」クラスもこれまでと同様に、OriginalTrade.mqhファイルに記述していきますが、記述が煩雑になるので、今回の記事では「OriginalCPositions」とそのメンバに関する記述のみにしてあります。
<復習用リンク>
これまでのOriginalTrade.mqhファイル全体の記述内容
↑OriginalCTradeクラスのメンバや、これまでに追加してきた独立関数の記述が確認できます。
今回は以上とさせていただきます。
最後までお読みいただきありがとうございました<m(__)m>
【超入門】MQL5 EA講座 第82回「ポジション情報管理クラスを作る-その1」←
→【超入門】MQL5 EA講座 第84回「ポジション情報を取得する独立関数を作る」
—————————————————————
-<PR>-
MQL5を使って自作したEAをシステムトレードに利用するには、取引プラットフォームとしてMT5を提供しているFX会社に口座を開設しなくてはいけません。
当サイトでは以下のFX会社での口座開設・EA運用をおススメしています。
おススメする理由の詳細につきましては、各FX会社について解説する記事を書いておりますので、下記のリンク記事を参考にしていただければと思います。
※外為ファイネストに関する記事は↓をご覧ください。
※アヴァトレードジャパンに関する記事は↓をご覧ください。
※フィリップ証券に関する記事は↓をご覧ください。
コメント