仕掛けシグナルに2本の移動平均線の交差、手仕舞いに移動平均線と終値の交差を利用します。
終値は期間1の移動平均線と同じことなので、移動平均線と終値は、2本の移動平均線の交差より早く交差します。したがって、次の仕掛けシグナルより早く手仕舞いシグナルを出すことができます。
<aside> 💡 売りポジションの手仕舞い(買いシグナル):2本前から1本前にかけて終値が手仕舞い用移動平均線を下から上に交差したとき 買いポジションの手仕舞い(売りシグナル):2本前から1本前にかけて終値が手仕舞い用長期移動平均線を上から下に交差したとき
</aside>
//共通ライブラリ
#include "LibEA.mqh"
sinput double Lots = 0.1; //売買ロット数
//ティック時実行関数
void Tick()
{
int sig_entry = EntrySignal(); //仕掛けシグナル
int sig_exit = ExitSignal(); //手仕舞いシグナル
//成行売買
MyOrderSendMarket(sig_entry, sig_exit, Lots);
}
input int FastMAPeriod = 20; //短期移動平均の期間
input int SlowMAPeriod = 50; //長期移動平均の期間
//仕掛けシグナル関数
int EntrySignal()
{
//1本前と2本前の移動平均
double FastMA1 = iMA(_Symbol, 0, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
double FastMA2 = iMA(_Symbol, 0, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 2);
double SlowMA1 = iMA(_Symbol, 0, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
double SlowMA2 = iMA(_Symbol, 0, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 2);
int ret = 0; //シグナルの初期化
//買いシグナル
if(FastMA2 <= SlowMA2 && FastMA1 > SlowMA1) ret = 1;
//売りシグナル
if(FastMA2 >= SlowMA2 && FastMA1 < SlowMA1) ret = -1;
return ret; //シグナルの出力
}
input int ExitMAPeriod = 30; //手仕舞い用移動平均の期間
//手仕舞いシグナル関数
int ExitSignal()
{
//1本前と2本前の移動平均
double ExitMA1 = iMA(_Symbol, 0, ExitMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
double ExitMA2 = iMA(_Symbol, 0, ExitMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 2);
int ret = 0; //シグナルの初期化
//買いシグナル
if(Close[2] <= ExitMA2 && Close[1] > ExitMA1) ret = 1;
//売りシグナル
if(Close[2] >= ExitMA2 && Close[1] < ExitMA1) ret = -1;
return ret; //シグナルの出力
}
手仕舞いシグナルとして、手仕舞い用移動平均線(仕掛け用の移動平均線でもよい)を用意し、2本前の移動平均ExitMA2
と終値Close[2]
、1本前の移動平均ExitMA1
と終値Close[1]
の大小関係でシグナルの判別を行います。
この場合、手仕舞いシグナルの方が仕掛けシグナルより先に出ることになるので、MyOrderSendMarket()
の第2引数には、sig_exit
のみを代入しています。
<aside>
💡 iMA()
のshift
パラメータを1
、2
の代わりに0
、1
、終値をClose[0]
、Close[1]
とすることで、最新のバーで終値が移動平均線を交差した瞬間にシグナルを出すことができます。ただし、その場合、ストラテジーテスターのモデルを「全ティック」にしてバックテストする必要があります。
</aside>