Как установить стоповую (BuyStop & SellStop) сетку

Программирование прибыли: от азов к секретам мастерства. Читайте, спрашивайте, делитесь опытом.
Бонус за сообщение 0.5$
Ответственный Модератор - Haos

Как установить стоповую (BuyStop & SellStop) сетку

Сообщение Haos » 15 сен 2017, 13:02

Часто в сеточной торговле возникает задача установки стоповой сетки (речь идет о том, что выше текущей цены устанавливаются ордера типа BuyStop, а ниже текущей цены выставляются ордера типа SellStop). Установка такого вида сетки подразумевают торговую ситуацию, когда цена должна пройти значительное в бычьем или медвежьем направлении расстояние, но в каком конкретно - не известно (такая ситуация может возникать перед выходом важных новостей, особенно, когда предшествующего тренда толком и нет).
В качестве задаваемых параметров обычно всегда присутствуют следующие:
1. Шаг сетки (пнт.)
2. Кол-во ордеров сетки
3. Отступ от цены до первых ордеров сетки (пнт.)
4. Величина SL (пнт.)
5. Величина TP (пнт.)
Пункт 3 означает, что первым считается ордер ближайший к текущей цене, а таких ордеров два по месту расположения - выше цены и ниже цены.
Рассмотрим случай, когда не подразумевается увеличение (уменьшение) размера лота в зависимости от уровня сетки.
Удобно создать функцию, которую потом можно будет каждый раз для новой разработки кода просто вставлять в код, а не писать в очередной раз (как много раз указывалось для правильного стиля программирования).
Код такой функции приведен ниже. Однако для её работы требуются ряд уже написанных функций стандартных операций (рассмотрим позже).
Код: выделить все
void f_SetStopGrid(double q, int n, int de, int sl, int tp, int ot, int si)
{
   double dblSL, dblTP, dblY;
   int int_Pos = f_GetNumberOfPositions("0", -1, intMagic);
   int int_Ord = f_GetNumberOfOrders("0", -1, intMagic);
   if(int_Pos ==0 && int_Ord == 0)
   {
      for(int i = 1; i <= n; i++)
      {
         // установка байстоп ордеров:
         dblY = NormalizeDouble(Ask + (ot + de * (i - 1)) * _Point, _Digits);
         dblSL = f_SL("0", sl, OP_BUYSTOP, dblY);
         dblTP = f_TP("0", tp, OP_BUYSTOP, dblY);
         f_SetOrder("0", OP_BUYSTOP, q, dblY, dblSL, dblTP, si, intMagic, "", 0); 
         // установка селлстоп ордеров:
         dblY = NormalizeDouble(Bid - (ot + de * (i - 1)) * _Point, _Digits);
         dblSL = f_SL("0", sl, OP_SELLSTOP, dblY);
         dblTP = f_TP("0", tp, OP_SELLSTOP, dblY);         
         f_SetOrder("0", OP_SELLSTOP, q, dblY, dblSL, dblTP, si, intMagic, "", 0);         
      }
   }
}

В качестве параметров в функцию f_SetStopGrid() передаются:
q - Размер торгового лота;
n - Кол-во ордеров сетки;
de - Шаг сетки (пнт.);
sl - Величина SL (пнт.) {если 0, то SL не выставляется};
tp - Величина TP (пнт.) {если 0, то TP не выставляется};
ot - Отступ от цены до 1-ых ордеров сетки (пнт.);
si - Проскальзывание цены (пнт.);
Также используется переменная intMagic типа int, которая должна (может) быть задана в качестве внешней переменной или глобальной переменной на уровне данного кода.
Далее в необходимом месте кода происходит вызов данной функции:
Код: выделить все
f_SetStopGrid(dblQ, intN, intDe, intSL, intTP, intOt, intSI);
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Re: Как установить стоповую (BuyStop & SellStop) сетку

Сообщение Haos » 15 сен 2017, 13:06

Теперь рассмотрим используемые в коде функции другие функции, на которые происходит ссылка:
1. f_GetNumberOfPositions() - данная функция рассматривается в статье: Как определить количество открытых позиций в MQL4
2. f_GetNumberOfOrders() - данная функция рассматривается в статье Как определить количество установленных ордеров
3. f_SL() - данная функция рассматривается в статье Формализация расчета уровней СЛ и ТП в коде
4. f_TP() - данная функция рассматривается в статье Формализация расчета уровней СЛ и ТП в коде
5. f_SetOrder() - Как установить ордер
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Как установить стоповую (BuyStop & SellStop) сетку

Сообщение Haos » 22 янв 2018, 18:28

Функцию для установки стоповой сетки можно несколько скорректировать:
Код: выделить все
void f_SetStopGrid(double &Y[], int n, double pr, int sl, int tp, int de, int si, int mn)
{
/*
   Функция устанавливает стоповую сетку ордеров. Тип стоповой сетки определяется
   положением цены относительно рынка.
   Используются ф-ии: f_SL(), f_TP(), f_SetOrder()
   Параметры:
   Y[]   - массив объемов ордеров сетки
   n     - кол-во ордеров в сетке
   pr    - Уровень цены 1-го ордера сетки
   sl    - СЛ ордеров (пнт.)
   tp    - ТП ордеров (пнт.)
   de    - Шаг сетки (пнт.)
   si    - Проскальзывание цены (slippage) (пнт.)
   mn    - Идентификатор эксперта
*/
   int      int_ty = 0;
   double   dbl_Pr = 0,
            dbl_SL = 0,
            dbl_TP = 0;   
   double   dbl_Pr0 = NormalizeDouble(pr, Digits); // цена установки 1-го ордера
   
   if(dbl_Pr0 < Bid)       int_ty = 1;  // OP_SELLSTOP
   else if(dbl_Pr0 > Ask)  int_ty = 2;  // OP_BUYSTOP
   
   for(int i = 0; i < n; i++)
   {
      if(int_ty == 1) // Установка OP_SELLSTOP ордеров
      {
         // Цена установки селлстоп ордеров:
         dbl_Pr = NormalizeDouble(dbl_Pr0 - i * de * Point, Digits);
         // СЛ для OP_SELLSTOP ордеров:
         if(sl == 0) dbl_SL = 0;
         else { dbl_SL = f_SL("0", sl, OP_SELLSTOP, dbl_Pr);}
         // ТП для OP_SELLSTOP ордеров:
         if(tp == 0) dbl_TP = 0;
         else { dbl_TP = f_TP("0", tp, OP_SELLSTOP, dbl_Pr); }
         f_SetOrder("0", OP_SELLSTOP, Y[i], dbl_Pr, dbl_SL, dbl_TP, si, mn, "StopGridPP-v1", 0);     
      }
      if(int_ty == 2) // Установка OP_BUYSTOP ордеров:
      {     
         // Цена установки BUYSTOP ордеров:
         dbl_Pr = NormalizeDouble(dbl_Pr0 + i * de * Point, Digits);
         // СЛ для BUYSTOPT ордеров:
         if(sl == 0) dbl_SL = 0;
         else { dbl_SL = f_SL("0", sl, OP_BUYSTOP, dbl_Pr); }
         // ТП для BUYSTOPT ордеров:
         if(tp == 0) dbl_TP = 0;
         else { dbl_TP = f_TP("0", tp, OP_BUYSTOP, dbl_Pr); }         
         f_SetOrder("0", OP_BUYSTOP, Y[i], dbl_Pr, dbl_SL, dbl_TP, si, mn, "StopGridPP-v1", 0);
      }         
   }
   if(int_ty == 0) Alert("Цена установки сетки расположена слишком близко к рынку!");
}

В данной реализации количество открытых позиций и установленных ордеров оценивается в главной процедуре программы что более логично, а функцию осуществляет лишь установку сетки по заданным параметрам:
Y[] - массив объемов ордеров сетки
n - кол-во ордеров в сетке
pr - Уровень цены 1-го ордера сетки
sl - СЛ ордеров (пнт.)
tp - ТП ордеров (пнт.)
de - Шаг сетки (пнт.)
si - Проскальзывание цены (slippage) (пнт.)
mn - Идентификатор эксперта
Функция f_SetStopGrid() использует в своей работе функции: f_SL(), f_TP(), f_SetOrder(). Первые две (установка СЛ и ТП рассмотрены в статье Формализация расчета уровней СЛ и ТП в коде), а функция для установки ордера - f_SetOrder() в статье Как установить ордер).
Функция установки стоповой сетки устанавливает за один вызов одну сетку с одной стороны от цены. Это происходит путем анализа на положение текущей котировки актива относительно уровня цены 1-го ордера сетки. Т.е. если котировка актива ниже переданной в функцию цены для 1-го ордера сетки, то установится BUYSTOP сетка. Если котировка актива выше переданной в функцию цены для 1-го ордера сетки, то установится SELLSTOP сетка (см. участок кода функции):
Код: выделить все
...
double   dbl_Pr0 = NormalizeDouble(pr, Digits); // цена установки 1-го ордера
   
   if(dbl_Pr0 < Bid)       int_ty = 1;  // OP_SELLSTOP
   else if(dbl_Pr0 > Ask)  int_ty = 2;  // OP_BUYSTOP
...

Таким образом, что установить обе сетки вокруг цены (BUYSTOP и SELLSTOP), функцию из основной процедуры программы нужно вызвать два раза.
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Как установить стоповую (BuyStop & SellStop) сетку

Сообщение Haos » 22 янв 2018, 18:34

По аналогии с вариантом установки стоповой сетки можно написать функцию для установки лимитной сетки:
Код: выделить все
void f_SetLimitGrid(double &Y[], int n, double pr, int sl, int tp, int de, int si, int mn)
{
/*
   Функция устанавливает лимитных ордеров сетку. Тип лимитных ордеров определяется положением
   цены относительно рынка (выше - селлимит, ниже - байлимит).
   Используются ф-ии: f_SL(), f_TP(), f_SetOrder()
   Параметры:
   Y[]   - массив объемов ордеров сетки
   pr    - Уровень цены 1-го ордера сетки
   sl    - СЛ ордеров (пнт.)
   tp    - ТП ордеров (пнт.)
   de    - Шаг сетки (пнт.)
   si    - Проскальзывание цены (slippage) (пнт.)
   mn    - Идентификатор эксперта
*/
   int      int_ty = 0;
   double   dbl_Pr = 0,
            dbl_SL = 0,
            dbl_TP = 0;   
   double   dbl_Pr0 = NormalizeDouble(pr, Digits); // цена установки 1-го ордера
   
   if(dbl_Pr0 < Bid)       int_ty = 1;  // OP_BUYLIMIT
   else if(dbl_Pr0 > Ask)  int_ty = 2;  // SELLIMIT

   for(int i = 0; i < n; i++)
   {
      if(int_ty == 1) // Установка OP_BUYLIMIT ордеров
      {
         // Цена установки байлимит ордеров:
         dbl_Pr = NormalizeDouble(dbl_Pr0 - i * de * Point, Digits);
         // СЛ для OP_BUYLIMIT ордеров:
         if(sl == 0) dbl_SL = 0;
         else { dbl_SL = NormalizeDouble(dbl_Pr - sl * Point, Digits); }
         // ТП для OP_BUYLIMIT ордеров:
         if(tp == 0) dbl_TP = 0;
         else { dbl_TP = NormalizeDouble(dbl_Pr + tp * Point, Digits); }
         f_SetOrder("0", OP_BUYLIMIT, Y[i], dbl_Pr, dbl_SL, dbl_TP, si, mn, "", 0);
      }
      if(int_ty == 2) // Установка OP_SELLIMIT ордеров:
      {     
         // Цена установки селлимит ордеров:
         dbl_Pr = NormalizeDouble(dbl_Pr0 + i * de * Point, Digits);
         if(sl == 0) dbl_SL = 0;
         else { dbl_SL = NormalizeDouble(dbl_Pr + sl * Point, Digits); }
         // ТП для OP_SELLIMIT ордеров:
         if(tp == 0) dbl_TP = 0;
         else { dbl_TP = NormalizeDouble(dbl_Pr - tp * Point, Digits); }         
         f_SetOrder("0", OP_SELLLIMIT, Y[i], dbl_Pr, dbl_SL, dbl_TP, si, mn, "", 0);
      }     
   }
   if(int_ty == 0) Alert("Цена установки сетки расположена слишком близко к рынку!");   
}

Те же самые параметры передаются в функцию f_SetLimitGrid() и те же функции использует она в своей работе: f_SL(), f_TP(), f_SetOrder(). Данная функция также анализирует положение цены котировки актива относительно переданного уровня цены для 1-го уровня сетки и выставляет в зависимости от этого положения тип сетки или BUYLIMIT или SELLIMIT.
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Как установить стоповую (BuyStop & SellStop) сетку

Сообщение Haos » 22 янв 2018, 18:36

Таким образом, рассмотренные функции для установки сеток позволяют в программах одной строкой, фактически, оформлять процедуру установки. В код программы просто вставляется необходимая функция для стоповой или лимитной сетки и сопутствующие ей три упомянутые выше функции для СЛ, ТП и установки ордера.
Однако, для полноты картины нам нужно разобраться как формируется массив торговых объемом сетки Y[ ], но этому нужно посвятить отдельную статью.
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.


Вернуться в MQL – теория и практика

Кто сейчас на форуме?

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 35

Права доступа к форуму

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

cron