Мультивалютный советник

MQL5 Эксперты

Работа завершена

Время выполнения 3 дня
Отзыв от исполнителя
Рад помочь!

Техническое задание

Советник должен использовать для торговли десять валютных пар. Внутри каждой валютной пары торгуют девять экранов или так называемых "карт". Набор позиций осуществляется сеткой. Для этого советника необходима хеджинговая система учета ордеров. Также хочу отметить, что этот советник существует на MQL4, правда он не мультивалютный. Поэтому, я смогу оказывать разработчику всевозможную поддержку. Это если коротко о самой идее.


Рассмотрим настройки карт на примере. В примере, для простоты, я рассматриваю только три карты. Настройку сдвига никогда не использовал. Только таймфрейм, период, количество сделок в сетке, а также идентификатор сделки. Настройки лотажности. Стоп лосс, тейк профит, а также трейлинг стоп в советнике не используется.

sinput string Performance№0 = "Настройка риск-менеджмента";
extern double LotsForEquity = 0.01;
extern int    Equity        = 1000;
extern int    Assets        = 10;
extern int    Trades№1      = 5;
extern int    Trades№2      = 10;
extern int    Trades№3      = 20;
extern int    Slippage      = 5;

sinput string Performance№1 = "Настройка 1-й карты";
extern int    TimeFrame№1   = 1;
extern int    Period1      = 50;
extern int    Magic№1       = 100;

sinput string Performance№2 = "Настройка 2-й карты";
extern int    TimeFrame№2   = 1;
extern int    Period2      = 100;
extern int    Magic№2       = 200;

sinput string Performance№3 = "Настройка 3-й карты";
extern int    TimeFrame№3   = 1;
extern int    Period3      = 200;
extern int    Magic№3       = 300;

Технический анализ советника построен на Bollinger Bands - открытие и закрытие сделок, Average True Range - используется для динамического шага сетки.

   Average№1 = iBands (Symbol(), TimeFrame№1, Period1, 2.0, 0, 0, MODE_MAIN, 0);   
   Ressist№1 = iBands (Symbol(), TimeFrame№1, Period1, 2.0, 0, 0, MODE_UPPER, 0); 
   Support№1 = iBands (Symbol(), TimeFrame№1, Period1, 2.0, 0, 0, MODE_LOWER, 0);   

   Average№2 = iBands (Symbol(), TimeFrame№2, Period2, 2.0, 0, 0, MODE_MAIN, 0);   
   Ressist№2 = iBands (Symbol(), TimeFrame№2, Period2, 2.0, 0, 0, MODE_UPPER, 0);
   Support№2 = iBands (Symbol(), TimeFrame№2, Period2, 2.0, 0, 0, MODE_LOWER, 0);   

   Average№3 = iBands (Symbol(), TimeFrame№3, Period3, 2.0, 0, 0, MODE_MAIN, 0);   
   Ressist№3 = iBands (Symbol(), TimeFrame№3, Period3, 2.0, 0, 0, MODE_UPPER, 0);   
   Support№3 = iBands (Symbol(), TimeFrame№3, Period3, 2.0, 0, 0, MODE_LOWER, 0);  
   Step№1 = NormalizeDouble (iATR (Symbol(), TimeFrame№1, Period1, 0)*Sign, 0);
   Step№2 = NormalizeDouble (iATR (Symbol(), TimeFrame№2, Period2, 0)*Sign, 0); 
   Step№3 = NormalizeDouble (iATR (Symbol(), TimeFrame№3, Period3, 0)*Sign, 0); 

Также стоит пояснить еще одну переменную.

   Sign = MathPow (10.0, Digits);  

Итак, открытие первой сделки и последующая работа советника. Обращаю внимание на проверку спреда, сопоставление его с шагом перед открытием и закрытием сделок. Это своего рода защита от ночной ликвидности, а также от системного риска, насколько это возможно. Обращаю внимание на сетку, она разбрасывается при движении от последней цены открытия сделки вверх и вниз. Обращаю внимание на то, что сетка второй карты может расширяться по количеству при открытых противоположных позициях на первой карте. Аналогично дело обстоит и с третьей картой. 

   if (spread <= Step№1 && CountBuy№1() + CountSell№1() == 0 && Ask < Support№1 && Average№1 > 0)
   {
      if (OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "", Magic№1, 0, Blue) < 1)
         Print("Не удалось открыть ордер на покупку!");   
   }
      
   if (spread <= Step№1 && CountBuy№1() + CountSell№1() == 0 && Bid > Ressist№1 && Average№1 > 0)
   {
      if (OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, "", Magic№1, 0, Red) < 1)
         Print("Не удалось открыть ордер на продажу!");      
   }    
   
   if (spread <= Step№1 && CountBuy№1() >= 1 && CountBuy№1() < Trades№1)
   {
      price = FindLastBuyPrice№1();
      if ((price - Ask) >= Step№1*Point || (Ask - price) >= Step№1*Point)
      {
         if (OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "", Magic№1, 0, Blue) < 1)
            Print("Не удалось открыть ордер на продажу!");
      }
   }       
   
   if (spread <= Step№1 && CountBuy№1() >= 1 && Bid > Ressist№1 && Average№1 > 0)
   {
      CloseAll№1();
   }    
   
   if (spread <= Step№1 && CountSell№1() >= 1 && CountSell№1() < Trades№1)
   {
      price = FindLastSellPrice№1();
      if ((Bid - price) >= Step№1*Point || (price - Bid) >= Step№1*Point)
      {
         if (OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, "", Magic№1, 0, Red) < 1)
            Print("Не удалось открыть ордер на продажу!");
      } 
   }      
   
   if (spread <= Step№1 && CountSell№1() >= 1 && Ask < Support№1 && Average№1 > 0)
   {
      CloseAll№1();
   } 
   
   if (spread <= Step№2 && CountBuy№2() + CountSell№2() == 0 && Ask < Support№2 && Average№2 > 0)
   {
      if (OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "", Magic№2, 0, Blue) < 1)
         Print("Не удалось открыть ордер на покупку!");   
   }   
   
   if (spread <= Step№2 && CountBuy№2() + CountSell№2() == 0 && Bid > Ressist№2 && Average№2 > 0)
   {
      if (OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, "", Magic№2, 0, Red) < 1)
         Print("Не удалось открыть ордер на продажу!");      
   }  
   
   if (spread <= Step№2 && CountBuy№2() >= 1 && CountBuy№2() < Trades№2 + CountSell№1())
   {
      price = FindLastBuyPrice№2();
      if ((price - Ask) >= Step№2*Point || (Ask - price) >= Step№2*Point)
      {
         if (OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "", Magic№2, 0, Blue) < 1)
            Print("Не удалось открыть ордер на продажу!");
      }
   }      
   
   if (spread <= Step№2 && CountBuy№2() >= 1 && Bid > Ressist№2 && Average№2 > 0)
   {
      CloseAll№2();
   }
   
   if (spread <= Step№2 && CountSell№2() >= 1 && CountSell№2() < Trades№2 + CountBuy№1())
   {
      price = FindLastSellPrice№2();
      if ((Bid - price) >= Step№2*Point || (price - Bid) >= Step№2*Point)
      {
         if (OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, "", Magic№2, 0, Red) < 1)
            Print("Не удалось открыть ордер на продажу!");
      } 
   }     
   
   if (spread <= Step№2 && CountSell№2() >= 1 && Ask < Support№2 && Average№2 > 0)
   {
      CloseAll№2();
   }   
   
   if (spread <= Step№3 && CountBuy№3() + CountSell№3() == 0 && Ask < Support№3 && Average№3 > 0)
   {
      if (OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "", Magic№3, 0, Blue) < 1)
         Print("Не удалось открыть ордер на покупку!");   
   }   
   
   if (spread <= Step№3 && CountBuy№3() + CountSell№3() == 0 && Bid > Ressist№3 && Average№3 > 0)
   {
      if (OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, "", Magic№3, 0, Red) < 1)
         Print("Не удалось открыть ордер на продажу!");      
   }

   if (spread <= Step№3 && CountBuy№3() >= 1 && CountBuy№3() < Trades№3 + CountSell№2())
   {
      price = FindLastBuyPrice№3();
      if ((price - Ask) >= Step№3*Point || (Ask - price) >= Step№3*Point)
      {
         if (OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "", Magic№3, 0, Blue) < 1)
            Print("Не удалось открыть ордер на продажу!");
      }
   }   
   
   if (spread <= Step№3 && CountBuy№3() >= 1 && Bid > Ressist№3 && Average№3 > 0)
   {
      CloseAll№3();
   }

   if (spread <= Step№3 && CountSell№3() >= 1 && CountSell№3() < Trades№3 + CountBuy№2())
   {
      price = FindLastSellPrice№3();
      if ((Bid - price) >= Step№3*Point || (price - Bid) >= Step№3*Point)
      {
         if (OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, "", Magic№3, 0, Red) < 1)
            Print("Не удалось открыть ордер на продажу!");
      } 
   }
   
   if (spread <= Step№3 && CountSell№3() >= 1 && Ask < Support№3 && Average№3 > 0)
   {
      CloseAll№3();
   }

