Нужна помощь по советнику!!!

 

Советник воспринимает сигналы только от индикатора АС.

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

Но когда пересекает отметку не важно в какую сторону, ордер то открывается и всё хорошо НО!!! Когда открытый ордер закроется по тейку или стопу, то тут же открывается другой ордер, а мне нужно чтобы другой ордер открылся когда индикатор АС уйдет в минус.

Проблема: множество ордеров открывается когда индикатор АС в положительной зоне, множество ордеров открывается когда индикатор АС в отрицательной зоне.

Необходимо: реализовать открытие только одного ордера.

//--------------------------------------------------------------------

//--------------------------------------------------------------------


//--------------------------------------------------------------- 1 --
                                   
extern double StopLoss   =5;     // SL для открываемого ордера
extern double TakeProfit =13;      // ТР для открываемого ордера    
extern double Lots       =2.0;     // Жестко заданное колич. лотов
extern double Prots      =30.00;    // Процент свободных средств

bool Work=true;                    // Эксперт будет работать.
string Symb;                       // Название финанс. инструмента
//--------------------------------------------------------------- 2 --

int start()
  {
   int
   Total,                           // Количество ордеров в окне 
   Tip=-1,                          // Тип выбран. ордера (B=0,S=1)
   Ticket;                          // Номер ордера
   double
 
   AC_1_t,
   Vl_1_t,                          // Значен. МА_2 текущее 
   Lot,                             // Колич. лотов в выбран.ордере
   Lts,                             // Колич. лотов в открыв.ордере
   Min_Lot,                         // Минимальное количество лотов
   Step,                            // Шаг изменения размера лота
   Free,                            // Текущие свободные средства
   One_Lot,                         // Стоимость одного лота
   Price,                           // Цена выбранного ордера
   SL,                              // SL выбранного ордера 
   TP;
                                // TP выбранного ордера
   bool
   
   Ans  =false,                     // Ответ сервера после закрытия
   Cls_B=false,                     // Критерий для закрытия  Buy
   Cls_S=false,                     // Критерий для закрытия  Sell
   Opn_B=false,                     // Критерий для открытия  Buy
   Opn_S=false;
                    

//--------------------------------------------------------------- 4 --
   // Учёт ордеров
   Symb=Symbol();                               // Название фин.инстр.
   Total=0;                                     // Количество ордеров
   for(int i=1; i<=OrdersTotal(); i++)          // Цикл перебора ордер
     {
      if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий
        {                                       // Анализ ордеров:
         if (OrderSymbol()!=Symb)continue;      // Не наш фин. инструм
         if (OrderType()>1)                     // Попался отложенный
           {
            Alert("Обнаружен отложенный ордер. Эксперт не работает.");
            return (0);                             // Выход из start()
           }
         Total++;                               // Счётчик рыночн. орд
         if (Total>1)                           // Не более одного орд
           {
            Alert("Несколько рыночных ордеров. Эксперт не работает.");
            return (0);
                                        // Выход из start()
           }
         Ticket=OrderTicket();                  // Номер выбранн. орд.
         Tip   =OrderType();                    // Тип выбранного орд.
         Price =OrderOpenPrice();               // Цена выбранн. орд.
         SL    =OrderStopLoss();                // SL выбранного орд.
         TP    =OrderTakeProfit();              // TP выбранного орд.
         Lot   =OrderLots();                    // Количество лотов
        }
     }
//--------------------------------------------------------------- 5 --
   // Торговые критерии
   AC_1_t=iAC (NULL,0,0);
   Vl_1_t=iVolume (NULL,0,0);
   if (AC_1_t > 0.000001)
      {
         Opn_B=true;
      }
   if (AC_1_t < -0.000001)
      {
         Opn_S=true;
      }
//--------------------------------------------------------------- 6 --
//--------------------------------------------------------------- 7 --
   // Стоимость ордеров
   RefreshRates();                              // Обновление данных
   Min_Lot=MarketInfo(Symb,MODE_MINLOT);        // Миним. колич. лотов 
   Free   =AccountFreeMargin();                 // Свободн средства
   One_Lot=MarketInfo(Symb,MODE_MARGINREQUIRED);// Стоимость 1 лота
   Step   =MarketInfo(Symb,MODE_LOTSTEP);       // Шаг изменен размера

   if (Lots > 0)                                // Если заданы лоты,то 
      Lts =Lots;                                // с ними и работаем 
   else                                         // % свободных средств
      Lts=MathFloor(Free*Prots/One_Lot/Step)*Step;// Для открытия

   if(Lts < Min_Lot) Lts=Min_Lot;               // Не меньше минимальн
   if (Lts*One_Lot > Free)                      // Лот дороже свободн.
     {
      Alert(" Не хватает денег на ", Lts," лотов");
      return (0);                                   // Выход из start()
     }
//--------------------------------------------------------------- 8 --
   // Открытие ордеров
   while(true)                                  // Цикл закрытия орд.
     {
      if (Total==0 && Opn_B==true  )              // Открытых орд. нет +
        {
                                               // критерий откр. Buy
         RefreshRates();                        // Обновление данных
         SL=Bid - New_Stop(StopLoss)*Point;     // Вычисление SL откр.
         TP=Bid + New_Stop(TakeProfit)*Point;   // Вычисление TP откр.
         Alert("Попытка открыть Buy. Ожидание ответа..");
         Ticket=OrderSend(Symb,OP_BUY,Lts,Ask,2,SL,TP);  //Открытие Buy
         if (Ticket > 0)                        // Получилось :)
           {
            Alert ("Открыт ордер Buy ",Ticket);
            return (0);
                                        // Выход из start()
           }
        
         if (Fun_Error(GetLastError())==1)      // Обработка ошибок
            continue;                           // Повторная попытка
         return (0);                                // Выход из start()
        }
     
        
      if (Total==0 && Opn_S==true  )              // Открытых орд. нет +
        {                                       // критерий откр. Sell
         RefreshRates();                        // Обновление данных
         SL=Ask + New_Stop(StopLoss)*Point;     // Вычисление SL откр.
         TP=Ask - New_Stop(TakeProfit)*Point;   // Вычисление TP откр.
         Alert("Попытка открыть Sell. Ожидание ответа..");
         Ticket=OrderSend(Symb,OP_SELL,Lts,Bid,2,SL,TP);//Открытие Sel
         if (Ticket > 0 && Total==1)                        // Получилось :)
           {
            Alert ("Открыт ордер Sell ",Ticket);
            return (0);                                      // Выход из start()
           }
         if (Fun_Error(GetLastError())==1)      // Обработка ошибок
            continue;                           // Повторная попытка
         return (0);                            // Выход из start()
        }
      break;                                    // Выход из while
     }
//--------------------------------------------------------------- 9 --
   return (0);                                      // Выход из start()
  }
//-------------------------------------------------------------- 10 --
int Fun_Error(int Error)                        // Ф-ия обработ ошибок
  {
   switch(Error)
     {                                          // Преодолимые ошибки            
      case  4: Alert("Торговый сервер занят. Пробуем ещё раз..");
         Sleep(3000);                           // Простое решение
         return(1);                             // Выход из функции
      case 135:Alert("Цена изменилась. Пробуем ещё раз..");
         RefreshRates();                        // Обновим данные
         return(1);                             // Выход из функции
      case 136:Alert("Нет цен. Ждём новый тик..");
         while(RefreshRates()==false)           // До нового тика
            Sleep(1);                           // Задержка в цикле
         return(1);                             // Выход из функции
      case 137:Alert("Брокер занят. Пробуем ещё раз..");
         Sleep(3000);                           // Простое решение
         return(1);                             // Выход из функции
      case 146:Alert("Подсистема торговли занята. Пробуем ещё..");
         Sleep(500);                            // Простое решение
         return(1);                             // Выход из функции
         // Критические ошибки
      case  2: Alert("Общая ошибка.");
         return(0);                             // Выход из функции
      case  5: Alert("Старая версия терминала.");
         Work=false;                            // Больше не работать
         return(0);                             // Выход из функции
      case 64: Alert("Счет заблокирован.");
         Work=false;                            // Больше не работать
         return(0);                             // Выход из функции
      case 133:Alert("Торговля запрещена.");
         return(0);                             // Выход из функции
      case 134:Alert("Недостаточно денег для совершения операции.");
         return(0);                             // Выход из функции
      default: Alert("Возникла ошибка ",Error); // Другие варианты   
         return(0);                             // Выход из функции
     }
  }
//-------------------------------------------------------------- 11 --
int New_Stop(int Parametr)                      // Проверка стоп-прик.
  {
   int Min_Dist=MarketInfo(Symb,MODE_STOPLEVEL);// Миним. дистанция
   if (Parametr<Min_Dist)                       // Если меньше допуст.
     {
      Parametr=Min_Dist;                        // Установим допуст.
      Alert("Увеличена дистанция стоп-приказа.");
     }
   return(Parametr);                            // Возврат значения
  }
//-------------------------------------------------------------- 12 --
Файлы:
bg4ma.ex4  10 kb
 
hazan:

Советник воспринимает сигналы только от индикатора АС.

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

Но когда пересекает отметку не важно в какую сторону, ордер то открывается и всё хорошо НО!!! Когда открытый ордер закроется по тейку или стопу, то тут же открывается другой ордер, а мне нужно чтобы другой ордер открылся когда индикатор АС уйдет в минус.

Проблема: множество ордеров открывается когда индикатор АС в положительной зоне, множество ордеров открывается когда индикатор АС в отрицательной зоне.

Необходимо: реализовать открытие только одного ордера

hazan:

Советник воспринимает сигналы только от индикатора АС.

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

Но когда пересекает отметку не важно в какую сторону, ордер то открывается и всё хорошо НО!!! Когда открытый ордер закроется по тейку или стопу, то тут же открывается другой ордер, а мне нужно чтобы другой ордер открылся когда индикатор АС уйдет в минус.

Проблема: множество ордеров открывается когда индикатор АС в положительной зоне, множество ордеров открывается когда индикатор АС в отрицательной зоне.

Необходимо: реализовать открытие только одного ордера.

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

//============== новый бар для текущего окна ============================

static datetime New_Time=0; // Время текущего бара

New_Bar=false; // Нового бара нет

if(New_Time!=iTime(NULL,PERIOD_D1,0)) // Сравниваем время

{

New_Time=iTime(NULL,PERIOD_D1,0); // Теперь время такое

if(MathAbs(TimeCurrent()-New_Time)<180) // это моя строчка, так как при незапланированном перезапуске VDS существует некоторая ошибка приводящая к открытию нескольких одинаковых //ордеров (180 - это цифра в секундах для дневного таймфрейма)

New_Bar=true; // Поймался новый бар

}

На открытие сделок введите еще пару переменных типа триггерных и будет все ОК и еще можно искать открытые ордера по комментарию и открывать их с комментарием, немного проще и нагляднее, по истории правда надо привязываться к каждому брокеру (по разному пишут и что-то добавляют) и еще лучше ориентироваться по коду по номеру строк, в новом терминале строки есть, наверно надо пользовать ножницы.

примечание. Сам ориентируюсь на АС - очень хороший индикатор и к нему (верней его как основу открытия-закрытия прикрепил к разного рода другим) впечатляет.

предлагаю немного другой алгоритм открытия - закрытия ордеров (в отдельной библиотеке, вложенный файл)


Файлы:
 
Предлагайте еще варианты! Люди!
 

Проверяй значение индикатора на прошлом минутном баре. И дату открытия последнего ордера.


Тебе нужно чтобы значение индикатора было отрицательное и дата последнего ордера меньше чем дата текущего минутного бара.

 
По моему на минутных барах чего то добится невозможно, там нет никакой определенности и профит в 10 пунктов - не реально(максимум - 2-3 пункта - но какой брокер даст(а вообще надо попробовать, на EXNESS например, там даже часы по дням не сходятся, максимум Н1, у всех 5 свечей в неделю, у них - шесть)), на Н4 и то по истории проблемно даже взять 10 пунктов на 100% со стопом 800-1000 (неадекватный риск) и то гарантия сомнительна, кстати тренировал стратегию с MACDом, так там иногда получалось лучше на рабочей свече сделку открывать, чем на закрытой.
Причина обращения: