0
может кому интересен будет код
avatar

igrun

  • 7 ноября 2025, 21:36
0
составляй все тз с нуля, или найди авторов
avatar

igrun

  • 5 ноября 2025, 16:08
0
это есть в коде посмотри
avatar

igrun

  • 5 ноября 2025, 14:30
0
кстати а ты их разархивировал?
avatar

igrun

  • 5 ноября 2025, 14:29
0
там семь индикаторов должно быть, а эти новые имеют случайное название и также ждут сигналы от случайных индикаторов. кстати а откуда код — кто догадался что тз одноразовое.
avatar

igrun

  • 5 ноября 2025, 00:15
0
там семь индикаторов должно быть, а эти новые имеют случайное название и также ждут сигналы от случайных индикаторов.
avatar

igrun

  • 5 ноября 2025, 00:13
0
zakaz.opentraders.ru/133227.html готово но учти — есть много подробностей
avatar

igrun

  • 4 ноября 2025, 22:14
0
можешь зарегать демку для мт4 — а то я как маша растеряша желательно робо
avatar

igrun

  • 4 ноября 2025, 19:53
0
а там 4 файла какой из них советник
avatar

igrun

  • 4 ноября 2025, 19:38
0
пока дело обстоит так я жду твое тз с нуля — если справлюсь мт4 мт5 то платишь не справлюсь нет
avatar

igrun

  • 4 ноября 2025, 12:13
0
хотя публикуйте раз в месяц ваше тз может найдется смельчак и за дешево сделает — это как обычно вопрос времени либо денег
avatar

igrun

  • 3 ноября 2025, 22:41
0
потому и цену Андрей выставляет такую потому что программисты из рук вон плохо ведут проекты, я советую вам не использовать их труд — они посредственные.
avatar

igrun

  • 3 ноября 2025, 22:33
0
а у тебя там исходники или что — а тз все это добро есть хотя бы?
avatar

igrun

  • 3 ноября 2025, 21:56
0
точно как я не догадался…
avatar

igrun

  • 29 октября 2025, 00:47
0
//+------------------------------------------------------------------+
//| Обновление размера лота на основе изменения баланса |
//+------------------------------------------------------------------+
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);
double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
if(currentLot < minLot) currentLot = minLot;
if(currentLot > maxLot) currentLot = maxLot;
currentLot = MathRound(currentLot / lotStep) * lotStep;
currentLot = NormalizeDouble(currentLot, 2);
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 NormalizeDouble(price — slPoints, Digits);
else if(orderType == OP_SELL)
return NormalizeDouble(price + slPoints, Digits);
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 NormalizeDouble(price + tpPoints, Digits);
else if(orderType == OP_SELL)
return NormalizeDouble(price — tpPoints, Digits);
return 0;
}

//+------------------------------------------------------------------+
//| Закрытие всех ордеров |
//+------------------------------------------------------------------+
bool CloseAllOrders()
{
int totalOrders = OrdersTotal();
if(totalOrders == 0)
{
Print(«Нет ордеров для закрытия»);
return true;
}
int closedCount = 0;
int errorCount = 0;
for(int i = totalOrders — 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
double closePrice = 0;
int orderType = OrderType();
if(orderType == OP_BUY)
closePrice = Bid;
else if(orderType == OP_SELL)
closePrice = Ask;
else
continue; // Пропускаем отложенные ордера
bool result = OrderClose(OrderTicket(), OrderLots(), closePrice, 3, clrRed);
if(result)
{
closedCount++;
Print(«Ордер закрыт: », OrderTypeToString(orderType),
", Прибыль: ", OrderProfit());
}
else
{
errorCount++;
int error = GetLastError();
Print(«Ошибка закрытия ордера », OrderTypeToString(orderType),
": ", error, " — ", GetErrorDescription(error));
}
// Небольшая пауза между закрытиями
Sleep(100);
}
}
}
// Обновляем баланс после закрытия ордеров
balanceReference = AccountBalance();
Print(«Итог закрытия: успешно=», closedCount, ", ошибки=", errorCount, ", новый баланс=", balanceReference);
return (errorCount == 0);
}

