Rever27 Опубликовано 18 июля, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 18 июля, 2020 4 часа назад, Stranger80 сказал: double NormaliseDouble(double Lots, int 2); Компилятор ругается Потому что NormalizeDouble это функция, которой нужно задать параметры без объявления типа данных. Если вам нужно округлить лот до 2 знаков после запятой, то это можно сделать так: double Lots = 0.1; double ND = NormalizeDouble(Lots,2); Вначале объявлен лот, который вам нужен. Можно и не объявлять, если он уже есть из какого то ордера. Потом объявляется переменная ND, которая уже округляет дробное число. Можно сделать и так: double Lots = 0.1; Lots = NormalizeDouble(Lots,2); 2 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Stranger80 Опубликовано 19 июля, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 19 июля, 2020 22 часа назад, Rever27 сказал: double Lots =( Free / D); Lots = NormaliseDouble( Lots, 2); объявил функцию: 39 double NormaliseDouble(); получил: 74 double Lots =( Free / D); 75 Lots = NormaliseDouble( Lots, 2); 80 MA_1 = NormaliseDouble( MA_1, Digits);0 81 MA_2 = NormaliseDouble(MA_2, Digits); 'NormaliseDouble' - wrong parameters count Test!.mq4 74 14 'NormaliseDouble' - wrong parameters count Test!.mq4 79 8 'NormaliseDouble' - wrong parameters count Test!.mq4 80 8 Когда объявлял 38 double NormaliseDouble(double MA_1,int Digits); 39 double NormaliseDouble(double MA_2,int Digits); 40 double NormaliseDouble(double Lots,int 2); получал только 1 errors, 0 warnings 2 1 '2' - comma expected Test!.mq4 40 40 при этом строки 75, 80 и81 возражений не вызывали. Решил, что от номалзции объёма можно отказаться и вычеркнул строку 40 после чег компилятор сказал: 1 errors, 0 warnings 2 1 'NormaliseDouble' - function must have a body Test!.mq4 38 8 Но там тело функции есть. После вычёркивании 38-й требовал тело 39-й,а посл удаления и её сообщил, 3 ошибки что в 74, 79 и 80 функция NormaliseDouble 'NormaliseDouble' - function not defined Test!.mq4 75 14 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Ent Опубликовано 19 июля, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 19 июля, 2020 36 минут назад, Stranger80 сказал: Спойлер объявил функцию: 39 double NormaliseDouble(); получил: 74 double Lots =( Free / D); 75 Lots = NormaliseDouble( Lots, 2); 80 MA_1 = NormaliseDouble( MA_1, Digits);0 81 MA_2 = NormaliseDouble(MA_2, Digits); 'NormaliseDouble' - wrong parameters count Test!.mq4 74 14 'NormaliseDouble' - wrong parameters count Test!.mq4 79 8 'NormaliseDouble' - wrong parameters count Test!.mq4 80 8 Когда объявлял 38 double NormaliseDouble(double MA_1,int Digits); 39 double NormaliseDouble(double MA_2,int Digits); 40 double NormaliseDouble(double Lots,int 2); получал только 1 errors, 0 warnings 2 1 '2' - comma expected Test!.mq4 40 40 при этом строки 75, 80 и81 возражений не вызывали. Решил, что от номалзции объёма можно отказаться и вычеркнул строку 40 после чег компилятор сказал: 1 errors, 0 warnings 2 1 'NormaliseDouble' - function must have a body Test!.mq4 38 8 Но там тело функции есть. После вычёркивании 38-й требовал тело 39-й,а посл удаления и её сообщил, 3 ошибки что в 74, 79 и 80 функция NormaliseDouble 'NormaliseDouble' - function not defined Test!.mq4 75 14 Посмотрите внимательно на синтаксис, не NormaliseDouble, а NormalizeDouble Пример: double Lots, MA_1, MA_2; Lots = NormalizeDouble((Free / D), 2); MA_1 = NormalizeDouble(MA_1, _Digits); MA_2 = NormalizeDouble(MA_2, _Digits); Соответственно переменные Free и D должны также быть объявлены и определены. 2 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Stranger80 Опубликовано 20 июля, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 20 июля, 2020 Не могу найти ответ. Что делать? И уже не могу вспомнить как задать вопрос. 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Aestral Опубликовано 27 июля, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 27 июля, 2020 Здравствуйте, изучаю mql4, возник вопрос: почему в enum нульзя явно указать строку, допустим вот так: enum MODE_ENUM { All_symbols="", //All symbols Current_symbol="0", //Current symbol }; Компилятор ругается: '=' - constant expression is not integral Приходится вот так изворачиваться: enum MODE_ENUM { All_symbols, //All symbols Current_symbol, //Current symbol }; и далее: string Symb; switch(Mode) { case All_symbols: Symb=""; break; case Current_symbol: break; Symb="0"; } Как правильнее реализовать мою идею без этого костыля? Изменено 27 июля, 2020 пользователем Aestral Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rever27 Опубликовано 27 июля, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 27 июля, 2020 2 часа назад, Aestral сказал: почему в enum нульзя явно указать строку, допустим вот так: Потому что енум это перечисление, и может быть больше целым чистом типа int. Строковые и другие типа данных сюда не подходят. 2 часа назад, Aestral сказал: Как правильнее реализовать мою идею без этого костыля? Это не костыль, а корректный вариант назначения стринговой переменной в зависимости от значения енум. Можно этот записать короче: enum MODE_ENUM { All_symbols = 0, //All symbols Current_symbol = 1, //Current symbol }; string Symb=(Mode == All_symbols ? "" : "0"); Изменено 27 июля, 2020 пользователем Rever27 2 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Aestral Опубликовано 28 июля, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 28 июля, 2020 Еще один вопрос на засыпку: Делаю панельку с помощью класса CPanel, которая выводит на график историю сделок. Как заставить панель быть поверх созданных объектов на графике (истории ордеров)? Вариант с ObjectSet(...,OBJPROP_BACK,true); не подходит, так как нужно чтоб объекты были поверх графика, но не поверх панели. Изменено 28 июля, 2020 пользователем Aestral Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rever27 Опубликовано 28 июля, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 28 июля, 2020 1 час назад, Aestral сказал: Как заставить панель быть поверх созданных объектов на графике (истории ордеров)? Автор панели на форуме MQL ответил лаконично - никак. Чтобы панель была поверх объектов, созданных после нее - нужно свернуть и развернуть ее. Лично я не силен в ООП, почему копаться в этой огромной библиотеке нет желания в поисках той функции, которая обновляет данные, если она вообще там есть. Как вариант, можно написать код, который бы проверял каждый тик количество графических объектов на графике и если их стало больше - обновлял панель, как это происходить при сворачивании/разворачивании. Вот вариант, который удаляет панель и снова возвращает на график. Но минус в том, что она перемещается на первоначальное место создания и все ее данные сбиваются, если они там есть. int _ObjectsTotal = 0; void OnTick() { if(ObjectsTotal() != _ObjectsTotal) { _ObjectsTotal = ObjectsTotal(); TradePanel.Destroy(5); TradePanel.Create(ChartID(),ea_name,0,7,20,205,354); TradePanel.Run(); } } А так да, нужно копать код, искать, где именно она создается и обновлять все ее элементы сразу после появления нового объекта. 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
0ll Опубликовано 29 июля, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 29 июля, 2020 17 часов назад, Rever27 сказал: Чтобы панель была поверх объектов, созданных после нее - нужно свернуть и развернуть ее. У панели в заголовке есть соответствующие кнопочки. @Aestral проверьте после восстановления панели она сверху будет или нет? если Ок, то к кнопочкам привязаны соответствующие функции, которые можно вставить в код @Rever27 и всё. Ссылка на сообщение Поделиться на другие сайты More sharing options...
Элёр Опубликовано 30 июля, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 30 июля, 2020 extern int StopLoss = 20; extern int TakeProfit = 20; void OnTick() { double OpenPrice1 = Ask+5*Point; double BuyStopLoss = OpenPrice1 - (StopLoss * Point); double TakeProfitBuy = OpenPrice1 + (TakeProfit * Point); double OpenPrice2 = Bid-5*Point; double SellStopLoss = OpenPrice2 + (StopLoss * Point); double TakeProfitSell = OpenPrice2 - (TakeProfit * Point); //int buyOchil; if (OrdersTotal() == 0) { int buyOchil = OrderSend(Symbol(), OP_BUYSTOP, 1, OpenPrice1, 3, BuyStopLoss, TakeProfitBuy); bool resb = OrderSelect(buyOchil, SELECT_BY_TICKET); double r=OrderOpenPrice(); int sellOchil = OrderSend(Symbol(), OP_SELLSTOP, 1, OpenPrice2, 3, SellStopLoss, TakeProfitSell); bool ress = OrderSelect(sellOchil, SELECT_BY_TICKET); double r2=OrderOpenPrice(); double k = r-10*Point; double l = r2+10*Point; if (Ask == k) { int sellOchil2 = OrderSend(Symbol(), OP_BUYSTOP, 2, Ask+10*Point, 3, NULL, NULL); Alert("1 ishladi"); } if (Bid == l) { int buyOchil2 = OrderSend(Symbol(), OP_SELLSTOP, 2, Bid-10*Point, 3, NULL, NULL); Alert("2 ishladi"); } } } if не работает Что мой ошибка!!! Помогите!!! Ссылка на сообщение Поделиться на другие сайты More sharing options...
usver73 Опубликовано 31 июля, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 31 июля, 2020 8 часов назад, Элёр сказал: if не работает Вещественные числа сравнивать точно == не рекомендуется- где гарантия, что до 16(?) знака у Вас будет совпадение. Проверяйте через if(Ask >= k) (или <= - как по логике). п.с. Не уверен, но может NormalizeDouble(k,_Digits) поможет Изменено 31 июля, 2020 пользователем usver73 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
0ll Опубликовано 1 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 1 августа, 2020 @Элёр достижение ценой некого расчётного уровня нужно делать в 2 шага: 1. сохраняем Ask, 2. на следующем тике сравниваем if ( Ask1 < k && Ask2 >= k ) ..... Это гарантированно работает 2 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 3 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 3 августа, 2020 В 17.07.2020 в 16:43, diodio сказал: Ну у меня почти тоже самое написано, только немного по-другому, вопрос в том почему в журнале такие числа? На каждом тике считает? Потому, что: 1. Вы не обнуляете профит перед началом цикла. Между тиками накопленное значение сохраняется, а потом на следующем тике вы в него еще насыпаете тех же ордеров в цикле. 2. Вывод в консоль внутри цикла. Это уже не очень существенно, но все же неправильно. Скажем, если забыть о первой проблеме и считать в цикле три ордера с профитом по доллару, в консоли вы увидите профит 1, профит 2, профит 3 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 3 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 3 августа, 2020 В 21.07.2020 в 02:36, Stranger80 сказал: Не могу найти ответ. Что делать? И уже не могу вспомнить как задать вопрос. Отсыпь и мне немного 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 3 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 3 августа, 2020 В 27.07.2020 в 21:28, Rever27 сказал: Потому что енум это перечисление, и может быть больше целым чистом типа int. Строковые и другие типа данных сюда не подходят. Это не костыль, а корректный вариант назначения стринговой переменной в зависимости от значения енум. Можно этот записать короче: enum MODE_ENUM { All_symbols = 0, //All symbols Current_symbol = 1, //Current symbol }; string Symb=(Mode == All_symbols ? "" : "0"); Еще лучше потом объявить массив строк и обращаться к его значениям по элементам енумерации: enum MY_ENUM { ZERO = 0, //that's zero ONE, //and one TWO //and two }; string myEnumStr[] = {"String for zero", "String for one", "String for two"}; ..... void PrintInfo(MY_ENUM _e) { Print("Element ", EnumToString(_e), " number ", int(_e), " is associated with a string '", myEnumStr[_e], "'"); } А можно и не строк. Очень удобный механизм разделения логики 2 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rigal Опубликовано 3 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 3 августа, 2020 В 02.08.2020 в 04:32, 0ll сказал: @Элёр достижение ценой некого расчётного уровня нужно делать в 2 шага: 1. сохраняем Ask, 2. на следующем тике сравниваем if ( Ask1 < k && Ask2 >= k ) ..... Это гарантированно работает ну и в целом сравнение двух чисел с плавающей точкой принято делать через величину их разницы: if(MathAbs(a - b) < DBL_EPSILON) these two are equal if(MathAbs(price1 - price2) < Point()) the price is the same Как-то так 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
0ll Опубликовано 4 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 4 августа, 2020 23 часа назад, Rigal сказал: ну и в целом сравнение двух чисел с плавающей точкой принято делать через величину их разницы Сравнить на равенство - да, но пересечение уровня может быть с микрогэпом и тогда разницы в пипс будет недостаточно, нужно исследовать изменение знака - короче более сложно для нашей темы, имхо. Ссылка на сообщение Поделиться на другие сайты More sharing options...
diodio Опубликовано 6 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 6 августа, 2020 Всем привет, подскажите как оформить переменные и в каком месте советника, чтоб их значения сохранялись для дальнейшей работы с ними? Допустим у меня переменная HistTotalBuy в которую должен складываться профит от закрытых ордеров на протяжении всей работы советника и чтоб это значение не удалялось после прохода множественных итераций. Ссылка на сообщение Поделиться на другие сайты More sharing options...
machine Опубликовано 6 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 6 августа, 2020 Любые глобальные переменные. В OnInit не инициализировать, а сразу при объявлении. Тогда не будет сбрасываться при переключении таймфрейма/переинициализации. Ссылка на сообщение Поделиться на другие сайты More sharing options...
diodio Опубликовано 6 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 6 августа, 2020 1 час назад, machine сказал: Любые глобальные переменные. В OnInit не инициализировать, а сразу при объявлении. Тогда не будет сбрасываться при переключении таймфрейма/переинициализации. int init() { int HistTotalBuy = 0; return(0); } Вот так пойдет? Далее в нее уже запишется нужное мне значение и она уже будет не нулевой? Изначальное значение должно быть ноль просто. Ссылка на сообщение Поделиться на другие сайты More sharing options...
machine Опубликовано 6 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 6 августа, 2020 Так: int HistTotalBuy = 0; int init() { return(0); } Изменено 6 августа, 2020 пользователем machine Ссылка на сообщение Поделиться на другие сайты More sharing options...
pavlus777 Опубликовано 6 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 6 августа, 2020 Новый урок https://tlap.com/massivy-i-czikly/ 5 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
diodio Опубликовано 11 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 11 августа, 2020 Всем привет! Объявил статический массив для подсчёта ордеров: int arrCountOrders[50]; Теперь чтоб в цикле подсчитать ордера я пишу так: void CountOrder() { ArrayInitialize(arrCountOrders,0); for(int x=OrdersTotal()-1; x>=0; x--) { if(OrderSelect(x, SELECT_BY_POS, MODE_TRADES)==false) continue; if(OrderSymbol()!=Symbol() || OrderMagicNumber() != Magic) continue; arrCountOrders[OrderType()]++; } return; } или же чтоб его правильно заполнить, необходимо указать на массив путем ссылки? void CountOrder(int &arrCountOrders[50]) { ArrayInitialize(arrCountOrders,0); for(int x=OrdersTotal()-1; x>=0; x--) { if(OrderSelect(x, SELECT_BY_POS, MODE_TRADES)==false) continue; if(OrderSymbol()!=Symbol() || OrderMagicNumber() != Magic) continue; arrCountOrders[OrderType()]++; } return; } Какой вариант будет правильным? Изменено 11 августа, 2020 пользователем diodio Ссылка на сообщение Поделиться на другие сайты More sharing options...
Rever27 Опубликовано 11 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 11 августа, 2020 2 часа назад, diodio сказал: Какой вариант будет правильным? Зачем для того, чтобы просто узнать сколько ордеров по этой паре у этого советника объявлять массив? Просто можно сделать так: void OnStart() { count_buy = CountOrder(OP_BUY); count_sell = CountOrder(OP_SELL); } //+------------------------------------------------------------------+ int CountOrder(int Order_Type) { int orders=0; for(int i=OrdersTotal()-1;i>=0;i--){ if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==false) continue; if(OrderSymbol()!=_Symbol || OrderMagicNumber() != MagicNumber) continue; if(Order_Type == OrderType() || Order_Type == -1) orders++; } return orders; } В итоге можно знать отдельно сколько ордеров на покупку, а сколько на продажу. Либо же если вызвать функцию так count = CountOrder(-1); То будет суммарный подсчет всех ордеров сразу. Если же нужно в массив записывать типы ордеров, то правильнее сделать так: void CountOrder() { ArrayInitialize(arrCountOrders,0); int i = 0; for(int x=OrdersTotal()-1; x>=0; x--) { if(OrderSelect(x, SELECT_BY_POS, MODE_TRADES)==false) continue; if(OrderSymbol()!=Symbol() || OrderMagicNumber() != Magic) continue; arrCountOrders[i] = OrderType(); i++; } return; } Но в сумме это тоже не совсем корректно, потому что ордеров может быть больше 50, а массив является статическим. Лучше уж тогда его сделать динамическим, если для этой задачи он вообще нужен. Лиииибо, если все же нужен массив и нужно знать значение всех типов ордеров, то можно сделать так: void OnStart() { int arrCountOrders[6]; CountOrder(arrCountOrders); Print("BUY: ",arrCountOrders[OP_BUY]); Print("SELL: ", arrCountOrders[OP_SELL]); Print("BUYLIMIT: ", arrCountOrders[OP_BUYLIMIT]); Print("BUYSTOP: ", arrCountOrders[OP_BUYSTOP]); Print("SELLLIMIT: ", arrCountOrders[OP_SELLLIMIT]); Print("SELLSTOP: ", arrCountOrders[OP_SELLSTOP]); } //+------------------------------------------------------------------+ void CountOrder(int &arrCountOrders[6]) { ArrayInitialize(arrCountOrders,0); for(int x=OrdersTotal()-1; x>=0; x--) { if(OrderSelect(x, SELECT_BY_POS, MODE_TRADES)==false) continue; if(OrderSymbol()!=Symbol() || OrderMagicNumber() != Magic) continue; if(OrderType() > 5) continue; arrCountOrders[OrderType()]++; } return; } Изменено 11 августа, 2020 пользователем Rever27 2 Ссылка на сообщение Поделиться на другие сайты More sharing options...
usver73 Опубликовано 11 августа, 2020 Поделиться Обучение языку MQL4 под MetaTrader 4 Опубликовано 11 августа, 2020 4 часа назад, diodio сказал: Всем привет! Объявил статический массив для подсчёта ордеров: int arrCountOrders[50]; Теперь чтоб в цикле подсчитать ордера я пишу так: Исказил всю идею Размерность массива определяется количеством типов ордеров, т.е. 6 4 часа назад, diodio сказал: или же чтоб его правильно заполнить, необходимо указать на массив путем ссылки? ты его объявляешь на глобальном уровне, т.е. он будет доступен во всех функциях. Не нужно его передавать при вызове функции подсчета. Все это обкашлено 100 раз... 1 Ссылка на сообщение Поделиться на другие сайты More sharing options...
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти