As barras e o volume não são confiáveis para detectar novas barras.
Um computador está trabalhando em nano segundos, então um EA bem codificado pode fazer muito em 20 ms.
- 2010.10.11
- Konstantin Gruzdev
- www.mql5.com
- www.mql5.com
Obrigado, Alain,
muito interessante ... exatamente o que eu acho ... 10 vezes mais rápido . ... hmmm.
Significa ..: TimeCurrent() é rápido e sincronizado com as bordas das barras ?
Por que .... hmmm ...
Preciso de um tempo para pensar sobre isso.
Willbur ...
Ok - para pessoas que gostam de coisas como esta: Meu estudo sobre este assunto.
Eu escrevi uma frase em um arquivo em cada evento "OnTick".
TimeLocal (PC CLock), TimeCurrent(), usando SymbolInfoTick() algumas informações sobre o último tick que chegou e - usando CopyRates() - algumas informações sobre a barra atual.
Um exemplo de "USD/JPY" - Período é "M1":
São 19:43:01 no PC-Clock quando o primeiro tick do 43º minuto chega, ao mesmo tempo em que surge uma nova barra.
Além do falso, que o volume do tique não é 1. este é o fluxo normal das coisas.
Às vezes não é tão fácil - como neste caso:
O PC já mostra 19:42:00 quando mais três tiquetaques do bar de 41min entraram. Eles ainda têm um carimbo da hora de 19:41:59.
Agora o mundo respira profundamente - 8.150 msec de quietude total.
Então - o PC já mostra 19:42:09 - o primeiro tique da nova barra - a barra de 42 minutos - entra.
O Tick é marcado com 19:42:07 e - porque é a barra de 19:42 que aparece com ele - o timestamp das barras é 19:42:00
Agora .... hmmm ....
1. O TimeCurrent() é sempre igual ao carimbo de tempo do tick?
Verifiquei o registro de 40.000 e encontrei apenas cinco casos em que o TimeCurrent já está trocado enquanto o carimbo de tempo do último carimbo não está.
2. O último_marcador está sempre à frente da abertura da nova barra?
(a ser continuado)
TimeCurrent() é a hora do último tick do servidor, depende do seu código se é ou não do seu símbolo gráfico.
Eu não entendo seu "último tick", você deve mostrar o código que produziu esta saída.
Oi Alain
Eu verifico o TimeCurrent() em OnTick() que deve garantir que ele pertence ao símbolo com o qual eu lido.
Bem, este deve ser meu "New Bar Identifier" - pequeno e rápido - o que você acha?
//--- New Bar
bool NewBar = false;
long currPeriodSeconds;
double currPeriodProgress = 0;
int OnInit(void) //-----------------------------------------------
{
currPeriodSeconds = PeriodSeconds();
return(INIT_SUCCEEDED);
}
void OnTick() //--------------------------------------------------
{
if(MathMod(TimeCurrent(),currPeriodSeconds) < currPeriodProgress)
NewBar = true;
else NewBar = false;
currPeriodProgress = MathMod(TimeCurrent(),currPeriodSeconds);
Vou verificá-lo com esta sequência:
//--- Just for testing
int ExtHdlFile1=0;
MqlRates rates[1];
//--- New Bar
bool NewBar = false;
long currPeriodSeconds;
double currPeriodProgress = 0;
int OnInit(void) // -------------------------------------------------------
{
currPeriodSeconds = PeriodSeconds();
ExtHdlFile1=FileOpen("NewBarTest.csv",FILE_READ|FILE_WRITE|FILE_CSV);
FileSeek (ExtHdlFile1,0,SEEK_END);
FileWrite(ExtHdlFile1, "TimeLocal",
"TimeCurrent",
"rates[0].time",
"rates[0].tick");
return(INIT_SUCCEEDED);
}
void OnTick() // -----------------------------------------------------------
{
if(MathMod(TimeCurrent(),currPeriodSeconds) < currPeriodProgress)
NewBar = true;
else NewBar = false;
currPeriodProgress = MathMod(TimeCurrent(),currPeriodSeconds);
//--- lets check this
if(NewBar)
{
// last Time Stamp of old Bar
FileWrite(ExtHdlFile1, " ",
" ",
TimeToString(rates[0].time, TIME_MINUTES|TIME_SECONDS),
IntegerToString(rates[0].tick_volume));
// get the new bar
if(CopyRates(Symbol(),Period(),0,1,rates)!= 1) return;
// first Time Stamp of new Bar
FileWrite(ExtHdlFile1,TimeToString(TimeLocal(),TIME_MINUTES|TIME_SECONDS),
TimeToString(TimeCurrent(), TIME_MINUTES|TIME_SECONDS),
TimeToString(rates[0].time, TIME_MINUTES|TIME_SECONDS),
IntegerToString(rates[0].tick_volume));
}
if(CopyRates(Symbol(),Period(),0,1,rates)!= 1) return; // != clean code - just a test
}
void OnDeinit(const int reason)
{
FileClose(ExtHdlFile1);
return;
}
Oi Alain
Eu verifico o TimeCurrent() em OnTick() que deve garantir que ele pertence ao símbolo com o qual eu lido.
Bem, este deve ser meu "New Bar Identifier" - pequeno e rápido - o que você acha?
Aqui está minha versão final.
Na verdade, estou um pouco preocupado porque é tão fácil.
Alain: Seria bom se você emitisse a bênção.
// -----------------------------------------------------------------------
bool NewBar(void)
{
bool iNewBar = false;
static double currPeriodProgress = 0;
currPeriodProgress = MathMod(TimeCurrent(),PeriodSeconds());
return(iNewBar);
}
// ------------------------------------------------------------------------
void OnTick()
{
if(NewBar()) PlaySound("tick.wav");
Saudações de Colônia
Willbur
A maneira mais fácil:
data/hora estática tlastbar=0;
datetime tnewbar=iTime(NULL,PERIOD_CURRENT,0);
bool isewbar=tnewbar!=tlastbar;
tlastbar=tnewbar=tnewbar;
- 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 fervo como indicar quando uma nova barra vê a luz do dia.
Preocupo-me principalmente com o desempenho. Em alguns símbolos eu vi carrapatos a cada 20 ms. Não tenho muito tempo para reagir.
Uma idéia é o volume.tick_volume
Mqlrates rates[1];
OnInit()
{
if(CopyRates(_Symbol,_Period,0,1,rates) < 1)
if(rates[0].tick_volume == 1)
{
... deal with new bar ...
}
Outra idéia poderia ser a verificação se o número de barras foi aumentado.
OnInit()
{
if(BarsOld < Bars(_Symbol,_Period))
{
BarsOld = Bars(_Symbol,_Period);
... deal with new bar ...
}
Verifiquei também a OnChartEvent, mas não encontrei nenhuma maneira de diferenciar as barras novas de outras coisas.
Obrigado por sua avaliação
WIllbur