Cualquier pregunta de novato, para no saturar el foro. Profesionales, no pasen de largo. En ninguna parte sin ti - 6. - página 125

 
Sepulca:

Yo lo habría hecho así:


P.D. Contestado al mismo tiempo)))

No lo entiendo:

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

si se abre en la primera barra, mirando de cero a cero?

 
artmedia70:

No lo entiendo:

si se abre en la primera barra, ¿estamos buscando de cero a cero?


Se trata de una pequeña tranquilidad en el caso de que el precio de apertura de la orden sea ya mucho más alto que el Bajo en el momento de la apertura. Es decir, no utilizamos la barra de apertura para buscar. Para eso está PERIOD_M1.
 
Sepulca:
Se trata de una pequeña cobertura en el caso de que el precio de apertura de la orden sea ya significativamente superior al mínimo en el momento de la apertura. Es decir, no utilizamos la barra de apertura para buscar. Para eso está PERIOD_M1.

Yo lo haría de otra manera. En general, yo empezaría a buscar sólo cuando la posición haya durado más de una barra. Al fin y al cabo, el mejor precio puede estar justo en la barra de apertura, y lo desperdiciaremos.
 
artmedia70:
Yo lo haría de otra manera. En general, sólo empezaría a buscar cuando la posición haya durado más de una barra. Después de todo, el mejor precio puede estar justo en la barra de apertura, y lo desperdiciaremos...

Estoy de acuerdo. Probablemente sería más eficiente recordar el precio mínimo (o máximo) de cada orden abierta en la matriz en cada tick, y cerrar las órdenes cuando se alcanza la condición, que volver a buscar el mínimo desde el momento en que se abrió la orden, por así decirlo:

 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;
 }
Y en caso de problemas como pérdida de conexión, reinicio del asesor, etc. modificaría de vez en cuando el stoploss en las órdenes.
 
artmedia70:
He argumentado que el array debe pasarse aquí por referencia. De lo contrario, la función tendrá que trabajar con una sola matriz estrictamente definida. Incluso si lo tienes definido globalmente.


Hmm. Depende del array que se pase a la función de llamada. Si se trata de un array específico, entonces la función llamada funcionará con él... Porque eso es...

Si, por ejemplo,

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

Llamándolo de esta manera:

FindOrders(OrdersMassive)

Funciona con la matriz OrdersMassive.

Y así:

FindOrders(massiveOfOrders)

Con la matriz massiveOfOrders.

 
¿Pueden decirme cómo averiguar el diferencial en el momento de abrir una operación, o mejor aún, cómo conseguir que se muestre en el registro?
 
Forexman77:
¿Puedes decirme cómo averiguar el tamaño del spread, en el momento de abrir una operación, o, mejor, cómo mostrarlo en el registro?

Si (spread) == algún valor, entonces... haz algo... (Por ejemplo, abrir una orden o imprimir su valor en el diario). O viceversa, si no es igual o mayor que (menor que) algún valor, entonces lo mostramos en el diario y hacemos algo. Puedes hacer lo que quieras.
 

Voy a repetir la pregunta que hice ayer. No quiero publicarlo en un hilo aparte. Si algo no está claro, responderé a todas las preguntas.

Me sigue costando cerrar las posiciones requeridas. La situación es la siguiente:

1. Se está realizando un seguimiento del cierre de posiciones.

2. Tan pronto como la última posición se haya cerrado en la línea de toma... ...todas las posiciones abiertas y pendientes deben cerrarse de una vez. Todo se cierra ordenado por lotes, es decir, lotes grandes a la vez, y luego más pequeños. Esto está pensado sólo para ganar experiencia con las órdenes.

La aplicación es la siguiente:

En start() en cada tick:

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

Nos interesa cerrar las órdenes de mercado, ya que la pendiente se borra como es debido. Esto es lo que tenemos:

//+-------------------------------------------------------------------------------------+
//| Получаем состояние последней позиции (Открыта или закрыта)                          |
//+-------------------------------------------------------------------------------------+
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 ");
}

Por alguna razón algunos de los pedidos no se están cerrando. Imprimo algunos segmentos cuando los veo, no entiendo nada. He aquí un ejemplo:

El comentario muestra que lastOOTHist = 01:30:00, aunque en realidad no es correcto. Si comprobamos lastOOTHist en la ventana de resultados, veremos que

sus horarios de cierre son diferentes...

¿Qué ocurre aquí?

 
hoz:


Hmm. Depende del array que se pase a la función de llamada. Si se trata de un array específico, entonces la función llamada funcionará con él... Porque eso es...

Si, por ejemplo,

Llamándolo de esta manera:

Funciona con la matriz OrdersMassive

Y así:

Con el array massiveOfOrders.


Cuando pasas una variable (array) a una función por valor, se crea una variable local dentro de la función y la declaras en la cabecera: miFunción(int mi_var). De este modo, los cambios de esta variable no pueden verse fuera de la función. Y en el caso de un array, el compilador te lo recordará.

Si quieres que los cambios en el valor de la variable sean visibles fuera (fuera de la función), pasa las variables por referencia : myFunct(int & my_var)

 
hoz:


Depende de la matriz que se pase a la función de llamada. Si hay un determinado array, entonces la función llamada trabajará con él... Es así...

Si, por ejemplo,

Llamándolo así:

Funciona con la matriz OrdersMassive

Y por aquí:

Con el array massiveOfOrders

Exactamente. Eso es lo que estoy diciendo - por qué querrías que un array específico estuviera codificado en la propia función, si puedes pasarle cualquier array del mismo tamaño y tipo.