こんにちは~。
MQLをマスターしたくて、野菜不足を解消しようとしてとにかくミニトマトを口に放り込むりょうです。
今回は学んだテクニカルを活用してEAを作ってみる試みです。
以前、ズブの素人がMQLを学んでいく様を記事にしましたが(奮闘記①・奮闘記②・奮闘記③・奮闘記④)、それ以降も悪戦苦闘しながらEAを作成しております。
そして、今回は以前学んだRSIを活用してEAを作ってみましたので記事にしてみました。
RSIを使ってエントリー、決済条件を作成
早速ですが、今回作成したEAはこちらです↓。
//+------------------------------------------------------------------+
//| RSI.mq4 |
//| Copyright 2021, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
input double p_buyLot = 0.05; //買い注文の時のロット
input uint p_slippage = 2; //許容スリップページ(pips)
input uint p_stopLoss = 200; //ストップロス
input int p_magicNumber = 358168; //マジックナンバー 他のEAと当たらない値を使用する
input uint p_RSIPERIOD = 14; //RSIを計算する期間
input uint p_RSIupperlimit = 70; //RSI上限
input uint p_RSIlowerlimit = 30; //RSI下限
datetime _newBarTime = 0;
bool _entryPermission = false;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
//---
//1本前のRSIの値を取得する
double RSI = iRSI( NULL, 0, p_RSIPERIOD, PRICE_CLOSE, 1 );
//新しいローソク足に切り替わった時だけ実行する処理
if(_newBarTime != Time[0]) {
_newBarTime = Time[0];
//RSIが下限以上になるとエントリー許可を出す
if( RSIOverLowerLimit( RSI ) == true ) {
_entryPermission = true;
}
//決済条件
//エントリー中、RSIが上限を超すと決済する
for( int i = 0; i <= OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true) {
if( RSIOverUpperLimit( RSI ) == true ) {
int result = OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(), p_slippage );
}
}
}
//エントリー条件
//RSIが下限以下になるとロングエントリーする
if( _entryPermission == true && RSIUnderLowerLimit( RSI ) == true ) {
int result = OrderSend( Symbol(), OP_BUY, p_buyLot, Ask, p_slippage, 0, 0, NULL, clrRed );
//エントリーしたらエントリー許可をfalseにする
_entryPermission = false;
}
}
}
//+------------------------------------------------------------------+
//RSIが下限以下になるとtrue(エントリー条件に使用)
bool RSIUnderLowerLimit(double RSI) {
if( p_RSIlowerlimit >= RSI )return true;
else return false;
}
//+------------------------------------------------------------------+
//RSIが下限以上になるとtrue(エントリー許可フラグに使用)
bool RSIOverLowerLimit(double RSI) {
if( p_RSIlowerlimit <= RSI )return true;
else return false;
}
//+------------------------------------------------------------------+
//RSIが上限以上になるとtrue(決済条件に使用)
bool RSIOverUpperLimit(double RSI) {
if( p_RSIupperlimit <= RSI )return true;
else return false;
}
内容としては、
- RSIが30以下になったらロングエントリー
- エントリー中、RSIが70以上になったら決済
というEAです。

RSIだけを使ったEAだね



シンプルにゃ
iRSI()関数の()内の引数はこのようになっています↓。





iMA()関数と引数がちょっと違う
通貨ペア・適用する価格・算出する位置は以前のiMA()関数の時と同じですね。
今回は時間軸のところを『0』にしてみました。
以前のiMA()関数の時は『PERIOD_CURRENT』にしていましたが同じ意味です。
この時間軸というのは『1分足』『5分足』『4時間足』『1日足』『1週間足』などの時間軸の事で、『0』または『PERIOD_CURRENT』は現在表示している時間足の事です。
PERIOD_CURRENT(0)・・・・・現在のチャートの時間足
PERIOD_M1(1)・・・・・1分足
PERIOD_M5(5)・・・・・5分足
PERIOD_M15(15)・・・・・15分足
PERIOD_M30(30)・・・・・30分足
PERIOD_H1(60)・・・・・1時間足
PERIOD_H4(240)・・・・・4時間足
PERIOD_D1(1440)・・・・・1日足
PERIOD_W1(10080)・・・・・1週間足
PERIOD_MN1(43200)・・・・・1ヶ月足
↑このように時間軸にはそれぞれ識別子があり『PERIOD_CURRENT』と入れても、()の中の『0』を入れてもどちらでも大丈夫です。



