Quaisquer perguntas de recém-chegados sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos - página 522

 
PolarSeaman:

Que reviravolta!))))

Ordem 1 (de# não, até#2) -- > Ordem2 (de#1, até#3) -- > Ordem3 (de#2, até# não)

A partir disto, você pode encontrar toda a cadeia.

Olhamos para o comentário aberto e, se houver de #XXX, significa que ele foi fechado parcialmente - procure pelo bilhete XXX do comentário e procure-o na história. Olhe lá comentário - se houver de#YYYY - significa que também foi parcialmente fechado antes - olhe bilhete YYY de comentário e procure-o na história. Veja o comentário - se houver de#ZZZZ - significa que também foi parcialmente fechado antes - repita a busca. Se não há nenhum de#..., então é o primeiro de toda a cadeia.

 
Artyom Trishkin:

Order 1 (de# não, até#2) -- > Order2 (de#1, até#3) -- > Order3 (de#2, até# não)

A partir disto, você pode encontrar toda a cadeia.

Olhamos para o comentário aberto e, se houver de #XXX, significa que anteriormente estava parcialmente fechado - procure pelo bilhete XXX do comentário e procure-o na história. Olhe lá comentário - se houver de#YYYY - significa que também foi parcialmente fechado antes - olhe bilhete YYY de comentário e procure-o na história. Veja o comentário - se houver de#ZZZZ - significa que também foi parcialmente fechado antes - repita a busca. Se não há nenhum de#..., então é o primeiro de toda a cadeia.

Obrigado, pode haver uma ordem na direção oposta, que eu também cortarei. Tenho medo de ficar confuso. Eu acho que seria mais fácil usar a ordem de lucro de uma determinada data, é claro, se formos capazes de descobrir quando a posição foi aberta, porque a data muda quando a posição é parcialmente fechada

 
Artyom Trishkin:

Order 1 (de# não, até#2) -- > Order2 (de#1, até#3) -- > Order3 (de#2, até# não)

A partir disto, você pode encontrar toda a cadeia.

Veja comentário aberto e se houver de #XXX, significa que foi parcialmente fechado antes - procure o bilhete XXX a partir de comentário e procure-o na história. Veja o comentário lá - se houver de#YYYY - então também foi parcialmente fechado antes - veja o bilhete YYY a partir do comentário e procure por ele na história. Veja o comentário - se houver de#ZZZZ - significa que também foi parcialmente fechado antes - repita a busca. Se não há nenhum de#..., então é o primeiro de toda a cadeia.

Artem você sabe que este nem sempre é o caso. E para não traçar uma corrente para não interrogar o terminal três vezes - a história é conduzida, mesmo assim, em matrizes e estruturas próprias. Não é diferente de manter seu próprio banco de dados, exceto pelas etapas extras

O terminal e seu API é o nível mais baixo possível. E para implementar a lógica do robô, é lógico fazer a contabilidade em seus termos (comércio, cadeia, grupo, transação - todos a chamam de forma diferente). É apenas sensato mantê-lo separado e não tentar reconstruí-lo a cada espirro (tick/bar).

 
Maxim Kuznetsov:

Você sabe que este nem sempre é o caso, Artyom. E assim, não é preciso perguntar três vezes ao terminal ao rastrear a cadeia - a história ainda é conduzida para suas próprias matrizes e estruturas. Não é diferente de manter seu próprio banco de dados, exceto pelas etapas extras

O terminal e seu API é o nível mais baixo possível. E para a realização da lógica robótica, é lógico manter a contabilidade em seus termos (comércio, cadeia, grupo, transação - todos a chamam de forma diferente). É apenas sensato mantê-lo separado e não tentar reconstruí-lo a cada espirro (tick/bar).

Há muito tempo eu tenho tudo feito - não leio a história todas as vezes - mas está sempre atualizado, e posso encontrar tudo o que preciso lá com facilidade e muito rapidamente. Mas para aconselhar alguém a fazer o mesmo, eu preciso de pelo menos alguns artigos. E assim escrevi a lógica de encontrar a cadeia inteira.

 
PolarSeaman:

Obrigado, pode haver uma ordem na direção oposta que eu também triturarei. Tenho medo de ficar confuso. Eu acho que seria mais fácil usar a função Lucro para fechar uma posição a partir de uma determinada data, é claro, se você puder descobrir quando a posição foi aberta, porque em um fechamento parcial a data muda

Para buscar uma cadeia, basta conhecer o ticket da ordem, a cadeia inteira da qual você quer saber - passe o ticket como parâmetro para a função de busca, e a saída - uma matriz preenchida ou uma matriz de estruturas com todos os dados de cada ordem da cadeia inteira.

 
Artyom Trishkin:

Uma matriz preenchida ou uma matriz de estruturas com todos os dados de cada ordem de toda a cadeia.

Eu nem sei aproximadamente o que você acabou de dizer.

Ao menos me mostre um exemplo de como deveria ser.

 
PolarSeaman:

Eu nem sei aproximadamente o que você acabou de dizer.

Pelo menos me dê um exemplo de como deveria ser.

Eu resolvo o problema da seguinte maneira: busca de correntes pela história. Bem, para que a história esteja inequivocamente disponível, eu utilizo duas variantes:

  1. Se sem DLL, então na descrição do programa em 24 negrito )))) especifico que o histórico da conta deve ser sempre carregado por completo (guia Histórico da conta da janela Terminal, menu de contexto - Todo Histórico).
  2. Com DLL - Expert Advisor mantém a guia "Account history" atualizada, independentemente de qualquer ação do usuário.

Funções para determinar a ordem pai, se a ordem atual não for a principal:

int GetSignOfPartialOrCloseByClose()
{
   string comment = OrderComment();
   if (comment == "")
      return 0;
   
   // Ордер образовался вследствии частичного закрытия
   int fromStart = StringFind(comment, "from #");
   if (fromStart >= 0)
      return GetTicketByPartialClose(comment, fromStart, OrderType(), OrderOpenTime());
   
   // Ордер образовался вследствии встречного закрытия
   if (StringFind(comment, "partial close") >= 0)
   {
      datetime openTime = OrderOpenTime();
      int type = OrderType();
      for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
      {
         if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
            continue;
            
         if (OrderOpenTime() != openTime)
            continue;
            
         if (OrderType() != type)
            continue;
            
         if (StringFind(OrderComment(), "partial close") < 0)
            continue;
            
         return OrderTicket();
      }
   }
   
   return 0;
}


int GetTicketByPartialClose(string comment, int fromStart, int orderType, datetime openTime)
{
   string sTicket = StringSubstr(comment, fromStart + 6);
   int iTicket = (int)StringToInteger(sTicket);
   int type = OrderType();
   if (!OrderSelect(iTicket, SELECT_BY_TICKET))
      return 0;
      
   if (OrderType() == type)                                                                        // Дочерний ордер указывает на родителя - уходим
      return iTicket;
      
   // Дочерний ордер указывает на противоположный ордер. Необходимо искать родительский
   for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
         continue;
         
      if (OrderType() != orderType || OrderOpenTime() != openTime)
         continue;
         
      int iFind = StringFind(OrderComment(), "close hedge by #");
      if (iFind < 0)
         continue;
         
      sTicket = StringSubstr(OrderComment(), iFind + 16);
      int iNewTicket = (int)StringToInteger(sTicket);
      if (iNewTicket != iTicket)
         continue;
         
      return OrderTicket();
   }
   
   return 0;
}

Fácil de usar:

   for (int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS))
         continue;

      ....         

      int nFromTicket = GetSignOfPartialOrCloseByClose();                // Обязательно последней строкой в теле цикла, т. к. может измениться текущий выбранный ордер
   }


 
Ihor Herasko:

O erro mais grosseiro aqui é especificar o valor 100 em vez do bilhete no argumento OrderDelete().

O próximo erro não é tão rude, mas está relacionado ao fato de que o valor calculado de Stop Loss é verificado, não seu valor real.

O tipo de pedido também não é verificado. E se tivermos escolhido uma ordem de mercado? Como apagá-lo? O símbolo do pedido não foi verificado.

Levando em consideração estes erros, obtemos o código de eliminação da ordem pendente quando o preço atinge seu Stop Loss:

Além disso, em seu código, o Stop Loss é verificado imediatamente após a abertura do pedido. Parece que depois de abrir uma ordem pendente, este código não é mais executado. Ou seja, é preciso separar os ramos de execução. Um é responsável pela definição do pedido, e o segundo é responsável pelo seu acompanhamento.

Obrigado por sua resposta detalhada!

Seguindo seu conselho, eu separei as filiais e tudo funciona.

Depois me deparei com o problema da abertura simultânea de 10-15 ordens pendentes, resolvi este problema adicionando-o depois de seu código:

if (OrdersTotal ()>0) return;

Tenho certeza de que há uma maneira melhor.

Por seu código, você poderia explicar o que 1; i >=0; --i significa?

for (int i = OrdersTotal() - 1; i >= 0; --i)
 

Por favor, ajude-me a entender como escrever um indicador. Eu desenhei um tal boneco, como fazer um comprimento de indicador a ser desenhado em pontos de tamanho acima da atual Proposta, a partir do momento em que o indicador é colocado no gráfico? Talvez o erro seja que eu esteja mudando esta matriz na direção errada?

Eu sei que é "canônico", sem qualquer pré-cálculo etc., mas eu preciso disso assim


#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot 
#property indicator_label1  "myInd"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Blue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

double buff[], Bid;
input int lenght = 50, size = 5;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping

   ArrayResize(buff, 50);
   ArrayInitialize(buff, 0);
   SetIndexBuffer(0, buff, INDICATOR_DATA);
   //--- установим метку для отображения в DataWindow
   PlotIndexSetString(0,PLOT_LABEL,"myInd");   
//--- установим имя для показа в отдельном подокне и во всплывающей подсказке
   IndicatorSetString(INDICATOR_SHORTNAME,"myInd");
//--- укажем точность отображения значений индикатора
   IndicatorSetInteger(INDICATOR_DIGITS, _Point);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   for(int i = lenght-1; i>0; i--){
      buff[i] = buff[i-1];
   }
   buff[0] = Bid+size;
   


   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Roman Sharanov:

Por favor, ajude-me a entender como escrever um indicador. Eu desenhei um tal boneco, como fazer um comprimento de indicador a ser desenhado em pontos de tamanho acima da atual Proposta, a partir do momento em que o indicador é colocado no gráfico? Talvez o erro seja que eu esteja mudando esta matriz na direção errada?

Eu sei que é "canônico", sem pré-cálculo e coisas assim.


O que é o cânone? Há um documento oficial - é exatamente como o seu.

1. você deve definir a serialização de todas as matrizes usadas dentro da OnCalculate.

Antes de entrar no loop, coloque buff[length]=Bid+size; - você terá aproximadamente o que você quer. Uma linha curva e no final uma "viseira" no tamanho Bid+size

3. observar os limites da matriz. É claro que as tarifas_total é dificilmente <comprimento, mas você não pode errar :-)

4.
buff[i] = buff[i+1]; // если тайм-серия (а вы подразумеваете их) то +