Глобальные переменные и закрытие терминала.

 
Столкнулся с проблемой: у меня для торговли используется глоб. переменная - семафор.
Т.е. пока идёт торговая оперция, эксперт устанавливает её значение в 1, а когда заканчивает, в 0.
Ну, и, естественно, пока она равна 1, ни один другой эксперт торговать не может.
Так вот если закрыть терминал во время торговли, она остаётся равна 1, и при следюющем запуске никто не может торговать.

Посоветуйте, плз, как обойти проблему? Может можно как-то при старте терминала обнулять эту переменную? Или перед выходом?

Я думал использовать UninitializeReason( ). Если бы был код возврата "Закрытие терминала", я бы обнуление вставил в деинит экспертов.

REASON_REMOVE 1 Эксперт удален из диаграммы.
REASON_RECOMPILE 2 Эксперт перекомпилирован.
REASON_CHARTCHANGE 3 Символ или период графика был изменен.
REASON_CHARTCLOSE 4 График закрыт.
REASON_PARAMETERS 5 Входные параметры были изменены пользователем.
REASON_ACCOUNT 6 Активирован другой счет.
REASON_SHUTDOWN 7 Терминал закрыт.
 
Посмотрите функцию:


bool GlobalVariableSetOnCondition( string name, double value, double check_value)


Устанавливает новое значение глобальной переменной, если текущее значение равно третьему параметру check_value. Если переменной не существует, функция вернет false(ЛОЖЬ) и установит значение константы ERR_GLOBAL_VARIABLE_NOT_FOUND в LastError. При успешном выполнении функция возвращает true(ИСТИНА), иначе - false(ЛОЖЬ). Для того, чтобы получить информацию об ошибке, вызовите функцию GetLastError().
Функция может быть использованна в качестве семафора для доступа к общим ресурсам.

Параметры

name - Имя глобальной переменной.
value - Новое значение.
check_value - Значение для проверки с текущим значением глобальной переменной.

Пример

  int init()
    {
     //---- создание гловальной переменной
     GlobalVariableSet("DATAFILE_SEM",0);
     //...
    }
  
  int start()
    {
     //---- перед использованием ресурса пытаемся его заблокировать
     while(!IsStopped())
       {
        //---- блокируем
        if(GlobalVariableSetOnCondition("DATAFILE_SEM",1,0)==true)  break;
        //---- переменная удалена?
        if(GetLastError()==ERR_GLOBAL_VARIABLE_NOT_FOUND) return(0);
        //---- задержка исполнения в полсекунды
        Sleep(500);
       }
     //---- ресурс заблокирован
     // ... работа с файлом
     //---- разблокируем ресурс
     GlobalVariableSet("DATAFILE_SEM",0);
    }


 
Посмотрите функцию:
смотрел. Пользуюсь. Если чесно, не понимаю, как она может мне помочь в этой ситуации...
Проблема в том, что если закрыть терминал в момент, когда выдерживается пауза между торг. операциями (гл. переменная = 1), при следующем включении она тоже будет = 1. А чтоб поменять её обратно на 0, надо выполнять ф-цию с середины, что невозможно ( в начале ф-ции есть проверка - если гл. переменная = 1, то просто ждём, когда она станет = 0, ничего не делаем ).

Кроме того, при выключении терминала (у меня, по крайней мере ) деинит не отрабатывается. При откреплении эксперта - всё ОК, а при закрытии программы - ничего не происходит. Поэтому и в деинит ничего не вставишь =(
 
Посмотрите функцию:
смотрел. Пользуюсь. Если чесно, не понимаю, как она может мне помочь в этой ситуации...
Проблема в том, что если закрыть терминал в момент, когда выдерживается пауза между торг. операциями (гл. переменная = 1), при следующем включении она тоже будет = 1. А чтоб поменять её обратно на 0, надо выполнять ф-цию с середины, что невозможно ( в начале ф-ции есть проверка - если гл. переменная = 1, то просто ждём, когда она станет = 0, ничего не делаем ).

Кроме того, при выключении терминала (у меня, по крайней мере ) деинит не отрабатывается. При откреплении эксперта - всё ОК, а при закрытии программы - ничего не происходит. Поэтому и в деинит ничего не вставишь =(


Та же проблема. Деинит отрабатывается по принципу "то потухнет, то погаснет". Можно попытаться ввести разбиение на интервалы торговли по разным символам, как у Элдера в TSD. Должно помочь, если тики поступают достаточно часто. Кроме того, на демо часто стала выскакивать ошибка #146 "Trade context is busy". В МТ3 на демо такое случалось довольно редко. Что сие за зверь и как с ним бороться? Мешает работать.
 
Можно попытаться ввести разбиение на интервалы торговли по разным символам, как у Элдера в TSD.
ещё одно извращение =)
Должно и так работать. Должно. Только чтоб отрабатывался деинит и (желательно) добавить REASON_SHUTDOWN.

а то опять городИть придётся.... например, при каждом запуске терминала цеплять какой-нить скрипт с необходимыми на старте операциями ;) обнулить глоб. переменные, удалить объекты, .......
 
Мало ли что кому должно. Я предпочитаю возмжно полный контроль за программой хотя бы на своей стороне, потому что на сервере и без того забот хватает. И косяков там наверняка полнО. Конечно, это выливается в некоторую дополнительную работу по контролю за ошибками. Ну и хрен с ним. Спокойствие важнее. Просто не доверяю вещам, которые не понимаю, как работают.
 
да всё правильно....я тоже такой =)

только неправильно это - кто-то оставляет косяки, а кто-то постоянно придумывает, как их обходить...
не упрёк даже, скорее, наблюдение...

А предыдущий пост адресовался скорее совести разработчиков =)
 
Эта дискуссия уже была :)
По-моему, в "ошибке 6". Мне тогда подсказали :) устанавливать одну переменную в нужное значение, затем другую - в знак того, что первая успешно установлена (на случай, если терминал зависнет в процессе). Я это пожелание проигнорировал, а вместо него - ВНИМАНИЕ, Я СТАЛ СЕРЬЕЗНЫМ -

посоветовал разработчикам ввести скрипт под названием startup, нечто вроде init, но не для эксперта, а для всей системы. Пока ответа не было.

Альтернатива - исполнение инициализации (установка переменной в ноль) в init, но поскольку в каждом советнике это делать нельзя, а надо лишь один (первый) раз, то либо в советнике, чей маджик меньше, либо опять через систему глобальных семафоров. У буржуев есть замечательный термин для такого программирования - error prone. То есть, криво.

Я бы все-таки предложил ввести startup скрипт.
 
Я бы все-таки предложил ввести startup скрипт.
да, было бы хорошо...
А пока, повешу наверное советника на евру, который будет заниматься подобной работой. Переинициализаций у него не будет (из-за смены чарта или компилирования), поэтому он будет работать только после запуска терминала...
Тоже вариант =)
 
Я бы все-таки предложил ввести startup скрипт.
да, было бы хорошо...
А пока, повешу наверное советника на евру, который будет заниматься подобной работой. Переинициализаций у него не будет (из-за смены чарта или компилирования), поэтому он будет работать только после запуска терминала...
Тоже вариант =)


У этого варианта один большой минус - ты не знаешь, чей тик придет первым, скажем, EURUSD (на котором висит инициализация), или EURJPY (например). Ночью тики ходят редко. Перезапустишь терминал, и жди, пока сработает нужный советник...
 
Вариант с разделением времени между символами лично мне кажется наиболее надежным, однако скорее всего придется сочинить некую процедуру RareTicksControl() для контроля "необычных" тиков, чтобы эксперт не пытался на них ориентироваться. Как правило, ночью активность все равно низкая, так что это не должно быть серьезной проблемой (IMHO).

посоветовал разработчикам ввести скрипт под названием startup, нечто вроде init, но не для эксперта, а для всей системы. Пока ответа не было.


Не совсем понятно, что именно этот скрипт должен делать?

Закачал, по всей видимости, последнюю версию 1.8.1, поставил, запустил редактор -- опять та же фенька c ^C ^V... <8-[[[
Причина обращения: