Форум » Алгоритмы » Сюда можно дать приб.. » Ответить

Сюда можно дать приб..

Azer: Сюда можно дать приблизительный алгоритм???

Ответов - 41, стр: 1 2 3 4 5 All

SK: Можно.

Андрей: Добрый день, Сергей. Помогите пожалуйста, никак не получается организовать цикл. cur_side = MathAbs(Buffer[0] - Buffer[1]) / Point; for (i = 0; i < 100; i++) { if ((masiv_B[cur_side] >=1)&& (cur_side >= i)) { masiv_sort = masiv_B[cur_side]; } } if (masiv_sort() пустой) тогда вернуться к cur_side снова его считаем и +1 else идем дальше у меня есть массив masiv_B[100][100]... я получаю некоторую переменную cur_side = MathAbs(Buffer[0] - Buffer[1]) / Point; и теперь мне нужно....чтобы все переменные из массива masiv_B с индексом строки равной cur_side были перенесены в массив masiv_sort[]...поскольку он одномерный...то там только один индекс переменной... (пример) т.е. получается, что masiv_sort[5] = masiv_B[cur_side][5]... и так далее...пока не будут заполнены все переменные...в массиве masiv_sort и masiv_B[][] имеет в наличии 100 столбцов...и masiv_sort[] - 100 столбцов...т.е. они совпадают... но вот что у меня не получалось....это организовать цикл... т.е. мы нашли cur_side, заполнили masiv_sort[].. если массив masiv_sort() не будет пустым...а будет иметь хоть одно значение...тогда цикла заканчивает свою работу и сохраняет cur_side а если массив masiv_sort() будет пустым....тогда нужно вернуться ...пересчитать cur_sid, прибавить 1..и снова заполнить массив вот.

SK: 1. Честно говоря.. это что-то новое:) Что такое cur_side = MathAbs(Buffer[0] - Buffer[1]) / Point; Это типа.. показания на 0 баре - показания на 1 баре, делённое на 0.0001. В сущности, это разница цен в пунктах. Например, (1.2347 - 1.2345)/0.0001 = 0.0002/0.0001 = 2. Я не понимаю как это значение можно использовать в качестве индекса массива. Ну, т.е. технически это возможно. Математика стерпит. Но.. не меряют же температуру в километрах, а вес в амперах. 2. Вот это masiv_sort = masiv_B[cur_side] и это masiv_sort[5] = masiv_B[cur_side][5] вещи несовметимые. masiv_sort может быть либо массивом, любо переменной, а masiv_B может быть либо 1- либо 2-мерным массивом. Указание индексов обязательно. Числом или переменной неважно. Важно, чтоб место, где должен быть указан индекс, не пустовало.


Владимир25/04: Здравствуйте Сергей. Хочу направить Вам вопрос но после того как зарегистрируюсь.

Владимир25/04: Здравствуйте Сергей. Не могу зарегистрироваться.

Владимир25/04: О'кей зарегистрировался. Здравствуйте Сергей еще раз. Вот пишу Вам первый раз . Надеюсь не последний. В сравнении с тем о чем и на какие темы говорят и пишут на форуме я новичок. Язык изучил за месяц, примерно пол года назад, " Учебник по программированию на MQL4" в Вашем авторстве. Прекрасный учебник, очень толково написан. Написал несколько советников, пользовательских индикаторов, скриптов. На все непонятные вопросы ответы пытаюсь найти на форуме. Но столкнулся с одной вроде бы мелочью, а ответа найти не могу. Задал вопрос вчера на форуме, но внятный ответ так и не получил. Помогите пожалуйста. Вопрос касается использование #include <ХХХ.mqh>, перечитал весь форум не нашел ответа. На одной из веток 20.10.2007 Вы написали: "...Ещё можно добавить, что файл ех4 является самодостаточным - для того, чтоб он работал, не требуется, чтоб в include находились исходные коды пользовательских функций. Файл ех4 можно скопировать, передать другим трейдерам и там использовать. Он является полноценным независимо от технологии его получения." Вот в этом и проблема. Допустим я сделал советник в который вставил директиву #include<...>, затем сделал включаемый заголовочный файл с куском кода. Откомпилировал советник и включил в торговлю. Все работает. Беру свой советник копирую и переношу на другой компьютер, другому трейдеру . После этого советник не хочет работать и пишет, что нет функции к которой обращается #include<...>, то есть он не видит включаемый заголовочный файл и не компилируется. А пишет при компиляции - 'PointZigZag.mqh' - cannot open the program file D:\Program Files\MetaTrader2\experts\Киблиот.mq4 (10, 1) Как я понял из учебника и Ваших высказываний, передается советник в mg4, а включаемый файл с ним прицепом в ех4. И получается, что код советника виден, а включаемый файл не виден но в любом случае должен работать. Вот пример советника и включаемого заголовочного файла. Посмотрите в чем ошибка именно по вопросу. //+------------------------------------------------------------------+ //| Киблиот.mq4 | //| Copyright © 2009, MetaQuotes Software Corp. | //| http://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "Copyright © 2009, MetaQuotes Software Corp." #property link "http://www.metaquotes.net" #include <PointZigZag.mqh> //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() {PointZigZag(); Comment("Прод.-y21 = ",y21," ","Пок.-x21 = ",x21); return(0); } //+------------------------------------------------------------------+ жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж //+------------------------------------------------------------------+ //| PointZigZag.mqh | //| Copyright © 2009, MetaQuotes Software Corp. | //| http://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "Copyright © 2009, MetaQuotes Software Corp." #property link "http://www.metaquotes.net" extern int ExtDepth = 12; //------- переменные ZigZag extern int ExtDeviation = 5; //------- переменные ZigZag extern int ExtBackstep = 3; //------- переменные ZigZag extern int ShiftBars = 2; //------- переменные ZigZag //------- переменные ZigZag ------------------------------------------ double y3, y2, y1, zz;// int x3, x2, x1, sh;// double x31, x21, x11; // Точки перегиба ZigZag double y31, y21, y11; // Точки перегиба ZigZag double TimeZZ, TimeOO; //------------------------------------------------------------------------------ double PointZigZag() {y3=0;y2=0;y1=0; sh=ShiftBars; while (y3==0) {zz=iCustom(NULL, 0, "ZigZag", ExtDepth, ExtDeviation, ExtBackstep, 0, sh); if (zz!=0 && zz!=EMPTY_VALUE) {if (y1==0) { x1=sh; y1=zz; } else if (y2==0) { x2=sh; y2=zz; } else if (y3==0) { x3=sh; y3=zz; }}sh++; } if (High[x1]>High[x2]) {x11=High[x1]; x21=Low[x2]; x31=High[x3]; y11=0;y21=0;y31=0;TimeZZ=Time[x2]; }else {y11=Low[x1]; y21=High[x2]; y31=Low[x3]; x11=0;x21=0;x31=0;TimeZZ=Time[x2];} } //+------------------------------------------------------------------+ Большое Спасибо.

SK: Владимир25/04 пишет: На одной из веток 20.10.2007 Вы написали: "...Ещё можно добавить, что файл ех4 является самодостаточным - для того, чтоб он работал, не требуется, чтоб в include находились исходные коды пользовательских функций. Файл ех4 можно скопировать, передать другим трейдерам и там использовать. Он является полноценным независимо от технологии его получения." Вот в этом и проблема. Допустим я сделал советник в который вставил директиву #include<...>, затем сделал включаемый заголовочный файл с куском кода. Откомпилировал советник и включил в торговлю. Все работает. Беру свой советник копирую и переношу на другой компьютер, другому трейдеру . После этого советник не хочет работать и пишет, что нет функции к которой обращается #include<...>, то есть он не видит включаемый заголовочный файл и не компилируется. А пишет при компиляции - 'PointZigZag.mqh' - cannot open the program file D:\Program Files\MetaTrader2\experts\Киблиот.mq4 (10, 1) Как я понял из учебника и Ваших высказываний, передается советник в mg4, а включаемый файл с ним прицепом в ех4. И получается, что код советника виден, а включаемый файл не виден но в любом случае должен работать. Судя по всему, Вы неправильно понимаете суть дела. Различают исходные коды (mq...) и исполняемые (ex4). На любом ПК в терминале МТ 4 можно запустить на исполнение только готовую прикладную программу (ех4). При этом действительно не имеет значения каким образом получен ех4-файл - то ли это просто текст программы mq4, то ли текст программы mq4, в котором используется включение файлов с помощью строки #include. Другое дело, что для получения исполняемого файла ех4 на момент компиляции нужны все компоненты. Если Вы компилируете программу (выполняете действия в МЕ для получения ех4) на своём ПК, то всё получается, т.к. на Вашем ПК все компоненты имеются. Если же Вы берёте только один файл mq4 (в котором используется включение файлов с помощью строки #include), относите его на другой ПК и пытаетесь выполнить компиляцию на этом ПК, то компиляция не завершится удачно, т.к. в данном случае нет того фрагмента текста, который вставляется (нет включаемого файла). Для успешной компиляции на другом ПК нужно разложить по соотв. каталогам все файлы - и собственно код эксперта (скрипта, индикатора) и включаемые файлы mqh. -- Смысл использования mqh сводится к простому удобству. Во время компиляции при исполнении директивы #include текст, содержащийся в mqh файле, просто вставляется в код эксперта взамен строки #include. Если программа большая, то (главный) файл эксперта может вообще не содержать кода, а лишь #include А, #include В,#include С. При этом алгоритмы прописываются в соотв. файлах mqh с названиями А, В, С. Но на момент компиляции все эти файлы должны присутствовать, чтоб компилятор мог собрать их коды и затолкать в файл эксперта. Потом компиляция = получение самодостаточного ех4.

Владимир25/04: SK пишет: На любом ПК в терминале МТ 4 можно запустить на исполнение только готовую прикладную программу (ех4). При этом действительно не имеет значения каким образом получен ех4-файл - то ли это просто текст программы mq4, то ли текст программы mq4, в котором используется включение файлов с помощью строки #include. Добрый вечер. Спасибо за внимание и оперативность. Конечно Ваш авторитет для меня непререкаемый так сказать последняя инстанция, но есть маленький вопрос. Со своего компьютера я копирую советник в mq4 , переношу на другой и вставляю. Там появляется такой же советник mq4 и самое главное если смотреть папку include не в открытом терминале, а проводнике Windows то в ней появилась запись включаемого файла не компилированная в ex4. Как это объяснить? И еще тогда я вообще не понимаю смысл включаемого файла сheck. из ваших примеров. Если он идет в открытом виде то в нем теряется смысл. А если в закрытом то как.

SK: Файлы самопроизвольно не копируются. Я не знаю как объяснить чудеса между Вашими ПК. Но мне по-прежнему кажется, что Вы не до конца понимаете суть. Включаемые файлы не нужно отдавать в открытом виде. Да и никакие исходные коды вообще (основн. файл эксперта). Отдать другу Вы можете один файл ех4. Он будет работать, его компилировать не нужно (он уже является результатом компиляции). И он не потребует никаких включаемых файлов. Его просто нужно положить в папку экспертов. После запуска МТ4 в списке экспертов в терминале он будет сегого цвета (если рядом нет его исходников) или жёлто-синего (если исходники тут же).

SK: Включаемый файл отдельно компилировать не нужно. Он просто несёт в себе текст, который будет вставлен в основной код эксперта при компиляции.

Владимир25/04: SK пишет: Отдать другу Вы можете один файл ех4. Он будет работать, его компилировать не нужно (он уже является результатом компиляции). И он не потребует никаких включаемых файлов. Его просто нужно положить в папку экспертов. После запуска МТ4 в списке экспертов в терминале он будет сегого цвета (если рядом нет его исходников) или жёлто-синего (если исходники тут же). Все, спасибо. Хоть какой-то смысл появился от включаемых файлов. Советник в виде ех4 на другом компьютере работает. Удачи.

SK: ОК.

Владимир25/04: Здравствуйте Сергей. Я себе уже сломал всю голову. В MetaTrader в скриптах, базовой поставки, есть следующий скрипт: #property copyright "Copyright © 2004, MetaQuotes Software Corp." #property link "http://www.metaquotes.net/" #property show_confirm //+------------------------------------------------------------------+ //| script "send pending order with expiration data" | //+------------------------------------------------------------------+ int start() { int ticket,expiration; double point; //---- point=MarketInfo(Symbol(),MODE_POINT); expiration=CurTime()+PERIOD_D1*60; //---- while(true) { ticket=OrderSend(Symbol(),OP_SELLSTOP,1.0,Bid-100*point,0,0,0,"some comment",16384,expiration,Green); if(ticket<=0) Print("Error = ",GetLastError()); else { Print("ticket = ",ticket); break; } //---- 10 seconds wait Sleep(10000); } //---- return(0); } Что это за функция CurTime() где она объявлена и где её код. Если её убираешь компилятор ругается. Я понимаю, что это время, но если она предопределенная то где про неё почитать.

Scriptong: Это устаревшее название функции TimeCurrent. Прчитать про нее можно в Справочнике MQL4-Устаревшие функции. Убирать ее не нужно, просто заменить на TimeCurrent.

Владимир25/04: Большое спасибо. Ясно и понятно. Удачи.

dhot: Мое почтение, Сергей. Вероятно, с Вами можно вдумчиво поговорить о вещах совсем непонятных, творящихся в MQL. Признаться, и Метатрейдер и язык оставляют впечатление очень сырых продуктов. Я не исключаю, что мне могут быть неизвестны все тонкости их реализации, но прозрачности и однозначности в них точно нет. Я, например, так и не понял, почему функция Alert() записи в журнале оставляет, а диалоговое окно не выводит? MessageBox(), к слову, тоже. Был как-то случай, когда одна и та же конструкция в реальном времени, в тестере и в режиме визуализации того же тестера выдавала совершенно разные результаты. Тогда на форуме мне пришлось удовлетвориться простой констатацией факта, что в тестере подобная конструкция не работает. Хоть не моя глупость, уже легче. Однако на затею пришлось плюнуть. Сейчас снова непонятная заминка возникла, но плевать не хочется - много уже сделано. А проблема в следующем. Идея создания на графиках интерактивных элементов новизной не блещет - в режиме визуализации как без рук сидишь. Вот и мне понадобилось создать текстовую метку, выставляемую на определенном ценовом уровне и остающуюся у левого края графика при его прокрутке. При этом хотелось иметь возможность циклически менять два возможных варианта текста метки, смещая ее мышью с исходного положения. Привожу код небольшого эксперта, моделирующего эту идею: //+------------------------------------------------------------------+ //| тест.mq4 | //+------------------------------------------------------------------+ #property copyright "" #property link "" double LabPr; datetime LabTm; int Value; int Shift; int Flag; int init() { Value=1; Shift=6; LabPr=Bid; Flag=0; LabTm=iTime(NULL,0,WindowFirstVisibleBar( )-Shift); ObjectCreate("LabTest",OBJ_TEXT,0,LabTm,LabPr); ObjectSetText("LabTest",DoubleToStr(Value,0) ,11,"Tahoma",Red); } int start() { if(LabPr!=ObjectGet("LabTest",OBJPROP_PRICE1)|| LabTm!=ObjectGet("LabTest",OBJPROP_TIME1)) { if(Flag==0) { Value=Value*(-1); Flag=1; } } else Flag=0; LabTm=iTime(NULL,0,WindowFirstVisibleBar( )-Shift); ObjectSet("LabTest",OBJPROP_TIME1,LabTm); ObjectSet("LabTest",OBJPROP_PRICE1,LabPr); ObjectSetText("LabTest",DoubleToStr(Value,0) ,11,"Tahoma",Red); } //+------------------------------------------------------------------+ По каким-то причинам иногда фокус со смещением метки не срабатывает. А вот если функцию ObjectSetText() поставить не в самом конце, а сразу за инструкцией Value=Value*(-1) (где ей, собственно, и место), то тогда фокус будет иногда срабатывать. Но крайне редко. Самое интересное, что в последнем случае Comment(GetLastError()) сразу за ObjectSetText() выдает 4202 - отсутствие объекта, а вот ObjectFind() непосредственно перед ObjectSetText() объект видит. Этому феномену есть какие-то объяснения?

SK: dhot, Тут, мне кажется, всего по чуть-чуть. Алерт. Чтобы он работал нужно ему разрешить это в настройках МТ 4. Тестер. В самый последний период его, вроде бы, довели до ума, но поручиться за все ситуации я не могу. Интерактивные кнопки. Смотря чего от них хотеть. Из представленного кода не очень понятно какое управляющее воздействие должно осуществляться. Рекомендую на эту тему почитать одну из моих статей: http://articles.mql4.com/ru/117/ Там описаны общие принципы. Главная особенность этой методики состоит в том, что основная прикладная программа (в статье скрипт, в вашем случае - эксперт) должна быть зациклена, т.е. обрабатывать управляющее воздействие пользователя постоянно. Если этого не сделать, то между тиками программка не будет работать. Эксперт отработает 1 раз на каждом новом тике - start() будет запущена терминалом 1 раз по факту прихода нового тика. А между тиками - как не сдвигай объект, - толку не будет, т.к. некому ( start()-то уже отработала и молчит) обработать это событие. -- Попробуйте написать стратегию под AG 4. В этом случае всё просто - не нужно ничего зацикливать, т.к. стратегия вызывается из AG 4 прибл. 100 раз в сек. Нужно просто анализировать факт наличия объекта и его координаты. Если объект удалён - восстанавливать + дать сообщение пользователю. Если объект сдвинут - осуществлять некоторое заданное действие. Можно с вариантами: вниз - одно действие, вверх - другое:)

Scriptong: dhot пишет: Вот и мне понадобилось создать текстовую метку, выставляемую на определенном ценовом уровне и остающуюся у левого края графика при его прокрутке. При этом хотелось иметь возможность циклически менять два возможных варианта текста метки, смещая ее мышью с исходного положения. А почему вы пользуетесь текстовым объектом, а не текстовой меткой? Ведь объект-текст привязывается к цене и времени, а поэтому смещается с перемещением графика. Если же использовать текстовую метку (OBJ_LABEL), то автоматически отпадает необходимость слежения за положением графика, так как метка позиционируется относительно графика в пикселях, а не относительно времени и цены.

dhot: Scriptong пишет: А почему вы пользуетесь текстовым объектом, а не текстовой меткой? Я отмечал, что мне нужна привязка к цене. :) Вообще-то у меня в полном варианте идет горизонтальная линия и привязанная к ней интерактивная метка. Ну, вернее текст. Из меток, само собой, я собрал панель инструментов и информационную панель... :)

dhot: SK пишет: Из представленного кода не очень понятно какое управляющее воздействие должно осуществляться. Менять значение переменной-переключателя Value и отображать его (значение). Или соответствующий значению текст, но это тонкости. Вообще-то проблема в том, что я уже второй раз сталкиваюсь вот с какой несуразицей - чем глубже зарыта инструкция ObjectSet() во вложенные операторы if, тем нестабильнее она работает. Не буду приводить здесь весь код, он довольно громоздок, покажу лишь принцип. Нужно мне было при определенных условиях изменить стиль отрисовки линии. На протяжении жизни линии это делалось лишь один раз и больше стиль линии не менялся. В общих чертах конструкция выглядела так: if(проверка условия 1) { (набор действий) if(проверка условия 2) { (набор действий) if(проверка условия 3) { LevOp=1; ObjectSet(name,OBJPROP_STYLE,STYLE_DASH); } } } Надо отметить, что стиль линии визуализировал состояние переменной LevOp (либо 0, либо 1). Так вот, переменной присваивалось новое значение, а линия не изменялась. Мало того, GetLastError() выдавала ошибку 4202 - объект не существует, а я сидел и смотрел на этот самый объект в окне графика! Уже чисто машинально я изменил код, вытащив ObjectSet() с третьего уровня на второй и это начало срабатывать. Но очень нестабильно. На первом уровне все заработало вроде нормально. Правда условие проверялось теперь на каждом тике и стиль линии присваивался вне зависимости от того, как она была отрисована. Но это уже казалось мелочью... :)))

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

SK: Дело не в том, востребована или не востребована предлагаемая технология. Дело в том, что это объясняет отсутствие реакции прикладной программы на смещение объекта.

dhot: SK пишет: Дело в том, что это объясняет отсутствие реакции прикладной программы на смещение объекта. М-м-да... Жаль, что не удалось посмотреть в работе представленный в статье комплекс. Результат компиляции эксперта: '' - unexpected end of program C:\Program Files\MetaTrader - UMIS\experts\include\Metsenat_exp.mq4 (26, 1) '' - unexpected end of program C:\Program Files\MetaTrader - UMIS\experts\include\Del_GV_exp.mq4 (19, 1) '' - unexpected end of program C:\Program Files\MetaTrader - UMIS\experts\include\Component_exp.mq4 (49, 1) '' - unexpected end of program C:\Program Files\MetaTrader - UMIS\experts\include\Component_uni.mq4 (33, 1) '' - unexpected end of program C:\Program Files\MetaTrader - UMIS\experts\Expert.mq4 (47, 1) С индикатором и скриптом аналогичная история. Это к вопросу об однозначности поведения продуктов от MetaQuotes.

SK: В конце каждого кода есть комбинация символов /* Удалите эти символы и компиляция будет успешной.

dhot: SK пишет: Дело в том, что это объясняет отсутствие реакции прикладной программы на смещение объекта. Я не говорил, что отсутствует реакция. Из цепочки событий, являющихся реакцией на манипуляции с меткой (изменение значения переменной - изменение текста в метке - возврат метки в исходное положение) выпадает лишь одно - изменение текста. Все остальное срабатывает. Идею с непрерывным опросом управляющих элементов я уловил сразу. Вот только разница между инициацией опроса новым витком цикла и новым тиком должна по идее заключаться лишь в скорости реакции программы, но уж ни как не в наличии или отсутствии этой реакции. Пусть тик придет через пять минут и реакция на действие пользователя произойдет через пять минут, но она ПРОИЗОЙДЕТ!!! Или я что-то не так понял, не учел? Вопрос же востребованности технологии не праздный. Каков бы ни был пользовательский интерфейс терминала, он все-таки предоставляет необходимые средства управления, а вот тестер стратегий не дает ни чего. И именно он в первую очередь нуждается в интерактивных элементах. То, что я сейчас собираю, заточено именно под тестер, а в нем, как вы понимаете, недостатка в тиках нет. Ну, а будет проводится опрос пять раз в секунду или пятьсот - я думаю, не столь критично. Во всяком случае, не на столько, что бы усложнять программу. :))

SK: dhot пишет: Я не говорил, что отсутствует реакция. Из цепочки событий, являющихся реакцией на манипуляции с меткой (изменение значения переменной - изменение текста в метке - возврат метки в исходное положение) выпадает лишь одно - изменение текста. Все остальное срабатывает. Идею с непрерывным опросом управляющих элементов я уловил сразу. Вот только разница между инициацией опроса новым витком цикла и новым тиком должна по идее заключаться лишь в скорости реакции программы, но уж ни как не в наличии или отсутствии этой реакции. Пусть тик придет через пять минут и реакция на действие пользователя произойдет через пять минут, но она ПРОИЗОЙДЕТ!!! Или я что-то не так понял, не учел? Конечно, реакция должна быть, если управление передаётся соотв. оператору или функции. Но в Вашем коде есть множество if-ов. Возможно, не срабатывают их условия, управление не паредаётся в тело оператора if(). Вопрос же востребованности технологии не праздный. Каков бы ни был пользовательский интерфейс терминала, он все-таки предоставляет необходимые средства управления, а вот тестер стратегий не дает ни чего. И именно он в первую очередь нуждается в интерактивных элементах. То, что я сейчас собираю, заточено именно под тестер, а в нем, как вы понимаете, недостатка в тиках нет. Ну, а будет проводится опрос пять раз в секунду или пятьсот - я думаю, не столь критично. Во всяком случае, не на столько, что бы усложнять программу. :)) Да, для тестера это не критично. В AG 4 различаются режимы. В тестовом режиме управляющие элементы опрашиваются 1 раз.

Scriptong: dhot пишет: Я отмечал, что мне нужна привязка к цене. :) Вообще-то у меня в полном варианте идет горизонтальная линия и привязанная к ней интерактивная метка. Ну, вернее текст. Из меток, само собой, я собрал панель инструментов и информационную панель... :) Так ведь никто не мешает вам преобразовывать цену в пиксели - http://codebase.mql4.com/ru/6346

dhot: SK пишет: В конце каждого кода есть комбинация символов /* Удалите эти символы Да-да, именно это я и сделал в первую очередь. (Так и не поняв, к чему такие сложности. :) ) Вот только в три часа ночи было уже трудно сообразить, что включаемые файлы надо не только отредактировать, но и сохранить. Стереотип уже сложился - отредактировал, скомпилировал. Да еще после повторной компиляции клик на ошибке выбрасывал курсор в произвольную строку уже открытого и отредактированного файла. Опять о неоднозначности. Впрочем, это я уже занудствую. :))))) Я все-таки хочу вернуться к первоначальному вопросу. Дело в том, что для меня, как человека пользовавшегося до сих пор объектно ориентированными средами программирования некоторые тонкости процедурного программирования могут быть далеко не очевидными. Ну вот, скажем, такой пример. В приведенном в самом начале коде я пытался реализовать функционал кнопки - нажали, получили действие, кнопка вернулась в исходное положение. Поскольку метка не кнопка и нажимать нечего, заменил нажатие смещением. А дальше по отработанной схеме - определил факт смещения, выполнил действия, прописал возврат метки. При этом совершенно не учел, что программирую не конкретное событие, а постоянно нахожусь в потоке событий. То есть, пока метка зацеплена мышью и перемещается (а следовательно находится не на месте) опрос ее состояния происходит не единожды и предписанное действие происходит не единожды. Для меня это было не очевидно и ошибку я обнаружил лишь получив некорректный результат. Изменил код так, что бы в следующий раз метка срабатывала только после того, как она фактически побывает в исходном положении. Теперь проблема состоит в том, что из назначенных на смещение кнопки действий одно выполняется не регулярно - изменение текста. Причем чем глубже оно находится во вложенных операторах if, тем нестабильнее работает. Может я что-то упускаю из виду? Ну, скажем, в той же последовательности событий?

dhot: SK пишет: Возможно, не срабатывают их условия, управление не паредаётся в тело оператора if(). В том-то и дело, что передается! В теле оператора две инструкции - одна меняет значение переменной, другая устанавливает свойство объекта. Так вот, переменная меняется, а свойство объекта нет. Я уже писал, программа не видит объект - ошибка 4202. Приходится выносить это в отдельную задачу - проверять состояние переменной и в соответствии с ним менять свойство объекта.

SK: Честно говоря, я не вижу в чём проблема. Вы сами всё хорошо понимаете. Обратите внимание также на необходимость перерисовки графиков после изменения свойств объектов (см. WindowRedraw() ).

dhot: Scriptong пишет: Так ведь никто не мешает вам преобразовывать цену в пиксели Да, я видел это, но стараюсь избегать обращения к системным dll. У Дениса Орлова есть такой советник: http://codebase.mql4.com/ru/6012http://codebase.mql4.com/ru/6012 Судя по комментариям, вполне работоспособный, но у меня почему-то глючит. Вместо того, что бы остановиться на заданном уровне подвешивает тачпад. Автор в недоумении. Я грешил на загаженность системы, но даже после ее переустановки глюк остался ( у меня XP, SP не ниже второго, лицензионная).

dhot: SK пишет: Обратите внимание также на необходимость перерисовки графиков после изменения свойств объектов (см. WindowRedraw() ). Упс! А вот об этом не подумал! Попробую...

dhot: Все равно ни чего не получается. Сергей, могли бы вы ответить всего на один конкретный вопрос? Запустите, пожалуйста, этот советник в тестере, в режиме визуализации. Выделите и переместите созданный им в окне графика текст ( 1 ). Собственно вопрос: почему третий алерт, из тех, что выводятся в результате этого действия, показывает ошибку 4202? [pre2]//+------------------------------------------------------------------+ //| тест.mq4 | //+------------------------------------------------------------------+ #property copyright "" #property link "" double LabPr; datetime LabTm; int Value; int Shift; int Flag; int init() { Value=1; Shift=6; LabPr=Bid; Flag=0; LabTm=iTime(NULL,0,WindowFirstVisibleBar( )-Shift); ObjectCreate("LabTest",OBJ_TEXT,0,LabTm,LabPr); ObjectSetText("LabTest",DoubleToStr(Value,0) ,11,"Tahoma",Red); } int start() { if(LabPr!=ObjectGet("LabTest",OBJPROP_PRICE1)|| LabTm!=ObjectGet("LabTest",OBJPROP_TIME1)) { if(Flag==0) { Value=Value*(-1); Alert("Value=",Value); Flag=1; Alert("Поиск объекта - ",ObjectFind("LabTest")); ObjectSetText("LabTest",DoubleToStr(Value,0) ,11,"Tahoma",Red); Alert("Ошибка - ",GetLastError()); } } else Flag=0; LabTm=iTime(NULL,0,WindowFirstVisibleBar( )-Shift); ObjectSet("LabTest",OBJPROP_TIME1,LabTm); ObjectSet("LabTest",OBJPROP_PRICE1,LabPr); } [/pre2]

SK: После некоторых экспериментов выяснилось, что: - поиск объекта всегда выполняется корректно (независимо от факта перемещения мышкой) - изменение свойства ObjectSetText объекта (GetLastError()=0) выполняется только в том случае, если объект покоится (не перемещается мышкой) - изменение свойства ObjectSetText объекта не выполняется (GetLastError()=4202), если объект перемещается мышкой; при этом указание программы изменить значение ObjectSetText запоминается терминалом и выполняется при ближайшем удобном случае (объект покоится) В этом можно убедиться, установив медленную прокрутку (скорость образования новых баров). Если объект сдвинуть и быстро отпустить, то скорее всего ошибка будет=0, т.к. перемещение объекта попадает на период между исполнениями start(), т.е. фактически на момент исполнения ObjectSetText() объект покоится. Если объект сдвинуть и подержать до момента образования нового бара, то ошибка =4202, т.к. на момент исполнения start() объект перемещался мышкой. Для наглядности добавьте одну строку: Alert("Поиск объекта - ",ObjectFind("LabTest")); Alert("Ошибка До- ",GetLastError()); ObjectSetText("LabTest",DoubleToStr(Value,0) ,20,"Tahoma",Red); Alert("Ошибка После- ",GetLastError());

dhot: SK пишет: при этом указание программы изменить значение ObjectSetText запоминается терминалом и выполняется при ближайшем удобном случае (объект покоится) Вообще-то первый удобный случай, как я понял, наступает в момент отпускания объекта, но проблема в том и заключается, что изменения свойства не происходит. Однако за идею весьма признателен. Такой расклад вполне возможно обработать. Кстати, Alert("Ошибка До- ",GetLastError()); будет в любом случае показывать 0. Переменная LastError обнуляется после вызова в строке Alert("Ошибка После- ",GetLastError()); и больше ей негде принять новое значение. :)) Сергей, говорят, Вы готовите учебник по MQL5. Не подскажете, когда его можно будет увидеть? Да и с самим MT5 как дела обстоят? А то окажется, что все мои искания напрасны... :))) И спасибо вам за терпение!

SK: dhot пишет: Кстати, Alert("Ошибка До- ",GetLastError()); будет в любом случае показывать 0. Да. Это-то и свидетельствует о том, что клиентский терминал находит объект независимо от факта его перемещения мышью. dhot пишет: Вообще-то первый удобный случай, как я понял, наступает в момент отпускания объекта, но проблема в том и заключается, что изменения свойства не происходит. Нет. Всё дело в подробностях. Случай не инициируется фактом отпускания объекта пользователем. Случай - это строка кода в функции start(). Start() запускается новым тиком и исполняется обычно быстро, т.е. успевает закончиться раньше, чем приходит новый тик. После того, как start() закончила своё исполнение, до нового запуска страт (на следующем тике) возникает пауза. Если в период исполнения старт (конкретно функции ObjectSetText) объект тянется мышей, то неизбежно возникает ошибка 4202. Если же пользователь успел отпустить объект в период паузы, т.е. до прихода нового тика, то ObjectSetText в start() (запущенной фактом прихода нового тика) исполнится без ошибки. Если Вас интересуют эти подробности (что вполне понятно при создани функций обработки событий, связанных с объектами), то не поленитесь составить диаграмму, на кот. отобразить все варианты начала и окончания перетаскивания объекта по отношению к началу и концу исполнения start(). dhot пишет: Сергей, говорят, Вы готовите учебник по MQL5. Не подскажете, когда его можно будет увидеть? Да и с самим MT5 как дела обстоят? А то окажется, что все мои искания напрасны... :))) Это правда. Надеюсь, что учебник появится к концу лета. Более точно сказать не могу - как дело пойдёт. Что касается МТ 5, то, по моим представлениям (я не разработчик,- и платформу и язык создали сотрудники MQ), процесс отладки продолжится прибл. до конца года и выход учебника прибл. совпадёт по срокам с официальным представлением МТ 5. Историю развития МТ 5 можно посмотреть здесь http://www.mql5.com/ru/forum, об учебнике немного здесь http://www.mql5.com/ru/forum/3/page3.

dhot: SK пишет: Случай - это строка кода в функции start(). Start() запускается новым тиком и исполняется обычно быстро, т.е. успевает закончиться раньше, чем приходит новый тик. Я так понимаю, что при создании рабочего прототипа программы проще, быстрее и надежнее фиксировать состояние объектов в переменных и при каждом запуске start() приводить их в соответствие. Позже, когда будут доведены логика и интерфейс, попытаться оптимизировать какие-то процессы, если возникнет в том потребность. Спасибо за советы. :)

SK: dhot пишет: Я так понимаю, что при создании рабочего прототипа программы проще, быстрее и надежнее фиксировать состояние объектов в переменных и при каждом запуске start() приводить их в соответствие Думаю, что это зависит от задачи. start() запускается новым тиком. Если этого достаточно, то так и сделать. Во всяком случае, необходимо обрабатывать все ситуации, в том числе, делать анализ ошибок. В Вашем случае нужно выловить ошибку 4202 и соотв. образом отреагировать. Например, не выполнять модификацию объекта и выйти из start(). Есть и другой способ - если координаты объекта смещены, то удалить объект. Объект не будет удалён, если в момент попытки удаления он перетягивается. И тут же проверить наличие объекта: если он есть, то его тянут; если его нет, то создать новый в новых координатах и с новыми параметрами. (отсутствие объекта нужно обрабатывать само собой, т.к. возможно случайное удаление) Если же пойти по пути зацикленной start(), то это с одной стороны, позволит быстро реагировать на управляющие воздействия пользователя, с другой стороны, повлечёт необходимость более глубокого анализа ситуации (в т.ч. обработку факта перекл. таймфрейма - пересчёт координат). И если идею развивать и углублять, то через некоторое время может получиться AutoGraf :)

coldun: Здравствуйте Сергей! Пожалуйста помогите разобраться. Хочу реализовать в алгоритме советника изменение настроек в зависимости от состояния рынка. Например: задан стандартный шаг между ордерами, нужно увеличить шаг при обвале рынка. Когда изменяю этот шаг через коэффициент, шаг изменяется, но зацикливается и либо увеличивается без остановки, либо уменьшается до нуля. Как правильно сделать эту функцию. K = NormalizeDouble((AccountFreeMargin()/AccountBalance()),2); // коэффициент изменения шага PromShag = Shag / K; //промежуточные вычисления Shag = PromShag; //шаг между отложенными ордерами выраженный через промежуточную переменную

SK: В подобных случаях, как всегда, решение кроется в скурпулёзном рассмотрении подробностей. 1. Что такое шаг? Дистанция в пунктах между отложенными ордерами? 2. Что значит увеличить шаг? Модифицировать все отложенники так, чтобы дистанция между ними увеличилась? 3. "шаг изменяется, но зацикливается и либо увеличивается без остановки либо уменьшается до нуля" - попробуйте сообразить, можно ли это понять? Для того, чтобы разобраться что там зацикливается, нужно же посмотреть код, включающий оператор цикла. Код Вы не даёте. Ну.. и что дальше? 4. "Как правильно сделать эту функцию" Какую функцию? Чтобы что-то сказать о том КАК сделать, нужно сначала иметь точное представление о том, ЧТО нужно сделать. Но Вы же не даёте Вашей идеи, т.е. какие факторы принимаются во внимание, чтобы расчитать шаг? Обычно программа не работает или плохо работает, если программист допускает невнимательность или недодумывает свой метод расчёта. Попробуйте самостоятельно ответить на все вопросы. Если не получится сделать самостоятельно, то выкладывайте всё по полочкам, попробуем разобраться вместе.

Exyga: спасибо



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