2개의 EMA 교차 EA를 만들었습니다. 조언이 필요합니다. - 페이지 3

 
deVries :


현재 스프레드로 테스트하면 이것은 매우 미친 움직임이므로 스프레드가 매우 커질 수 있습니다.

그래서 테스트는 어떻게 하셨나요??

고정 스프레드 또는 현재 스프레드 ??


자, 이제 Google로 "확산"할 시간입니다.

내 어리석은 질문에 답변해 주셔서 감사합니다.))

나는 잠시 후에 돌아올 것이다

 
prupru :


자, 이제 Google "확산"으로 이동합니다.

내 어리석은 질문에 답변해 주셔서 감사합니다.))

나는 잠시 후에 돌아올 것이다

스프레드 = 묻기 - 입찰
 

각 틱 이 값은 변경될 수 있습니다.

내가 방법을 물은 이유는 당신이 테스트를 어떻게했는지

 
deVries :

각 틱 이 값은 변경될 수 있습니다.

내가 방법을 물은 이유는 당신이 테스트를 어떻게했는지

바로 그거죠!

차이점은 현재 스프레드 테스트 때문이었습니다. 고정 스프레드로 테스트를 수행했을 때 정확히 동일했습니다!

정말 감사합니다!

지식이 정말 많이 늘었어요.

그리고 코드에서 개선해야 할 부분이 있으면 알려주세요.

 
prupru :

바로 그거죠!

차이점은 현재 스프레드 테스트 때문이었습니다. 고정 스프레드로 테스트를 수행했을 때 정확히 동일했습니다!

정말 감사합니다!

지식이 정말 많이 늘었어요.

그리고 코드에서 개선해야 할 부분이 있으면 알려주세요.


코드가 어떻게 되었는지 보여주면

새로운 오류 처리도 보고 싶습니다. RaptorUK https://www.mql5.com/en/forum/148529 댓글 참조

 
deVries :


코드가 어떻게 되었는지 보여주면

새로운 오류 처리도 보고 싶습니다. RaptorUK https://www.mql5.com/en/forum/148529 댓글 참조

자, 이제 시작하겠습니다.

 #property copyright "me"
#property link        "killnosock.net"
extern int SlowEma = 21 ;
extern int FastEma = 10 ;
extern int MaxRisk = 100 ; // % of Depo to be traded per order
extern int   TakeProfit= 0 ;
extern int   StopLoss= 0 ;
extern int TrailingStop= 0 ;
extern int Slippage = 10 ;

extern double MinDiff = 0.002 ;

int LastBars = 0 ;
//0 - undefined, 1 - bullish cross (fast MA above slow MA), -1 - bearish cross (fast MA below slow MA)
int PrevCross = 0 ;

int init(){ return ( 0 );}
int deinit() { return ( 0 );}

가격 정상화:

 double NormPrice( double g_price)
{
   return ( NormalizeDouble (g_price, MarketInfo ( Symbol (), MODE_DIGITS )));
}

GetLot 기능, 변경되지 않은 것 같습니다

 //function GetLot, get size of the lot according to MaxRisk
double GetLot( int Risk)
{ double Free    = AccountFreeMargin ();
 double One_Lot = MarketInfo ( Symbol (), MODE_MARGINREQUIRED );
 double Min_Lot = MarketInfo ( Symbol (), MODE_MINLOT );
 double Max_Lot = MarketInfo ( Symbol (), MODE_MAXLOT );
 double Step    = MarketInfo ( Symbol (), MODE_LOTSTEP );
 double Lot     = MathFloor (Free*Risk/ 100 /One_Lot/Step)*Step;
 if (Lot<Min_Lot) Lot=Min_Lot;
 if (Lot>Max_Lot) Lot=Max_Lot;
 if (Lot*One_Lot>Free) {
 Alert ( " free= " , AccountFreeMargin (), " for one lot= " , MarketInfo ( Symbol (), MODE_MARGINREQUIRED ), " lot= " , Lot);
 return ( 0.0 );}
return (Lot);}

새 주문 기능은 이제 정규화된 가격을 사용합니다.

 //function NewOrder, place new order
int NewOrder( int Cmd, double Lot)
{ double TP= 0 ; //тейкпрофит
 double SL= 0 ; //стоплосс
 double PR= 0 ; //Цена
 color clr = CLR_NONE;
 while (! IsTradeAllowed ()) Sleep ( 10 );
 RefreshRates ();
 if (Cmd== OP_BUY )
   {PR= Ask ;
     if (TakeProfit> 0 ) TP=NormPrice( Ask + Ask *TakeProfit/ 100 );
     if (StopLoss> 0 ) SL=NormPrice( Ask - Ask *StopLoss/ 100 );
     if (SL< 0 ) SL = 0 ;
     if (TP< 0 ) TP = 0 ;
    clr = Green;}
 if (Cmd== OP_SELL )
   {PR= Bid ;
     if (TakeProfit> 0 ) TP=NormPrice( Bid - Bid *TakeProfit/ 100 );
     if (StopLoss> 0 ) SL=NormPrice( Bid + Bid *StopLoss/ 100 );
     if (SL< 0 ) SL = 0 ;
     if (TP< 0 ) TP = 0 ;
    clr=Red;}
 int tic= OrderSend ( Symbol (),Cmd,Lot,PR,Slippage,SL,TP, "" , 0 , 0 ,clr);
 if (tic< 0 )
  {
   Print ( "open order error:" ,GetLastError());
   Print ( "cmd " , Cmd, " Lot " , Lot, " PR " , PR, " Slip " , Slippage, " SL " , SL, " TP " , TP, " Ask " , Ask , " Bid " , Bid );
  }
return (tic);}

1개 또는 모든 주문 닫기

나는 하나의 심볼에서만 거래할 것이고 계정당 하나의 EA로 거래할 것이기 때문에 심볼과 매직 넘버를 확인하기 위해 주문 마감 기능을 변경하지 않았습니다. 하지만 다른 더 중요한 문제와 튜닝을 처리한 후에 할 것입니다.

 //CloseOrder
void CloseOrder()
{ double PR= 0 ;
 while (! IsTradeAllowed ()) Sleep ( 10 );
 RefreshRates ();
 if ( OrderType ()== OP_BUY )  PR= Bid ;
 if ( OrderType ()== OP_SELL ) PR= Ask ;
 if (! OrderClose ( OrderTicket (), OrderLots (),PR,Slippage,CLR_NONE))
  {
   Print ( "Close order error: " ,GetLastError());
   Print ( "Type " , OrderType (), " PR " ,PR, " Ask " , Ask , " Bid " , Bid , " OrderTicket " , OrderTicket (), " OrderLots " , OrderLots ());
  }
return ;}
//--------------------------- end of close order

//Close all Orders
void CloseAllOrders()
{
   for ( int i= OrdersTotal ()- 1 ;i>= 0 ;i--)
   if ( OrderSelect (i, SELECT_BY_POS , MODE_TRADES ))
     {
      CloseOrder();
     }
return ;}

EmaDiff[2]를 EmaDiff[1]로 비교하는 EMA 교차 감지를 EmaDiff[0]을 0으로 비교하고 추가 플래그를 사용하도록 변경했습니다.

분 규모 데모 계정에서는 스프레드가 너무 높아서 매수 거래가 EMA를 교차하도록 만든 다음 같은 분 막대 내에서 이후에 오는 매도 거래가 그들을 다시 분리하게 만들 때 잘못된 트리거를 만듭니다.

[url=http://postimg.org/image/udq4ufmqf/][img]http://s15.postimg.org/udq4ufmqf/mess.jpg[/img][/url]

나는 지금 이것을 처리하는 방법을 생각하고 있습니다

 // check cross
void CheckCross()
{
   double FMA_Current = iMA ( Symbol (), 0 ,FastEma, 0 , MODE_EMA , PRICE_CLOSE , 0 );
   double SMA_Current = iMA ( Symbol (), 0 ,SlowEma, 0 , MODE_EMA , PRICE_CLOSE , 0 );
   double Poin = (FMA_Current + SMA_Current)/ 2 ;
   double Lot;
   if (PrevCross == 0 ) //Was undefined
   {
       if ((FMA_Current - SMA_Current) >= MinDiff * Poin) PrevCross = 1 ; //Bullish state
       else if ((SMA_Current - FMA_Current) >= MinDiff * Poin) PrevCross = - 1 ; //Bearish state
       return ;
   }
   else if (PrevCross == 1 ) //Was bullish
   {
       if ((SMA_Current - FMA_Current) >= MinDiff * Poin) //Became bearish
      {
         CloseAllOrders();
         Lot = GetLot(MaxRisk);
         NewOrder( OP_SELL ,Lot);
         PrevCross = - 1 ;
      }
   }
   else if (PrevCross == - 1 ) //Was bearish
   {
       if ((FMA_Current - SMA_Current) >= MinDiff * Poin) //Became bullish
      {
         CloseAllOrders();
         Lot = GetLot(MaxRisk);
         NewOrder( OP_BUY ,Lot);
         PrevCross = 1 ;
      }
   }
}

후행 정지 기능:

 // trailing stop
void DoTrailing()
{
   int total = OrdersTotal ();
   for ( int pos = 0 ; pos < total; pos++)
   {
       if ( OrderSelect (pos, SELECT_BY_POS ) == false ) continue ;
       if ( OrderSymbol () == Symbol ())
      {
         if ( OrderType () == OP_BUY )
         {
             RefreshRates ();
             if ( Bid - OrderOpenPrice () >= TrailingStop * Bid / 100 ) //If profit is greater or equal to the desired Trailing Stop value
            {
               if ( OrderStopLoss () < ( Bid - TrailingStop * Bid / 100 )) //If the current stop-loss is below the desired trailing stop level
                   OrderModify ( OrderTicket (), OrderOpenPrice (), NormPrice( Bid - TrailingStop * Bid / 100 ), OrderTakeProfit (), 0 );
            }
         }
         else if ( OrderType () == OP_SELL )
         {
             RefreshRates ();
             if ( OrderOpenPrice () - Ask >= TrailingStop * Ask / 100 ) //If profit is greater or equal to the desired Trailing Stop value
            {
                       if (( OrderStopLoss () > ( Ask + TrailingStop * Ask / 100 )) || ( OrderStopLoss () == 0 )) //If the current stop-loss is below the desired trailing stop level
                   OrderModify ( OrderTicket (), OrderOpenPrice (), NormPrice( Ask + TrailingStop * Ask / 100 ), OrderTakeProfit (), 0 );
            }
         }
      }
   }   
}

그리고 몸 자체:

 //main program
int start()
  {

   if (TrailingStop > 0 ) DoTrailing();
          
         static datetime Time0;
         if (Time0 == Time [ 0 ]) return ;
        Time0 = Time [ 0 ];
      {
       CheckCross();     
              
      }

   return ( 0 );
  }

관심을 가져주셔서 감사합니다!

 
prupru :


나는 하나의 심볼에서만 거래할 것이고 계정당 하나의 EA로 거래할 것이기 때문에 심볼과 매직 넘버를 확인하기 위해 주문 마감 기능을 변경하지 않았습니다. 하지만 다른 더 중요한 문제와 튜닝을 처리한 후에 할 것입니다.


게으르지 말고 직접 해보세요!!!!

항상 포함해야 하는 중요한 사항입니다.

당신이 당신의 프로그램을 수정하고 우리가 수행해야 할 조언을 제공하는 경우

그런 다음 문제를 해결하기 위해 노력하고 싶지 않다면 우리는 무엇을 하고 있습니까?

 
deVries :


게으르지 말고 직접 해보세요!!!!

항상 포함해야 하는 중요한 사항입니다.

당신이 당신의 프로그램을 수정하고 우리가 수행해야 할 조언을 제공하는 경우

그런 다음 문제를 해결하기 위해 노력하고 싶지 않다면 우리는 무엇을 하고 있습니까?


알았어 알았어 진정해)

여기 있습니다, 나는 그것이 트릭을 수행해야한다고 생각합니다.

오픈 주문 기능:

 OrderSend ( Symbol (),Cmd,Lot,PR,Slippage,SL,TP, "" ,Expert_ID, 0 ,clr);

모든 주문 기능 닫기:

//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == Expert_ID))  CloseOrder();
     }
    else
     {
      Print("Error selecting order: ",GetLastError());
      Print(" i= ", i, " Symbol= ", OrderSymbol());
     }
   }
return;}
 

이제 더 큰 문제가 생겼습니다. 브로커는 부분적으로 주문을 실행하는 경향이 있습니다.

고객님, 안녕하세요,

귀하의 거래가 가격 587.318에 부분적으로 열렸습니다(15.84개 중 2.32개).

이 문제에 대해 추가 질문이 있는 경우 주저하지 말고 당사에 문의하십시오.

감사합니다.

브로커.

지원 내용은 다음과 같습니다.

변동성이 높거나 유동성이 낮은 기간에는 지정가 주문이 부분적으로 실행될 수 있습니다. 이는 가격이 충족되면 포지션이 즉시 전체 또는 부분적으로 채워진다는 것을 의미합니다. 귀하의 주문이 부분적으로 실행된 경우 통지서를 수신한 것입니다.

부분적으로 닫혀 있음에도 불구하고 모든 주문을 닫는 방법을 알고 있습니다 . OrdersTotal() > 0인 동안 모든 주문 닫기를 수행해야 하지만 주문이 부분적으로 열릴 때 아직 무엇을 해야 할지 모르겠습니다.

편집하다:

올바른 Symbol 및 magicnumber 순서를 확인해야한다는 것을 깨달았습니다. 조금 더 어렵습니다.

편집: 부분 마감이 있더라도 주문을 마감해야 하는 모든 주문 닫기 기능 이 있습니다.

 //Close all my Orders
void CloseAllOrders()
{
int notMyOrders = 0 ;

for ( int j= OrdersTotal ()- 1 ;j>= 0 ;j--)
{
     if ( OrderSelect (j, SELECT_BY_POS , MODE_TRADES ))
      {
       if (( OrderSymbol () != Symbol ()) || ( OrderMagicNumber () != Expert_ID)) notMyOrders++;
      }
     else
      {
       Print ( "Error selecting order: " ,GetLastError());
       Print ( " j= " , j, " Symbol= " , OrderSymbol ());
      }    
}

 while ( OrdersTotal ()>notMyOrders)
 {
   for ( int i= OrdersTotal ()- 1 ;i>= 0 ;i--)
   {
     if ( OrderSelect (i, SELECT_BY_POS , MODE_TRADES ))
     {
       if (( OrderSymbol () == Symbol ()) && ( OrderMagicNumber () == Expert_ID))  CloseOrder();
     }
     else
     {
       Print ( "Error selecting order: " ,GetLastError());
       Print ( " i= " , i, " Symbol= " , OrderSymbol ());
     }
   }
 }


return ;}
 

다음은 공개 주문을 부분적으로 실행하는 데 어려움을 겪고 있는 방법입니다.

열기 주문은 더 이상 NewOrder 함수 로 수행되지 않지만 다음과 같이 수행됩니다.

 //OpenOrders in case of partial execution
int OpenPartOrders( int Cmd, double Lot)
{
 int NumOrders = 0 ;
 int LastTic = - 1 ;
 double Step = MarketInfo ( Symbol (), MODE_LOTSTEP );
 double LotRemains = Lot;
 
 //MathFloor( /Step)*Step;;
while (LotRemains> 0 )
 {
  LastTic = NewOrder(Cmd, LotRemains);
  NumOrders++;
   if ( OrderSelect (LastTic, SELECT_BY_TICKET )== true )
     {
      LotRemains = LotRemains - OrderLots();
       Print ( "NumberOfOrders " , NumOrders, " Ticket " , LastTic, " LotRemains " , LotRemains, " initial Lot " , Lot);          
     }
   else
   {
     Print ( "OrderSelect returned the error of " ,GetLastError());
    LotRemains = 0 ;//not to create an endless loop opening new orders again and again
   }
 } 
return (NumOrders);}