Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 1920

 
MrBrooklin #:

Gracias por el consejo, Alexey! Primero esperaré una respuesta en este hilo, pero si no pasa nada, entonces pasaré al hilo de Errores, Bugs, Preguntas.

Sinceramente, Vladimir.

No obtendrás ninguna respuesta de los desarrolladores en este hilo. Si has encontrado un error, asegúrate de que es realmente un error, comunícalo a la rama que dirige Alexey. No hay que esperar que los moderadores actúen en esto, también somos humanos y a veces no tenemos tiempo.

 
Artyom Trishkin #:

Es poco probable que obtengas respuestas de los desarrolladores en este hilo. Si encuentras un error, asegúrate de que es realmente un error, infórmalo a la rama de Alexey. No hay que esperar acciones de los moderadores en esta ocasión, también somos personas y tampoco tenemos tiempo.

¡Hola Artem!

Todo está claro.

Sinceramente, Vladimir.

 

¡¡¡¡Buenas tardes!!!!

Aquí hay dos funciones para el asesor de la red la primera función es el cálculo de beneficios, teniendo en cuenta el cierre parcial de las órdenes perdedoras

//+----------------------------------------------------------------------------+
//| Калькуляция сетки ордеров                                                  |
//+----------------------------------------------------------------------------+
bool CalculiteProfit()
  {
   double oProfit=0,oLoss=0,percent;
   int i;
   nOrd=0;
   for(i = OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES) || OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic || OrderType()>OP_SELL)
         continue;
      if(OrderProfit()>=0)
         oProfit += OrderProfit();
      else
        {
         oLoss+=OrderProfit();
         Ord_ticket[nOrd]=OrderTicket();
         Ord_lot[nOrd]=OrderLots();
         nOrd++;
        }
     }
   oLoss = MathAbs(oLoss+GetOrderSwap()+GetOrderCommission());
   if(oLoss>0)
      percent=oProfit/oLoss*100;
   else
      percent=100;
   if(percent<MinPercentForClose) //MinPercentForClose переменная из настроек 
      return(false);
   for(i=0; i<nOrd; i++)
     {
      Ord_lot[i]=(MathCeil((Ord_lot[i]*RowLots)*percent)/100)/RowLots;
     }
   return(true);
  }

La segunda función es el cierre de órdenes con cierre parcial de órdenes perdedoras

//+----------------------------------------------------------------------------+
//| Закрытие сетки ордеров при заданной команде с учетом части ордеров         |
//+----------------------------------------------------------------------------+
void ClosseAll()
  {
   int i,j,tkt;

   for(i = OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES) || OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic)
         continue;
      tkt=OrderTicket();
      RefreshRates();
      if(OrderProfit()>=0)
        {
         if(OrderType() == OP_BUY)
           {
            if(!OrderClose(OrderTicket(), OrderLots(), Bid, slip))
               Print("Не удалось закрыть ордера на покупку!");
           }
         else
            if(OrderType() == OP_SELL)
              {
               if(!OrderClose(OrderTicket(), OrderLots(), Ask, slip))
                  Print("Не удалось закрыть ордер на продажу!");
              }
        }
      else
         for(j=0; j<nOrd; j++)
            if(tkt==Ord_ticket[j])
              {
               if(OrderLots()<Ord_lot[j])
                  Ord_lot[j]=OrderLots();
               Ord_lot[j]=NRL(Ord_lot[j]);
               if(OrderType() == OP_BUY)
                 {
                  if(!OrderClose(OrderTicket(), Ord_lot[j], Bid, slip))
                     Print("Не удалось закрыть ордера на покупку!");
                 }
               else
                  if(OrderType() == OP_SELL)
                    {
                     if(!OrderClose(OrderTicket(), Ord_lot[j], Ask, slip))
                        Print("Не удалось закрыть ордер на продажу!");
                    }
               break;
              }
     }
  }

La situación es la siguiente: si cierro una parrilla de órdenes teniendo en cuenta el cierre parcial de las órdenes perdedoras, obtengo una pérdida como resultado del redondeo hacia el lado mayor de algunos lotes que deben cerrarse

La pregunta es si se pueden utilizar estas dos funciones para escribir una función para calcular las órdenes perdidas, o más bien una parte de una orden que se va a cerrar.

Si es así, por favor ayúdame a escribirlo

Gracias

 
EVGENII SHELIPOV #:

¡¡¡¡Buenas tardes!!!!

Si es así, ayúdame a escribirlo.

No es un buen momento.

¿Te refieres a escribirlo para ti?

 
Andrey Sokolov #:

No son buenos tiempos.

¿Te refieres a escribir para ti?

No te destroces Alexander

 

perdido en lo elemental:

cómo organizo una pose de arrastre - codirigida, por alguna razón arrastra una pose, es decir, no arrastra... MT5

for (i=0; i<PositionsTotal(); i++)   
     if (a_position.Select(_Symbol))       
     if (PositionSelect(_Symbol)) if(Symbol()==PositionGetSymbol(i))  
     if (Magic==PositionGetInteger(POSITION_MAGIC))  
   //  magic = myposition.Magic();   
      {
         //  ------------   перевод в бу  BUY   ------------    
         //if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) 
         if (a_position.PositionType() == POSITION_TYPE_BUY)
          if (NLb_fun > 0)
            {
                Print(" перевод в безубыток BUY, _SL = ", _SL, " POSITION_PRICE_OPEN: ",
                     NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits),
                     " NLb_fun = ", NormalizeDouble(NLb_fun,_Digits));
               Modify = true;
 if(Modify)
              {
               Print(" серия рыночных позиций BUY назначена к переводу в безубыток, текущией позы POSITION_PRICE_OPEN = ",
               NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits)," тикет = ",PositionGetInteger(POSITION_TICKET));
                
               trade.PositionModify(_Symbol,SymbolInfoDouble(_Symbol, SYMBOL_BID) - 50*_Point,PositionGetDouble(POSITION_TP));
               Print(" Перенос в бу стоп лосса позиции Buy № ",  PositionGetInteger(POSITION_TICKET));
    ...
           } // к if(Modify)
        }    // к if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) 

...

puedo utilizar una simple sección de código como enumeración de posiciones para un arrastre con posiciones de mercado HEDGE - gracias.

¡el problema está resuelto! ¡¡¡Enhorabuena una vez más a Vladimir Karputov!!!

¡con su red de arrastre!

https://www.mql5.com/ru/code/17263

¡¡¡el truco clave es mirar el índice en el bucle y modificarlo con la opción ticket!!!

//--- при таком методе мы будет сюда попадать на каждом тике.
   for(int i=PositionsTotal()-1;i>=0;i--)
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==Symbol() && m_position.Magic()==m_magic)
           {
            //--- TrailingStop -> подтягивание StopLoss у ПРИБЫЛЬНОЙ позиции
            if(m_position.PositionType()==POSITION_TYPE_BUY)
              {
               //--- когда у позиции ещё нет StopLoss
               if(m_position.StopLoss()==0)
                 {
                  //--- пока StopLoss равен 0.0, TrailingStep не учитываем
                  if(m_symbol.Bid()-ExtTrailingStop>m_position.PriceOpen())
                    {
                     //--- модификация позиции
                     m_trade.PositionModify(m_position.Ticket(),m_position.PriceOpen(),0.0);
                    }
                 } 
TrailingStop
TrailingStop
  • www.mql5.com
Пример советника с реализацией Trailing Stop.
 

Una tarea sencilla: hay que eliminar todos los elementos de la matriz J que tengan el mismo índice y valor que los elementos de la matriz I:

int OnInit()
  {
   int CommonArray[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 13, 13};
   int ArrayI[20]=   {0, 0, 0, 0, 0, 0, 0, 8, 9, 10,  0, 12, 13, 13, 13, 13,  0,  0, 13,  0};
   int ArrayJ[];

   for(int j=0; j<ArraySize(ArrayI); j++)
   {
      ArrayResize(ArrayJ,j+1);
      ArrayJ[j]=CommonArray[j];
   }

   ArrayPrint(ArrayI);
   ArrayPrint(ArrayJ);

   for(int i=0; i<ArraySize(ArrayI); i++)
      if(ArrayI[i])
         for(int j=0; j<ArraySize(ArrayJ); j++)
            if(ArrayI[i]==ArrayJ[j])
               ArrayRemove(ArrayJ,j,1);

   ArrayPrint(ArrayJ);
//---
   return(INIT_SUCCEEDED);
  }

La cadena de claves está resaltada. Resultado:

2022.02.26 13:56:48.489 test (NZDUSD,H4)         0  0  0  0  0  0  0  8  9 10  0 12 13 13 13 13  0  0 13  0
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7  8  9 10 11 12 13 13 13 13 13 13 13 13
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7 11

Se espera:

2022.02.26 13:56:48.489 test (NZDUSD,H4)         0  0  0  0  0  0  0  8  9 10  0 12 13 13 13 13  0  0 13  0
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7  8  9 10 11 12 13 13 13 13 13 13 13 13
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7          11                13 13    13

ArrayJ es dinámico, parece que hay algo que no funciona... Pero tampoco necesito una estática.

Me ha roto la cabeza. ¿QUÉ PASA? ¿O es el equivalente a la vieja canción

https://www.mql5.com/ru/forum/1111/page3141#comment_27152680

и

https://www.mql5.com/ru/forum/1111/page3142#comment_27371998

sobre las constantes con nombre?

Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • 2022.01.28
  • www.mql5.com
Общее обсуждение: Ошибки, баги, вопросы
 
x572intraday los elementos de la matriz I:

La cadena de claves está resaltada. Resultado:

Se espera:

ArrayJ es dinámico, parece que hay algo que no funciona... Pero tampoco necesito una estática.

1. ArrayResize sería mejor moverlo fuera del bucle.

ArrayResize(ArrayJ,ArraySize(ArrayI));
for(int j=0; j<ArraySize(ArrayI); j++)
   {
      ArrayJ[j]=CommonArray[j];
   }

2. ArrayRemove no hace que un elemento del array esté "vacío", sino que "desplaza" los elementos siguientes a su lugar. Por lo tanto, la coincidencia de elementos en los índices posteriores se rompe.

 
JRandomTrader #:

1. ArrayResize debería salir del bucle

2. ArrayRemove no hace que un elemento del array esté "vacío", sino que "desplaza" los elementos posteriores en su lugar. Por lo tanto, la coincidencia de elementos en los índices posteriores se rompe.

No hay duda sobre la 2, sólo he puesto los intervalos para que quede más claro. Además, en Help dice sobre un array estático:"Si la función se utiliza para un array de tamaño fijo, el tamaño del array en sí no cambia: la "cola" restante se copia físicamente a la posición inicial."El ejemplo de la Ayuda también utiliza un array de tamaño fijo, y yo tengo uno dinámico.

Re 1. No podemos ponerlo fuera de un bucle, ya que en una tarea real no sabemos de antemano ni el tamaño de ArrayJ ni el de ArrayI, y mucho menos el de CommonArray, ya que no coinciden todos.

También tengo un ejemplo en el que el vertido de elementos no se rompe a medias, como en este ejemplo:

int OBJTFVArray[]={1, 2, 3, 4, 5, 6, 10, 12, 1520, 30, 16385, 16386, 16387, 16388, 16390, 16392, 16396, 16408, 32769, 49153, 49154, 49155, 49156, 49157, 49158, 49159, 49160};
int PArray[20]={0, 0, 0, 0, 0, 00, 16390, 16392, 163960, 32769, 49153, 49153, 49153, 49153, 0, 0, 49153, 0};
int PArray_[];

int OnInit()
  {
   for(int p_=0; p_<ArraySize(PArray); p_++)
   {
      ArrayResize(PArray_,p_+1);
      PArray_[p_]=OBJTFVArray[p_+8];
   }

   ArrayPrint(PArray);
   ArrayPrint(PArray_);

   for(int p=0; p<ArraySize(PArray); p++)
      if(PArray[p])
         for(int p_=0; p_<ArraySize(PArray_); p_++)
            if(PArray[p]==PArray_[p_])
               ArrayRemove(PArray_,p_,1);

   ArrayPrint(PArray_);

   return(INIT_SUCCEEDED);
  }

El resultado es bueno:

 0     0     0     0     0     0     0 16390 16392 16396     0 32769 49153 49153 49153 49153     0     0 49153     0
15    20    30 16385 16386 16387 16388 16390 16392 16396 16408 32769 49153 49154 49155 49156 49157 49158 49159 49160
15    20    30 16385 16386 16387 16388                   16408             49154 49155 49156 49157 49158 49159 49160

Pero necesitas esa variante para que funcione. Al parecer, el problema se produce si hay elementos con el mismo valor (véase el post anterior) en la cola de la derecha, lo que es similar al problema al que me refería más arriba.

 
x572intraday #:

No hay preguntas sobre la 2, pongo los intervalos para mayor claridad. Además, en la Ayuda dice sobre el array estático:"Si la función se utiliza para un array de tamaño fijo, el tamaño del propio array no cambia: copia físicamente la "cola" restante a la posición inicial."El ejemplo de la Ayuda también utiliza un array de tamaño fijo, y yo tengo uno dinámico.

Re 1. No podemos ponerlo fuera de un bucle, ya que en una tarea real no sabemos de antemano ni el tamaño de ArrayJ ni el de ArrayI, y mucho menos el de CommonArray, ya que no coinciden todos.

También tengo un ejemplo en el que el barajado de elementos no se interrumpe a mitad de camino, como en el ejemplo anterior:

El resultado es bueno:

Pero necesito que esa variante funcione. Al parecer, el problema se produce si hay elementos con el mismo valor en la cola de la derecha (véase el post anterior), lo que es similar al problema al que me refería antes.

1. Puedes y debes sacarlo del bucle, de la manera que he mostrado. A menos que el tamaño de ArrayI cambie a lo largo del bucle.

2. Entonces algo como esto

int k=0; // объявляем до цикла - чтобы использовать после
for(int i=0; i<ArraySize(ArrayI); i++) // после предыдущего кода (1) размеры ArrayI и ArrayJ равны
  if(ArrayI[i]!=ArrayJ[i])
    {
     ArrayJ[k++]=ArrayI[i];
    }
ArrayResize(ArrayJ,k);
Razón de la queja: