FXの自動売買のためにMT5のEAを作ってみたので内容をまとめる。【ソースコードあり】

Last Updated on 2021-01-17 by toshiikuo

FXの自動売買のためにMT5のEAを作ってみたので、内容をまとめる。

EAを作るのが初めてだったので、基本は以下のサイトを参考にした。

https://www.mql5.com/en/articles/100

考え方

市場参加者の中にはデイトレーダーと呼ばれる、1日の中で取引を取引を完結させる取引を行う人が存在する。

デイトレーダーは長期でポジションを持つ投資家に比べて取れる値幅が小さいことから、同じだけの利益を上げるためには、大きな数量のポジションを持つ必要がある。

そのため、デイトレーダーが1日の中での値動きに与える影響が大きいと推測できるが、ポジションをとったその日のうちに反対売買をして決済をすることから、1日の終わりにはデイトレーダーが動かした分の値幅は戻ると考えられる。

その戻りを利益にするためのEAを作った。

売買ロジック

1日の取引の始値から、乖離したら逆張りでエントリー。

始値に戻ったら利益確定。

その日の取引終了時には全決済。

MQL5のコード

ご自由にお使いください。投資は自己責任で。

//+------------------------------------------------------------------+
//|                                                  My_First_EA.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#include<Trade\Trade.mqh>
CTrade trade;
//--- input parameters
input int StartHour=1;
input datetime StartTime=D'2020.01.02 06:00:00';
input int CloseHour=23;
input datetime CloseTime=D'2020.01.02 06:00:00';
input int    endtime;
input int      EA_Magic=104190;  
input double   Lot=0.01;          // Lots to Trade
input double step=0.05;

//--- Other parameters

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- set MagicNumber for your orders identification
   trade.SetExpertMagicNumber(EA_Magic);
//--- set available slippage in points when buying/selling
   int deviation=10;
   trade.SetDeviationInPoints(deviation);
//--- order filling mode, the mode allowed by the server should be used
   trade.SetTypeFilling(ORDER_FILLING_RETURN);
//--- logging mode: it would be better not to declare this method at all, the class will set the best mode on its own
   trade.LogLevel(1); 
//--- what function is to be used for trading: true - OrderSendAsync(), false - OrderSend()
   trade.SetAsyncMode(true);
//---
   return(0);
  }

void OnTick()
{
  
   MqlTick latest_price;      // To be used for getting recent/latest price quotes
   MqlTradeRequest mrequest;  // To be used for sending our trade requests
   MqlTradeResult mresult;    // To be used to get our trade results
   MqlRates mrate[];          // To be used to store the prices, volumes and spread of each bar
   ZeroMemory(mrequest);      // Initialization of mrequest structure
   datetime ct=TimeCurrent();
   MqlDateTime mqlct;
   TimeToStruct(ct,mqlct);
   int cthour=mqlct.hour;
   MqlDateTime mqlst;
   mqlst=mqlct;
   mqlst.hour=StartHour;
   mqlst.min=0;
   mqlst.sec=0;
   datetime StartTime=StructToTime(mqlst);
   MqlDateTime mqlet;
   mqlet=mqlct;
   mqlet.hour=CloseHour;
   mqlet.min=0;
   mqlet.sec=0;
   datetime CloseTime=StructToTime(mqlet);


//--- Get the last price quote using the MQL5 MqlTick Structure
   if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Error getting the latest price quote - error:",GetLastError(),"!!");
      return;
     }

//--- Get the details of the latest 3 bars
   if(CopyRates(_Symbol,_Period,0,3,mrate)<0)
     {
      Alert("Error copying rates/history data - error:",GetLastError(),"!!");
      ResetLastError();
      return;
     }

//---入力された時間の値段を取得
   MqlRates rates[];
   CopyRates(_Symbol,_Period,StartTime,1,rates);
   ArrayPrint(rates);
   double openrate=NormalizeDouble(rates[0].open,_Digits);
   
//---現在の値段を取得
   MqlTick CurrentTick;
   SymbolInfoTick(_Symbol,CurrentTick);
   double CurrentRate=NormalizeDouble(CurrentTick.bid,_Digits);
   
//---差
   double diff = CurrentRate-openrate;
//---エントリー
bool isdealtime = (StartTime<=ct && ct<CloseTime);
   if(isdealtime){
int x;
   for(x=1;diff<=-step*x;x++){
      if(PositionsTotal()<x){
         ZeroMemory(mrequest);
         mrequest.action = TRADE_ACTION_DEAL;                                  // immediate order execution
         mrequest.price = NormalizeDouble(latest_price.ask,_Digits);           // latest ask price
         mrequest.symbol = _Symbol;                                            // currency pair
         mrequest.volume = Lot;                                                 // number of lots to trade
         mrequest.magic = EA_Magic;                                             // Order Magic Number
         mrequest.type = ORDER_TYPE_BUY;                                        // Buy Order
         mrequest.type_filling = ORDER_FILLING_FOK;                             // Order execution type
         mrequest.deviation=100;                                                // Deviation from current price
         mrequest.tp = NormalizeDouble(openrate,_Digits); // Take Profit
         //--- send order
         OrderSend(mrequest,mresult);
         // get the result code
         if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed
           {
            Alert("A Buy order has been successfully placed with Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("The Buy order request could not be completed -error:",GetLastError());
            ResetLastError();           
            return;
           }
      }
   }
      for(x=1;diff>=step*x;x++){
      if(PositionsTotal()<x){
         ZeroMemory(mrequest);
         mrequest.action = TRADE_ACTION_DEAL;                                  // immediate order execution
         mrequest.price = NormalizeDouble(latest_price.bid,_Digits);           // latest bid price
         mrequest.symbol = _Symbol;                                            // currency pair
         mrequest.volume = Lot;                                                 // number of lots to trade
         mrequest.magic = EA_Magic;                                             // Order Magic Number
         mrequest.type = ORDER_TYPE_SELL;                                        // Buy Order
         mrequest.type_filling = ORDER_FILLING_FOK;                             // Order execution type
         mrequest.deviation=100;                                                // Deviation from current price
         mrequest.tp = NormalizeDouble(openrate,_Digits); // Take Profit
         //--- send order
         OrderSend(mrequest,mresult);
         // get the result code
         if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed
           {
            Alert("A Sell order has been successfully placed with Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("The Sell order request could not be completed -error:",GetLastError());
            ResetLastError();           
            return;
           }
      }
   }
   
  }

//---時間決済

   if(mqlct.hour==mqlet.hour){
         trade.PositionClose(Symbol());
   }

   return;
  }
//+------------------------------------------------------------------+

バックテスト結果

散々な結果。買いと売りを逆にすれば勝てるかな?

私が使っている口座

MT5でスプレッド、手数料を最小限に抑えるためには、

TradeViewのMT5のILC口座をTariTaliというキャッシュバックサイトから口座開設するのがベストです。(私調べ)
海外FXキャッシュバック口座開設ならTariTali(タリタリ)

2021/1/17追記

売りと買いを逆にしたEAを作ってみた。

「FXの自動売買のためにMT5のEAを作ってみたので内容をまとめる。【ソースコードあり】」への1件のフィードバック

  1. ピンバック: 初めて作ったMT5のEAのバックテスト結果が散々だったので、買いと売りを逆にしてみた。 - Akinai Life

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です