//+------------------------------------------------------------------+
//| Подсчет открытых ордеров |
//+------------------------------------------------------------------+
int CountOpenOrders()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber &&
(OrderType() == OP_BUY || OrderType() == OP_SELL))
{
count++;
}
}
}
return count;
}

//+------------------------------------------------------------------+
//| Получение даты без времени |
//+------------------------------------------------------------------+
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»;
}

//+------------------------------------------------------------------+
//| Получение описания ошибки |
//+------------------------------------------------------------------+
string GetErrorDescription(int errorCode)
{
switch(errorCode)
{
case 130: return «Неправильные стопы — проверьте минимальные расстояния»;
case 131: return «Неправильный объем»;
case 132: return «Неправильная цена»;
case 133: return «Торговля запрещена»;
case 134: return «Недостаточно денег»;
case 135: return «Цена изменилась»;
case 136: return «Нет цен»;
case 137: return «Брокер занят»;
case 138: return «Требуется перезагрузка цен»;
case 139: return «Ордер заблокирован»;
case 140: return «Разрешение на торговлю запрещено»;
case 146: return «Торговая подсистема занята»;
case 4108: return «Ордер не найден»;
default: return «Неизвестная ошибка: » + IntegerToString(errorCode);
}
}
avatar

igrun

  • 25 октября 2025, 20:43
0
//+------------------------------------------------------------------+
//| Проверка времени для открытия ордера |
//+------------------------------------------------------------------+
bool IsTradeTime()
{
datetime currentTime = TimeCurrent();
MqlDateTime timeStruct;
TimeToStruct(currentTime, timeStruct);
string tradeTimeStr = TradeTime;
int tradeHour = (int)StringToInteger(StringSubstr(tradeTimeStr, 0, 2));
int tradeMinute = (int)StringToInteger(StringSubstr(tradeTimeStr, 3, 2));
return (timeStruct.hour == tradeHour && timeStruct.min == tradeMinute && timeStruct.sec >= 0 && timeStruct.sec <= 59);
}

//+------------------------------------------------------------------+
//| Функция открытия торговли |
//+------------------------------------------------------------------+
void OpenTrade()
{
// Перед открытием финальная проверка — нет ли открытых ордеров
if(CountOpenOrders() > 0)
{
Print(«ОШИБКА: Обнаружены открытые ордера перед открытием нового!»);
return;
}
// Обновляем объем лота на основе изменения баланса
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
{
Print(«Ошибка: Не удалось определить направление ордера»);
return;
}
// Проверяем корректность стоп-уровней
if(!ValidateStopLevels(openPrice, sl, tp, orderType))
{
Print(«Ошибка: Некорректные стоп-уровни. Ордер не открыт.»);
return;
}
int ticket = OrderSend(Symbol(), orderType, currentLot, openPrice, 3, sl, tp,
«DailyTrade», MagicNumber, 0, clrBlue);
if(ticket > 0)
{
Print(«УСПЕХ: Ордер открыт: », OrderTypeToString(orderType),
", Лот: ", currentLot,
", Цена: ", openPrice,
", SL: ", sl,
", TP: ", tp);
}
else
{
int error = GetLastError();
Print(«ОШИБКА открытия ордера: », error, " — ", GetErrorDescription(error));
// Дополнительная диагностика для ошибки 130
if(error == 130)
{
Print(«ДИАГНОСТИКА 130:»);
Print(" — Ask: ", Ask, ", Bid: ", Bid);
Print(" — SL: ", sl, ", TP: ", tp);
Print(" — Stop Level: ", MarketInfo(Symbol(), MODE_STOPLEVEL));
Print(" — Spread: ", MarketInfo(Symbol(), MODE_SPREAD));
}
}
}

//+------------------------------------------------------------------+
//| Проверка корректности стоп-уровней |
//+------------------------------------------------------------------+
bool ValidateStopLevels(double price, double &sl, double &tp, int orderType)
{
if(sl == 0 && tp == 0) return true;
double point = MarketInfo(Symbol(), MODE_POINT);
double spread = MarketInfo(Symbol(), MODE_SPREAD) * point;
double stopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * point;
double minDistance = stopLevel + spread;
// Добавляем запас 10% для надежности
minDistance *= 1.1;
if(orderType == OP_BUY)
{
if(sl > 0 && (price — sl) < minDistance)
{
double newSL = NormalizeDouble(price — minDistance, Digits);
Print(«Корректируем SL для BUY. Было: », sl, " Стало: ", newSL);
sl = newSL;
}
if(tp > 0 && (tp — price) < minDistance)
{
double newTP = NormalizeDouble(price + minDistance, Digits);
Print(«Корректируем TP для BUY. Было: », tp, " Стало: ", newTP);
tp = newTP;
}
}
else if(orderType == OP_SELL)
{
if(sl > 0 && (sl — price) < minDistance)
{
double newSL = NormalizeDouble(price + minDistance, Digits);
Print(«Корректируем SL для SELL. Было: », sl, " Стало: ", newSL);
sl = newSL;
}
if(tp > 0 && (price — tp) < minDistance)
{
double newTP = NormalizeDouble(price — minDistance, Digits);
Print(«Корректируем TP для SELL. Было: », tp, " Стало: ", newTP);
tp = newTP;
}
}
return true;
}

//+------------------------------------------------------------------+
//| Определение направления ордера |
//+------------------------------------------------------------------+
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;
}

avatar

igrun

  • 25 октября 2025, 20:43
+1
//+------------------------------------------------------------------+
//| DailyTrader.mq4 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| www.mql5.com |
//+------------------------------------------------------------------+
#property copyright «Copyright 2023, MetaQuotes Software Corp.»
#property link «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; // Стоп-лосс в пунктах
input int MagicNumber = 12345; // Магический номер ордеров

//--- Глобальные переменные
datetime lastTradeDate = 0;
datetime lastCloseTime = 0;
bool closeInProgress = false;
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();
// В первую очередь — проверяем необходимость закрытия ордеров в конце дня
if(IsEndOfDayTime() && !closeInProgress)
{
if(lastCloseTime != TimeCurrentDate())
{
Print("=== КОНЕЦ ДНЯ: Начинаем закрытие ордеров ===");
closeInProgress = true;
if(CloseAllOrders())
{
lastCloseTime = TimeCurrentDate();
lastTradeDate = 0; // Сбрасываем дату торговли
Print("=== Все ордера закрыты ===");
}
closeInProgress = false;
}
return;
}
// Сбрасываем флаг закрытия после 01:00
if(TimeHour(currentTime) == 1 && TimeMinute(currentTime) == 0 && lastCloseTime == TimeCurrentDate() — 86400)
{
lastCloseTime = 0;
Print(«Сброс флагов для нового торгового дня»);
}
// Если идет процесс закрытия — не открываем новые ордера
if(closeInProgress) return;
// Проверяем, есть ли открытые ордера — если есть, не открываем новые
if(CountOpenOrders() > 0)
{
// Если сегодня уже должна была быть торговля, но ордера остались — закрываем их
if(lastTradeDate == TimeCurrentDate())
{
Print(«Обнаружены открытые ордера в торговое время. Закрываем...»);
CloseAllOrders();
lastTradeDate = 0; // Сбрасываем дату торговли
}
return;
}
// Проверяем, было ли уже открытие ордера сегодня
if(lastTradeDate == TimeCurrentDate()) return;
// Проверяем время открытия ордера
if(IsTradeTime())
{
Print("=== Время открытия ордера ===");
OpenTrade();
lastTradeDate = TimeCurrentDate();
}
}

//+------------------------------------------------------------------+
//| Проверка времени закрытия (конец дня) |
//+------------------------------------------------------------------+
bool IsEndOfDayTime()
{
datetime currentTime = TimeCurrent();
MqlDateTime timeStruct;
TimeToStruct(currentTime, timeStruct);
// Закрываем с 23:55 до 00:05 (окно 10 минут для надежности)
if((timeStruct.hour == 23 && timeStruct.min >= 55) ||
(timeStruct.hour == 0 && timeStruct.min <= 5))
{
return true;
}
return false;
}

avatar

igrun

  • 25 октября 2025, 20:43
0
//+------------------------------------------------------------------+
//| Обновление размера лота на основе изменения баланса              |
//+------------------------------------------------------------------+
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);
   double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   
   if(currentLot < minLot) currentLot = minLot;
   if(currentLot > maxLot) currentLot = maxLot;
   
   currentLot = MathRound(currentLot / lotStep) * lotStep;
   currentLot = NormalizeDouble(currentLot, 2);
}

//+------------------------------------------------------------------+
//| Расчет стоп-лосса                                               |
//+------------------------------------------------------------------+
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 NormalizeDouble(price - slPoints, Digits);
   else if(orderType == OP_SELL)
      return NormalizeDouble(price + slPoints, Digits);
   
   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 NormalizeDouble(price + tpPoints, Digits);
   else if(orderType == OP_SELL)
      return NormalizeDouble(price - tpPoints, Digits);
   
   return 0;
}

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

//+------------------------------------------------------------------+
//| Подсчет открытых ордеров                                        |
//+------------------------------------------------------------------+
int CountOpenOrders()
{
   int count = 0;
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == 0 && 
            (OrderType() == OP_BUY || OrderType() == OP_SELL))
         {
            count++;
         }
      }
   }
   return count;
}

//+------------------------------------------------------------------+
//| Получение даты без времени                                      |
//+------------------------------------------------------------------+
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";
}

//+------------------------------------------------------------------+
//| Получение описания ошибки                                       |
//+------------------------------------------------------------------+
string GetErrorDescription(int errorCode)
{
   switch(errorCode)
   {
      case 130: return "Неправильные стопы";
      case 131: return "Неправильный объем";
      case 132: return "Неправильная цена";
      case 133: return "Торговля запрещена";
      case 134: return "Недостаточно денег";
      case 135: return "Цена изменилась";
      case 136: return "Нет цен";
      case 137: return "Брокер занят";
      case 138: return "Требуется перезагрузка цен";
      case 139: return "Ордер заблокирован";
      case 140: return "Разрешение на торговлю запрещено";
      case 146: return "Торговая подсистема занята";
      case 4108: return "Ордер не найден";
      default: return "Неизвестная ошибка: " + IntegerToString(errorCode);
   }
}
avatar

igrun

  • 25 октября 2025, 20:26
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;
datetime lastCloseTime = 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();
   
   // Проверяем закрытие ордеров в конце дня (23:59:30 - 00:00:30)
   if(IsEndOfDayTime())
   {
      if(lastCloseTime != TimeCurrentDate())
      {
         Print("Время закрытия ордеров в конце дня: ", TimeToString(currentTime));
         CloseAllOrders();
         lastCloseTime = TimeCurrentDate();
      }
      return;
   }
   
   // Сбрасываем флаг закрытия после 00:30
   if(TimeHour(currentTime) == 0 && TimeMinute(currentTime) >= 30 && lastCloseTime == TimeCurrentDate() - 86400)
   {
      lastCloseTime = 0;
      lastTradeDate = 0;
      Print("Сброс флагов для нового торгового дня: ", TimeToString(currentTime));
   }
   
   // Проверяем, было ли уже открытие ордера сегодня
   if(lastTradeDate == TimeCurrentDate())
      return;
   
   // Проверяем время открытия ордера
   if(IsTradeTime())
   {
      // Перед открытием нового ордера проверяем, что нет открытых ордеров
      if(CountOpenOrders() == 0)
      {
         OpenTrade();
         lastTradeDate = TimeCurrentDate();
      }
      else
      {
         Print("ВНИМАНИЕ: Обнаружены открытые ордера перед открытием нового. Закрываем их.");
         CloseAllOrders();
         // Не открываем новый ордер сегодня, ждем следующего дня
         lastTradeDate = TimeCurrentDate();
      }
   }
}

//+------------------------------------------------------------------+
//| Проверка времени закрытия (конец дня)                           |
//+------------------------------------------------------------------+
bool IsEndOfDayTime()
{
   datetime currentTime = TimeCurrent();
   MqlDateTime timeStruct;
   TimeToStruct(currentTime, timeStruct);
   
   // Закрываем с 23:59:30 до 00:00:30 (окно 1 минута)
   if((timeStruct.hour == 23 && timeStruct.min == 59 && timeStruct.sec >= 30) ||
      (timeStruct.hour == 0 && timeStruct.min == 0 && timeStruct.sec <= 30))
   {
      return true;
   }
   
   return false;
}

//+------------------------------------------------------------------+
//| Проверка времени для открытия ордера                            |
//+------------------------------------------------------------------+
bool IsTradeTime()
{
   datetime currentTime = TimeCurrent();
   MqlDateTime timeStruct;
   TimeToStruct(currentTime, timeStruct);
   
   string tradeTimeStr = TradeTime;
   int tradeHour = (int)StringToInteger(StringSubstr(tradeTimeStr, 0, 2));
   int tradeMinute = (int)StringToInteger(StringSubstr(tradeTimeStr, 3, 2));
   
   return (timeStruct.hour == tradeHour && timeStruct.min == tradeMinute);
}

//+------------------------------------------------------------------+
//| Функция открытия торговли                                        |
//+------------------------------------------------------------------+
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;
   
   // Проверяем корректность стоп-уровней
   if(!ValidateStopLevels(openPrice, sl, tp, orderType))
   {
      Print("Ошибка: Некорректные стоп-уровни. Ордер не открыт.");
      return;
   }
   
   int ticket = OrderSend(Symbol(), orderType, currentLot, openPrice, 3, sl, tp, 
                         "DailyTrade", 0, 0, clrBlue);
   
   if(ticket > 0)
   {
      Print("Ордер открыт: ", OrderTypeToString(orderType), 
            ", Лот: ", currentLot, 
            ", Время: ", TimeToString(TimeCurrent()),
            ", Цена: ", openPrice,
            ", SL: ", sl, 
            ", TP: ", tp);
   }
   else
   {
      Print("Ошибка открытия ордера: ", GetLastError(), " - ", GetErrorDescription(GetLastError()));
   }
}

//+------------------------------------------------------------------+
//| Проверка корректности стоп-уровней                              |
//+------------------------------------------------------------------+
bool ValidateStopLevels(double price, double &sl, double &tp, int orderType)
{
   if(sl == 0 && tp == 0) return true;
   
   double point = MarketInfo(Symbol(), MODE_POINT);
   double spread = MarketInfo(Symbol(), MODE_SPREAD) * point;
   double stopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * point;
   double minDistance = MathMax(stopLevel, spread * 2);
   
   if(orderType == OP_BUY)
   {
      if(sl > 0 && (price - sl) < minDistance)
      {
         double newSL = price - minDistance;
         Print("Корректируем SL для BUY. Было: ", sl, " Стало: ", newSL);
         sl = newSL;
      }
      if(tp > 0 && (tp - price) < minDistance)
      {
         double newTP = price + minDistance;
         Print("Корректируем TP для BUY. Было: ", tp, " Стало: ", newTP);
         tp = newTP;
      }
   }
   else if(orderType == OP_SELL)
   {
      if(sl > 0 && (sl - price) < minDistance)
      {
         double newSL = price + minDistance;
         Print("Корректируем SL для SELL. Было: ", sl, " Стало: ", newSL);
         sl = newSL;
      }
      if(tp > 0 && (price - tp) < minDistance)
      {
         double newTP = price - minDistance;
         Print("Корректируем TP для SELL. Было: ", tp, " Стало: ", newTP);
         tp = newTP;
      }
   }
   
   // Нормализуем цены
   sl = NormalizeDouble(sl, Digits);
   tp = NormalizeDouble(tp, Digits);
   
   return true;
}

//+------------------------------------------------------------------+
//| Определение направления ордера                                   |
//+------------------------------------------------------------------+
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;
}

avatar

igrun

  • 25 октября 2025, 20:26
0
а журнал
avatar

igrun

  • 25 октября 2025, 20:17