Kashtan
Игорь

 
Уровень 19

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


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

Рейтинг 2159



РЕКОМЕНДУЮ



Советник Intraday

Просьба написать советник для МТ4

1. Советник открывает по одному ордеру каждый день в заданное время
2. Направление ордера зависит от выбора одного из двух вариантов в настройках (1,2)
Если 1, ордер открывается в направлении последней закрывшейся свечи (бычья — покупка, медвежья — продажа)
Если 2, ордер открывается в противоположном направлении (бычья — продажа, медвежья — покупка)
Из этого следует, что возможные ТФ для работы от М1 до Н4
3. В конце дня (00:00) ордер закрывается советником, если ранее не успел закрыться сам по ТП или СЛ
4. В код желательно добавить функцию для автоматического повышения/понижения объёма следующего ордера при изменении баланса
Пример: Начальный лот задан 0.1, баланс 10К. Если после закрытия очередного ордера по ТП баланс стал 11К или более,
следующий открывается 0.11. При 12К — 0.12. И т.д. При уменьшении баланса лот меняется по такому же принципу в сторону уменьшения

Настройки:
Время
Направление (1,2)
Начальный лот
ТП
СЛ
  • 0
  • Просмотров: 221
  • 23 октября 2025, 19:19
  • Kashtan
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

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

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

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

+
0
1000р.
avatar

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

  • 24 октября 2025, 09:37
+
0
пополам
avatar

  24  igrun Сообщений: 1779 - igrun

  • 24 октября 2025, 15:38
+
0
//+------------------------------------------------------------------+
//|                                                  DailyTrader.mq4 |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//--- Входные параметры
input string   TradeTime = "10:00";          // Время открытия ордера (формат "ЧЧ:ММ")
input int      DirectionMode = 1;            // Режим направления (1-по тренду, 2-против тренда)
input double   InitialLot = 0.1;             // Начальный лот
input double   TakeProfit = 50.0;            // Тейк-профит в пунктах
input double   StopLoss = 30.0;              // Стоп-лосс в пунктах

//--- Глобальные переменные
datetime lastTradeDate = 0;
double currentLot = InitialLot;
double balanceReference = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   balanceReference = AccountBalance();
   Print("Советник инициализирован. Начальный баланс: ", balanceReference);
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Print("Советник деинициализирован");
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   datetime currentTime = TimeCurrent();
   MqlDateTime timeStruct;
   TimeToStruct(currentTime, timeStruct);
   
   // Проверяем, нужно ли закрыть ордер в 00:00
   if(timeStruct.hour == 0 && timeStruct.min == 0)
   {
      CloseAllOrders();
      lastTradeDate = 0; // Сбрасываем дату торговли для нового дня
      return;
   }
   
   // Проверяем, было ли уже открытие ордера сегодня
   if(lastTradeDate == TimeCurrentDate())
      return;
   
   // Проверяем время открытия ордера
   string tradeTimeStr = TradeTime;
   int tradeHour = (int)StringToInteger(StringSubstr(tradeTimeStr, 0, 2));
   int tradeMinute = (int)StringToInteger(StringSubstr(tradeTimeStr, 3, 2));
   
   if(timeStruct.hour == tradeHour && timeStruct.min == tradeMinute)
   {
      OpenTrade();
      lastTradeDate = TimeCurrentDate();
   }
}

