Em um indicador padrão, você construiria as matrizes de proteção com dados dos parâmetros enviados através da função de evento OnCalulate( ... ). Mas, para multi-currency e/ou multi-time-frame, você terá que usar uma de duas soluções:
- Usando o método antigo das variações "iFunction", tais como iTime(), iVolume, iOpen, iClose, etc., mas com um símbolo diferente como "EURUSD", "JPYUSD", etc. em vez do padrão _Symbol ou Symbol().
- Usando o método mais recente da primeira variante da função ArrayCopyRates() juntamente com apontadores de array de MqlRates. Os arrays "copiados", na verdade não ocuparão nenhum espaço e serão apenas apontadores para os dados existentes dos vários símbolos e quadros de tempo.
Entretanto, para que isto funcione, uma de duas condições tem que existir para que o multi-símbolo e/ou o multi-modelo de tempo funcione:
- Ou os respectivos gráficos para os símbolos e quadros temporais já estão abertos, de modo que nenhum erro seja gerado,
- ou você receberá um erro 4066 (ERR_HISTORY_WILL_UPDATED) na primeira vez que solicitar os dados, e você terá que codificar um loop de sono e nova tentativa, a fim de esperar que os dados sejam baixados e então solicitar os dados novamente.
Minha solução pessoal sugerida, que considero como a mais eficiente, bem como a maneira mais fácil de lidar com o erro 4066, é o método ArrayCopyRates() e MqlRates .
Há mais informações sobre isso na documentação MQL4 e nos arquivos de ajuda.
PS! NB! Ao acessar funções indicadoras embutidas, tais como iMA(), iATR(), etc. para os vários símbolos e prazos, lembre-se também de implementar os laços de dormir e tentar novamente para não obter o erro 4066 também. Aqui está uma citação do documento MQL4:
Lembre-se, a OP está perguntando sobre um indicador. Sleep() é ignorado nos indicadores
Desculpe, mas não sabia disso! Utilizo este método bastante extensivamente nos EA, mas não nos Indicadores, portanto não sabia sobre a deficiência do sono.
Nesse caso, ele terá que construir um loop de repetição em torno de chamadas sucessivas em cada chamada para a função OnCalculate() (onde o uso do ArrayCopyRates() é a melhor solução).
Alternativamente, se funcionar na função OnInit(), pode ser o método preferido de preparação dos dados para o indicador, com uma reentrada muito longa (sem o sono) para este caso.
...
- ou você receberá um erro 4066 (ERR_HISTORY_WILL_UPDATED) na primeira vez que solicitar os dados, e você terá que codificar um loop de sono e nova tentativa, a fim de esperar que os dados sejam baixados e então solicitar os dados novamente.
PS! NB! Ao acessar funções indicadoras embutidas, tais como iMA(), iATR(), etc. para os vários símbolos e prazos, lembre-se também de implementar os laços de dormir e tentar novamente, para não obter o erro 4066 também. Aqui está uma citação do documento MQL4:
A menos que eles tenham mudado algo recentemente, você receberá o erro 4066 toda vez desde a primeira chamada de função (e somente desde esta primeira chamada), independentemente das condições ou do progresso de atualização do histórico. Ele não tem utilidade prática.
FMIC: Nesse caso, ele terá que construir um loop de repetição em torno de chamadas sucessivas em cada chamada para a função OnCalculate() (onde o uso do ArrayCopyRates() é a melhor solução). Alternativamente, se funcionar na função OnInit(), pode ser o método preferido para preparar os dados para o indicador, com uma recontagem muito longa (sem o sono) para este caso. |
|
if(pair1[0].time == 0) return;
Isto nunca será verdade.
Se houver algum histórico carregado para o símbolo e o cronograma, a função recuperará o valor mais recente.
Se não houver nenhum histórico carregado, você obterá um Array fora do intervalo de erro.
O mesmo com o iTime, etc.
Isto nunca será verdade.
Se houver algum histórico carregado para o símbolo e o cronograma, a função recuperará o valor mais recente.
Se não houver nenhum histórico carregado, você obterá um Array fora do intervalo de erro.
O mesmo com o iTime, etc.
Eu estou inclinado a concordar!
Pessoalmente, eu apenas verifico o valor de retorno do "ArrayCopyRates()" e depois disso eu apenas acompanho o tamanho da matriz antes de acessar os dados da matriz.
Com relação ao "iTime()" e outras funções semelhantes, eu sempre verifico o "iBars()" primeiro.
Isto nunca será verdade.
if(pair1[0].time == 0) return;
Se houver algum histórico carregado para o símbolo e o cronograma, a função recuperará o valor mais recente.
Se não houver nenhum histórico carregado, você obterá um Array fora do intervalo de erro.
O mesmo com o iTime, etc.
Há muitos exemplos históricos (600 pré-construção) de olhar para um ACR. Não há outra maneira de fazer isso. Chamadas subsequentes ao ACR ou ao iTime NÃO retornarão 4066, então como você pode saber se os dados foram baixados?
O iTime sempre retornou zero em um erro.
Há muitos exemplos históricos (pré-construção 600) de verificação de um ACR. Não há outra maneira de fazer isso. Chamadas subsequentes ao ACR ou ao iTime NÃO retornarão 4066, então como você pode saber se os dados foram baixados.
O iTime sempre retornou zero em um erro.
O que você quer dizer com "não há outra maneira de fazer isso"?
Verificar a contagem de retorno do "ArrayCopyRates", e verificar o tamanho da matriz, parece ser um método mais robusto de verificação, do que fazer "par1[0].time == 0" que pode facilmente retornar umerro "Array index is out of range".
EDIT: Removi algumas de minhas declarações após ter relido seu post mais de perto.
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Eu quero escolher ENTRE 1 a 10 moedas diferentes e 5 barras para cada moeda.
Mas eu não sei como fazer isso.