создал советника по пересечению 2 EMA, нужен совет - страница 3

 
deVries:


нет, если вы тестируете с текущим спредом, это очень сумасшедшее движение, так что спред может стать очень большим

как вы проводили тест?

фиксированный спред или текущий спред?


Хорошо, сейчас я как раз то время, когда я гуглю "спред".

Я ценю, что вы отвечаете на мои глупые вопросы))

Я вернусь через некоторое время

 
prupru:


Ок, сейчас я набираю в гугле "спред".

Я ценю, что вы отвечаете на мои глупые вопросы))

Я вернусь через некоторое время

Спред = Ask - Bid
 

и каждый тик это значение может меняться

причина, по которой я спросил метод, как вы сделали тест

 
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);}

Новая функция Order, теперь использует нормализованные цены:

//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 или все ордера

Я не изменил функцию закрытия ордеров, чтобы проверить символ и магические числа, потому что я собираюсь торговать только на одном символе и только с одним советником на счету. Но я сделаю это после того, как разберусь с другими более важными вопросами и настройкой.

//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;}

Я изменил определение пересечения EMA с сравнения EmaDiff[2] с EmaDiff[1] на сравнение EmaDiff[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:


Я не изменил функцию закрытия ордера для проверки символа и магических чисел, потому что я собираюсь торговать только на одном символе и только с одним советником на счете. Но я сделаю это после того, как разберусь с другими более важными вопросами и настройкой.


не ленитесь, сделайте это прямо !!!!.

это важная вещь, которую всегда нужно включать.

если вы хотите исправить свою программу, и мы дадим совет, что нужно сделать.

тогда, если вы не хотите работать над исправлением, то зачем мы вам помогаем?

 
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;}
 

У меня теперь более серьезная проблема, мой брокер склонен частично исполнять ордера.

Уважаемый клиент,

Настоящим сообщаем, что Ваша сделка была открыта частично (2.32 лота из 15.84) по цене 587.318.

Если у вас возникнут дополнительные вопросы по данной проблеме, не стесняйтесь обращаться к нам.

С уважением,

Брокер.

вот что говорят в службе поддержки:

Пожалуйста, имейте в виду, что в периоды высокой волатильности или низкой ликвидности лимитные ордера могут исполняться частично. Это означает, что позиция будет исполнена немедленно полностью или частично, если цена будет достигнута. В вашем случае ваш ордер был исполнен частично, поэтому вы получили письмо-уведомление.

Я понимаю, как закрыть все ордера, несмотря на их частичное закрытие, нужно просто сделать Close all Orders while OrdersTotal() > 0, но я не знаю, что делать, когда ордера открываются частично.

edit:

Только что понял, что мне нужно проверить правильность ордеров Symbol и magicnumber, это немного сложнее.

edit: вот функция close all orders, которая должна закрывать ордера даже при частичном закрытии

//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);}