Скрипт по методике торговли "Мажорный Ва-Банк" (v. 2)

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

Скрипт по методике торговли "Мажорный Ва-Банк" (v. 2)

Сообщение Haos » 15 дек 2021, 18:08

У нас уже есть созданный чуть раньше скрипт по торговой методике "Мажорный Ва-банк", который производит все необходимые расчеты по семи валютным парам на закрытии недельной свечи с целью выявления той свечи, что прошла наибольшее расстояние в пунктах от цены открытия до закрытия (в скрипте используется расстояние от цены закрытия до открытия для удобства). Однако, данный скрипт не открывал торговой сделки в соответствие с описанной методики "Мажорный Ва-банк".

Сделаем торговую версию скрипта, т.е. чтобы скрипт открывал сделку в нужном направлении, а не трейдеру приходилось это делать вручную.

Прежде всего во внешних параметрах нам понадобятся:
Код: выделить все
input double dblQ    = 0.01;  // Размер торгового лота
input int    intTP   = 500;   // TP
input int    intSL   = 500;   // SL
input int    intSI     = 10;  // Проскальзывание цены (пнт.)

- размер торгового лота (по умолчанию выставим минимальный объем);
- величина ТП в пунктах;
- величина СЛ в пунктах;
- величина проскальзывания цены в пунктах.

В функции OnStart() нам нужно будет ввести несколько переменных:
Код: выделить все
   int intDir = -1;     // Направление торговли (OP_BUY -> 0, OP_SELL - > 1)
   int intPos = 0;      // Количество позиций, открытых данным скриптом
   string strSym = "";  // пара с наибольшим проходом за неделю
   double dblSL = 0;
   double dblTP = 0;

intDir - переменная типа int соответствующая направлению торговли (0 - покупка, 1- продажа);
intPos - количество позиций, открытых данным скриптом. Здесь нужно уточнить, что в этой версии скрипта появляется мэджик для присвоения его сделкам, открытым данным скриптом, чтобы отличать их от всех остальных сделок, открытых по нужному активу;
strSym - пара с наибольшим проходом за неделю;
А также переменные dblSL и dblTP типа double для расчета уровней цены СЛ и ТП.

Мы будем также пользоваться давно разработанными функциями:

1. Для получения количества открытых позиций:
Код: выделить все
int f_GetNumberOfPositions(string sy = "", int op = -1, int mn = -1)
{
/*
   Версия   : 28.10.2015 г.                                                 
   Описание : Возвращает количество позиций (покупок или продаж или тех и других вместе)
   Сторонних ресурсов не использует           
   Параметры:                                                               
   sy - наименование инструмента   (""   - любой символ, "0"- текущий символ)             
   op - операция {-1 любая; OP_BUY; OP_SELL}
   mn - MagicNumber  (-1 - любой маджик)               
*/

  int i, k = OrdersTotal(), kp = 0;
  if(k == 0) return(0); // нет позиций вообще никаких
 
  if(sy == "0") sy = Symbol();
  for(i = 0; i < k; i++)
  {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
      if(OrderSymbol() == sy || sy == "")
      {
        if(OrderType() == OP_BUY || OrderType() == OP_SELL)
        {
          if(op < 0 || OrderType() == op)
          {
            if(mn < 0 || OrderMagicNumber() == mn) kp++;
          }
        }
      }
    }
  }
return(kp);
}


2. Для открытия позиций:
Код: выделить все
void f_OpenPosition(string sy, int op, double ll, double sl, double tp, int mn, int si, string co)
{
/*
   Версия   : 13.09.2015                                                     
   Описание : Открывает позицию по рыночной цене   
   Сторонних ресурсов не использует!!!                       
   Параметры:                                                               
   sy - наименование инструмента   ("0" - текущий символ)         
   op - операция {OP_BUY; OP_SELL}                                                           
   ll - лот                                                               
   sl - уровень стоп (0)                                                     
   tp - уровень тейк  (0)                                                   
   mn - MagicNumber
   si - проскальзывание (slippage) (пнт.)                                                       
   co - комментарий ("" - нет комментария)                                                       
*/
   double   pp;
   int      int_Tic     = 0;
   int      int_Try     = 5;              // Количество торговых попыток
   bool     bol_Sou     = true;           // Использовать звуковой сигнал
   string   str_Suc     = "ok.wav";       // Звук успеха
   string   str_Err     = "timeout.wav";  // Звук ошибки
   bool     bol_Sin     = true;           // Использовать значок открытия сделки?
   color    clOpen      = clrNONE,
            clOpenBuy   = LightBlue,      // Цвет значка открытия покупки
            clOpenSell  = LightCoral;     // Цвет значка открытия продажи
   double   dbl_Ask,
            dbl_Bid;
   
   if(sy == "0") sy = Symbol();   
   int int_Dig  = (int) MarketInfo(sy, MODE_DIGITS);
   
   for(int i = 1; i <= int_Try; i++)
   {
      if(!IsTesting() && (!IsExpertEnabled() || IsStopped()))
      {
         Print("OpenPosition(): Остановка работы функции");
         break;
      }
      while(!IsTradeAllowed()) Sleep(5000);
      RefreshRates();
      if(op == OP_BUY)
      {
         dbl_Ask  = MarketInfo(sy, MODE_ASK);
         pp = dbl_Ask;
         if(bol_Sin) clOpen = clOpenBuy;
      }
      else if(op == OP_SELL)
      {
         dbl_Bid  = MarketInfo(sy, MODE_BID);
         pp = dbl_Bid;
         if(bol_Sin) clOpen = clOpenSell;
      }
      pp = NormalizeDouble(pp, int_Dig);
      int_Tic = OrderSend(sy, op, ll, pp, si, sl, tp, co, mn, 0, clOpen);
      if(int_Tic > 0)
      {
         if(bol_Sou) PlaySound(str_Suc);
         Print("Функция OrderSend успешно выполнена");
         break;
      }
      else if(int_Tic < 0)
      {
         if(bol_Sou) PlaySound(str_Err);
         Print("OrderSend завершилась с ошибкой #", GetLastError());
      }
   }
}


3. Для расчета уровня ТП:
Код: выделить все
double f_TP(string sy, int tp, int ty, double pr)
{
/*
   Описание:
   Функция осуществляет расчет уровня ТП
   Параметры:
   sy - наименование инструмента   ("0" - текущий символ)
   tp - величина ТП
   ty - тип ордера
   pr - цена входа или уровень входа (установки ордера)
*/
   if(sy == "0") sy = Symbol();
   int      int_Dig  = (int) MarketInfo(sy, MODE_DIGITS);
   double   dbl_Poi  = MarketInfo(sy, MODE_POINT);
     
   if(tp == 0) return(0);
   if(ty == OP_BUY || ty == OP_BUYLIMIT || ty == OP_BUYSTOP)
   {
      return(NormalizeDouble(pr + tp * dbl_Poi, int_Dig));
   }
   else if(ty == OP_SELL || ty == OP_SELLLIMIT || ty == OP_SELLSTOP)
   {
      return(NormalizeDouble(pr - tp * dbl_Poi, int_Dig));   
   }

return(-1);
}


4. Для расчета уровня СЛ:
Код: выделить все
double f_SL(string sy, int sl, int ty, double pr)
{
/*
   Описание:
   Функция осуществляет расчет уровня СЛ
   Параметры:
   sy - наименование инструмента   ("0" - текущий символ)
   sl - величина СЛ
   ty - тип ордера
   pr - цена входа или уровень входа (установки ордера)
*/
   if(sy == "0") sy = Symbol();
   int      int_Dig  = (int) MarketInfo(sy, MODE_DIGITS);
   double   dbl_Poi  = MarketInfo(sy, MODE_POINT);
     
   if(sl == 0) return(0);
   if(ty == OP_BUY || ty == OP_BUYLIMIT || ty == OP_BUYSTOP)
   {
      return(NormalizeDouble(pr - sl * dbl_Poi, int_Dig));
   }
   else if(ty == OP_SELL || ty == OP_SELLLIMIT || ty == OP_SELLSTOP)
   {
      return(NormalizeDouble(pr + sl * dbl_Poi, int_Dig));   
   }

return(-1);
}


После нахождения индекса максимального элемента массива пройденных расстояний цены по семи валютным парам как в первой версии скрипта и фактического его значения, мы определяем направление торговли нашей позиции:
Код: выделить все
if(intYmax >= 0) { intDir = 1; } // будем продавать
else if(intYmax < 0) { intDir = 0; } // будем покупать

Наименование символа по которму будет совершать сделку мы также получаем как в первой версии скрипта:
Код: выделить все
strSym = strMSym[intJmax];


Далее, когда все необходимые значения параметров мы получили, будем осуществлять подготовку к отрытию позиции:
Вначале получаем количество уже открытых позиций, т.е. не открыли ли мы уже позицию ранее и она не закрылась. Тогда нам не нужно открывать новую позицию.
Код: выделить все
intPos = f_GetNumberOfPositions(strSym, -1, intMagic);


Далее, работаем только с условием, что сделок нет (еще не открыли):
Код: выделить все
if(intPos == 0) // Если нет сделок еще
{
      // RefreshRates();
      double dblAsk = MarketInfo(strSym, MODE_ASK);
      double dblBid = MarketInfo(strSym, MODE_BID);
      if(intDir == 0) // для покупки
      {
         dblSL = f_SL(strSym, intSL, intDir, dblBid);
         dblTP = f_TP(strSym, intTP, intDir, dblAsk);
      }
      else if(intDir == 1) // для продажи
      {
         dblSL = f_SL(strSym, intSL, intDir, dblAsk);
         dblTP = f_TP(strSym, intTP, intDir, dblBid);
      }
      f_OpenPosition(strSym, intDir, dblQ, dblSL, dblTP, intMagic, intSI, "");
}

Вначале получаем значения Ask и Bid по нужному нам торговому активу (валютной паре, по которой открываем позицию).
Код: выделить все
double dblAsk = MarketInfo(strSym, MODE_ASK);
double dblBid = MarketInfo(strSym, MODE_BID);

Далее расчитываем величины ТП и СЛ в зависимости от направления торговой позиции (их расчет разный для покупки и продажи).
Код: выделить все
if(intDir == 0) // для покупки
{
   dblSL = f_SL(strSym, intSL, intDir, dblBid);
   dblTP = f_TP(strSym, intTP, intDir, dblAsk);
}
else if(intDir == 1) // для продажи
{
   dblSL = f_SL(strSym, intSL, intDir, dblAsk);
   dblTP = f_TP(strSym, intTP, intDir, dblBid);
}

Наконец, открываем позицию:
Код: выделить все
f_OpenPosition(strSym, intDir, dblQ, dblSL, dblTP, intMagic, intSI, "");


В завершении выводим в левый верхний угол окна графика на котором мы запускаем скрипт, информацию также как и в первой версии скрипта:
Код: выделить все
   Comment( "\n", "Размер прошлой недельной свечи (пнт.): ",
            "\n", strMSym[0]," = ", intMDeY[0],
            "\n", strMSym[1]," = ", intMDeY[1],
            "\n", strMSym[2]," = ", intMDeY[2],
            "\n", strMSym[3]," = ", intMDeY[3],
            "\n", strMSym[4]," = ", intMDeY[4],
            "\n", strMSym[5]," = ", intMDeY[5],
            "\n", strMSym[6]," = ", intMDeY[6],
            "\n", "------------------------",
            "\n", "Ymax = ", intYmax,
            "\n", "Sym  = ", strSym);

Фактически, это справочная информация, информация для проверки. Сделка после выполнения скрипта открывается.
Ниже приведен скрин графика AUDUSD по которому открыта сделка после запуска скрипта (поскольку скрипт запущен в СР, то цена, само-собой, уже далеко ушла от уровня открытия недельной свечи).

Ва-банк в. 2.png

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

Скрипт по методике торговли "Мажорный Ва-Банк" (v. 2)

Сообщение Haos » 16 дек 2021, 10:01

Мы будет также пользоваться давно разработанными функциями:

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


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

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

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

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

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

cron