なぜ私のEAはバックテスト時にマイナスの利益を出し続けるのでしょうか?

 

ここにある例と同じEAを真似して書いてみました https://www.mql5.com/en/articles/1510 売買の条件を除いては

買いポジションを持つための条件RSIが5以下、かつ、売値が200日移動平均線より上、売値が5日移動平均線より上になったら終了。

売りポジションを建てる条件RSIが95以上、かつ買値が200日移動平均線より下、買値が5日移動平均線より下になったら終了。

バックテストでは、毎回マイナスの利益が出ますが、これはなぜでしょうか?一番いいのは、時々エラー134が出ることで、これは十分な資金がないことを意味します。

iRSI()インジケータに 必要なパラメータですが、何を書けばいいのかわからないので、0を代入しています。

以下はそのコードです。

//+------------------------------------------------------------------+
//|                                              My RSI strategy.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#include <stderror.mqh> 
#include <stdlib.mqh>  
//All Variables here

extern double UpperBound    =  90;      //set upper bound value for RSI
extern double LowerBound    =  5;      //set lower bound value for RSI
extern double VarPeriod     =  2;      //number of periods
extern double BuyVolume     = 0.1;       //set buying volume(lots)
extern double SellVolume    = 0.1;       //set selling volume(lots)
extern double StopLoss      = 25;       //Set the stop loss level
extern double TakeProfit    = 25;       //Set the take profit level
extern double TrailingStop = 30;


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   Alert ("The minimum stoploss and take profit is " + MarketInfo(Symbol(),MODE_STOPLEVEL));
   double CurrentRSI;                  //Finds out the RSI for now
   double MA200;                       //200 day Moving Average           
   double MA5;                         //5 day Moving Average
   double CurrentAsk;                  //Finds out the Ask price now
   double CurrentBid;                  //Finds out the Bid price now
  
   
   CurrentAsk = MarketInfo(Symbol(), MODE_ASK);
   CurrentBid = MarketInfo(Symbol(), MODE_BID);
   MA200 = iMA(NULL, 0, 200, 8,MODE_SMA,PRICE_CLOSE, 0);
   MA5 = iMA(NULL, 0, 5, 8,MODE_SMA,PRICE_CLOSE, 0);
   CurrentRSI = iRSI (NULL, 0, VarPeriod,PRICE_CLOSE ,0);
   
   Alert("Bid is " + CurrentBid);
   Alert("Ask is " + CurrentAsk);
   Alert("200 Day Moving Average is " + MA200); 
   Alert("5 Day Moving Average is " + MA5); 
   Alert("RSI Index is " + CurrentRSI);
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   
   double CurrentRSI;                  //Finds out the RSI for now
   double MA200;                       //200 day Moving Average           
   double MA5;                         //5 day Moving Average
   double CurrentAsk;                  //Finds out the Ask price now
   double CurrentBid;                  //Finds out the Bid price now
   int Ticket;
   int cnt;
   int Ticket2;
   int Total;
   
   CurrentAsk = MarketInfo(Symbol(), MODE_ASK);
   CurrentBid = MarketInfo(Symbol(), MODE_BID);
   MA200 = iMA(NULL, 0, 200, 8,MODE_SMA,PRICE_CLOSE, 0);
   MA5 = iMA(NULL, 0, 5, 8,MODE_SMA,PRICE_CLOSE, 0);
   CurrentRSI = iRSI (NULL, 0, VarPeriod,PRICE_CLOSE ,0);
   
   
    if(Bars<100)
     {
      Print("bars less than 100");
      return(0);  
     }
   
   if(AccountFreeMargin()<(1000*BuyVolume))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
   
    if (CurrentRSI < LowerBound && MarketInfo(Symbol(), MODE_ASK) > MA200 ) {    //Condition to execute buy entry
  
        Ticket = OrderSend(Symbol(), OP_BUY, BuyVolume, Ask, 3, Bid - ( StopLoss * Point ), Ask + ( TakeProfit * Point ), "Buy.", 111,0,Yellow)   ;       //execute buy order
   
    if(Ticket>0)
           {
            if(OrderSelect(Ticket,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("BUY order opened : ",OrderOpenPrice());
           }
         if (Ticket < 0) {
         Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
   }
   return(0);
  }
  
 
  if (CurrentRSI > UpperBound && MarketInfo(Symbol(), MODE_BID) > MA200) {     //Condition to execute sell entry
  
       Ticket2 = OrderSend(Symbol(), OP_SELL, SellVolume, Bid, 3, Ask + ( StopLoss * Point ), Bid - ( TakeProfit * Point ), "Sell.",000, 0, Yellow)  ;     //execute sell order
       if(Ticket2>0)
           {
            if(OrderSelect(Ticket2,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("SELL order opened : ",OrderOpenPrice());
           }
         if (Ticket2<0) {
          Print("Error opening SELL order : ",GetLastError()); 
         return(0); 
        }
       return(0);
   
   } 
   
   Total=OrdersTotal();
    for(cnt=0;cnt<Total;cnt++)
  {
   OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
   if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())  // check for symbol and check for opened position 
     {
if(OrderType()==OP_BUY)   // long position is opened
{
   
   if (CurrentAsk > MA5){      //condition to close long position
    OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close long position
   return(0); // exit
   
   if(TrailingStop>0)  
              {                 
               if(Bid-OrderOpenPrice()>Point*TrailingStop)
                 {
                  if(OrderStopLoss()<Bid-Point*TrailingStop)
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
                     return(0);
                    }
                 }
              }
   
   }
   }
   
   if(OrderType()==OP_SELL)   // long position is opened
{
   if(CurrentBid < MA5){       //condition to close short position
   OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close short position
   return(0); // exit
   }
   
  if(TrailingStop>0)  
              {                 
               if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
                 {
                  if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
                     return(0);
                    }
                 }
              }
   }
   }
   }
   
    
   
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
 

RSIパラメータを0に設定しても、結果が出ない ... ...なし

RSI 0

少なくとも2

rsi 2

 

すべてのEA、すべてのストラテジーが利益を生むわけではありません。

strategytesterを使うときはビジュアルモードをオンにして、EAで設定したのと同じ設定のインジケータをチャートに置いてください。

   MA200 = iMA(NULL, 0, 200, 8,MODE_SMA,PRICE_CLOSE, 0);
   MA5 = iMA(NULL, 0, 5, 8,MODE_SMA,PRICE_CLOSE, 0);
   CurrentRSI = iRSI (NULL, 0, VarPeriod,PRICE_CLOSE ,0);

ティックごとに上記の値を計算しており、" ...,PRICE_CLOSE,0);" を選択しているため、ティックごとに変更される可能性があります。

テストが完了したときにチャートに表示される値は、取引が開始されたときの値ではありません...

   if(AccountFreeMargin()<(1000*BuyVolume))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
   
    if (CurrentRSI < LowerBound && MarketInfo(Symbol(), MODE_ASK) > MA200 ) {    //Condition to execute buy entry
  
        Ticket = OrderSend(Symbol(), OP_BUY, BuyVolume, Ask, 3, Bid - ( StopLoss * Point ), Ask + ( TakeProfit * Point ), "Buy.", 111,0,Yellow)   ;       //execute buy order
   
    if(Ticket>0)
           {
            if(OrderSelect(Ticket,SELECT_BY_TICKET,MODE_TRADES)) 
               Print("BUY order opened : ",OrderOpenPrice());
           }
         if (Ticket < 0) {
         Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
   }
   return(0);
  }
  

買いの条件を満たし、テスターで買いを入れた場合、すでに同じ条件で買いが入っているかどうかが確認されない。

買いが成立した後、次のティックで再び取引を開始するための条件を満たすことができます。

この取引開始はStrategyTesterでは可能ですが、デモでは実際の口座で リアルタイムに行われます。

例えば、スリッページを「3」にすると、「5桁」の口座で取引するには低すぎるというエラーが発生します。

OrderStopLoss() と OrdertakeProfit() > 0 の値で OrderSend を送ると、ECN口座では失敗する。

   Total=OrdersTotal();
    for(cnt=0;cnt<Total;cnt++)
  {
   OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
   if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())  // check for symbol and check for opened position 
     {
OrderSendとトレードチェックのループで、OrderMagicNumber()を使っているのは懐かしいですね。

ループがカウントダウンの代わりにカウントアップしているのを見ましたが、必要に応じてポジションをクローズさせたいので、別のエラーになります

OrderModifyはPointごとに発生するため、tradecontextが忙しすぎるなど、ブローカーからのエラーにつながる可能性があります。

 
FXEWEN:

RSIパラメータを0に設定しても、結果が出ない ... ...何もない

少なくとも2

iRSIの周期を2に設定したのですが....

 
cyxstudio:


iRSI()インディケータに必要なパラメータですが、何を書いていいのかわからなかったので、0を代入しました。


どこからその情報を得たのか分かりませんが、それは間違っています。

iRSI() double iRSI(string symbol,int timeframe,int period,int applied_price,int shift)

shiftは、MAを 取得したい時間のバー番号で、ma_shiftは、バー番号に対してMAの値を移動させることができるので、shiftを5、ma_shiftを-2にすれば、7バーのMAを取得できます。


 
deVries:


strategytesterを使用して、ビジュアルモードをオンにして、EAで設定したのと同じ設定で、チャート上に指標を配置することもできます。

ティックごとに上記の値を計算しているのですが、" ....,PRICE_CLOSE,0);" を選択しているため、ティックごとに値が変わってしまう可能性があります。


シフト値「......PRICE_CLOSE,0);」は何を選択すればいいのでしょうか?

 
cyxstudio:

シフト値「......PRICE_CLOSE,0)」は何を選択 すればよいのでしょうか。

あなたのストラテジーは何を要求しているのでしょうか? それを使います。 バー0を使っても構いませんが、PRICE_CLOSE, Close[0]( バー0の終値) == Bidを使っても「再描画」されます。 バー0が最後に閉じるとバー0ではなくなり、バー1になるのです。
 
deVries:

すべてのEA、すべてのストラテジーが利益を生むわけではありません。

strategytesterを使用し、ビジュアルモードをオンにして、EAで設定したのと同じ設定のインジケータをチャートに配置します。

1ティックごとに上記の値を計算し、" ...,PRICE_CLOSE,0);" を選択したため、ティックごとに値が変化する可能性があります。

テストが終わったときにチャートに表示される値は、取引が開始されたときの値ではない...。

買いを開くための条件を満たし、テスターが買いを開いたとき、同じ条件ですでに買いが開かれているかどうかはチェックされません。

買いが成立した後、次のティックで再び取引を開始するための条件を満たすことができます。

この取引開始はStrategyTesterでは可能ですが、デモでは実際の口座でリアルタイムに行われます。

例えば、スリッページを「3」にすると、「5桁」の口座で取引するには低すぎるというエラーが発生します。

OrderStopLoss() と OrdertakeProfit() > 0 の値で OrderSend を送ると、ECN口座では失敗する。

