Семафор - он сильно нужен?

 
Вчера вечером наступил на интересные грабли.
Во-первых: в советнике стоит проверка на возможность торговли, если низя - завершает и ждем следующего тика.
Во-вторых, при попытке выставить отложенную покупку, берется Ask из Обзора рынка, что вроде страхует от устаревания цен(Рефреш не делал, правда).

В итоге, когда наступил подходящий момент вчера, советник пытался выставить отложенный BuyStop на Фунте по цене 1.7969, при этом Аск в обзоре был 1.7961 (то есть запас в 8 пунктов с лихвой перекрывает СтопЛевел). Пришла СМСка об этой попытке, но выставить не удалось. Тогда советник пытался открыть по рынку по Аску из Обзора Рынка с проскальзыванием в 3 пункта, эта попытка тоже не увенчаллась успехом.
Сегодня пришел и глянул логи. Было много ошибок номер шесть, подозреваю, что из-за другого плохого советника, который гад пытался модифицировать стоп по другой паре по одной и той же цене. Теперь я ему сделал нормализацию, чтоб больше не мешал.
Все советники имеют проверку на доступность торговли, вот подозреваю, что имеено этот плохой советник и наломал мне дров.
Я в первый раз наступаю на такие грабли и задумался, что тоже не помешает вставить семафор на торговые операции. Вот собственно и вопрос - помогает семафор реально или нет?
 
Кварк писАл, что ошибок стало меньше. Имеет смысл использовать, если торгует больше 2 экспертов.
 
Хмм.... Оказывается в моих советниах не было проверки на вохможность торговли

   if (!IsTradeAllowed()) {Print(TimeToStr(CurTime())," торговые операции недоступны");return;}




Видимо, хотел, да забыл вставить.
Только в одном была, так что надо все заново проверять.

 
в MarketInfo добавлен режим MODE_TRADEALLOWED, при помощи которого можно выяснить, можно ли торговать данным инструментом в данный момент
 
Да у меня только валюты крутятся, там сливать можно круглосуточно :))
Но за напоминание - спасибо.
 
в MarketInfo добавлен режим MODE_TRADEALLOWED, при помощи которого можно выяснить, можно ли торговать данным инструментом в данный момент

Slawa, к сожалению название енумератора и название функции - isTradeAllowed - совпадают. Хелп тоже не делает различий между ними.
На самом деле, нужно как-то различать TradeAllowed, то есть разрешено ли торговать вообще, и TradeContextBusy, то есть открыт или занят торговый канал в текущий момент времени в реалтайм.
Не могли бы Вы пояснить, какую функцию надо использовать для получения информации выше.
Спасибо
 
в MarketInfo добавлен режим MODE_TRADEALLOWED, при помощи которого можно выяснить, можно ли торговать данным инструментом в данный момент


За этот режим спасибо - многое упрощается.

Семафор - он сильно нужен?


Нужен, и не просто семафор, а еще и в комплексе с таймаутом, чтобы на реале зря не напрягать брокера. Вопрос в том, как его корректно инициализировать. Если это глобальная переменная, то обнулять ее перед запуском терминала придется, скорее всего, руками, либо после запуска скриптом. Хуже другое: если будет сбой (связи, сервера, терминала, ...), и машина при этом останется без присмотра, вся система неминуемо войдет в клинч. Со всеми вытекающими... Думаю, тут есть почва для размышлений.
 
Нужен, и не просто семафор, а еще и в комплексе с таймаутом, чтобы на реале зря не напрягать брокера. Вопрос в том, как его корректно инициализировать. Если это глобальная переменная, то обнулять ее перед запуском терминала придется, скорее всего, руками, либо после запуска скриптом. Хуже другое: если будет сбой (связи, сервера, терминала, ...), и машина при этом останется без присмотра, вся система неминуемо войдет в клинч. Со всеми вытекающими... Думаю, тут есть почва для размышлений.

да, над этим давно думаем =)
пока выход - startup эксперт, который обнуляет этот самый семафор. Запускается только при запуске терминала и в init делает своё дело )

Но это, конечно, обходы... Надо бы сделать ПРИНУДИТЕЛЬНУЮ ДЕИНИЦИАЛИЗАЦИЮ при выключении терминала и добавить в UninitializeReason( ) REASON_TERMINALSHUTDOWN. Проблем быть не должно.
В deinit эксперта делаем проверку UninitializeReason( ), и если она говорит, что терминал закрывается, обнуляем всё что можно =)))
 
Нужен, и не просто семафор, а еще и в комплексе с таймаутом, чтобы на реале зря не напрягать брокера. Вопрос в том, как его корректно инициализировать. Если это глобальная переменная, то обнулять ее перед запуском терминала придется, скорее всего, руками, либо после запуска скриптом. Хуже другое: если будет сбой (связи, сервера, терминала, ...), и машина при этом останется без присмотра, вся система неминуемо войдет в клинч. Со всеми вытекающими... Думаю, тут есть почва для размышлений.

да, над этим давно думаем =)
пока выход - startup эксперт, который обнуляет этот самый семафор. Запускается только при запуске терминала и в init делает своё дело )

Но это, конечно, обходы... Надо бы сделать ПРИНУДИТЕЛЬНУЮ ДЕИНИЦИАЛИЗАЦИЮ при выключении терминала и добавить в UninitializeReason( ) REASON_TERMINALSHUTDOWN. Проблем быть не должно.
В deinit эксперта делаем проверку UninitializeReason( ), и если она говорит, что терминал закрывается, обнуляем всё что можно =)))


Есть системный вариант - поставить хук на запуск терминала и в этот момент что-то сотворить с глобальной переменной; то же самое - при выгрузке терминала из памяти. Когда-то я нечто подобное делал. С помощью перехвата можно решить и проблемы с перебоями связи. Однако так нельзя, либо очень сложно, отследить внутреннюю жизнь терминала, и если сбой произойдет именно в нем, то сделать, скорее всего, ничего не удастся. Однако это уже вопрос к разработчикам :)
 
Slawa, к сожалению название енумератора и название функции - isTradeAllowed - совпадают. Хелп тоже не делает различий между ними.
На самом деле, нужно как-то различать TradeAllowed, то есть разрешено ли торговать вообще, и TradeContextBusy, то есть открыт или занят торговый канал в текущий момент времени в реалтайм.
Не могли бы Вы пояснить, какую функцию надо использовать для получения информации выше.
Спасибо

наш хелп в постоянной доработке. сейчас с ним работает лингвист-переводчик. скоро будет полностью готов. спасибо за замечание.
функция IsTradeAllowed проверяет, во-первых, флаг разрешения эксперту торговать (это ещё из тройки идёт), во-вторых, занятость торгового потока.
режим MODE_TRADEALLOWED позволяет узнать из настроек инструмента, разрешена торговля данным инструментом в данный момент или нет.

кстати о совпадениях. для тестирования MODE_TRADEALLOWED мы сделали возможным передавать в функцию IsTradeAllowed два параметра - символ и время
bool IsTradeAllowed(string symbol, datetime tested_time);
но эта возможность - недокументирована. неизвестно, как долго она проживёт.
 

функция IsTradeAllowed проверяет, во-первых, флаг разрешения эксперту торговать (это ещё из тройки идёт), во-вторых, занятость торгового потока.

Я испытываю проблемы с использованием этой функции в мутексе, которым защищены все торговые операции в моих экспертах.
void TradeMutexLock()
{
    if (IsTesting())
        return;

    while(!IsStopped())
    {
        if (IsTradeAllowed())
        {
            if (GlobalVariableSetOnCondition(TRADEMUTEX, 1., 0.))
                return;
        
            if (GetLastError() == ERR_GLOBAL_VARIABLE_NOT_FOUND)
            {
                TradeMutexInit();
                continue;
            }
        }
        
        Sleep(100);
    }
    Alert("TradeMutexLock(): execution stopped due to 2.5s timeout.");
}


Понятно, что функция будет подвисать, если флаг разрешения торговли снят.
Нужно как-то разделить две функциональности IsTradeAllowed, о которых Вы говорите, раскидать их по разным функциям.

Вообще, все эти мутексы, семафоры и таймауты - попытка to workaround "ошибку №6".

Кстати, у меня уже несколько недель крутится простенький эксперт на августовском билде, который время от времени начинает выдавать серию instant execution ордеров на разных инструментах. Сейчас посмотрел логи, единственная ошибка - trade context busy. Никаких мутексов там нет, все довольно тупо, OrderSend со стопами в ответ на определенные условия. Экспертов больше десятка. На демо счету, правда, и реально торговать я им не пробовал.
На более поздних билдах торговля экспертом невозможна из-за шестерки. Бьет по карману. :(

Причина обращения: