見出し画像

【バックテスト】条件追加してみた【RSI】

さて、一個前の記事ですが、

バックテスト

と、

MQLの中身

の両方をやったので、ごっちゃになったかもしれませんね。

なので、前回の記事は、まあバックテストを主体に見てもらえればと思います😹

今回は、

MovingAverageの中身に、エントリー条件の追加をしてみようと思います。

正直、それだけならとても簡単なんです。

では有名なRSIを追加してみましょう。


RSIとは

まず、RSIとは、売られすぎ買われすぎの指標です。下記画像をご覧ください。

【Relativ Vigor Index】の略で、チャートに入れるとこんな感じです。

画像1

RSI(14)という窓が一つ増えました😹

これは、陽線が続くと「こんだけ買われすぎてるよ。」ってのを数値にしてくれています。

ちなみに、(14)を見てくれるとわかるように、14本分の動きから計算しております。計算式は省きますが、まあ大体そんな感じで使うオシレーターです。


追加後のコード

まずは全体を記載します🐱

//+------------------------------------------------------------------+
//|                                               Moving Average.mq4 |
//|                   Copyright 2005-2014, MetaQuotes Software Corp. |
//|                                              http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "http://www.mql4.com"
#property description "Moving Average sample expert advisor"

#define MAGICMA  20131111
//--- Inputs
input double Lots          =0.1;
input double MaximumRisk   =0.02;
input double DecreaseFactor=3;
input int    MovingPeriod  =12;
input int    MovingShift   =6;
//+------------------------------------------------------------------+
//| 1  Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
 {
  int buys=0,sells=0;
//---
  for(int i=0;i<OrdersTotal();i++)
    {
     if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
     if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
       {
        if(OrderType()==OP_BUY)  buys++;
        if(OrderType()==OP_SELL) sells++;
       }
    }
//--- return orders volume
  if(buys>0) return(buys);
  else       return(-sells);
 }
//+------------------------------------------------------------------+
//| 2  Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double LotsOptimized()
 {
  double lot=Lots;
  int    orders=HistoryTotal();     // history orders total
  int    losses=0;                  // number of losses orders without a break
//--- select lot size
  lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
//--- calcuulate number of losses orders without a break
  if(DecreaseFactor>0)
    {
     for(int i=orders-1;i>=0;i--)
       {
        if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
          {
           Print("Error in history!");
           break;
          }
        if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL)
           continue;
        //---
        if(OrderProfit()>0) break;
        if(OrderProfit()<0) losses++;
       }
     if(losses>1)
        lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
    }
//--- return lot size
  if(lot<0.1) lot=0.1;
  return(lot);
 }
 
//+------------------------------------------------------------------+
//| 3  Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
 {
  double ma;
  int    res;
//--- go trading only for first tiks of new bar
  if(Volume[0]>1) return;
  
//--- get Moving Average 
  ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
  
//RSIを追加
   double rsi = iRSI( NULL, 30, 14, PRICE_CLOSE, 1);
             //RSIの中身を入れる。通貨ペアは現在、30分足、期間14,終値判定、1本前。という内容を、rsiという箱に全部入れる。
 
//--- sell conditions
  if(Open[1]>ma && Close[1]<ma
  
    && rsi > 40    //ここを追加。1本前のrsi値が40を超えている
  
    )
    {
     res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
     return;
    }
//--- buy conditions
  if(Open[1]<ma && Close[1]>ma
  
      && rsi < 60 //ここを追加。1本前のrsi値が60未満である
 
      )
    {
     res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);
     return;
    }
//---
 }
 
 
 
 
//+------------------------------------------------------------------+
//| 4  Check for close order conditions                                 |
//+------------------------------------------------------------------+
void CheckForClose()
 {
  double ma;
//--- go trading only for first tiks of new bar
  if(Volume[0]>1) return;
//--- get Moving Average 
  ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
//---
  for(int i=0;i<OrdersTotal();i++)
    {
     if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
     if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
     //--- check order type 
     if(OrderType()==OP_BUY)
       {
        if(Open[1]>ma && Close[1]<ma)
          {
           if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,White))
              Print("OrderClose error ",GetLastError());
          }
        break;
       }
     if(OrderType()==OP_SELL)
       {
        if(Open[1]<ma && Close[1]>ma)
          {
           if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,White))
              Print("OrderClose error ",GetLastError());
          }
        break;
       }
    }
//---
 }
//+------------------------------------------------------------------+
//| 5  OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
 {
//--- check for history and trading
  if(Bars<100 || IsTradeAllowed()==false)
     return;
//--- calculate open orders by current symbol
  if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
  else                                    CheckForClose();
//---
 }
//+------------------------------------------------------------------+


上記の中から、追加部分のみ抜粋します。3のエントリー条件の部分にRSIの指定を追加しました。

今回は以上です😹


//+------------------------------------------------------------------+
//| 3  Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
 {
  double ma;
  int    res;
//--- go trading only for first tiks of new bar
  if(Volume[0]>1) return;
  
//--- get Moving Average 
  ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
  
//RSIを追加
   double rsi = iRSI( NULL, 30, 14, PRICE_CLOSE, 1);
 //RSIの中身を入れる。通貨ペアは現在、30分足、期間14,終値判定、1本前。という内容を、rsiという箱に全部入れる。
 
//--- sell conditions
  if(Open[1]>ma && Close[1]<ma
  
    && rsi > 40    //ここを追加。1本前のrsi値が40を超えている
  
    )
    {
     res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
     return;
    }
//--- buy conditions
  if(Open[1]<ma && Close[1]>ma
  
      && rsi < 60 //ここを追加。1本前のrsi値が60未満である
 
      )
    {
     res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);
     return;
    }
//---
 }
 
 
        

この記事が気に入ったらサポートをしてみませんか?