백 테스트 시 EA가 계속 마이너스 이익을 내는 이유는 무엇입니까?

 

나는 매수/매도 조건을 제외하고 여기 https://www.mql5.com/en/articles/1510의 예와 동일한 EA를 모방하고 작성했습니다.

매수 포지션을 여는 조건 : RSI 5 미만 및 200일 이동 평균 이상 매도 가격, 매도 가격이 5일 이동 평균 이상일 때 종료.

매도 포지션 오픈 조건 : RSI가 95 이상, Bid price가 200 이하일 때, Bid price가 5일 이동평균 이하일 때 퇴장.g

내가 테스트를 다시 할 때 나는 왜 그런지 알지 못하는 매번 마이너스 이익을 얻습니다. 가장 좋은 점은 때때로 돈이 충분하지 않다는 것을 의미하는 오류 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자리' 계정에서 거래하기에는 Slippage가 너무 낮습니다.

ECN 계정에 대해 OrderStopLoss() 및 OrdertakeProfit() > 0 값과 함께 OrderSend를 보내면 실패합니다.

   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( 문자열 기호, int timeframe, int period, int apply_price, int shift)

아마도 당신은 iMA() 를 의미 했습니까? shift는 MA를 원하는 시간의 막대 번호입니다. ma_shift를 사용하면 막대 번호를 기준으로 MA 값을 이동할 수 있으므로 5의 shift와 -2의 ma_shift를 지정하면 MA가 제공됩니다. 7번 마디의 경우, 내가 맞는지 확인하기 위해 약간의 실험이 필요합니다. 원칙적으로는 맞습니다.


 
deVries :


전략 테스터를 사용하여 시각적 모드를 켜고 차트에 배치하십시오. 표시기는 EA에서 설정한 것과 동일한 설정입니다.

위의 값을 계산하는 모든 눈금은 " ...., PRICE_CLOSE , 0 );"을 선택했기 때문에 모든 눈금과 함께 변경될 수 있습니다.


시프트 값으로 무엇을 선택해야 합니까 " ...., PRICE_CLOSE , 0 );" 그 다음에?

 
cyxstudio :

시프트 값으로 무엇을 선택해야 합니까 " ...., PRICE_CLOSE , 0 );" 그 다음에?

당신의 전략은 무엇을 요구합니까? 그것을 사용합니다. 원하는 경우 막대 0을 사용하지만 PRICE_CLOSE, Close[0](막대 0의 종가 ) == Bid를 사용해도 "다시 칠"합니다. Bar 0이 마침내 닫히면 더 이상 Bar 0이 아니라 Bar 1이 됩니다.
 
deVries :

모든 EA와 모든 전략이 수익성이 있는 것은 아닙니다.

전략 테스터를 사용하여 시각적 모드를 켜고 차트에 배치하십시오. 표시기는 EA에서 설정한 것과 동일한 설정입니다.

위의 값을 계산하는 모든 눈금은 " ...., PRICE_CLOSE , 0 );"을 선택했기 때문에 모든 눈금과 함께 변경될 수 있습니다.

테스트가 완료되었을 때 차트에 표시되는 값은 거래가 열렸을 때의 값이 아닙니다...

공개 매수에 대한 조건이 충족되고 테스터가 매수를 열면 동일한 조건으로 이미 열린 매수가 있는지 확인하지 않습니다.

매수가 다음 틱을 연 후 다시 거래를 열 수 있는 조건을 가질 수 있습니다.

이 거래 개시는 StrategyTester에서 작동할 수 있지만 실제 계정의 데모에서는 실시간으로,

테스터에서 볼 수 없는 오류가 발생할 수 있습니다. 예를 들어 "3"을 선택하면 '5자리' 계정에서 거래하기에는 Slippage가 너무 낮습니다.

ECN 계정에 대해 OrderStopLoss() 및 OrdertakeProfit() > 0 값과 함께 OrderSend를 보내면 실패합니다.

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를 사용하고 있습니다.

하지만 PC의 전원 공급이 중단되고 PC와 메타트레이더를 다시 시작해야 하는 경우에는 어떻게 될까요?

EA에서 거래가 열리면 그 순간을 확인 해야 합니다.

어떻게 할거야????

특정 OrderMagicNumber를 사용하여 보다 쉽게 거래를 확인하고 확인할 수 있습니다.

.

이동 평균은 이제 미래에 일부 막대를 이동하지 않습니다.

그러나 init() 섹션에서만 계산합니다. 이는 Expert Advisor를 시작할 때만 실행됩니다.

나는 Start() 에서 그것을 그리워합니다 .... 왜 거기에서 제거 했습니까 ???

.

 

코드를 다시 작성하고 테스트를 시도했으며 설정도 참조하십시오.

최고의 백테스트 데이터는 아니지만 올바르게 수행하면 수익성이 있을 수 있습니다.

전략 테스터 보고서
RSI_strategy_cyxstudio
AlpariUK-데모 - 마이크로+클래식(빌드 451)

상징 EURUSD(유로 vs 미국 달러)
기간 매일(D1) 2010.10.01 00:00 - 2013.01.29 00:00 (2010.10.01 - 2013.01.30)
모델 모든 틱(사용 가능한 모든 최소 시간 프레임을 기반으로 한 가장 정확한 방법)
매개변수 RSIP 기간=3; 상한=90; 하한=5; MASlowPeriod=200; MAFastPeriod=5; 로트=0.1; 손절매 = 60; 테이크프로핏=120; TrailingStop=40; 매직넘버=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%)





그것은 내가 옳지 않은 것이 있다고 생각하게 만들 것입니다.