移動平均線のゴールデンクロスでエントリーするという、古典的なトレード手法をEAにしてみました。
ソースコードも公開しているので、ご参考くださいませ。
MT4のインストールは必須
MT4のインストールは必須です。私はXMTrading のMT4を使用していますが、基本的な操作は、どのサードパーティのMT4でも同じです。
なお、XMTradingのインストール方法はこちらの記事にまとめました。
デモ口座が使えるので、無料で最初から始められます。
単純移動平均線のゴールデンクロスとは?
今回、EAにしたのは、「単純移動平均線のゴールデンクロスでエントリー」です。
ゴールデンクロスは、短期移動平均線が下から、長期移動平均線に重なったときのタイミングを指します。逆はデッドクロス。
MQL4でコーディング
メタエディタを使ってコーディングします。基本的なコーディング方法と、使い方は、こちらの記事にまとめました。初心者の方はご参考ください。
ソースコード
今回の移動平均線のゴールデンクロスで買うというソースコードはこちら。
注意:実トレードで使わないでください。めっちゃ損します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
//+------------------------------------------------------------------+ //| GoldenCross_buy.mq4 | //| Copyright 2020, Yanoteck | //| https://investment-vmoney.com/ | //+------------------------------------------------------------------+ #property strict #define MAGIC 20200412007 //SMA short extern int sma_short = 20; //SMA long extern int sma_long = 100; //パラメータ extern double Lots = 0.1; //ロット extern int Slippage = 30; //スリッページ extern double Profitrate = 0.002; //利確(0.002=0.2%) extern double SLrate = 0.01; //損切り(0.01=1%) int flg_buy = 0; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- flg_buy = 0; //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- //変数 double now_ask = Ask; //現在のAsk double now_bid = Bid; //現在のBid //SMA取得 double sma_short_now = iMA(NULL,PERIOD_CURRENT,sma_short,0,MODE_SMA,PRICE_CLOSE,0); double sma_long_now = iMA(NULL,PERIOD_CURRENT,sma_long,0,MODE_SMA,PRICE_CLOSE,0); double sma_short_before = iMA(NULL,PERIOD_CURRENT,sma_short,0,MODE_SMA,PRICE_CLOSE,1); double sma_long_before = iMA(NULL,PERIOD_CURRENT,sma_long,0,MODE_SMA,PRICE_CLOSE,1); //ゴールデンクロスでBUYエントリー if((sma_short_before < sma_long_before) && //1バー前の短期移動平均線が長期移動平均線より小さい (sma_short_now >= sma_long_now) && //今の短期移動平均線が長期以上? flg_buy == 0){ // レートのリフレッシュ RefreshRates(); //成り行き買いオーダー OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,Ask*(1-SLrate),Ask*(1+Profitrate),"Buy order",MAGIC,0,Blue); //フラグON flg_buy = 1; //デッドクロスでBUYクローズ }else if((sma_short_before >= sma_long_before) && //1バー前の短期移動平均線が長期移動平均線以上 (sma_short_now < sma_long_now) && //今の短期移動平均線が長期より小? flg_buy == 1){ ClosePositions_BUY(); //フラグOFF flg_buy = 0; } } //+------------------------------------------------------------------+ //| ポジション決済 | //+------------------------------------------------------------------+ void ClosePositions_BUY(){ int i; for(i=0;i<OrdersTotal();i++){ if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == false){ break; } if(OrderMagicNumber() != MAGIC || OrderSymbol() != Symbol()){ continue; } //買いポジションのチェック if(OrderType() == OP_BUY){ OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White); break; } // ループを抜ける break; } } void ClosePositions_SELL(){ int i; for(i=0;i<OrdersTotal();i++){ if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == false){ break; } if(OrderMagicNumber() != MAGIC || OrderSymbol() != Symbol()){ continue; } //売りポジションのチェック if(OrderType() == OP_SELL){ OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,White); break; } // ループを抜ける break; } } //+------------------------------------------------------------------+ |
フラグがないと、しこたまBuyオーダーが入ります。
バックテストの結果
- USDJPY1時間足でテスト
- 1000$スタートで、−787$の赤字
- 勝率65.79%
- 25勝13敗
大負け。ですが、びっくりしたのが勝率。古典的な手法ですが、意外と勝率は良いですね。
意外と結構勝ってます。でも、負けるときに、めっちゃ大負けします。
チャートを分析
チャートをみてみると、勝ってるときはこんな感じ。ちゃんと、ゴールデンクロスでエントリー出来てます。青い線なので分かりづらいですが・・・
デッドクロスで決済する処理入れてますが、OrderSend時に利益率(0.2%)を設定しているので、それで決済してます。
ところが、こんなにキレイなゴールデンクロスだけじゃないんですね。
いわゆる「騙し」があります。短期と長期が、ぐちゃぐちゃってなるケース。
目視だと絶対にこういうケースで売買はしないけど、プログラムだと条件に合致しちゃうので、ここでエントリーしてしまいます。
大負けするときは、ほとんどこのパターン。
移動平均線のクロスは「騙し」の対処を入れる必要あり
騙しをいかにして対処するかがポイントになりそうです。
一応、思いついた対処法書いてみましたが、他のテクニカル併せているので、スマートではありません。どうも対処が思いつきませんでした。
修正部分のソース
騙しが発生するときは、ボリンジャーバンドの2σ〜-2σの間隔が、めちゃくちゃ狭くなるので、一定以上の幅の時しかトレードしないという処理を入れました。これはこれでアリだと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
//修正部分のみ(★の箇所を追加) //★追加:ボリンジャーバンドの値を取得 double bb_2 = iBands(NULL,PERIOD_CURRENT,20,2,0,PRICE_CLOSE,1,0); double bb_M2 = iBands(NULL,PERIOD_CURRENT,20,2,0,PRICE_CLOSE,2,0); //★追加:ボリンジャーバンドの幅 double damashi_chk = bb_2 - bb_M2; //ゴールデンクロスでBUYエントリー if((sma_short_before < sma_long_before) && //1バー前の短期移動平均線が長期移動平均線より小さい (sma_short_now >= sma_long_now) && //今の短期移動平均線が長期以上? (damashi_chk >= 0.7) && //★追加:騙しチェック flg_buy == 0){ // レートのリフレッシュ RefreshRates(); //成り行き買いオーダー OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,Ask*(1-SLrate),Ask*(1+Profitrate),"Buy order",MAGIC,0,clrYellow); //フラグON flg_buy = 1; //デッドクロスでBUYクローズ }else if((sma_short_before >= sma_long_before) && //1バー前の短期移動平均線が長期移動平均線以上 (sma_short_now < sma_long_now) && //今の短期移動平均線が長期より小? flg_buy == 1){ ClosePositions_BUY(); //フラグOFF flg_buy = 0; } |
修正後のバックテストの結果
前と同じ条件でテストした結果です。
2019年のデータでは、何とかプラス。
- USDJPY1時間足でテスト
- 1000$スタートで、+15$の黒字
- 勝率84.62%
- 11勝2敗
騙しは、ある程度は回避成功。ちょっとはマシになりました。
ただし、2回の敗けでマイナス。
敗けた箇所のチャート分析
超暴騰、直後のゴールデンクロスで天井を掴んでしまってます。騙しは無し。これは別の対処が必要ですね。
こちらも、直前の騙しは回避できたけど、暴騰直後のゴールデンクロスで引っかかりました。
うーん。他にも色々ありそう。
まとめ
単純移動平均線のクロスの売買は、そのままでは使えないなというのはよく分かりました。
ある程度の勝率はあるけど、騙しがあったり、その対処だけではカバー出来ない問題も多々ありますね。
線のクロス処理は、他でも多様するので、EAづくりの練習としては、良い素材でした。
ご質問はコメント欄からお願いします