Organizar el ciclo de pedidos - página 12

 
Artyom Trishkin:

- ¿Para qué necesitas una sartén?

- Por ejemplo, para freír huevos.

- no se trata de huevos revueltos, se trata de la sartén...


Ooh, eso es gracioso... dos asaltantes chocando... Sigue así. Es aburrido...

 
Artyom Trishkin:

- ¿Para qué necesitas una sartén?

- Como freír huevos, por ejemplo.

- Así que no estamos hablando de huevos revueltos, sino de una sartén...

¿Has visto eso? Ya creo que tú y yo estamos encerrados en una experiencia cercana a la muerte.

Me está dando un poco de pereza seguir con esta discusión. No puedo entender por qué cada milésima de segundo hay que repasar las órdenes. A menos que sea para freír un huevo...

 
Alexey Viktorov:

¿Has visto eso? Ya creo que tú y yo estamos encerrados en una experiencia cercana a la muerte.

Me está dando un poco de pereza esta discusión. No puedo entender por qué tenemos que revisar las órdenes cada milisegundo. A menos que quieras freír huevos con ellos...

Sip... lo tengo justo en el talón... :)
No digo que todas las veces. Pero a menudo, a tiempo para detectar un cambio en el entorno.
 
Bueno, yo no juego así... ...marchitado... decepcionado...
 

Foro sobre comercio, sistemas de comercio automatizados y prueba de estrategias de comercio

Organizar un bucle de pedidos

fxsaber, 2017.10.06 02:00

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

Versión sin referencia a la historia.

struct HISTORY_UNIT
{
  long Ticket;
  int Type;
  double Lots; 
    
  HISTORY_UNIT( void ) : Ticket(::OrderTicket()), Type(::OrderType()), Lots(::OrderLots())
  {
  }

  bool operator !=( const HISTORY_UNIT &Unit ) const
  {
    return((this.Ticket != Unit.Ticket) || (this.Type != Unit.Type) || (this.Lots != Unit.Lots));
  }
      
  bool IsChange( void )
  {
    const HISTORY_UNIT Tmp;
    const bool Res = (this != Tmp);
    
    if (Res)
      this = Tmp;
      
    return(Res);
  }
};

// Возвращает true только в случае, если с последнего вызова произошли торговые изменения
bool IsChange( void )
{
  static HISTORY_UNIT History[];  

  const int Total = OrdersTotal();  
  bool Res = (ArraySize(History) != Total);

  for (int i = 0, j = Res ? ArrayResize(History, 0, Total) : 0; i < Total; i++)      
    if (OrderSelect(i, SELECT_BY_POS))
    {
      if (Res || (Res = History[j].IsChange()))
        ArrayResize(History, j + 1, Total);
      
      j++;
    }
  
  return(Res);
}

Esta versión es especialmente relevante para MT5 en VPS, ya que MT5 trabaja con Historia muy lentamente y es computacionalmente caro.

 
fxsaber:

Versión sin referencia a la historia.

Esta versión es especialmente relevante para MT5 en VPS, ya que MT5 es muy lento y computacionalmente intensivo.


En este caso es mejor utilizar la función normal OnTrade().

OnTrade

Esta función es llamada en la ocurrencia del eventoTrade, que ocurre cuando se cambia la lista deórdenes colocadas yposiciones abiertas, elhistorial de órdenes y elhistorial de operaciones. Cuando se produce cualquier acción comercial (apertura de una orden pendiente, apertura/cierre de una posición, establecimiento de stops, activación de una orden pendiente, etc.) el historial de órdenes y operaciones y/o la lista de posiciones y órdenes actuales se modifican en consecuencia.

 
Sergey Chalyshev:

En ese caso, es mejor usar el OnTrade() normal.

No se puede, por desgracia. De esto se trata la rama.

 
Pocos discutirán esta afirmación

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Bichos, errores, preguntas

fxsaber, 2018.01.23 09:39

Después de que OrderSend haya fallado y OrderSend haya tenido éxito, el entorno comercial actual debe leerse completamente de nuevo. Esta regla debería aplicarse siempre.

Esta es una regla general. Pero poca gente piensa en su implementación en MT5. Por eso escribí una plantilla de TS más sencilla (en kodobase casi todas son así)

// Шаблон большинства ТС

#include <Trade/Trade.mqh>

// Сигнал на покупку
bool BuySignal( const string Symb ) { return(true); }

// Сигнал на продажу
bool SellSignal( const string Symb ) { return(false); }

// Находит позицию соответствующего типа
bool PositionsScan( const string Symb, const ENUM_POSITION_TYPE Type )
{
  for (int i = PositionsTotal() - 1; i >= 0; i--)
    if ((PositionGetSymbol(i) == Symb) && (PositionGetInteger(POSITION_TYPE) == Type))
      return(true);    
    
  return(false);  
}

// Торговое действие на сигнал
bool Action( const string Symb, const ENUM_POSITION_TYPE Type, const double Lots = 1 )
{
  static CTrade Trade;    
  bool Res = true;    
  
  // Закрыли противоположные сигналу позиции
  while ((PositionsScan(Symb, (ENUM_POSITION_TYPE)(1 - Type))) && (Res = Trade.PositionClose(PositionGetInteger(POSITION_TICKET))));

  // Открыли позицию по сигналу
  return(Res && !PositionsScan(Symb, Type) && (Type ? Trade.Sell(Lots, Symb) : Trade.Buy(Lots, Symb)));
}

// Шаблон торговой стратегии
void Strategy( const string Symb )
{
  if (BuySignal(Symb))
    Action(Symb, POSITION_TYPE_BUY);
  else if (SellSignal(Symb))
    Action(Symb, POSITION_TYPE_SELL);
}

void OnTick()
{
  Strategy(_Symbol);
}

Por alguna razón, algunas personas escriben más código para la misma TS. Pero en realidad este código lo hace igual de bien. La mayoría de los CTs sólo requieren escribir BuySignal y SellSignal. No se necesita nada más.

La plantilla de ejemplo está escrita específicamente con SB. Así que la pregunta a los expertos de MT5, ¿es el código correcto?

 
fxsaber:
Casi nadie discutiría esta afirmación

Esta es una regla universal. Pero no mucha gente piensa en su implementación en MT5. Por eso escribí una plantilla de TS más sencilla (en kodobase casi todas son así)

Por alguna razón, algunas personas escriben más código para la misma TS. Pero en realidad este código lo hace igual de bien. La mayoría de los CTs sólo requieren escribir BuySignal y SellSignal. No se necesita nada más.

La plantilla de ejemplo está escrita específicamente con SB. Así que la pregunta a los expertos de MT5, ¿es el código correcto?

Sobre esta declaración:

Después de un fallo de OrderSend y de un OrderSend exitoso, el entorno comercial actual debe ser leído completamente de nuevo. Esta regla debe aplicarse siempre.

¿Por qué hay que tirar de todo después de un fracaso? ¿Por qué debemos comprobar el historial de pedidos y posiciones? ¿También los pedidos y posiciones actuales? ¿No es suficiente con actualizar los precios y los datos necesarios para el momento actual?

 
Artyom Trishkin:

¿Por qué tirar todo después de una mala? ¿Por qué molestarse con el historial de órdenes y posiciones? ¿También los pedidos y posiciones actuales? ¿No es suficiente con actualizar los precios y los datos que necesitamos en este momento?

Si lo toma literalmente, puede leer el historial de ticks de cada símbolo en Market Watch. Pero creo que realmente entiendes el significado de la declaración.

El código implementa esa afirmación. Por eso tenía una pregunta para todos los que entienden de MT5: ¿el código es correcto?