EAにトレーリングストップを追加する(サンプルソース)

EA
スポンサーリンク

FXで自動売買等で利用しているEAに、トレーリングストップ機能を追加するサンプルソースです。

概要

MT4でポジションを持った際、トレーリングストップ機能はデフォルトで存在しますが、EAの場合は自分で機能を追加しなければなりません。

今回はトレーリングストップ機能ってどうやって作るの?といった方向けに、以前作ったRSIのEAにトレーリングストップ機能を追加していきます。

※RSIの元のソースコードはこちら

修正ソース

ソースコード抜粋

トレーリングストップの処理は割と簡単で以下の処理を入れると出来ます。(単ポジのみ有効ですが)
※複数ポジをトレーリングストップする場合はFor文等で複数回実行する必要があります

input int TRARE = 150;   //トレール値

   total=OrdersTotal();
   
   if(total == 1){
      bool TKekka = OrderSelect(0,SELECT_BY_POS,MODE_TRADES);  
      if(Bid - TRARE * Point > OrderOpenPrice() && OrderType()==OP_BUY && Bid - TRARE * Point > OrderStopLoss()){
          TKekka = OrderModify(OrderTicket(),OrderOpenPrice(),Bid - TRARE * Point,OrderTakeProfit(),0,clrYellow);
      }
      if(Ask + TRARE * Point < OrderOpenPrice() && OrderType()==OP_SELL && Ask + TRARE * Point < OrderStopLoss()){
          TKekka = OrderModify(OrderTicket(),OrderOpenPrice(),Ask + TRARE * Point,OrderTakeProfit(),0,clrYellow);
      }
   }  

1行目は、パラメータ設定にてトレーリングストップ値を設定できるようにしています。

以降は、ポジションがあればOrderModify()関数を使って変更注文を行い随時トレーリングストップをするという形ですね。

ソースコード全体

上記をRSI-EAのソースコードに追加するとこんな感じです。

//+------------------------------------------------------------------+
//|                                                     RSI_TEST.mq4 |
//|                                    Copyright 2020, mef Software. |
//|                                             https://fx-prog.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, mef Software."
#property link      "https://fx-prog.com/"
#property version   "1.00"
     
input int RSI_KIKAN = 19;
input int RSI_KAI = 23;
input int RSI_URI = 71;
  
input int A_SPREAD = 20;
input double Lots = 1;
  
input int SL = 175;
input int TP = 100;

input int TRARE = 15;   //トレール値
  
datetime prevtime;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---
            
//---
   return(INIT_SUCCEEDED);
  }
         
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
int start()
{
int orderPtn=0; //0:何もしない 1:買い 2:売り
int total=0;
         
double ea_order_stop_price=0,ea_order_good_price=0; //ストップロスレート,利確レート,エントリーレート
bool OrderKekka;
        
//---


   total=OrdersTotal();
   
   if(total == 1){
      bool TKekka = OrderSelect(0,SELECT_BY_POS,MODE_TRADES);  
      if(Bid - TRARE * Point > OrderOpenPrice() && OrderType()==OP_BUY && Bid - TRARE * Point > OrderStopLoss()){
          TKekka = OrderModify(OrderTicket(),OrderOpenPrice(),Bid - TRARE * Point,OrderTakeProfit(),0,clrYellow);
      }
      if(Ask + TRARE * Point < OrderOpenPrice() && OrderType()==OP_SELL && Ask + TRARE * Point < OrderStopLoss()){
          TKekka = OrderModify(OrderTicket(),OrderOpenPrice(),Ask + TRARE * Point,OrderTakeProfit(),0,clrYellow);
      }
   }  

   //新しい足ができた時だけやる
   if(Time[0] != prevtime){
      prevtime = Time[0];
   }else{
      return(0);
   }
         
//***売買判断箇所***//
     
   double RSI_atai   = iRSI(NULL, 0, RSI_KIKAN, PRICE_CLOSE, 0);    //RSIの値を取得
     
   //RSI買い判断
   if(RSI_atai < RSI_KAI)
   {
      //ロングエントリー
      orderPtn=1;
   }
   //RSI売り判断 
   else if(RSI_atai > RSI_URI)
   {
      //ショートエントリー   
      orderPtn=2;
   }
   else
   {
      //エントリーしない   
      orderPtn=0;
   }
     
//***売買判断箇所***//
         
//***決済判断箇所***//
   total=OrdersTotal();
   if(total ==0 && orderPtn > 0)   
   {
      if(orderPtn == 1)
      {
         ea_order_stop_price = Ask - SL * Point;
         ea_order_good_price = Ask + TP * Point;     
      }
      else if(orderPtn == 2)
      {
         ea_order_stop_price = Bid + SL * Point;  
         ea_order_good_price = Bid - TP * Point;  
      }   
        
      //新規注文
      OrderKekka = funcOrder_Send(orderPtn - 1,ea_order_stop_price,ea_order_good_price,0,0);
        
   }
           
   return(0);
}
        
//+------------------------------------------------------------------+
//|【関数】新規注文関数                                                 |
//|                                                                  |
//|【引数】 ea_order_entry_Type:売買(0:買 1:売)                         |
//|【引数】 ea_order_stop_price:損切値  ea_order_good_price:利確値      |
//|【引数】 orderComment:オーダーコメント    ea_order_MagicNo:マジックNo       |
//|                                                                  |
//|【戻値】True:成功                                                   |
//|                                                                  |
//| 
bool funcOrder_Send(int ea_order_entry_Type, double ea_order_stop_price, double ea_order_good_price,int orderComment,int ea_order_MagicNo)
{
        
   int order_resend_num;        // エントリー試行回数
   int ea_ticket_res;           // チケットNo
   int errorcode;               // エラーコード
   double ea_order_entry_price; // エントリーレート
   color order_Color;
   bool kekka;
           
   for( order_resend_num = 0; order_resend_num < 10; order_resend_num++ ) {    // エントリー試行回数上限:10回
        
      if(MarketInfo(NULL,MODE_SPREAD) < A_SPREAD){
        
         if(ea_order_entry_Type == OP_BUY){   
            ea_order_entry_price = Ask;               // 現在の買値でエントリー
            order_Color = clrBlue;
         }else if(ea_order_entry_Type == OP_SELL){        
            ea_order_entry_price = Bid;               // 現在の売値でエントリー
            order_Color = clrRed;            
         }
        
         // FXCMでは新規エントリー時にストップ/リミットを設定出来ない。
         ea_ticket_res = OrderSend(   // 新規エントリー注文
            NULL,                 // 通貨ペア
            ea_order_entry_Type,      // オーダータイプ[OP_BUY / OP_SELL]
            Lots,                     // ロット[0.01単位](FXTFは1=10Lot)
            ea_order_entry_price,     // オーダープライスレート
            20,                       // スリップ上限    (int)[分解能 0.1pips]
            ea_order_stop_price,      // ストップレート
            ea_order_good_price,      // リミットレート
            orderComment,             // オーダーコメント
            ea_order_MagicNo,         // マジックナンバー(識別用)
            0,                        // オーダーリミット時間
            order_Color               // オーダーアイコンカラー
            );
      }
                    
      if ( ea_ticket_res == -1) {            // オーダーエラー
         errorcode = GetLastError();      // エラーコード取得
        
         if( errorcode != ERR_NO_ERROR) { // エラー発生
            printf("エラー");
         }
        
         Sleep(2000);                                           // 1000msec待ち
         RefreshRates();                                        // レート更新
        
         printf("再エントリー要求回数:%d, 更新エントリーレート:%g",order_resend_num+1 ,ea_order_entry_price);
        
      } else {    // 注文約定
         Print("新規注文約定。 チケットNo=",ea_ticket_res," レート:",ea_order_entry_price);
         Sleep(300);                                           // 300msec待ち(オーダー要求頻度が多過ぎるとエラーになる為)
                    
         break;
      }
   }
   return kekka;   
}
   

色が変わっている部分のみ修正しています。私が作っているソースコードを見ている方ならわかるかもしれないですが、値動きがある度にトレーリングストップは実行されるようにしています。
※//新しい足ができた時だけやる の処理より上でトレーリングストップ機能を実行しているため

これでパラメータ設定のTRAREに150とすると、15pipsでトレーリングストップを行うようになります。5pipsにしたい場合は50と設定しましょう。

if文の詳細

if(Bid - TRARE * Point > OrderOpenPrice() && OrderType()==OP_BUY && Bid - TRARE * Point > OrderStopLoss()){
    TKekka = OrderModify(OrderTicket(),OrderOpenPrice(),Bid - TRARE * Point,OrderTakeProfit(),0,clrYellow);
}
if(Ask + TRARE * Point < OrderOpenPrice() && OrderType()==OP_SELL && Ask + TRARE * Point < OrderStopLoss()){
    TKekka = OrderModify(OrderTicket(),OrderOpenPrice(),Ask + TRARE * Point,OrderTakeProfit(),0,clrYellow);
}

まず『Bid – TRARE * Point > OrderOpenPrice()』で、トレーリングストップ値以上の利益が出た場合に変更注文を行うといった判定をしています。次に『OrderType()==OP_BUY』買い注文の場合、『Bid – TRARE * Point > OrderStopLoss()』トレーリングストップ値が現在のSLよりも良くなった場合にトレーリングストップを更新するといった感じです。売り注文の場合はその反対ですね。

ダウンロード

上記のEAファイルになります。

“RSIとトレーリングストップのEA” をダウンロード

RSI-TR.ex4 – 123 回のダウンロード – 11.25 KB

さいごに

以上、『EAにトレーリングストップを追加する』でした。

思ったより簡単ではなかったでしょうか?トレーリングストップ機能は、簡単なつくりですが割と使う機能なので覚えておいて損は無いと思います。

※ MT4・EAが使えるFX会社のおすすめ

※ EAのサンプルソースを一覧表にまとめました


コメント