手仕舞いシグナルとしてRSIのレベルを利用します。
この例では、仕掛けシグナルとして2本の移動平均線の交差を使っています。この場合、次のシグナルがトレンドが反転した後に出ることが多いので、RSIのようなオシレータ系の指標を使って売られすぎ、買われすぎのタイミングで手仕舞いをします。
<aside> 💡 売りポジションの手仕舞い(買いシグナル):1本前のRSIが30を下回ったとき 買いポジションの手仕舞い(売りシグナル):1本前のRSIが70を上回ったとき
</aside>
//共通ライブラリ
#include "LibEA.mqh"
sinput double Lots = 0.1; //売買ロット数
//ティック時実行関数
void Tick()
{
int sig_entry = EntrySignal(); //仕掛けシグナル
int sig_exit = ExitSignal(); //手仕舞いシグナル
//成行売買
MyOrderSendMarket(sig_entry, 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 RSIPeriod = 14; //RSIの期間
//手仕舞いシグナル関数
int ExitSignal()
{
//1本前のRSI
double RSI1 = iRSI(_Symbol, 0, RSIPeriod, PRICE_CLOSE, 1);
int ret = 0; //シグナルの初期化
//買いシグナル
if(RSI1 < 30) ret = 1;
//売りシグナル
if(RSI1 > 70) ret = -1;
return ret; //シグナルの出力
}
ExitSignal()
は、RSIのレベルによる仕掛けシグナルと全く同じ考え方をします。
1本前のRSIRSI1
のレベルによってシグナルの判別を行います。
ただし、手仕舞いシグナルより先に仕掛けシグナルが出ることがあるので、MyOrderSendMarket()
の第2引数には、sig_entry+sig_exit
を代入しています。
<aside>
💡 iRSI()
のshift
パラメータを1
の代わりに0
とすることで、最新のバーのRSIの値でシグナルを出すことができます。ただし、その場合、RSIの値はティックごとに変化するので、ストラテジーテスターのモデルを「全ティック」にしてバックテストする必要があります。
</aside>