//-----------------------------------------------------------------------------+ // Киму Респект и уважуха !!! | //+----------------------------------------------------------------------------+
Это,несомненно, была самая нагрузочная часть кода))))
Так. Я вот ниччч-чегошеньки не понимаю. Довёл до ума секундный ТФ. Всё должно работать как часы. Но не работает. Нет, работать-то работает, но не так как ожидается. Тысячу раз всё перепроверял. Ни синтактических, ни алгоритмических ошибок сам не вижу. Попробую объяснить, полный код прикрепляю. Итак:
Δtime=TimeCurrent()-time;//перестраховка на случай, если TimeCurrent() во время выполнения цикла изменитсяswitch(Δtime){
case0 ://если секунда не прошла
AccumulatorOfTicks(false);//заносим в массив-накопительbreak;
case1 ://если прошла ОДНА секунда после последнего тика
WriteBar();//по предыдущему тику рисуем свечу
AccumulatorOfTicks(true);//и ловим текущий тикbreak;
default://если прошло НЕСКОЛЬКО секунд после последнего тика
WriteBar();//по предыдущему тику рисуем свечу
Δtime--; time++;//уменьшаем разницу на единицу, т.к. свечу уже нарисовалиwhile(Δtime!=0) WriteDash();//и рисуем прочерки по кол-ву пропущ. сек. минус один
AccumulatorOfTicks(true);//ловим текущий тик
}
Здесь в начале start() поставил обработчик по количеству пройденных с момента последнего запуска start() секунд. Повторяющиеся участки вынес в пользовательские функции. Новое значение time=TimeCurrent() присваивается там же, в пользовательских функциях.
void AccumulatorOfTicks(bool AtFirst){
if (AtFirst){
ArrayResize(bid, 1);//урезаем использованные массивыArrayResize(ask, 1);
i=0;//обнуляем счётчик тиков в секунду
time=TimeCurrent();//приводим счётчик времени к текущему
}else{
ArrayResize(bid, i+1);
ArrayResize(ask, i+1);
i++;
}
bid[i]=MarketInfo(symbol, MODE_BID);
ask[i]=MarketInfo(symbol, MODE_ASK);
if (bid[i]==ask[i]) Alert("from accumulator: bid=ask");
}
Функция работает в двух режимах: в первой ветке, AtFirst=true она только ловит тик, с предварительным обнулением массивов-накопителей, а во второй ветке, AtFirst=false, она работает именно как накопитель тиков. То есть мы либо обнуляем и урезаем накопитель и ловим бид-аск в нулевую ячейку, либо удлинняем накопитель и ловим бид-аск. Алерт ставил только для отладки. Условие обнуления накопителя распишу дальше.
void WriteBar(){
if(FileSeek(hand1e, fpos, SEEK_SET) == false){//перемещаем указатель на новую позицию, которую мы запомнили в FileTell//проверяем, переместилось-не переместилось, это я убрал, т.к. к вопросу не относится.
}else{
FileWriteInteger(hand1e, time, LONG_VALUE);//TimeCurrent()FileWriteDouble (hand1e, bid[0], DOUBLE_VALUE);//Open[]FileWriteDouble (hand1e, bid[ArrayMaximum(bid)], DOUBLE_VALUE);//High[]FileWriteDouble (hand1e, ask[ArrayMinimum(ask)], DOUBLE_VALUE);//Low[]FileWriteDouble (hand1e, ask[ArraySize(ask)-1], DOUBLE_VALUE);//Close[]FileWriteDouble (hand1e, ArraySize(ask), DOUBLE_VALUE);//Volume[]FileFlush (hand1e);
fpos = FileTell (hand1e);//запоминаем позицию записи в файлеif(ArraySize(ask)==2) Alert(StringConcatenate(TimeToStr(TimeCurrent(), TIME_SECONDS), " - volume = ", ArraySize(ask)));
if(bid[0]==ask[ArraySize(ask)-1]) Alert(StringConcatenate(TimeToStr(TimeCurrent(), TIME_SECONDS), " - bid=ask, Ticks = ", ArraySize(ask)));
/*Необходимое пояснение. Хотя код рассчитан в т.ч. на тени свечей (т.е. независимыми от Open и Close
High и Low), в реальности их на чарте не будет, т.к. в секунде максимум 2 тика, три тика в секунде
я ещё не встречал. Поэтому в массиве из двух элементов (т.е. двух тиков)
один будет максимумом, другой минимумом, - и невольно совпадать с Open и Close.*/
}
}
Функция "рисования" свечи (занесения свечи в .hst, открытый в автономном чарте). Аналогично - алерты ставил для отладки. Первый алерт сигналит при двух пойманных тиках в одну секунду (размер массива равен двум, и по идее объём должен быть равен двум), а второй при биде, равном аску в пойманном тике (аналогичному алерту в накопителе: но работают они почему-то несинхронно), и объём свечи. Это всё по идее, на деле при занесённой в файл (по алерту) например двойке (или 0х00 00 00 00 00 00 00 40, double 2.0) там почему-то всё равно оказывается один (0х00 00 00 00 00 00 F0 3F, double 1.0 в формате BigEndian). Тот алерт в накопителе я обычно закомменчиваю, сигналит часто, с этими двумя работаю.
void WriteDash(){
if(FileSeek(hand1e, fpos, SEEK_SET) == false){//перемещаем указатель на новую позицию, которую мы запомнили в FileTell//аналогично убрал, т.к. к вопросу не относится.
}else{//ставим прочерк на Close[0]
Δtime--; time++;
FileWriteInteger(hand1e, time, LONG_VALUE);//TimeCurrent()FileWriteDouble (hand1e, ask[ArraySize(ask)-1], DOUBLE_VALUE);//Open[]FileWriteDouble (hand1e, ask[ArraySize(ask)-1], DOUBLE_VALUE);//High[]FileWriteDouble (hand1e, ask[ArraySize(ask)-1], DOUBLE_VALUE);//Low[]FileWriteDouble (hand1e, ask[ArraySize(ask)-1], DOUBLE_VALUE);//Close[]FileWriteDouble (hand1e, 0, DOUBLE_VALUE);//Volume[]FileFlush (hand1e);
fpos = FileTell (hand1e);//запоминаем позицию записи в файле
}
}
Функция "рисования" прочерка в случае, если в какую секунду тика не было. Работает всё по следующему алгоритму:
Δtime=0: ловим (копим) тики.
Δtime=1: рисуем свечу по пойманному до этого тику, потом ловим тик (с предварительным обнулением накопителя).
Δtime>1: рисуем свечу по пойманному до этого тику, рисуем прочерки по линии Close[0] в количестве Δtime-1, ловим тик (с предварительным обнулением накопителя). Накопитель во всех случаях обнуляем тогда, когда свеча по нему уже нарисована и значит нам аккумулятор больше не нужен. Это бывает при Δtime>0.
Прогоняем:
Стрелочкой подрисовал моменты, где бид по идее равен аску, и объём должен быть по идее равен единице. Я не захватил низ с объёмами, там всё равно нифига не видно, мелко. Но они все вровень, то есть либо ноль, либо один, ни один до двух не поднимается (хотя алерт сигналит). Два тика в секунду - всё равно при наведении мышки железно высвечивается volume=1, а бид равен аску тоже железно высвечивается volume=0. Почему? Я понимаю что где-то ошибка, но скорее всего, ошибку не замечаю или не там смотрю. Прикрепляю код, в своей части всё хорошо раскомментировал, за отступами везде проследил, инклюдники убрал, только выбрал из них используемые функции, чтобы компилилось быстрее. Единственное замечание - в оффлайне, т.е. с TimeLocal, в отличие от оригинального сборщика тиков, не работает, потому что в if(tickTimeLocal==true) я там от балды написал (т.к. мне это больно не надо было). Пробовал перевести в советника по совету Тараса, - свечи тогда не высвечиваются в автономном чарте (хотя линия текущей котировки нормально двигается).
Появился такой вопрос. Допустим сегодня понедельник. Мне надо узнать цену закрытия в пятницу. Могу ли я так писать
iClose(NULL, Period_D1, 1)
Вопрос такой потому появился, что на тестере вижу бары суботы и восккресья. Но в эти дни торговля неведеться. Выше написана строка даст цену закрытия пятницы или воскресения ?
Появился такой вопрос. Допустим сегодня понедельник. Мне надо узнать цену закрытия в пятницу. Могу ли я так писать
Вопрос такой потому появился, что на тестере вижу бары суботы и восккресья. Но в эти дни торговля неведеться. Выше написана строка даст цену закрытия пятницы или воскресения ?
Даст цену пятницы! Если сервер закрывает не позже 24.00 в пятницу и начинает не раньше 0.00 после воскресенья!
Рекомендую перед высланием ордера обновлять котировки:
RefreshRates();
OrderSend (...);
И обратите внимание, что слипадж у вас =3, для 4-значных котировок будет =3 пункта, а для 5-значных будет рассчитывать как 0,3 пункта. Поэтому если советник будет работать с 5-значными котировками, то ставте слипадж = 30.
на алерте равном 2 снимаю индикатор с минуток, провожу мышкой по свече... Volume=1.
Смотрел RateInfo в hst через FileInsight (типа дебагера), думаю может там int, а не double в Volume - нет, таки-double...
Посмотрел Ваш код.... слишком вы все запутали)))
Я не вполне понимаю, зачем аккумулировать тики, ведь нам достаточно хранить в памяти (или даже не хранить, ведь текущий бар надо писать в HST - иначе график не будет обновляться) параметры текущего бара - шесть чисел TOHLCV, и при поступлении тиков обновлять их по мере необходимости, а по заданному условию (TimeCurrent()-O>1) делать отсечку баров.
Попробуйте переработать код таким образом, он сократится раз в 8, я гарантирую это (проверено:)
Интересная тут ситуация.ДУмал затестить один индикатор,вывел цифры на график,а сколько не жди они не меняются.попробую сказать по другому,мне от приложенного надо чтобы как крестик встает на зигзаг цена или алертом или принтом фиксировалась,а она застывает на момент подключения.При смене тайм фрейма значения меняются,но стоит вернуться и цифры те же самые,подскажите пожалуйста как это можно исправить.
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
//-----------------------------------------------------------------------------+
// Киму Респект и уважуха !!! |
//+----------------------------------------------------------------------------+
Это,несомненно, была самая нагрузочная часть кода))))
Так. Я вот ниччч-чегошеньки не понимаю. Довёл до ума секундный ТФ. Всё должно работать как часы. Но не работает. Нет, работать-то работает, но не так как ожидается. Тысячу раз всё перепроверял. Ни синтактических, ни алгоритмических ошибок сам не вижу. Попробую объяснить, полный код прикрепляю. Итак:
Здесь в начале start() поставил обработчик по количеству пройденных с момента последнего запуска start() секунд. Повторяющиеся участки вынес в пользовательские функции. Новое значение time=TimeCurrent() присваивается там же, в пользовательских функциях.
Функция работает в двух режимах: в первой ветке, AtFirst=true она только ловит тик, с предварительным обнулением массивов-накопителей, а во второй ветке, AtFirst=false, она работает именно как накопитель тиков. То есть мы либо обнуляем и урезаем накопитель и ловим бид-аск в нулевую ячейку, либо удлинняем накопитель и ловим бид-аск. Алерт ставил только для отладки. Условие обнуления накопителя распишу дальше.
Функция "рисования" свечи (занесения свечи в .hst, открытый в автономном чарте). Аналогично - алерты ставил для отладки. Первый алерт сигналит при двух пойманных тиках в одну секунду (размер массива равен двум, и по идее объём должен быть равен двум), а второй при биде, равном аску в пойманном тике (аналогичному алерту в накопителе: но работают они почему-то несинхронно), и объём свечи. Это всё по идее, на деле при занесённой в файл (по алерту) например двойке (или 0х00 00 00 00 00 00 00 40, double 2.0) там почему-то всё равно оказывается один (0х00 00 00 00 00 00 F0 3F, double 1.0 в формате BigEndian). Тот алерт в накопителе я обычно закомменчиваю, сигналит часто, с этими двумя работаю.
Функция "рисования" прочерка в случае, если в какую секунду тика не было. Работает всё по следующему алгоритму:
Δtime=0: ловим (копим) тики.
Δtime=1: рисуем свечу по пойманному до этого тику, потом ловим тик (с предварительным обнулением накопителя).
Δtime>1: рисуем свечу по пойманному до этого тику, рисуем прочерки по линии Close[0] в количестве Δtime-1, ловим тик (с предварительным обнулением накопителя). Накопитель во всех случаях обнуляем тогда, когда свеча по нему уже нарисована и значит нам аккумулятор больше не нужен. Это бывает при Δtime>0.
Прогоняем:
Стрелочкой подрисовал моменты, где бид по идее равен аску, и объём должен быть по идее равен единице. Я не захватил низ с объёмами, там всё равно нифига не видно, мелко. Но они все вровень, то есть либо ноль, либо один, ни один до двух не поднимается (хотя алерт сигналит). Два тика в секунду - всё равно при наведении мышки железно высвечивается volume=1, а бид равен аску тоже железно высвечивается volume=0. Почему? Я понимаю что где-то ошибка, но скорее всего, ошибку не замечаю или не там смотрю. Прикрепляю код, в своей части всё хорошо раскомментировал, за отступами везде проследил, инклюдники убрал, только выбрал из них используемые функции, чтобы компилилось быстрее. Единственное замечание - в оффлайне, т.е. с TimeLocal, в отличие от оригинального сборщика тиков, не работает, потому что в if(tickTimeLocal==true) я там от балды написал (т.к. мне это больно не надо было). Пробовал перевести в советника по совету Тараса, - свечи тогда не высвечиваются в автономном чарте (хотя линия текущей котировки нормально двигается).
ваши портянки.
Здраствуйте
Появился такой вопрос. Допустим сегодня понедельник. Мне надо узнать цену закрытия в пятницу. Могу ли я так писать
Вопрос такой потому появился, что на тестере вижу бары суботы и восккресья. Но в эти дни торговля неведеться. Выше написана строка даст цену закрытия пятницы или воскресения ?Здраствуйте
Появился такой вопрос. Допустим сегодня понедельник. Мне надо узнать цену закрытия в пятницу. Могу ли я так писать
Вопрос такой потому появился, что на тестере вижу бары суботы и восккресья. Но в эти дни торговля неведеться. Выше написана строка даст цену закрытия пятницы или воскресения ?Даст цену пятницы! Если сервер закрывает не позже 24.00 в пятницу и начинает не раньше 0.00 после воскресенья!
Пользуйтесь индикатором DailyPivotPoints!
Не, я решительно ничего не понимаю. Явно уже пишу
на алерте равном 2 снимаю индикатор с минуток, провожу мышкой по свече... Volume=1.
Смотрел RateInfo в hst через FileInsight (типа дебагера), думаю может там int, а не double в Volume - нет, таки-double...
Добрый вечер.
Спасибо за ответ на мой вопрос))
Подскажите плз, если открываешь ордер на покупку то так OrderSend (Symbol(),OP_BUY,Lot,Ask,3,0,0,"Покупка",0,0,Green);
а если на продажу OrderSend (Symbol(),OP_SELL,Lot,Ask,3,0,0,"Продажа",0,0,Red);
разница в синем цвете??? или еще нужно и красный цвет менять??? т.е. где OP_BUY там цена Bid
где OP_SELL там цена Ask
и если все верно и менять ничего не надо, то почему на тестере все гуд, на деме все гуд, а на РЕАЛЕ "Ошибка открытия ордера 129" хелп плз.
Добрый вечер.
Спасибо за ответ на мой вопрос))
Подскажите плз, если открываешь ордер на покупку то так OrderSend (Symbol(),OP_BUY,Lot,Ask,3,0,0,"Покупка",0,0,Green);
а если на продажу OrderSend (Symbol(),OP_SELL,Lot,Ask,3,0,0,"Продажа",0,0,Red);
разница в синем цвете??? или еще нужно и красный цвет менять??? т.е. где OP_BUY там цена Bid
где OP_SELL там цена Ask
и если все верно и менять ничего не надо, то почему на тестере все гуд, на деме все гуд, а на РЕАЛЕ "Ошибка открытия ордера 129" хелп плз.
Добрый вечер.
Спасибо за ответ на мой вопрос))
Подскажите плз, если открываешь ордер на покупку то так OrderSend (Symbol(),OP_BUY,Lot,Ask,3,0,0,"Покупка",0,0,Green);
а если на продажу OrderSend (Symbol(),OP_SELL,Lot,Ask,3,0,0,"Продажа",0,0,Red);
...На продажу:
Рекомендую перед высланием ордера обновлять котировки:
RefreshRates(); OrderSend (...);И обратите внимание, что слипадж у вас =3, для 4-значных котировок будет =3 пункта, а для 5-значных будет рассчитывать как 0,3 пункта. Поэтому если советник будет работать с 5-значными котировками, то ставте слипадж = 30.Не, я решительно ничего не понимаю. Явно уже пишу
на алерте равном 2 снимаю индикатор с минуток, провожу мышкой по свече... Volume=1.
Смотрел RateInfo в hst через FileInsight (типа дебагера), думаю может там int, а не double в Volume - нет, таки-double...
Посмотрел Ваш код.... слишком вы все запутали)))
Я не вполне понимаю, зачем аккумулировать тики, ведь нам достаточно хранить в памяти (или даже не хранить, ведь текущий бар надо писать в HST - иначе график не будет обновляться) параметры текущего бара - шесть чисел TOHLCV, и при поступлении тиков обновлять их по мере необходимости, а по заданному условию (TimeCurrent()-O>1) делать отсечку баров.
Попробуйте переработать код таким образом, он сократится раз в 8, я гарантирую это (проверено:)