Форум » Консультации по программированию » Я в шоке! Подскажите. » Ответить

Я в шоке! Подскажите.

Sergey: Всем привет! Я в шоке! Выпал из рынка на 3,5 месяца, а тут такие перемены. Игорь подскажи, где можно ознакомиться с изменениями в MQL4? Хотел перенести все данные на новый комп, но некоторые индикаторы после компиляции перестают работать. Вот один из них. http://gfile.ru/a8cCP Хотя не перекомпилированные файлы работают. Компиляция ошибок в коде не выявляет. Но при отладке выдается ошибка формирования массива стр.67. Но в чем ошибка не пойму. Буду благодарен, если найдешь время исправить.

Ответов - 204, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 All

Sergey: Scriptong пишет: В OnInit еще рано делать выводы о том, закачана история по нужному ТФ или нет. Проверить достаточность баров правильнее так: На сколько я понял, пытаться подкачивать историю в OnInit не правильно. Тогда ошибка понятна. Исправил все с учетом рекомендаций, вроде работает. Огромное спасибо!

Scriptong: Sergey пишет: пытаться подкачивать историю в OnInit не правильно Как раз правильно. В OnInit всегда стоит начать подкачку данных, просто обратившись в первому бару нужного таймфрейма. Но вот проверять результат там еще рано.

Sergey: Scriptong пишет: Как раз правильно. В OnInit всегда стоит начать подкачку данных, просто обратившись к первому бару нужного таймфрейма. Игорь, а обращение к первому бару нужного таймфрейма запускает подкачку историии и в советниках тоже?


Scriptong: Sergey пишет: Игорь, а обращение к первому бару нужного таймфрейма запускает подкачку историии и в советниках тоже? В MQL4 -да. При обращении к любому бару таймфрейма терминал, по идее, проверяет полноту истории по указанному символу/таймфрейму. Если какого-то бара нет, то запускается процесс подкачки истории, а вызванная функция генерирует ошибку, возвращая 0. Поэтому и используется подобный механизм проверки полноты истории. Но, сразу скажу, он не является идеальным, т. к. изначально не задумывался разработчиками именно таким образом. Поэтому "на все 100" надеяться на него не приходится. В MQL5 для решения этой проблемы есть специально разработанный способ получения данных с сервера.

Sergey: Игорь, подскажи, как определить координату "y" в "окне" у осциллятора ( к примеру Sto), "окна" массштабируются, а координаты нет. Мне нудно отобразить значения показаний индикатора (объектами Wingdings) на всех ТФ в "окне" осциллятора.

Scriptong: Sergey пишет: Игорь, подскажи, как определить координату "y" в "окне" у осциллятора ( к примеру Sto), "окна" массштабируются, а координаты нет. Мне нудно отобразить значения показаний индикатора (объектами Wingdings) на всех ТФ в "окне" осциллятора. Нужно больше информации. Что подразумевается под координатой Y? По моему пониманию, Y в подокнах - это значение индикатора. Также может быть значение в пикселях от одного из четырех углов подокна. И, кстати, уточните, какие исходные данные Вы хотите использовать для определения координат точки?

Sergey: Scriptong пишет: По моему пониманию, Y в подокнах - это значение индикатора. Именно так. Текущее значение индикатора на всех ТФ в виде точки нужно отобразить под соответствующими надписями (М1.....MN) справа от индикатора текущего ТФ. Картинку я дал по Sto, но буду делать WPR . Осциллятор WPR ограничен значениями (-100-0). Я не знаю, как можно перевести значение индикатора в пиксели с учетом масштабирования индикатора. Единственная идея, которая мне пришла - это перевести координату Х надписи соответствующего ТФ в смещение показаний значения индикатора от нулевого бара. (Перевести координиту Х во время и рассчитать смещение в барах). Но я этого ни разу не делал, а возможно есть и другие способы. Нужна Ваша консультация - как грамотнее сделать.

Scriptong: Sergey пишет: Именно так. Текущее значение индикатора на всех ТФ в виде точки нужно отобразить под соответствующими надписями (М1.....MN) справа от индикатора текущего ТФ. Картинку я дал по Sto, но буду делать WPR . Осциллятор WPR ограничен значениями (-100-0). Я не знаю, как можно перевести значение индикатора в пиксели с учетом масштабирования индикатора. Единственная идея, которая мне пришла - это перевести координату Х надписи соответствующего ТФ в смещение показаний значения индикатора от нулевого бара. (Перевести координиту Х во время и рассчитать смещение в барах). Но я этого ни разу не делал, а возможно есть и другие способы. Нужна Ваша консультация - как грамотнее сделать. Тут получается, что Х-координата должна быть в пикселях, а Y - в значениях индикатора. Таким образом, проблема решается преобразованием не Х-координаты, а Y-координаты. Х-координата должна быть известна всегда - это смещение столбца "таблицы" относительно правого верхнего угла подокна. Далее нужно преобразовать значение индикатора в пиксели для подокна. Для этого существует функция ChartTimePriceToXY. Только с ее помощью преобразуйте именно "цену" (так будет представляться значение индикатора) в Y. Время и, соответственно, Х в данном случае преобразовывать не нужно.

Sergey: Scriptong пишет: Для этого существует функция ChartTimePriceToXY. Я уже пробовал делать через нее. ChartTimePriceToXY(0, WindowFind(short_name),TimeCurrent(), SlowWPR, X_SlowWPR, Y_SlowWPR); Но координата У, как выяснилось, отсчитывается от верхней границы графика, а не подокна. Т.е если поднять окно до верхней граници графика, то все отображается, правда все равно со смещением по у. В нормальном же виде, данные даже не попадают в зону видимости подокна. Чтобы использовать данный способ, надо как то определить координату У подокна в системе координат окна основного графика. Я не знаю, как это сделать.

Scriptong: Sergey пишет: Чтобы использовать данный способ, надо как то определить координату У подокна в системе координат окна основного графика. Я не знаю, как это сделать. Эта задача точно такая же: datetime GetAddBarToTime(datetime srcTime, int addBars) { int srcBar = iBarShift(NULL, 0, srcTime); if (srcBar >= addBars) return iTime(NULL, 0, srcBar - addBars); return iTime(NULL, 0, 0) + (addBars - srcBar) * PeriodSeconds(); } ... int subWnd = WindowFind("<имя индикатора>"); if (subWnd < 0) return; int x0, y0; int firstBar = WindowFirstVisibleBar(); int totalBars = WindowBarsPerChart(); datetime lastBarTime = GetAddBarToTime(iTime(NULL, 0, firstBar), totalBars); if (!ChartTimePriceToXY(0, subWnd, lastBarTime, indicator_maximum, x0, y0)) Print("ChartTimePriceToXY error: ", GetLastError()); else Print("x0 = ", x0, ", y0 = ", y0); Таким образом определяете координаты верхнего правого угла подокна относительно левого верхнего угла графика. А далее, получив координаты нужной точки, вычитаете из этих координат "нулевые" координаты.

Sergey: Scriptong пишет: Таким образом определяете координаты верхнего правого угла подокна относительно левого верхнего угла графика. А далее, получив координаты нужной точки, вычитаете из этих координат "нулевые" координаты. Игорь, огромное спасибо! Идея понятна, реализация удалась.

Sergey: Игорь, есть вопрос, но даже не знаю как его сформулировать, чтобы было понятно. Я сделал индикатор и советник на его основе. Обращение к данным индикатора сделал через iCustom. Теперь хочу встроить индикатор в советник. Проблема в том, что индикатор рассчитывается при помощи нескольких циклов, то есть нельзя взять и рассчитать нужные бары без циклов. В индикаторе, чтобы повторно не рассчитывать циклы используем limit = GetRecalcIndex(total, rates_total, prev_calculated); Как это можно реализовать в советнике?

Scriptong: Sergey пишет: Теперь хочу встроить индикатор в советник. Проблема в том, что индикатор рассчитывается при помощи нескольких циклов, то есть нельзя взять и рассчитать нужные бары без циклов. Сегодня уже отвечал на подобный вопрос в другом месте (Недискретные рэндж-бары). Суть в том, что для каждого конкретного индикатора пишется свой собственный алгоритм расчета данных в советнике. В большинстве случаев такой алгоритм будет проще, если все сделать правильно.

Sergey: Scriptong пишет: В большинстве случаев такой алгоритм будет проще, если все сделать правильно. А как правильно? В смысле, какие есть варианты? К примеру, я сейчас просто сокращаю количество проходов по циклам до достаточного и вместо динамического массива использую статический, плюс ограничиваю расчет только открытием нового бара. Была идея перекопирования массива со смещением на одну позицию, тогда в расчет попадает только последний бар. Но запнулся на проверке. Ведь возможны пробелы в следствии, к примеру, разрыва связи с терминалом.

Scriptong: Sergey пишет: А как правильно? В смысле, какие есть варианты? Вариантов настолько много, что все их не перебрать. Проблема в том, что даже если я покажу пример встраивания индикатора в советник, то этот пример подойдет только для одного конкретного индикатора. Сделать по образу и подобию для другого индикатора не получится. Общий смысл встраивания индикаторов, показания которых основаны на своих же предыдущих показаниях, заключается в повторении этой цепочки расчетов в советнике. Для этого не нужно создавать массив, длинной во всю историю котировок. Во многих случаях достаточно всего двух значений: предыдущего и текущего. Эти значения проходят по всей истории, передавая эстафету друг другу. Подобным образом работают индикатор Divergence_Viewer и советник Divergence. Чтобы не мучаться каждый раз со встраиванием индикатора во советник, я разработал единый класс CDivergence, который подключается к любой программе.



полная версия страницы