OrderSendとトレードチェックのループで、OrderMagicNumber()を使っているのは懐かしいですね。

ループがカウントダウンの代わりにカウントアップしているのを見ましたが、必要に応じてポジションをクローズさせたいので、別のエラーになります

OrderModify はすべての Point で発生する可能性があり、tradecontext がビジーであるなど、ブローカーからのエラーにつながる可能性があります。

私はすべてをやり直し、ループ、スリッページを修正し、移動平均とRSIの値を修正し、すべてのオープンポジションが新しいポジションを開始する前にクローズされることを確認しました。しかし、私はそれをバックテスト するとき、何も起こりません、買い/売りは実行されていません。

//+------------------------------------------------------------------+
//|                                                My Strategy 4.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

extern double StopLoss = 40;
extern double TakeProfit = 40;
extern double Lots = 0.1;
extern double Slippage = 10;
extern double RSINow;
extern double MA200;
extern double MA5;
extern bool A1 = false;
extern bool A2 = false;
extern int Ticket;
extern int Ticket2;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+ 
int init()
  {
//----
   Alert("Minimum Stop Level is " + MarketInfo(Symbol(), MODE_STOPLEVEL)); //find out minimum stop loss
   
   RSINow = iRSI(NULL, 1440, 2, PRICE_CLOSE, 0);			//calculates the RSI value for 2 days
   MA200 = iMA(NULL, 1440, 200, 0, MODE_SMA, PRICE_CLOSE,0);		//calculates the moving average for 200 days
   MA5 = iMA(NULL, 1440, 5, 0, MODE_SMA, PRICE_CLOSE,0);     		//calculates the moving average for 5 days
   Alert(RSINow);
   Alert(MA200);
   Alert(MA5);
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----

   
   
   //check if a long position is possible, A is false means no buy trade is open , execute buy when RSI drops below 5 and when Ask price rises above 200 day moving average
   if (A1 == false && RSINow < 5 && Ask > MA200) {
   
   Ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, Bid - ( StopLoss * Point ), Ask + ( TakeProfit * Point ));
   
   if(Ticket>0) {
            if(OrderSelect(Ticket,SELECT_BY_TICKET,MODE_TRADES)) {
               Print("BUY order opened : ",OrderOpenPrice());
               A1 = true;
           }
         if (Ticket < 0) {
         Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
   }
   }
   } 
   
   
   
     //check if a short position is possible, A2 is false means no sell trade is open , execute sell when RSI rises above 95 and when Bid price drops below 200 day moving average

   if (A2 == false && RSINow > 95 && Bid < MA200) {
   
   Ticket2 = OrderSend(Symbol(), OP_BUY, Lots, Bid, Slippage, Ask + ( StopLoss * Point ), Bid - ( TakeProfit * Point ));
   if(Ticket2>0) {
            if(OrderSelect(Ticket2,SELECT_BY_TICKET,MODE_TRADES)) {
               Print("SELL order opened : ",OrderOpenPrice());
               A2 = true;
           }
         if (Ticket2 < 0) {
         Print("Error opening SELL order : ",GetLastError()); 
         return(0); 
         }
   }
   
   } 
   
   
   //check if buy position can be closed, once Ask price rises above 5 day moving average, its time to close the position.
   
   if ((A1 == true) && (Ask > MA5)) {
   OrderClose(Ticket, Lots, Bid, Slippage, Violet);
   A1 = false;
   return(0);
   }
   
   
   
   
   //check if sell position can be closed, if Bid price drops below 5 day moving average, close sell position.
   
   if ((A2 == true) && (Bid < MA5)) {
   OrderClose(Ticket2, Lots, Bid, Slippage, Violet);
   A2 = false;
   return(0);
   }
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
cyxstudio:

私はすべてをやり直し、ループ、スリッページを修正し、移動平均とRSIの値を修正し、すべてのオープンポジションが新しいポジションを開始する前にクローズされることを確認しました。しかし、私はそれをバックテストするとき、何も起こりません、買い/売りは実行されていません。


ループは修正されておらず、削除されています。

A1 と A2 を使っていますが、これは取引が始まった瞬間に真の値を取得します。

しかし、もしPCの電源が落ちて、PCとメタトレーダーを再起動しなければならない場合はどうなるでしょうか。

その時、EAからトレードが始まっているかどうかをチェック しなければなりません。

どうやってやるんだ?

もっと簡単にするために、特定のOrderMagicNumberを使用して、トレードをオープンしてチェックします。

.

移動平均は、現在、将来的にいくつかのバーを移動させないようにすることができます。

しかし、あなたはそれをセクションinit()で計算する これはあなたのExpert Advisorを起動するときにのみ実行されます。

私はそれを欠場Start() ...なぜあなたはそれをそこに削除しましたか?

.

 

あなたのコードを書き換えて、テストしてみました。

最高のバックテスト・データではありませんが、正しく実行すれば、利益を上げることができます。

ストラテジーテスターレポート
RSI_ストラテジー_CYXSTUDIO
AlpariUK-Demo - Micro+Classic (Build 451)

シンボルEURUSD (ユーロ vs 米ドル)
期間日足(D1) 2010.10.01 00:00 ~ 2013.01.29 00:00 (2010.10.01 ~ 2013.01.30)
モデル毎ティック(利用可能なすべての最小時間枠に基づく最も正確な方法)
パラメータRSIPeriod=3; UpperBound=90; LowerBound=5; MASlowPeriod=200; MAFastPeriod=5; Lots=0.1; StopLoss=60; TakeProfit=120; TrailingStop=40; MagicNumber=54333; CommentEA="RSI strategies"; Slippage.Pips=3.1;
テスト中のバー1603モデル化されたティック数40187739モデリング品質n/a
グラフの不一致エラー2062601
初期預金3000.00
純利益の合計967.18売上総利益2226.34総損失-1259.16
利益率1.77期待ペイオフ13.62
絶対的ドローダウン107.10最大ドローダウン327.47 (7.99%)相対ドローダウン7.99% (327.47)
総トレード数71ショートポジション (勝率)66 (69.70%)ロングポジション (ウォン)5 (80.00%)
利益取引 (%)50 (70.42%)損失トレード (% of total)21 (29.58%)
最大の利益取引120.07損失トレード-60.00
平均値利益トレード44.53損切り取引-59.96
最大連勝(儲け)8 (424.26)連続負け(損失)3 (-179.93)
最大連続利益(勝利数)424.26 (8)連続損失-179.93 (3)
平均値連勝4連敗2

 
deVries:

あなたのコードを書き換えて、テストしてみました。

最高のバックテスト・データではありませんが、正しく実行すれば、利益を上げることができます。


総取引数71ショートポジション (勝率)66(69.70%)ロングポジション (勝率)5(80.00%)





これだと、何かおかしいと思うのですが。