为什么我的EA在回测时一直给出负利润?

 

我模仿并写了一个与这里的例子相同的EA,https://www.mql5.com/en/articles/1510,除了买入/卖出的条件。

开启买入头寸的条件。RSI低于5,并且卖价高于200日移动平均线,当卖价高于5日移动平均线时退出。

建立卖出头寸的条件。RSI高于95,且买入价低于200日移动平均线,当买入价低于5日移动平均线时退出。

当我回测时,我每次都得到负利润,我不知道为什么。最重要的是有时它会给我错误134,这意味着没有足够的资金。

另外,我想知道什么是shift和ma_shift,我应该如何填写?它是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和策略都是盈利的

在使用策略测试器时,也要打开视觉模式,并在图表上放置你在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位数 "账户的交易来说太低了。

发送OrderSend时,OrderStopLoss()和OrdertakeProfit()的值>0,对于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可能发生在每个点上,这可能导致经纪商的错误,如tradecontext太忙。

 
FXEWEN:

RSI参数设置为0,没有结果,因为 . . .没有什么

至少有2

我确实将iRSI周期设置为2....

 
cyxstudio:


另外,我想知道什么是shift和ma_shift,我应该如何填写?它是iRSI()指标需要的参数,我不知道该怎么写,所以我只是把它赋值为0。


不知道你从哪里得到的信息,但这是不正确的. . .

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

也许你指的是iMA()?shift是你想要的MA的时间的条数,ma_shift允许你将MA值相对于条数移动,所以如果你给它一个5的shift和一个-2的ma_shift,它将给你条7的MA,你将需要试验一下以检查我是否正确,原则上我是的。


 
deVries:


在使用strategytester时,也要打开可视化模式,并在图表上放置你在EA中设置的相同指标。

每一个tick你都在计算上面的数值,它们可以随着每一个tick而改变,因为你选择了"....,PRICE_CLOSE,0);"


那么 我应该选择什么样的转移值"....,PRICE_CLOSE,0);"?

 
cyxstudio:

那么我应该选择什么样的转移值" ....,PRICE_CLOSE,0);"?

你的策略是什么? 使用它。 如果你想的话,使用第0条,但即使你使用PRICE_CLOSE,Close[0] 第0条的收盘价)==Bid,它也会 "重新涂抹"。 当第0条最终关闭时,它不再是第0条,而是成为第1条。
 
deVries:

并非每一个EA和策略都是盈利的

在使用strategytester的时候,也要打开视觉模式,并在图表上放置你在EA中设置的相同的指标。

每一个tick都要计算上述数值,它们可以随着每一个tick而变化,因为你选择了"....,PRICE_CLOSE,0);"

测试完成后,你在图表上看到的数值并不是你在交易开始时的数值......

当满足了买入的条件后,测试者打开了一个买入,然后没有检查你是否已经有一个相同条件的买入。

在买入后的下一个交易日,你可以再次拥有开启交易的条件。

这种交易的开启在StrategyTester中是可行的,但在真实账户的模拟交易中却是实时的。

例如,选择 "3 "滑点对 "5位数 "账户的交易来说太低了。

发送OrderSend时,OrderStopLoss()和OrdertakeProfit()的值>0,对于ECN账户来说会失败。

在OrderSend和这个检查交易的循环中,我想念你使用你的OrderMagicNumber()。

我看到这个循环是向上计数,而不是向下计数,而你也希望它在需要时关闭头寸,所以另一个错误。

OrderModify可能发生在每个点上,这可能导致经纪人的错误,如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,当交易开始时,它们的值为真。

但是如果你的电脑电源坏了,你不得不重新启动你的电脑和metatrader,会发生什么?

你必须检查 那一刻是否有交易从你的EA打开。

你打算怎么做 ????

为了使它更容易,使用一个特定的OrderMagicNumber打开和检查你的交易

.

移动平均线现在没有移动,在未来的一些条形图中也是如此。

但你只在init()部分计算它,这将只在启动你的专家顾问时运行。

我错过了Start()....,为什么你把它移到那里?

.

 

我已经重写了你的代码,并进行了测试,也看到了设置。

虽然没有最好的回溯数据,但如果你做得对的话,是可以盈利的。

策略测试报告
RSI_strategy_cyxstudio
AlpariUK-Demo - Micro+Classic (Build 451)

符号欧元兑美元(欧元对美元)
时间每日(D1) 2010.10.01 00:00 - 2013.01.29 00:00 (2010.10.01 - 2013.01.30)
模型Every tick (基于所有可用的最小时间框架的最精确方法)
参数RSIPeriod=3; UpperBound=90; LowerBound=5; MASlowPeriod=200; MAFastPeriod=5; Lots=0.1; StopLoss=60; TakeProfit=120; TrailingStop=40; MagicNumber=54333; CommentEA="RSI策略"; Slippage.Pips=3;
测试中的交易棒1603模拟的点数40187739建模质量不适用
不匹配的图表错误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%)亏损交易(占总数的百分比)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%)





这让我觉得有什么地方不对。