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

 
PolarSeaman:

Qué giro!)))

Orden 1 (de# no, a#2) -- > Orden2 (de#1, a#3) -- >Orden3 (de#2, a# no)

A partir de esto se puede encontrar toda la cadena.

Miramos el comentario abierto y si hay de#XXX, significa que antes estaba parcialmente cerrado - busque el ticket XXX del comentario y búsquelo en el historial. Mire allí el comentario - si hay de#YYY - significa que fue parcialmente cerrado antes también - busque el ticket YYY del comentario y búsquelo en el historial. Mira el comentario - si hay de#ZZZZ - significa que fue parcialmente cerrado antes también - repetir la búsqueda. Si no hay desde#..., entonces es el primero de toda la cadena.

 
Artyom Trishkin:

Orden 1 (de# no, a#2) -- > Orden2 (de#1, a#3) -- > Orden3 (de#2, a# no)

A partir de esto se puede encontrar toda la cadena.

Miramos el comentario abierto y si hay de#XXX, significa que antes se cerró parcialmente - busque el ticket XXX del comentario y búsquelo en el historial. Mire allí el comentario - si hay de#YYY - significa que fue parcialmente cerrado antes también - busque el ticket YYY del comentario y búsquelo en el historial. Mira el comentario - si hay de#ZZZZ - significa que fue parcialmente cerrado antes también - repetir la búsqueda. Si no hay desde#..., entonces es el primero de toda la cadena.

Gracias, puede haber una orden en sentido contrario, que también picaré. Tengo miedo de confundirme. Creo que sería más fácil utilizar la orden Profit de una fecha determinada, por supuesto, si somos capaces de averiguar cuándo se abrió la posición, porque la fecha cambia cuando la posición se cierra parcialmente

 
Artyom Trishkin:

Orden 1 (de# no, a#2) -- > Orden2 (de#1, a#3) -- > Orden3 (de#2, a# no)

A partir de esto se puede encontrar toda la cadena.

Mira el comentario abierto y si hay de#XXX, significa que fue parcialmente cerrado antes - busca el ticket XXX del comentario y búscalo en el historial. Vea el comentario allí - si hay de#YYY - así que fue parcialmente cerrado antes también - vea el ticket YYY del comentario y búsquelo en la historia. Mira el comentario - si hay de#ZZZZ - significa que fue parcialmente cerrado antes también - repetir la búsqueda. Si no hay desde#..., entonces es el primero de toda la cadena.

Artem sabes que no siempre es así. Y para no trazar una cadena no interrogar el terminal tres veces - la historia todo lo mismo se maneja en matrices y estructuras propias. No es diferente de mantener su propia base de datos, excepto por los pasos adicionales

El terminal y su API es el nivel más bajo posible. Y para aplicar la lógica del robot, es lógico hacer la contabilidad en sus términos (comercio, cadena, grupo, transacción - cada uno lo llama de manera diferente). Lo sensato es mantenerlo separado y no intentar reconstruirlo a cada estornudo (garrapata/barra).

 
Maxim Kuznetsov:

Sabes que no siempre es así, Artyom. Y así no hay que preguntarle al terminal tres veces cuando se rastrea la cadena - la historia se sigue manejando en sus propias matrices y estructuras. No es diferente de mantener su propia base de datos, excepto por los pasos adicionales

El terminal y su API es el nivel más bajo posible. Y para la realización de la lógica del robot, es lógico llevar las cuentas en sus términos (comercio, cadena, grupo, transacción - cada uno lo llama de manera diferente). Lo más sensato es mantenerlo separado y no intentar reconstruirlo a cada estornudo (garrapata/barra).

Lo tengo todo hecho desde hace mucho tiempo - no leo el historial cada vez - pero siempre está actualizado, y puedo encontrar fácilmente y muy rápidamente todo lo que necesito allí. Pero para aconsejar a alguien que haga lo mismo, necesito al menos un par de artículos. Y así he escrito la lógica de encontrar toda la cadena.

 
PolarSeaman:

Gracias, es posible que haya una orden en sentido contrario que también desmenuzaré. Tengo miedo de confundirme. Creo que sería más fácil utilizar la función Profit para cerrar una posición a partir de una fecha determinada, por supuesto si se puede saber cuándo se abrió la posición, porque en un cierre parcial la fecha cambia

Para buscar una cadena, basta con conocer el ticket de la orden, toda la cadena de la que se quiere saber - pasar el ticket como parámetro a la función de búsqueda, y la salida - un array o matriz de estructuras rellena con todos los datos de cada orden de la cadena completa.

 
Artyom Trishkin:

Un array lleno o un array de estructuras con todos los datos de cada orden de toda la cadena.

Ni siquiera sé aproximadamente lo que acabas de decir.

Al menos muéstrame un ejemplo de cómo debería ser.

 
PolarSeaman:

Ni siquiera sé aproximadamente lo que acabas de decir.

Al menos dame un ejemplo de cómo debería ser.

Resuelvo el problema de la siguiente manera: busco cadenas por historia. Pues bien, para que la historia esté disponible de forma inequívoca, utilizo dos variantes:

  1. Si no hay DLL, entonces en la descripción del programa en 24 negritas )))) especifico que el historial de cuentas siempre debe ser cargado en su totalidad (pestaña de Historial de Cuentas de la ventana de Terminal, menú contextual - Todo el Historial).
  2. Con DLL - Expert Advisor mantiene actualizada la pestaña "Historial de la cuenta", independientemente de cualquier acción del usuario.

Funciones para determinar el orden principal, si el orden actual no es el principal:

int GetSignOfPartialOrCloseByClose()
{
   string comment = OrderComment();
   if (comment == "")
      return 0;
   
   // Ордер образовался вследствии частичного закрытия
   int fromStart = StringFind(comment, "from #");
   if (fromStart >= 0)
      return GetTicketByPartialClose(comment, fromStart, OrderType(), OrderOpenTime());
   
   // Ордер образовался вследствии встречного закрытия
   if (StringFind(comment, "partial close") >= 0)
   {
      datetime openTime = OrderOpenTime();
      int type = OrderType();
      for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
      {
         if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
            continue;
            
         if (OrderOpenTime() != openTime)
            continue;
            
         if (OrderType() != type)
            continue;
            
         if (StringFind(OrderComment(), "partial close") < 0)
            continue;
            
         return OrderTicket();
      }
   }
   
   return 0;
}


int GetTicketByPartialClose(string comment, int fromStart, int orderType, datetime openTime)
{
   string sTicket = StringSubstr(comment, fromStart + 6);
   int iTicket = (int)StringToInteger(sTicket);
   int type = OrderType();
   if (!OrderSelect(iTicket, SELECT_BY_TICKET))
      return 0;
      
   if (OrderType() == type)                                                                        // Дочерний ордер указывает на родителя - уходим
      return iTicket;
      
   // Дочерний ордер указывает на противоположный ордер. Необходимо искать родительский
   for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
         continue;
         
      if (OrderType() != orderType || OrderOpenTime() != openTime)
         continue;
         
      int iFind = StringFind(OrderComment(), "close hedge by #");
      if (iFind < 0)
         continue;
         
      sTicket = StringSubstr(OrderComment(), iFind + 16);
      int iNewTicket = (int)StringToInteger(sTicket);
      if (iNewTicket != iTicket)
         continue;
         
      return OrderTicket();
   }
   
   return 0;
}

Fácil de usar:

   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS))
         continue;

      ....         

      int nFromTicket = GetSignOfPartialOrCloseByClose();                // Обязательно последней строкой в теле цикла, т. к. может измениться текущий выбранный ордер
   }


 
Ihor Herasko:

El error más grave aquí es especificar el valor 100 en lugar de ticket en el argumento OrderDelete().

El siguiente error no es tan grave, pero está relacionado con el hecho de que se comprueba el valor calculado del Stop Loss, y no su valor real.

Tampoco se comprueba el tipo de pedido. ¿Y si hemos elegido una orden de mercado? ¿Cómo borrarlo? No se ha comprobado el símbolo de la orden.

Teniendo en cuenta estos errores, obtenemos el código de borrar la orden pendiente cuando el precio alcanza su Stop Loss:

Además, en su código, el Stop Loss se comprueba inmediatamente después de la apertura de la orden. Parece que después de abrir una orden pendiente, este código ya no se ejecuta. Es decir, hay que separar las ramas de ejecución. Uno se encarga de establecer el orden y el segundo de acompañarlo.

Gracias por su detallada respuesta.

Siguiendo tus consejos, he separado las ramas y todo funciona.

Entonces me he enfrentado con el problema de la apertura simultánea de 10-15 órdenes pendientes, he resuelto este problema mediante la adición después de su código:

if (OrdersTotal ()>0) return;

Estoy seguro de que hay una forma mejor.

Con su código, ¿podría explicar qué significa 1; i >=0; --i?

for (int i = OrdersTotal() - 1; i >= 0; --i)
 

Por favor, ayúdenme a entender cómo escribir un indicador. ¿Cómo hacer que la longitud del indicador se dibuje en puntos de tamaño por encima de la oferta actual, a partir del momento en que el indicador se coloca en el gráfico? ¿Tal vez el error es que estoy desplazando esta matriz en la dirección equivocada?

Sé que es "canónico", sin ningún prev_calculado, etc., pero lo necesito así


#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot 
#property indicator_label1  "myInd"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Blue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

double buff[], Bid;
input int lenght = 50, size = 5;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping

   ArrayResize(buff, 50);
   ArrayInitialize(buff, 0);
   SetIndexBuffer(0, buff, INDICATOR_DATA);
   //--- установим метку для отображения в DataWindow
   PlotIndexSetString(0,PLOT_LABEL,"myInd");   
//--- установим имя для показа в отдельном подокне и во всплывающей подсказке
   IndicatorSetString(INDICATOR_SHORTNAME,"myInd");
//--- укажем точность отображения значений индикатора
   IndicatorSetInteger(INDICATOR_DIGITS, _Point);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   for(int i = lenght-1; i>0; i--){
      buff[i] = buff[i-1];
   }
   buff[0] = Bid+size;
   


   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Roman Sharanov:

Por favor, ayúdenme a entender cómo escribir un indicador. ¿Cómo hacer que la longitud del indicador se dibuje en puntos de tamaño por encima de la oferta actual, a partir del momento en que el indicador se coloca en el gráfico? ¿Tal vez el error es que estoy desplazando esta matriz en la dirección equivocada?

Sé que es "canónico", sin prev_calculado y cosas así.


¿Cuál es el canon? Hay un documento oficial - es exactamente como el tuyo.

1. debe establecer la serialización de todas las matrices utilizadas dentro de OnCalculate.

2. Antes de entrar en el bucle, pon buff[length]=Bid+size; - obtendrás aproximadamente lo que quieres. Una línea curva y al final una "visera" en Bid+size

3. Observa los límites del array. Por supuesto, rates_total apenas es < length, pero no te puedes equivocar :-)

4.
buff[i] = buff[i+1]; // если тайм-серия (а вы подразумеваете их) то +
Razón de la queja: