Organizar el ciclo de pedidos - página 8

 
Alexey Viktorov:

¿He hecho que suene tan complicado? El DC gana dinero con los diferenciales y las comisiones, el programador gana dinero escribiendo código.

Uno de los operadores dice que hay que ahorrar en spreads y comisiones (no pagar lo máximo posible).

El otro comerciante dice que no es justo escribir el código por el dinero (si es posible, no pagar).

Ambos se ocupan de su propia cartera. No parece que se diferencien entre sí...

Excepto que usted, como programador, apoya lo primero y discute lo segundo demostrando que está equivocado.

Entiendo al comerciante que quiere encontrar un programador más barato. También entiendo al comerciante que busca mejores condiciones de negociación. ¿Cuál es el problema? ¿Qué hay de malo en querer ahorrar dinero?

Pero aquí es una historia diferente. Pensar en su propio algoritmo para hacer que funcione más eficazmente con las órdenes, y así aumentar el beneficio del sistema, significa ser un buen desarrollador. En mi opinión, uno puede descuidar varios pips sólo en la etapa de prueba aproximada de una idea.

 
Andrey Khatimlianskii:

Entiendo que un comerciante quiera encontrar un programador más barato. También entiendo al comerciante que busca mejores condiciones de negociación. ¿Cuál es el problema? ¿Qué hay de malo en querer ahorrar dinero?

Pero aquí es una historia diferente. Pensar en su propio algoritmo para que funcione más eficazmente con las órdenes, y así aumentar el beneficio del sistema, significa ser un buen desarrollador. Creo que podemos descuidar varios pips sólo en la fase de prueba aproximada de una idea.

Bien. Y de alguna manera entiendo su reticencia a escribir gratis más. Tampoco hay problema...

En general, no estoy en contra de intentar ahorrar dinero, pero no hasta el punto de la locura. No puedes poner el ahorro en el diferencial a la cabeza del comercio...

 
Alexey Viktorov:

No me importa intentar ahorrar dinero en general, pero no hasta el punto de volverse loco. No se puede poner el ahorro en el diferencial en el centro del comercio...

Si haces las cuentas, no es tan descabellado. Pero no trato de convencer.

 
Andrey Khatimlianskii:

Si haces las cuentas, no es tan descabellado. Pero no trato de convencer.

Hay que contar los beneficios, no los costes.

Si se ahorran costes, es muy fácil tener pérdidas. Si la ST está diseñada para soportar gastos, pero da beneficios, entonces es una buena ST, porque en un escenario diferente, puede dar pérdidas.

De hecho, ¡no se juzga a los ganadores!

 

¿No se puede trasladar la página 7 a la página actual a un tema aparte (incluso se podría enlazar a él como "Más discusión aquí") y continuar para lo que se creó en este hilo?

 
Vitaly Muzichenko:

Hay que contar los beneficios, no los costes.

Cuando se ahorran costes, es muy fácil incurrir en pérdidas. Si la ST está diseñada para incurrir en gastos, pero al mismo tiempo da ingresos, entonces es una buena ST, porque en otro escenario, puede dar pérdidas.

Y en general, ¡los ganadores no son juzgados!

No entiendo a qué viene este comentario.

¿Se trata de la poca importancia del tamaño de la comisión para las estrategias súper rentables?

 
Vamos a ejecutar el siguiente Asesor Experto en la MT4 EURUSD
// В случае изменения количества ордеров по основному символу, сигнализирует об их количестве

// #include <MT4Orders.mqh>

const bool Init =  EventSetMillisecondTimer(1);

int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}

void OnTimer()
{
  static int PrevAmount = 0;
  
  const int Amount = AmountOrders(_Symbol);
  
  if (Amount != PrevAmount)
  {
    PrevAmount = Amount;
    
    Alert(Amount);
  }    
}


Abramos 5 órdenes EURUSD y 5 USDJPY al azar. Ahora echemos un vistazo al código inocuo de AmountOrders e imaginemos el siguiente escenario

  1. Estamos en AmountOrders en tiempo de ejecución donde i == 3.
  2. Cerramos una posición en el USDJPY. A continuación, los pedidos se agitan en la tabla de pedidos actuales.
  3. Cuando i == 2, podemos encontrar el mismo orden que en el punto 1 a través de OrderSelect. Debido a esto, AmountOrders puede devolver un valor más de lo que realmente era.


Aquí se confirma lo que hemos dicho

#property strict

void OnStart()
{
  for (int i = 0; i < 5; i++)
    OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, 0);
    
  int PrevTicket = 0;
  
  for (int i = OrdersTotal() - 1; i > 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      if (OrderSelect(i - 1, SELECT_BY_POS))      
        OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
    }
}


Resultado

2017.10.06 01:28:05.885 TestTets EURUSD,M1: close #240725107  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.775 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.775 TestTets EURUSD,M1: close #240725108  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.673 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.673 TestTets EURUSD,M1: close #240725110  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.578 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.578 TestTets EURUSD,M1: close #240725111  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.480 TestTets EURUSD,M1: open #240725112  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.343 TestTets EURUSD,M1: open #240725111  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.253 TestTets EURUSD,M1: open #240725110  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.138 TestTets EURUSD,M1: open #240725108  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.035 TestTets EURUSD,M1: open #240725107  buy 1.00 EURUSD at 1.17121 ok


El mismo billete puede salir dos veces en un bucle inofensivo de recuento de pedidos.

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
 
fxsaber:

El mismo billete puede salir dos veces en un ciclo inocuo de recuento de pedidos.

Para despejar todas las dudas, haz lo siguiente.

Instalar el Asesor Experto

// Советник будет алертовать, если OrderSelect соседних индексов выберет один и тот же ордер
const bool Init =  EventSetMillisecondTimer(1);

void OnTimer()
{
  int PrevTicket = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      Sleep(1); // 1 миллисекунда - это много или мало?
    }
}


Iniciar la secuencia de comandos

#property strict

void OnStart()
{
  // Открыли позиции
  for (int i = 0; i < 25; i++)
    OrderSend(_Symbol, OP_BUY, 1, SymbolInfoDouble(_Symbol, SYMBOL_ASK), 100, 0, 0);

  int Tickets[];
  const int Total = OrdersTotal();
  
  ArrayResize(Tickets, Total);
  
  for (int i = 0; i < Total; i++)
    if (OrderSelect(i, SELECT_BY_POS))
      Tickets[i] = OrderTicket();
    
  // Закрыли позиции
  for (int i = 0; i < Total; i++)
    OrderClose(Tickets[i], 1, SymbolInfoDouble(_Symbol, SYMBOL_BID), 100);
}


Y observamos que el EA selecciona las mismas órdenes bajo diferentes índices. Y esto puede llevar al fracaso total de la lógica comercial.

 
fxsaber:

el EA selecciona las mismas órdenes bajo diferentes índices. Y esto puede llevar a una ruptura total de la lógica comercial.

Así que, ¡este es el tema principal en su totalidad! ¿Cómo se organiza el bucle de pedidos? Por ejemplo, ¿cómo escribir correctamente una función de este tipo?

// Возращает количество ордеров данного символа
int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}


Este hilo comenzó con la especificación de la necesidad de algunas acciones repetidas cuando hay una pausa en el ciclo de búsqueda. Aquí basta con una pausa de aproximadamente un milisegundo para ver el efecto.

Hasta ahora es una muleta.

bool IsChange( const bool InitFlag = false )
{
  static int PrevTotal = 0;
  static int PrevHistoryTotal = 0;
  
  const int Total = OrdersTotal();
  const int HistoryTotal = OrdersHistoryTotal();    
  
  if (InitFlag)
  {
    PrevTotal = Total;
    PrevHistoryTotal = HistoryTotal;    
  }
  
  return(!InitFlag && ((Total != PrevTotal) || (HistoryTotal != PrevHistoryTotal)));
}

// Возращает количество ордеров данного символа
int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  IsChange(true);
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (IsChange())
    {
      i = OrdersTotal();
      
      Res = 0;
    }
    else if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}

Pero no hay certeza de que siempre funcione correctamente.

 
fxsaber:

Para despejar todas las dudas, haz lo siguiente.

Instalar el Asesor Experto

Ejecutar el script

Y observamos que el EA selecciona las mismas órdenes bajo diferentes índices. Y esto puede llevar al fracaso total de la lógica comercial.

He cambiado

// Советник будет алертовать, если OrderSelect соседних индексов выберет один и тот же ордер
const bool Init =  EventSetMillisecondTimer(1);

bool IsChange( const bool InitFlag = false )
{
  static int PrevTotal = 0;
  static int PrevHistoryTotal = 0;
  
  const int Total = OrdersTotal();
  const int HistoryTotal = OrdersHistoryTotal();    
  
  if (InitFlag)
  {
    PrevTotal = Total;
    PrevHistoryTotal = HistoryTotal;    
  }
  
  return(!InitFlag && ((Total != PrevTotal) || (HistoryTotal != PrevHistoryTotal)));
}

void OnTimer()
{
  int PrevTicket = 0;
  
  IsChange(true);
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (IsChange())
    {
      i = OrdersTotal();
      
      PrevTicket = 0;
    }
    
    else if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      Sleep(1); // 1 миллисекунда - это много или мало?
    }
}

Hemos cambiado el guión sin alertas.

Razón de la queja: