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

Я новичок.

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

Scriptong: Добрый день, Анатолий. Давайте начнем с азов: как работает индикатор? Функция start индикатора запускается только под одному событию - приходу нового тика. Так, если мы только что запустили индикатор на выполнение, то он обработает только один пришедший тик. Пользователю же нужно, чтобы индикатор отобразил свои показания на всей или хотя бы на части доступной истории. Таким образом, необходимо иметь в виду, что при первой загрузке индикатор должен рассчитать свои показания для уже имеющихся баров, т. е. пройтись по истории. Достигается это путем перебора всех исторических баров: int total = Bars - 1; for (int i = total; i >= 0; i--) { // расчет показаний индикатора на баре с индексом i } В Вашем же примере цикл обрабатывает только текущий формирующийся бар с индексом 0. Но и указанный мною вариант не является до конца правильным, т. к. при таком подходе индикатор на каждом новом тике будет снова и снова обрабатывать всю историю, т. е. выполнять бесполезную работу, которая будет тормозить систему. Для того чтобы не рассчитывать уже вычисленные данные повторно, в старом MQL4 есть функция IndicatorCounted(). В обновленном MQL4 надобность в ней отпала. Посмотрите пример использования этой функции в индикаторе - здесь. Далее. Внутри цикла Вы оперируете массивами (SellBuffer, BuyBuffer, Low, High) как переменными. Это в корне неверно. Возможно, Вы просто не понимаете суть массивов. О них можно почитать в Учебнике. И самая главная ошибка - внутри цикла используется сравнение одних и тех же данных (mainStoc_1 и mainStoc_2), значение которых почему-то вычисляется за пределами цикла. Также есть несколько мелких ошибок (странное использование SetIndexEmptyValue), но о них позже, когда разберемся с основами.

Anatoliy: Добрый суток, Игорь. Я голову ломаю. Да, давайте начнем с азов! Но я пока ещё не далеко понял. Я его изменил условия на пересечение основной и сигнальной линии, и результат есть, но есть нюансы. int start() { //--- int limit = Bars - 1; for(int i=limit;i>=0;i--) { double mainStoc_0 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,i); double signalStoc_0 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,i); double mainStoc_1 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,i+1); double signalStoc_1 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,i+1); //--- Пересечение основной и сигнальной линии ----------------- if ( signalStoc_0 < mainStoc_0 && signalStoc_1 > mainStoc_1) BuyBuffer = High+10*Point; if ( signalStoc_0 > mainStoc_0 && signalStoc_1 < mainStoc_1) SellBuffer = Low-10*Point; //------------------------------------------------------------- } //--- return(0); } 1. Функция SetIndexEmptyValue я удалил, пока не знаю зачем (устанавливает значение пустой величины для линии индикатора). 2. Сигнал выводит по текущему бару (0 бар), мне надо завещающий бар (1 бар). Это от чего зависит? 3. Расстояния между стрелка и максимальный или минимальный бар. Посмотреть на M5 то нармально, а если переключить на H4 уже по-другому. Так должно быть? 4. Пересечение уровни 20 и 80. Нужно написать условие внутри цикла? Условия, например: if (mainStoc_0 > 20 && mainStoc_1 < 20) для Buy, а для Sell аналогично как Buy только знаки поменять. Что нужно изменит или/и добавит внутри функция start()?

Scriptong: Уже лучше, но пока присутствует впечатление, что код написан "под копирку" (по аналогии с другими кодами), а не с полным осознанием того, что Вы пишете. И не забудьте поразмыслить насчет функции IndicatorCounted(). Ее Вы так и не применили. Anatoliy пишет: 1. Функция SetIndexEmptyValue я удалил, пока не знаю зачем (устанавливает значение пустой величины для линии индикатора). Эта функция в данном случае, действительно, не нужна. Ведь если значение буферов стрелок не заполняется, то оно все равно остается пустым. Назначать же еще какое-либо пустое значение для конкретной ситуации не имеет никакого смысла. Anatoliy пишет: 2. Сигнал выводит по текущему бару (0 бар), мне надо завещающий бар (1 бар). Это от чего зависит? Вы же сами написали в коде: double mainStoc_0 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,i); double signalStoc_0 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,i); double mainStoc_1 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,i+1); double signalStoc_1 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,i+1); Подумайтехорошнько: что здесь есть нулевой бар, а что первый? Anatoliy пишет: 3. Расстояния между стрелка и максимальный или минимальный бар. Посмотреть на M5 то нармально, а если переключить на H4 уже по-другому. Так должно быть? Это предлагаю оставить на потом, т. к. вопрос относится уже к эстетике, а не к правильности вычислений. Anatoliy пишет: 4. Пересечение уровни 20 и 80. Нужно написать условие внутри цикла? Условия, например: if (mainStoc_0 > 20 && mainStoc_1 < 20) для Buy, а для Sell аналогично как Buy только знаки поменять. Да, но пока, судя по коду, с массивами Вы так и не разобрались. Ведь приведенный код не компилируется. Разве у Вас не так?


Anatoliy: Прошу прошения. Что-то квадратные скобки пропали. Я скопировал коды и вставил, а потом отправил и проверил, а квадратные скобки пропали. Квадратные скобки должен быть после BuyBuffer, SellBuffer, High, Low и между квадратные скобки переменная i.

Scriptong: Anatoliy пишет: Прошу прошения. Что-то квадратные скобки пропали. Я скопировал коды и вставил, а потом отправил и проверил, а квадратные скобки пропали. Квадратные скобки должен быть после BuyBuffer, SellBuffer, High, Low и между квадратные скобки переменная i. Действительно, забыл. Дело в том, что буква i в квадратных скобках - это один из BB-кодов форума, который означает начало выделения слов курсивом. Тогда вопрос по массивам снимается. Остается только IndicatorCounted и вопрос нахождения баров 1 и 2 вместо 0 и 1, как сейчас в коде.

Anatoliy: Scriptong пишет: Действительно, забыл. Дело в том, что буква i в квадратных скобках - это один из BB-кодов форума, который означает начало выделения слов курсивом. Тогда вопрос по массивам снимается. Остается только IndicatorCounted и вопрос нахождения баров 1 и 2 вместо 0 и 1, как сейчас в коде. Я не забыл, на форумах только что пришёл, ни разу не пользовался. А так работает не плохо мой индикатор, но есть нюансы. Хочу спросить, как загрузит файлы или/и рисунки, чтобы показать. Я сейчас устал, мне нужно отдохнут завтра другой день.

Scriptong: Anatoliy пишет: Я не забыл, на форумах только что пришёл, ни разу не пользовался. Я не про Вас, а про себя. Это я забыл о BB-кодах, сам недавно на эти грабли наступал.

Anatoliy: То есть double mainStoc_0 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,i+1); double signalStoc_0 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,i+1); double mainStoc_1 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,i+2); double signalStoc_1 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,i+2);

Scriptong: Anatoliy пишет: То есть double mainStoc_0 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,i+1); double signalStoc_0 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,i+1); double mainStoc_1 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_MAIN,i+2); double signalStoc_1 = iStochastic(NULL,0,5,3,3,MODE_SMA,0,MODE_SIGNAL,i+2); Правильно. Таким образом, на баре с индексом i, который в данный момент времени можно условно называть "текущим баром", Вы получаете значения линий стохастика на двух последних сформированных барах. Бар с индексом (i + 1) - это условно первый бар, а (i + 2) - условно второй. Далее посмотрите, пожалуйста, пример с работой функции IndicatorCounted. Если что-то будет непонятно, то задайте вопрос, попробую разъяснить.

Anatoliy: Добрый суток, Игорь. Scriptong пишет: Далее посмотрите, пожалуйста, пример с работой функции IndicatorCounted. Если что-то будет непонятно, то задайте вопрос, попробую разъяснить. Я пока в голову не дошел, давайте разберемся все по порядку. Перед тем понять, как работает, я воспользовался с помощью скрипта, но результат отличает. 1 пример. int total = Bars - 1; for(int i=total;i>=0;i--) { //..... } Bars это общее количество баров на текущем графике и отнимаем на один бар, зачем отнимать бар? Или можно попроще for(int i=Bars; i>=0; i--). Далее, цикл зацикливает, берет от начала исторического баров до текущего бар. Правильно я понял? 2 пример. int limit; int counted_bars=IndicatorCounted(); //---- последний посчитанный бар будет пересчитан if(counted_bars>0) counted_bars--; limit=Bars-counted_bars; //---- основной цикл for(int i=0; i<limit; i++) { //..... } IndicatorCounted() это возвращает количество баров, не измененных после последнего вызова индикатора. Посмотрел, как работает в скрипте, что это -1, то есть еще один бар перед 0 бара. Цикл зацикливает наоборот, смылено представил, но этот код у меня не работает в пользовательском индикаторе, и не могу понять.

Scriptong: Anatoliy пишет: Bars это общее количество баров на текущем графике и отнимаем на один бар, зачем отнимать бар? Bars - это количество, а индексация баров начинается с нуля. Так, если баров на графике 3, то их индексы будут 0, 1 и 2. Если обратиться к бару №3, то получим фатальную ошибку - выход за пределы массива баров. Anatoliy пишет: Цикл зацикливает наоборот, смылено представил, но этот код у меня не работает в пользовательском индикаторе, и не могу понять. Да, в этом примере цикл идет от конца истории к ее началу. В большинстве случаев лучше использовать обратную нумерацию. Сама же функция IndicatorCounted работает следующим образом: 1. Запуск индикатора. Функция возвращает значение 0 - еще не было посчитанных баров. В итоге переменная limit будет иметь значение Bars. В показанном примере будут рассчитаны все бары от 0 до Bars, не включая бара с индексом Bars (такого попросту нет). Индикатор рассчитывает все исторические значения. 2. Следующий тик. Функция возвращает значение Bars (на предыдущем тике были рассчитаны все бары). В итоге limit получает значение 1. Индикатор пересчитывает значения на баре с индексом 0 - текущий бар. 3. В момент формирования нового бара IndicatorCounted выдаст значение, на 1 меньше Bars. Переменная limit получит значение 2. Индикатор заново рассчитает значения на барах с индексами 0 и 1.

Anatoliy: Добрый суток, Игорь и любители трейдинга. У меня все новые и новые проблемы в процессе работы программировании, оптимизации и тестировании. Больше всего в популярности я пользуюсь ноутбуком и иногда у знакомых, но это не так комфортно и каждый раз ломаю голову. В первом деле хочу приобрести ПК, но я не тороплюсь без знания системного блока и не хочу просто так приобрести ПК, а потом возникали множественные вопросы. Я обращаю, поделите и позвольте мне собрать информации о железе для системного блока. Я написал консольное приложения для проверки быстродействия ПК в Visual Studio 2010 Express, но возникла ошибка, пока не могу устранить, эта ошибка не синтетическая и не компиляторная, на мой взгляд, скорей все Windows или ноутбук, пока не известно. Как только я обнаружу, исправлю и вложу файл (приложения для проверки быстродействия ПК). Я еще раз обращаю, поделите и позвольте мне собрать информации о железе для работы программировании, оптимизации и тестировании.

Scriptong: Anatoliy пишет: Я обращаю, поделите и позвольте мне собрать информации о железе для системного блока. Если речь идет о комфортной работе с MQL4/MQL5 (программировании), то особых требований к железу и нет. В свое время мне было достаточно вот такого дедушки: 1. Процессор AMD Sempron 3200+ Socket AM2 2. Материнская плата Biostar NF520-A2, Socket AM2, PCI-E, sound int, LAN int 3. Модуль памяти DDR-II 1Gb 4. Модуль памяти DDR-II 2Gb 5. Видеокарта Inno3D PCI-E GeForce 7300GS-F4E3 128Mb DDR2 6. HDD Seagate 500GB Естественно, если речь идет о тестировании и оптимизации экспертов, то такой компьютер решает поставленные задачи ну о-о-очень долго. То же самое можно сказать и о работе в Visual Studio. На указанном железе компиляция проектов нередко занимала 5 минут и больше. Это серьезно сбивало ритм работы. Более-менее современные конфигурации это: 1. Процессор 64-бит от 4-х ядер с тактовой частотой каждого ядра 3GHz и более 2. Материнская плата с поддержкой памяти DDR3 и частотой шины данных не менее 2GHz 3. Оперативная память не менее 8Gb 4. Видеокарта на памяти DDR3 - DDR5 с объемом от 1 Гб и разрядностью шины данных не менее 256 бит 5. Жесткий диск - система на SSD, данные на HDD

Anatoliy: Scriptong пишет: Более-менее современные конфигурации это: Игорь, спасибо за совет. Во время тестирования в режиме визуализации там есть прокрутка режимы скорости. Если поставит 31, то еле-еле, а если поставит 32, то я сам не успеваю визуально проанализировать. Как регулировать скорость по себя?

Scriptong: Anatoliy пишет: Как регулировать скорость по себя? К сожалению, в МТ4 никак. Об этом разработчиков терминала просят уже много лет. Пока они отреагировали на эту просьбу в МТ5 - там прокрутка более плавная, хотя тоже не идеальная. Плюс к этому в МТ5 скорость визуализации можно настраивать более точно - есть специальные кнопки увеличения скорости на одно деление и уменьшение на одно деление.



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