Все приказы на совершение торговых операций отправляются в виде структуры торгового запроса MqlTradeRequest с помощью функции OrderSend(). Результат выполнения этой функции помещается в структуру MqlTradeResult, поле retcode которой содержит код возврата торгового сервера.
10004 |
TRADE_RETCODE_REQUOTE |
Реквота |
10006 |
TRADE_RETCODE_REJECT |
Запрос отклонен |
10007 |
TRADE_RETCODE_CANCEL |
Запрос отменен трейдером |
10008 |
TRADE_RETCODE_PLACED |
Ордер размещен |
10009 |
TRADE_RETCODE_DONE |
Заявка выполнена |
10010 |
TRADE_RETCODE_DONE_PARTIAL |
Заявка выполнена частично |
10011 |
TRADE_RETCODE_ERROR |
Ошибка обработки запроса |
10012 |
TRADE_RETCODE_TIMEOUT |
Запрос отменен по истечению времени |
10013 |
TRADE_RETCODE_INVALID |
Неправильный запрос |
10014 |
TRADE_RETCODE_INVALID_VOLUME |
Неправильный объем в запросе |
10015 |
TRADE_RETCODE_INVALID_PRICE |
Неправильная цена в запросе |
10016 |
TRADE_RETCODE_INVALID_STOPS |
Неправильные стопы в запросе |
10017 |
TRADE_RETCODE_TRADE_DISABLED |
Торговля запрещена |
10018 |
TRADE_RETCODE_MARKET_CLOSED |
Рынок закрыт |
10019 |
TRADE_RETCODE_NO_MONEY |
Нет достаточных денежных средств для выполнения запроса |
10020 |
TRADE_RETCODE_PRICE_CHANGED |
Цены изменились |
10021 |
TRADE_RETCODE_PRICE_OFF |
Отсутствуют котировки для обработки запроса |
10022 |
TRADE_RETCODE_INVALID_EXPIRATION |
Неверная дата истечения ордера в запросе |
10023 |
TRADE_RETCODE_ORDER_CHANGED |
Состояние ордера изменилось |
10024 |
TRADE_RETCODE_TOO_MANY_REQUESTS |
Слишком частые запросы |
10025 |
TRADE_RETCODE_NO_CHANGES |
В запросе нет изменений |
10026 |
TRADE_RETCODE_SERVER_DISABLES_AT |
Автотрейдинг запрещен сервером |
10027 |
TRADE_RETCODE_CLIENT_DISABLES_AT |
Автотрейдинг запрещен клиентским терминалом |
10028 |
TRADE_RETCODE_LOCKED |
Запрос заблокирован для обработки |
10029 |
TRADE_RETCODE_FROZEN |
Ордер или позиция заморожены |
10030 |
TRADE_RETCODE_INVALID_FILL |
Указан неподдерживаемый тип исполнения ордера по остатку |
10031 |
TRADE_RETCODE_CONNECTION |
Нет соединения с торговым сервером |
10032 |
TRADE_RETCODE_ONLY_REAL |
Операция разрешена только для реальных счетов |
10033 |
TRADE_RETCODE_LIMIT_ORDERS |
Достигнут лимит на количество отложенных ордеров |
10034 |
TRADE_RETCODE_LIMIT_VOLUME |
Достигнут лимит на объем ордеров и позиций для данного символа |
10035 |
TRADE_RETCODE_INVALID_ORDER |
Неверный или запрещённый тип ордера |
10036 |
TRADE_RETCODE_POSITION_CLOSED |
Позиция с указанным POSITION_IDENTIFIER уже закрыта |
10038 |
TRADE_RETCODE_INVALID_CLOSE_VOLUME |
Закрываемый объем превышает текущий объем позиции |
10039 |
TRADE_RETCODE_CLOSE_ORDER_EXIST |
Для указанной позиции уже есть ордер на закрытие. Может возникнуть при работе в системе хеджинга:
|
10040 |
TRADE_RETCODE_LIMIT_POSITIONS |
Количество открытых позиций, которое можно одновременно иметь на счете, может быть ограничено настройками сервера. При достижении лимита в ответ на выставление ордера сервер вернет ошибку TRADE_RETCODE_LIMIT_POSITIONS. Ограничение работает по-разному в зависимости от типа учета позиций на счете:
|
10041 |
TRADE_RETCODE_REJECT_CANCEL |
Запрос на активацию отложенного ордера отклонен, а сам ордер отменен |
10042 |
TRADE_RETCODE_LONG_ONLY |
Запрос отклонен, так как на символе установлено правило «Разрешены только длинные позиции» (POSITION_TYPE_BUY) |
10043 |
TRADE_RETCODE_SHORT_ONLY |
Запрос отклонен, так как на символе установлено правило «Разрешены только короткие позиции» (POSITION_TYPE_SELL) |
10044 |
TRADE_RETCODE_CLOSE_ONLY |
Запрос отклонен, так как на символе установлено правило «Разрешено только закрывать существующие позиции« |
Предупреждения компилятора носят информационный характер и не являются сообщениями об ошибках.
21 |
Неполная запись даты в строке datetime |
22 |
Ошибочные числа в строке datetime для даты, требования: год 1970<=X<=3000 месяц 0<X<=12 день 0<X<= 31/30/28(29)…. |
23 |
Ошибочные числа в строке datetime для времени, требования: час 0<=X<24 минута 0<=X<60 |
24 |
Некорректный цвет в формате RGB: одна из компонент RGB меньше 0 или больше 255 |
25 |
Неизвестный символ эскейп последовательности. Известные: n r t \ » ’ X x |
26 |
Слишком большой объем локальных переменных (>512кб) функции, уменьшите их количество |
29 |
Перечисление уже определено (дублирование) – члены будут добавлены к первому определению |
30 |
Переопределение макроса |
31 |
Переменная объявлена, но нигде не используется |
32 |
Конструктор должен иметь тип void |
33 |
Деструктор должен иметь тип void |
34 |
Константа не вмещается в диапазон целых (X>_UI64_MAX || X<_I64_MIN) и будет преобразована в тип double |
35 |
Слишком длинный HEX больше 16 значащих символов (обрезаются старшие полубайты) |
36 |
Нет ни одного полубайта в HEX строке «0x» |
37 |
Нет ни одной функции — нечего будет выполнять |
38 |
Используется неинициализированная переменная |
41 |
Функция не имеет тела, но и не вызывается |
43 |
Возможны потери данных при преобразовании типа. Пример: int x=(double)z; |
44 |
Потеря точности(данных) при преобразовании константы. Пример: int x=M_PI |
45 |
Несовпадение знаков операндов в операциях сравнения. Пример: (char)c1>(uchar)c2 |
46 |
Проблемы с импортом функций – требуется объявление #import либо импорт функций уже закрыт |
47 |
Описание слишком большое – лишние символы не будут включены в исполняемый файл |
48 |
Количество индикаторных буферов объявлено меньше, чем требуется |
49 |
Не указан цвет для отрисовки графической серии в индикаторе |
50 |
Нет ни одной графической серии для отображения индикатора |
51 |
Не обнаружена функция-обработчик ‘OnStart» в скрипте |
52 |
Функция-обработчик ‘OnStart» определена с неверными параметрами |
53 |
Функция ‘OnStart’ может быть определена только в скрипте |
54 |
Функция ‘OnInit’ определена с неверными параметрами |
55 |
Функция ‘OnInit’ не используется в скриптах |
56 |
Функция ‘OnDeinit’ определена с неверными параметрами |
57 |
Функция ‘OnDeinit’ не используется в скриптах |
58 |
Определены две функции ‘OnCalculate’. Будет использована OnCalculate() на одном ценовом массиве |
59 |
Обнаружено переполнение при вычислении сложной целочисленной константы |
60 |
Возможно, переменная неинициализирована. |
61 |
Данное объявление делает недоступным обращение к локальной переменной, объявленной на указанной строке |
62 |
Данное объявление делает недоступным обращение к глобальной переменной, объявленной на указанной строке |
63 |
Не может быть использовано для статических массивов |
64 |
Данное объявление делает недоступным обращение к предопределенной переменной |
65 |
Значение выражения всегда true/false |
66 |
Использование переменной или выражения типа bool в математических операциях является небезопасным |
67 |
Результат применения оператора унарного минуса к беззнаковому типу ulong неопределен |
68 |
Версия, указанная в свойстве #property version, недопустима для размещения в разделе Маркет, правильный формат #property version «XXX.YYY» |
69 |
Отсутствует выражение для выполнения по условию |
70 |
Неверный возвращаемый тип функции или некорректные параметры при объявлении функции-обработчика события |
71 |
Требуется явное приведение структур к одному типу |
72 |
Данное объявление делает недоступным прямое обращение к члену класса, объявленному на указанной строке. Доступ будет возможен только с помощью операции разрешения контекста :: |
73 |
Константа в двоичной записи слишком велика, старшие разряды будут отброшены |
74 |
Параметр в методе наследуемого класса отличается модификатором const, дочерняя функция перегрузила функцию родителя |
75 |
Отрицательное или слишком большое значения смещения в битовой операции сдвига, результат выполнения неопределён |
76 |
Функция должна вернуть значение |
77 |
Функция типа void не должна возвращать значение |
78 |
Не все варианты выполнения возвращают значение |
79 |
Выражения на глобальном уровне не разрешены |
80 |
Возможна ошибка в последовательности выполнения операций, используйте скобки для явного указания порядка |
81 |
Найдено два вида вызова OnCalCulate(). Вызываться будет вариант с использованием таймсерий OHLC |
82 |
Структура не содержит членов, размер будет приравнен 1 байту |
83 |
Нет обработки результата выполнения функции |
84 |
Индикатор, включаемый как ресурс, скомпилирован в режиме отладки. Это снижает его производительность. Для повышения скорости работы его нужно перекомпилировать |
85 |
Слишком большой код символа в строке, должен быть в диапазоне от 0 до 65535 |
86 |
Нераспознанный служебный символ в строке |
87 |
Не указано свойство индикатора, задающее вывод в главное окно или в отдельное подокно. Будет применено свойство #property indicator_chart_window |
MetaEdtior 5, редактор mql5-программ, выдает сообщения об ошибках программы, обнаруженных встроенным компилятором на стадии компиляции. Список этих ошибок приведен ниже в таблице. Для компиляции исходного кода в исполняемый нажмите F7. Программы с ошибками не могут быть скомпилированы, пока ошибки, указанные компилятором, не будут устранены.
100 |
Ошибка чтения файла |
101 |
Ошибка открытия *.EX5 файла для записи |
103 |
Недостаточно свободной памяти для завершения компиляции |
104 |
Нераспознанная компилятором пустая синтаксическая единица |
105 |
Некорректное имя файла в #include |
106 |
Ошибка доступа к файлу в #include (возможно файл не существует) |
108 |
Неподходящее имя для #define |
109 |
Неизвестная команда препроцессора (допустимы #include,#define,#property,#import) |
110 |
Неизвестный для компилятора символ |
111 |
Функция не реализована (описание есть, тела нет) |
112 |
Пропущена двойная кавычка («) |
113 |
Пропущена открывающая угловая скобка (<) или двойная кавычка («) |
114 |
Пропущена одинарная кавычка (‘) |
115 |
Пропущена закрывающая угловая скобка «>» |
116 |
Не указан тип в объявлении |
117 |
Нет оператора возврата return или имеется не во всех ветках выполнения |
118 |
Ожидалась открывающая скобка параметров вызова |
119 |
Ошибка записи EX5 |
120 |
Некорректный доступ к элементу массива |
121 |
Функция не имеет тип void и оператор return должен вернуть значение |
122 |
Некорректное объявление деструктора |
123 |
Отсутствует двоеточие «:» |
124 |
Переменная уже объявлена |
125 |
Переменная с таким идентификатором уже объявлена |
126 |
Имя переменной слишком длинное (>250 символов) |
127 |
Структура с таким идентификатором уже определена |
128 |
Структура не определена |
129 |
Член структуры с таким именем уже определен |
130 |
Нет такого члена структуры |
131 |
Нарушена парность квадратных скобок |
132 |
Ожидается открывающая круглая скобка «(« |
133 |
Несбалансированные фигурные скобки ( отсутствует «}» ) |
134 |
Сложно для компиляции (слишком большое ветвление, внутренний стек уровней переполнен) |
135 |
Ошибка открытия файла на чтение |
136 |
Недостаточно памяти для загрузки исходного файла в память |
137 |
Ожидается переменная |
138 |
Ссылка не может быть инициализирована |
140 |
Ожидалось присваивание (возникает при объявлении) |
141 |
Ожидается открывающая фигурная скобка «{« |
142 |
Параметр может быть только динамическим массивом |
143 |
Использование типа «void» недопустимо |
144 |
Нет пары для «)» или «]», т.е. отсутствует «(» или «[« |
145 |
Нет пары для «(» или «[«, т.е. отсутствует «)» или «]» |
146 |
Некорректная размерность массива |
147 |
Слишком много параметров (>64) |
149 |
Этот токен тут не ожидается |
150 |
Недопустимое использование операции (неправильные операнды) |
151 |
Выражение типа void недопустимо |
152 |
Ожидается оператор |
153 |
Неправильное использование break |
154 |
Ожидается точка с запятой «;» |
155 |
Ожидается запятая «,» |
156 |
Тип должен быть определен как класс, а не как структура |
157 |
Ожидалось выражение |
158 |
В HEX встречается «не HEX символ» или слишком длинное число (количество цифр > 511) |
159 |
Строка-константа имеет более 65534 символов |
160 |
Определение функции здесь недопустимо |
161 |
Неожиданный конец программы |
162 |
Форвардная декларация для структур запрещена |
163 |
Функция с таким именем уже определена и имеет иной тип возвращаемого значения |
164 |
Функция с таким именем уже определена и имеет иной набор параметров |
165 |
Функция с таким именем уже определена и реализована |
166 |
Перегрузка функции для данного вызова не найдена |
167 |
Функция с возвращаемым значением типа void не может возвращать значение |
168 |
Функция не определена |
170 |
Ожидается значение |
171 |
В выражении case допустимы только целочисленные константы |
172 |
Значение для case в этом switch уже использовано |
173 |
Ожидается целочисленное значение |
174 |
В выражении #import ожидается имя файла |
175 |
Выражения на глобальном уровне не допустимы |
176 |
Пропущена круглая скобка «)» перед «;» |
177 |
Слева от знака равенства предполагается переменная |
178 |
Результат выражения не используется |
179 |
Объявление переменных в case недопустимо |
180 |
Неявное преобразование из строки в число |
181 |
Неявное преобразование числа в строку |
182 |
Неоднозначный вызов перегруженной функции (подходят несколько перегрузок) |
183 |
Недопустимый else без соответствующего if |
184 |
Недопустимый case или default без соответствующего switch |
185 |
Недопустимое использование эллипсиса |
186 |
Инициализирующая последовательность имеет большее количество элементов чем инициализируемая переменная |
187 |
Ожидается константа для case |
188 |
Требуется константное выражение |
189 |
Константная переменная не может быть изменена |
190 |
Ожидается закрывающая скобка или запятая (объявление члена массива) |
191 |
Идентификатор перечисления уже используется |
192 |
Перечисление не может иметь модификаторов доступа (const, extern, static) |
193 |
Член перечисления уже объявлен с другим значением |
194 |
Существует переменная, определенная с таким же именем |
195 |
Существует структура, определенная с таким же именем |
196 |
Ожидается имя члена перечисления |
197 |
Ожидается целочисленное выражение |
198 |
Деление на ноль в константном выражении |
199 |
Неверное количество параметров в функции |
200 |
Параметром по ссылке должна быть переменная |
201 |
Ожидается переменная такого же типа для передачи по ссылке |
202 |
Константная переменная не может быть передана по неконстантной ссылке |
203 |
Требуется целочисленная положительная константа |
204 |
Ошибка доступа к защищенному члену класса |
205 |
Импорт уже определен по другому пути |
208 |
Исполняемый файл не создан |
209 |
Для индикатора не найдена точка входа ‘OnCalculate’ |
210 |
Оператор continue может быть использован только внутри цикла |
211 |
Ошибка доступа к private(закрытому) члену класса |
213 |
Метод структуры или класса не объявлен |
214 |
Ошибка доступа к private(закрытому) методу класса |
216 |
Копирование структур с объектами недопустимо |
218 |
Выход индекса за границы массива |
219 |
Недопустима инициализация массивов в объявлении структуры или класса |
220 |
Конструктор класса не может иметь параметров |
221 |
Деструктор класса не может иметь параметров |
222 |
Метод класса или структуры с таким именем и параметрами уже объявлен |
223 |
Ожидается операнд |
224 |
Метод класса или структуры с таким именем есть, но с другими параметрами (объявление!=реализация) |
225 |
Импортируемая функция не описана |
226 |
Функция ZeroMemory() не применима для классов с защищенными членами или наследованием |
227 |
Неоднозначный вызов перегруженной функции (точное совпадение параметров для нескольких перегрузок) |
228 |
Ожидается имя переменной |
229 |
Ссылку нельзя объявить в этом месте |
230 |
Уже используется в качестве имени перечисления |
232 |
Ожидается класс или структура |
235 |
Нельзя вызывать delete для удаления массива |
236 |
Ожидается оператор ‘ while ‘ |
237 |
В delete должен быть указатель |
238 |
default для этого switch уже есть |
239 |
Синтаксическая ошибка |
240 |
Escape-последовательность может встретиться только в строках ( начинается с ‘’ ) |
241 |
Требуется массив – квадратная скобка ‘[‘ не относится к массиву либо в качестве параметра-массива подают не массив |
242 |
Не может быть инициализировано посредством инициализирующей последовательности |
243 |
Импорт не определен |
244 |
Ошибка оптимизатора на синтаксическом дереве |
245 |
Объявлено слишком много структур (упростите программу) |
246 |
Преобразование параметра недопустимо |
247 |
Некорректное использование оператора delete |
248 |
Нельзя объявить указатель на ссылку |
249 |
Нельзя объявить ссылку на ссылку |
250 |
Нельзя объявить указатель на указатель |
251 |
Недопустимо объявление структуры в списке параметров |
252 |
Недопустимая операция приведения типов |
253 |
Указатель можно объявить только для класса или структуры |
256 |
Необъявленный идентификатор |
257 |
Ошибка оптимизатора исполняемого кода |
258 |
Ошибка генерации исполняемого кода |
260 |
Недопустимое выражение для оператора switch |
261 |
Переполнение пула строковых констант, упростите программу |
262 |
Невозможно преобразовать к перечислению |
263 |
Нельзя использовать virtual для данных (членов класса или структуры) |
264 |
Нельзя вызвать защищенный метод класса |
265 |
Переопределяемая виртуальная функция возвращает другой тип |
266 |
Класс нельзя наследовать от структуры |
267 |
Структуру нельзя наследовать от класса |
268 |
Конструктор не может быть виртуальным (спецификатор virtual недопустим) |
269 |
Структура не может иметь виртуальных методов |
270 |
Функция должна иметь тело |
271 |
Перегрузка системных функций (функций терминала) запрещена |
272 |
Спецификатор const недопустим для функций, не являющихся членом класса или структуры |
274 |
Нельзя менять члены класса в константном методе |
276 |
Неподходящая инициализирующая последовательность |
277 |
Пропущено значение по умолчанию для параметра (специфика объявления параметров по умолчанию) |
278 |
Переопределение параметра по умолчанию (в объявлении и реализации разные значения) |
279 |
Нельзя вызвать неконстантный метод для константного объекта |
280 |
Для доступа к членам требуется объект (поставлена точка для не класса/структуры) |
281 |
Имя уже объявленной структуры нельзя использовать при объявлении |
284 |
Неразрешенное преобразование (при закрытом наследовании) |
285 |
Структуры и массивы не могут быть использованы в качестве input-переменных |
286 |
Спецификатор const недопустим для конструктора/деструктора |
287 |
Неправильное строковое выражение для типа datetime |
288 |
Неизвестное свойство (#property) |
289 |
Некорректное значение для свойства |
290 |
Некорректный индекс для свойства в #property |
291 |
Пропущен параметр вызова – < func(x,) > |
293 |
Объект должен быть передан по ссылке |
294 |
Массив должен быть передан по ссылке |
295 |
Функция была декларирована как экспортируемая |
296 |
Функция не была декларирована как экспортируемая |
297 |
Экспортировать импортируемую функцию нельзя |
298 |
Импортируемая функция не может иметь такого параметра (нельзя передавать указатель, класс или структуру, содержащую динамический массив, указатель, класс и т.д.) |
299 |
Должен быть класс |
300 |
Секция #import не закрыта |
302 |
Несоответствие типов |
303 |
extern-переменная уже инициализирована |
304 |
Не найдено ни одной экспортируемой функции или стандартной точки входа |
305 |
Явный вызов конструктора запрещен |
306 |
Метод был объявлен константным |
307 |
Метод не был объявлен константным |
308 |
Некорректный размер ресурсного файла |
309 |
Некорректное имя ресурса |
310 |
Ошибка открытия файла ресурса |
311 |
Ошибка чтения файла ресурса |
312 |
Неизвестный тип ресурса |
313 |
Некорректный путь к файлу ресурса |
314 |
Указанное имя ресурса уже используется |
315 |
Ожидались параметры макроса |
316 |
После имени макроса должен быть пробел |
317 |
Ошибка в описании параметров макроса |
318 |
Неверное число параметров при использовании макроса |
319 |
Превышение максимального количества(16) параметров для макроса |
320 |
Макрос слишком сложный, требуется упрощение |
321 |
Параметром EnumToString() может быть только перечисление |
322 |
Имя ресурса слишком длинное |
323 |
Неподдерживаемый формат изображения (допустим только BMP-формат с глубиной цвета 24 или 32 бита) |
324 |
Объявление массива внутри оператора запрещено |
325 |
Функцию можно определить только на глобальном уровне |
326 |
Данное объявление недопустимо для текущей области видимости (области определения) |
327 |
Инициализация статичных переменных значениями локальных недопустима |
328 |
Недопустимое объявление массива объектов, не имеющих конструктора по умолчанию |
329 |
Список инициализации разрешен только для конструкторов |
330 |
Отсутствует определение функции после списка инициализации |
331 |
Список инициализации пуст |
332 |
Инициализация массива в конструкторе запрещена |
333 |
В списке инициализации запрещено инициализировать члены родительского класса |
334 |
Ожидалось выражение целого типа |
335 |
Требуемый объем памяти для массива превышает максимально допустимое значение |
336 |
Требуемый объем памяти для структуры превышает максимально допустимое значение |
337 |
Требуемый объем памяти для переменных, объявленных на глобальном уровне, превышает максимально допустимое значение |
338 |
Требуемый объем памяти для локальных переменных превышает максимально допустимое значение |
339 |
Конструктор не определен |
340 |
Недопустимое имя для файла иконки |
341 |
Не удалось открыть файла иконки по указанному пути |
342 |
Файл иконки некорректен и не соответствует формату ICO |
343 |
Повторная инициализация члена в конструкторе класса/структуры с помощью списка инициализации |
344 |
Инициализация статических членов в списке инициализации конструктора не допускается |
345 |
Инициализация нестатического члена класса/структуры на глобальном уровне запрещена |
346 |
Имя метода класса/структуры совпадает с ранее объявленным именем члена |
347 |
Имя члена класса/структуры совпадает с ранее объявленным именем метода |
348 |
Виртуальная функция не может быть объявлена как static |
349 |
Модификатор const недопустим для статической функции |
350 |
Конструктор или деструктор не могут быть статическими |
351 |
Нельзя обращаться к нестатическому члену/методу класса или структуры из статической функции |
352 |
После ключевого слова operator ожидается перегружаемая операция (+,-,[],++,— и т.д.) |
353 |
Не все операции можно перегружать в MQL5 |
354 |
Определение не соответствует объявлению |
355 |
Указано неверное количество параметров для оператора |
356 |
Не обнаружено ни одной функции-обработчика события |
357 |
Методы не могут быть экспортируемыми |
358 |
Нельзя приводить указатель на константный объект к указателю на неконстантный объект |
359 |
Шаблоны классов пока не поддерживаются |
360 |
Перегрузка шаблонов функций пока не поддерживается |
361 |
Невозможно применить шаблон функции |
362 |
Неоднозначный параметр в шаблоне функции (подходят несколько типов параметра) |
363 |
Невозможно определить к какому типу параметра приводить аргумент шаблона функции |
364 |
Неверное количество параметров в шаблоне функции |
365 |
Шаблон функции не может быть виртуальным |
366 |
Шаблоны функций не могут быть экспортированы |
367 |
Нельзя импортировать шаблоны функций |
368 |
Структуры, содержащие объекты, недопустимы |
369 |
Массивы строк и структуры, содержащие объекты, недопустимы |
370 |
Статический член класса/структуры должен быть явно инициализирован |
371 |
Ограничение компилятора: строка не может содержать более 65 535 символов |
372 |
Несогласованные #ifdef/#endif |
373 |
Результатом выполнения функции не может быть объект класса, так как отсутствует конструктор копирования |
374 |
Нельзя использовать нестатические члены и/или методы при инициализации статической переменной |
375 |
OnTesterInit() нельзя использовать без объявления обработчика OnTesterDeinit() |
376 |
Имя локальной переменной совпадает с именем одного из параметров функции |
377 |
Нельзя использовать макросы __FUNCSIG__ и __FUNCTION__ вне тела функции |
378 |
Недопустимый возвращаемый тип. Например, такая ошибка будет выдана для функций, импортированных из DLL, которые возвращают структуру или указатель в качестве результата |
379 |
Ошибка при использовании шаблона |
380 |
Не используется |
381 |
Недопустимый синтаксис при объявлении чисто виртуальной функции, разрешено «=NULL» или «=0» |
382 |
Только виртуальные функции могут быть объявлены со спецификатором чисто виртуальной функции («=NULL» или «=0») |
383 |
Нельзя создать экземпляр абстрактного класса |
384 |
Для динамического приведения с помощью оператора dynamic_cast типом назначения должен быть указатель на пользовательский тип |
385 |
Ожидается тип «указатель на функцию» |
386 |
Указатели на методы не поддерживаются |
387 |
Ошибка – невозможно определить тип указателя на функцию |
388 |
Приведение типа недоступно из-за закрытого наследования |
389 |
Переменная с модификатором const должна быть проинициализирована при объявлении |
393 |
В интерфейсе могут быть объявлены только методы с публичным доступом |
394 |
Недопустимое вложение интерфейса в другой интерфейс |
395 |
Интерфейс может наследоваться только от другого интерфейса |
396 |
Ожидается интерфейс |
397 |
Интерфейсы поддерживают только публичное наследование |
398 |
Интерфейс не может содержать члены |
399 |
Нельзя создавать объекты интерфейса напрямую, только через наследование |
GetLastError() – функция, возвращающая код последней ошибки, которая хранится в предопределенной переменной _LastError. Значение этой переменной можно сбросить в ноль функцией ResetLastError().
ERR_SUCCESS |
0 |
Операция выполнена успешно |
ERR_INTERNAL_ERROR |
4001 |
Неожиданная внутренняя ошибка |
ERR_WRONG_INTERNAL_PARAMETER |
4002 |
Ошибочный параметр при внутреннем вызове функции клиентского терминала |
ERR_INVALID_PARAMETER |
4003 |
Ошибочный параметр при вызове системной функции |
ERR_NOT_ENOUGH_MEMORY |
4004 |
Недостаточно памяти для выполнения системной функции |
ERR_STRUCT_WITHOBJECTS_ORCLASS |
4005 |
Структура содержит объекты строк и/или динамических массивов и/или структуры с такими объектами и/или классы |
ERR_INVALID_ARRAY |
4006 |
Массив неподходящего типа, неподходящего размера или испорченный объект динамического массива |
ERR_ARRAY_RESIZE_ERROR |
4007 |
Недостаточно памяти для перераспределения массива либо попытка изменения размера статического массива |
ERR_STRING_RESIZE_ERROR |
4008 |
Недостаточно памяти для перераспределения строки |
ERR_NOTINITIALIZED_STRING |
4009 |
Неинициализированная строка |
ERR_INVALID_DATETIME |
4010 |
Неправильное значение даты и/или времени |
ERR_ARRAY_BAD_SIZE |
4011 |
Запрашиваемый размер массива превышает 2 гигабайта |
ERR_INVALID_POINTER |
4012 |
Ошибочный указатель |
ERR_INVALID_POINTER_TYPE |
4013 |
Ошибочный тип указателя |
ERR_FUNCTION_NOT_ALLOWED |
4014 |
Системная функция не разрешена для вызова |
ERR_RESOURCE_NAME_DUPLICATED |
4015 |
Совпадении имени динамического и статического ресурсов |
ERR_RESOURCE_NOT_FOUND |
4016 |
Ресурс с таким именем в EX5 не найден |
ERR_RESOURCE_UNSUPPOTED_TYPE |
4017 |
Неподдерживаемый тип ресурса или размер более 16 MB |
ERR_RESOURCE_NAME_IS_TOO_LONG |
4018 |
Имя ресурса превышает 63 символа |
ERR_MATH_OVERFLOW |
4019 |
При вычислении математической функции произошло переполнение |
Графики |
||
ERR_CHART_WRONG_ID |
4101 |
Ошибочный идентификатор графика |
ERR_CHART_NO_REPLY |
4102 |
График не отвечает |
ERR_CHART_NOT_FOUND |
4103 |
График не найден |
ERR_CHART_NO_EXPERT |
4104 |
У графика нет эксперта, который мог бы обработать событие |
ERR_CHART_CANNOT_OPEN |
4105 |
Ошибка открытия графика |
ERR_CHART_CANNOT_CHANGE |
4106 |
Ошибка при изменении для графика символа и периода |
ERR_CHART_WRONG_PARAMETER |
4107 |
Ошибочное значение параметра для функции по работе с графиком |
ERR_CHART_CANNOT_CREATE_TIMER |
4108 |
Ошибка при создании таймера |
ERR_CHART_WRONG_PROPERTY |
4109 |
Ошибочный идентификатор свойства графика |
ERR_CHART_SCREENSHOT_FAILED |
4110 |
Ошибка при создании скриншота |
ERR_CHART_NAVIGATE_FAILED |
4111 |
Ошибка навигации по графику |
ERR_CHART_TEMPLATE_FAILED |
4112 |
Ошибка при применении шаблона |
ERR_CHART_WINDOW_NOT_FOUND |
4113 |
Подокно, содержащее указанный индикатор, не найдено |
ERR_CHART_INDICATOR_CANNOT_ADD |
4114 |
Ошибка при добавлении индикатора на график |
ERR_CHART_INDICATOR_CANNOT_DEL |
4115 |
Ошибка при удалении индикатора с графика |
ERR_CHART_INDICATOR_NOT_FOUND |
4116 |
Индикатор не найден на указанном графике |
Графические объекты |
||
ERR_OBJECT_ERROR |
4201 |
Ошибка при работе с графическим объектом |
ERR_OBJECT_NOT_FOUND |
4202 |
Графический объект не найден |
ERR_OBJECT_WRONG_PROPERTY |
4203 |
Ошибочный идентификатор свойства графического объекта |
ERR_OBJECT_GETDATE_FAILED |
4204 |
Невозможно получить дату, соответствующую значению |
ERR_OBJECT_GETVALUE_FAILED |
4205 |
Невозможно получить значение, соответствующее дате |
MarketInfo |
||
ERR_MARKET_UNKNOWN_SYMBOL |
4301 |
Неизвестный символ |
ERR_MARKET_NOT_SELECTED |
4302 |
Символ не выбран в MarketWatch |
ERR_MARKET_WRONG_PROPERTY |
4303 |
Ошибочный идентификатор свойства символа |
ERR_MARKET_LASTTIME_UNKNOWN |
4304 |
Время последнего тика неизвестно (тиков не было) |
ERR_MARKET_SELECT_ERROR |
4305 |
Ошибка добавления или удаления символа в MarketWatch |
Доступ к истории |
||
ERR_HISTORY_NOT_FOUND |
4401 |
Запрашиваемая история не найдена |
ERR_HISTORY_WRONG_PROPERTY |
4402 |
Ошибочный идентификатор свойства истории |
ERR_HISTORY_TIMEOUT |
4403 |
Превышен таймаут при запросе истории |
ERR_HISTORY_BARS_LIMIT |
4404 |
Количество запрашиваемых баров ограничено настройками терминала |
ERR_HISTORY_LOAD_ERRORS |
4405 |
Множество ошибок при загрузке истории |
ERR_HISTORY_SMALL_BUFFER |
4407 |
Принимающий массив слишком мал чтобы вместить все запрошенные данные |
Global_Variables |
||
ERR_GLOBALVARIABLE_NOT_FOUND |
4501 |
Глобальная переменная клиентского терминала не найдена |
ERR_GLOBALVARIABLE_EXISTS |
4502 |
Глобальная переменная клиентского терминала с таким именем уже существует |
ERR_GLOBALVARIABLE_NOT_MODIFIED |
4503 |
Не было модификаций глобальных переменных |
ERR_GLOBALVARIABLE_CANNOTREAD |
4504 |
Не удалось открыть и прочитать файл со значениями глобальных переменных |
ERR_GLOBALVARIABLE_CANNOTWRITE |
4505 |
Не удалось записать файл со значениями глобальных переменных |
ERR_MAIL_SEND_FAILED |
4510 |
Не удалось отправить письмо |
ERR_PLAY_SOUND_FAILED |
4511 |
Не удалось воспроизвести звук |
ERR_MQL5_WRONG_PROPERTY |
4512 |
Ошибочный идентификатор свойства программы |
ERR_TERMINAL_WRONG_PROPERTY |
4513 |
Ошибочный идентификатор свойства терминала |
ERR_FTP_SEND_FAILED |
4514 |
Не удалось отправить файл по ftp |
ERR_NOTIFICATION_SEND_FAILED |
4515 |
Не удалось отправить уведомление |
ERR_NOTIFICATION_WRONG_PARAMETER |
4516 |
Неверный параметр для отправки уведомления – в функцию SendNotification() передали пустую строку или NULL |
ERR_NOTIFICATION_WRONG_SETTINGS |
4517 |
Неверные настройки уведомлений в терминале (не указан ID или не выставлено разрешение) |
ERR_NOTIFICATION_TOO_FREQUENT |
4518 |
Слишком частая отправка уведомлений |
ERR_FTP_NOSERVER |
4519 |
Не указан FTP сервер |
ERR_FTP_NOLOGIN |
4520 |
Не указан FTP логин |
ERR_FTP_FILE_ERROR |
4521 |
Не найден файл в директории MQL5Files для отправки на FTP сервер |
ERR_FTP_CONNECT_FAILED |
4522 |
Ошибка при подключении к FTP серверу |
ERR_FTP_CHANGEDIR |
4523 |
На FTP сервере не найдена директория для выгрузки файла |
ERR_FTP_CLOSED |
4524 |
Подключение к FTP серверу закрыто |
Буферы пользовательских индикаторов |
||
ERR_BUFFERS_NO_MEMORY |
4601 |
Недостаточно памяти для распределения индикаторных буферов |
ERR_BUFFERS_WRONG_INDEX |
4602 |
Ошибочный индекс своего индикаторного буфера |
Свойства пользовательских индикаторов |
||
ERR_CUSTOM_WRONG_PROPERTY |
4603 |
Ошибочный идентификатор свойства пользовательского индикатора |
Account |
||
ERR_ACCOUNT_WRONG_PROPERTY |
4701 |
Ошибочный идентификатор свойства счета |
ERR_TRADE_WRONG_PROPERTY |
4751 |
Ошибочный идентификатор свойства торговли |
ERR_TRADE_DISABLED |
4752 |
Торговля для эксперта запрещена |
ERR_TRADE_POSITION_NOT_FOUND |
4753 |
Позиция не найдена |
ERR_TRADE_ORDER_NOT_FOUND |
4754 |
Ордер не найден |
ERR_TRADE_DEAL_NOT_FOUND |
4755 |
Сделка не найдена |
ERR_TRADE_SEND_FAILED |
4756 |
Не удалось отправить торговый запрос |
ERR_TRADE_CALC_FAILED |
4758 |
Не удалось вычислить значение прибыли или маржи |
Индикаторы |
||
ERR_INDICATOR_UNKNOWN_SYMBOL |
4801 |
Неизвестный символ |
ERR_INDICATOR_CANNOT_CREATE |
4802 |
Индикатор не может быть создан |
ERR_INDICATOR_NO_MEMORY |
4803 |
Недостаточно памяти для добавления индикатора |
ERR_INDICATOR_CANNOT_APPLY |
4804 |
Индикатор не может быть применен к другому индикатору |
ERR_INDICATOR_CANNOT_ADD |
4805 |
Ошибка при добавлении индикатора |
ERR_INDICATOR_DATA_NOT_FOUND |
4806 |
Запрошенные данные не найдены |
ERR_INDICATOR_WRONG_HANDLE |
4807 |
Ошибочный хэндл индикатора |
ERR_INDICATOR_WRONG_PARAMETERS |
4808 |
Неправильное количество параметров при создании индикатора |
ERR_INDICATOR_PARAMETERS_MISSING |
4809 |
Отсутствуют параметры при создании индикатора |
ERR_INDICATOR_CUSTOM_NAME |
4810 |
Первым параметром в массиве должно быть имя пользовательского индикатора |
ERR_INDICATOR_PARAMETER_TYPE |
4811 |
Неправильный тип параметра в массиве при создании индикатора |
ERR_INDICATOR_WRONG_INDEX |
4812 |
Ошибочный индекс запрашиваемого индикаторного буфера |
Стакан цен |
||
ERR_BOOKS_CANNOT_ADD |
4901 |
Стакан цен не может быть добавлен |
ERR_BOOKS_CANNOT_DELETE |
4902 |
Стакан цен не может быть удален |
ERR_BOOKS_CANNOT_GET |
4903 |
Данные стакана цен не могут быть получены |
ERR_BOOKS_CANNOT_SUBSCRIBE |
4904 |
Ошибка при подписке на получение новых данных стакана цен |
Файловые операции |
||
ERR_TOO_MANY_FILES |
5001 |
Не может быть открыто одновременно более 64 файлов |
ERR_WRONG_FILENAME |
5002 |
Недопустимое имя файла |
ERR_TOO_LONG_FILENAME |
5003 |
Слишком длинное имя файла |
ERR_CANNOT_OPEN_FILE |
5004 |
Ошибка открытия файла |
ERR_FILE_CACHEBUFFER_ERROR |
5005 |
Недостаточно памяти для кеша чтения |
ERR_CANNOT_DELETE_FILE |
5006 |
Ошибка удаления файла |
ERR_INVALID_FILEHANDLE |
5007 |
Файл с таким хэндлом уже был закрыт, либо не открывался вообще |
ERR_WRONG_FILEHANDLE |
5008 |
Ошибочный хэндл файла |
ERR_FILE_NOTTOWRITE |
5009 |
Файл должен быть открыт для записи |
ERR_FILE_NOTTOREAD |
5010 |
Файл должен быть открыт для чтения |
ERR_FILE_NOTBIN |
5011 |
Файл должен быть открыт как бинарный |
ERR_FILE_NOTTXT |
5012 |
Файл должен быть открыт как текстовый |
ERR_FILE_NOTTXTORCSV |
5013 |
Файл должен быть открыт как текстовый или CSV |
ERR_FILE_NOTCSV |
5014 |
Файл должен быть открыт как CSV |
ERR_FILE_READERROR |
5015 |
Ошибка чтения файла |
ERR_FILE_BINSTRINGSIZE |
5016 |
Должен быть указан размер строки, так как файл открыт как бинарный |
ERR_INCOMPATIBLE_FILE |
5017 |
Для строковых массивов должен быть текстовый файл, для остальных – бинарный |
ERR_FILE_IS_DIRECTORY |
5018 |
Это не файл, а директория |
ERR_FILE_NOT_EXIST |
5019 |
Файл не существует |
ERR_FILE_CANNOT_REWRITE |
5020 |
Файл не может быть переписан |
ERR_WRONG_DIRECTORYNAME |
5021 |
Ошибочное имя директории |
ERR_DIRECTORY_NOT_EXIST |
5022 |
Директория не существует |
ERR_FILE_ISNOT_DIRECTORY |
5023 |
Это файл, а не директория |
ERR_CANNOT_DELETE_DIRECTORY |
5024 |
Директория не может быть удалена |
ERR_CANNOT_CLEAN_DIRECTORY |
5025 |
Не удалось очистить директорию (возможно, один или несколько файлов заблокированы и операция удаления не удалась) |
ERR_FILE_WRITEERROR |
5026 |
Не удалось записать ресурс в файл |
ERR_FILE_ENDOFFILE |
5027 |
Не удалось прочитать следующую порцию данных из CSV-файла (FileReadString, FileReadNumber, FileReadDatetime, FileReadBool), так как достигнут конец файла |
Преобразование строк |
||
ERR_NO_STRING_DATE |
5030 |
В строке нет даты |
ERR_WRONG_STRING_DATE |
5031 |
В строке ошибочная дата |
ERR_WRONG_STRING_TIME |
5032 |
В строке ошибочное время |
ERR_STRING_TIME_ERROR |
5033 |
Ошибка преобразования строки в дату |
ERR_STRING_OUT_OF_MEMORY |
5034 |
Недостаточно памяти для строки |
ERR_STRING_SMALL_LEN |
5035 |
Длина строки меньше, чем ожидалось |
ERR_STRING_TOO_BIGNUMBER |
5036 |
Слишком большое число, больше, чем ULONG_MAX |
ERR_WRONG_FORMATSTRING |
5037 |
Ошибочная форматная строка |
ERR_TOO_MANY_FORMATTERS |
5038 |
Форматных спецификаторов больше, чем параметров |
ERR_TOO_MANY_PARAMETERS |
5039 |
Параметров больше, чем форматных спецификаторов |
ERR_WRONG_STRING_PARAMETER |
5040 |
Испорченный параметр типа string |
ERR_STRINGPOS_OUTOFRANGE |
5041 |
Позиция за пределами строки |
ERR_STRING_ZEROADDED |
5042 |
К концу строки добавлен 0, бесполезная операция |
ERR_STRING_UNKNOWNTYPE |
5043 |
Неизвестный тип данных при конвертации в строку |
ERR_WRONG_STRING_OBJECT |
5044 |
Испорченный объект строки |
Работа с массивами |
||
ERR_INCOMPATIBLE_ARRAYS |
5050 |
Копирование несовместимых массивов. Строковый массив может быть скопирован только в строковый, а числовой массив – в числовой |
ERR_SMALL_ASSERIES_ARRAY |
5051 |
Приемный массив объявлен как AS_SERIES, и он недостаточного размера |
ERR_SMALL_ARRAY |
5052 |
Слишком маленький массив, стартовая позиция за пределами массива |
ERR_ZEROSIZE_ARRAY |
5053 |
Массив нулевой длины |
ERR_NUMBER_ARRAYS_ONLY |
5054 |
Должен быть числовой массив |
ERR_ONEDIM_ARRAYS_ONLY |
5055 |
Должен быть одномерный массив |
ERR_SERIES_ARRAY |
5056 |
Таймсерия не может быть использована |
ERR_DOUBLE_ARRAY_ONLY |
5057 |
Должен быть массив типа double |
ERR_FLOAT_ARRAY_ONLY |
5058 |
Должен быть массив типа float |
ERR_LONG_ARRAY_ONLY |
5059 |
Должен быть массив типа long |
ERR_INT_ARRAY_ONLY |
5060 |
Должен быть массив типа int |
ERR_SHORT_ARRAY_ONLY |
5061 |
Должен быть массив типа short |
ERR_CHAR_ARRAY_ONLY |
5062 |
Должен быть массив типа char |
ERR_STRING_ARRAY_ONLY |
5063 |
Должен быть массив типа string |
Работа с OpenCL |
||
ERR_OPENCL_NOT_SUPPORTED |
5100 |
Функции OpenCL на данном компьютере не поддерживаются |
ERR_OPENCL_INTERNAL |
5101 |
Внутренняя ошибка при выполнении OpenCL |
ERR_OPENCL_INVALID_HANDLE |
5102 |
Неправильный хэндл OpenCL |
ERR_OPENCL_CONTEXT_CREATE |
5103 |
Ошибка при создании контекста OpenCL |
ERR_OPENCL_QUEUE_CREATE |
5104 |
Ошибка создания очереди выполнения в OpenCL |
ERR_OPENCL_PROGRAM_CREATE |
5105 |
Ошибка при компиляции программы OpenCL |
ERR_OPENCL_TOO_LONG_KERNEL_NAME |
5106 |
Слишком длинное имя точки входа (кернел OpenCL) |
ERR_OPENCL_KERNEL_CREATE |
5107 |
Ошибка создания кернел — точки входа OpenCL |
ERR_OPENCL_SET_KERNEL_PARAMETER |
5108 |
Ошибка при установке параметров для кернел OpenCL (точки входа в программу OpenCL) |
ERR_OPENCL_EXECUTE |
5109 |
Ошибка выполнения программы OpenCL |
ERR_OPENCL_WRONG_BUFFER_SIZE |
5110 |
Неверный размер буфера OpenCL |
ERR_OPENCL_WRONG_BUFFER_OFFSET |
5111 |
Неверное смещение в буфере OpenCL |
ERR_OPENCL_BUFFER_CREATE |
5112 |
Ошибка создания буфера OpenCL |
ERR_OPENCL_TOO_MANY_OBJECTS |
5113 |
Превышено максимальное число OpenCL объектов |
ERR_OPENCL_SELECTDEVICE |
5114 |
Ошибка выбора OpenCL устройства |
Работа с WebRequest |
||
ERR_WEBREQUEST_INVALID_ADDRESS |
5200 |
URL не прошел проверку |
ERR_WEBREQUEST_CONNECT_FAILED |
5201 |
Не удалось подключиться к указанному URL |
ERR_WEBREQUEST_TIMEOUT |
5202 |
Превышен таймаут получения данных |
ERR_WEBREQUEST_REQUEST_FAILED |
5203 |
Ошибка в результате выполнения HTTP запроса |
Пользовательские символы |
||
ERR_NOT_CUSTOM_SYMBOL |
5300 |
Должен быть указан пользовательский символ |
ERR_CUSTOM_SYMBOL_WRONG_NAME |
5301 |
Некорректное имя пользовательского символа. В имени символа можно использовать только латинские буквы без знаков препинания, пробелов и спецсимволов (допускаются «.», «_», «&» и «#»). Не рекомендуется использовать символы <, >, :, «, /,, |, ?, *. |
ERR_CUSTOM_SYMBOL_NAME_LONG |
5302 |
Слишком длинное имя для пользовательского символа. Длина имени символа не должна превышать 32 знака с учётом завершающего 0 |
ERR_CUSTOM_SYMBOL_PATH_LONG |
5303 |
Слишком длинный путь для пользовательского символа. Длина пути не более 128 знаков с учётом «Custom\», имени символа, разделителей групп и завершающего 0 |
ERR_CUSTOM_SYMBOL_EXIST |
5304 |
Пользовательский символ с таким именем уже существует |
ERR_CUSTOM_SYMBOL_ERROR |
5305 |
Ошибка при создании, удалении или изменении пользовательского символа |
ERR_CUSTOM_SYMBOL_SELECTED |
5306 |
Попытка удалить пользовательский символ, выбранный в обзоре рынка (Market Watch) |
ERR_CUSTOM_SYMBOL_PROPERTY_WRONG |
5307 |
Неправильное свойство пользовательского символа |
ERR_CUSTOM_SYMBOL_PARAMETER_ERROR |
5308 |
Ошибочный параметр при установке свойства пользовательского символа |
ERR_CUSTOM_SYMBOL_PARAMETER_LONG |
5309 |
Слишком длинный строковый параметр при установке свойства пользовательского символа |
ERR_CUSTOM_TICKS_WRONG_ORDER |
5310 |
Не упорядоченный по времени массив тиков |
Пользовательские ошибки |
||
ERR_USER_ERROR_FIRST |
65536 |
С этого кода начинаются ошибки, задаваемые пользователем |
Не могу закрыть ордер
void Buy()
<
MqlTick Tick;
SymbolInfoTick ( Symbol (),Tick);
MqlTradeRequest request=< 0 >;
MqlTradeResult result=< 0 >;
request.action = TRADE_ACTION_DEAL ;
request.symbol = Symbol ();
request.volume = 1 ;
request.type = ORDER_TYPE_BUY ;
request.price = Tick.ask;
if (! OrderSend (request,result)) PrintFormat ( «OrderSend ошибка %d» , GetLastError ());
else Print ( __FUNCTION__ , «: » ,result.comment, » код ответа » ,result.retcode);
>
void Sell()
<
MqlTick Tick;
SymbolInfoTick ( Symbol (),Tick);
MqlTradeRequest request=< 0 >;
MqlTradeResult result=< 0 >;
request.action = TRADE_ACTION_DEAL ;
request.symbol = Symbol ();
request.volume = 1 ;
request.type = ORDER_TYPE_SELL ;
request.price = Tick.bid;
if (! OrderSend (request,result)) PrintFormat ( «OrderSend ошибка %d» , GetLastError ());
else Print ( __FUNCTION__ , «: » ,result.comment, » код ответа » ,result.retcode);
>
void ClBuy()
<
MqlTradeRequest request = < 0 >;
MqlTradeResult result = < 0 >;
int total= PositionsTotal ();
for ( int pos= 0 ; pos if ( PositionSelectByTicket ( PositionGetTicket (pos)))
<
if ( PositionGetInteger ( POSITION_TYPE )== POSITION_TYPE_BUY )
<
//OrderClose(OrderTicket(),OrderLots(),Bid,0,clrGold);
Print ( «Ticket » , PositionGetTicket (pos));
request.action = TRADE_ACTION_CLOSE_BY ;
request.position = PositionGetTicket (pos);
request.position_by = PositionGetInteger ( POSITION_TICKET );
request.price = SymbolInfoDouble ( Symbol (), SYMBOL_BID );
/*request.symbol = Symbol(); //PositionGetString(POSITION_SYMBOL);
request.volume = PositionGetDouble(POSITION_VOLUME);
request.type = ORDER_TYPE_BUY;*/
if (! OrderSend (request,result)) PrintFormat ( «OrderSend ошибка %d» , GetLastError ());
else Print ( __FUNCTION__ , «: » ,result.comment, » код ответа » ,result.retcode);
>
>
>
>
Закрыть позицию встречной
Установить торговый ордер на немедленное совершение сделки с указанными параметрами (поставить рыночный ордер)
Источник
my EA doesn’t want to trade anymore
When sending a TradeRequest, my EA now always returns the error 4752 ( Trading by Expert Advisors prohibited) and the retcode =10027 ( Autotrading disabled by client terminal).
Still, the «Options/ExpertAdvisor/Allow Auto Trading» is well checked and the 3 cases of «Disable Auto Trading» are unchecked.
A reboot doesn’t help. I don’t understand what going on.
Maybe you have an idea ?
Thank you in advance.
I have MT with MetaQuotes server. Now my EA can’t trade but script can. I think MQ wants to run ATC trouble free. That was just my opinion, I didn’t check with other broker server.
However I don’t understand your retcode 10027, did you click the auto trading button on MT toolbar ?
I have MT with MetaQuotes server. Now my EA can’t trade but script can. I think MQ wants to run ATC trouble free. That was just my opinion, I didn’t check with other broker server.
However I don’t understand your retcode 10027, did you click the auto trading button on MT toolbar ?
Thank you for your reply.
if temres is a MqlTradeResult type variable, temres.retcode is what is returned after an Ordersend command is placed.
However, it works again when I tried it this morning (probably Metaquotes did something on their side)
Источник
Коды возврата торгового сервера
Все приказы на совершение торговых операций отправляются в виде структуры торгового запроса MqlTradeRequest с помощью функции OrderSend(). Результат выполнения этой функции помещается в структуру MqlTradeResult, поле retcode которой содержит код возврата торгового сервера.
Запрос отменен трейдером
Заявка выполнена частично
Ошибка обработки запроса
Запрос отменен по истечению времени
Неправильный объем в запросе
Неправильная цена в запросе
Неправильные стопы в запросе
Нет достаточных денежных средств для выполнения запроса
Отсутствуют котировки для обработки запроса
Неверная дата истечения ордера в запросе
Состояние ордера изменилось
Слишком частые запросы
В запросе нет изменений
Автотрейдинг запрещен сервером
Автотрейдинг запрещен клиентским терминалом
Запрос заблокирован для обработки
Ордер или позиция заморожены
Указан неподдерживаемый тип исполнения ордера по остатку
Нет соединения с торговым сервером
Операция разрешена только для реальных счетов
Достигнут лимит на количество отложенных ордеров
Достигнут лимит на объем ордеров и позиций для данного символа
Неверный или запрещённый тип ордера
Позиция с указанным POSITION_IDENTIFIER уже закрыта
Закрываемый объем превышает текущий объем позиции
Для указанной позиции уже есть ордер на закрытие. Может возникнуть при работе в системе хеджинга:
- при попытке закрытия позиции встречной, если уже есть ордера на закрытие этой позиции
- при попытке полного или частичного закрытия, если суммарный объем уже имеющихся ордеров на закрытие и вновь выставляемого ордера превышает текущий объем позиции
Количество открытых позиций, которое можно одновременно иметь на счете, может быть ограничено настройками сервера. При достижении лимита в ответ на выставление ордера сервер вернет ошибку TRADE_RETCODE_LIMIT_POSITIONS. Ограничение работает по-разному в зависимости от типа учета позиций на счете:
- Неттинговая система — учитывается количество открытых позиции. При достижении лимита платформа не позволит выставлять новые ордера, в результате исполнения которых может увеличиться количество открытых позиций. Фактически, платформа позволит выставлять ордера только по тем символам, по которым уже есть открытые позиции. В неттинговой системе при проверке лимита не учитываются текущие отложенные ордера, поскольку их исполнение может привести к изменению текущих позиций, а не увеличению их количества.
- Хеджинговая система — помимо открытых позиций, учитываются выставленные отложенные ордера, поскольку их срабатывание всегда приводит к открытию новой позиции. При достижении лимита платформа не позволит выставлять рыночные ордера на открытие позиций, а также отложенные ордера.
Запрос на активацию отложенного ордера отклонен, а сам ордер отменен
Запрос отклонен, так как на символе установлено правило » Разрешены только длинные позиции» (POSITION_TYPE_BUY)
Запрос отклонен, так как на символе установлено правило » Разрешены только короткие позиции» ( POSITION_TYPE_SELL)
Запрос отклонен, так как на символе установлено правило » Разрешено только закрывать существующие позиции «
Запрос отклонен, так как для торгового счета установлено правило » Разрешено закрывать существующие позиции только по правилу FIFO » (ACCOUNT_FIFO_CLOSE=true)
Запрос отклонен, так как для торгового счета установлено правило » Запрещено открывать встречные позиции по одному символу «. Например, если на счете имеется позиция Buy, то пользователь не может открыть позицию Sell или выставить отложенный ордер на продажу. Правило может применяться только на счетах с хеджинговой системой учета (ACCOUNT_MARGIN_MODE=ACCOUNT_MARGIN_MODE_RETAIL_HEDGING).
Источник
Причина возникновения ошибки 4756
У меня такая ошибка возникает из-за кривого контроля величины выставляемых стопов.
У меня такая ошибка возникает из-за кривого контроля величины выставляемых стопов.
Как Вы определили, что это реквоты?
Эта ошибка возникает при неудаче OrderSend. А что конкретно там произошло, можно выяснить, проанализировав код возврата торгового сервера. Об этом явно сказано в описании функции OrderSend
Как Вы определили, что это реквоты?
Эта ошибка возникает при неудаче OrderSend. А что конкретно там произошло, можно выяснить, проанализировав код возврата торгового сервера. Об этом явно сказано в описании функции OrderSend
ну у меня в логах тестера пишет:
2010.07.30 12:05:26 Core 1 price corrected from 1.23434 to 1.23437, deviation: 10 (instant sell 4.00 EURUSD at 1.23434 sl: 1.23634 tp: 1.21934)(1.23437 / 1.23452 / 1.23437)
2010.07.30 12:05:25 Core 1 requote 1.23431 / 1.23446 / 1.23431 (instant sell 4.00 EURUSD at 1.23443 sl: 1.23643 tp: 1.21943)
ну у меня в логах тестера пишет:
2010.07.30 12:05:26 Core 1 price corrected from 1.23434 to 1.23437, deviation: 10 (instant sell 4.00 EURUSD at 1.23434 sl: 1.23634 tp: 1.21934)(1.23437 / 1.23452 / 1.23437)
2010.07.30 12:05:25 Core 1 requote 1.23431 / 1.23446 / 1.23431 (instant sell 4.00 EURUSD at 1.23443 sl: 1.23643 tp: 1.21943)
Реквота тут совершенно не причём и возникает уже при следующем вызове OrderSend().
Стопы также достаточные: 200 и 500 пипсов
Цена также влазит в deviation в данном случае
ERR_TRADE_SEND_FAILED 4756 Не удалось отправить торговый запрос
А вообще то у Вас сделки совершаются ?
Источник
Причина возникновения ошибки 4756 — страница 3
Возможно что есть еще ошибки до того, как отправилась команда на сервер
Приведите выкопировку из кода по модификации позиции
Ренат, привожу текст скрипта на модификацию:
Ренат, привожу текст скрипта на модификацию:
Вырезал по максимуму. Оставил только модификацию позиции BUY: просто пытаемся тупо выставить SL и TP заданные во входных параметрах.
закономерно получаем 10018.
ВНИМАНИЕ: данный код НЕЛЬЗЯ применять в реале! Здесь не анализруется текущий SL и TP у позиции, нет проверки на уровни заморозки и отступа .
Ренат, привожу текст скрипта на модификацию:
и эту функцию бы глянуть:
Вырезал по максимуму. Оставил только модификацию позиции BUY: просто пытаемся тупо выставить SL и TP заданные во входных параметрах.
закономерно получаем 10018.
ВНИМАНИЕ: данный код НЕЛЬЗЯ применять в реале! Здесь не анализруется текущий SL и TP у позиции, нет проверки на уровни заморозки и отступа .
Владимир, я попробовал Ваш скрипт. Действительно, получил ожидаемый результат 10018, то есть рынок закрыт. Я буду совершенствовать этот скрипт: добавлю модификацию для POSITION_TYPE_SELL, добавлю анализ SL и TP на предмет того, может они уже такие, как я хочу, и, следовательно, в модификации не нуждаются. Не знаю, есть ли смысл проверять уровни заморозки и отступа.
В любом случае, огромное Вам спасибо за хлопоты ! Можно было, конечно, найти в Code Base такой уже готовый скрипт. Но хотелось бы иметь свой скрипт, которым я лично умею управлять, исправлять .
Владимир, я попробовал Ваш скрипт. Действительно, получил ожидаемый результат 10018, то есть рынок закрыт. Я буду совершенствовать этот скрипт: добавлю модификацию для POSITION_TYPE_SELL, добавлю анализ SL и TP на предмет того, может они уже такие, как я хочу, и, следовательно, в модификации не нуждаются. Не знаю, есть ли смысл проверять уровни заморозки и отступа.
В любом случае, огромное Вам спасибо за хлопоты ! Можно было, конечно, найти в Code Base такой уже готовый скрипт. Но хотелось бы иметь свой скрипт, которым я лично умею управлять, исправлять .
Вот и ладненько. Счёт вытираю из своего терминала.
Источник
Разработка торговых экспертов на языке MQL4 является не такой уж простой задачей. Во-первых – алгоритмизация любой сложной торговой системы уже представляет собой проблему, так как нужно учесть очень много деталей, начиная с особенностей ТС и заканчивая спецификой среды MetaTrader 4. Во-вторых, даже наличие детальнейшего алгоритма не избавляет от сложностей, возникающих при переносе разработанного алгоритма на язык программирования MQL4.
Компилятор оказывает некоторую помощь при написании корректных экспертов. После начала компиляции MetaEditor сообщит обо всех синтаксических ошибках в вашем коде. Но, к сожалению, помимо синтаксических ошибок ваш советник может содержать еще и логические ошибки, которые компилятор выловить не может. Поэтому этим нам придется заняться самим. Как это сделать – в нашем сегодняшнем материале.
MQL4 — Ошибки и как их исправить
Самые распространенные ошибки компиляции
При наличии ошибок в коде программа не может быть скомпилирована. Для полного контроля всех ошибок рекомендуется использовать строгий режим компиляции, который устанавливается директивой:
Этот режим значительно упрощает поиск ошибок. Теперь перейдем к самым распространенным ошибкам при компиляции.
Идентификатор совпадает с зарезервированным словом
Если наименование переменной или функции совпадает с одним из зарезервированных слов:
int char[]; // неправильно int char1[]; // правильно int char() // неправильно { return(0); }
то компилятор выводит сообщения об ошибках:
Для исправления данной ошибки нужно исправить имя переменной или функции. Я рекомендую придерживаться следующей системы для именования:
Все функции должны обозначать действие. То есть это должен быть глагол. Например, OpenLongPosition() или ModifyStopLoss(). Ведь функции всегда именно что-то делают, верно?
Кроме того, функции желательно называть в так называемом CamelCase стиле. А переменные в cebab_case стиле. Это общепринятая практика.
Кстати, об именах переменных. Переменные – это существительные. Например, my_stop_loss, day_of_week, current_month. Не так страшно назвать переменную длинным именем, гораздо страшнее назвать ее непонятно. Что такое dow, индекс Dow Jones? Нет, это, оказывается, день недели. Конечно, сегодня вам и так понятно, что это за переменная. Но когда вы откроете код советника месяц спустя, все будет уже не так явно. А это время, упущенное на расшифровку посланий из прошлого – оно вам надо?
Специальные символы в наименованиях переменных и функций
Идем дальше. Если наименования переменных или функций содержат специальные символы ($, @, точка):
int $var1; // неправильно int @var2; // неправильно int var.3; // неправильно void f@() // неправильно { return; }
то компилятор выводит сообщения об ошибках:
Для исправления данной ошибки снова нужно скорректировать имена переменных или функций, ну или сразу называть их по-человечески. В идеале код нужно писать так, чтобы даже человек, не знающий программирование, просто его прочел и понял, что там вообще происходит.
Ошибки использования оператора switch
Старая версия компилятора позволяла использовать любые значения в выражениях и константах оператора switch:
void start() { double n=3.14; switch(n) { case 3.14: Print("Pi"); break; case 2.7: Print("E"); break; } }
В новом компиляторе выражения и константы оператора switch должны быть целыми числами, поэтому при использовании подобных конструкций возникают ошибки:
Поэтому, когда вы разбираете код классики, такой, как WallStreet, Ilan и прочей нетленки (что очень полезно для саморазвития), можно натолкнуться на эту ошибку. Лечится она очень просто, например, при использовании такой вот строки:
switch(MathMod(day_48, 10))
Вот так можно запросто решить проблему:
switch((int)MathMod(day_48, 10))
Возвращаемые значений функций
Все функции, кроме void, должны возвращать значение объявленного типа. Например:
При строгом режиме компиляции (strict) возникает ошибка:
В режиме компиляции по умолчанию компилятор выводит предупреждение:
Если возвращаемое значение функции не соответствует объявлению:
Тогда при строгом режиме компиляции возникает ошибка:
В режиме компиляции по умолчанию компилятор выводит предупреждение:
Для исправления таких ошибок в код функции всего-навсего нужно добавить оператор возврата return c возвращаемым значением соответствующего типа.
Массивы в аргументах функций
Массивы в аргументах функций передаются только по ссылке. Раньше это было не так, поэтому в старых советниках можно встретить эту ошибку. Вот пример:
double ArrayAverage(double a[]) { return(0); }
Данный код при строгом режиме компиляции (strict) приведет к ошибке:
В режиме компиляции по умолчанию компилятор выводит предупреждение:
Для исправления таких ошибок нужно явно указать передачу массива по ссылке, добавив префикс & перед именем массива:
double ArrayAverage(double &a[]) { return(0); }
Кстати, константные массивы (Time[], Open[], High[], Low[], Close[], Volume[]) не могут быть переданы по ссылке. Например, вызов:
вне зависимости от режима компиляции приводит к ошибке:
Для устранения подобных ошибок нужно скопировать необходимые данные из константного массива:
//--- массив для хранения значений цен открытия double OpenPrices[]; //--- копируем значения цен открытия в массив OpenPrices[] ArrayCopy(OpenPrices,Open,0,0,WHOLE_ARRAY); //--- вызываем функцию ArrayAverage(OpenPrices);
Одна из самых распространенных ошибок – потеря советником индикатора. В таких случаях обычно пользователи эксперта на форумах гневно пишут: «Советник не работает!» или «Ставлю советник на график и ничего не происходит!». Решение этого вопроса на самом деле очень простое. Как всегда, достаточно просто заглянуть на вкладку «Журнал» терминала и обнаружить там запись вроде:
2018.07.08 09:15:44.957 2016.01.04 00:51 cannot open file 'C:Users1AppDataRoamingMetaQuotesTerminal MQL4indicatorsKELTNER_F12.ex4' [2]
Говорит это нам о том, что индикатор в папку положить забыли, или же он назван по-другому. Если индикатор отсутствует, нужно добавить его в папку с индикаторами. Если он есть, стоит проверить его название в коде советника – скорее всего там он называется по-другому.
Предупреждения компилятора
Предупреждения компилятора носят информационный характер и не являются сообщениями об ошибках, однако они указывают на возможные источники ошибок и лучше их скорректировать. Чистый код не должен содержать предупреждений.
Пересечения имен глобальных и локальных переменных
Если на глобальном и локальном уровнях присутствуют переменные с одинаковыми именами:
int i; // глобальная переменная void OnStart() { int i=0,j=0; // локальные переменные for (i=0; i<5; i++) { j+=i; } PrintFormat("i=%d, j=%d",i,j); }
то компилятор выводит предупреждение и укажет номер строки, на которой объявлена глобальная переменная:
Для исправления таких предупреждений нужно скорректировать имена глобальных переменных.
Несоответствие типов
В следующем примере:
#property strict void OnStart() { double a=7; float b=a; int c=b; string str=c; Print(c); }
при строгом режиме компиляции при несоответствии типов компилятор выводит предупреждения:
В данном примере компилятор предупреждает о возможной потере точности при присвоении различных типов данных и неявном преобразовании типа int в string.
Для исправления нужно использовать явное приведение типов:
#property strict void OnStart() { double a=7; float b=(float)a; int c=(int)b; string str=(string)c; Print(c); }
Неиспользуемые переменные
Наличие переменных, которые не используются в коде программы (лишние сущности) не является хорошим тоном.
void OnStart() { int i,j=10,k,l,m,n2=1; for(i=0; i<5; i++) {j+=i;} }
Сообщения о таких переменных выводятся вне зависимости от режима компиляции:
Для исправления нужно просто убрать неиспользуемые переменные из кода программы.
Диагностика ошибок при компиляции
Часто после написания программы возникают проблемы при компиляции, вызванные ошибками в коде. Это могут быть самые различные ошибки, но в любом случае возникает необходимость оперативного обнаружения участка кода, где допущена ошибка.
Нередко у людей уходит немало времени и масса нервов на поиски какой-нибудь лишней скобки. Однако, есть способ быстрого обнаружения ошибок, который основан на использовании комментирования.
Написать достаточно большой код без единой ошибки – очень приятно. Но, к сожалению, так получается не часто. Я не рассматриваю здесь ошибки, которые приводят к неверному исполнению кода. Здесь пойдёт речь об ошибках, из-за которых становится невозможной компиляция.
Весьма распространённые ошибки – вставка лишней скобки в сложном условии, нехватка скобки, не выставление двоеточия, запятой при объявлении переменных, опечатка в названии переменной и так далее. Часто при компиляции можно сразу увидеть, в какой строке допущена подобная ошибка. Но бывают и случаи, когда найти такую ошибку не так просто. Ни компилятор, ни зоркий глаз нам не могут помочь сразу найти ошибку. В таких случаях, как правило, начинающие программисты начинают “обходить” весь код, пытаясь визуально определить ошибку. И снова, и снова, пока выдерживают нервы.
Однако MQL, как и другие языки программирования, предлагает отличный инструмент – комментирование. Используя его, можно отключать какие-то участки кода. Обычно комментирование используют именно для вставки каких-то комментариев, или же отключения неиспользуемых участков кода. Комментирование можно также успешно применять и при поиске ошибок.
Поиск ошибок обычно сводится к определению участка кода, где допущена ошибка, а затем, в этом участке, визуально находится ошибка. Думаю, вряд ли кто-то будет сомневаться в том, что исследовать “на глаз” 5-10 строчек кода проще и быстрей, чем 100-500, а то и несколько тысяч.
При использовании комментирования задача предельно проста. Сначала нужно закомментировать различные участки кода (иногда чуть ли не весь код), тем самым “отключив” его. Затем, по очереди, комментирование снимается с этих участков кода. После очередного снятия комментирования совершается попытка компиляции. Если компиляция прошла успешно – ошибка не в этом участке кода. Затем открывается следующий участок кода и так далее. Когда находится проблемный участок кода, визуально ищется ошибка, затем устраняется. Опять происходит попытка компиляции. Если всё прошло успешно, ошибка устранена.
Важно правильно определять участки кода, которые необходимо комментировать. Если это условие (или иная логическая конструкция), то оно должно комментироваться полностью. Если комментируется участок кода, где объявляются переменные, важно, чтобы не был открыт участок, где происходит обращение к этим переменным. Иначе говоря – комментирование должно применяться по логике программирования. Несоблюдения такого подхода приводит к возникновению новых, вводящих в заблуждение, ошибок при компиляции.
Вот отличный пример ошибки, когда неясно, где ее искать и нас может выручить комментирование кода.
Ошибки времени выполнения
Ошибки, возникающие в процессе исполнения кода программы, принято называть ошибками времени выполнения (runtime errors). Такие ошибки обычно зависят от состояния программы и связаны с некорректными значениями переменных.
Например, если переменная используется в качестве индекса элементов массива, то ее отрицательные значения неизбежно приведут к выходу за пределы массива.
Выход за пределы массива (Array out of range)
Эта ошибка часто возникает в индикаторах при обращении к индикаторным буферам. Функция IndicatorCounted() возвращает количество баров, не изменившихся после последнего вызова индикатора. Значения индикаторов на уже рассчитанных ранее барах не нуждаются в пересчете, поэтому для ускорения расчетов достаточно обрабатывать только несколько последних баров.
Большинство индикаторов, в которых используется данный способ оптимизации вычислений, имеют такой вид:
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { //--- иногда для расчета требуется не менее N баров (например, 100) // если на графике нет такого количества баров (например, на таймфрейме MN) if (Bars<100) { return(-1); // прекращаем расчет и выходим досрочно } //--- количество баров, не изменившихся с момента последнего вызова индикатора int counted_bars=IndicatorCounted(); //--- в случае ошибки выходим if (counted_bars<0) { return(-1); } //--- позиция бара, с которого начинается расчет в цикле int limit=Bars-counted_bars; //--- если counted_bars=0, то начальную позицию в цикле нужно уменьшить на 1, if (counted_bars==0) { limit--; // чтобы не выйти за пределы массива при counted_bars==0 //--- в расчетах используется смещение на 10 баров вглубь //--- истории, поэтому добавим это смещение при первом расчете limit-=10; } else { //--- индикатор уже рассчитывался ранее, counted_bars>0 //--- при повторных вызовах увеличим limit на 1, чтобы //--- гарантированно обновлять значения индикатора для последнего бара limit++; } //--- основной цикл расчета for (int i=limit; i>0; i--) { // используются значения баров, уходящих вглубь истории на 5 и 10 Buff1[i]=0.5*(Open[i+5]+Close[i+10]) } }
Часто встречается некорректная обработка случая counted_bars==0 (начальную позицию limit нужно уменьшить на значение, равное 1 + максимальный индекс относительно переменной цикла).
Также следует помнить о том, что в момент исполнения функции start() мы можем обращаться к элементам массивов индикаторных буферов от 0 до Bars()-1. Если есть необходимость работы с массивами, которые не являются индикаторными буферами, то их размер следует увеличить при помощи функции ArrayResize() в соответствии с текущим размером индикаторных буферов. Максимальный индекс элемента для адресации также можно получить вызовом ArraySize() с одним из индикаторных буферов в качестве аргумента.
Деление на ноль (Zero divide)
Ошибка “Zero divide” возникает в случае, если при выполнении операции деления делитель оказывается равен нулю:
void OnStart() { int a=0, b=0,c; c=a/b; Print("c=",c); }
При выполнении данного скрипта во вкладке “Эксперты” возникает сообщение об ошибке и завершении работы программы:
Обычно такая ошибка возникает в случаях, когда значение делителя определяется значениями каких-либо внешних данных. Например, если анализируются параметры торговли, то величина задействованной маржи оказывается равна 0, если нет открытых ордеров. Другой пример: если анализируемые данные считываются из файла, то в случае его отсутствия нельзя гарантировать корректную работу. По этой причине желательно стараться учитывать подобные случаи и корректно их обрабатывать.
Самый простой способ – проверять делитель перед операцией деления и выводить сообщение о некорректном значении параметра:
void OnStart() { int a=0, b=0,c; if (b!=0) { c=a/b; Print(c); } else { Print("Error: b=0"); return; } }
В результате критической ошибки не возникает, но выводится сообщение о некорректном значении параметра и работа завершается:
Использование 0 вместо NULL для текущего символа
В старой версии компилятора допускалось использование 0 (нуля) в качестве аргумента в функциях, требующих указания финансового инструмента.
Например, значение технического индикатора Moving Average для текущего символа можно было запрашивать следующим образом:
AlligatorJawsBuffer[i]=iMA(0,0,13,8,MODE_SMMA,PRICE_MEDIAN,i); // неправильно
В новом компиляторе для указания текущего символа нужно явно указывать NULL:
AlligatorJawsBuffer[i]=iMA(NULL,0,13,8,MODE_SMMA,PRICE_MEDIAN,i); // правильно
Кроме того, текущий символ и период графика можно указать при помощи функций Symbol() и Period().
AlligatorJawsBuffer[i]=iMA(Symbol(),Period(),13,8,MODE_SMMA,PRICE_MEDIAN,i); // правильно
Еще лучше, если вы будете использовать предопределенные переменные _Symbol и _Period – они обрабатываются быстрее:
AlligatorJawsBuffer[i]=iMA(_Symbol,_Period,13,8,MODE_SMMA,PRICE_MEDIAN,i); // правильно
Строки в формате Unicodе и их использование в DLL
Строки представляют собой последовательность символов Unicode. Следует учитывать этот факт и использовать соответствующие функции Windows. Например, при использовании функций библиотеки wininet.dll вместо InternetOpenA() и InternetOpenUrlA() следует вызывать InternetOpenW() и InternetOpenUrlW(). При передаче строк в DLL следует использовать структуру MqlString:
#pragma pack(push,1) struct MqlString { int size; // 32-битное целое, содержит размер распределенного для строки буфера LPWSTR buffer; // 32-разрядный адрес буфера, содержащего строку int reserved; // 32-битное целое, зарезервировано, не использовать }; #pragma pack(pop,1)
Совместное использование файлов
При открытии файлов необходимо явно указывать флаги FILE_SHARE_WRITE и FILE_SHARE_READ для совместного использования.
В случае их отсутствия, файл будет открыт в монопольном режиме, что не позволит больше никому его открывать, пока он не будет закрыт монополистом.
Например, при работе с оффлайновыми графиками требуется явно указывать флаги совместного доступа:
// 1-st change - add share flags ExtHandle=FileOpenHistory(c_symbol+i_period+".hst", FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ);
Особенность преобразования datetime
Следует иметь ввиду, что преобразование типа datetime в строку зависит от режима компиляции:
datetime date=D'2014.03.05 15:46:58'; string str="mydate="+date; //--- str="mydate=1394034418" - без директивы #property strict //--- str="mydate=2014.03.05 15:46:58" - с директивой #property strict
Например, попытка работы с файлами, имя которых содержит двоеточие, приведет к ошибке.
Обработка ошибок времени выполнения
Так как без использования встроенных пользовательских функций не сможет обойтись ни один торгующий эксперт, то в первую очередь попытаемся упростить себе жизнь при анализе ошибок, возвращаемых этими функциями.
В наборе “из коробки” доступны некоторые библиотеки для упрощения написания советников, в том числе и для работы с ошибками. Хранятся они в папке MQL4/Include:
Нам понадобятся две библиотеки:
- stderror.mqh – содержит константы для номера каждой ошибки;
- stdlib.mqh – содержит несколько вспомогательных функций, в том числе и функцию возврата описания ошибки в виде строки:
string ErrorDescription(int error_code)
Поэтому подключим в наш проект обе эти библиотеки:
#include <stderror.mqh> #include <stdlib.mqh>
Сами описания ошибок находятся в файле MQL4/Library/stdlib.mql4 и они на английском языке. Поэтому, если вы против иностранных языков, всегда можно переписать описания на свой родной.
Еще одна встроенная необходимая нам функция – GetLastError(). Именно она возвращает коды ошибок в виде целого числа (int), который мы потом будем обрабатывать. Сами коды ошибок и их описания на русском можно посмотреть в руководстве по mql4 от MetaQuotes. Оттуда же можно взять информацию для перевода файла stdlib.mql4 на русский.
Теперь, когда мы подключили необходимые библиотеки, рассмотрим результаты работы функций, непосредственно связанных с торговыми операциями, так как игнорирование сбоев в этих функциях может привести к критическим для бота последствиям.
К сожалению, средствами MQL4 нельзя написать обобщенную библиотеку для обработки всех возможных ошибочных ситуаций. В каждом отдельном случае придется обрабатывать ошибки отдельно. Но не все так плохо, – многие ошибки не нужно обрабатывать, их достаточно исключить на этапе разработки и тестирования эксперта, хотя для этого и нужно вовремя узнать об их наличии.
Рассмотрим для примера две типичные для экспертов на MQL4 ошибки:
- Ошибка 130 – ERR_INVALID_STOPS
- Ошибка 146 – ERR_TRADE_CONTEXT_BUSY
Одним из случаев, когда возникает первая ошибка, является попытка эксперта выставить отложенный ордер слишком близко к рынку. Ее наличие может серьезно ухудшить показатели эксперта в некоторых случаях. Например, допустим эксперт, открыв прибыльную позицию, поджимает прибыль каждые 150 пунктов. Если при очередной такой попытке возникнет ошибка 130, а цена безвозвратно вернется к предыдущему уровню стопа, эксперт может лишить вас законной прибыли. Несмотря на возможность таких последствий, данную ошибку можно исключить в корне, доработав код эксперта так, чтобы он учитывал минимальное допустимое расстояние между ценой и стопами.
Вторую ошибку, связанную с занятостью торгового контекста терминала, полностью исключить не получится. При работе нескольких экспертов в одном терминале всегда возможна ситуация, когда один из экспертов попытается открыть позицию, пока другой все еще делает то же самое. Следовательно, такую ошибку всегда нужно обрабатывать.
Таким образом, мы всегда должны быть в курсе, если какая-то из используемых встроенных функций возвращает ошибку во время работы эксперта. Добиться этого можно, используя следующую нехитрую вспомогательную функцию:
void logError(string functionName, string msg, int errorCode = -1) { Print("ERROR: in " + functionName + "()"); Print("ERROR: " + msg ); int err = GetLastError(); if (errorCode != -1) { err = errorCode; } if (err != ERR_NO_ERROR) { Print("ERROR: code=" + err + " - " + ErrorDescription( err )); } }
Использовать ее мы будем следующим образом:
void openLongTrade() { int ticket = OrderSend(Symbol(), OP_BUY, 1.0, Ask + 5, 5, 0, 0); if (ticket == -1) { logError("openLongTrade", "could not open order"); } }
Конечно, это упрощенный пример. Для написания более грамотных функций открытия, закрытия и модификации ордеров смотрите этот урок.
Первым параметром в функцию logError() передается имя функции, в которой была обнаружена ошибка, в нашем примере – в функции openLongTrade(). Если наш эксперт вызывает функцию OrderSend() в нескольких местах, это позволит нам точно установить, в каком из них произошла ошибка. Вторым параметром передается описание ошибки, чтобы можно было понять, где именно внутри функции openLongTrade() была обнаружена ошибка. Это может быть как краткое описание ошибки, так и более развернутое, с перечислением значений всех параметров, переданных во встроенную функцию.
Я предпочитаю последний вариант, так как при возникновении ошибки можно сразу получить всю необходимую для анализа информацию. Для примера допустим, что до вызова OrderSend() текущая цена успела сильно отклониться от последней известной нам цены. В результате при выполнении этого примера произойдет ошибка и в протоколе работы эксперта появятся следующие строки:
ERROR: in openLongTrade() ERROR: could not open order ERROR: code=138 - requote
То есть сразу будет видно:
- в какой функции произошла ошибка;
- к чему она относится (в данном случае – к попытке открыть позицию);
- какая именно ошибка возникла (код ошибки и ее описание).
Теперь рассмотрим третий, необязательный, параметр функции logError(). Он необходим в тех случаях, когда мы хотим обработать конкретный вид ошибки, а об остальных будем отчитываться в протоколе работы эксперта, как и прежде:
void updateStopLoss(double newStopLoss) { bool modified = OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), OrderExpiration()); if (!modified) { int errorCode = GetLastError(); if (errorCode != ERR_NO_RESULT ) { logError("updateStopLoss", "failed to modify order", errorCode); } } }
Здесь в функции updateStopLoss() вызывается встроенная функция OrderModify(). Эта функция несколько отличается в плане обработки ошибок от OrderSend(). Если ни один из параметров изменяемого ордера не отличается от его текущих параметров, то функция вернет ошибку ERR_NO_RESULT. Если в нашем эксперте такая ситуация допустима, то мы должны игнорировать конкретно эту ошибку. Для этого мы анализируем значение, возвращаемое GetLastError(). Если произошла ошибка с кодом ERR_NO_RESULT, то мы ничего не выводим в протокол.
Однако если произошла другая ошибка, то необходимо полностью отрапортовать о ней, как мы делали это раньше. Именно для этого мы сохраняем результат функции GetLastError() в промежуточной переменной и передаем его третьим параметром в функцию logError(). Дело в том, что встроенная функция GetLastError() автоматически обнуляет код последней ошибки после своего вызова. Если бы мы не передали код ошибки явно в logError(), то в протоколе была бы отражена ошибка с кодом 0 и описанием “no error”.
Похожие действия необходимо совершать и при обработке других ошибок, например, реквотов. Основная идея заключается в том, чтобы обрабатывать только ошибки, требующие обработки, а остальные передавать в функцию logError(). Тогда мы всегда будем в курсе, если во время работы эксперта произошла непредвиденная ошибка. Проанализировав логи, мы сможем решить, требует ли данная ошибка отдельной обработки или же ее можно исключить, доработав код эксперта. Такой подход часто заметно упрощает жизнь и сокращает время, уходящее на борьбу с ошибками.
Диагностика логических ошибок
Логические ошибки в коде эксперта могут доставить много проблем. Отсутствие возможности пошаговой отладки экспертов делают борьбу с такими ошибками не очень приятным занятием. Основным средством для диагностики этого на данный момент является встроенная функция Print(). С ее помощью можно выполнять распечатку текущих значений важных переменных, а также протоколировать ход работы эксперта прямо в терминале во время тестирования. При отладке эксперта во время тестирования с визуализацией также может помочь встроенная функция Comment(), которая выводит сообщения на график. Как правило, убедившись, что эксперт работает не так, как было задумано, приходится добавлять временные вызовы функции Print() и протоколировать внутреннее состояние эксперта в предполагаемых местах возникновения ошибки.
Однако, для обнаружения сложных ошибочных ситуаций порой приходится добавлять десятки таких вызовов функции Print(), а после обнаружения и устранения проблемы их приходится удалять или комментировать, чтобы не загромождался код эксперта и не замедлялось его тестирование. Ситуация ухудшается, если в коде эксперта функция Print() уже используется для периодического протоколирования различных состояний. Тогда удаление временных вызовов Print() не удается выполнить путем простого поиска фразы ‘Print’ в коде эксперта. Приходится задумываться, чтобы не удалить еще и полезные вызовы этой функции.
Например, при протоколировании ошибок функций OrderSend(), OrderModify() и OrderClose() полезным бывает печатать в протокол текущее значение переменных Bid и Ask. Это несколько облегчает распознавание причин таких ошибок, как ERR_INVALID_STOPS и ERR_OFF_QUOTES.
Чтобы выделить такие диагностические выводы в протокол, я рекомендую использовать такую вспомогательную функцию:
void logInfo(string msg) { Print("INFO: " + msg); }
Это желательно сделать по нескольким причинам. Во-первых, теперь такие вызовы не будут попадаться при поиске ‘Print’ в коде эксперта, ведь искать мы будем logInfo. Во-вторых, у этой функции есть еще одна полезная особенность, о которой мы поговорим чуть позже.
Добавление и удаление временных диагностических вызовов функции Print() отнимает у нас драгоценное время. Поэтому я предлагаю рассмотреть еще один подход, который эффективен при обнаружении логических ошибок в коде и позволяет немного сэкономить наше время. Рассмотрим следующую несложную функцию:
void openLongTrade(double stopLoss) { int ticket = OrderSend(Symbol(), OP_BUY, 1.0, Ask, 5, stopLoss, 0); if (ticket == -1) { logError("openLongTrade", "could not open order"); } }
В данном случае, так как мы открываем длинную позицию, совершенно очевидно, что при нормальной работе эксперта значение параметра stopLoss никогда не будет больше или равно текущей цене Bid. То есть, при вызове функции openLongTrade() всегда выполняется условие stopLoss < Bid. Так как мы знаем об этом еще на этапе написания рассматриваемой функции, то мы сразу же можем этим воспользоваться следующим образом:
void openLongTrade( double stopLoss ) { assert("openLongTrade", stopLoss < Bid, "stopLoss < Bid"); int ticket = OrderSend(Symbol(), OP_BUY, 1.0, Ask, 5, stopLoss, 0); if (ticket == -1) { logError("openLongTrade", "could not open order"); } }
То есть мы логируем наше утверждение в коде при помощи новой вспомогательной функции assert(). Сама функция выглядит довольно просто:
void assert(string functionName, bool assertion, string description = "") { if (!assertion) { Print("ASSERT: in " + functionName + "() - " + description); } }
Первым параметром функции является ее имя, в котором проверяется наше условие (по аналогии с функцией logError()). Вторым параметром передается результат проверки этого условия. И третьим параметром передается его описание. В результате, если ожидаемое условие не выполняется, в протокол будет выведена следующая информация:
- название функции, в которой условие было нарушено;
- описание нарушенного условия.
В качестве описания можно передавать, например, само условие, а можно выводить и более подробное описание, содержащее значения контролируемых переменных на момент проверки условия, если это поможет разобраться в причинах ошибки.
Конечно же, рассмотренный пример максимально упрощен. Но, надеюсь, основную идею отражает достаточно хорошо. В процессе наращивания функциональности эксперта мы отдаем себе отчет в том, как он должен работать и какие состояния и входные параметры функций допустимы, а какие нет. Фиксируя это в коде эксперта при помощи функции assert() мы получаем ценную информацию о месте, в котором нарушается логика работы эксперта. Более того, мы частично избавляем себя от необходимости добавлять и удалять временные вызовы функции Print(), так как функция assert() выдает диагностические сообщения в протокол только в момент обнаружения несоответствий в ожидаемых нами условиях.
Еще одним полезным приемом является использование этой функции перед каждой операцией деления. Дело в том, что иногда в результате той или иной логической ошибки иногда происходит деление на ноль. Работа эксперта в этом случае прекращается, а в протоколе появляется одна лишь строка с печальным диагнозом: ‘zero divide’. Узнать, в каком именно месте произошла эта ошибка, если операция деления используется в коде неоднократно, достаточно сложно. Вот здесь и поможет функция assert(). Вставляем соответствующие проверки перед каждой операцией деления:
assert("buildChannel", distance > 0, "distance > 0"); double slope = delta / distance;
И теперь, в случае деления на ноль, достаточно будет лишь взглянуть в логи, чтобы узнать, в каком именно месте произошла ошибка.
Обработка состояний
Во время работы эксперта на вашем счете могут возникнуть некоторые ситуации, которые не являются ошибками – так называемые состояния эксперта. Такие состояния не являются ошибками, но все же их стоит логировать. В этом помогают специальные функции языка mql4.
Функция IsExpertEnabled() возвращает информацию о возможности запуска экспертов. Функция вернет true, если в клиентском терминале разрешен запуск экспертов, иначе возвращает false. В случае возврата false полезно будет известить об этом пользователя с просьбой включить соответствующую настройку. Пример:
void OnStart() { if (!IsExpertEnabled() { //советникам не разрешено торговать Alert("Attention! Please press the "Expert Advisors" button in MT4"); } //рабочий алгоритм советника return; }
Если эксперт использует внешние библиотеки, пригодится функция IsLibrariesAllowed(). Она возвращает true, если эксперт может вызвать библиотечную функцию, иначе возвращает false.
Если библиотека в виде dll файла, пригодится функция IsDllsAllowed(). Также нелишним будет проверить, есть ли вообще возможность торговать при помощи экспертов с помощью функции IsTradeAllowed().
Если вы хотите узнать, является ли счет демонстрационным, или же реальным, можно использовать функцию IsDemo().
Все вышеперечисленные проверки стоит сделать в функции OnInit().
Конечно же, стоит проверять периодически связь с сервером. В этом поможет функция IsConnected().
Следующие три функции помогут определить, в каком режиме находится советник. Если IsOptimisation() возвращает true, проводится оптимизация, если IsTesting(), то тестирование, IsVisualMode() – тестирование в режиме визуализации. Под каждый из этих вариантов в советнике может быть предусмотрена своя логика. Например, для режима визуализации можно что-то выводить на график (и не выводить в других режимах ради экономии ресурсов). В режиме тестирования можно выводить отладочную информацию, в режиме оптимизации максимально облегчить код, чтобы сэкономить время.
И последняя функция – IsTradeContextBusy(). Она вернет true, если поток для выполнения торговых операций занят. Это бывает полезно при совершении экспертом торговых операций. Можно применить функцию Sleep для ожидания некоторого момента и новой попытки.
Еще одна полезная функция – UninitializeReason()
int deinit() { switch(UninitializeReason()) { case REASON_CHARTCLOSE: case REASON_REMOVE: CleanUp(); break; // очистка и освобождение ресурсов. case REASON_RECOMPILE: case REASON_CHARTCHANGE: case REASON_PARAMETERS: case REASON_ACCOUNT: StoreData(); break; // подготовка к рестарту. } //... }
Можно также логировать причину выхода советника.
Коды самых распространенных ошибок и их вероятное решение
№ ошибки | Значение | Проблема | Решение |
4, 146 | Торговый сервер занят | Советник подал слишком много приказов одновременно или не дождавшись ответа от сервера, при выполнении операции – советник пытается отправить новый приказ | Перезагрузка терминала или оптимизация кода советника с помощью функций обработки ошибок |
8, 141 | Слишком частые запросы | Предыдущие причины ошибки, в сильно частом запросе | Аналогичное решение |
129 | Неправильная цена | Цена по которой Вы пытаетесь открыть позицию (BUY или SELL) неправильная | BUY нужно открывать по Ask а закрывать по BID; SELL нужно открывать по BID а закрывать по ASK |
130, 145 | Неправильные стопы | Стоп лосс, тейк профит или уровень открытия отложки или лимитника неверные. Стопы расположены слишком близко к цене. Ваш счет открыт в группе ECN (ЕЦН) или NDD (НДД), что не дает сразу выставлять стопы |
Проверьте значения Ваших стоп лоссов, тейк профитов, уточните минимальный стоп уровень по Вашему инструменту у брокера, при выставлении стопов – соблюдайте уровень минимальной дистанции. В хорошо написанном советнике должны быть функции работы на счетах ECN и NDD – это происходит путем модификации ордера уже после его открытия |
131 | Неправильный объем | Неправильный лот при открытии сделки, или меньше минимального (больше максимального). Разрядность лота тоже может отличаться от разрядности брокера | Проверьте правильность открытия лота, изучите спецификацию контракта и прочтите условия торговли в Вашем ДЦ, проверьте минимальный и максимальный лот в Вашем ДЦ и на Вашем счете |
132 | Рынок закрыт | Рынок закрыт на выходные дни | Пробуйте связаться с рынком после выходных |
133 | Торговля запрещена | В данный момент торговля запрещена | По данной валютной паре запрещено торговать – в конкретный момент времени или вообще. Часто у брокеров есть перерыв в несколько минут в полночь |
134 | Недостаточно денег для совершения операции | Лот, который Вы пытаетесь открыть, слишком большой, на него не хватает маржи | Проверьте уровень свободных средств и рассчитайте средства, которые Вам нужны для открытия лота, следите за уровнем Ваших свободных средств |
135-138 | Цена изменилась | Реквот, слишком быстрый рынок (новости), Брокер или ДЦ не дает Вам поставить позицию по заявленной цене | Не торгуйте в такие моменты, увеличьте уровень проскальзывания, но помните, что это влечет за собой открытие позиций не по заявленной Вами цене. Предусмотрите в советнике функцию обработки ошибок и количество попыток открытия позиций |
147 | Использование даты истечения ордера запрещено брокером | Ваш советник или Вы пытаетесь установить срок истечения отложенного ордера | В советнике, в функции OrderSend в параметре срок истечения поставьте 0 (ноль). Не устанавливайте срок истечения ордера |
148 | Количество открытых и отложенных ордеров достигло предела, установленного брокером | Максимальное количество открытых ордеров и позиций достигло предела, установленного брокером | Удалите или закройте часть позиций. Остановите процесс открытия новых позиций |
4012, 4013 | Остаток от деления на ноль | Вы пытаетесь поделить число на 0 (ноль) | Проверьте код советника на наличие ошибки, или же проверьте все значения из MarketInfo функций на момент возвращения 0, иногда при MarketInfo(Symbol(),MODE_SPREAD) возвращается не спред, а 0 (у брокеров с плавающим спредом) |
4017 | Вызовы DLL не разрешены | В Вашем терминале запрещен вызов DLL | Разрешите вызов DLL через Меню – сервис – Настройки – Советник – Разрешить вызов DLL |
4018, 4019 | Невозможно загрузить библиотеку | Библиотека повреждена или ее вызов завершается с ошибкой, возможно она вообще отсутствует | Проверьте библиотеку DLL |
4020 | Вызовы внешних библиотечных функций не разрешены | В Вашем терминале запрещен вызов функций из внешних экспертов | Разрешите вызов функций через Меню – сервис – Настройки – Советник – Разрешить вызов внешних экспертов |
4103 | Невозможно открыть файл | Данный файл не существует или заблокирован другим процессом | Проверьте наличие указанного файла. Проверьте, не заблокирован ли файл системой антивируса, разрешен ли режим записи-чтения файла |
4106 | Неизвестный символ | Символа нет в обзоре рынка | В обзоре рынка – правой кнопкой мыши – показать все символы. Проверить названия символа в советнике и наличие его в обзоре рынка. Некоторые советники используют четкие названия без суффиксов, а брокеры намеренно ставят суффиксы, например EURUSDx где х – суффикс |
4108 | Неверный номер тикета | Тикет ордера, который выбирает эксперт – не существует. Эксперт пытается выбрать тикет, но данный ордер был закрыт другим советником или руками. При попытке осуществления приказа над ордером, тикет был исполнен и закрыт брокером | Если данная ошибка появляется очень часто, 100-1000 раз за минуту, проверьте функции Вашего советника. Отключите другие советники или настройте их так, чтобы они не конфликтовали, не закрывайте ордер руками, когда эксперт выполняет операцию. Иногда такое случается, когда несколько советников используют одинаковый MagicNumber |
4109 | Торговля не разрешена | Советнику запрещено торговать, на графике грустный смайл или крестик | Включите галочку «Разрешить советнику торговать» во вкладе при установке советника, либо в меню – сервис – настройки – советники |
4110, 4111 | Длинные/короткие позиции не разрешены | В настройках советника, во вкладке Общие не разрешен тип позиций | Во вкладке Общие, при установке советника, есть выбор позиций, разрешенных к открытию |
Заключение
Рассмотренные вспомогательные функции и несложные приемы позволяют заметно упростить и ускорить процесс обнаружения и исправления ошибок в коде торговых экспертов, написанных на языке программирования MQL4. Грамотное написание кода и функций для логирования и сопровождения работы советника существенно ускоряют процесс его разработки.
Тема на форуме
С уважением, Дмитрий аkа Silentspec
TradeLikeaPro.ru
Когда вы программируете советника, обычно вы хотите, чтобы он торговал за вас. В этой статье мы рассмотрим, как советник может открывать ордера с помощью функции OrderSend().
OrderSend() — это функция, которая позволяет открывать новые ордера. Она состоит из следующих аргументов:
int OrderSend( string symbol, // символ int cmd, // торговая операция double volume, // количество лотов double price, // цена int slippage, // проскальзывание double stoploss, // стоп-лосс double takeprofit, // тейк-профит string comment=NULL, // комментарий int magic=0, // идентификатор datetime expiration=0, // срок истечения ордера color arrow_color=clrNONE // цвет );
Разберем каждый агрумент подробнее:
- symbol — это торговый инструмент, которым вы хотите торговать, например, EURUSD. Обычно в советнике мы будем использовать функцию Symbol(), которая возвращает имя символа текущего графика.
- cmd — это тип ордера для отправки, который может быть OP_BUY или OP_SELL для рыночных ордеров на покупку и продажу. OP_BUYLIMIT, OP_SELLLIMIT, OP_BUYSTOP, OP_SELLSTOP для лимитных и стоп-ордеров.
- volume — количество лотов или размер позиции. К примеру, 0,1 или 0,01.
- price — цена, по которой ордер должен быть открыт. Для ордера на покупку это будет цена Ask. Для ордера на продажу, это будет цена Bid. Для отложенных ордеров это будет любая действительная цена, которая будет выше или ниже текущей цены.
- slippage — это приемлемая разница между ценой открытия, запрошенной клиентом и фактической ценой на сервере. Например, проскальзывание в 3 пункта позволяет открыть ордер, поданный по цене 1.1980, если цена на сервере отличается не более, чем на 3 пункта (то есть между 1.1983 и 1.1977).
- stoploss — значение стоп-лосса.
- takeprofit — значение тейк-профита. Важно помнить, что ордера стоп-лосс и тейк-профит не могут быть размещены слишком близко к цене открытия, иначе ордер не будет открыт. Также цены стоп-лосса и тейк-профита должны быть округлены к числу десятичных знаков, используемых брокером.
- comment — комментарий к ордеру.
- magic — это число, которое вы можете присвоить ордеру, чтобы его идентифицировать. Например, вы хотите использовать одно и то же число для всех ордеров, открытых вашим советником.
- expiration — это время, в течение которого отложенный ордер остается в силе. По истечении срока экспирации он не будет исполнен.
- arrow_color — это цвет стрелки на графике при отправке ордера.
Функция OrderSend() имеет тип данных int и возвращает номер тикета открытого ордера, если он отправлен успешно, и -1, если отправка ордера не удалась. В этом случае можно использовать функцию GetLastError(), чтобы увидеть причину ошибки.
Посмотрим на простой пример скрипта:
//+------------------------------------------------------------------+ //| Test-1.mq4 | //| Copyright 2019, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Александр Паркер" #property link "https://traderblog.net/" #property version "1.00" #property strict //Определяем базовые данные double StopLoss=30; //Размер стоп-лосса в пунктах. double TakeProfit=50; //Размер тейк-профита в пунктах. double LotSize=0.05; //Размер позиции в лотах. double Slippage=5; //Допустимое проскальзывание в пунктах. double Command=OP_BUY; //Тип ордера. В данном случае ордер на покупку. double CalculateNormalizedDigits() { if(Digits<=3){ return(0.01); } else if(Digits>=4){ return(0.0001); } else return(0); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { // Рассчитываем цены для стоп-лосса, тейк-профита. double nDigits=CalculateNormalizedDigits(); double OpenPrice=Ask; double StopLossPrice=Ask-StopLoss*nDigits; double TakeProfitPrice=Ask+TakeProfit*nDigits; //Определяем переменную для хранения результата работы функции OrderSend() int OrderNumber; OrderNumber=OrderSend(Symbol(),Command,LotSize,OpenPrice,Slippage,StopLossPrice,TakeProfitPrice); //Проверяем, исполнился ордер или нет, затем выводим результат. if(OrderNumber>0){ Alert("Ордер ",OrderNumber," открыт"); } else{ Alert("Ордер не открыт. Ошибка - ",GetLastError()); } }
Функция Symbol() возвращает текущий торговый инструмент графика. OP_BUY указывает, что это рыночный ордер на покупку. Ask — это предопределенная переменная в MQL4, в которой хранится самая последняя цена Ask.
Проскальзывание Slippage является целым числом. Если ваш брокер использует 4-значные котировки (2-значные для пар с йеной), 1 пункт будет равен 1 пункту. Однако, если ваш брокер предлагает 3 и 5-значные котировки, в этом случае вам нужно добавить дополнительный ноль.
Запустим скрипт на EURUSD:
Если мы захотим разместить отложенный ордер, цена открытия будет отличаться от текущей рыночной цены. Значения стоп-лосса и тейк-профита должны быть рассчитаны относительно цены открытия отложенного ордера.
В нашем примере мы будем использовать переменную PendingPrice для цены отложенного ордера. Ее можно рассчитать по нашему торговому алгоритму или в качестве внешнего параметра. Для стоп-ордера на покупку PendingPrice должна быть больше текущей цены Ask.
OrderSend(Symbol(),OP_BUYSTOP,LotSize,PendingPrice,Slippage,BuyStopLoss, BuyTakeProfit,"Buy Stop Ордер",MagicNumber,0,Green);
Мы используем OP_BUYSTOP для указания стоп-ордера на покупку и PendingPrice для цены открытия нашего ордера.
Лимитные ордера аналогичны стоп-ордерам, за исключением того, что цена отложенного ордера является обратной относительно текущей цены и типа ордера. Для лимитных ордеров на покупку цена отложенного ордера должна быть меньше текущей цены Bid.
OrderSend(Symbol(),OP_BUYLIMIT,LotSize,PendingPrice,Slippage,BuyStopLoss, BuyTakeProfit,"Buy Limit Ордер",MagicNumber,0,Green);
Мы использовали OP_BUYLIMIT, чтобы разместить лимитный ордер на покупку. В остальном параметры идентичны параметрам для стоп-ордеров.
Рассмотрим пример скрипта, который может помочь вам открыть ордер с большим количеством опций. Двумя основными ограничениями при открытии ордера вручную в MetaTrader являются:
- Ручной расчет размера позиции.
- Невозможность установить магическое число.
Скрипт позволит вам установить процент капитала, которым вы готовы рискнуть, а также рассчитать размер позиции в зависимости от установленного вами стоп-лосса.
#property copyright "Александр Паркер" #property link "https://traderblog.net/" #property version "1.00" #property strict #property show_inputs enum Operation{ buy=OP_BUY, //BUY sell=OP_SELL, //SELL }; extern double Lots=1; //Размер позиции. extern bool UseRiskPercentage=true; //Процент риска для расчета размера позиции. extern double RiskPercentage=2; //Процент доступного баланса торгового счета для риска. input Operation Command=buy; //Тип ордера. extern int TakeProfit=40; //Тейк-профит в пунктах. extern int StopLoss=20; //Стоп-лосс в пунктах. extern int Slippage=2; //Проскальзывание в пунктах. extern int MagicNumber=0; //Магическое число. extern string Cmt=""; //Комментарий. //Нормализуем пункты. double CalculateNormalizedDigits() { if(Digits<=3){ return(0.01); } else if(Digits>=4){ return(0.0001); } else return(0); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- //Если стоп-лосс не установлен и используется процент риска, останавливаем скрипт и выводим требуется стоп-лосс. if(StopLoss==0 && UseRiskPercentage){ Print("Необходим стоп-лосс, если вы используете процент риска."); return; } int Cmd=Command; //Нормализуем и рассчитываем размер позиции. double nTickValue=MarketInfo(Symbol(),MODE_TICKVALUE); double nDigits=CalculateNormalizedDigits(); if(Digits==3 || Digits==5){ Slippage=Slippage*10; nTickValue=nTickValue*10; } if(UseRiskPercentage){ Lots=(AccountBalance()*RiskPercentage/100)/(StopLoss*nTickValue); Lots=MathRound(Lots/MarketInfo(Symbol(),MODE_LOTSTEP))*MarketInfo(Symbol(),MODE_LOTSTEP); } //Установливаем цены открытия, стоп-лосса и тейк-профита double OpenPrice=0; double TakeProfitPrice=0; double StopLossPrice=0; if(Cmd==OP_BUY){ OpenPrice=NormalizeDouble(MarketInfo(Symbol(),MODE_ASK),Digits); if(TakeProfit!=0) TakeProfitPrice=NormalizeDouble(OpenPrice+TakeProfit*nDigits,Digits); if(StopLoss!=0) StopLossPrice=NormalizeDouble(OpenPrice-StopLoss*nDigits,Digits); } if(Cmd==OP_SELL){ OpenPrice=NormalizeDouble(MarketInfo(Symbol(),MODE_BID),Digits); if(TakeProfit!=0) TakeProfitPrice=NormalizeDouble(OpenPrice-TakeProfit*nDigits,Digits); if(StopLoss!=0) StopLossPrice=NormalizeDouble(OpenPrice+StopLoss*nDigits,Digits); } //Выводим всю информацию Print("Открываем ордер ",Command," размер ",Lots, " цены открытия ",OpenPrice," проскальзывание ",Slippage," стоп-лосс ",StopLossPrice," тейк-профит ",TakeProfitPrice," комментарий ",Cmt," магическое число ",MagicNumber); //Отправляем ордер. int OrderNumber; OrderNumber=OrderSend(Symbol(),Cmd,Lots,OpenPrice,Slippage,StopLossPrice,TakeProfitPrice,Cmt,MagicNumber); if(OrderNumber>0){ Print("Ордер ",OrderNumber," открыт"); } else{ Print("Ошибка - ",GetLastError()); } }
Содержание
- Коды ошибок
- A) Полностью соответствуют MQL4 OrderSend() требованиям синтаксиса
- B) Ошибка 130: == «недействительная остановка»
- C) Хорошая практика не назначать в extern итераторных-переменных
MQL для чайников, программирование на MQL4, MQL5
Что значит 2010.02.01 17:00 MyExpert GBPUSD,M15: OrderModify error 130
почему обычно эта ошибка возникает?
Очень много подобных вопросов мне приходит. Поэтому публикую таблицу кодов ошибок. Например посмотрев вышеописанную ошибку error 130 становится понятно, что функция OrderModify пытается изменить стоп-лосс или тейк-профит слишком близко к текущей цене.
Коды ошибок
GetLastError() — функция, возвращающая коды ошибок. Кодовые константы ошибок определены в файле stderror.mqh. Для вывода текстовых сообщений следует использовать функцию ErrorDescription(), определенную в файле stdlib.mqh.
Коды ошибок, возвращаемые торговым сервером или клиентским терминалом:
Значение | Описание |
---|---|
Нет ошибки | |
1 | Нет ошибки, но результат неизвестен |
2 | Общая ошибка |
3 | Неправильные параметры |
4 | Торговый сервер занят |
5 | Старая версия клиентского терминала |
6 | Нет связи с торговым сервером |
7 | Недостаточно прав |
8 | Слишком частые запросы |
9 | Недопустимая операция нарушающая функционирование сервера |
64 | Счет заблокирован |
65 | Неправильный номер счета |
128 | Истек срок ожидания совершения сделки |
129 | Неправильная цена |
130 | Неправильные стопы |
131 | Неправильный объем |
132 | Рынок закрыт |
133 | Торговля запрещена |
134 | Недостаточно денег для совершения операции |
135 | Цена изменилась |
136 | Нет цен |
137 | Брокер занят |
138 | Новые цены |
139 | Ордер заблокирован и уже обрабатывается |
140 | Разрешена только покупка |
141 | Слишком много запросов |
145 | Модификация запрещена, так как ордер слишком близок к рынку |
146 | Подсистема торговли занята |
147 | Использование даты истечения ордера запрещено брокером |
148 | Количество открытых и отложенных ордеров достигло предела, установленного брокером. |
Коды ошибок выполнения MQL4 программы:
GetLastError() — функция, возвращающая коды ошибок. Кодовые константы ошибок определены в файле stderror.mqh. Для вывода текстовых сообщений следует использовать функцию ErrorDescription(), определенную в файле stdlib.mqh.
Коды ошибок, возвращаемые торговым сервером или клиентским терминалом:
Я пытаюсь вставить takeprofit и stoploss аргумент в моей SendOrder() функции, но я получаю следующее сообщение об ошибке:
Я уже проверил документацию для функции NormalizeDouble() , но я все еще получаю ошибку.
A) Полностью соответствуют MQL4 OrderSend() требованиям синтаксиса
Ваш код не на установление правильной SHORT торговли входной цены, как это следует читать , а Bid не Ask (эта ошибка скрыта , как это эффективно замаскированных на довольно космическом расстоянии 100 точек на допустимом расстоянии проскальзывания от указанной цены) ,
Ваш код не при назначении int ( 0 ) в месте, где , string как ожидается.
Вы должны проверить с вашим брокером несколько деталей:
- Допускает ли их условия и условия в OrderSend() одной стоп-инструкции, в т.ч., TP и SL, или же брокер T & C требуют , чтобы сначала открыть торгово-позицию и только после того, как это происходит , чтобы позволить OrderModify() инструкции к прайс-уровней настройки TP и SL?
- В любом случае, проверьте настройки Брокер T & C для STOPLEVEL & FREEZELEVEL расстояний, в пределах которого Брокер отвергает любые TP и SL установки (ы) или модификации (части).
C) Хорошая практика не назначать в extern итераторных-переменных
Хотя это не является корневой причиной вашей проблемы, не приживаются с передовой отраслевой практикой, один из которых не является присвоить любое значение заявленного extern . Вместо объявить собственную переменную, что вы контролируете объем & назначения их, но оставить extern (s) не-прикоснулся с вашей стороны кода.
Содержание
- Is ERR_TRADE_TOO_MANY_ORDERS (148) likely to happen and if it occurs + orderModify happens then.
- Ошибка 148 (MT4)
- OrderSend Error 148 — How to Fix?
- Коды ошибок в MQL4
- chocolate
- expforex
- expforex
- rbrus
- expforex
- Капиталист
- Капиталист
- imelam
- imelam
- frybit
- gince
- DIO-Soft
- gince
- expforex
- innovision
Is ERR_TRADE_TOO_MANY_ORDERS (148) likely to happen and if it occurs + orderModify happens then.
Above taken from code: /*. */ are mixture of docs and forum notes.
Given above blurb:
Let’s say max open+pending orders «. has reached the limit set by the broker.» ref: ERR_TRADE_TOO_MANY_ORDERS (148)
So ok, error code is detected and flag set to inhibit further OrderSend()s until it is seen that less than broker limit, at this time another order could be considered.
However during the time that EA at this limit, the code continues to do other open trade maintenance duties each time start() called eg, monitoring/moving TPs and SLs etc.
You know. in cruise mode just dreaming about massive income while the orders do their thing and we just tweak around the edges via orderModify 😉
And that would seem where can come unstuck because OrderModify() closes original order and reopens new order with requested mods and issues new ticket#
(which has to be discovered by EA using magic#. nice one MT)
btw support: since modify is type bool — why not do something really useful and make type int?
A return value like OrderSend() does and give out the ticket# of the new/modded order.
This is a real no-brainer solution to current non-clever I/F. Take a few mins to do?
You must have that new ticket# somewhere and modify builtin could lay hands on it, yes?
If at this broker max value and then decide time to move SL on market order, modify issued.
Will the broker refuse this modify order or will broker allow?
Would seem all based on how modify implemented on server: is possible that will now go max+1 and that’s not allowed according to docs.
.Of course if 148 never likely to happen — can forget all of above (I think 😉
it goes without saying that am inferring that a well behaved EA would qualify for the «never likely to happen» wording simply due to never issuing massive number of open,pending orders.
But that is not a solution — just a fingers crossed kludge.
how does one learn what is this maximum limit set by broker?
IF there is such a datum THEN is easy to build code around this knowledge and have happy error handler function and start() too, yes?
ELSE seems back into the usual guessing game again regards error handling.
Источник
Ошибка 148 (MT4)
Пытаюсь сделать обновление своего программного продукта.
При автоматическом тестировании все отлично — ошибок нету.
А вот от модераторов пришел ответ
Я добавил проверку по AccountInfoInteger ( ACCOUNT_LIMIT_ORDERS ).
Хотя, как написано в документации, это максимально количество ОТЛОЖЕННЫХ ордеров.
У меня они не используются. Использую только РЫНОЧНЫЕ (BUY и SELL).
Все равно ошибка повторяется. Как минимум по одному из символов (EURUSD) ошибки нету.
Сколько ни тестировал различных брокеров, AccountInfoInteger (ACCOUNT_LIMIT_ORDERS) везде выдает не менее 50.
Где еще нужна проверка? и какая проверка?
Пытаюсь сделать обновление своего программного продукта.
При автоматическом тестировании все отлично — ошибок нету.
А вот от модераторов пришел ответ
Я добавил проверку по AccountInfoInteger ( ACCOUNT_LIMIT_ORDERS ).
Хотя, как написано в документации, это максимально количество ОТЛОЖЕННЫХ ордеров.
У меня в справочнике написано так:
Количество открытых и отложенных ордеров достигло предела, установленного брокером
У меня они не используются. Использую только РЫНОЧНЫЕ (BUY и SELL).
Все равно ошибка повторяется. Как минимум по одному из символов (EURUSD) ошибки нету.
Сколько ни тестировал различных брокеров, AccountInfoInteger (ACCOUNT_LIMIT_ORDERS) везде выдает не менее 50.
Где еще нужна проверка? и какая проверка?
Вот примерный код
maxcount = MathMin(13, AccountInfoInteger(ACCOUNT_LIMIT_ORDERS));
if (maxcount == 0) maxcount = 13;
for (int i = 0; i // делаем что-то
if (count >= maxcount) return;
// БЛОК ОТКРЫТИЯ ОРДЕРОВ
Вот примерный код
maxcount = MathMin(13, AccountInfoInteger(ACCOUNT_LIMIT_ORDERS));
if (maxcount == 0) maxcount = 13;
Вторая часть по сути верная. В первой части мешает вот это:
Ведь если не удалось получить значение лимита, то это ошибка. В таком случае нельзя запускать эксперт вообще:
Вторая часть по сути верная. В первой части мешает вот это:
Ведь если не удалось получить значение лимита, то это ошибка. В таком случае нельзя запускать эксперт вообще:
А где написано, что 0 это ошибка?
Наоборот — 0 ОГРАНИЧЕНИЙ НЕТ
Максимально допустимое количество действующих отложенных ордеров (0-ограничений нет)
А где написано, что 0 это ошибка?
Когда терминал возвращает 0 в размере пункта , то в документации тоже нигде не написано, что это ошибка. Пользуемся чисто здравым смыслом.
Uladzimir Kirychenka :
Наоборот — 0 ОГРАНИЧЕНИЙ НЕТ
Когда терминал возвращает 0 в размере пункта , то в документации тоже нигде не написано, что это ошибка. Пользуемся чисто здравым смыслом.
Я пока не видел бесконечной памяти ни у одного компьютера. Поэтому именно здесь не верю тому, что написано в документации. Есть большая вероятность того, что это поле попросту не заполнено на стороне сервера. Таким образом, это ошибка.
Максимально допустимое количество действующих отложенных ордеров (0-ограничений нет)
Кстати, по-моему уже поднималась тема о том, что в справке допущена неточность. Точный вариант такой:
Максимально допустимое количество действующих и отложенных ордеров (0-ограничений нет)
Как и обещал делюсь результатом:
Похоже настроено, что количество ордеров должно быть не более AccountInfoInteger( ACCOUNT_LIMIT_ORDERS )-1 . Потому что при открытии AccountInfoInteger(ACCOUNT_LIMIT_ORDERS) ордера уже сообщает об ошибке.
Например: если AccountInfoInteger(ACCOUNT_LIMIT_ORDERS) возвращает 10, то при открытии 10 (а не 11 . ) ордера уже ошибка. Может это особенность работы с металлами, может есть еще какой-то скрытый ордер для внутреннего использования.
- Бесплатные приложения для трейдинга
- Форексный VPS бесплатно на 24 часа
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Источник
OrderSend Error 148 — How to Fix?
OrderSend Error 148 or ERR_TRADE_TOO_MANY_ORDERS is a frequently appearing MetaTrader 4 error message, especially if you are trading on some demo/real contest account. The error means that you are trying to place an order or open a position when the maximum number has already been reached. Some Forex brokers limit the number of simultaneously open orders and positions (this doesn’t count the and orders). When the maximum is reached and your MT4 expert advisor sends a new order request (pending or market) you will get an «OrderSend Error 148» message in the Experts log of your platform; the order won’t be executed.
As an MQL4 coder, you should handle these situations properly as they obviously lead to the incorrect functioning of the EA. Your expert advisor should be checking the maximum allowed number of orders and avoid opening new ones if the maximum is reached. Alternatively, it can try closing previous orders if a new order is to be opened.
The number of currently active orders and opened positions should be checked with the OrdersTotal() function.
The MQL4 (and MQL5 too) function to check the maximum allowed number of orders is the following:
If the returned value is zero, then there is no limit on maximum simultaneously opened orders or positions in this account.
You can use this simple demo script to print the value in your trading platform:
After executing, this script produces the following output in the RoboForex live account:
Unfortunately, there is no easy way to fix OrderSend Error 148 if you are a trader who doesn’t know how to code in MQL4. In this case, your solution could probably be to ask your Forex broker to increase the limit, but that is quite unlikely to happen. Of course, there is no point in doing this if your EA tends to open infinite number of orders. In that case, it is better to ask some coder (on our Forex Jobs forum section, for example) to fix the expert advisor.
If you have any thoughts, comments, or questions regarding MT4 OrderSend Error 148 and the ways to treat it, feel free to join our Forex forum for discussions with other traders and MQL4 developers.
If you want to get news of the most recent updates to our guides or anything else related to Forex trading, you can subscribe to our monthly newsletter.
Источник
Коды ошибок в MQL4
chocolate
Гуру форума
Для того, чтобы не искать номер ошибки в ручную, нажимаете ctrl+f и вводите код ошибки
Тему сделал важной.
expforex
Программиров
expforex
Программиров
Разбор полетов! Коды ошибок, их значения и способы устранения.
Разбор полетов! Коды ошибок, их значения и способы устранения.
Ввиду частых обращений ко мне, как специалисту в области программирования советников на мт4, с вопросами об ошибках, я попытаюсь Вам рассказать наиболее частые ошибки трейдера, и ошибки советников, способы их устранения и причины их возникновения.
Каждый советник имеет свой функциональный режим, но будем исходить из стандартного набора проблем и распространенных ошибок советников.
Краткая справка по ошибкам изложена в Коды Ошибок, а также в самом терминале MetaTrader4
Исходя из них — мы попробуем в стиле Руководства по ошибкам электронной техники описать проблему и способ ее решения.
Если Вашей ошибки нет в данной таблице, или способы решения не помогли, обратитесь к автору Вашего советника, но перед этим воспользуйтесь статьей Log файлы для детального рассмотрения проблемы с роботами* (Expforex Прибыльные советники — — Стратегии Форекс —)
ошибка 4, 146
Торговый сервер занят
1. Советник подал слишком много приказов одновременно
2. Не дождавшись ответа от сервера, при выполнении операции — советник пытается отправить новый приказ, Сервер перегружен
1. Перезагрузка терминала
2. Оптимизация кода советника с помощью функций обработки ошибок.
ошибка8, 141
Слишком частые запросы
1. Предыдущие причины ошибки, в сильно частом запросе.
ошибка129
Неправильная цена
1. Цена по которой Вы пытаетесь открыть позицию (BUY SELL)- неправильная
1. Золотое правило: BUY нужно открывать по Ask а закрывать по BID
SELL нужно открывать по BID а закрывать по ASK
ошибка130,145
Неправильные стопы
1. Стопы= Стоплосс, тейкпрофит или уровень открытия отложенника или лимитника.
2. Стопы расположены слишком близко к цене
3. Ваш счет открыт в группе ECN (ЕЦН) или NDD (НДД)
4. Ваш брокер использует Рыночное исполнение позиций
1. Проверьте значения Ваших стоплосс, тейпрофитов
2. Уточните минимальный стоп уровень по Вашему инструменту у брокера, при выставлении стопов — соблюдайте уровень минимальной дистанции
3. В хорошо написанном советнике должны быть функции работы на счетах ECN и NDD
ошибка131
Неправильный объем
1. Неправильный лот при открытии сделки
2. Лот, который вы пытаетесь открыть, меньше минимального
3. Лот, который вы пытаетесь открыть больше максимального
4. Разрядность лота отличается от разрядности брокера.
1. Проверьте правильность открытия лота, изучите спецификацию контракта и прочтите условия торговли в Вашем ДЦ
2.3. Проверьте, Минимальный и Максимальный лот в Вашем ДЦ и на Вашем счете. На некоторых типах счетов, минимальный лот может быть 0.01 а также 0.1 и даже 3. Максимальный лот может быть 5 лотов и 999 лотов и другие.
4. Уточните разрядность лотов на Вашем сервере. Если например разрядность лотов=1, то можно открыть лот 0.1 или 0.5 или 1.2 и так далее, с 1 знаком после запятой, если разрядность лота 2 знака, то исходя из минимального лота, лот может быть 0.01, 0.06, 0.17, 1.48. Также в некоторых ДЦ существует порядок степени лотов, например можно открыть 0.5 и 1 и 1.5 и так далее, а например 0.6 открыть нельзя. Уточните у своего брокера порядок установки лотов.
ошибка132
Рынок закрыт
1. Рынок закрыт в Выходные дни
1.Пробуйтесвязаться с рынком после выходных
ошибка133
Торговля запрещена
1. В данный момент торговля запрещена
2. По данной валютной паре запрещено торговать
1. Попробуйте торговать после выходных
ошибка134
Недостаточно денег для совершения операции
1. Лот, который Вы пытаетесь открыть, слишком большой, на него не хватает маржи
1. Проверьте уровень свободных средств, ирассчитайтесредства, которые Вам нужны, для открытия лота
2. Следите за уровнем Ваших свободных средств
ошибка135..138
Цена изменилась
1. Реквот
2. Слишком быстрый рынок
3. Брокер или ДЦ не дает Вам поставить позицию по заявленной цене
1. Не торгуйте в такие моменты
2. Увеличьте уровеньпроскальзывания, но помните что это влечет за собой открытие позиций не по заявленной Вами цене.
3. Сделайте в советнике функцию обработки ошибок и количество попыток открытия позиций
ошибка 147
Использование даты истечения ордера запрещено брокером
1. Ваш советник или Вы пытаетесь установить срок истечения отложенного ордера
1. В советнике, в функции OrderSend в параметре срок истечения поставьте=0
2. Не устанавливайте срок истечения ордера.
ошибка 148
Количество открытых и отложенных ордеров достигло предела, установленного брокером.
1. Максимальноеколичествооткрытых ордеров и позиций достигнут предела, установленного брокером.
1. Удалите или закройте часть позиций
2. Остановите процесс открытия новых позиций
3. Соблюдайте иерархию сделок, лучше открыть 1 позицию лото 0.1 одновременно, чем 10 позиций лотом 0.01 с потерей спреда.
ошибка 4012, 4013
zero devide
Остаток от деления на ноль
- Вы пытаетесь поделить число на 0.
- Проверьте Весь код советника на наличие такой грубой ошибки, или же проверьте все значения из MarketInfo функций на момент возвращения 0, иногда при MarketInfo(Symbol(),MODE_SPREAD) возвращается не спред а 0 (у брокеров с плавающим спредом)
ошибка 4017
Вызовы DLL не разрешены
- В Вашем терминале запрещен вызов DLL
- Разрешите вызов DLL через Меню – сервис – Настройки – Советник – Разрешить вызов DLL, но помните, разрешайте данную опцию только для советников, в которых Вы уверены, и уверены что в ДЛЛ не сидит какой-нибудь троян. Проверьте ДЛЛ на наличие троянов с помощью антивируса.
Ошибка 4018 , 4019
Невозможно загрузить библиотеку
- Библиотека повреждена
- Вызов библиотеки осуществляется с ошибкой
- Проверьте библиотеку DLL
- Обратитесь к разработчику данной библиотеки
Ошибка 4020
Вызовы внешних библиотечных функций не разрешены
- В Вашем терминале запрещен вызов функций из внешних экспертов
- Разрешите вызов функций через Меню – сервис – Настройки – Советник – Разрешить вызов внешних экспертов,
Ошибка 4103
Невозможно открыть файл
- Данный файл не существует
- Данный файл заблокирован
- Проверьте наличие указанного файла в папке experts – files
Tester – files
- Проверьте не заблокирован ли файл системой антивируса. Разрешен ли режим записичтения файла
Ошибка 4106
Неизвестный символ
- Символа нет в обзоре рынка
- В обзоре рынка – правой кнопкой мыши – показать все символы
- Проверить названия символа в советнике и наличие его в обзоре рынка
- Некоторые советники используют четкие названия без суфиксов, а брокеры намеренно ставят суфиксы, например EURUSDx где х – суфикс.
Ошибка 4108
Неверный номер тикета
- Тикет ордера, который выбирает эксперт – не существует
- Эксперт пытается выбрать тикет, но данный ордер был закрыт другим советником или руками.
- При попытке осуществления приказа над ордером, тикет был исполнен и закрыт брокером.
- Если данная ошибка появляется очень часто, 100-1000 раз за минуту, проверьте функции Вашего советника
- Отключите другие советники, или настройте их так, чтобы они не конфликтовали, не закрывайте ордер руками, когда эксперт выполняет операцию
Ошибка 4109
Торговля не разрешена
- Советнику запрещено торговать, на графике грустный смайл или крестик
- Включите галочку «Разрешить советнику торговать» в вкладе при установке советника, либо в меню- сервис – настройки – советники.
Ошибка 4110, 4111
Длинные позиции не разрешены
Короткие позиции не разрешены
- В настройках советника, в вкладке Общие не разрешен тип позиций
- В Вкладке Общие, при установке советника есть выбор позиций:
Long Short – Разрешены BUY SELL
Only Long– Разрешен BUY
Only Short – Разрешен SELL
НЕ ЗАБЫВАЕМ ГОВОРИТЬ СПАСИБО И НАЖИМАТЬ КНОПКУ
rbrus
Прохожий
в стандартных библиотеках
#include
#include
есть функция
string ErrorDescription(int error_code);
выводит описание ошибки
expforex
Программиров
Капиталист
Активный участник
Гуру форума
Капиталист
Активный участник
У меня скальпер на ЕСН альпари такую шнягу выдаёт!
А вот это что тогда?
2015.01.26 10:11:33.233 ‘54669’: order buy 0.01 EURUSD opening at 1.12608 sl: 1.12538 tp: 1.15108 failed [Off quotes]
и это:
2015.01.26 16:45:04.623 HistoryBase: 2 errors in ‘EURUSD1’
спасибо!
Гуру форума
На ECN Market Execution. Похоже советник рассчитан на работу с Instant Execution. На Альпари счета стандарт.
imelam
Интересующийся
Гуру форума
imelam
Интересующийся
frybit
Прохожий
Гуру форума
gince
Местный знаток
У меня не ошибка , а предупреждение. Ни как не могу его понять что плохо.
possible loss of data due to type conversion ************.mq4 1214 9
а вот эта строка (она вторая)
dg=MarketInfo(sy,MODE_DIGITS);
if(dg==0)
Есть и еще раз
int dg=MarketInfo(OrderSymbol(), MODE_DIGITS)
Тут символ пробовал писать и нс прямую, но не в этом дело.
DIO-Soft
Новичок форума
У меня не ошибка , а предупреждение. Ни как не могу его понять что плохо.
possible loss of data due to type conversion ************.mq4 1214 9
а вот эта строка (она вторая)
dg=MarketInfo(sy,MODE_DIGITS);
if(dg==0)
Есть и еще раз
int dg=MarketInfo(OrderSymbol(), MODE_DIGITS)
Тут символ пробовал писать и нс прямую, но не в этом дело.
не соответствие типов,
если напрягает — сделайте так:
int dg=(int)MarketInfo(OrderSymbol(), MODE_DIGITS);
gince
Местный знаток
не соответствие типов,
если напрягает — сделайте так:
int dg=(int)MarketInfo(OrderSymbol(), MODE_DIGITS);
expforex
Программиров
innovision
Новичок форума
вот еще +38 штук
4210:ERR_CHART_PROP_INVALID = Неизвестное свойство графика
4211:ERR_CHART_NOT_FOUND = График не найден
4212:ERR_CHARTWINDOW_NOT_FOUND = Не найдено подокно графика
4213:ERR_CHARTINDICATOR_NOT_FOUND = Индикатор не найден
4220:ERR_SYMBOL_SELECT = Ошибка выбора инструмента
4250:ERR_NOTIFICATION_ERROR = Ошибка отправки push-уведомления
4251:ERR_NOTIFICATION_PARAMETER = Ошибка параметров push-уведомления
4252:ERR_NOTIFICATION_SETTINGS = Уведомления запрещены
4253:ERR_NOTIFICATION_TOO_FREQUENT = Слишком частые запросы отсылки push-уведомлений
5001:ERR_FILE_TOO_MANY_OPENED = Слишком много открытых файлов
5002:ERR_FILE_WRONG_FILENAME = Неверное имя файла
5003:ERR_FILE_TOO_LONG_FILENAME = Слишком длинное имя файла
5004:ERR_FILE_CANNOT_OPEN = Ошибка открытия файла
5005:ERR_FILE_BUFFER_ALLOCATION_ERROR = Ошибка размещения буфера текстового файла
5006:ERR_FILE_CANNOT_DELETE = Ошибка удаления файла
5007:ERR_FILE_INVALID_HANDLE = Неверный хендл файла (файл закрыт или не был открыт)
5008:ERR_FILE_WRONG_HANDLE = Неверный хендл файла (индекс хендла отсутствует в таблице)
5009:ERR_FILE_NOT_TOWRITE = Файл должен быть открыт с флагом FILE_WRITE
5010:ERR_FILE_NOT_TOREAD = Файл должен быть открыт с флагом FILE_READ
5011:ERR_FILE_NOT_BIN = Файл должен быть открыт с флагом FILE_BIN
5012:ERR_FILE_NOT_TXT = Файл должен быть открыт с флагом FILE_TXT
5013:ERR_FILE_NOT_TXTORCSV = Файл должен быть открыт с флагом FILE_TXT или FILE_CSV
5014:ERR_FILE_NOT_CSV = Файл должен быть открыт с флагом FILE_CSV
5015:ERR_FILE_READ_ERROR = Ошибка чтения файла
5016:ERR_FILE_WRITE_ERROR = Ошибка записи файла
5017:ERR_FILE_BIN_STRINGSIZE = Размер строки должен быть указан для двоичных файлов
5018:ERR_FILE_INCOMPATIBLE = Неверный тип файла (для строковых массивов-TXT, для всех других-BIN)
5019:ERR_FILE_IS_DIRECTORY = Файл является директорией
5020:ERR_FILE_NOT_EXIST = Файл не существует
5021:ERR_FILE_CANNOT_REWRITE = Файл не может быть перезаписан
5022:ERR_FILE_WRONG_DIRECTORYNAME = Неверное имя директории
5023:ERR_FILE_DIRECTORY_NOT_EXIST = Директория не существует
5024:ERR_FILE_NOT_DIRECTORY = Указанный файл не является директорией
5025:ERR_FILE_CANNOT_DELETE_DIRECTORY = Ошибка удаления директории
5026:ERR_FILE_CANNOT_CLEAN_DIRECTORY = Ошибка очистки директории
5027:ERR_FILE_ARRAYRESIZE_ERROR = Ошибка изменения размера массива
5028:ERR_FILE_STRINGRESIZE_ERROR = Ошибка изменения размера строки
5029:ERR_FILE_STRUCT_WITH_OBJECTS = Структура содержит строки или динамические массивы
Источник