今日は、まだ一度もExpert Advisorを作ったことがない人のためにMetatrader4用のテンプレートEAを作りました!
移動平均と終値を使った単純ルールです。エントリーのフィルタも移動平均を使った単純なものです。利益は望めません^^;
移動平均の代わりに他のインジケーターを使ったり、フィルターを替えたり、シグナルの条件を替えたりしてみましょう!
プログラミングの練習に役立てていただけたらうれしいです。
テンプレートEAが入っている【template.zip】をダウンロード
少し難易度が上がりましたが、新MQL4で複数ポジションや両建て可否選択に対応したテンプレートEAも作成しました。
最新版【Template_2019.mq4】をダウンロード
Dr.EA
Template_2019.mq4のコードがこちら
//+------------------------------------------------------------------+ //| Template_2019.mq4 | //+------------------------------------------------------------------+ #property strict // 外部パラメーター extern double Lots = 0.01; extern double TakeProfit = 0.0; extern double StopLoss = 0.0; extern double Slippage = 1.0; extern string EA_Comment = "Sample EA"; extern int MagicNumber = 20191119; extern int MaxOrder_Buy = 2; extern int MaxOrder_Sell = 2; extern bool HedgeMode = true; extern bool UseMA_TrendFilter = true; extern bool UseMA_Exit = false; extern int MA_Period = 20; extern int MA_Shift = 0; extern ENUM_MA_METHOD MA_Method = MODE_SMA; extern ENUM_APPLIED_PRICE MA_Applied = PRICE_CLOSE; // グローバル変数 double _point; int entry_bar_buy; int entry_bar_sell; //+------------------------------------------------------------------+ //| EA稼働開始時に実行される関数 | //+------------------------------------------------------------------+ int OnInit() { // パラメーターをPips入力にする為の処理 _point = Point; if (Digits % 2 == 1) { _point *= 10; Slippage *= 10; } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| EA稼働終了時に実行される関数 | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| ティック毎に実行される関数 | //+------------------------------------------------------------------+ void OnTick() { int i; // 保有ポジションを確認 ------------------------------------------ int pos_cnt_buy = 0; int pos_cnt_sell = 0; for (i=0; i<OrdersTotal(); i++) { if (OrderSelect(i, SELECT_BY_POS) == false) return; if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue; if (OrderType() == OP_BUY) pos_cnt_buy++; if (OrderType() == OP_SELL) pos_cnt_sell++; } // シグナル判定 ------------------------------------------------- // MAの値取得 double ma_1 = iMA(NULL, 0, MA_Period, MA_Shift, MA_Method, MA_Applied, 1); double ma_2 = iMA(NULL, 0, MA_Period, MA_Shift, MA_Method, MA_Applied, 2); // MAとプライスのクロスシグナル判定 int ma_sign = 0; if (ma_2 >= Close[2] && ma_1 < Close[1]) ma_sign = 1; if (ma_2 <= Close[2] && ma_1 > Close[1]) ma_sign = -1; bool filter_ok_buy = true; bool filter_ok_sell = true; // MA 上昇下降エントリーフィルター if (UseMA_TrendFilter == true) { if (ma_2 > ma_1) filter_ok_buy = false; if (ma_2 < ma_1) filter_ok_sell = false; } // エントリー用シグナル int entry_sign = 0; if (ma_sign == 1) if (filter_ok_buy == true) entry_sign = 1; if (ma_sign == -1) if (filter_ok_sell == true) entry_sign = -1; // ポジション保有時の処理 -------------------------------------- // 決済判定 bool exit_ok_buy = false; if (pos_cnt_buy > 0) if (UseMA_Exit == true && ma_sign == -1) exit_ok_buy = true; bool exit_ok_sell = false; if (pos_cnt_sell > 0) if (UseMA_Exit == true && ma_sign == 1) exit_ok_sell = true; if (exit_ok_buy == true || exit_ok_sell == true) { for (i=OrdersTotal()-1; i>=0; i--) { if (OrderSelect(i, SELECT_BY_POS) == false) continue; if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue; if (exit_ok_buy == true && OrderType() == OP_BUY) if (OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), (int)Slippage, clrYellow) == true) pos_cnt_buy--; if (exit_ok_sell == true && OrderType() == OP_SELL) if (OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), (int)Slippage, clrYellow) == true) pos_cnt_sell--; } } // エントリー注文処理 ----------------------------------- int ticket; double sl, tp; if (HedgeMode == false) { if (pos_cnt_buy > 0 || pos_cnt_sell == MaxOrder_Sell) entry_bar_sell = Bars; if (pos_cnt_sell > 0 || pos_cnt_buy == MaxOrder_Buy) entry_bar_buy = Bars; } // 買いエントリー判定 bool entry_ok_buy = false; if (pos_cnt_buy < MaxOrder_Buy) if (entry_bar_buy != Bars) if (entry_sign == 1) entry_ok_buy = true; // 買い注文処理 if (entry_ok_buy == true) { sl = 0; tp = 0; if (StopLoss > 0) sl = Ask - StopLoss * _point; if (TakeProfit > 0) tp = Ask + TakeProfit * _point; ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, (int)Slippage, sl, tp, EA_Comment, MagicNumber, 0, clrBlue); if (ticket > 0) entry_bar_buy = Bars; else Print("OrderSend(Buy) error."); } // 売りエントリー判定 bool entry_ok_sell = false; if (pos_cnt_sell < MaxOrder_Sell) if (entry_bar_sell != Bars) if (entry_sign == -1) entry_ok_sell = true; // 売り注文処理 if (entry_ok_sell == true) { sl = 0; tp = 0; if (StopLoss > 0) sl = Bid + StopLoss * _point; if (TakeProfit > 0) tp = Bid - TakeProfit * _point; ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, (int)Slippage, sl, tp, EA_Comment, MagicNumber, 0, clrRed); if (ticket > 0) entry_bar_sell = Bars; else Print("OrderSend(Sell) error."); } }
にゃんた
わーい♪
ps
素敵なクリスマスをお過ごしください(^0^)/
メタトレーダーについて検索してて、たどり着きました。
とても為になる記事ばかりですね!自動売買少し諦めかけてたのですが、このブログを読んでなんだか出来そうな気がします。
これからの記事も、楽しみにしてます。
おはようございます、sakiさん。
自動売買は人件費がかからない優秀な従業員を雇うようなもの。時間がかかっても少しずつシステムを作っていきましょう!
これからも、記事作りに力を注いでいきますので、よろしくお願いいたします。
私はMT4初心者なので一生懸命勉強して自動売買出来るようになろう!と決意して参考になるものを購入したり各ブログでずっとずっと勉強したのですが結局は初歩の初歩、肝心なところで急に難しく書かれていたりして結局諦めていました。それが慶二さんのブログに出会いほんの数時間で自動売買の自分の望むプログラムを完成することができました。本当の意味で初心者に分かりやすく慶二さんには感謝しきりです。
そこでもしよろしければ質問があるのですが、検証のところでポンド円5分足オープンプライスですぐ結果が表示されていたのがプログラムを修正コンパイルして再度検証するとものすごく時間がかかりエラー画面が出てきます。他の通貨ならこのプログラムでも問題なくすぐ結果表示されるのですがポンド円5分足だけ検証が出来ません。アンインストールしてインストールし直してもやはり同じです。これはどの様な理由が考えられるのでしょうか?もしお暇なときがあれば宜しくお願いします。慶二はMT4の本を出版されるお考えはないのでしょうか?今あるのは初心者にはやさしく書いていると思えば急に難しくなったり結局わからないままなので慶二さんみないに本当に初心者の立場に立った書き方の出来る方に本を出していただきたいです。おそらくこのように思っているのは私だけではないと思いますので。本当にもう私には無理と思っていたのが慶二さんのブログのおかげでプログラムを作るまでを理解することができました。有難うございました。
すみません!慶次さんのつづりがまちがっていますね。しかも呼び捨てにしているところも。本当にすみませんでしたm(_ _)mこれからもブログを楽しみにしています。
MIKIさん、はじめまして。
MIKIさんの様に言っていただけたらそれだけでうれしいです!私は、まだまだMT4やプログラムに関して未熟なのでこのブログを通じてみんなと上達していけたらと思っています。
エラー画面とは、テスターの操作履歴に出るものですか?OSのエラーですか?
テスターのエラーの場合は、MetaEditorのNavigatorウィンドウのFilesのstdlib.mq4に英語ですが、原因が書いてあります。
OSのエラーの場合は、メモリ不足のため応答なしということが起こります。これは、ポンド円の5分足データがとても多いか計算のどこかでループしているかかと思います。(値が200を超えているとループしてしまうなど)
今分かるのはこれぐらいです。
また、コメントお願いしますね。
>慶次さん
テンプレートがすばらしいですね。
これからもいろいろな記事を楽しみにしてます。
>MIKIさん
ちなみにエラーメッセージはなんですか?
「操作履歴」になにか出ているはずです。
為替龍さん、お褒めの言葉ありがとうございます。
これからの記事もより良いものを書いていくのでよろしくお願いします。