Перейти к содержанию

Обучение языку MQL4 под MetaTrader 4


Рекомендуемые сообщения

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Добрый день! Может кто подскажет кусочек кода в советник. Необходимо что бы советник сам находил последнюю накинутую в ручную  сетку Фибоначчи на графике. Затем от нее получить ценовые значения 0 и 100 уровня для дальнейшего расчета других уровней.  В последствии пропишу условие если цена касается уровня 100% - вход на бай. Тейк профит на 161 уровне. Столосс на уровень 80%. Советник получиться полуавтоматический. Вдруг может кто то видел подобную информацию по программированию графического объекта сетка фибо поделитесь пожалуйста.

Ссылка на сообщение
Поделиться на другие сайты

  • Ответов 6,8k
  • Создано
  • Последний ответ

Популярные авторы

Популярные авторы

Популярные посты

Смотрим видео-уроки, изучаем MQL:       Скачать видеокурс «MQL программирование. Как самому написать форекс советник/ индикатор/ скрипт»   P.S. Тема про Обучение MQ

Перейти

Циклы цикл for Иногда необходимо повторять одно и то же действие несколько раз подряд. Для этого используют циклы. К примеру, мы хотим проанализировать последние 10 баров и выяснить наименьшую цен

Перейти

Речь идет о том, что не будет значимых нововведений. А только баги периодически будут править. А вот все новое мол - в МТ5. Когда они вживую сказали то же самое на конференции в Москве, я уточнил: "То

Перейти
Обучение языку MQL4 под MetaTrader 4 Опубликовано
8 часов назад, mishastar сказал:

Добрый день! Может кто подскажет кусочек кода в советник.

   int ObjTotal = ObjectsTotal();
   long last_number = 0;
   int obj_i = 0;
   for (int i=ObjTotal-1; i>= 0; i--) {
      string name = ObjectName(0,i);
      if(ObjectType(name) == OBJ_FIBO) {
         StringReplace(name,"Fibo ","");
         long number = StringToInteger(name);
         if(number > last_number) {
            last_number = number;
            obj_i = i;
         }
      }
   }
   
   string name = ObjectName(0,obj_i);

   double level_0 = ObjectGetDouble(0,name,OBJPROP_PRICE2);
   double level_100 = ObjectGetDouble(0,name,OBJPROP_PRICE1);
   Print("Уровень 0: ",DoubleToString(level_0,Digits));
   Print("Уровень 100: ",DoubleToString(level_100,Digits));

Данный скрипт находит все вручную установленные Фибо, ищет ту, у которой номер самый поздний и принимает ее за последнюю.

Далее узнает у нее две цена - на 0 и на 100 отметке и выдает принт.

Думаю, разберешься.

  • Лайк 2
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
7 часов назад, Rever27 сказал:

   int ObjTotal = ObjectsTotal();
   long last_number = 0;
   int obj_i = 0;
   for (int i=ObjTotal-1; i>= 0; i--) {
      string name = ObjectName(0,i);
      if(ObjectType(name) == OBJ_FIBO) {
         StringReplace(name,"Fibo ","");
         long number = StringToInteger(name);
         if(number > last_number) {
            last_number = number;
            obj_i = i;
         }
      }
   }
   
   string name = ObjectName(0,obj_i);

   double level_0 = ObjectGetDouble(0,name,OBJPROP_PRICE2);
   double level_100 = ObjectGetDouble(0,name,OBJPROP_PRICE1);
   Print("Уровень 0: ",DoubleToString(level_0,Digits));
   Print("Уровень 100: ",DoubleToString(level_100,Digits));

Данный скрипт находит все вручную установленные Фибо, ищет ту, у которой номер самый поздний и принимает ее за последнюю.

Далее узнает у нее две цена - на 0 и на 100 отметке и выдает принт.

Думаю, разберешься.

