Organizando o ciclo do pedido - página 8

 
Alexey Viktorov:

Será que eu fiz parecer tão complicado? O CD ganha dinheiro em spreads e comissões, o programador ganha dinheiro escrevendo código.

Um dos comerciantes diz que devemos economizar em spreads e comissões (não pagar tanto quanto possível).

O outro comerciante diz que não é justo escrever o código para o dinheiro (se possível, não pagar).

Ambos cuidam de sua própria carteira. Não parecem diferir um do outro...

Exceto que você, como programador, apóia o primeiro e discute com o segundo provando que ele está errado.

Entendo o comerciante que quer encontrar um programador mais barato. Também entendo o comerciante que está procurando melhores condições comerciais. Qual é o problema? O que há de errado em querer economizar dinheiro?

Mas aqui é uma história diferente. Pensar através de seu próprio algoritmo para fazê-lo funcionar mais efetivamente com os pedidos, e assim aumentar o lucro do sistema - significa ser um bom desenvolvedor. Na minha opinião, pode-se negligenciar vários pips somente na fase de teste rudimentar de uma idéia.

 
Andrey Khatimlianskii:

Eu entendo o comerciante que quer encontrar um programador mais barato. Também entendo o comerciante que está procurando melhores condições comerciais. Qual é o problema? O que há de errado em querer economizar dinheiro?

Mas aqui é uma história diferente. Pensar através de seu próprio algoritmo para fazê-lo funcionar mais efetivamente com os pedidos, e assim aumentar o lucro do sistema - significa ser um bom desenvolvedor. Acho que podemos negligenciar vários pips somente na fase de teste rudimentar de uma idéia.

Muito bem. E de alguma forma entendo sua relutância em escrever de graça mais. Também não há problema...

Em geral, não sou contra a tentativa de economizar dinheiro, mas não ao ponto de enlouquecer. Não se pode colocar a economia no spread à frente do comércio.

 
Alexey Viktorov:

Não me importo de tentar economizar dinheiro em geral, mas não ao ponto de ficar louco. Não se pode colocar a economia na propagação no centro do comércio.

Se você fizer as contas, não é tão louco assim. Mas eu não estou tentando convencer.

 
Andrey Khatimlianskii:

Se você fizer as contas, não é tão estúpido assim. Mas eu não estou tentando convencer.

Você tem que contar os lucros, não os custos.

Se você economiza custos, é muito fácil fazer perdas. Se o TS é projetado para suportar despesas, mas dá um lucro, então este é um bom TS, porque em um cenário diferente, ele pode ter um prejuízo.

Na verdade, os vencedores não são julgados!

 

Não é possível mover a página 7 para a página atual para um tópico separado (você poderia até fazer um link para ela como "Mais discussão aqui") e continuar o que ela foi criada para este tópico?

 
Vitaly Muzichenko:

Você tem que contar os lucros, não os custos.

Quando você economiza custos, é muito fácil incorrer em perdas. Se o TS é projetado para incorrer em despesas, mas ao mesmo tempo dá renda, então é um bom TS, porque em outro cenário, ele pode ter uma perda.

E em geral, os vencedores não são julgados!

Não entendo do que se trata este comentário.

Trata-se da falta de importância do tamanho da comissão para estratégias super lucrativas?

 
Vamos executar o seguinte Expert Advisor sobre o 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);
  }    
}


Vamos abrir 5 ordens EURUSD e 5 USDJPY ao acaso. Agora vamos dar uma olhada no código inócuo AmountOrders e imaginar o seguinte cenário

  1. Estamos em AmountOrders em tempo de execução onde i === 3.
  2. Fechamos uma posição em USDJPY. As ordens são então sacudidas na tabela de ordens atuais.
  3. Quando i === 2, podemos encontrar a mesma ordem que no ponto 1 através da OrderSelect. Por causa disso, a AmountOrders pode devolver um valor a mais do que realmente foi.


Aqui está uma confirmação do que dissemos

#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


O mesmo bilhete pode sair duas vezes em um inofensivo ciclo de contagem de pedidos!

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

O mesmo bilhete pode sair duas vezes em um inócuo ciclo de contagem de pedidos!

Para descansar todas as dúvidas, faça o seguinte.

Instale o Expert Advisor

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


Lançar o roteiro

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


E observamos que a EA seleciona as mesmas ordens sob índices diferentes. E isto pode levar ao completo fracasso da lógica comercial.

 
fxsaber:

a EA seleciona as mesmas ordens sob índices diferentes. E isto pode levar a uma quebra completa da lógica comercial.

Portanto, esta é a questão principal em sua totalidade! Como organizar o ciclo dos pedidos? Por exemplo, como escrever corretamente uma função desse 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);
}


Esta linha começou com a especificação da necessidade de algumas ações repetidas quando há uma pausa no ciclo de busca. Uma pausa de cerca de um milissegundo é suficiente aqui para ver o efeito.

Até agora, uma muleta assim.

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

Mas não há certeza de que sempre funcionará corretamente.

 
fxsaber:

Para descansar todas as dúvidas, faça o seguinte.

Instale o Expert Advisor

Execute o roteiro

E observamos que a EA seleciona as mesmas ordens sob índices diferentes. E isto pode levar ao completo fracasso da lógica comercial.

Eu mudei

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

Nós mudamos o roteiro sem alertas.

Razão: