К содержимому
Форекс
на автомате

После перезагрузки VPS старый советник открыл вторую позицию

igor36с 07.2020
Испытатель
11сообщений
Автор темы#1
Советник на MQL4, которому лет восемь, торгует EURUSD и USDCHF, одна позиция на символ. В прошлый четверг VPS ночью перезагрузился, хостинг что-то обслуживал. Терминал поднялся автозапуском, советник стартовал. Утром вижу на EURUSD две покупки по 0,5 вместо одной.
Полез в код. Признак «в рынке» у меня хранится в обычной переменной bool inTrade: ставится в true после успешного OrderSend и в false после закрытия. После перезапуска она, понятно, false, советник видит сигнал на покупку, который всё ещё действует, и открывает вторую. Там же в переменных хранится, переносил ли я стоп в безубыток и сколько входов было за день, у меня лимит два входа в день на символ. Всё это после рестарта обнулилось.
Понимаю, что так писать нельзя. Как правильно, с учётом того, что советник старый и переписывать его целиком не хочется?
mamontс 04.2023
Исследователь
10сообщений
#2
Всё, что можно узнать у сервера, у сервера и узнавай. В OnInit и вообще перед каждым решением о входе пробегись по OrdersTotal(), выбери ордера по своему мэджику и символу, вот тебе и inTrade. Отдельная переменная для этого не нужна, она только врёт. Я в своём старом советнике так и переделал, когда наступил на то же самое: функция подсчёта своих ордеров вызывается в начале каждого OnTick, на скорость это никак не влияет.
igor36с 07.2020
Испытатель
11сообщений
Автор темы#3
С позицией понятно. А безубыток и счётчик входов за день? Их по открытым ордерам не узнаешь.
egorov_mс 09.2024
Системный практик
14сообщений
#4
Узнаешь больше, чем кажется. Безубыток виден по самой позиции: если у покупки стоп на уровне цены открытия или выше, значит, переносил. Счётчик входов за день считается по истории: сколько ордеров с твоим мэджиком по символу открыто сегодня, открытые плюс закрытые. Так даже надёжнее, потому что учитывает и то, что закрылось, пока советник лежал.
Остаётся то, что с сервера действительно не восстановить: например, советник ждёт второго подтверждения сигнала или помнит уровень, от которого считает откат. Это хранится в файле и пишется сразу при изменении, через временный файл и переименование, чтобы при обрыве не остался битый. Глобальные переменные терминала тоже вариант, но они, насколько помню, записываются на диск при нормальном закрытии терминала, и при падении последние изменения могут потеряться.
И главное правило при старте: если файл говорит одно, а сервер другое, верить серверу и громко писать в журнал, что состояние разошлось.
Сергей 1973с 01.2025
Системный практик
14сообщений
#5
Подтверждаю про глобальные переменные. У меня в прошлом году после жёсткого рестарта VPS пропала глобальная переменная с уровнем отката, и советник посчитал его заново от текущей цены. Ничего страшного не случилось, но с тех пор пишу в файл, а если всё-таки пользуюсь глобальными, вызываю GlobalVariablesFlush после каждой записи.
igor36с 07.2020
Испытатель
11сообщений
Автор темы#6
Отчитываюсь через две недели. Переделал, как mamont и egorov_m писали: inTrade убрал, позицию ищу по мэджику и символу перед каждым решением, безубыток определяю по стопу относительно цены открытия, счётчик входов за день считаю по истории.
И вылезла штука, которую я бы сам не нашёл, если бы не стал проверять. OrdersHistoryTotal() в MQL4 видит только ту историю, которая выбрана во вкладке «История счёта». На тестовом терминале там стоял произвольный период, который я когда-то выставлял для отчёта, и заканчивался он прошлой неделей. Советник видел ноль закрытых сделок за сегодня и разрешал третий вход. Поставил «вся история», а в советник добавил проверку: если история пустая, а сделки по счёту точно были, писать предупреждение и не входить.
Тест делал простой: на демо открыта позиция, снимаю процесс терминала через диспетчер задач и запускаю снова. Двадцать раз в разные моменты, в том числе сразу после OrderSend. Дублей ни разу.
toha.isaevс 07.2024
Первый прогон
4сообщения
#7
А если при старте на сервере есть позиция с твоим мэджиком, которую советник не открывал? Например, руками. Берёшь под управление или не трогаешь?
Продолжить обсуждение

Для ответа войдите в свой аккаунт.

Войти
← Предыдущая темаСледующая тема →