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

Я новичок.

Anatoliy: Пишу пользовательский индикатор на основе пересечение уровни 20 и 80. Если главная линия Stochastic пересекла уровень 80 (сверху - вниз), то выводит стрелка Sell на ценовых графиках, а если главная линия Stochastic пересекла уровень 20 (снизу - верх), то стрелка Buy на ценовых графиках. #property strict #property indicator_chart_window #property indicator_buffers 2 //--- plot Buy #property indicator_type1 DRAW_ARROW #property indicator_color1 clrGreen #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot Sell #property indicator_type2 DRAW_ARROW #property indicator_color2 clrRed #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- input parameters //--- indicator buffers double BuyBuffer[]; double SellBuffer[]; //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж //+------------------------------------------------------------------+ //| Функция инициализации пользовательского индикатора | //+------------------------------------------------------------------+ int init() { //--- SetIndexBuffer(0,BuyBuffer); SetIndexArrow(0,233); SetIndexStyle(0,DRAW_ARROW); //--- SetIndexBuffer(1,SellBuffer); SetIndexArrow(1,234); SetIndexStyle(1,DRAW_ARROW); //--- SetIndexEmptyValue(0,80.0); SetIndexEmptyValue(1,20.0); //--- return(0); } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж //+------------------------------------------------------------------+ //| Функция пользовательского индикатора итерации | //+------------------------------------------------------------------+ int start() { //--- int i, Counted_bars; double mainStoc_1 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,1); // бар 1 double mainStoc_2 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,2); // бар 2 Counted_bars=IndicatorCounted(); // Количество просчитанных баров i=Bars-Counted_bars-1; for(i=0;i>=0;i--) { if (mainStoc_2 > 80.0 && mainStoc_1 < 80.0) SellBuffer = Low-5*Point; else SellBuffer = 0.0; if (mainStoc_2 < 20.0 && mainStoc_1 > 20.0) BuyBuffer = High+5*Point; else BuyBuffer = 0.0; } //--- return(0); } И в результатах индикатор вообще не работает. Как его исправит?

Ответов - 300, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 All

Anatoliy: Anatoliy пишет: По всей видимости, прямоугольники Вы не обновляете, создавая новые. Я не знаю как!

Scriptong: Anatoliy пишет: Я не знаю как! Два раза уже писал Вам: необходимо оформить еще одно условие, которое будет выполняться в теле цикла, если нет пересечений. А Вы зачем-то убрали условия пересечения и на каждом новом баре создаете новый прямоугольник. Всего-то нужно было добавить три строки: lastHigh = MathMax(lastHigh, High[ i ]); lastLow = MathMin(lastLow, Low[ i ]); ShowRectangle(PREFIX + IntegerToString(lastCrossTime), 0, lastCrossTime, lastHigh, Time[ i ], lastLow); В итоге получаем такой индикатор. P. S. Ну и удалять все объекты при деинициализации индикатора нельзя. Удалять можно только то, что сама же программа и создала. Для этого существует пользовательская функция DeleteObjectsAll (не путать со штатной ObjectsDeleteAll).

Anatoliy: Игорь, спасибо! У меня не опыты, не давно я прошёл на Си. Оказалось не так просто, но и надо знать хорошо по математике, не хорошо надо знать, а отлично знать по математике. И я начал в MQL4, брал простейшие примеры в сайте MQL4 и придумывал что-то иногда не получается.


Scriptong: Anatoliy пишет: И я начал в MQL4, брал простейшие примеры в сайте MQL4 и придумывал что-то иногда не получается. Штудируйте учебник от корки до корки, пока он не станет для Вас полностью понятным. Несмотря на то, что язык обновился, учебник не потерял свою актуальность - это как раз та информация, которая необходима для начального уровня программирования.

Anatoliy: Я посмотрел, на много отличается: 1) да, не надо убрать условия пересечения. 2) lastHigh и lastLow инициализированы нули для того чтобы обновит и были добавлены две строки в конце теле цикла для того чтобы присвоит максимальное и минимальное число из двух значений. 3) был заменён на for, на сколько я знаю самые популярные операторы это for и if. И добавлены операторы continue для того чтобы пропустит. 4) заметны ShowRectangle() параметры 5) DeleteObjectsAll() чем отличие от стандартного ObjectsDeleteAll? Я ещё хочу добавит временной период, а прямоугольники показывает везде, т.е ShowRectangle() добавит ещё один параметр? И кое-что я обнаружил, что прямоугольник не дорисовывает, значит добавит стандартного функция WindowRedraw() для того чтобы перерисовал прямоугольник?

Scriptong: Anatoliy пишет: lastHigh и lastLow инициализированы нули для того чтобы обновит и были добавлены две строки в конце теле цикла для того чтобы присвоит максимальное и минимальное число из двух значений. Фактически не влияет на результат. Просто правило хорошего тона, которое в некоторых случаях (не предусмотришь, когда) избавит от неуловимых багов. Anatoliy пишет: был заменён на for, на сколько я знаю самые популярные операторы это for и if. И добавлены операторы continue для того чтобы пропустит. Экономит три строки на переходе к новой итерации цикла. Иначе везде, где стоит continue, пришлось бы еще и i++ писать. Anatoliy пишет: заметны ShowRectangle() параметры Не заменены, а использованы умолчательные значения для использования более коротких вызовов функции. Anatoliy пишет: DeleteObjectsAll() чем отличие от стандартного ObjectsDeleteAll? Посмотрите тело функции. При использовании ObjectsDeleteAll удаляются все объекты на графике, в том числе те, которые созданы другими программами. Так поступать нельзя. Удалять можно лишь те объекты, которые программа сама создала.

Anatoliy: Добрый суток, Игорь. Как правильно записать условии, например, 3 МА смотрит вверх, вот код: double ma_Red_1 = iMA(NULL, 0, period_1, 0, method, price, i+1); double ma_Green_1 = iMA(NULL, 0, period_1, 0, method, price, i+1); double ma_Blue_1 = iMA(NULL, 0, period_1, 0, method, price, i+1); double ma_Red_2 = iMA(NULL, 0, period_1, 0, method, price, i+2); double ma_Green_2 = iMA(NULL, 0, period_1, 0, method, price, i+2); double ma_Blue_2 = iMA(NULL, 0, period_1, 0, method, price, i+2); //--------------------------------------------------------------------------------- if(ma_Red_0 > ma_Green_0 && ma_Green_0 > ma_Blue_0 && ma_Red_0 > ma_Blue_0 && ma_Red_1 < ma_Green_1 && ma_Green_1 < ma_Blue_1 && ma_Red_1 < ma_Blue_1) { // Buy }

Scriptong: Anatoliy пишет: Как правильно записать условии, например, 3 МА смотрит вверх, вот код: Для пересечения трех МА "правильного" алгоритма не существует, т. к. в этом случае возможно несколько подходов к определению момента пересечения. Ведь очевидно, что пересекаются три линии не в одной точке. Сначала пересекается две линии, а потом к ним подтягивается (или не подтягивается до обратного пересечения) третья линия. Поэтому правильность будет определяться только постановкой условия пересечения вверх и пересечения вниз. Какие критерии для определения каждого из состояний хотите описать Вы?

Anatoliy: Scriptong пишет: Для пересечения трех МА "правильного" алгоритма не существует, т. к. в этом случае возможно несколько подходов к определению момента пересечения. Ведь очевидно, что пересекаются три линии не в одной точке. Сначала пересекается две линии, а потом к ним подтягивается (или не подтягивается до обратного пересечения) третья линия. Я понял. Вначале хочу построит индикатор для исследования, и самому определить критерии на основе Alligator с тремя прямоугольниками (как ObjRectangle_2MA v.1) рис. 1 Зелёный прямоугольник (Быстрая МА > Средняя МА > Медленная МА) Красный прямоугольник (Быстрая МА < Средняя МА < Медленная МА) Серый прямоугольник (не соотвествует, Быстрая МА < Средняя МА > Медленная МА и Быстрая МА > Средняя МА < Медленная МА) Игорь, почему прямоугольник не дорисовывает (инд. ObjRectangle_2MA v.1) рис. 2

Scriptong: Anatoliy пишет: Зелёный прямоугольник (Быстрая МА > Средняя МА > Медленная МА) Красный прямоугольник (Быстрая МА < Средняя МА < Медленная МА) Серый прямоугольник (не соотвествует, Быстрая МА < Средняя МА > Медленная МА и Быстрая МА > Средняя МА < Медленная МА) Тогда так: if(ma_Red_1 > ma_Green_1 && ma_Green_1 > ma_Blue_1 { // Зеленый прямоугольник (начало формирования или продолжение) } else if(ma_Red_1 < ma_Green_1 && ma_Green_1 < ma_Blue_1 { // Красный прямоугольник (начало формирования или продолжение) } else { // Серый прямоугольник (начало формирования или продолжение) } В этом случае проверять пересечения попросту не нужно. Нужно лишь следить за тем, какой объект сейчас отображается. Anatoliy пишет: Игорь, почему прямоугольник не дорисовывает (инд. ObjRectangle_2MA v.1) Потому что эта версия индикатора не предназначена для работы онлайн. Для онлайн в ней еще много неучтенностей, рассказывать о которых Вам преждевременно как минимум до тех пор, пока не Вы научитесь самостоятельно формализовать простейшие задачи типа пересечения МА. Промежуточным решением может быть следующее изменение в коде: static datetime lastCrossTime = 0; static double lastHigh = 0, lastLow = 0; Но, опять же, этот вариант не учитывает моменты непоследовательного обновления истории.

Anatoliy: Добрый суток, Игорь. Я почти научился создавать простейшие пользовательские индикаторы, а, вот, когда усложняю я его, то у меня возникает трудности понимание , т.е. в интерпретаторе ругается, например:2014.10.05 19:40:24.438 array out of range in 'i_arrowSignals_v1.mq4' (89,15) Как вы сами разбираете, подсчитываете и так далее? Как мне самому понимать?

Scriptong: Когда в программе происходит что-то, недоступное пониманию, необходимо прибегать к ее отладке - документированию каждого ее шага. В самом сложном случае достаточно расположить операторы Print после каждой строки программы с выводом в журнал значений всех переменных, которые используются на данном шаге программы. Это поможет наглядно представить выполнение программы. В приведенном примере интерпретатор указывает на выход за пределы массива в строке 89, символ 15. Скорее всего, использован индекс массива-таймсерии (High, Los, Open Close, Volume), который больше или равен Bars. Такая ошибка устраняется проведением проверки на корректность индекса перед его использованием в массиве. К примеру: int index = ...; ... if (index >= 0 && index < Bars) price = High[index];

Balbesik: Добрый вечер, Игорь! Сегодня у меня «настроение» - вроде 722 билд нормально работает. Просто «под настроение по наглею» и несколько консультаций попрошу. Понятно, что для участников форума это некорректно и их покоробит. Но ты умеешь доступно и заинтересованно для других объяснять. Речь о MultiIndicators_AutoOptimize_Expert (такая тема в статьях у тебя была). 1. Пытаясь перейти на МТ5, для решения проблемы «накопления памяти» - есть ли смысл? Т.е. невозможность импорта котировок (только навязанный сервер) приведет к « тупику» «Хвостов» - это ВТБ в свое время прошли с Онлайнброкером (мне понравилось, что в Маркете («Хвостов») у тебя = 0 и вообще они превратили свой форум в рынок (базар – книжки, журналы, заказы и прочее), но это их проблемы). Возникает вопрос – есть ли смысл заниматься МТ5 в свете их политики (это им не базар и их в конечном итоге «пошлют») , но сиюминутно решит ли мою проблему МТ5, в части накопления памяти в реале без перезагрузки (чем тогда МТ от Квика отличается)? 2. Чисто технические моменты по МТ4. //while (!IsStopped()) //{ // start(); // Sleep(i_pause); //} Вот эта твоя часть, четко работает в офлайне (не требуется принудительный тик), но для реала ее надо комментировать (с задержкой разбираться проблемно). Можно ли организовать программное отключение в реале – критерий? Работа советника, с т.з. программиста – Какой вариант более предпочтительней? Связанно ( к примеру) с моим недопониманием по МТ5 и твоим объяснениями. if(IsTesting()) { if(TimeCurrent()<StrToTime(i_TesterStartDateTime)) { Print(" TestingXXXXXXXXXXXX: = ",1," TimeCurrent(): = ",TimeCurrent()); return (0); } } // if(IsTesting()) // { // if(iBars(NULL,PERIOD_D1)<i_optimizeDaysAmount) // { // Print(" TestingXXXXXXXXXXXX: = ",1," TimeCurrent(): = ",TimeCurrent()); // return (0); // } // } // if(IsTesting()) // { // if(Bars < (PERIOD_D1*i_optimizeDaysAmount)) // { // Print(" TestingXXXXXXXXXXXX: = ",1," TimeCurrent(): = ",TimeCurrent()); // return (0); // } // } В связи с предварительным обменом мнениями вытекает , что «сбросить память» советником в реале без перезагрузки проблемно. Тогда логически вытекает – идем к полуавтомату. Тогда на первое место (особенно в свете МТ5) выходит твоя тема – «Тестирование на реальной истории» , но на нестандартных графиках я ее еще не проверял (думаю работать будет). Штатный тестер «сбрасывает память» (серьезное и принципиальное отличие) и половину ты сделал, но тогда частный вопрос: «А как с этим – «Нет, не нужно. В пределах истории, которая существует в FXT-файле тестер может обращаться к данным любого ТФ. Ведь FXT-файл - это тиковый файл, из которого можно получить любой ТФ, что тестер и делает. P. S. Для успокоения совести проверил этот момент в двух опытах: 1. На М1 FXT-файле правильно прочитаны данные со всех старших ТФ. 2. На D1 FXT-файле правильно прочитаны данные со всех младших ТФ.» - половина «ручной работы уже решено, а вместо «ручек» запустить советник, а ему нужен штатный ТФ 1 (1440 баров) день и «загнать» результаты в реал?» И на перспективу – А можно ли результаты тестирования штатного тестера «загнать» в советник автоматом (я понимаю, что при желании все можно).

Scriptong: Balbesik пишет: Возникает вопрос – есть ли смысл заниматься МТ5 в свете их политики (это им не базар и их в конечном итоге «пошлют») , На сегодняшний день их (компании Meta Quotes) позиции крепки. Но так как жизнь полна сюрпризов, то прогнозирование (сколько еще просуществует компания) дело неблагодарное. но сиюминутно решит ли мою проблему МТ5, в части накопления памяти в реале без перезагрузки (чем тогда МТ от Квика отличается)? Не решит, т. к. подход там такой же - индикаторы не выгружаются до конца тестирования.

Scriptong: Balbesik пишет: 2. Чисто технические моменты по МТ4. //while (!IsStopped()) //{ // start(); // Sleep(i_pause); //} Вот эта твоя часть, четко работает в офлайне (не требуется принудительный тик), но для реала ее надо комментировать (с задержкой разбираться проблемно). Можно ли организовать программное отключение в реале – критерий? Эту часть уже можно заменить на более удобную с точки зрения программирования. В MQL4 появился таймер, что избавляет от необходимости использования зацикленных участков кода. Теперь все это можно переписать так: int OnInit() { ... EventSetMillisecondTimer(пауза в миллисекундах); ... } void OnTimer() { // код для выполнения каждые "пауза в миллисекундах" миллисекунд } Что подразумевается под программным отключением и о каком критерии ты спрашиваешь?



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