でも『PERIOD_CURRENT』とか『PERIOD_M15』とかの方が意味はパッと見てわかりやすいね



コードが長くなって見づらいときは『0』とか『15』の方が短くてスッキリするにゃ



わかりやすい方を使えば良いのだ
次に計算する期間の部分ですが、『p_RSIPERIOD』としています。
これは16行目で自分が設定したパラメータです↓。
input uint p_RSIPERIOD = 14; //RSIを計算する期間
こうしておくことで、現在はデフォルトの値として14を入れていますが、自由に期間を設定することができます。



これは使いやすい



色々パラメータをいじって勝てそうな期間を探すことができるにゃ



今回のEAはその他にもRSIの上限・下限とかエントリー条件の値もパラメーター化しているよ
エントリーの許可を設定してみた
今回、工夫した部分はこちらです↓。
bool _entryPermission = false;
//RSIが下限以上になるとエントリー許可を出す
if( RSIOverLowerLimit( RSI ) == true ) {
_entryPermission = true;
}
//エントリーしたらエントリー許可をfalseにする
_entryPermission = false;
これが何なのかと言いますと、『RSIが下限以下に居続けているとエントリーしまくる現象を回避』するためのコードです。
何言うとんねんという感じなので、画像を見た方が早いと思います。
上のコードが無かったら以下のようになります↓。


このようにRSIが下限(デフォルトでは30)以下が続くとローソク足が変わるたびにずっとエントリーし続けます。



なんか・・・美しくないな
とぼくは今回思ったので手を加えた次第です。
具体的に流れを言いますと、まず21行目で
bool _entryPermission = false;
↑このような変数を作っておきます。初期値はfalseです。
そして52~54行目の
//RSIが下限以上になるとエントリー許可を出す
if( RSIOverLowerLimit( RSI ) == true ) {
_entryPermission = true;
}
↑こちら、RSIが下限(デフォルトでは30)以上で『_entryPermission』がtrueになります。
次にエントリー条件の68~72行目、
//エントリー条件
//RSIが下限以下になるとロングエントリーする
if( _entryPermission == true && RSIUnderLowerLimit( RSI ) == true ) {
int result = OrderSend( Symbol(), OP_BUY, p_buyLot, Ask, p_slippage, 0, 0, NULL, clrRed );
//エントリーしたらエントリー許可をfalseにする
_entryPermission = false;
}
『_entryPermission』がtrue かつRSIが下限以下になるとエントリーです。
ここでエントリーすると同時に 『_entryPermission』をfalseにさせます。
こうすることでエントリー条件である 『_entryPermission == true』 から外れるので次のローソク足からはエントリーしません。



条件を満たす最初のローソク足だけエントリーさせる事ができたぞ!
そして先ほどの
//RSIが下限以上になるとエントリー許可を出す
if( RSIOverLowerLimit( RSI ) == true ) {
_entryPermission = true;
}
このコードによって『RSIが30以下にある状態から上に突き抜けると_entryPermissionがtrue』になり、再び条件を満たせばエントリーする事ができるようになります。


↑こちらがイメージの図になります。
そしてテストした結果がこちらになります↓。


RSIが30以下の状態が続いていますが、エントリーは最初の1回だけです。



狙い通りなのにゃ



こうしてまたMQLを覚えたりょうであった



稼げるかどうかは別だけどね



・・・そうなのであった・・・・・