![MQL5 - Linguagem para estratégias de negociação inseridas no terminal do cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
Você está perdendo oportunidades de negociação:
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Registro
Login
Você concorda com a política do site e com os termos de uso
Se você não tem uma conta, por favor registre-se
Isto NÃO está na documentação! Consequentemente, este é um ensaio sobre um tema livre. Assim como minha declaração sobre inicialização automática, ainda mais fria. Pelo menos o meu tinha um termo de responsabilidade.
É impossível descrever absolutamente tudo na documentação.
Se "prev_calculate==0" - significa que temos que passar por todo o buffer de indicadores. Se "prev_calculate!=0", então somente a barra mais à direita ou várias barras novas serão calculadas (usamos limite):
{
//---
if(prev_calculated==0)
{
Print("prev_calculated==0");
for(int i=0;i<rates_total;i++)
{
//--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
}
return(rates_total);
}
//--- экономный пересчёт только самого правого бара или новых баров
int limit=rates_total-prev_calculated+1;
//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
for(int i=0;i<limit;i++)
{
ExtBuffer[i]=чевой-то там;
}
É impossível descrever absolutamente tudo na documentação.
Se "prev_calculate==0" - significa que temos que passar por todo o buffer de indicadores. Se "prev_calculate!=0", então somente a barra mais à direita ou várias barras novas serão calculadas (usamos limite):
{
//---
if(prev_calculated==0)
{
Print("prev_calculated==0");
for(int i=0;i<rates_total;i++)
{
//--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
}
return(rates_total);
}
//--- экономный пересчёт только самого правого бара или новых баров
int limit=rates_total-prev_calculated+1;
//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
for(int i=0;i<limit;i++)
{
ExtBuffer[i]=чевой-то там;
}
Qual é o valor? Eu não preciso de nenhum valor, exceto a barra mais à direita. MAS!!! Então, quando esta à direita se desloca para a esquerda, estes dados devem ser salvos.
Você não precisa escrever todos os buffers, mas poderia escrever um com meus desejos em mente. Se for a primeira corrida, toda a história deve estar vazia. Se a pré-cálculo foi redefinido como resultado da troca do histórico, TUDO que foi colocado em buffer deve permanecer inalterado. Mesmo que haja buracos.
Conclusões preliminares:
Por que você está falando bobagens? Se esta inicialização for colocada na OnCalculate, ela é zerada sem nenhum ciclo. Mas se zeramos os dados pré-calculados, isso limpa todos os dados que foram acumulados durante a operação...
Qual é o valor??? Não preciso de nenhum valor a não ser a barra mais à direita. MAS!!! Então, quando esta mais à direita se desloca para a esquerda, esses dados precisam ser salvos...
...
Eu já sugeri um caminho:
Fórum sobre comércio, sistemas automatizados de comércio e teste de estratégias comerciais
pré_calculado
Karputov Vladimir, 2016.10.18 15:11
Desculpe pelo atraso na resposta. A única maneira de salvar os valores calculados para um determinado período de tempo é salvá-los em um arquivo. Você precisa cuidar da sincronização - para que ao ler do arquivo os dados sejam colocados em suas barras. A forma mais lógica é sincronizá-la com o tempo de abertura da barra, mas pode haver algumas nuances: por exemplo, o tempo de abertura da barra (salvo em um arquivo) era 2016.09.05. 25:02, mas agora há uma barra no gráfico com tempo igual a 2016.09.05. 25:01.Um indicador não é um banco de dados ou um repositório.
Portanto, se o indicador exibir dados que depois não podem ser calculados sobre o histórico, então é necessário apenas salvar o buffer do indicador em um arquivo, e depois (em caso de troca de histórico) ler e sincronizar o arquivo e as barras.Eu já sugeri um caminho:
Um indicador não é um banco de dados ou um repositório.
Portanto, se o indicador mostrar os dados, que então não podem ser calculados sobre o histórico, então temos apenas que salvar o buffer indicador em um arquivo, e então (no caso de paginação do histórico) realizar a leitura e sincronizar o arquivo e as barras.... e de preferência sem escrever para um arquivo ou ainda mais para a GV.
Vladimir, uma vez que você dedicou este tópico especificamente para o pré-cálculo, torne-o útil sobre este tópico. Antes de tudo, deve-se especificar o problema que geralmente ocorre com esta variável. Se você não estiver familiarizado com estes problemas, eu formularei
---
a-- apesar de dizer na ajuda
A razão é (está escrito em ajuda + dito pelos desenvolvedores) que a variável é zerada quando o checksum muda, geralmente por causa da troca de histórico.
---
b - você também não pode usar o pré-cálculo == 0 como bandeira da primeira corrida onCalculate. Pela mesma razão
---
c - e você também não pode usar pré_calculo == 0 como bandeira de paging do histórico
---
Para reduzir o desgaste dos usuários, o texto deve ser breve e inequívoco: se a paginação do histórico não tiver acontecido na chamada atual da OnCalculate, o pré-cálculo contém o número de barras processadas na chamada anterior. Se isso aconteceu - é zerada
---
Todos os 3 problemas listados podem ser resolvidos com muletas. Entretanto, como o MT5 não pode ter muletas por definição, Vladimir, você poderia criar uma solução atraente para esses três problemas? Um feio é algo parecido com isto:
#property indicator_buffers 0
#property indicator_plots 0
struct BROWNIE {
int i_Prew_Calculated; // кол-во посчитанных баров
bool b_First_Run; // флаг первого запуска
bool b_History_Updated; // флаг обновления истории
BROWNIE() {
i_Prew_Calculated = WRONG_VALUE;
b_First_Run = true;
b_History_Updated = false;
}
void f_Reset(bool b_Reset_First_Run = true) {
i_Prew_Calculated = WRONG_VALUE;
if(b_Reset_First_Run) b_First_Run = true;
b_History_Updated = false;
}
void f_Update(int i_New_Prew_Calculated = WRONG_VALUE) {
if(i_New_Prew_Calculated > -1) {
b_History_Updated = i_New_Prew_Calculated == 0 && i_Prew_Calculated > WRONG_VALUE;
if(b_First_Run) b_First_Run = false;
if(i_Prew_Calculated == WRONG_VALUE) i_Prew_Calculated = i_New_Prew_Calculated;
else if(i_New_Prew_Calculated > 0) i_Prew_Calculated = i_New_Prew_Calculated;
}
}
};
BROWNIE go_Brownie;
int OnInit(void) {return(INIT_SUCCEEDED);}
void OnDeinit(const int reason) {
go_Brownie.f_Reset(reason != REASON_CHARTCHANGE);
}
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 &TickVolume[],
const long &Volume[],
const int &Spread[]
) {
if(go_Brownie.b_First_Run) {/* обработка 1го запуска */}
if(go_Brownie.b_History_Updated) {/* обработка обновления истории */}
go_Brownie.f_Update(prev_calculated);
return(rates_total);
}
Isenção de responsabilidade: Código - apenas uma idéia, eu não a experimentei em um gráfico.
No OnDeinit há uma amostra - processamento para o indicador que não usa tampões, não se importa com TF e símbolo, a cada mudança de TF/símbolo não há necessidade de começar do zero. Por exemplo, ele funciona com elementos gráficos existentes, produz informações sobre o status da conta, pedidos, etc.
---
A propósito
Se o buffer indicador fosse salvo em um arquivo, e então (em caso de carregamento do histórico) seria necessário ler e sincronizar o arquivo e as barras.
... e de preferência sem escrever para um arquivo ou ainda mais para um GV.
Talvez isto lhe sirva?
Eu não entrei em detalhes, mas isto é resolvido por esta linha de código. Copiar uma matriz em si mesma com um deslocamento de índice.
ArrayCopy(arr, arr, 0, 1, 4);
// и дальнейшее заполнение 4го индекса массива.