Nです.今回はMT5のサンプルプログラムである”Moving Average.mq5″の中の”SelectPosition”関数と”OnInit”関数の内容を解読しました.
SelectPosition
bool SelectPosition()
{
bool res=false;
//--- check position in Hedging mode
if(ExtHedging)
{
uint total=PositionsTotal();
for(uint i=0; i<total; i++)
{
string position_symbol=PositionGetSymbol(i);
if(_Symbol==position_symbol && MA_MAGIC==PositionGetInteger(POSITION_MAGIC))
{
res=true;
break;
}
}
}
//--- check position in Netting mode
else
{
if(!PositionSelect(_Symbol))
return(false);
else
return(PositionGetInteger(POSITION_MAGIC)==MA_MAGIC); //---check Magic number
}
//--- result for Hedging mode
return(res);
}
概要
この関数は取引の形式がHedgingかNettingかに応じて,現在持っているポジションの中にこのオートトレードプログラムの取引によって生じたポジションが存在するかどうかを確かめる関数です.返り値としてはポジションが取得できたかどうかをbool値の変数resとして返します.
具体的には_Symbolと一致する銘柄でかつMA_MAGICというプログラムごとに自分で決めた識別番号が一致するかを確認しています.
詳細説明
まず,ポジションの管理方法は2種類ありHedingとNettingが存在します.どちらにするかは自分で設定できます.
Hedingは1つの銘柄に対して複数のポジションを持つことを許容する方式です.
Nettingは1つの銘柄に対して1つのポジションしか持たない方式です.つまり,追加でオープンしたポジションは過去のポジションと合算されて管理されます.
そのため,現在のポジションについて確認する場合はNettingならば1つ確認すれは全て確認したことになりますが,Hedgingの場合にはオープンされているすべてのポジションについて確認する必要があります.
Hedgingの場合
//--- check position in Hedging mode
if(ExtHedging)
{
uint total=PositionsTotal();
for(uint i=0; i<total; i++)
{
string position_symbol=PositionGetSymbol(i);
if(_Symbol==position_symbol && MA_MAGIC==PositionGetInteger(POSITION_MAGIC))
{
res=true;
break;
}
}
}
上記のプログラムではPositionsTotal関数でオープンになっているポジションの総数を取得し,その数だけforループを回しています.
forループ内ではPositionGetSymbol関数を使って引数として入力したi番目のポジションの銘柄名を取得しています.
さらにPositionGetSymbol関数で選択したポジションの情報を取り出すPositionGetInteger関数にPOSITION_MAGICを引数として与えることでそのポジションのマジックナンバーを調べています.
これらの関数から得られたマジックナンバーと銘柄がオートトレードプログラムを実行したときの_SymbolとMA_MAGICと一致するかを確認し,一致している場合はresにtrueを入れてブレイクしています.
Nettingの場合
//--- check position in Netting mode
else
{
if(!PositionSelect(_Symbol))
return(false);
else
return(PositionGetInteger(POSITION_MAGIC)==MA_MAGIC); //---check Magic number
}
まず,PositionSelect関数で_Symbolの銘柄に対してポジションが選択できるか(存在するか)を調べています.ここで存在しない場合はfalseを返し,存在する場合はさらにマジックナンバーの確認を行ってその結果を返しています.
上記のような形でSelectPosition内ではポジションの確認を行っています.
ポイント
PositionGetInteger関数は参照するポジションについて何も引数を渡せず,あらかじめ参照する所が決まっている.そのためPositionGetInteger関数を使用する前には必ず直前にPositionGetSymbol関数やPositionSelect関数で目的のポジションの情報を取得しておく必要がある.
OnInit
int OnInit(void)
{
//--- prepare trade class to control positions if hedging mode is active
ExtHedging=((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
ExtTrade.SetExpertMagicNumber(MA_MAGIC);
ExtTrade.SetMarginMode();
ExtTrade.SetTypeFillingBySymbol(Symbol());
//--- Moving Average indicator
ExtHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
if(ExtHandle==INVALID_HANDLE)
{
printf("Error creating MA indicator");
return(INIT_FAILED);
}
//--- ok
return(INIT_SUCCEEDED);
}
概要
この関数はプログラムの実行時必ず実行される関数で,サンプルプログラムでは証拠金計算モードの取得(Hedging or Netting)やマジックナンバーや取引銘柄の構造体への登録,インディケーター(ここでは移動平均指標)のハンドルの取得を行っています.最後に成功した場合はINIT_SUCCEEDEDを返すことで初期化の設定の成功を知らせています.
返り値には4つのタイプがあり,状況に応じて適切な返り値を返すことでバグの修正や実行時のバグを減らせます.
- INIT_SUCCEEDED 初期化の成功を意味し0と同じ意味を持ちます.
- INIT_FAILED 初期化の失敗を意味し0以外の値と同じ意味を持ちます.
- INIT_PARAMETERS_INCORRECT 間違ったパラメータが入力されたときに使用し,このタスクを再試行のために渡さなくなります.?
- INIT_AGENT_NOT_SUITABLE 初期化のエラーはないがメモリ不足などの理由でテストできない場合に使用します.
詳細説明
//--- prepare trade class to control positions if hedging mode is active
ExtHedging=((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
ここではアカウントの設定がHedgingになっているかNettingになっているかを確認しています.
AccountInfoInteger関数は引数で指定した口座の情報をlong型で返す関数でここではACCOUNT_MARGIN_MODE(アカウントの設定がHedgingかNettingか)についての情報を取得するのに使用しています.さらに返り値がlong型なのでACCOUNT_MARGIN_MODE_RETAIL_HEDGING(アカウントのモードがHedgingであることを示す)と比較するためにENUM_ACCOUNT_MARGIN_MODEにキャストしています.
つまりExtHedgingはHedgingモードなら1,Nettingモードなら0が入っている変数です.
ExtTrade.SetExpertMagicNumber(MA_MAGIC);
ExtTrade.SetMarginMode();
ExtTrade.SetTypeFillingBySymbol(Symbol());
ExTradeはグローバル空間でCTradeクラスとして宣言された変数で取引を行うために必要となる関数がメソッドとして定義されています.ここではマジックナンバーの定義と証拠金計算モード(Hedging or Netting)の設定,注文を行う銘柄の設定を行っています.
//--- Moving Average indicator
ExtHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
if(ExtHandle==INVALID_HANDLE)
{
printf("Error creating MA indicator");
return(INIT_FAILED);
}
移動平均インディケーターiMAのハンドルの取得を行い失敗したときにはINIT_FAILEDを返しています.
iMAは以下のような引数を取ります.
int iMA(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
int ma_shift, // horizontal shift
ENUM_MA_METHOD ma_method, // smoothing type
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
これらの引数によってどの銘柄のどの時間の単位の何項のどんな移動平均を返すかを指定することができます.今回のサンプルプログラムの場合はある銘柄_Symbolの_Period単位のMovingShift分ずらしたMovingPeriod項のMODE_SMA(シンプルな移動平均)をPRICE_CLOSE(終値)について計算したものを指標としています.
プログラム中ではグローバル変数としてMovingPeriodは12が与えられているので終値に対して12項の移動平均を返していることになります.MovingShiftもグローバル変数として6が与えられており移動平均の移動平均の始点をずらしているようです?
終わりに
今回でMoving Average.mq5関数の解読は終了です.次回はランダム取引プログラムを作ってみたいと思います.
次回のリンクはこちら.
コメント