0
то есть все равно не закрывает
avatar

igrun

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

//+------------------------------------------------------------------+
//| Обновление размера лота на основе изменения баланса              |
//+------------------------------------------------------------------+
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;
   
   // Проверяем шаг лота
   double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   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;
}

//+------------------------------------------------------------------+
//| Закрытие всех ордеров                                           |
//+------------------------------------------------------------------+
void CloseAllOrders()
{
   int closedCount = 0;
   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))
            {
               closedCount++;
               Print("Ордер закрыт в 00:00: ", OrderTypeToString(OrderType()), 
                     ", Прибыль: ", OrderProfit());
            }
            else
            {
               Print("Ошибка закрытия ордера ", OrderTypeToString(OrderType()), ": ", 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)
         {
            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 "Торговая подсистема занята.";
      default: return "Неизвестная ошибка.";
   }
}
avatar

igrun

  • 25 октября 2025, 20:00
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 lastCloseCheck = 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 (проверяем каждую минуту с 00:00 до 00:01)
   if(timeStruct.hour == 0 && timeStruct.min == 0 && currentTime - lastCloseCheck >= 60)
   {
      Print("Проверка закрытия ордеров в 00:00");
      CloseAllOrders();
      lastCloseCheck = currentTime;
      // Не сбрасываем lastTradeDate здесь, чтобы новый ордер мог открыться в заданное время
      return;
   }
   
   // Сбрасываем флаг закрытия после 00:01
   if(timeStruct.hour == 0 && timeStruct.min == 1 && lastCloseCheck > 0)
   {
      lastCloseCheck = 0;
      lastTradeDate = 0; // Сбрасываем дату торговли для нового дня
      Print("Сброс флагов для нового торгового дня");
   }
   
   // Проверяем, было ли уже открытие ордера сегодня
   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)
   {
      // Перед открытием нового ордера проверяем, что нет открытых ордеров
      if(CountOpenOrders() == 0)
      {
         OpenTrade();
         lastTradeDate = TimeCurrentDate();
      }
      else
      {
         Print("ВНИМАНИЕ: Обнаружены открытые ордера перед открытием нового. Закрываем их.");
         CloseAllOrders();
      }
   }
}

//+------------------------------------------------------------------+
//| Функция открытия торговли                                        |
//+------------------------------------------------------------------+
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()), ", SL: ", sl, ", TP: ", tp);
   }
   else
   {
      Print("Ошибка открытия ордера: ", GetLastError(), " - ", GetErrorDescription(GetLastError()));
   }
}

avatar

igrun

  • 25 октября 2025, 19:59
0
// Нормализуем цены
   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;
}

//+------------------------------------------------------------------+
//| Обновление размера лота на основе изменения баланса              |
//+------------------------------------------------------------------+
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;
   
   // Проверяем шаг лота
   double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   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;
}

//+------------------------------------------------------------------+
//| Закрытие всех ордеров                                           |
//+------------------------------------------------------------------+
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";
}

//+------------------------------------------------------------------+
//| Получение описания ошибки                                       |
//+------------------------------------------------------------------+
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 "Торговая подсистема занята.";
      default: return "Неизвестная ошибка.";
   }
}
avatar

igrun

  • 25 октября 2025, 19:34
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;
   
   // Проверяем корректность стоп-уровней
   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()));
   }
   else
   {
      Print("Ошибка открытия ордера: ", GetLastError(), " - ", GetErrorDescription(GetLastError()));
   }
}

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

igrun

  • 25 октября 2025, 19:34
0
пополам
avatar

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

igrun

  • 24 октября 2025, 15:37
0
ну уж как смог
avatar

igrun

  • 19 октября 2025, 02:34
0
покаж
avatar

igrun

  • 17 октября 2025, 14:00
0
8.2. Простая установка:
Открыть MetaTrader 5

Найти индикатор в списке

Перетащить на график

Наслаждаться картинкой!

9. Что делать с этой информацией?
9.1. Простые стратегии:
Стратегия 1: Торговля флета

