Полезные функции и др. в помощь разработчику экспертов

Хранилище собственных творений: индикаторы, скрипты, советники, в общем, все, на что муза вдохновила. Так же полезное ПО, взятое из открытых источников в Интернет.
Бонус за сообщение 0.4$
Ответственный Модератор - Рэндом

Полезные функции и др. в помощь разработчику экспертов

Сообщение Haos » 31 мар 2015, 16:01

Функция возвращает максимальный размер лота из открытых позиций. Сторонние ресурсы (переменные и т.п.) не используются.
Код: выделить все
/*
Описание : Возвращает максимальный размер лота из открытых позиций           Параметры:                                                               
//|    sy - наименование инструмента   (""   - любой символ,                   
//|                                     "0" - текущий символ)                 
//|    op - операция                   (-1   - любая позиция)                 
//|    mn - MagicNumber                (-1   - любой магик)                   
*/
double GetMaxLotFromOpenPos(string sy, int op, int mn)
{
   double l = 0;
   int    i, k = OrdersTotal();

   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)
                  {
                     if(l < OrderLots()) l = OrderLots();
                  }
               }
            }
         }
      }
   }
return(l);
}
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Полезные функции и др. в помощь разработчику экспертов

Сообщение Haos » 31 мар 2015, 16:03

Функция возвращает сумму лотов открытых позиций. Сторонние ресурсы (переменные и т.п.) не используются.
Код: выделить все
double GetAmountLotFromOpenPos(string sy, int op, int mn)
{
/*
Описание : Возвращает сумму лотов открытых позиций                       
Параметры:                                                               
sy - наименование инструмента   (""   - любой символ,                   
                                "0" - текущий символ)                 
op - операция                   (-1   - любая позиция)                 
mn - MagicNumber                (-1   - любой магик)                   
*/
   double l = 0;
   int    i, k = OrdersTotal();

   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)
                  {
                     l += OrderLots();
                  }
               }
            }
         }
      }
   }
return(l);
}
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Полезные функции и др. в помощь разработчику экспертов

Сообщение Haos » 09 июн 2015, 18:33

Состряпал :hi_hi_hi: функцию для открытия позиций. MQL5. Хорошо бы услышать дополнения и замечания, т.к. на 5-ку только перехожу. Осознаю, что нет обработки возможных ошибок в функции, но, как обычно, всегда спешишь и делаешь главное, а остальное на потом. :-):
В качестве указания типа торговой операции выбрал просто "BUY" - покупка или "SELL" - продажа.
Код: выделить все
void OpenPosition(string sy, string op, double ll, double sl, double tp, long mn, ulong sli, string co)
{
/*
   Описание: функция открывает позицию по рыночной цене
   
   sy - имя торгового инструмента ("0"  - текущий символ)
   op - торговая операция ("BUY" - покупка; "SELL" - продажа)
   ll - размер лота сделки
   sl - уровень СЛ
   tp - уровень ТП
   mn - Magic Number
   sli - проскальзывание (пнт.)
   co - комментарий
*/
   MqlTradeRequest   trReq; //объявляем структуру типа MqlTradeRequest для формирования запроса
   MqlTradeResult    trRes; //в этой структуре будет ответ сервера на запрос
   MqlTick           trTick;   //Здесь будут храниться цены последнего пришедшего тика
   double  Ask, Bid;
   int      dg;
   
   if(sy == "0") sy = _Symbol;
   dg = (int) SymbolInfoInteger(sy, SYMBOL_DIGITS);
   
   SymbolInfoTick(sy, trTick);   //заполняем структуру trTick последними ценами текущего символа.
   Ask = trTick.ask;             //Обновляем переменные Ask и Bid для дальнейшего использования
   Bid = trTick.bid;
     
   //далее заполняеем все НЕОБХОДИМЫЕ поля структуры запроса
   trReq.action = TRADE_ACTION_DEAL; // Установить торговый ордер на немедленное совершение сделки
                             // с указанными параметрами (поставить рыночный ордер)
   trReq.symbol      = sy;
   trReq.volume      = NormalizeDouble(ll, 2); // размер лота
   trReq.sl          = NormalizeDouble(sl, dg);
   trReq.tp          = NormalizeDouble(tp, dg);
   trReq.deviation = sli;//проскальзывание в пунктах
   if(op == "BUY")
   {
      trReq.type  = ORDER_TYPE_BUY;
      trReq.price = NormalizeDouble(Ask, dg);//Цена, при достижении которой ордер должен быть исполнен.                                 
   }
   else if(op == "SELL")
   {
      trReq.type  = ORDER_TYPE_SELL;
      trReq.price = NormalizeDouble(Bid, dg);
   }
   trReq.type_filling = ORDER_FILLING_FOK;//Указываем как исполнять ордер. 
   //Сделка может быть совершена исключительно в указанном объеме и по цене равной или лучше указанной в ордере.
   trReq.comment  = co;  //комментарий ордера
   trReq.magic    = mn;    //магическое число ордера   
   
   ResetLastError();//обнуляем код последней ошибки
   if(OrderSend(trReq, trRes))   //отправляем запрос на открытие позиции. При этом проверяем
                                          //успешно ли прошла отправка запроса
     {
      // Если сервер принял ордер то смортрим на результат
      Print("Код результата операции - ", trRes.retcode);
     }
   else
     {
      //Сервер не принял ордер в нем есть ошибки, выводим их в журнал
      Print("Код результата операции - ", trRes.retcode);
      Print("Ошибка открытия ордера = ",GetLastError());
     }                                                                                             
}

Пример строки использования ф-ии в эксперте (продажа EURUSD 0.1 лотом, без СЛ и ТП, мэджик - 77777, проскальзывание - 2 пнт., без комментариев):
Код: выделить все
OpenPosition("EURUSD", "SELL", 0.1, 0, 0, 77777, 2, "");
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Полезные функции и др. в помощь разработчику экспертов

Сообщение Haos » 29 июн 2015, 18:52

Функция рассчитывает значение F2 (цифровой фильтр FATL)

Код: выделить все
double f_F2(int shi)
{
// shi - сдвиг относительно текущего бара назад
// функция рассчитывает значение F2 (цифровой фильтр FATL)
double   dblY = 0,
         dblMKF2[12];
int      i;
         
   dblMKF2[0]  = 0.478587904692;   dblMKF2[1]  = 0.379277117724;
   dblMKF2[2]  = 0.2209611454869;  dblMKF2[3]  = 0.0633622332562;
   dblMKF2[4]  = -0.0435124635048; dblMKF2[5]  = -0.0805484264105;
   dblMKF2[6]  = -0.0619243262733; dblMKF2[7]  = -0.02036290337871;
   dblMKF2[8]  = 0.01355720160666; dblMKF2[9]  = 0.02548332231989;
   dblMKF2[10] = 0.02464568413704; dblMKF2[11] = 0.000473510344313;
           
 for(i = 0; i <= 11; i++) dblY += Close[i + shi] * dblMKF2[i];

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

Полезные функции и др. в помощь разработчику экспертов

Сообщение Haos » 29 июн 2015, 18:53

Функция рассчитывает значение S2 (цифровой фильтр SATL)

Код: выделить все
double f_S2(int shi)
{
// функция рассчитывает значение S2 (цифровой фильтр SATL)
// shi - сдвиг относительно текущего бара назад
double   dblY = 0,
         dblMKS2[27];
int      i;
         
   dblMKS2[0]  = 0.1245623625238;      dblMKS2[1]  = 0.1225692825295;
   dblMKS2[2]  = 0.1186543785610;      dblMKS2[3]  = 0.1129532955802;
   dblMKS2[4]  = 0.1056655720289;      dblMKS2[5]  = 0.0970359372867;
   dblMKS2[6]  = 0.0873542022479;      dblMKS2[7]  = 0.0769300886028;
   dblMKS2[8]  = 0.0660913494946;      dblMKS2[9]  = 0.0551609571815;
   dblMKS2[10] = 0.0444472341891;      dblMKS2[11] = 0.0342350090749;
   dblMKS2[12] = 0.02476242962154;     dblMKS2[13] = 0.01623437391500;
   dblMKS2[14] = 0.00878866698955;     dblMKS2[15] = 0.002525462501680;
   dblMKS2[16] = -0.002520782458992;   dblMKS2[17] = -0.00636253842152;
   dblMKS2[18] = -0.00905025851659;    dblMKS2[19] = -0.01070097068904;
   dblMKS2[20] = -0.01141788111694;    dblMKS2[21] = -0.01138741568260;
   dblMKS2[22] = -0.01072852457424;    dblMKS2[23] = -0.00961748350852;
   dblMKS2[24] = -0.00822648900819;    dblMKS2[25] = -0.00669086955497;
   dblMKS2[26] = -0.01126738879688;                   
   
   for(i = 0; i <= 26; i++) dblY += Close[i + shi] * dblMKS2[i];

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

Полезные функции и др. в помощь разработчику экспертов

Сообщение Haos » 29 июн 2015, 18:54

Ф-ия определяет сигнал по пересечению F2 и S2 (на последнем закрытом баре)

Код: выделить все
string f_F2S2Syg()                 
/*
   19.06.2015 г.
   Ф-ия определяет сигнал по пересечению F2 и S2 (на последнем закрытом баре)
   возвращает "UP" если F2 пересек вверх S2
   возвращает "DN" если F2 пересек вниз  S2
   возвращает "NO" если нет пересечения
   Параметры:

*/
{
double   dblF2_1,   // значение F2 на предыдущем баре
         dblF2_2,   // значение F2 два бара назад
         dblS2_1,   // значение S2 на предыдущем баре
         dblS2_2;   // значение S2 два бара назад
 
   dblF2_1 = f_F2(1);
   dblF2_2 = f_F2(2);
   dblS2_1 = f_S2(1);
   dblS2_2 = f_S2(2);
   
   if(dblF2_2 < dblS2_2 && dblF2_1 > dblS2_1) return("UP");
   if(dblF2_2 > dblS2_2 && dblF2_1 < dblS2_1) return("DN");
   
return("NO");
}
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Полезные функции и др. в помощь разработчику экспертов

Сообщение Haos » 29 июн 2015, 19:23

Применение последних функций в эксперте (пример):

Код: выделить все
...
// количество открытых позиций, покупок и продаж:
   intBuys  = o.GetNumberOfPositions("0", OP_BUY,  intMagic); // кол-во покупок
   intSells = o.GetNumberOfPositions("0", OP_SELL, intMagic); // кол-во продаж
   strF2S2Syg = f_F2S2Syg(); // анализ на наличие сигнала на пересечение Фатла и Сатла
   if(strF2S2Syg == "UP") // если сигнал на покупку
   {
      if(intSells > 0)  o.ClosePositions("0", OP_SELL, intMagic); // если есть позиция (позиции) на продажу то закроем их
      if(intBuys == 0) // если нет покупки
      {
         if(intSL == 0) dblSL = 0; // если был задан СЛ нулевым, делаем ноль в качестве параметра для передачи в ф-ию
         else if(intSL > 0) dblSL  = Bid - intSL * Point; // если СЛ не нулевой - рассчитываем уровень СЛ
         if(intTP == 0) dblTP = 0; // аналогично для ТП
         else if(intTP > 0) dblTP  = Ask + intTP * Point;
         o.OpenPosition("0", OP_BUY,  dblLot, dblSL, dblTP, intMagic, ""); // открываем позицию на покупку
      }
   }
...
// аналогичный анализ, если сигнал strF2S2Syg = "DN"
...
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Полезные функции и др. в помощь разработчику экспертов

Сообщение Haos » 01 июл 2015, 17:30

Скрипт, для открытия позиции с учетом риска.
Задается:
1. Величина СЛ в пунктах
2. Риск в сделке в %
3. От баланса или средств этот процент будет рассчитываться
4. Направление сделки (покупка или продажа)
v-2.png

Если рассчитанный лот меньше минимального, сделка не открывается а выдается предупреждающее сообщение о недостатке средств и совет снизить СЛ (внести доп. средства самим догадаться можно :hi_hi_hi: ).

Участок кода, отвечающий за осуществляемые расчеты:
Код: выделить все
enum TradeDir
{
   Покупка = 1,     
   Продажа = 2,     
};

//*******************************************************************************************

enum enuDepo
{
   Баланса = 1,
   Средств = 2,
};

//*******************************************************************************************

input int      intSL = 100; // Величина СЛ (пнт.)
input double   dblR  = 1.0; // Риск в сделке (%):
input enuDepo  intDe = 1;   // Риск рассчитывать от
input TradeDir intTD = 1;   // Направление торговли

//*******************************************************************************************

void OnStart()
{
   clsOrders o;
   double   dblSL,
            dblLotMin,
            dblML = 0,   // макс. убыток в сделке
            dblLot;  // величина торгового лота
   int      intMagic = 20150701,
            intSpread;
           
   intSpread  = (int) MarketInfo(Symbol(), MODE_SPREAD);
   dblLotMin  = MarketInfo(Symbol(), MODE_MINLOT);
   if(intDe == 1)       dblML = NormalizeDouble(AccountBalance()  * dblR / 100, 2);
   else if(intDe == 2)  dblML = NormalizeDouble(AccountEquity()   * dblR / 100, 2);
   dblLot     = NormalizeDouble(dblML / (intSL + intSpread), 2);
   if(dblLot >= dblLotMin)
   {
      if(intTD == 1) // покупка
      {
         dblSL  = Bid - intSL * Point;
         o.OpenPosition("0", OP_BUY,  dblLot, dblSL, 0, intMagic, "");
      } 
      else if(intTD == 2)  // продажа
      {
         dblSL  = Ask + intSL * Point;
         o.OpenPosition("0", OP_SELL,  dblLot, dblSL, 0, intMagic, "");
      }
      Comment( "\n", "Максимальный убыток в сделке: ",  DoubleToStr(dblML, 2),
               "\n", "Величина торговоло лота: ",       DoubleToStr(dblLot, 2));
   }
   else if(dblLot < dblLotMin)
   {
      Comment( "\n", "Недостаточно средств! Уменьшите SL");
   }
}
Вложения
SC-Trade&MM_v-2.ex4
(17.43 KB) Скачиваний: 39
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Полезные функции и др. в помощь разработчику экспертов

Сообщение Haos » 03 июл 2015, 19:15

Код подредактировал и выложу в ближайшее время новую версию. Суть в том, что стоимость пункта у валютных пар рассчитывается по следующему алгоритму:
Цена пункта по валютным парам рассчитывается, исходя из текущего курса валютной пары.
Ниже приведены формулы для расчёта стоимости пункта по валютным парам:
Расчёт стоимости для 1 пункта (1 pips):
1. XXX/USD
c.п. = 1 * (объём сделки)
2. USD/XXX
c.п. = 1/(USD/XXX) * (объём сделки)
Для USD/JPY c.п. = 100/(USD/JPY) * (объём сделки)
3. AAA/BBB
c.п. =(AAA/USD)/ (AAA/BBB) * (объём сделки)

В процессе создания алгоритма я исходил из следующих соображений. Пусть
ML - максимальный убыток в сделке (у.е.);
SL - стоплосс;
spred - спред данного актива;
X - стоимость 1 пнт. (у.е.);
Тогда,
ML = X * (SL + spred) (1)
Из (1) видно, что стоимость 1 пнт. будет:
X = ML / (SL + spred) (2)

1) Для ***/USD:
X = 1 * Y, где
Y - объем сделки (то, что мы и ищем). =>
Y = ML / (SL + spred)

2) USD/***
Y = [ML / (SL + spred)] * (USD/***)
Для USD/JPY:
Y = [ML / (SL + spred)] * (USD/JPY) * (1 / 100)

3) AAA/BBB
Y = [ML / (SL + spred)] * [(AAA/BBB) / (AAA/USD)]
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Полезные функции и др. в помощь разработчику экспертов

Сообщение mfcoder » 03 июл 2015, 19:30

как-то запутанно..
я проще считаю стоимость одного пункта при лоте 1 равна TICKVALUE / TICKSIZE * POINT
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.


Вернуться в Творческая мастерская

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

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

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

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

cron