Organiser le cycle de commande - page 8

 
Alexey Viktorov:

Est-ce que j'ai donné l'impression que c'était si compliqué ? Le DC gagne de l'argent sur les spreads et les commissions, le programmeur gagne de l'argent en écrivant du code.

L'un des traders dit que nous devrions économiser sur les spreads et les commissions (ne pas payer autant que possible).

L'autre commerçant dit qu'il n'est pas juste d'écrire le code pour l'argent (si possible, ne pas payer).

Ils prennent tous les deux soin de leur propre portefeuille. Ils ne semblent pas différer les uns des autres...

Sauf que vous, en tant que programmeur, soutenez le premier et argumentez le second en prouvant qu'il a tort.

Je comprends le commerçant qui veut trouver un programmeur moins cher. Je comprends également le trader qui recherche de meilleures conditions de trading. Quel est le problème ? Qu'y a-t-il de mal à vouloir économiser de l'argent ?

Mais ici, c'est une autre histoire. Réfléchir à son propre algorithme pour le faire fonctionner plus efficacement avec les ordres, et ainsi augmenter le bénéfice du système, c'est être un bon développeur. A mon avis, on ne peut négliger plusieurs pips qu'au stade du test grossier d'une idée.

 
Andrey Khatimlianskii:

Je comprends le commerçant qui veut trouver un programmeur moins cher. Je comprends également le trader qui recherche de meilleures conditions de trading. Quel est le problème ? Qu'y a-t-il de mal à vouloir économiser de l'argent ?

Mais ici, c'est une autre histoire. Réfléchir à son propre algorithme pour le faire fonctionner plus efficacement avec les ordres, et ainsi augmenter le bénéfice du système, c'est être un bon développeur. Je pense qu'on ne peut négliger plusieurs pips qu'au stade du test grossier d'une idée.

Bien. Et d'une certaine manière, je comprends votre réticence à écrire plus gratuitement. Pas de problème non plus...

En général, je ne suis pas contre le fait d'essayer d'économiser de l'argent, mais pas au point de devenir fou. Vous ne pouvez pas mettre les économies sur le spread à la tête de la négociation...

 
Alexey Viktorov:

Je veux bien essayer d'économiser de l'argent en général, mais pas au point d'en devenir fou. Vous ne pouvez pas mettre les économies sur le spread au centre du commerce...

Si vous faites le calcul, ce n'est pas si fou. Mais je n'essaie pas de convaincre.

 
Andrey Khatimlianskii:

Si vous faites le calcul, ce n'est pas si bête. Mais je n'essaie pas de convaincre.

Il faut compter les bénéfices, pas les coûts.

Si vous faites des économies, il est très facile de faire des pertes. Si le TS est conçu pour supporter des dépenses, mais qu'il dégage un bénéfice, alors c'est un bon TS, car dans un autre scénario, il peut générer une perte.

En fait, les gagnants ne sont pas jugés !

 

La page 7 de la page actuelle ne peut-elle pas être déplacée vers un sujet séparé (vous pourriez même y mettre un lien comme "Further discussion here") et continuer ce pour quoi elle a été créée dans ce fil ?

 
Vitaly Muzichenko:

Il faut compter les bénéfices, pas les coûts.

Lorsque vous faites des économies, il est très facile de faire des pertes. Si le TS est conçu pour encourir des dépenses, mais qu'en même temps il donne un revenu, alors c'est un bon TS, car dans un autre scénario, il peut faire une perte.

Et en général, les gagnants ne sont pas jugés !

Je ne comprends pas le sens de ce commentaire.

S'agit-il de la non-importance de la taille de la commission pour les stratégies super rentables ?

 
Exécutons le Conseiller Expert suivant sur le 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);
  }    
}


Ouvrons 5 ordres EURUSD et 5 ordres USDJPY au hasard. Maintenant, jetons un coup d'œil au code inoffensif de AmountOrders et imaginons le scénario suivant

  1. Nous sommes dans AmountOrders au moment de l'exécution où i == 3.
  2. Nous fermons une position sur USDJPY. Les commandes sont ensuite réparties dans le tableau des commandes en cours.
  3. Lorsque i == 2, nous pouvons rencontrer la même commande qu'au point 1 par le biais de OrderSelect. Pour cette raison, AmountOrders peut renvoyer une valeur de plus qu'elle ne l'était en réalité.


Voici une confirmation de ce que nous avons dit

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


Résultat

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


Le même billet peut sortir deux fois dans une boucle inoffensive de comptage des commandes !

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

Le même ticket peut sortir deux fois dans un cycle anodin de comptage des commandes !

Pour dissiper tous les doutes, procédez comme suit.

Installer le conseiller expert

// Советник будет алертовать, если 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 миллисекунда - это много или мало?
    }
}


Lancer le script

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


Et nous observons que l'EA sélectionne les mêmes ordres sous différents indices. Et cela peut conduire à l'échec complet de la logique commerciale.

 
fxsaber:

l'EA sélectionne les mêmes ordres sous différents indices. Et cela peut conduire à une rupture complète de la logique de négociation.

Voilà donc la question principale dans son intégralité ! Comment organiser la boucle des commandes ? Par exemple, comment écrire correctement une telle fonction ?

// Возращает количество ордеров данного символа
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);
}


Ce fil de discussion a commencé par préciser la nécessité de certaines actions répétées lorsqu'il y a une pause dans le cycle de recherche. Une pause d'environ une milliseconde est suffisante ici pour voir l'effet.

Jusqu'à présent, une telle béquille.

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

Mais il n'y a aucune certitude qu'il fonctionnera toujours correctement.

 
fxsaber:

Pour dissiper tous les doutes, procédez comme suit.

Installer le conseiller expert

Exécuter le script

Et nous observons que l'EA sélectionne les mêmes ordres sous différents indices. Et cela peut conduire à l'échec complet de la logique commerciale.

J'ai changé

// Советник будет алертовать, если 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 миллисекунда - это много или мало?
    }
}

Nous avons changé le scénario sans alertes.