Бары и объем ненадежны для обнаружения нового бара.
Компьютер работает в наносекундах, поэтому хорошо закодированный советник может сделать многое за 20 мс.
- 2010.10.11
- Konstantin Gruzdev
- www.mql5.com
- www.mql5.com
Спасибо, Ален,
очень интересно... именно то, что я предполагал... В 10 раз быстрее... хммм...
Значит: TimeCurrent() работает быстро и синхронно с границами баров?
Почему .... хммм ...
Мне нужно время, чтобы подумать об этом.
Willbur
Хорошо - для людей, которые любят подобные вещи: Мое исследование по этому вопросу.
Я написал предложение в файл в каждом событии "OnTick".
TimeLocal (PC CLock), TimeCurrent(), используя SymbolInfoTick() некоторую информацию о последнем пришедшем тике и - используя CopyRates() - некоторую информацию о текущем Баре.
Пример из "USD/JPY" - Период - "M1":
Сейчас 19:43:01 на PC-часах, когда приходит первый тик 43-й минуты, в это же время возникает новый бар.
Не считая того, что тик-объем не равен 1, это нормальный ход вещей.
Иногда это не так просто - как в данном случае:
ПК показывает уже 19:42:00, когда пришли еще три тика бара 41мин. Они все еще имеют временную метку 19:41:59.
Сейчас мир делает глубокий вдох - 8.150 мс полной неподвижности.
Затем - компьютер показывает уже 19:42:09 - наступает первый тик нового бара - бара длительностью 42 минуты.
Тик отмечен 19:42:07 и - поскольку это бар 19:42, который приходит с ним - временная метка бара 19:42:00.
Теперь .... хммм ....
1. Всегда ли TimeCurrent() равен временной метке тика?
Я проверил 40.000 записей и нашел только пять случаев, в которых TimeCurrent уже переключен, а временная метка последнего тика - нет.
2. Всегда ли last_tick опережает открытие нового бара?
(будет продолжено)
TimeCurrent() - это время последнего тика с сервера, от вашего кода зависит, будет ли это время от символа вашего графика или нет.
Я не понимаю вашу проблему с "последним тиком", вы должны показать код, который выдал этот результат.
Привет Ален
Я проверяю TimeCurrent() в OnTick(), что должно гарантировать, что он принадлежит символу, с которым я имею дело.
Ну, это должен быть мой "Новый идентификатор бара" - маленький и быстрый - что вы думаете?
//--- 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);
Я собираюсь проверить его с помощью этого секвенса:
//--- 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;
}
Привет Ален
Я проверяю TimeCurrent() в OnTick(), что должно гарантировать, что он принадлежит символу, с которым я имею дело.
Ну, это должен быть мой "Новый идентификатор бара" - маленький и быстрый - что вы думаете?
Вот моя окончательная версия.
На самом деле я немного волнуюсь, потому что это так просто.
Ален: Было бы хорошо, если бы вы дали благословение.
// -----------------------------------------------------------------------
bool NewBar(void)
{
bool iNewBar = false;
static double currPeriodProgress = 0;
currPeriodProgress = MathMod(TimeCurrent(),PeriodSeconds());
return(iNewBar);
}
// ------------------------------------------------------------------------
void OnTick()
{
if(NewBar()) PlaySound("tick.wav");
Приветствую вас из Кельна
Вилбур
Самый простой способ:
static datetime tlastbar=0;
datetime tnewbar=iTime(NULL,PERIOD_CURRENT,0);
bool isnewbar=tnewbar!=tlastbar;
tlastbar=tnewbar;
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Мне интересно, как указать, когда новый бар видит свет.
В первую очередь я беспокоюсь о производительности. На некоторых символах я видел тики каждые 20 мс. Не так много времени для реакции.
Одна из идей - rates.tick_volume
Mqlrates rates[1];
OnInit()
{
if(CopyRates(_Symbol,_Period,0,1,rates) < 1)
if(rates[0].tick_volume == 1)
{
... deal with new bar ...
}
Другой идеей может быть проверка, было ли увеличено количество баров.
OnInit()
{
if(BarsOld < Bars(_Symbol,_Period))
{
BarsOld = Bars(_Symbol,_Period);
... deal with new bar ...
}
Я проверил также OnChartEvent, но не нашел способа отличить новые бары от других.
Спасибо за вашу оценку
WIllbur