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.

[Excluído]  
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.

[Excluído]  
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.
[Excluído]  
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?

[Excluído]  
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.