Características da linguagem mql5, subtilezas e técnicas - página 33

 
Artyom Trishkin:

Destacado pode retornar 0. O BCS deparou-se.

Sim, corretores corruptos. Eles também colocariam números negativos lá.

Seria bom se os desenvolvedores tivessem um limite de faixa de valores possíveis de cada parâmetro quando os corretores definirem símbolos.

 
Artyom Trishkin:

O que é que se passa exactamente? Essa era a questão - o que estou fazendo de errado para obter dados indicadores a partir de um período de tempo não nativo?

Exemplo: O indicador é executado em M1, e os dados de AO devem ser obtidos de M5. Então, enquanto temos limite>1 (o histórico precisa ser recalculado), AO de M5 retorna zeros com ausência de erro de dados. Assim que o histórico é calculado (limite==0), os dados começam a chegar de AO com M5.

Para começar - você não precisa fazer tais entradas:

periodForWork=PeriodForWork;

No início pensei que estavas a atribuir uma variável ao seu próprio valor.

A seguir:

size_ao=CopyBuffer(handle_ao,0,0,count,array_ao);

Não há necessidade de copiar durante a inicialização. A inicialização não é para este fim. Além disso, este registro não será significativo quando o pedido de dados de TFs mais antigos, que no momento do pedido do OnInit() ainda não será calculado.

ArraySetAsSeries(BufferAO,true);

Mas este registo é suficiente para ser feito apenas uma vez na fase de inicialização.

Além disso... um... subjectivamente, não é assim que eu o faria.

Eu gosto de dividir o programa em:

1. Primeira execução (análise do histórico);

2. Corridas subseqüentes:

2.1. cada carrapato;

2.2. a barra formada;

Isto é..:

if( prev_calculated > 0 )             // Не первый запуск
{
 if( rates_total <= prev_calculated ) // Новый бар не сформирован
  {
  }
 else                                 // Новый бар сформирован
  {
  }
}
else                                  // Первый запуск
{
}

E só depois - ciclo principal de cálculo (função).

As suas funções de cópia dão erros não-informativos. O código não é muito bom.

Não há verificação de sincronização de dados do TF mais antigo.

E o mais importante aqui é compreender a sequência. Aconselho a criação de um indicador de teste, para que ele só solicite os dados da maior TF no primeiro início e para entender como a cópia é feita. Isto é, para remover isto do início do código:

ArraySetAsSeries(array_ao,true);

E desajustar o primeiro e o último elemento da matriz. E só então, se necessário, mudar a direcção da indexação.

 
Seja como for, começa por aí:
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
input   ENUM_TIMEFRAMES inpTimeframe=PERIOD_M5;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int _handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   _handle=iAO(_Symbol,inpTimeframe);
   if(_handle==INVALID_HANDLE)
     {
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),"! Хэндл индикатора iAO ТФ "+EnumToString(inpTimeframe)+" не получен!");
      return( INIT_FAILED );
     }
//---
   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[])
  {
//--- Массив-приемник значений индикатора
   double ao[];
//---
   if(prev_calculated>0)
     {

     }
   else                                        // Если первый запуск
     {
      //--- Количество просчитанных баров старшего ТФ
      int bars;
      if(( bars=BarsCalculated(_handle))<0 || !(bool)SeriesInfoInteger(_Symbol,inpTimeframe,SERIES_SYNCHRONIZED))
         return( 0 );
      //--- 
      int num=CopyBuffer(_handle,0,0,bars,ao);
      //---
      if(num<0)
        {
         Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": Запрашиваемая таймсерия еще не построена!");
         return( 0 );
        }
      else if(num!=bars)
        {
         Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": Скопированы не все данные (",num," из ",bars,")");
         return( 0 );
        }
      //---
      Print(__FUNCTION__,": Успех! Скопировано ",num," из ",bars," значение индикатора АО ТФ "+EnumToString(inpTimeframe));
     }
//---
   return( rates_total );
  }
//+------------------------------------------------------------------+
 
Alexey Kozitsyn:

Para começar - você não precisa fazer tais entradas:

Primeiro pensei que estavas a atribuir a uma variável o seu próprio valor.

A seguir:

Não há necessidade de copiar durante a inicialização. A inicialização não é para este fim. Além disso, este registro não será significativo quando o pedido de dados de TFs mais antigos, que no momento do pedido do OnInit() ainda não será calculado.

Mas este registo é suficiente para ser feito apenas uma vez na fase de inicialização.

Além disso... um... subjectivamente, não é assim que eu o faria.

Eu gosto de dividir o programa em:

1. Primeira execução (análise do histórico);

2. Corridas subseqüentes:

2.1. cada carrapato;

2.2. a barra formada;

Isto é..:

E só depois - ciclo principal de cálculo (função).

As suas funções de cópia dão erros não-informativos. O código não é muito bom.

Não há verificação de sincronização de dados do TF mais antigo.

E o mais importante aqui é compreender a sequência. Aconselho a criação de um indicador de teste, para que ele só solicite os dados da maior TF no primeiro início e para entender como a cópia é feita. Isto é, para remover isto do início do código:

E desajustar o primeiro e o último elemento da matriz. E só então, se for necessário, mudar a direcção da indexação.

Eu faço variáveis que são claras para mim num piscar de olhos. Se você não os entende, faça-os de uma forma que você os entenda ;).

Começo sempre a escrever variáveis não globais com uma letra pequena - a razão é simples: inteligência sensível a maiúsculas e minúsculas...

Este é o código de teste, pois o código não-teste é suficientemente grande, e no MT4 ele voa ao trocar o traf, e não há erros de dados em falta - tudo está sempre lá. Mas MT5 quando eu troco mtf apenas por meio minuto carrega o histórico, e depois não funciona com os dados não é o seu TF - diz sobre a sua ausência.

Foi por isso que discuti o que estava a fazer mal. Verificou-se que é necessário solicitar os dados para todos os clientes usados no init. Eu acho que se você não souber com antecedência o número estimado de telefones usados, você precisa solicitar todos eles. Só um por meio minuto conta. São 21, no total...

Alguma coisa errada de novo?

 
Isto é muito útil para osprincipiantes:

No MT5, demora apenas meio minuto a descarregar o histórico quando se muda um etf


escreveu sobre isso

я правильно понимаю тогда, что подготовив кэш,терминал при последующих обращениях (начиная со 2 обращения) затрачивает на порядки меньше времени?

можно ли как-то уменьшить время первого обращения после перезагрузки терминала,чтобы было как в МТ4?
Теперь выводы:

    Разница только в скорости начальной инициализации кеша чарта 0.6 мс МТ4 против 113 мс у МТ5

mais detalhes aqui

https://www.mql5.com/ru/forum/1111/page1871#comment_4866969

https://www.mql5.com/ru/forum/1111/page1871#comment_4867939

Isto é e será. Quanto mais TF ou símbolos pedir, mais lento será o início.

Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • www.mql5.com
Форум алго-трейдеров MQL5
 
kaus_bonus:


escreveu sobre isso

mais detalhes aqui

https://www.mql5.com/ru/forum/1111/page1871#comment_4866969

https://www.mql5.com/ru/forum/1111/page1871#comment_4867939

Quanto mais TFs ou caracteres forem consultados, mais lento será o início.

Acho que seria bom se apenas quando o indicador for iniciado pela primeira vez. Tenho de mudar os prazos e demora meio minuto a carregar o histórico. Eu sei que não devia ser assim, mas... Estou a fazer algo errado... E só em um indicador acontece - quando tento aceder a um período de tempo não nativo.
 
Artyom Trishkin:
Seria bom se apenas quando eu iniciar o indicador pela primeira vez. Eu tenho meio minuto de histórico de carga cada vez que troco de tempo. Eu sei que não devia ser assim, mas... Estou a fazer algo errado... Estou a tentar aceder a um período de tempo não nativo em apenas um indicador.

Bem, meça a velocidade da cópia de dados de outro período de tempo e veja onde está o gargalo de engarrafamento.
 
Artyom Trishkin:

Se você precisar usar vários indicadores de diferentes TFs para os cálculos - você precisa obter o controle de cada TF.

Se você quiser que seja mais rápido - reduza o tamanho do histórico no terminal.

Já fizeste o meu indicador de teste? Está a recolher dados?

 
Alexey Kozitsyn:

Se você precisar usar vários indicadores de diferentes TFs para os cálculos - você precisa obter o controle de cada TF.

Se você quiser que seja mais rápido - reduza o tamanho do histórico no terminal.

Já fizeste o meu indicador de teste? Está a recolher dados?

Não, não tenho.

Acontece que se você precisar de TODOS os prazos, você deve criar 21 alças do indicador AO? Não é um desperdício?

 
Artyom Trishkin:

Não, ainda não o fiz.

Acontece que se você precisar de TODOS os prazos, você precisa criar 21 alças indicadoras AO? Não é um desperdício?

De que outra forma posso obter os dados a partir do símbolo/TF correcto? O CopyBuffer só funciona com alças.
Razão: