Perguntas de Iniciantes MQL4 MT4 MetaTrader 4 - página 247

 
Valeriy Yastremskiy #:

Insira o código corretamente, alt S ou por ícone, código de dica.

Por que você precisa de uma sérieSaveTick?

Você usa apenas 2 elementos da matriz. Substitua-os por variáveis globais ou estáticas se você as declarar em uma função.

Não é sensato usar uma matriz para 2 variáveis.

E você parece chamar arrays antes que a funçãoFindTick() seja chamada, onde o tamanho da matriz SaveTick é definido. E há um excesso da matriz.

Obrigado. Entendi.
Você pode me dizer qual é o erro, parece-me que a função não está contando corretamente


***
 
makssub #:

Obrigado. Entendi.
Você pode me dizer qual é o erro, parece-me que a função não está contando corretamente


Insira o código corretamente, é a 13ª caixa no topo da janela de resposta.

E você pode escrever em palavras o que a função faz linha por linha.

Certamente não parece correto.

Eu não entendo onde e como a variável Tick é atribuída ao bilhete de pedido. E não há necessidade de verificar o número mágico e o tipo de ordem de acordo com a seguinte condição
_magic < 0 || OrderMagicNumber() == _magic
Se a função for chamada com um número mágico menor que zero ou o número mágico for igual ao número da ordem selecionada, solicitaremos o tamanho do ponto e se for igual a zero, procuraremos um valor vazio no símbolo da ordem... e assim por diante.

Ah, e lembre-se, a seleção do pedido preenche a estrutura de dados do pedido e a armazena. E somente após o próximo pedido selecionar com um número de pedido ou bilhete diferente é que os dados nesta estrutura mudarão.

Isto é, OrderSend não preenche a estrutura de dados do pedido, mas devolve o ticket de pedido ou menos 1. E a estrutura do pedido só é preenchida pela OrderSelect. E então os dados desta ordem podem ser obtidos a partir desta estrutura.

 
Valeriy Yastremskiy #:

Insira o código corretamente, é a 13ª caixa na parte superior da janela de resposta.

E você pode escrever em palavras o que a função faz linha por linha.

Parece estar errado, é claro.

E não está claro onde e como a variável Tick é atribuída ao bilhete de pedido. E não há necessidade de verificar o número mágico e o tipo de ordem pela seguinte condição
_magic < 0 || OrderMagicNumber() == _magic
Se a função for chamada com um número mágico menor que zero ou se o número mágico for igual à ordem selecionada, solicitaremos o tamanho do ponto e se for igual a zero procuraremos um valor vazio no símbolo da ordem... e assim por diante.

Ah, e lembre-se, a seleção do pedido preenche a estrutura de dados do pedido e a armazena. E somente após o próximo pedido selecionar com um número de pedido ou bilhete diferente é que os dados nesta estrutura mudarão.

Isto é, OrderSend não preenche a estrutura de dados do pedido, mas devolve o ticket de pedido ou menos 1. E a estrutura do pedido só é preenchida pela OrderSelect. E então a partir desta estrutura podemos obter os dados desta encomenda.

int FindTicket()
   {
   int oldticket;
   int tick=0;
   ticket=0;
   
   
   for(int cnt = OrdersTotal ()-1; cnt>=0; cnt--)
      {
      if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
         {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
            {
            oldticket = OrderTicket();
            if (oldticket > ticket)
               {
               ticket = oldticket;
               tick = OrderTicket();
               }
            }
         }
      }
   return(tick); 
   }              
int TickF = FindTicket();
int CalculateProfitHistory() 
{
  double _point;
  int    i, _ototal = OrdersHistoryTotal(), _profit=0;
  for   (i = 0; i < OrdersHistoryTotal(); i++) 
  {
    if (OrderSelect(TickF, SELECT_BY_TICKET, MODE_HISTORY)) 
    {
      if (OrderSymbol() == Symbol())
      {
        if (OrderMagicNumber() == Magic) 
        {
           _point = MarketInfo(OrderSymbol(), MODE_POINT);
           if (_point == 0) 
           {
              if (StringFind(OrderSymbol(), "") < 0) 
                 _point = 0.0001; 
              else _point = 0.01;
           }   
           if (OrderType() == OP_BUY) 
           {
              _profit += int((MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice())/_point);
           }
           if (OrderType()==OP_SELL) 
           {
              _profit += int((OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK))/_point);
           }
         }
      }
    }
  }
  return(_profit);
}

Na primeira função, encontramos o ticket de pedido requerido e a segunda função deve calcular o lucro de todos os pedidos fechados após aquele ticket. O lucro daqueles pedidos que eram antes não tem interesse para mim. Mas o segundo não o calcula corretamente. Quando uma ordem é aberta, estas 2 funções são chamadas e, portanto, deve ser igual a 0, mas não é.
O PS seguiu seu conselho, desistiu de arrays)
12ª caixa acima)

 
makssub #:

Na primeira função, eu encontro o ticket da ordem requerida, e a segunda função deve calcular o lucro de todas as ordens fechadas após este ticket. Não estou interessado no lucro dos que o precederam.
PS seguiu seu conselho, eu recusei arrays)
a 12ª praça de cima)

A primeira função encontra o bilhete com o número mais alto, se os bilhetes aumentam com números)))) Na próxima iteração do loop, o bilhete do próximo pedido com o maior número é comparado com o bilhete do pedido anterior. A seleção do pedido preenche a estrutura do pedido, e OrderTicket recupera o valor do bilhete a partir desta estrutura.

Escreva ou leia por si mesmo o que cada linha de código faz.

Na segunda função, OrderSelect preencherá a estrutura do pedido com os mesmos dados do bilhete)

 
Valeriy Yastremskiy #:

A primeira função encontra o bilhete com o número mais alto, se os bilhetes aumentam com números)))) Na próxima iteração do loop, o bilhete da próxima ordem numerada mais alta é comparado com o bilhete da ordem anterior. A seleção do pedido preenche a estrutura do pedido, e OrderTicket recupera o valor do bilhete a partir desta estrutura.

Escreva ou leia por si mesmo o que cada linha de código faz.

Na segunda função, OrderSelect preencherá a estrutura do pedido com os mesmos dados do bilhete)

Escrito, mas parece ser ruim com lógica em relação a esta linguagem. Você pode me dizer como determinar o bilhete do último pedido aberto?

Como posso calcular o lucro de todos os pedidos fechados que se seguem a ele?

 
makssub #:

Escrito, mas parece ser ruim com a lógica em relação a esta linguagem. Você pode me dizer como determinar o bilhete do último pedido aberto?

Como posso calcular o lucro de todos os pedidos fechados que se seguem a ele?

No momento da abertura de um pedido. Deve ser o maior.) E não devemos usar o número do pedido. Ou temos que armazenar em nossa base os números de pedidos, os bilhetes, o estado dos pedidos e o tempo de abertura/fechamento.

 if(OrderSelect(Ticket, SELECT_BY_TICKET)==true) // Если выбор рыночного ордера произошел успешно
        {
         if(OrderCloseTime()==0)              // Если наш рыночный ордер не закрыт           {
            
            //           Alert("Наш рыночный ордер жив, Модифицируем его если нужно ");
            if(Tral_Stop!=0 || Tral_Profit!=0)
          {     ModifyTral(); }
            return;
           }
         if(OrderCloseTime()!=0)              // Если наш рыночный ордер закрылся
         {
Alert("Our market order has closed. The Adviser's work is completed ",
                  " Swap = ", OrderSwap(), " Commission = ", OrderCommission(),"Profit/loss = ",OrderProfit());
         // ..... // получаем профит и считаем общий профит например
         }

E é melhor lembrar a lógica até o fim. É mais fácil então. É melhor começar com os dados necessários, e deve haver dados suficientes para uma decisão)

Temos tempo aberto de pedidos (não pendentes). Temos suas passagens. Temos um preço aberto, SL e TP de cada ordem de mercado. E há um tempo de fechamento do pedido. E depois que o pedido é fechado, o campo Lucro é preenchido.

Estes são os dados de que precisamos para criar a lógica a partir destes campos.

A frase "ordens fechadas após a última ordem aberta" não está definida de forma alguma. Eles podem ir por número, por bilhete e por tempo.

 
Valeriy Yastremskiy #:

Até o momento de abertura do pedido. Deve ser o maior)

Você o escreve corretamente, mas o código parece um pouco complicado )))))

Eu o faria do jeito que você diz:

int GetTicketLastOpenOrder()
{
   int ticket = -1;
   datetime t = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderType() <= OP_SELL && OrderOpenTime() > t)
      {
         ticket = OrderTicket();
         t = OrderOpenTime();
      }
   }
   return(ticket);
}


ZS: OrderSelect() por número de bilhete levará muito mais tempo para ser executado do que uma simples busca por pedidos em aberto

 
Igor Makanu #:

Você escreve corretamente, mas o código é um pouco convoluto ))))

Basta seguir suas instruções:


S : OrderSelect() por número de bilhete levará muito mais tempo para ser executado do que uma simples enumeração de pedidos em aberto

Obrigado Igor, é que quando eles não entendem a essência, o código certo para algo não transmite a essência, então eu peço para não colocar algoritmos complicados em palavras))))

 
Valeriy Yastremskiy #:

Até o momento de abertura do pedido. Deve ser o maior) E apenas não pelo número do pedido, e muitas vezes a emissão de bilhetes também não é útil. Ou memorize números de pedido, tickets, status do pedido e horários de abertura/fechamento em seu banco de dados.

E é melhor lembrar a lógica até o final. É mais fácil então. É melhor começar com os dados necessários, e deve haver dados suficientes para uma decisão)

Temos tempo aberto de pedidos (não pendentes). Temos as passagens deles. Temos um preço aberto, SL e TP de cada ordem de mercado. E há um tempo de fechamento do pedido. E depois que o pedido é fechado, o campo Lucro é preenchido.

Estes são os dados de que precisamos para criar a lógica a partir destes campos.

A frase "ordens fechadas após a última ordem aberta" não está definida de forma alguma. Eles podem ir por número, por bilhete e por tempo.

Muito obrigado por suas respostas. Eu implementei algumas de suas sugestões.
Eu escrevi uma função que encontra o tique certo.
Escreveu uma função que conta o lucro de todas as ordens fechadas após o tique da ordem desejada da função selecionada. Tudo o que tenho que fazer agora é corrigi-lo de acordo com suas recomendações e acrescentar um cheque por tempo, etc.

tpl = NormalizeDouble(Bid - ProfitLock*Point, Digits);
            ticket = OrderSend (Symbol(), OP_SELL, lastlot, Bid, Slippage, 0, tpl, "",Magic, 0, Red);


double CalculateProfitHistory()
{
double order=0,op=0;
int cnt=0;
datetime time=0;
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
      if(OrderSelect(Tick,SELECT_BY_TICKET,MODE_HISTORY))
      {
         if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic)
         {
            
            
            op += OrderProfit();
            order +=op;
            cnt++;
            
         }
      }
      }
   return(order);
  }

A única coisa que me confunde agora é que ele não o calcula corretamente. Se TP sair 0,02 como resultado do teste, ele calcula e escreve 0,1300 em Comentário. Você pode me dizer o que há de errado com isso?

 
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
  • 2021.09.02
  • www.mql5.com
В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти н...