Небольшая помощь?

 

Итак, я изучаю mql4 после нескольких других языков, и я (или так я думал) только что закончил первую версию моего первого советника, простого трейдера скользящей средней. Я оставил его работать на весь вчерашний день без каких-либо проблем, вход и выход были такими, как ожидалось, и я решил, что он готов к работе. Сегодня утром я столкнулся со всевозможными проблемами, сначала код при повторном запуске только продавал независимо от позиции, а теперь, после небольшой возни, он покупает и продает в правильных позициях, но при покупке сделка закрывается на следующем тике независимо от позиции. Этого не происходит, когда я продаю, несмотря на тот же формат - может ли кто-нибудь указать мне направление, почему?

(В качестве побочного примечания, мой компьютер был в состоянии запустить код весь день вчера без особого гула (CPU в среднем 12%) сегодня он идет как черти колокола, чтобы запустить код (~60-90%))

Код:

int total;
//+------------------------------------------------------------------+
//| expert init function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                   |
//+------------------------------------------------------------------+
int start()
  {
//----
   int p,q,z,i,L;
   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 
RefreshRates();
//----
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
      {                                                                                                                             //---------- ^ conditions to buy
      p=OrderSend(Symbol(),OP_BUY,0.1,Bid,0,0,0,"",z,0,Red);                                                                        //---------- Buy Order
      OrderSelect(p,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))                             //- whilst the above remains true
            {
            RefreshRates();                                                                                                         //- refresh then do nothing
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);                                                                      //---when above is broken, close
         while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }
//-----         
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
       {                                                                                                                            //---Same steps as above for sell
       q=OrderSend(Symbol(),OP_SELL,0.1,Ask,0,0,0,"",z,0,Blue);
       OrderSelect(q,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))
            {
            RefreshRates();
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);
         while (TimeSeconds(TimeCurrent())!=0)
            {
            Sleep(1000);
         }      
         continue;
      }
if (total!=0)
   {
   L=0;
   for (i=1; i<=OrdersTotal(); i++)                                                       //--- if trades were open which werent initially closed
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- close them if now the position has change
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  L++;
               }
            }
            total=L;
         }
      }
   }
else 
   {
   Sleep(1000);
} 
}
//----
return;
}
//--------------------------------------------------------------+
 

Я не слишком глубоко вникал в ваш код.

Зачем делать RefreshRates и затем спать в течение 1 секунды, когда рынок быстро движется, данные будут устаревшими!?

Вы рассчитываете на тиках, а не на барах, поэтому 1 тик может вызвать ордер, если одна МА переместится выше/ниже другой на минимальную величину. Если на следующем тике (после сна) произойдет разворот, MA снова пересекутся, и ордер будет закрыт.

 

Идея заключается в том, чтобы просто оставаться в цикле, пока условия ждут, пока не наступят условия закрытия (Aka переключение sma) - признаю, что это не лучший способ сделать это, но один из самых дешевых с вычислительной точки зрения.

SMA быстро перемещаются выше/ниже друг друга - это одна из проблем кода - но я не вижу причин, почему, когда в настоящее время есть 10 - 15 пунктов между двумя, на которых я работаю, это приведет к закрытию? Условия определенно держатся, чтобы цикл while оставался под контролем, а не мгновенно перескакивал к закрытию (мое предположение состоит в том, что цикл while игнорируется для покупки, но не для продажи - и я не знаю почему).

 
j.w.msb:

Идея заключается в том, чтобы просто оставаться в цикле, пока условия ждут, пока не наступят условия закрытия (Aka переключение sma) - признаю, что это не лучший способ сделать это, но один из самых дешевых с вычислительной точки зрения.

SMA быстро перемещаются друг над/под другом - это одна из проблем кода - но я не вижу причин, почему, когда в настоящее время есть 10 - 15 пунктов между двумя, на которых я работаю, это приведет к закрытию? Условия определенно держатся, чтобы цикл while оставался под контролем, а не мгновенно перескакивал к закрытию (мое предположение состоит в том, что цикл while игнорируется для покупки, но не для продажи - и я не знаю почему).


Если вы только проверяете, находится ли одна МА выше/ниже другой, я сомневаюсь, что разница обычно составляет 10-15 пунктов, она может быть 0.1 пункта, и следующий тик может легко изменить ее.

Это только мое мнение, но при работе с кроссоверами, я считаю, что лучше всего рассчитывать только на закрытых барах, чтобы избежать слишком большого количества противоположных сигналов.

 

Также в вашем init

 int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}

ваш else применяется только к последнему if, так что если советник не закроет открытый ордер на продажу, то total будет увеличен на 1. Зачем вам это нужно?

 
GumRai:


Если вы только проверяете, находится ли одна МА выше/ниже другой, я сомневаюсь, что разница обычно составляет 10-15 пунктов, она может быть 0.1 пункта, и поэтому следующий тик может легко изменить ее.

Это только мое мнение, но при работе с кроссоверами, я считаю, что лучше всего рассчитывать только на закрытых барах, чтобы избежать слишком большого количества противоположных сигналов.


Это был просчет с моей стороны в плане пипсов! Я виноват! Но суть в том, что между ними есть определенное пространство, чтобы не было сигнала пересечения, который заставит продавать. Замена Sleep(1000) на while (TimeSecond(TimeCurrent)!=59) {Sleep(1000)} обеспечит тестирование кроссовера только на закрытии свечи?


Я убрал OrderClose в секции покупки, и ордер все равно открывается при исполнении, а затем закрывается на следующем пункте :s


Далее я поменял OP_BUY и OP_SELL, и продажа держится, как и ожидалось, когда 6SMA выше 21SMA - жду следующего пересечения, чтобы посмотреть, что произойдет (очевидно, я тестирую это на минутном таймфрейме на данный момент).

 

Есть что менять..... над чем работать.

Какой magicnumber имеют сделки, которые создает ваш советник...

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

int init()
  {

//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }

что здесь происходит...

      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair

         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose( OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(O rderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }

не рассчитывайте проверку сделок, она будет неудачной, если вы закроете сделки внутри цикла, как вы делаете сейчас.

Посмотрите здесь, чтобы увидеть, почему вы должны работать и как вести обратный отсчет.

https://www.mql5.com/en/forum/139654

(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)

это условие может меняться несколько раз за несколько мгновений, когда новый тик приходит в каждой сделке, за которую вы платите спреду

условие не всегда меняется один раз .... на одном баре.

   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 

что всегда запускается, вы позволяете ему спать

и в обычных условиях, когда тик закончился и наступает новый тик, start() вызывается снова.

    while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }

этот способ запуска кода только когда секунда равна 0 будет часто сбойным

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

если первый тик минуты приходит на 1 секунде, вам придется ждать новой минуты и надеяться, что в следующую минуту новый тик придет на 0 секунде

Проверьте функцию RefreshRates()

есть и другие вещи, например, чтобы заставить работать как 4-х, так и 5-ти значного брокера

проверка кодов возврата....

Проскальзывание ваше значение 0 зачем оно нужно ??? чтобы оно было больше

 
deVries:

Есть что менять..... над чем работать.

Какой magicnumber имеют сделки, которые создает ваш советник...

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

что здесь происходит...

не рассчитывайте проверку сделок, она будет неудачной, если вы закроете сделки внутри цикла, как вы делаете сейчас.

Посмотрите здесь, чтобы увидеть, почему вы должны работать и как вести обратный отсчет.

https://www.mql5.com/en/forum/139654

это условие может меняться несколько раз за несколько мгновений, когда приходит новый тик в каждой сделке, за которую вы платите спреду

условие не всегда меняется один раз .... на одном баре.

что всегда запускается, вы позволяете ему спать

и в обычных условиях, когда тик закончился и наступает новый тик, start() вызывается снова.

этот способ запуска кода только когда секунда равна 0 будет часто сбойным

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

если первый тик минуты приходит на 1 секунде, вам придется ждать новую минуту и надеяться, что новый тик придет на 0 секунде следующей минуты.

Проверьте функцию RefreshRates()

есть и другие вещи, например, чтобы заставить работать как 4-х, так и 5-ти значного брокера

проверка кодов возврата....

Проскальзывание ваше значение 0 зачем оно нужно ??? чтобы оно было больше

Спасибо за помощь, сейчас я вношу изменения и посмотрю, что получится! Глупые ошибки, усугубленные глупыми ошибками с моей стороны! Почти удивительно, почему он вообще запустился!
 

Итак, я убрал код, чтобы он работал в самом простом режиме (т.е. пересечение = обратные позиции) - он вызывает много ордеров на покупку/продажу, когда две SMA близки, но я не беспокоюсь об этом (пока) и работает нормально на демо-счете. Теперь меня беспокоит то, что если я запускаю свой код в тестере стратегий, он правильно открывает первую позицию, но затем не может двигаться вперед по времени, поэтому SMA никогда не пересекаются. Что я делаю не так? Мой список отпечатков выглядит следующим образом:

2013.10.22 23:41:26 2013.09.18 00:41 Тестер: ордер #1 закрыт

2013.10.22 23:41:26 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

...

2013.10.22 23:40:53 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:52 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:51 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:56:18 SMACode3 GBPJPY,M1: успешно загружен

Код:



//+------------------------------------------------------------------+
//|                                                   SMA scripy.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
extern int z=1234;
int total;
//----

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()!=0)
      {
      for (i=OrdersTotal()-1; i>=0; i--)                                                     
         {
         if (OrderSelect(i,SELECT_BY_POS))
            {
            if (OrderSymbol()==Symbol())
               {
               if (OrderMagicNumber()==z) 
                  {
                  if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     { 
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     {
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  else 
                     {
                     total++;                                                                 
                  }
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int start()
   {
//----
   int i,L;
   while (AccountBalance()>50)                                                                                     
   {
   RefreshRates();
//-----
double SMA6=iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0);
double SMA21=iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0);
double RSI70=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70;
double RSI30=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30;                                                                                                            
//-----   
if (IsTesting()==true)
{
Sleep(60000);
Print(GetLastError());
}
//----
   if (total==0)
      {
      if ((RSI70)&&(SMA6>SMA21))
         {                                                                                                                       
         OrderSend(Symbol(),OP_BUY,0.1,Ask,0,0,0,"",z,0,Red); 
         total+=1;                                                       
         continue;
      }
      if ((RSI30)&&(SMA6<SMA21))
         {
         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
         total+=1;
         continue;
      }  
   }
//---
if (total!=0)
   {
   L=0;
   for (i=OrdersTotal()-1; i>=0; i--)                                                    
      {
      if (OrderSelect(i,SELECT_BY_POS))
         {
         if (OrderSymbol()==Symbol())
            {
            if (OrderMagicNumber()==z) 
               {
               if ((OrderType()==OP_BUY)&&(SMA6<SMA21))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
                     total+=-1;
                 return;
               }
               if ((OrderType()==OP_SELL)&&(SMA6>SMA21))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                 
                     total+=-1;
                  return;
               }
               else 
                  {
                  L++;                                                                  
               }
            }
            total=L;
         }
      }
   }
}
//----
}
//----
return;
}
//--------------------------------------------------------------+
 
j.w.msb: Сейчас меня беспокоит то, что если я запускаю свой код в тестере стратегий, он правильно открывает первую позицию, но затем не может двигаться вперед по времени,
  1. int start(){
       while (AccountBalance()>50){
          :
    Конечно, нет. RTFM. Вы получаете новый тик только после возвращения со старта.
  2. if (IsTesting()==true){
        Sleep(60000);
        Print(GetLastError());
    }
    RTFM и ограничения тестера Вы НЕ можете спать в тестере
  3.         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
                      OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
    
    Что такое возвращаемые значения функции? Как их использовать? - Форум MQL4
 
RefreshRates не изменяет никаких значений в тестере, поэтому вы застряли в цикле while, так как у него нет новых значений для работы.
Причина обращения: