Любой вопрос новичка, чтоб не захламлять форум. Профи, не проходите мимо. Без вас никуда - 6. - страница 125

 
Sepulca:

Я бы сделал так:


P.S. Одновременно ответили)))

Не понял:

if(shift>0) shift=shift-1;

если открыта на первом баре, то ищем от нулевого до нулевого?

 
artmedia70:

Не понял:

если открыта на первом баре, то ищем от нулевого до нулевого?


Это небольшая перестраховка на случай если на момент открытия цена открытия ордера уже значительно больше Low. Т.е. для поиска не используем бар открытия. Для этого и PERIOD_M1.
 
Sepulca:
Это небольшая перестраховка на случай если на момент открытия цена открытия ордера уже значительно больше Low. Т.е. для поиска не используем бар открытия. Для этого и PERIOD_M1.

Я б иначе сделал. Я бы вообще начал поиск только тогда, когда позиция просуществует более одного бара. Ведь лучшая цена может быть как раз на баре открытия, а мы его в расход...
 
artmedia70:
Я б иначе сделал. Я бы вообще начал поиск только тогда, когда позиция просуществует более одного бара. Ведь лучшая цена может быть как раз на баре открытия, а мы его в расход...

Согласен. Наверное эффективней будет на каждом тике запоминать минимумы (или максимумы) цены для каждого открытого ордера в массиве и закрывать ордера при достижении условия, чем заново искать минимум с момента открытия ордера.Как-то так:

 ShortOrderTicket[i]=OrderSend(Symbol(),OP_SELL,......
 if(ShortOrderTicket[i]>=0) min[i]=Bid;
 //.....................................................
 //На каждом тике обновляем минимумы для каждого открытого ордера
 for(i=0;i<N;i++){
  if(ShortOrderTicket[i]>=0){
   min[i]=MathMin(min[i],Ask);
  }
// Если достигнуто условие, закрываем ордер
  if(Ask>min[i]+Delta) if(OrderClose(ShortOrderTicket[i],.....))ShortOrderTicket[i]=-1;
 }
Ну а на случай неприятностей вроде потери связи, перезапуска советника и т.п. время от времени модифицировать стоплосс у ордеров.
 
artmedia70:
Я утверждал, что массив сюда нужно передать по ссылке. Иначе функция обречена работать только с одним, жестко заданным массивом. Пусть он у вас и задан глобально.


Хм. Ведь это зависит от того, какой массив передаётся вызывающей функции. Если там стоит канкретный массив, то с ним вызываемая функция и будет работать... Ведь так..

Если, например,

void FindOrders(int massive[])
{
   int oType;
   ArrayInitialize(massive, 0);
   for (int i=OrdersTotal() - 1; i>=0; i--)
   {
      if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderMagicNumber() != i_magic) continue;
      
      oType = OrderType();
      massive[oType] = massive[oType] + 1;
   }
}

Вызвав её так:

FindOrders(OrdersMassive)

Работа идёт с массивом OrdersMassive

А так:

FindOrders(massiveOfOrders)

С массивом massiveOfOrders

 
Подскажите, как узнать размер спреда, в момент открытия сделки, а лучше, чтобы он отображался в журнале?
 
Forexman77:
Подскажите, как узнать размер спреда, в момент открытия сделки, а лучше, чтобы он отображался в журнале?

if (спред) == какое-то значение, то.. делаем, что-то... (Например, открыть ордер или печатаем в журнал его значение). Или, наоборот, если неравно или больше(меньше) значения какого-то, то выводим в журнал и что-то делаем. Как угодно..
 

Повторю вопрос, который задавал вчера. Не хочется выносить отдельной веткой. Если что не понятно, отвечу на все вопросы.

У меня тут продолжается стопор с закрытием требуемых позиций. Суть такая:

1. Отслеживается закрытие позиций.

2. Как только закрылась последняя позиция по тейку... требуется закрыть все открытые и отложенные позиции сразу. Закрывается всё отсортировано по лотам т.е. сразу большие лоты, а дальше меньшие. Ситуация сугубо для набраться опыта работы с ордерами.

Реализация такая:

в start() на каждом тике:

 for (int ord=OrdersTotal()-1; ord>=0; ord--)
   {
      if (!OrderSelect(ord,SELECT_BY_POS)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() == 6) continue;
        
      g_ticket = OrderTicket();
      g_type = OrderType();
              
      // Блок модификации ордеров       
      if (i_sl != 0 || i_tp != 0)
      {
         if (OrderStopLoss() == 0 && OrderTakeProfit() == 0)
         {
            OrdersModifyer(g_ticket);
         }
      }
      // Закрытие всех ордеров, если последний ордер закрыт
      if (isCloseByTakeLastOpenPos(2))
      {
         // if (g_type < 2)
          {
              ClosePosBySortLots();
          }
          //else
          if (g_type > 1)
          {
              DeletePendingOrders(g_ticket);
          }
      }
   }

На интересует закрытие рыночных ордеров, т.к. отложенный удаляется как требуется. Вот что имеем:

//+-------------------------------------------------------------------------------------+
//| Получаем состояние последней позиции (Открыта или закрыта)                          |
//+-------------------------------------------------------------------------------------+
bool isCloseByTakeLastOpenPos(int delta)
{
   datetime lastOrderCloseTime = -1,               // Время закрытия последнего открытого ордера
            lastOOTHist = -1;                     // Время открытия последнего открытого ордера из истории
   int j = -1;
   pr ("Запустилась функция isCloseByTakeLastOpenPos");
   
   for (int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() > 1) continue;               // Все удалённые отложки нас не интересуют..
  
      if (lastOrderCloseTime < OrderCloseTime())   // Находим время закрытия..
      {
         lastOrderCloseTime = OrderCloseTime();   // ..последней закрытой позиции в истории
         j = i;
         pr ("j = " + j + "   " + TimeToStr(TimeCurrent()));
      }
   }
  if (OrderSelect(j, SELECT_BY_POS, MODE_HISTORY))
   {
      if (OrderProfit() + OrderCommission() + OrderSwap() <= 0) return (false);
//      pr ("OTP() = " + OrderTakeProfit() + "; OCP() " + OrderClosePrice() + "   " + TimeToStr(TimeCurrent()));
  //    pr ("OOP() = " + OrderOpenPrice() + "; OCP() " + OrderClosePrice() + "   " + TimeToStr(TimeCurrent()));
      if (MathAbs(OrderTakeProfit() - OrderClosePrice()) > delta * pt) return (false);
      else
      {
         lastOOTHist = OrderOpenTime();
         Comment("\n", "FUNC isCloseByTakeLastOpenPos: ",
                 "\n", "j = ", j,
                 "\n", "lastOOTHist = ", TimeToStr(lastOOTHist, TIME_SECONDS));
      }
   }
   else
   {
      Comment("\n", "FUNC isCloseByTakeLastOpenPos: ",
              "\n", "j = ", j,
              "\n", "не удалось выбрать ордер в истории");
      return(false);
   }
  
   for(int h=OrdersTotal()-1; h>=0; h--)
   {
      if (OrderSelect(h, SELECT_BY_POS, MODE_TRADES))
      {
         if (OrderMagicNumber() != i_magic)   continue;
         if (OrderSymbol() != Symbol())       continue;
         if (OrderType() > 1)                 continue;
         if (lastOOTHist < OrderOpenTime()) return(false);  // Выбранная рыночная позиция открыта позже закрытой по тейку
      }
      else {Print("FUNC isCloseByTakeLastOpenPos : не удалось выбрать рыночный ордер");return(false);}
   }
   
   return (true);
}

//+-------------------------------------------------------------------------------------+
//| Закрытие ордеров, отсортированных по размеру лотов                                  |
//+-------------------------------------------------------------------------------------+
void ClosePosBySortLots()
{
   double a[][2];
   int p = 0;
   
   for (int i=OrdersTotal()-1; i>=0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() < 2)
      {
         p++;
         ArrayResize(a, p);
         a[p-1][0] = OrderLots();
         a[p-1][1] = OrderTicket();
      }
   }
   pr ("ClosePosBySortLots(): " + "p = " + p);
   if (p > 0)
   {
      ArraySort(a, WHOLE_ARRAY, 0, MODE_DESCEND);
      for(i=0; i<p; i++)
      {
         if (OrderSelect(a[i][1], SELECT_BY_TICKET, MODE_TRADES))
         {
             if (OrderCloseTime() == 0) ClosePosBySelect();
         }
      }
   }
}
//+-------------------------------------------------------------------------------------+
//| Закрытие одного, предварительно выбранного ордера                                   |
//+-------------------------------------------------------------------------------------+
void ClosePosBySelect()
{
   bool   fc;
   color  clClose, clCloseBuy = Blue, clCloseSell = Red;
   double ll, pa, pb, pp;
   int    err, it, NumberOfTry = 3;

   if (OrderType() == OP_BUY || OrderType() == OP_SELL)
   {
       for (it=1; it<=NumberOfTry; it++)
       {
           while (!IsTradeAllowed()) Sleep(5000);
           RefreshRates();
           pa = MarketInfo(OrderSymbol(), MODE_ASK);
           pb = MarketInfo(OrderSymbol(), MODE_BID);
           if (OrderType() == OP_BUY)
           {
               pp = pb; clClose = clCloseBuy;
           }
           else
           {
               pp = pa; clClose = clCloseSell;
           }
           ll = OrderLots();
           fc = OrderClose(OrderTicket(), ll, pp, 30, clClose);
           if (fc)
           {
              break;
           }
           else
           {
               err = GetLastError();
           }
       }
   }
   else Print("Некорректная торговая операция. Close ");
}

Почему-то не закрывается часть ордеров. Принтую некоторые сегменты когда, не чего не понятно. Вот например:

В коменте видно, что lastOOTHist = 01:30:00, хотя, на самом деле, это не есть верно. Ведь последние закрытые ордера, если прогортать в окне результы увидим вот что:

их время закрытия другие...

Что здесь не так?

 
hoz:


Хм. Ведь это зависит от того, какой массив передаётся вызывающей функции. Если там стоит канкретный массив, то с ним вызываемая функция и будет работать... Ведь так..

Если, например,

Вызвав её так:

Работа идёт с массивом OrdersMassive

А так:

С массивом massiveOfOrders


При передаче переменной (массива) в функцию по значению, внутри функции создается локальная переменная, которую вы и объявляете в заголовке : MyFunct(int my_var). Таким образом изменения этой переменной не могут быть видны вне функции. А в случае с массивом вам об этом напомнит компилятор.

Если вы хотите что бы изменения значения переменной были видны снаружи (вне функции), то передавайте переменные по ссылке : MyFunct(int & my_var)

 
hoz:


Хм. Ведь это зависит от того, какой массив передаётся вызывающей функции. Если там стоит канкретный массив, то с ним вызываемая функция и будет работать... Ведь так..

Если, например,

Вызвав её так:

Работа идёт с массивом OrdersMassive

А так:

С массивом massiveOfOrders

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