От Души Благодарю! Буду действовать дальше. Я не волшебник я только учусь))) 

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Добрый день! Продолжаем разговор) Вставил кусочек кода.. все отлично заработало. Но появились дополнительные не решенные вопросы.  Установил функцию удаления сетки после открытия ордера, что бы при последующих подходах цены к уровню сделки не открывались. Но в памяти где то эти  уровни сохраняются и ордера открываются снова без наличия сетки на графике. По картинке видно что при отсутствие сетки на графике значения уровней остаются. Вывел их через комментарий.  Вопрос Можно ли сделать так что бы значения уровней обнулялись после удаления сетки с графика?

if (CountTrades() > 0 )
          } 

ObjectsDeleteAll(0,OBJ_FIBO);
          }

 

Screenshot_201.thumb.png.552dc4b702e8e0e97d27e26a863dab11.png

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
В 06.11.2020 в 14:21, usver73 сказал:

int OrderMinProfit(int oType = -1)// -1 - проверяем все типы ордеров, иначе передаем тип ордера для поиска с мин. профитом
{
   double oMinProfit = 9999999.0;
   int    oTicketTmp = 0;
   
   for(int i = 0;i < OrdersTotal();i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol()!=_Symbol || OrderMagicNumber() != iMagic) continue;
      if(oType >-1 && OrderType() !=oType) continue;
      
      if(OrderProfit()< oMinProfit)
      {
         oMinProfit = OrderProfit();
         oTicketTmp = OrderTicket();
      }
   }
   
   return(oTicketTmp);
}
  

была ошибка - два return. Поправил

Спасибо.

Может еще функцию на закрытие это ордера подскажите?

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
7 часов назад, mishastar сказал:

Можно ли сделать так что бы значения уровней обнулялись после удаления сетки с графика?

Уровни хранятся в переменных, а не в на объектах. Нужно обнулять все переменные либо после открытия ордера, либо в начале каждого тика.

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
11 часов назад, Rever27 сказал:

Уровни хранятся в переменных, а не в на объектах. Нужно обнулять все переменные либо после открытия ордера, либо в начале каждого тика.

Все получилось!!! УРА!!Радости нет предела! Росту ))) Спасибо большое за подсказки!!! 

if (CountTrades() > 0 )
           {  
               ObjectsDeleteAll(0,OBJ_FIBO); 
               ZeroMemory( level_160 ); 
               ZeroMemory( level_100 );
               ZeroMemory( level_0 );
            }

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
В 08.12.2020 в 19:53, makssub сказал:

Спасибо.

Может еще функцию на закрытие это ордера подскажите?

Можно в функцию поиска добавить или внешнюю дописать
 

int OrderMinProfit(int oType = -1)// -1 - проверяем все типы ордеров, иначе передаем тип ордера для поиска с мин. профитом
{
   double oMinProfit = 9999999.0;
   int    oTicketTmp = -1;
   int    oTypeTmp = -1;
   
   for(int i = 0;i < OrdersTotal();i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol()!=_Symbol || OrderMagicNumber() != iMagic) continue;
      if(oType >-1 && OrderType() !=oType) continue;
      
      if(OrderProfit()< oMinProfit)
      {
         oMinProfit = OrderProfit();
         oTicketTmp = OrderTicket();
         oTypeTmp = OrderType(); 
      }
   }
  //закрываем ордер с максимальной просадкой 
  if(oTicketTmp > -1)
  {
     if(oTypeTmp == OP_BUY)
        if(OrderClose(oTicketTmp, OrderLots(),Bid,0, clrRed)) Print ("Close order ", oTicketTmp);
     else if (oTypeTmp == OP_SELL)
        if(OrderClose(oTicketTmp, OrderLots(),Ask,0, clrRed)) Print ("Close order ", oTicketTmp);
  }
  return(oTicketTmp);
}

 

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
В 29.11.2020 в 13:36, Pavel888 сказал:

TmaSlope.v1.5-Normalized при компиляции даёт 2 ошибки как их устранить?

2052878684_3.thumb.png.0563e4d462368f08ff3f35469f6ca675.png

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
4 часа назад, Александр 1939 сказал:

TmaSlope.v1.5-Normalized при компиляции даёт 2 ошибки как их устранить?

"NULL" измени на цвет "clrNONE".

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
6 часов назад, MikR0ReR сказал:

"NULL" измени на цвет "clrNONE".

Спасибо.для индикатора получилось робот не получается.Вопрос можно ли использовать TmaSlope.v1.5-Normalized в советнике??кто-нибудь занимался этим? 

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
Только что, Александр 1939 сказал:

Спасибо.для индикатора получилось робот не получается.Вопрос можно ли использовать TmaSlope.v1.5-Normalized в советнике??кто-нибудь занимался этим? 

Единственное что я понял из написанного "Вопрос можно ли использовать TmaSlope.v1.5-Normalized в советнике??"

Ответ: Можно. Индикатор TmaSlope.v1.5-Normalized можно использовать в советнике.

Все остальное мне не понятно написано. Прошу переписать с толком, с расстановкой.

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
12 часов назад, MikR0ReR сказал:

Все остальное мне не понятно написано. Прошу переписать с толком, с расстановкой.

минимум что вписать из"TmaSlope.v1.5-Normalized" в iCustom

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
4 часа назад, Александр 1939 сказал:

минимум что вписать из"TmaSlope.v1.5-Normalized" в iCustom

Я не буду разбираться какие параметра на что влияют, объясню так.

  • Если нужно изменить 1й параметр, то только первый параметр и вписываешь. "1п."
  • Если нужно изменить 5й параметр, то вписываешь все параметры от 1 до 5. "1п,2п,3п,4п,5п"
  • Если ничего не нужно менять, будешь использовать индикатор по умолчанию, то ничего писать не надо. И этот вариант ответ на твой вопрос, ничего не вписывать.
Изменено пользователем MikR0ReR
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Приветствую всех профессионалов и любителей программирования торговых роботов.

 

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

Например, проверка маржи на случай, если брокер изменить требования по ней и т.д.

 

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

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Метаквоты у себя на сайте рекомендуют делать следующую проверку из 3 функций перед открытием ордера. Я немного менял их (вроде), прикрепляю свой вариант.

if(!CheckMoneyForTrade(Symbol(),lots,cmd)) return(false);
if(!IsNewOrderAllowed()) return(false);
if(!CheckVolumeValue(lots)) return(false);

//+------------------------------------------------------------------+
bool CheckMoneyForTrade(string symb, double _lots,int type)
  {
   double free_margin=AccountFreeMarginCheck(symb,type,_lots);
   //-- если денег не хватает
   if(free_margin<0)
     {
      string oper=(type==OP_BUY)? "Buy":"Sell";
      Print("Not enough money for ", oper," ",_lots, " ", symb, " Error code=",GetLastError());
      return(false);
     }
   //-- проверка прошла успешно
   return(true);
  }
  
//+------------------------------------------------------------------+
//| проверяет - можно ли выставить еще один ордер                    |
//+------------------------------------------------------------------+
bool IsNewOrderAllowed()
  {
//--- получим количество разрешенных на счете отложенных ордеров
   int max_allowed_orders=(int)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);

//--- если ограничения нет - вернем true, можно отослать ордер
   if(max_allowed_orders==0) return(true);

//--- если дошли до этого места, значит ограничение есть, узнаем, сколько уже ордеров действует
   int orders=OrdersTotal();

//--- вернем результат сравнения
   return(orders<max_allowed_orders);
  }
  
//+------------------------------------------------------------------+
//|  Проверяет объем ордера на корректность                          |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume)
  {
   string Description = "";
//--- минимально допустимый объем для торговых операций
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
     {
      Description=StringFormat("Объем меньше минимально допустимого SYMBOL_VOLUME_MIN=%.2f",min_volume);
      return(false);
     }

//--- максимально допустимый объем для торговых операций
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
     {
      Description=StringFormat("Объем больше максимально допустимого SYMBOL_VOLUME_MAX=%.2f",max_volume);
      return(false);
     }

//--- получим минимальную градацию объема
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      Description=StringFormat("Объем не является кратным минимальной градации SYMBOL_VOLUME_STEP=%.2f, ближайший корректный объем %.2f",
                               volume_step,ratio*volume_step);
      return(false);
     }
   if(Description != "") Print(Description);  
   
   return(true);
  }

 

  • Лайк 3
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Добрый день! Помогите пожалуйста доработать функцию. С циклами у меня вообще ничего не получается. Идея следующая - в свой советник решил добавить функцию, что бы по закрытию позиции сделки переносились на график , а затем делался скриншот графика. (Это нужно что бы упростить в последствии анализ торговли).

Представленные функции работают сами по себе хорошо.

Но нужно, что бы History_Graf() выгружала из истории на график только 5 последних сделок. И как только новая сделка закрылась и нарисовалась на графике, выполнялась функция ChartScreenShoter()

 

bool History_Graf()
{      
       string Name;
      double ClosePrice;
     for ( int m=0; m<OrdersHistoryTotal(); m++)
       {
        if (OrderSelect(m,SELECT_BY_POS,MODE_HISTORY))
        if (OrderSymbol()==Symbol() && OrderMagicNumber()== Magic)
           {
            Name="Order " +DoubleToStr(OrderTicket())+" "+DoubleToStr(OrderType())+" "+ DoubleToStr(OrderLots(),2)+"        "+DoubleToStr(OrderProfit(),2);
            ObjectCreate(Name,OBJ_ARROW,0,OrderOpenTime(),OrderOpenPrice());
            ObjectSet(Name,OBJPROP_ARROWCODE,1);
            if (OrderType()==0 || OrderType()==2 || OrderType()==4) ObjectSet(Name,OBJPROP_COLOR,Blue);
               else ObjectSet(Name,OBJPROP_COLOR,Red);
            Name="Close "+DoubleToStr(OrderTicket());
            if (OrderType()>1)ClosePrice=OrderOpenPrice();
               else ClosePrice=OrderClosePrice();
            ObjectCreate(Name,OBJ_ARROW,0,OrderCloseTime(),ClosePrice);
            ObjectSet(Name,OBJPROP_ARROWCODE,3);
            ObjectSet(Name,OBJPROP_COLOR,Goldenrod);
            Name="Order line "+DoubleToStr(OrderTicket());
            
            ObjectCreate(Name,OBJ_TREND,0,OrderOpenTime(),OrderOpenPrice(),OrderCloseTime(),ClosePrice);
            ObjectSet(Name,OBJPROP_RAY,0);
            ObjectSet(Name,OBJPROP_STYLE,2);
             if (OrderType()==0 ) ObjectSet(Name,OBJPROP_COLOR,Blue);
             if (OrderType()==1 ) ObjectSet(Name,OBJPROP_COLOR,Red);        
           }
       }
   return(false);
}
//+------------------------------------------------------------------+   
   void ChartScreenShoter()
{
     string fname = "Screenshot\\" + Symbol() + "\\" +  TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES| TIME_SECONDS); // формируем имя папки
       StringReplace(fname, ":", "_"); // в имени файла двоеточия не допустимы, заменяем на подчеркивания
        if(!ChartScreenShot(0, fname + ".png", 1600, 900))
        Print("ChartScreenShot failed, " );
}

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
12 часов назад, mishastar сказал:

Но нужно, что бы History_Graf() выгружала из истории на график только 5 последних сделок.

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

Если по простому и нужно только 5 последних ордеров с возможными ошибками, но одной строчкой, то меняем цикл for.

Нумерация ордеров идет с самого первого. Т.е. чтобы понять номера 5 последних нужно сделать цикл так:

for ( int m=OrdersHistoryTotal(); m>OrdersHistoryTotal()-5; m--)

Но может быть момент, что в эти пять ордеров не будут входить ордера по текущей паре, тогда ничего не нарисуется. Значит нужно либо увеличивать количество анализируемых ордеров, либо вводить счетчик. Типа того:

     for ( int m=OrdersHistoryTotal(); m>0; m--)
       { 
        if (OrderSelect(m,SELECT_BY_POS,MODE_HISTORY)) 
        if (OrderSymbol()==Symbol())
           {
            cnt++;
            if(cnt == 5) break;
			}
       }

 

12 часов назад, mishastar сказал:

И как только новая сделка закрылась и нарисовалась на графике, выполнялась функция ChartScreenShoter()

Просто сохрани в переменной на глобальном уровне данные о количестве закрытых ордеров. Как только фактическое значение не будет равным ему, тогда запускаешь цикл отрисовки и скриншота:

