« Предыдущий пост | На главную страницу | Следующий пост »

Как ограничить количество одновременно открытых позиций/отложенных ордеров

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

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

Функции Lock() и Unlock() я описывал в выпуске "Критическая секция": разграничение доступа к ресурсу".

//+------------------------------------------------------------------+
//| Lock()                                                        |
//|                                                                  |
//| Возвращает:                                                |
//|   0 - если "критическая секция" успешно        |
//|        заблокирована                                     |
//|   1 - в случае ошибки                                   |
//|   2 - эксперт остановлен                              |
//|   3 - по таймауту (слишком долго ждали)       |
//+------------------------------------------------------------------+
int Lock(string GlobVarName, int timeout = 0)
  {
    string critical_section = GlobVarName+"Lock";
// проверим, существует ли переменная critical_section if (!GlobalVariableCheck(critical_section)) { if (GetLastError()!=0) return(1);
// переменная не существует, создадим ее if (GlobalVariableSet(critical_section, -1.0)==0) return(1); // переменная создана }
int StartTime = GetTickCount();
// ждем "зеленового света" while (true) { // проверить, не загорелся ли "зеленый свет" if (GlobalVariableGet(critical_section)==-1.0) { // "зеленый свет" загорелся, зажигаем "красный свет" if (GlobalVariableSetOnCondition(critical_section, 1.0, -1.0)) return(0);
// нас опередили, поэтому ждем "зеленового света" }
// проверим, не остановлен ли эксперт if (IsStopped()) return(2);
// таймаут не истек? if (timeout!=0) { if ((GetTickCount()-StartTime)>timeout*1000) return(3); }
// спим 0.1 секунды Sleep(100); } }
//+------------------------------------------------------------------+ //| Unlock() | //| | //| Возвращает: | //| 0 - если "критическая секция" успешно | //| разблокирована | //| 1 - в случае ошибки | //| 2 - эксперт остановлен | //| 3 - по таймауту (слишком долго ждали) | //+------------------------------------------------------------------+ int Unlock(string GlobVarName, int timeout = 0) { string critical_section = GlobVarName+"Lock";
// проверим, существует ли переменная critical_section if (!GlobalVariableCheck(critical_section)) { if (GetLastError()!=0) return(1);
// переменная не существует, создадим ее if (GlobalVariableSet(critical_section, -1.0)==0) return(1);
// переменная создана, поэтому выходим return(-1.0); }
int StartTime = GetTickCount();
// бесконечный цикл while (true) { // пытаемся установить "зеленый свет" if (GlobalVariableSetOnCondition(critical_section, -1.0, 1.0)) return(0);
// проверим, не остановлен ли эксперт if (IsStopped()) return(2);
// таймаут не истек? if (timeout!=0) { if ((GetTickCount()-StartTime)>timeout*1000) return(3); }
// спим 0.1 секунды Sleep(100); } }

Для решения нашей задачи создадим дополнительно функции StartTrading() и StopTrading().

В функции StartTrading() последовательность действий такова:

  • Локируем критическую секцию, чтобы исключить одновременный доступ из нескольких экспертов к функции OrdersTotal() и для исключения одновременной торговли нескольких экспертов.
  • Если количество открытых позиций/ордеров меньше лимита, то возвращаем true.
  • Если количество открытых позиций/ордеров больше или равно лимиту, то пишем об этом в лог, разлокируем критичсекую секцию и возвращаем false.

Вот исходный код функции StartTrading():

bool StartTrading(int max_trades)
  {
    // залокируем критическую секцию
    if (Lock("MaxTrades")!=0) return(false);
int open_trades = OrdersTotal();
if (open_trades<max_trades) return(true); else { Print("Уже открыто ", open_trades, " позиций"); Unlock("MaxTrades"); return(false); } }

В функции StopTrading() мы просто разлокируем критическую секцию:

void StopTrading()
  {
    Unlock("MaxTrades");
    return;
  }

В следующем выпуске я приведу пример использования этих функций.



Все статьи по теме "Пишем советников для MetaTrader 4".

« Предыдущий пост | На главную страницу | Следующий пост »

Подписаться на мою рассылку



Размещение статьи "Как ограничить количество одновременно открытых позиций/отложенных ордеров" на Вашем сайте

Размещение статьи "Как ограничить количество одновременно открытых позиций/отложенных ордеров" на Вашем сайте возможно при условии выполнениия следующих условий:

  • Запрещается изменение оригинального текста без согласия автора - Андрея Ведихина.
  • Должен быть указан первоисточник. В случае публикации в интернете Вы должны разместить следующий код гиперссылки без изменений:
  • Запрещается коммерческое использование материалов, взятых с блога "Интернет-трейдинг на форекс / forex". Доступ к ним должен быть свободным, без взимания какой-либо платы, без обязательной регистрации и/или заполнения опросного листа (анкеты) и т.д.

В случае выполнения данных условий не требуется согласия автора блога "Интернет-трейдинг на форекс / forex" на размещение статьи "Как ограничить количество одновременно открытых позиций/отложенных ордеров" на Вашем сайте.

Журнал FOREX MAGAZINE:



Архив номеров FOREX MAGAZINE
Котировки Forex:

Счетчики:

Авторские права © 2005-2006 Андрей Ведихин

Условия использования материалов блога "Интернет-трейдинг на форекс / forex"

Контакты с автором:


Движок сайта:
Movable Type 5.04