Organiser le cycle de commande - page 12

 
Artyom Trishkin:

- A quoi sert une poêle à frire ?

- Par exemple, pour faire frire des œufs.

- il ne s'agit pas d'oeufs brouillés, il s'agit de la poêle à frire...


Ooh - drôle - deux attaquants qui s'affrontent... Continue. C'est ennuyeux...

 
Artyom Trishkin:

- A quoi sert une poêle à frire ?

- Comme les œufs au plat, par exemple.

- Donc on ne parle pas d'oeufs brouillés, on parle d'une poêle à frire...

Tu as vu ça ? Je pense déjà que toi et moi sommes enfermés dans une expérience de mort imminente.

Je deviens un peu paresseux pour continuer cette discussion. Je ne comprends pas pourquoi, à chaque milliseconde, il faut passer par les commandes. Sauf si c'est pour faire frire un oeuf...

 
Alexey Viktorov:

Tu as vu ça ? Je pense déjà que toi et moi sommes enfermés dans une expérience de mort imminente.

Je deviens un peu paresseux avec cette discussion. Je ne comprends pas pourquoi nous devons passer les commandes à chaque milliseconde. Sauf si vous voulez faire des œufs au plat avec...

Oui... c'est bien dans le talon... :)
Je ne dis pas à chaque fois. Mais souvent, à temps pour détecter un changement dans l'environnement.
 
Je ne joue pas comme ça... ...sont secs... déçu...
 

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

Organiser une boucle de commande

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

Version sans référence à l'histoire.

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

Cette version est particulièrement pertinente pour MT5 sur VPS, car MT5 travaille avec l'historique très lentement et est coûteux en calcul.

 
fxsaber:

Version sans référence à l'historique.

Cette version est particulièrement pertinente pour MT5 sur VPS, car MT5 est très lent et gourmand en ressources CPU.


Dans ce cas, il est préférable d'utiliser la fonction OnTrade() normale.

OnTrade

Cette fonction est appelée lorsqu'un événementTrade se produit, ce qui modifie la liste desordres placés et despositions ouvertes, l'historique des ordres et l'historique des transactions. Lors de toute action commerciale (ouverture d'un ordre en attente, ouverture/fermeture d'une position, mise en place de stops, déclenchement d'un ordre en attente, etc.), l'historique des ordres et des transactions et/ou la liste des positions et des ordres en cours sont modifiés en conséquence.

 
Sergey Chalyshev:

Dans ce cas, il est préférable d'utiliser la fonction normale OnTrade().

Vous ne pouvez pas, malheureusement. C'est le but de la branche.

 
Peu de gens contesteront cette affirmation

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

Bugs, bugs, questions

fxsaber, 2018.01.23 09:39

Après l'échec d'un OrderSend et la réussite d'un OrderSend, l'environnement commercial actuel doit être relu entièrement. Cette règle devrait toujours s'appliquer.

C'est une règle universelle. Mais peu de gens pensent à sa mise en œuvre dans MT5. C'est pourquoi j'ai écrit un modèle des TS les plus simples (dans kodobase presque tous sont comme ça)

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

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

Pour une raison quelconque, certaines personnes écrivent plus de code pour le même TS. Mais en fait, ce code fait tout aussi bien l'affaire. La plupart des CT ne nécessitent que l'écriture de BuySignal et SellSignal. Rien d'autre n'est nécessaire.

L'exemple de modèle est spécifiquement écrit avec SB. Alors question aux experts MT5, le code est-il correct ?

 
fxsaber:
Presque personne ne conteste cette affirmation

C'est une règle universelle. Mais peu de gens pensent à sa mise en œuvre dans MT5. C'est pourquoi j'ai écrit un modèle des TS les plus simples (dans kodobase presque tous sont comme ça)

Pour une raison quelconque, certaines personnes écrivent plus de code pour le même TS. Mais en fait, ce code fait tout aussi bien l'affaire. La plupart des CT ne nécessitent que l'écriture de BuySignal et SellSignal. Rien d'autre n'est nécessaire.

L'exemple de modèle est spécifiquement écrit avec SB. Alors question aux experts MT5, le code est-il correct ?

Sur cette déclaration :

Après un échec d' un OrderSend et un OrderSend réussi, l'environnement commercial actuel doit être relu complètement. Cette règle doit toujours être appliquée.

Pourquoi devrions-nous tout retirer après un échec ? Pourquoi devrions-nous vérifier l'historique des commandes et des positions ? Les commandes et les positions actuelles aussi ? Il ne suffit pas de mettre à jour les prix et les données nécessaires pour le moment actuel ?

 
Artyom Trishkin:

Pourquoi tout retirer après un mauvais coup ? Pourquoi s'embêter avec l'histoire des ordres et des positions ? Les commandes et les positions actuelles aussi ? N'est-il pas suffisant de mettre à jour les prix et les données dont nous avons besoin sur le moment ?

Si vous le prenez au pied de la lettre, vous pouvez lire l'historique des tics pour chaque symbole à partir de Market Watch. Mais je pense que vous comprenez en fait le sens de la déclaration.

Le code implémente en quelque sorte cette déclaration. C'est pourquoi j'avais une question pour tous ceux qui comprennent MT5 : le code est-il correct ?