int Order_History = 0;
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---

   if(Order_History > 0 && Order_History != OrdersHistoryTotal()) {
      Order_History = OrdersHistoryTotal();
      History_Graf();
      ChartScreenShoter();
   }

   return(rates_total);
  }

 

 

Кстати, мой индикатор после закрытия ордера делает такие же действия - рисует сделку и делает скриншот. Только намного больше настроек. Вдруг будет полезен. з.ы. открытый код не дам )

 

DaVinci Truly ScreenShot Indicator 2.06.ex4

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
Цитата

Кстати, мой индикатор после закрытия ордера делает такие же действия - рисует сделку и делает скриншот. Только намного больше настроек. Вдруг будет полезен. з.ы. открытый код не дам )

Премного благодарен за научения! Для меня это полезный пример. Смотрю и понимаю что это элементарно просто, а сам не могу так сообразить) . Переделал цикл, добавил условия - все заработало как надо. Индикатор полезная штука - спасибо - добавил себе в копилку, полезен он для матерых ребят. Вообще чем старше становишься тем больше (ленишься) - хочется автоматизировать упростить себе работу))).  Я только второй год постепенно вникаю в программирование по мере необходимости. Еще раз спасибо ! ))

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Подскажите люди добрые, уже измучился с этим.

Надо сделать задержку перед тем как функция CloseAll() исполнится. Задержать функцию на 10 сек например.

То есть как только я достигаю профита например 5 баксов, я не хочу чтобы советник сразу закрыл все сделки какие есть, а чуть подождал как бы дал время чтобы цена еще увеличилась и уже потом закрылся. Чтобы я не делал то у меня советник закрывает не все ордера, то закрывает и несмотря что есть слип открывает новые ордера то есть перестает работать по тому алгоритму что написано внизу.

 

      double op = CalculateProfit();
          
      if (op >= Profit)
      {
      CloseAll();
      SendNotification("Close Metatrader1");
      Sleep(60*60000);// 60.000 = 1 min
      SendNotification("Close Metatrader2");
      Sleep(10*60*60000);// 60.000 = 1 min
      }

 

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
16 минут назад, MikR0ReR сказал:

@Just Trader Первое Sleep(10000), потом CloseAll()


Sleep(10000);
CloseAll();

 

неужели думаете что я до этого не додумался? Я с этим уже неделю мучаюсь. Если бы все так легко было бы....

  • Попей водички 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

@Just Trader Какой код прислали, на тот и ответил. Если данный вариант не работает значит с логикой выполнения у Вас напутано.

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
1 час назад, Just Trader сказал:

Подскажите люди добрые, уже измучился с этим.

Попробуй такой вариант

int time_sec = 0;
bool close_me = false;
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   if(close_me && MathAbs(time_sec-Seconds()) >= 5) {
      close_me = false;
      CloseAll();
      SendNotification("Close Metatrader1");
   }
   
   
   double op = CalculateProfit();
          
   if (op >= Profit && !close_me)
   {
      time_sec = Seconds();
      close_me = true;
   } 

}
//+------------------------------------------------------------------+

 

Как только условие для закрытия выполнено, ты запоминаешь текущую секунду и активируешь булевую переменную.

Как только разница между текущей секундой у брокера и той, что в памяти будет больше, чем 5, то произойдет закрытие и close_me снова станет равной false.

 

Еще можно через таймер как-нибудь попробовать. Запустить OnTimer раз в 5 секунд. Много вариантом подобного извращения.

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
10 часов назад, Rever27 сказал:

Попробуй такой вариант

 

Как только условие для закрытия выполнено, ты запоминаешь текущую секунду и активируешь булевую переменную.

Как только разница между текущей секундой у брокера и той, что в памяти будет больше, чем 5, то произойдет закрытие и close_me снова станет равной false.

 

Еще можно через таймер как-нибудь попробовать. Запустить OnTimer раз в 5 секунд. Много вариантом подобного извращения.

к сожалению с этим советник вообще не закрывает((

Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Специальное предложение


  • Рекомендуемые брокеры

  • ×
    ×
    • Создать...