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

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

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

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

Husanboy: Scriptong пишет: Пожалуйста. Обращайтесь. Снова приветствую! Уважаемый Игорь есть еще просьба. Вложенный в архиве есть индикатор и советник. С кодом нету ни каких проблему, но не работает в новым билдом метатрейдера(компилируется без ошибки). Помогите пожалуйста?! http://qclk.ru/ks/0IUp

Genry: Husanboy пишет: С кодом нету ни каких проблему, но не работает в новым билдом метатрейдера(компилируется без ошибки). Помогите пожалуйста?! В прежней версии этот индикатор состоял из 2- частей - сам индикатор RSH.mq4 в котором был такой вызов второго индикатора HullMA.mq4 rel=(iCustom(NULL,0,"HullMA",periodoMA,tipoPrecio,tipoPromedio,0,k)-iCustom(NULL,0,"HullMA",periodoMA,tipoPrecio,tipoPromedio,0,i+1))+iCustom(NULL,0,"HullMA",periodoMA,tipoPrecio,tipoPromedio,0,i)-iCustom(NULL,0,"HullMA",periodoMA,tipoPrecio,tipoPromedio,0,k+1); В Вашей версии индикатор HullMA введен в индикатор RSH в виде функции и вызов теперь выглядит так: rel=hma[x]-hma[x+1]; Я взял старую отдельную версию индикатора HullMA и накинул ее на график - она ничего не рисует. Так что проблема в этой части индикатора и функция hma не работает. Если получится найти причину и заставить работать hma, то и RSH начнет выдавать сигналы советнику. Старая версия RSH и HullMA лежит здесь - на FOREX TSD

Genry: Нашел рабочую версию HullMA от Mladen - Здесь Так что можно посмотреть как работает советник со старой версией RSH и новой HullMA


Husanboy: Genry пишет: Нашел рабочую версию HullMA от Mladen - Здесь Так что можно посмотреть как работает советник со старой версией RSH и новой HullMA С уважением! Спасибо за помощь! Я сам исправил и это работает.

Genry: Husanboy пишет: Спасибо за помощь! Я сам исправил и это работает. Ok!

Sergey: Делаю советник, одна из функций которого, при параметре Symbols=false (не учитывать текущий символ) закрывать все открытые ордера, по всем валютным парам. FindOrders(); if (CommonProfit>Profit || CommonProfit<-AccountBalance()/100*Loss) { while (true) { CloseAllOrders(); FindOrders(); if (BuyCount==0 && SellCount==0) break; } } //+-------------------------------------------------------------------------------------+ //| Поиск своих ордеров. | //+-------------------------------------------------------------------------------------+ void FindOrders() { //---- BuyCount = 0; SellCount = 0; CommonProfit = 0; //---- for (int i = 0; i < OrdersTotal(); i++) // Используется весь список ордеров if (OrderSelect(i, SELECT_BY_POS)) // Убедимся, что ордер выбран if ((OrderMagicNumber() == MagicNumber || MagicNumber<0) // Ордер соответствует настройкам MagicNumber && (OrderSymbol() == Symbol() || !Symbols)) // Ордер соответствует настройкам валютной паре { CommonProfit += OrderProfit()+OrderSwap(); // Подсчет совокупного профита if (OrderType() == OP_SELL) SellCount++; if (OrderType() == OP_BUY) BuyCount++; } } //======================================================================================= //+-------------------------------------------------------------------------------------+ //| Закрытие позиций | //+-------------------------------------------------------------------------------------+ void CloseAllOrders() { for (int i = 0; i < OrdersTotal(); i++) // Используется весь список ордеров if (OrderSelect(i, SELECT_BY_POS)) // Убедимся, что ордер выбран if ((OrderMagicNumber() == MagicNumber || MagicNumber<0) // Ордер соответствует настройкам MagicNumber && (OrderSymbol() == Symbol() || !Symbols)) // Ордер соответствует настройкам валютной пары if (WaitForTradeContext()) { if (OrderType()==OP_BUY) if(OrderClose(OrderTicket(), OrderLots(), NT(Bid), Slippeg)) continue; if (OrderType()==OP_SELL) if(OrderClose(OrderTicket(), OrderLots(), NT(Ask), Slippeg)) continue; } } //======================================================================================= Однако, как только параметр устанавливается Symbols=false, советник виснет, когда поступает команда на закрытие позиций, хотя с текущим символом (при Symbols=true) проблем таких нет. В чем причина,понять не могу.

Scriptong: Sergey пишет: В чем причина,понять не могу. Такой код не сможет закрыть рыночные ордера, открытые по символам, отличным от текущего, т. к. цена закрытия указывается в ценах текущего символа. Для мультивалютных программ следует использовать такую конструкцию закрытия: double closePrice = SymbolInfoDouble(OrderSymbol(), SYMBOL_BID); if (OrderType() == OP_SELL) closePrice = SymbolInfoDouble(OrderSymbol(), SYMBOL_ASK); if (OrderClose(OrderTicket(), OrderLots(), closePrice, Slippeg)) continue; Думаю, во время зависаний в журнале эксперта было огромное количество ошибок - неправильные цены. Также при закрытии ордеров необходимо использовать обратный цикл перебора, а то будете закрывать ордера через один. Ну и не лучшее решение делать бесконечные циклы (while(true)). Как минимум, нужно использовать !IsStopped().

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

Sergey: При компиляции выпадает предупреждение old_color и old_startTime (possible loss of data due to type conversion) Как правильно вывести данные по объекту? double old_y1=ObjectGet(ObjName, OBJPROP_PRICE1); double old_y2=ObjectGet(ObjName, OBJPROP_PRICE2); color old_color=ObjectGet(ObjName, OBJPROP_COLOR); datetime old_startTime=ObjectGet(ObjName, OBJPROP_TIME1); Аналогично для int A=round(B); Как преобразовать данные? В учебнике ничего нет, или не могу найти где смотреть.

Sergey: Возможно мой вопрос был не замечен, а потому просто повторюсь. Sergey пишет: В режиме # property strict При компиляции выпадает предупреждение old_color и old_startTime (possible loss of data due to type conversion) Как правильно теперь вывести данные по объекту? double old_y1=ObjectGet(ObjName, OBJPROP_PRICE1); double old_y2=ObjectGet(ObjName, OBJPROP_PRICE2); color old_color=ObjectGet(ObjName, OBJPROP_COLOR); datetime old_startTime=ObjectGet(ObjName, OBJPROP_TIME1); Аналогично для int A=round(B); Как преобразовать данные? В учебнике ничего нет, или не могу найти где смотреть.

Scriptong: Sergey пишет: Возможно мой вопрос был не замечен, а потому просто повторюсь. Да, действительно, не заметил. Прошу прощения. Sergey пишет: При компиляции выпадает предупреждение old_color и old_startTime (possible loss of data due to type conversion) Как правильно вывести данные по объекту? double old_y1=ObjectGet(ObjName, OBJPROP_PRICE1); double old_y2=ObjectGet(ObjName, OBJPROP_PRICE2); color old_color=ObjectGet(ObjName, OBJPROP_COLOR); datetime old_startTime=ObjectGet(ObjName, OBJPROP_TIME1); Аналогично для int A=round(B); Как преобразовать данные? В учебнике ничего нет, или не могу найти где смотреть. В учебнике этого и не может быть, т. к. учебник был написан для "старого" MQL4, а для нового языка разработчики выпускать учебник не планируют. Суть проблемы заключается в том, что функция ObjectGet возвращает значение типа double, которое в коде присваивается типам color и datetime соответственно. Таким образом, имеем неявное приведение типов данных с возможной потерей точности значения. Именно об этом напоминает компилятор, заботясь о том, чтобы программа оперировала валидными данными. Для решения вопроса есть два пути: 1. Использовать явное приведение типов, указав компилятору о том, что мы осознаем риск приведения типов и считаем, что в данном случае оно никак не скажется на работоспособности программы. Явное приведение типов выглядит так: color old_color=(color)ObjectGet(ObjName, OBJPROP_COLOR); datetime old_startTime=(datetime)ObjectGet(ObjName, OBJPROP_TIME1); int A = (int)round(B); 2. Использовать специальные функции нового MQL4. Правда, для переменных типа color и datetime этот способ не поможет - нет для них специальных функций. А потому все равно придется прибегать к явному приведению: color old_color=(color)ObjectGetInteger(0, ObjName, OBJPROP_COLOR); datetime old_startTime=(datetime)ObjectGetInteger(0, ObjName, OBJPROP_TIME, 1); Тем не менее, второй способ выгоднее тем, что делает код более универсальным. В будущем такой код будет проще портировать в MQL5.

Sergey: Спасибо! Все понятно и все работает!

Sergey: Хочу сделать контроль тестового времени эксперта с использованием глобальных переменных. Проблема в этой строке if (!GlobalVariableGet(ControlTimeExpert, TimeExpertControl)) return; // Вызов гл.пер. Если ставлю &TimeExpertControl идет ошибка, а без & срабатывает return. Возможно есть еще ошибки, не знаю. string ControlTimeExpert; double TimeExpertControl; int j_TimeExpertControl; datetime LastBar; if (LastBar != iTime(NULL,PERIOD_D1,0)) // Если новый день, то делаем проверку { if (!GlobalVariableCheck(ControlTimeExpert)) // Если гл.пер. нет, то создаем GlobalVariableSet(ControlTimeExpert,TimeCurrent()); // Время первого запуска советника if (!GlobalVariableGet(ControlTimeExpert, TimeExpertControl)) return; // Вызов гл.пер. j_TimeExpertControl=(int)TimeExpertControl; if (TimeCurrent()>j_TimeExpertControl+7*24*60*60) // 7 суток на проверку { Alert("Время тестирования советника истекло"); return; } } LastBar = iTime(NULL,PERIOD_D1,0);

Scriptong: На вскидку код верный, если подразумевать, что приведен только участок кода, а не весь код. Если же это весь код, тогда проблема в том, что переменная ControlTimeExpert не инициализирована. В ней нет названия глобальной переменной, отсюда и проблемы. А почему выбран такой странный способ контроля? Ведь глобальную переменную пользователь может удалить вручную, что сведет на нет всю защиту. Лучше прописывать абсолютную дату окончания периода тестирования в самом коде. При отсылке конкретному пользователю просто перекомпилировать эксперт: input datetime i_currentTime = __DATE__; datetime g_testExpirationDate; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- g_testExpirationDate = i_currentTime + PERIOD_D1 * 60; //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if (TimeCurrent() > g_testExpirationDate) { Alert("Срок демо-версии истек. Советник отключен!"); ExpertRemove(); return; } }

Sergey: Для отдельных пользователей проблем нет. Но хочу разместить полнофункциональную демо версию на сайте и не заморачиваться под каждого клиента. Scriptong пишет: На вскидку код верный, если подразумевать, что приведен только участок кода, а не весь код. Если же это весь код, тогда проблема в том, что переменная ControlTimeExpert не инициализирована. Вообще то это весь код. Но кажется я понял. string ControlTimeExpert= "ControlTimeEA"; Теперь задана как название гл.переменной в начале. Попробую. Остался вопрос: Чтобы осознать не бесполезность своих действий, подскажите где хранятся глобальные переменные? Я к примеру не знаю, думаю и большинство трейдеров тоже.



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