Также покажу функции подсчета ордеров на покупку и продажу для одной карты, функцию закрытия всех сделок для одной карты, функции для определения последней цены открытия сделки на покупку и продажу для одной карты. Для каждой карты эти функции аналогичны, но они индивидуальны для каждой карты.

//+------------------------------------------------------------------+
int CountBuy№1()
{
   int count = 0;
   for (int trade = OrdersTotal()-1; trade >=0; trade--)
   {
      if (OrderSelect(trade, SELECT_BY_POS, MODE_TRADES) == true)
      {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic№1 && OrderType() == OP_BUY)
            count++;
      }
   }
   return (count);
}
//+------------------------------------------------------------------+
int CountSell№1()
{
   int count = 0;
   for (int trade = OrdersTotal()-1; trade >=0; trade--)
   {
      if (OrderSelect(trade, SELECT_BY_POS, MODE_TRADES) == true)
      {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic№1 && OrderType() == OP_SELL)
            count++;
      }
   }
   return (count);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void CloseAll№1()
{
   for (int i = OrdersTotal()-1; i>=0; i--)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic№1)
         {
            if (OrderType() == OP_BUY)
            {
               if (!OrderClose(OrderTicket(), OrderLots(), Bid, Slippage))
                  Print("Не удалось закрыть ордер на покупку!");
            }
            if (OrderType() == OP_SELL) 
            {
               if (!OrderClose(OrderTicket(), OrderLots(), Ask, Slippage))
                  Print("Не удалось закрыть ордер на продажу!");
               
            }
         }
      }
   }
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
double FindLastBuyPrice№1()
{
   int oldticket, ticket = 0;
   double oldopenprice =0;
   
   for (int cnt = OrdersTotal()-1; cnt>=0; cnt--)
   {
      if (OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES))
      {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic№1 && OrderType() == OP_BUY)
         {
            oldticket = OrderTicket();
            if (oldticket > ticket)
            {
               ticket = oldticket;
               oldopenprice = OrderOpenPrice();
            }
         }
      }
   }
   return (oldopenprice);
}
//+------------------------------------------------------------------+
double FindLastSellPrice№1()
{
   int oldticket, ticket = 0;
   double oldopenprice =0;
   
   for (int cnt = OrdersTotal()-1; cnt>=0; cnt--)
   {
      if (OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES))
      {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic№1 && OrderType() == OP_SELL)
         {
            oldticket = OrderTicket();
            if (oldticket > ticket)
            {
               ticket = oldticket;
               oldopenprice = OrderOpenPrice();
            }
         }
      }
   }
   return (oldopenprice);
}
//+------------------------------------------------------------------+

Функция подсчета лотажности.

//+------------------------------------------------------------------+
double GetLots()
{
   double clots = AccountEquity() / Equity / Assets * LotsForEquity;
   clots = MathMax (clots, MarketInfo (Symbol(), MODE_MINLOT));
   clots = MathMin (clots, MarketInfo (Symbol(), MODE_MAXLOT));
   
   clots = NormalizeDouble (clots, 2);
   return(clots);
}
//+------------------------------------------------------------------+

Также хочется чтобы в этом советнике были функции которые требует Metaquotes при размещении советника к себе в магазин. А именно блок обработки ошибок с распечаткой информации в журнал. Также мне будут нужны исходные файлы кода. Это не для того чтобы сделать этот проект коммерческим, а для того чтобы он в первую очередь корректно работал. У меня некоторых этих функций нет. Нужно чтобы были. Ну вот пожалуй и все. Я впервые составляю техзадание на сайте Metaquotes, поэтому прошу отнестись с пониманием и терпением.

Откликнулись

1
Разработчик 1
Оценка
(5)
Проекты
3
0%
Арбитраж
19
0% / 100%
Просрочено
0
Свободен
2
Разработчик 2
Оценка
(281)
Проекты
650
28%
Арбитраж
112
19% / 62%
Просрочено
318
49%
Свободен
3
Разработчик 3
Оценка
(473)
Проекты
1139
44%
Арбитраж
51
31% / 33%
Просрочено
501
44%
Свободен
4
Разработчик 4
Оценка
(68)
Проекты
111
26%
Арбитраж
17
6% / 71%
Просрочено
15
14%
Свободен
Опубликовал: 9 примеров
5
Разработчик 5
Оценка
(340)
Проекты
588
36%
Арбитраж
31
45% / 3%
Просрочено
16
3%
Свободен
Опубликовал: 13 примеров
6
Разработчик 6
Оценка
(106)
Проекты
189
46%
Арбитраж
34
24% / 41%
Просрочено
58
31%
Свободен
Опубликовал: 12 примеров

Информация о проекте

Бюджет
30 - 120 USD
Сроки выполнения
до 14 дн.