//+------------------------------------------------------------------+
//| Функция открытия торговли                                        |
//+------------------------------------------------------------------+
void OpenTrade()
{
   // Обновляем объем лота на основе изменения баланса
   UpdateLotSize();
   
   int orderType = GetOrderDirection();
   double openPrice = 0;
   double sl = 0, tp = 0;
   
   if(orderType == OP_BUY)
   {
      openPrice = Ask;
      sl = CalculateSL(openPrice, OP_BUY);
      tp = CalculateTP(openPrice, OP_BUY);
   }
   else if(orderType == OP_SELL)
   {
      openPrice = Bid;
      sl = CalculateSL(openPrice, OP_SELL);
      tp = CalculateTP(openPrice, OP_SELL);
   }
   else
      return;
   
   int ticket = OrderSend(Symbol(), orderType, currentLot, openPrice, 3, sl, tp, 
                         "DailyTrade", 0, 0, clrBlue);
   
   if(ticket > 0)
   {
      Print("Ордер открыт: ", OrderTypeToString(orderType), ", Лот: ", currentLot, 
            ", Время: ", TimeToString(TimeCurrent()));
   }
   else
   {
      Print("Ошибка открытия ордера: ", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Определение направления ордера                                   |
//+------------------------------------------------------------------+
int GetOrderDirection()
{
   // Получаем информацию о последней закрытой свече
   double open = iOpen(Symbol(), PERIOD_CURRENT, 1);
   double close = iClose(Symbol(), PERIOD_CURRENT, 1);
   
   bool isBullish = (close > open);
   
   if(DirectionMode == 1)
   {
      // Ордер в направлении последней свечи
      return isBullish ? OP_BUY : OP_SELL;
   }
   else if(DirectionMode == 2)
   {
      // Ордер против направления последней свечи
      return isBullish ? OP_SELL : OP_BUY;
   }
   
   return -1;
}

//+------------------------------------------------------------------+
//| Обновление размера лота на основе изменения баланса              |
//+------------------------------------------------------------------+
void UpdateLotSize()
{
   double currentBalance = AccountBalance();
   double balanceChange = currentBalance / balanceReference;
   
   // Изменяем лот пропорционально изменению баланса
   currentLot = NormalizeDouble(InitialLot * balanceChange, 2);
   
   // Проверяем минимальный и максимальный лот
   double minLot = MarketInfo(Symbol(), MODE_MINLOT);
   double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
   
   if(currentLot < minLot) currentLot = minLot;
   if(currentLot > maxLot) currentLot = maxLot;
   
   Print("Баланс: ", currentBalance, ", Референс: ", balanceReference, 
         ", Новый лот: ", currentLot);
}

//+------------------------------------------------------------------+
//| Расчет стоп-лосса                                               |
//+------------------------------------------------------------------+
double CalculateSL(double price, int orderType)
{
   if(StopLoss == 0) return 0;
   
   double point = MarketInfo(Symbol(), MODE_POINT);
   double slPoints = StopLoss * point;
   
   if(orderType == OP_BUY)
      return price - slPoints;
   else if(orderType == OP_SELL)
      return price + slPoints;
   
   return 0;
}

//+------------------------------------------------------------------+
//| Расчет тейк-профита                                             |
//+------------------------------------------------------------------+
double CalculateTP(double price, int orderType)
{
   if(TakeProfit == 0) return 0;
   
   double point = MarketInfo(Symbol(), MODE_POINT);
   double tpPoints = TakeProfit * point;
   
   if(orderType == OP_BUY)
      return price + tpPoints;
   else if(orderType == OP_SELL)
      return price - tpPoints;
   
   return 0;
}

//+------------------------------------------------------------------+
//| Закрытие всех ордеров                                           |
//+------------------------------------------------------------------+
void CloseAllOrders()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == 0)
         {
            double closePrice = 0;
            if(OrderType() == OP_BUY)
               closePrice = Bid;
            else if(OrderType() == OP_SELL)
               closePrice = Ask;
               
            if(!OrderClose(OrderTicket(), OrderLots(), closePrice, 3, clrRed))
               Print("Ошибка закрытия ордера ", OrderTypeToString(OrderType()), ": ", GetLastError());
         }
      }
   }
   
   // Обновляем референсный баланс при закрытии дня
   balanceReference = AccountBalance();
   Print("Все ордера закрыты. Новый референсный баланс: ", balanceReference);
}

//+------------------------------------------------------------------+
//| Получение даты без времени                                      |
//+------------------------------------------------------------------+
datetime TimeCurrentDate()
{
   MqlDateTime timeStruct;
   TimeToStruct(TimeCurrent(), timeStruct);
   timeStruct.hour = 0;
   timeStruct.min = 0;
   timeStruct.sec = 0;
   return StructToTime(timeStruct);
}

//+------------------------------------------------------------------+
//| Конвертация типа ордера в строку                               |
//+------------------------------------------------------------------+
string OrderTypeToString(int orderType)
{
   if(orderType == OP_BUY) return "BUY";
   if(orderType == OP_SELL) return "SELL";
   return "UNKNOWN";
}
avatar

  24  igrun Сообщений: 1779 - igrun

  • 24 октября 2025, 15:37

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