Ждем когда много зеленых линий

Покупаем у нижней границы, продаем у верхней

Стратегия 2: Торговля тренда

Ждем когда много красных линий

Покупаем если тренд вверх, продаем если вниз

Стратегия 3: Ожидание

Когда все белые — ждем пока рынок «проснется»

10. Важно помнить!
❗ Это помощник, а не волшебная палочка

❗ Всегда проверяйте другими способами

❗ Не рискуйте деньгами которые боитесь потерять

❗ Начинайте с маленьких сумм

Уровень сложности: ★☆☆☆☆ (очень простой)
Для кого: Для начинающих трейдеров
Что нужно знать: Как открыть MetaTrader 5
avatar

igrun

  • 6 октября 2025, 19:43
0
4. Что видно на графике?
4.1. Окно индикатора:
text
[ -1.0 ] ← Красная зона (ТРЕНД)
[ -0.15] ← Граница
[ 0.0 ] ← Центр
[ +0.15] ← Граница
[ +1.0 ] ← Зеленая зона (ФЛЕТ)
4.2. Пример что видит пользователь:
text
=== МУЛЬТИВАЛЮТНЫЙ ПОТОК ===
Время: 12:00:00 | Таймфрейм: H1
=========================
???? EURUSD: +0.23 (ФЛЕТ)
???? GBPUSD: -0.19 (ТРЕНД)
⚪ USDJPY: +0.05 (НЕЙТРАЛЬНО)
???? USDCHF: +0.31 (ФЛЕТ)
???? AUDUSD: -0.22 (ТРЕНД)
=========================
ВСЕГО: ФЛЕТОВ: 2 | ТРЕНДОВ: 2
5. Зачем это нужно?
5.1. Для новичков:
Видеть какие деньги двигаются, а какие стоят

Не торговать когда все в флете — будет скучно

Ловить моменты когда деньги начинают двигаться

5.2. Для продвинутых:
Находить куда перетекают деньги (из фунта в евро и т.д.)

Видеть общую картину рынка

Выбирать самые активные пары для торговли

6. Как это работает?
6.1. Простой принцип:
Смотрит на 50 последних свечек

Считает насколько сильно цена двигалась

Если двигалась мало → показывает ФЛЕТ (зеленый)

Если двигалась много → показывает ТРЕНД (красный)

6.2. Пример расчета:
ФЛЕТ: Цена ходила ± 10 пунктов → +0.8 (зеленый)

ТРЕНД: Цена ушла на 100 пунктов → -0.7 (красный)

НЕЙТРАЛЬНО: Цена двигалась средне → +0.1 (белый)

7. Как настроить под себя?
7.1. Для разных стилей торговли:
Если любишь быструю торговлю:

mql5
AnalysisPeriod = 20 // Смотреть меньше свечек
FlatThreshold = 0.10 // Быстрее реагировать
Если любишь медленную торговлю:

mql5
AnalysisPeriod = 100 // Смотреть больше свечек
FlatThreshold = 0.20 // Медленнее реагировать
8. Что нужно чтобы заработало?
8.1. Минимальные требования:
Компьютер с MetaTrader 5

Интернет (чтобы данные приходили)

Валютные пары в «Обзоре рынка»

8.2. Простая установка:
Открыть MetaTrader 5

Найти индикатор в списке

Перетащить на график

Наслаждаться картинкой!

9. Что делать с этой информацией?
9.1. Простые стратегии:
Стратегия 1: Торговля флета

Ждем когда много зеленых линий

Покупаем у нижней границы, продаем у верхней

Стратегия 2: Торговля тренда

Ждем когда много красных линий

Покупаем если тренд вверх, продаем если вниз

Стратегия 3: Ожидание

Когда все белые — ждем пока рынок «проснется»

10. Важно помнить!
❗ Это помощник, а не волшебная палочка

❗ Всегда проверяйте другими способами

❗ Не рискуйте деньгами которые боитесь потерять

❗ Начинайте с маленьких сумм

Уровень сложности: ★☆☆☆☆ (очень простой)
Для кого: Для начинающих трейдеров
Что нужно знать: Как открыть MetaTrader 5
avatar

igrun

  • 6 октября 2025, 19:42
0
Техническое задание для индикатора «Мультивалютный поток флета»
1. Что это такое?
Этот индикатор показывает, какие валютные пары сейчас находятся в флете (стоят на месте) или в тренде (двигаются вверх или вниз).

2. Что он делает?
2.1. Показывает линии для разных денег
Синяя линия — евро/доллар (EURUSD)

Красная линия — фунт/доллар (GBPUSD)

Зеленая линия — доллар/йена (USDJPY)

Фиолетовая линия — доллар/франк (USDCHF)

И еще много других валют!

2.2. Объясняет что значат линии:
???? ЗЕЛЕНАЯ ЗОНА (+0.15 до +1.0) — ФЛЕТ (деньги стоят на месте)

⚪ БЕЛАЯ ЗОНА (-0.15 до +0.15) — НЕПОНЯТНО (ни туда ни сюда)

???? КРАСНАЯ ЗОНА (-0.15 до -1.0) — ТРЕНД (деньги сильно двигаются)

3. Как пользоваться?
3.1. Простые настройки:
mql5
// Сколько свечек смотреть назад?
AnalysisPeriod = 50

// Насколько сильно должно двигаться чтобы считать трендом?
FlatThreshold = 0.15

// Показывать цифры? (да/нет)
ShowStrengthValues = true
3.2. Какие деньги показывать:
✅ Основные валюты (евро, фунт, йена...)

✅ Другие валюты (кросс-пары)

✅ Золото и серебро

✅ Криптовалюты (биткоин, эфириум...)

4. Что видно на графике?
4.1. Окно индикатора:
text
[ -1.0 ] ← Красная зона (ТРЕНД)
[ -0.15] ← Граница
[ 0.0 ] ← Центр
[ +0.15] ← Граница
[ +1.0 ] ← Зеленая зона (ФЛЕТ)
4.2. Пример что видит пользователь:
text
=== МУЛЬТИВАЛЮТНЫЙ ПОТОК ===
Время: 12:00:00 | Таймфрейм: H1
=========================
???? EURUSD: +0.23 (ФЛЕТ)
???? GBPUSD: -0.19 (ТРЕНД)
⚪ USDJPY: +0.05 (НЕЙТРАЛЬНО)
???? USDCHF: +0.31 (ФЛЕТ)
???? AUDUSD: -0.22 (ТРЕНД)
=========================
ВСЕГО: ФЛЕТОВ: 2 | ТРЕНДОВ: 2
5. Зачем это нужно?
5.1. Для новичков:
Видеть какие деньги двигаются, а какие стоят

Не торговать когда все в флете — будет скучно

Ловить моменты когда деньги начинают двигаться

5.2. Для продвинутых:
Находить куда перетекают деньги (из фунта в евро и т.д.)

Видеть общую картину рынка

Выбирать самые активные пары для торговли

6. Как это работает?
6.1. Простой принцип:
Смотрит на 50 последних свечек

Считает насколько сильно цена двигалась

Если двигалась мало → показывает ФЛЕТ (зеленый)

Если двигалась много → показывает ТРЕНД (красный)

6.2. Пример расчета:
ФЛЕТ: Цена ходила ± 10 пунктов → +0.8 (зеленый)

ТРЕНД: Цена ушла на 100 пунктов → -0.7 (красный)

НЕЙТРАЛЬНО: Цена двигалась средне → +0.1 (белый)

7. Как настроить под себя?
7.1. Для разных стилей торговли:
Если любишь быструю торговлю:

mql5
AnalysisPeriod = 20 // Смотреть меньше свечек
FlatThreshold = 0.10 // Быстрее реагировать
Если любишь медленную торговлю:

mql5
AnalysisPeriod = 100 // Смотреть больше свечек
FlatThreshold = 0.20 // Медленнее реагировать
8. Что нужно чтобы заработало?
8.1. Минимальные требования:
Компьютер с MetaTrader 5

Интернет (чтобы данные приходили)

Валютные пары в «Обзоре рынка»

8.2. Простая установка:
Открыть MetaTrader 5

Найти индикатор в списке

Перетащить на график

Наслаждаться картинкой!

9. Что делать с этой информацией?
9.1. Простые стратегии:
Стратегия 1: Торговля флета

Ждем когда много зеленых линий

Покупаем у нижней границы, продаем у верхней

Стратегия 2: Торговля тренда

Ждем когда много красных линий

Покупаем если тренд вверх, продаем если вниз

Стратегия 3: Ожидание

Когда все белые — ждем пока рынок «проснется»

10. Важно помнить!
❗ Это помощник, а не волшебная палочка

❗ Всегда проверяйте другими способами

❗ Не рискуйте деньгами которые боитесь потерять

❗ Начинайте с маленьких сумм

Уровень сложности: ★☆☆☆☆ (очень простой)
Для кого: Для начинающих трейдеров
Что нужно знать: Как открыть MetaTrader 5
avatar

igrun

  • 6 октября 2025, 19:42
0
бишь ну как
avatar

igrun

  • 6 октября 2025, 01:19
0
3.3. Входные параметры
Параметр Тип Значение по умолчанию Описание
AnalysisPeriod int 50 Период анализа для расчета флета
FlatThreshold double 0.15 Порог определения флета/тренда
ShowStrengthValues bool true Показывать значения в комментарии
EnableMajors bool true Включить основные валюты
EnableCrosses bool true Включить кросс-пары
EnableMetals bool true Включить металлы
EnableCrypto bool true Включить криптовалюты
LoadFullHistory bool true Загружать полную историю
HistoryBarsToLoad int 5000 Количество баров истории
MultiTimeframe bool true Мультитаймфрейм анализ
AnalysisTimeframe enum PERIOD_CURRENT Таймфрейм для анализа
4. Визуализация
4.1. Окно индикатора
Отдельное окно с фиксированной шкалой (-1.0 до +1.0)

Цветные линии для каждого инструмента

Горизонтальные уровни для ориентира

Легенда с названиями инструментов

4.2. Цветовая схема
???? Синий — EURUSD

???? Красный — GBPUSD

???? Зеленый — USDJPY

???? Фиолетовый — USDCHF

???? Оранжевый — AUDUSD

???? Пурпурный — USDCAD

???? Голубой — NZDUSD

???? Золотой — EURGBP

4.3. Комментарий на графике
text
=== UNIVERSAL FLAT FLOW MTF ===
TIME: 2024.01.01 12:00:00 | TF: H1
SCALE: ???? +0.15 to +1.0 = FLAT | ⚪ Neutral | ???? -0.15 to -1.0 = TREND
================================
???? EURUSD: +0.234
???? GBPUSD: -0.189
⚪ USDJPY: +0.045

================================
TOTAL: FLATS: 3 | TRENDS: 2 | NEUTRAL: 1
MAJORS: 2/5 FLAT | CROSSES: 1/3 FLAT
METALS: 0/1 FLAT | CRYPTO: 0/2 FLAT
HISTORY: FULL | BARS: 5000
5. Алгоритм работы
5.1. Инициализация
Парсинг списка инструментов по группам

Проверка доступности символов

Загрузка исторических данных

Инициализация буферов отображения

5.2. Расчет на каждом тике
Получение данных для каждого инструмента

Расчет силы флета по алгоритму волатильности

Обновление буферов отображения

Вывод информации в комментарий

5.3. Обработка ошибок
Автоматическое добавление символов в Обзор рынка

Повторные попытки получения данных

Визуальная индикация недоступных символов

6. Требования к системе
6.1. Минимальные требования
MetaTrader 5

Доступ к рыночным данным

100 Мб свободной памяти

Стабильное интернет-соединение

6.2. Рекомендуемые настройки
Для долгосрочного анализа:

text
HistoryBarsToLoad = 10000
AnalysisTimeframe = PERIOD_D1
Для внутридневной торговли:

text
HistoryBarsToLoad = 2000
AnalysisTimeframe = PERIOD_H1
Для скальпинга:

text
HistoryBarsToLoad = 1000
AnalysisTimeframe = PERIOD_M5
7. Сценарии использования
7.1. Анализ рыночных состояний
Определение общего настроения рынка

Выявление перетоков между инструментами

Анализ волатильности по группам активов

7.2. Торговые стратегии
Торговля пробоями из флета

Арбитраж между коррелированными инструментами

Хеджирование позиций

7.3. Risk Management
Мониторинг рыночной волатильности

Выявление периодов застоя/активности

Анализ корреляций между инструментами

8. Ограничения
8.1. Технические ограничения
Максимум 28 инструментов одновременно

Зависимость от качества данных брокера

Производительность при большом HistoryBarsToLoad

8.2. Функциональные ограничения
Не учитывает фундаментальные факторы

Основан только на ценовых данных

Требует наличия символов в Обзоре рынка

9. Дальнейшее развитие
9.1. Планируемые улучшения
Добавление оповещений о перетоках

Экспорт данных в файл

Интеграция с торговыми системами

Дополнительные алгоритмы анализа

9.2. Возможные модификации
Пользовательские списки инструментов

Дополнительные индикаторы волатильности

Адаптивные пороги определения флета

Машинное обучение для классификации состояний

avatar

igrun

  • 6 октября 2025, 01:18
0
3. Технические характеристики
3.1. Поддерживаемые инструменты
Основные валютные пары (7):

EURUSD, GBPUSD, USDJPY, USDCHF, AUDUSD, USDCAD, NZDUSD

Кросс-пары (9):

EURGBP, EURJPY, GBPJPY, EURAUD, EURCAD, GBPAUD, GBPCAD, AUDJPY, CADJPY

Металлы (6):

XAUUSD, XAGUSD, XAUAUD, XAUEUR, XPTUSD, XPDUSD

Криптовалюты (8):

BTCUSD, ETHUSD, XRPUSD, LTCUSD, BCHUSD, ADAUSD, DOTUSD, LINKUSD

3.2. Алгоритм расчета
Формула силы флета:

text
Сила_флета = 1 — (Среднее_изменение_цены / Средний_истинный_диапазон)
Нормализованная_сила = (Сила_флета — 0.5) * 2.0
Интерпретация значений:

+0.15 до +1.0 = СИЛЬНЫЙ ФЛЕТ (боковое движение)

-0.15 до +0.15 = НЕЙТРАЛЬНОЕ СОСТОЯНИЕ

-0.15 до -1.0 = СИЛЬНЫЙ ТРЕНД (направленное движение)
avatar

igrun

  • 6 октября 2025, 01:17
0
Техническое задание: Универсальный индикатор «MultiCurrency Flat Flow»
1. Общее описание
MultiCurrency Flat Flow — мультивалютный индикатор для анализа состояния флета/тренда на множестве финансовых инструментов с поддержкой мультитаймфреймного анализа и загрузки полной исторической данных.

2. Функциональное назначение
2.1. Основная функция
Определение силы флета/тренда для множества инструментов в реальном времени

Визуализация перетоков капитала между инструментами

Анализ рыночной волатильности и состояния рынка

2.2. Ключевые возможности
Мультивалютный анализ (до 28 инструментов)

Мультитаймфреймный анализ (M1 — MN1)

Загрузка глубокой исторической данных

Группировка инструментов по категориям

Визуализация в отдельном окне
avatar

igrun

  • 6 октября 2025, 01:17
0
бишь как обновить пример моего кода5
avatar

igrun

  • 5 октября 2025, 20:55
0
я вообще почти на заборе решил купить пк
avatar

igrun

  • 4 октября 2025, 19:01
0
нет — индюк ищет перетекание флета между парами
avatar

igrun

  • 4 октября 2025, 18:38
0
а то что там используется новый редкий принцип — нейросеть не увидела…
avatar

igrun

  • 4 октября 2025, 18:25