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

 
nick_travel:

¡Buenos días!

Por favor, ayude y explique por qué el Asesor Experto no funciona o no comercia?

¿Tal vez quiere comer? O esperando un cheque de pago...
 
hoz:


Sí, por cierto, esta disposición es más inteligente en la aplicación. La función asociada al inicio ocupa ahora más espacio. Resultó así:

No hay nada que optimizar, ¿verdad?

Quiero decir que es mucho más conveniente, cuando no hay mucho en el inicio. Y todo se llama puramente por funciones. Y la última vez resultó que el inicio tiene todo tipo de excesos de funciones principales y excesos de adicionales...

¿Y por qué pasar un array por referencia, si estás usando un nombre de array declarado globalmente en una función? Tal vez deberías hacerlo así:

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

Y puedes reducirlo un poco:

void FindOrders(int &massive[])
{
   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;
      
      massive[OrderType()] = massive[OrderType()] + 1;
   }
}

Y qué pasa con la llamada desde el inicio y la visualización de mensajes. Me parece que han metido la pata en algo. No podemos ver la función pr(), así que no tenemos nada que sugerir.

He comprobado el número de pedidos en el probador utilizando un algoritmo rápido:

   FindOrders(mn0, OrdersMassive);

   Comment ("\n"+"Всего ордеров = "+OrdersTotal()+
            "\n"+"Количество "+GetNameOP(0)+" = "+OrdersMassive[0]+
            "\n"+"Количество "+GetNameOP(1)+" = "+OrdersMassive[1]+
            "\n"+"Количество "+GetNameOP(2)+" = "+OrdersMassive[2]+
            "\n"+"Количество "+GetNameOP(3)+" = "+OrdersMassive[3]+
            "\n"+"Количество "+GetNameOP(4)+" = "+OrdersMassive[4]+
            "\n"+"Количество "+GetNameOP(5)+" = "+OrdersMassive[5]
            );

Puedes envolver toda la salida en una función que leerá los datos del array y mostrará la información de forma humana.

 
nick_travel:

¡Buenos días!

Por favor, ayudar y explicar por qué la EA no funciona o las operaciones?


Porque aquí. no todos telépatas y no todos ¡y visionarios!
 

¡Ya veo!

Quiero decir, ¿hay algún ajuste o algo más que necesites?

 
artmedia70:

¿Por qué pasar un array por referencia si se utiliza un nombre de array declarado globalmente en la función? Tal vez debería ser así:

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

En realidad, sí, tiene sentido. Pero aquí también se pasa por referencia:)) Lo tuve después de la última vez, cuando los parámetros no fueron declarados globalmente.

Y sobre la función pr. Aquí está:

//+-------------------------------------------------------------------------------------+
//| Распринтовка на экран                                                               |
//+-------------------------------------------------------------------------------------+
void pr (string txt)
{
   string info [];
   ArrayResize(info, 20);
   string h, m, s, cm; int i;
   
   h = DoubleToStr(Hour(), 0);    if (StringLen(h) < 2) h = "0" + h;
   m = DoubleToStr(Minute(), 0);  if (StringLen(m) < 2) m = "0" + m;
   s = DoubleToStr(Seconds(), 0); if (StringLen(s) < 2) s = "0" + s;
   txt = h + ":" + m + ":" + s + " - " + txt;
   
   for (i=20-1; i>=1; i--)
   info[i] = info[i-1];
   info[0] = txt;
   
   for (i=20-1; i>=0; i--)
   if (info[i] != "")
   {
      cm = info[i];
      ObjectCreate ("txtw"+i, OBJ_LABEL, 0, 0, 0);
      ObjectSet    ("txtw"+i, OBJPROP_CORNER, 1);
      ObjectSet    ("txtw"+i, OBJPROP_XDISTANCE, 10);
      ObjectSet    ("txtw"+i, OBJPROP_YDISTANCE, 30+15*i);
      ObjectSetText("txtw"+i, cm, 10, "Times New Roman", Green);
   }
}
 
nick_travel:

¡Ya veo!

Quiero decir, ¿hay algún ajuste o algo más que necesites?


Es decir, no creo que haya telépatas aquí, y aunque los haya, sólo hay que intentar que se interesen por tal hazaña... Adivina y ayuda...

 
hoz:


Es decir, apenas hay telépatas por aquí, y aunque los haya, será mejor que intentes que se interesen por esas hazañas... Adivina y ayuda...

¡Y tal vez un muy buen sistema que no permite la entrada equivocada en el mercado! Me gustaría tener uno.
 

Estoy teniendo un paro continuo en el cierre de posiciones requeridas. La conclusión es la siguiente:

1. se hace un seguimiento del cierre de posiciones.

2. Tan pronto como la última posición se haya cerrado en la retirada... ...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:

En realidad, sí, tiene sentido. Aunque también tienes un enlace aquí:)) Me quedó esto de la última vez, cuando los parámetros no eran globales.

Yo argumenté que el array debe ser pasado por referencia aquí. De lo contrario, la función está condenada a trabajar con una sola matriz codificada. Incluso si lo tienes definido globalmente.
 

Siento que me necesiten al final de la semana, pero preguntaré.

¿Alguien tiene experiencia en la lectura de un mensaje en un buzón de un remitente conocido?