AVPetrovich

 
Уровень 7

  Торгую в компаниях:


Группа "Стол заказов MQL"

Рейтинг 2146



РЕКОМЕНДУЮ



Советник "Время деньги"

В общем идея такова: Есть у нас волатильность, которая при разных обстоятельствах падает или увеличивается.При очень значимых событиях: пробой, разворот, выход новостей и т.д волатильность подымается и цена за секунды улетает как Гагарин в космос.При включении советник выставляет два отложенных ордера в разные стороны на расстоянии Н пунктов от цены.К ним стоп лосс и тейк профит.Прописывает время жизни ордеров.Если один ордер сработал второй уделяется.Если в течении времени жизни ордеров ни один ордер не сработал, советник закрывает старые и выставляет новые.
Параметры: Лот, расстояние от цены, стоп лосс, тейк профит и время жизни ордеров.Можно ещё приклеить мартин-если поймали лося следующие ордера удваиваются.
Вот такая идея.Вот.
  • 0
  • Просмотров: 3170
  • 11 мая 2022, 21:55
  • AVPetrovich
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

Вступите в группу "Стол заказов MQL", чтобы следить за обновлениями
ПРИСОЕДИНИТЬСЯ К ГРУППЕ
присоединиться
  Предыдущая запись в группе
открыть/закрыть
Следующая запись в группе  
Советник на отложенных ордерах
09 мая 2022
14 мая 2022

Брокер для ваших роботов, 15 лет на рынке

Комментарии (35)

+
0
Подобный (не 1:1, но о такой идее в основе) советник уже существует.
Называется «Советник, торгующий на новостях» или как-то так. Новостной, в общем, когда волатильность подскакивает.
Я его тестировал лет 5 назад (он уже тогда был не нов), результаты были отличные, но на демке сливал только в путь.
Проскальзывания, все дела…
Если его найду — скину.
Идея понятная, но далеко не новая.
avatar

  24  ShamanHand Сообщений: 1092 - Наношу добро, причиняю пользу.

  • 11 мая 2022, 22:22
+
0

//+------------------------------------------------------------------+
//|                                                  TimeIsMoney.mq4 |
//|                                               Copyright 2022, Ve |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, Ve"
#property link      ""
#property version   "1.00"
#property strict

extern double Lots         = 0.01;    //Лот
extern int Distance        = 100;     //Расстояние от цены
extern int TakeProfit      = 200;     //Тейк
extern int StopLoss        = 500;     //Cтоп-лосс
extern double KLot         = 2;       //умножение лота при лосе
extern int LifeTime        = 600;     //Время жизни ордеров
extern int Slip            = 10;      //Reqot
extern int Magic           = 123;     //Magic

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PutOrder(int type,double price)
  {
   int r=0;
   color clr=Green;
   double sl=0,tp=0;
   datetime time=TimeCurrent()+LifeTime;

   if(type==1 || type==3 || type==5)
     {
      clr=Red;
      if(TakeProfit>0)
       tp=NormalizeDouble(price-TakeProfit*_Point,_Digits);
      if(StopLoss>0)
       sl=NormalizeDouble(price+StopLoss*_Point,_Digits);
     }

   if(type==0 || type==2 || type==4)
     {
      clr=Blue;
      if(TakeProfit>0)
       tp=NormalizeDouble(price+TakeProfit*_Point,_Digits);
      if(StopLoss>0)
       sl=NormalizeDouble(price-StopLoss*_Point,_Digits);
     }
    r=OrderSend(NULL,type,Lot(),NormalizeDouble(price,Digits),Slip,sl,tp,"",Magic,time,clr);
    GetLastError();
   return;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Lot()
  {
   double lot=Lots;
   
   if(LastDealResult()==0)
     lot=NormalizeDouble(LastLot()*KLot,_Digits);
   return(lot);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double LastLot()
  {
   double lot=0;
   int oticket,ticketNumber=0;
   for(int i=OrdersHistoryTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()<2)
              {
               oticket=OrderTicket();
               if(oticket>ticketNumber)
                 {
                  ticketNumber=oticket;
                  lot=OrderLots();
                 }
              }
           }
        }
      }
   return(lot);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int LastDealResult()
  {
   int result=2,oticket,ticketNumber=0;
   double ord=0;
   for(int i=OrdersHistoryTotal()-1; i>=0; i--)
     {
     if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
       {
        if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
          {
           if(OrderType()<2)
             {
              oticket=OrderTicket();
              if(oticket>ticketNumber)
                {
                 ticketNumber=oticket;
                 ord=OrderProfit();
                }
             }
           }
         }
       }
    if(ord>0) result=1;//tp
    if(ord<0) result=0;//sl
   return(result);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CountOrders(int type=-1)
  {
   int count=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if((OrderType()>1 && type==-1)||(OrderType()<6 && type==6))
               count++;
           }
        }
     }
   return(count);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DelOrder()
  {
   bool del;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()>1)
               del=OrderDelete(OrderTicket());
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(CountOrders()<2)
    DelOrder();
   
   if(CountOrders(6)<1 )
     {
      PutOrder(4,Ask+Distance*_Point);
      PutOrder(5,Bid-Distance*_Point);
     }
   
  }
//+------------------------------------------------------------------+

avatar

  14  verta81 Сообщений: 390

  • 11 мая 2022, 22:48
+
0
Огромное спасибо, Поиграюсь результат скину.
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 08:15
+
0
Картинка получается красивая.Если ещё добавить трейлин стоп.Можно снизить количества убыточных сделок.
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 09:52
+
0
avatar

  24  ShamanHand Сообщений: 1092 - Наношу добро, причиняю пользу.

  • 11 мая 2022, 22:52
+
0
Идея родилась как раз после этого советника.Он только без умножения.И если я не ошибаюсь там что то не корректно работает. Я как то просил создателя поправить, он попросил за это миллион.Но было это очень давно.
Редактирован: 12 мая 2022, 16:11
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 16:07
+
0

Всех забираю с собой, едем на Мальдивы.
Редактирован: 12 мая 2022, 09:35
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 09:34
+
0

Ещё есть какие то моменты, когда советник не работает.
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 09:56
+
0

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(CountOrders()<2)//если отложенных ордеров меньше двух,  
    DelOrder();       // тогда оставшийся удаляем.
   
   if(CountOrders(6)<1 )//если нет ни открытых позиций ни отложенных ордеров
     {
      PutOrder(4,Ask+Distance*_Point);//тогда выставляем байстоп
      PutOrder(5,Bid-Distance*_Point);// и селлстоп ордераю
     }
   
  }
//+------------------------------------------------------------------+


У Вас на графике есть открытые позиции, поэтому отложенные ордера не выставляются.
Как только позиция закрылась — выставились два стоповых ордера.
В коде добавил комментарии для понимания что прописано в главной функции.
avatar

  16  ssg Сообщений: 817

  • 12 мая 2022, 10:22
+
0
Спасибо.Вам билет первого класса.))
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 10:42
+
0
Торговля на новостях и на сильных движениях -(лично по моему опыту) это большой риск. И очень часто за сильным движением идет аналогичный по размеру откат.
avatar

  18  Boris54 Сообщений: 810 - ПенSионер

  • 12 мая 2022, 11:03
+
0
При ручной торговле иногда использую такой вариант:
1.при срабатывании одного из ордеров — второй удаляется.
2.выставляется опять отложенный ордер того же направления что и удаленный, но уже по другой цене и другим увеличенным лотом. С целью, что в случае отката будет не равнозначное локирование позиций.
3.Спустя некоторое время или при продолжении движения цены в сторону открывшейся ранее позиции опять удаляю отложенный ордер и снова выставляю его опять уже по более выгодной цене. Таких шагов может быть несколько. Происходит некоторое подобие трала стопового ордера за ценой.
4.В ночное или неурочное, для меня, время могу запустить советник с автотралением ордеров.
avatar

  16  ssg Сообщений: 817

  • 12 мая 2022, 11:17
+
0
Да.Надо избегать гэпов и трейлинг стоп нужен как раз для откатов.
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 12:20
+
0
НА ОТКАТАХ НАДО ЗАРАБАТЫВАТЬ.
avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 28 мая 2022, 02:23
+
0
*hi* 
avatar

  16  ssg Сообщений: 817

  • 12 мая 2022, 11:03
+
0
Время жизни ордеров 600 это секунды?
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 11:38
+
0
Да.
avatar

  16  ssg Сообщений: 817

  • 12 мая 2022, 13:20
+
0
Думаю, в этот советник необходимо добавить функцию усреднения с мартином и шагающий трал. А ещё лучше — в советник на который дали ссылку выше babyforex.ru/shkola/universitet/a_teper_praktika/sovetniki/novostnoj_sovetnik_ea_news/
А то сбежит цена от безубытка, и поминай как звали.*cry* 
Редактирован: 12 мая 2022, 15:29
avatar

  4  repnin Сообщений: 17

  • 12 мая 2022, 15:17
+
0
В тестери работает а вот на демки запускаю какие то недочеты выходяит.
Редактирован: 12 мая 2022, 15:45
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 15:42
+
0
какие именно?
avatar

  14  verta81 Сообщений: 390

  • 12 мая 2022, 18:03
+
0
EA-ВРЕМЯ ДЕНЬГИ EURUSD,M5 inputs: Lots=0.01; Distance=10; TakeProfit=100; StopLoss=50; KLot=2.0; LifeTime=600; Slip=10; Magic=123; сообщение о включении.
2022.05.12 21:40:55.449 EA-ВРЕМЯ ДЕНЬГИ EURUSD,M5: open #10340624 buy stop 0.80 EURUSD at 1.0376 sl: 1.0326 tp: 1.0476 ok
2022.05.12 21:40:56.463 EA-ВРЕМЯ ДЕНЬГИ EURUSD,M5: delete #10340624 buy stop 0.80 EURUSD at 1.0376 sl: 1.0326 tp: 1.0476 ok
выставляет ордер лот не верно, и сразу закрывает.

avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 20:46
+
0
Distance увеличить нужно.
avatar

  14  verta81 Сообщений: 390

  • 12 мая 2022, 22:06
+
0
У меня по спецификации уровень стопов 6 пунктов.
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 22:28
+
0
Дистанция увеличил всё ок. Только лот 0,01 а выставил 0,80.
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 12 мая 2022, 22:51
+
0
Извиняюсь, тот советник, на который ссылка, даже на график не перетаскивается.( 
Редактирован: 12 мая 2022, 15:59
avatar

  4  repnin Сообщений: 17

  • 12 мая 2022, 15:58
+
0
Ну он фик пойми каких годов.
Возможно, современный билд его уже и не поддерживает.
Там основных функций было две, а не, как сейчас, три.
avatar

  24  ShamanHand Сообщений: 1092 - Наношу добро, причиняю пользу.

  • 12 мая 2022, 16:19
+
0
На мой взгляд, можно было бы добавить и усреднение, и трал, например, из советника «золото» zakaz.opentraders.ru/60330.html
Там неплохо всё реализовано. На демке очень нравится, как работает.
К сожалению, сам не могу.
avatar

  4  repnin Сообщений: 17

  • 12 мая 2022, 17:13
+
0
Добавил трал

//+------------------------------------------------------------------+
//|                                                  TimeIsMoney.mq4 |
//|                                               Copyright 2022, Ve |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, Ve"
#property link      ""
#property version   "1.00"
#property strict

extern double Lots         = 0.01;    //Лот
extern int Distance        = 100;     //Расстояние от цены
extern int TakeProfit      = 200;     //Тейк
extern int StopLoss        = 500;     //Cтоп-лосс
extern double KLot         = 2;       //умножение лота при лосе
extern int TrailingStop    = 40;      //трейлинг
extern int TrailingStep    = 50;      //шаг трейлинга
extern int LifeTime        = 600;     //Время жизни ордеров
extern int Slip            = 10;      //Reqot
extern int Magic           = 123;     //Magic

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PutOrder(int type,double price)
  {
   int r=0;
   color clr=Green;
   double sl=0,tp=0;
   datetime time=TimeCurrent()+LifeTime;

   if(type==1 || type==3 || type==5)
     {
      clr=Red;
      if(TakeProfit>0)
       tp=NormalizeDouble(price-TakeProfit*_Point,_Digits);
      if(StopLoss>0)
       sl=NormalizeDouble(price+StopLoss*_Point,_Digits);
     }

   if(type==0 || type==2 || type==4)
     {
      clr=Blue;
      if(TakeProfit>0)
       tp=NormalizeDouble(price+TakeProfit*_Point,_Digits);
      if(StopLoss>0)
       sl=NormalizeDouble(price-StopLoss*_Point,_Digits);
     }
    r=OrderSend(NULL,type,Lot(),NormalizeDouble(price,Digits),Slip,sl,tp,"",Magic,time,clr);
    GetLastError();
   return;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Lot()
  {
   double lot=Lots;
   
   if(LastDealResult()==0)
     lot=NormalizeDouble(LastLot()*KLot,_Digits);
   return(lot);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double LastLot()
  {
   double lot=0;
   int oticket,ticketNumber=0;
   for(int i=OrdersHistoryTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()<2)
              {
               oticket=OrderTicket();
               if(oticket>ticketNumber)
                 {
                  ticketNumber=oticket;
                  lot=OrderLots();
                 }
              }
           }
        }
      }
   return(lot);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int LastDealResult()
  {
   int result=2,oticket,ticketNumber=0;
   double ord=0;
   for(int i=OrdersHistoryTotal()-1; i>=0; i--)
     {
     if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
       {
        if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
          {
           if(OrderType()<2)
             {
              oticket=OrderTicket();
              if(oticket>ticketNumber)
                {
                 ticketNumber=oticket;
                 ord=OrderProfit();
                }
             }
           }
         }
       }
    if(ord>0) result=1;//tp
    if(ord<0) result=0;//sl
   return(result);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CountOrders(int type=-1)
  {
   int count=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if((OrderType()>1 && type==-1)||(OrderType()<6 && type==6))
               count++;
           }
        }
     }
   return(count);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DelOrder()
  {
   bool del;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()>1)
               del=OrderDelete(OrderTicket());
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Trailing()
  {
   bool mod;
   double all=0,count=0,sl=0;

   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()<2)
              {
               all+=OrderOpenPrice()*OrderLots();
               count+=OrderLots();
              }
           }
        }
     }
   if(count>0)
      all=NormalizeDouble(all/count,_Digits);
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==OP_BUY)
              {
               if(Bid-all>TrailingStop*_Point)
                 {
                  if(OrderStopLoss()<Bid-(TrailingStop+TrailingStep)*_Point)
                    {
                     sl=NormalizeDouble(Bid-TrailingStop*_Point,_Digits);
                     if(OrderStopLoss()!=sl)
                        mod=OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,Yellow);
                    }
                 }
              }
            if(OrderType()==OP_SELL)
              {
               if(all-Ask>TrailingStop*_Point)
                 {
                  if((OrderStopLoss()>(Ask+(TrailingStop+TrailingStep)*_Point)) || (OrderStopLoss()==0))
                    {
                     sl=NormalizeDouble(Bid+TrailingStop*_Point,_Digits);
                     if(OrderStopLoss()!=sl)
                        mod=OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,Yellow);
                    }
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(TrailingStop>0)//если значение трейлинга больше 0
     Trailing();     //тогда тралим позицию
     
   if(CountOrders()<2)//если отложенных ордеров меньше двух,  
    DelOrder();       // тогда оставшийся удаляем.
   
   if(CountOrders(6)<1 )//если нет ни открытых позиций ни отложенных ордеров
     {
      PutOrder(4,Ask+Distance*_Point);//тогда выставляем байстоп
      PutOrder(5,Bid-Distance*_Point);// и селлстоп ордераю
     }
  }
//+------------------------------------------------------------------+

avatar

  14  verta81 Сообщений: 390

  • 12 мая 2022, 18:10
+
0
verta81, добрый вечер. Коли Вы написали этот советник, может добавите отключаемую функцию трала оставшегося стопового ордера вместо его удаления.
Для полноты исследования возможностей данной стратегии. Думаю форумчанам понравиться.
Например:
<code>
extern bool DelStop    = true;      //удалять стоповые ордера
</code>

<code>
if(DelStop){          // если разрешено удаление стоповых ордеров
 if(CountOrders()<2)  // и если отложенных ордеров меньше двух,  
    DelOrder();       // тогда оставшийся удаляем.
    }
 else{                // иначе
      TrailingOrder(); // тралим оставшийся стоповый ордер за ценой
    }
</code>

Причем может быть есть смысл сначала удалить оставшийся ордер, а затем открыть новый, но уже большим лотом и по лучшей цене.
Редактирован: 12 мая 2022, 19:01
avatar

  16  ssg Сообщений: 817

  • 12 мая 2022, 18:58
+
0
Что в итоги получилось?
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 13 мая 2022, 12:03
+
0
вариант с временем торговли и модификацией без удаления по истечению: www.opentraders.ru/downloads/3318/

avatar

  35  AM2 Сообщений: 16266 - Андрей

  • 12 мая 2022, 22:16
+
0
<code>//+------------------------------------------------------------------+
double Lot()
{
   double lot=Lots;

   for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
         if(OrderProfit()>0)
            lot=Lots;
         if(OrderProfit()<0)
            lot=OrderLots()*KLot;
   if(lot>MaxLot)
      lot=Lots;       // lot=MaxLot; ???????????? Может так лучше?
   return(lot);
}
//+------------------------------------------------------------------+
</code>


Андрей, а Вы уверены, что это лот последнего закрытого ордера?
Редактирован: 19 мая 2022, 14:32
avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 19 мая 2022, 14:26
+
0
Не успел)) Андрей опередил))
avatar

  14  verta81 Сообщений: 390

  • 12 мая 2022, 22:49
+
0
У кого какие тесты получаются?
avatar

  7  AVPetrovich Автор Сообщений: 187

  • 13 мая 2022, 08:40
+
0
hola buenas tardes, estoy buscando ayuda en la creacion de un sistema automatico con mi estrategia, funciona con apertura diaria, horario de velas y y altos y minimos de estas mismas para abrir la operacion y tp en el 61.8 de fibo y el stop debajo de la segunda vela, todo modificable
avatar

  0  LatinTradeFx Сообщений: 2

  • 21 мая 2022, 19:31

Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий