テンプレートイメージ

今日は、まだ一度もExpert Advisorを作ったことがない人のためにMetatrader4用のテンプレートEAを作りました!

移動平均と終値を使った単純ルールです。エントリーのフィルタも移動平均を使った単純なものです。利益は望めません^^;
移動平均の代わりに他のインジケーターを使ったり、フィルターを替えたり、シグナルの条件を替えたりしてみましょう!

プログラミングの練習に役立てていただけたらうれしいです。

テンプレートEAが入っている【template.zip】をダウンロード

少し難易度が上がりましたが、新MQL4で複数ポジションや両建て可否選択に対応したテンプレートEAも作成しました。
最新版【Template_2019.mq4】をダウンロード

Dr.EADr.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^)/