← К каталогу
Исходный код · ID 4070

eatelemetry.mqh

Похожие материалы по тегам

one shoot ai v4.mq5MQL5 / MetaTrader 5 · 1 общих теговindicatorgoldy.pineTradingView · 1 общих теговdrawdownmeter.mq4MQL4 / MetaTrader 4 · 1 общих теговaccountequityanalyzer@lifeindreamsworld.mq4MQL4 / MetaTrader 4 · 1 общих теговaccountequityanalyzer v1.1.mq4MQL4 / MetaTrader 4 · 1 общих теговgeniusv101-ecn.mq4MQL4 / MetaTrader 4 · 1 общих тегов
Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

EATelemetry.mqh — библиотека телеметрии для торговых советников MetaTrader 4. Она обеспечивает сбор и сохранение данных о торговых операциях, состоянии корзин сделок и диагностике торговых условий. Библиотека работает с файлами CSV для ведения статистики сделок, истории корзин и диагностических снимков.

Основные возможности включают регистрацию открытия и закрытия сделок, отслеживание максимальной прибыли и просадки корзины, управление списком тикетов в корзине, а также подсчёт количества попыток и триггеров торговых условий. Данные сохраняются в файлы с префиксом, формируемым из имени советника, символа и таймфрейма.

Библиотека поддерживает восстановление состояния корзин и открытых сделок после перезапуска терминала, миграцию устаревших CSV-файлов и очистку финализированных записей. Все операции записи осуществляются в CSV-файлы, расположенные в общей директории данных терминала.

Состав библиотеки

Классов: 3 · методов: 0 · конструкторов: 0 · деструкторов: 0 · отдельных функций: 44

Классы
Класс class TelemetryMetric

Структура для хранения метрики телеметрии с именем и счётчиком.

Класс class TradeTelemetry

Структура для хранения телеметрии отдельной сделки.

Класс class TelemetryBasket

Структура для хранения телеметрии корзины сделок.

Функции
Функция int FindOrAddMetric(TelemetryMetric &arr[], string name)

Находит существующую метрику в массиве по имени или добавляет новую.

Функция int TelemetryFindTradeIndex(int ticket)

Находит индекс сделки в массиве телеметрии по номеру тикета.

Функция void TelemetryRemoveTrade(int idx)

Удаляет запись о сделке из массива телеметрии по индексу.

Функция int TelemetryFindBasketIndex(string basketId)

Находит индекс корзины в массиве истории по идентификатору.

Функция void TelemetryRemoveBasketFromHistory(int idx)

Удаляет корзину из массива истории по индексу.

Функция void TelemetryStoreBasketToHistory(TelemetryBasket &basket)

Сохраняет указанную корзину в массив истории, если она ещё не записана.

Функция void TelemetryStoreCurrentBasketToHistory()

Сохраняет текущую корзину в историю, если она неактивна.

Функция bool TelemetryGetBasketData(string basketId, TelemetryBasket &outBasket)

Возвращает данные корзины по идентификатору из текущей или истории.

Функция bool TelemetryBasketHasOpenTrades(string basketId)

Проверяет, есть ли открытые сделки, принадлежащие указанной корзине.

Функция void TelemetryCleanupFinalizedBasket(string basketId)

Заглушка для очистки финализированной корзины; фактически не удаляет данные.

Функция string TelemetryTimeframe()

Возвращает текстовое обозначение текущего таймфрейма.

Функция string TelemetryCleanFileName(string text)

Заменяет в строке недопустимые символы для имени файла.

Функция string TelemetryGenerateBasketId(string symbol, int magic)

Генерирует уникальный идентификатор корзины из символа и магического номера.

Функция string TelemetryOrderComment(int ticket)

Возвращает комментарий ордера по номеру тикета из активных или истории.

Функция string TelemetryTicketListToString(int &tickets[])

Преобразует массив тикетов в разделённую строку.

Функция void TelemetryParseTicketList(string str, int &tickets[])

Парсит строку с тикетами в массив целых чисел.

Функция string TelemetryBasketToString(TelemetryBasket &basket)

Сериализует данные корзины в разделённую строку полного состояния.

Функция void TelemetryPersistBasket()

Сохраняет текущую корзину в файл состояния, обновляя существующую запись.

Функция void TelemetryRemoveBasketFromFile(string basketId)

Удаляет запись о корзине из файла состояния по идентификатору.

Функция void TelemetryRecoverBaskets(int magic)

Восстанавливает корзины из файла состояния с фильтром по магическому номеру.

Функция void TelemetryMigrateLegacyCSV()

Мигрирует данные из устаревшего CSV-формата в новый формат.

Функция void TelemetryInit(string eaName, int magic)

Инициализирует телеметрию: формирует имена файлов, проверяет миграцию, восстанавливает данные.

Функция void TelemetryHeartbeat()

Обновляет MFE и MAE для открытых сделок при каждом тике.

Функция void TelemetryTradeOpened(int ticket, string symbol, int magic, string type, double lots, double price, string strategy)

Регистрирует открытие сделки в массиве телеметрии.

Функция void TelemetryRecoverOpenTrades(int magic, string strategy)

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

Функция bool TelemetryBasketContainsTicketInBasket(TelemetryBasket &basket, int ticket)

Проверяет, содержит ли указанная корзина данный тикет.

Функция void TelemetryTradeClosed(int ticket, string symbol, int magic, string type, double price, double profit, int duration, string reason, string strategy)

Регистрирует закрытие сделки и записывает данные в CSV-файл статистики.

Функция void TelemetryEvent(string eventName, string symbol, int magic, int ticket, string type, double price, double profit, int duration, string strategy)

Заглушка для события телеметрии; не записывает данные.

Функция void TelemetryAttempt(string metricName)

Увеличивает счётчик попыток для указанной метрики.

Функция void TelemetryTrigger(string metricName)

Увеличивает счётчик выполнений для указанного триггера.

Функция void TelemetryValue(string symbol, int magic, int ticket, string metric, double value, string strategy)

Заглушка для значения телеметрии; не записывает данные.

Функция void TelemetryError(string symbol, int magic, int ticket, string type, double price, double profit, string errorDesc)

Заглушка для ошибки телеметрии; не записывает данные.

Функция void TelemetryBasketAddTicket(int ticket)

Добавляет тикет в список тикетов текущей корзины.

Функция bool TelemetryBasketContainsTicket(int ticket)

Проверяет, принадлежит ли тикет текущей корзине.

Функция void TelemetryBasketUpdate(double currentProfit, int currentLayers, double currentLots)

Обновляет пиковую прибыль, просадку, количество слоёв и лотов корзины.

Функция void TelemetryBasketTradeAdded(int ticket, int layers)

Регистрирует добавление сделки в корзину, обновляя статистику и сохраняя состояние.

Функция void TelemetryWriteBasketClose(double finalProfit, string exitReason)

Заглушка для записи закрытия корзины; не выполняет действий.

Функция void TelemetryBasketClose(double finalProfit, string exitReason)

Фиксирует финальное состояние текущей корзины как закрытую.

Функция void TelemetryBasketCloseFromHistory(string exitReason)

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

Функция string TelemetryGetBasketId()

Возвращает идентификатор текущей активной корзины.

Функция bool TelemetryIsBasketActive()

Возвращает true, если текущая корзина активна.

Функция int TelemetryGetBasketTradeCount()

Возвращает количество сделок в текущей корзине.

Функция void TelemetrySummary()

Записывает итоговую сводку по метрикам и триггерам в CSV-файл.

Функция void TelemetryShutdown()

Завершает работу телеметрии, записывая итоговую сводку в файл.

Получить полный код

Поиск по коду файла

#property strict
#ifndef EATELEMETRY_MQH
#define EATELEMETRY_MQH

struct TelemetryMetric {
   string name;
   int count;
};

struct TradeTelemetry
{
   int      ticket;
   string   symbol;
   int      magic;
   string   type;
   double   lots;

   datetime entryTime;
   double   entryPrice;

   double   highestPrice;
   double   lowestPrice;

   string   strategy;
   string   comment;

   string   basketId;
};

struct TelemetryBasket
{
   string   basketId;
   string   symbol;
   int      magic;
   datetime startTime;

   double   peakProfit;
   double   maxDrawdown;
   double   finalProfit;

   int      ticketList[];
   int      ticketCount;
   int      tradeCount;
   int      maxLayers;
   double   maxLots;

   double   entryStrength;
   double   entrySecondStrength;
   double   entryStrengthGap;
   double   entryROC;
   double   entryStrengthDelta1;
   double   entryStrengthDelta3;
   double   entryStrengthDelta5;

   double   entryADX;
   double   entryATR;
   double   entryAvgATR;
   double   entryATRRatio;

   double   entryEMAFast;
   double   entryEMASlow;

   double   entrySpread;

   string   entryState;
   string   exitReason;

   bool     active;
   bool     finalized;
};

TelemetryMetric g_attempts[];
TelemetryMetric g_triggers[];
TradeTelemetry g_tradeTelemetry[];
int g_totalTrades = 0;

TelemetryBasket g_telemetryBasket;
TelemetryBasket g_telemetryBaskets[];

bool g_telemetryTickReceived = false;
bool g_telemetryWarningShown = false;
int  g_telemetryTickCount = 0;
uint g_telemetryStartTime = 0;

string g_statsFile;
string g_summaryFile;
string g_diagnosticFile;
string g_basketStateFile;

int FindOrAddMetric(TelemetryMetric &arr[], string name)
{
   for(int i=0; i<ArraySize(arr); i++) {
      if(arr[i].name == name) return i;
   }
   int s = ArraySize(arr);
   ArrayResize(arr, s + 1);
   arr[s].name = name;
   arr[s].count = 0;
   return s;
}

int TelemetryFindTradeIndex(int ticket)
{
   for(int i = 0; i < ArraySize(g_tradeTelemetry); i++)
   {
      if(g_tradeTelemetry[i].ticket == ticket)
         return i;
   }
   return -1;
}

void TelemetryRemoveTrade(int idx)
{
   int size = ArraySize(g_tradeTelemetry);
   for(int i = idx; i < size - 1; i++)
   {
      g_tradeTelemetry[i] = g_tradeTelemetry[i + 1];
   }
   if(size > 0)
      ArrayResize(g_tradeTelemetry, size - 1);
}

int TelemetryFindBasketIndex(string basketId)
{
   for(int i = 0; i < ArraySize(g_telemetryBaskets); i++)
   {
      if(g_telemetryBaskets[i].basketId == basketId)
         return i;
   }
   return -1;
}

void TelemetryRemoveBasketFromHistory(int idx)
{
   int size = ArraySize(g_telemetryBaskets);
   for(int i = idx; i < size - 1; i++)
   {
      g_telemetryBaskets[i] = g_telemetryBaskets[i + 1];
   }
   if(size > 0)
      ArrayResize(g_telemetryBaskets, size - 1);
}

void TelemetryStoreBasketToHistory(TelemetryBasket &basket)
{
   if(basket.basketId == "")
      return;

   if(TelemetryFindBasketIndex(basket.basketId) != -1)
      return;

   int idx = ArraySize(g_telemetryBaskets);
   ArrayResize(g_telemetryBaskets, idx + 1);
   g_telemetryBaskets[idx] = basket;
}

void TelemetryStoreCurrentBasketToHistory()
{
   if(g_telemetryBasket.basketId == "")
      return;

   if(g_telemetryBasket.active)
      return;

   TelemetryStoreBasketToHistory(g_telemetryBasket);
}

bool TelemetryGetBasketData(string basketId, TelemetryBasket &outBasket)
{
   if(g_telemetryBasket.basketId == basketId)
   {
      outBasket = g_telemetryBasket;
      return true;
   }

   int idx = TelemetryFindBasketIndex(basketId);
   if(idx != -1)
   {
      outBasket = g_telemetryBaskets[idx];
      return true;
   }

   return false;
}

bool TelemetryBasketHasOpenTrades(string basketId)
{
   for(int i = 0; i < ArraySize(g_tradeTelemetry); i++)
   {
      if(g_tradeTelemetry[i].basketId == basketId)
         return true;
   }
   return false;
}

void TelemetryCleanupFinalizedBasket(string basketId)
{

}

string TelemetryTimeframe()
{
   switch(Period())
   {
      case PERIOD_M1:   return "M1";
      case PERIOD_M5:   return "M5";
      case PERIOD_M15:  return "M15";
      case PERIOD_M30:  return "M30";
      case PERIOD_H1:   return "H1";
      case PERIOD_H4:   return "H4";
      case PERIOD_D1:   return "D1";
      case PERIOD_W1:   return "W1";
      case PERIOD_MN1:  return "MN1";
   }
   return IntegerToString(Period());
}

string TelemetryCleanFileName(string text)
{
   StringReplace(text, " ", "_");
   StringReplace(text, ".", "_");
   StringReplace(text, "/", "_");
   StringReplace(text, "\\", "_");
   StringReplace(text, ":", "_");
   return text;
}

string TelemetryGenerateBasketId(string symbol, int magic)
{
   return IntegerToString(magic) + "_" + symbol + "_" +
          TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS);
}

string TelemetryOrderComment(int ticket)
{
   if(OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES))
      return OrderComment();
   if(OrderSelect(ticket, SELECT_BY_TICKET, MODE_HISTORY))
      return OrderComment();
   return "";
}

string TelemetryTicketListToString(int &tickets[])
{
   string result = "";
   for(int i = 0; i < ArraySize(tickets); i++)
   {
      if(i > 0) result += ";";
      result += IntegerToString(tickets[i]);
   }
   return result;
}

void TelemetryParseTicketList(string str, int &tickets[])
{
   ArrayResize(tickets, 0);
   if(str == "") return;

   string parts[];
   int count = StringSplit(str, ';', parts);
   if(count <= 0) return;

   ArrayResize(tickets, count);
   for(int i = 0; i < count; i++)
   {
      tickets[i] = (int)StringToInteger(parts[i]);
   }
}

string TelemetryBasketToString(TelemetryBasket &basket)
{
   string tickets = TelemetryTicketListToString(basket.ticketList);

   return StringFormat(
      "%s|%s|%d|%d|%.10g|%.10g|%.10g|%d|%.10g|%d|%d|%d|%s|"
      "%.10g|%.10g|%.10g|%.10g|%.10g|%.10g|%.10g|%.10g|%.10g|%.10g|"
      "%.10g|%.10g|%.10g|%s|%s",
      basket.basketId,
      basket.symbol,
      basket.magic,
      (int)basket.startTime,
      basket.peakProfit,
      basket.maxDrawdown,
      basket.finalProfit,
      basket.maxLayers,
      basket.maxLots,
      basket.ticketCount,
      basket.active ? 1 : 0,
      basket.finalized ? 1 : 0,
      tickets,
      basket.entryStrength,
      basket.entrySecondStrength,
      basket.entryStrengthGap,
      basket.entryROC,
      basket.entryStrengthDelta1,
      basket.entryStrengthDelta3,
      basket.entryStrengthDelta5,
      basket.entryADX,
      basket.entryATR,
      basket.entryAvgATR,
      basket.entryATRRatio,
      basket.entryEMAFast,
      basket.entryEMASlow,
      basket.entrySpread,
      basket.entryState,
      basket.exitReason);
}

void TelemetryPersistBasket()
{
   if(g_telemetryBasket.basketId == "")
      return;

   string lines[];
   int lineCount = 0;
   bool found = false;

   int handle = FileOpen(g_basketStateFile, FILE_TXT|FILE_READ|FILE_SHARE_READ);
   if(handle != INVALID_HANDLE)
   {
      while(!FileIsEnding(handle))
      {
         string line = FileReadString(handle);
         if(StringFind(line, g_telemetryBasket.basketId + "|") == 0)
         {
            line = TelemetryBasketToString(g_telemetryBasket);
            found = true;
         }
         ArrayResize(lines, lineCount + 1);
         lines[lineCount] = line;
         lineCount++;
      }
      FileClose(handle);
   }

   if(!found)
   {
      ArrayResize(lines, lineCount + 1);
      lines[lineCount] = TelemetryBasketToString(g_telemetryBasket);
      lineCount++;
   }

   handle = FileOpen(g_basketStateFile, FILE_TXT|FILE_WRITE|FILE_SHARE_READ);
   if(handle != INVALID_HANDLE)
   {
      for(int i = 0; i < lineCount; i++)
         FileWrite(handle, lines[i]);
      FileClose(handle);
   }
}

void TelemetryRemoveBasketFromFile(string basketId)
{
   if(basketId == "")
      return;

   string lines[];
   int lineCount = 0;

   int handle = FileOpen(g_basketStateFile, FILE_TXT|FILE_READ|FILE_SHARE_READ);
   if(handle != INVALID_HANDLE)
   {
      while(!FileIsEnding(handle))
      {
         string line = FileReadString(handle);
         if(StringFind(line, basketId + "|") != 0)
         {
            ArrayResize(lines, lineCount + 1);
            lines[lineCount] = line;
            lineCount++;
         }
      }
      FileClose(handle);
   }

   handle = FileOpen(g_basketStateFile, FILE_TXT|FILE_WRITE|FILE_SHARE_READ);
   if(handle != INVALID_HANDLE)
   {
      for(int i = 0; i < lineCount; i++)
         FileWrite(handle, lines[i]);
      FileClose(handle);
   }
}

void TelemetryRecoverBaskets(int magic = 0)
{
   int handle = FileOpen(g_basketStateFile, FILE_TXT|FILE_READ|FILE_SHARE_READ);
   if(handle == INVALID_HANDLE)
      return;

   while(!FileIsEnding(handle))
   {
      string line = FileReadString(handle);
      if(line == "") continue;

      string parts[];
      if(StringSplit(line, '|', parts) < 29) continue;

      TelemetryBasket basket;
      basket.basketId            = parts[0];
      basket.symbol              = parts[1];
      basket.magic               = (int)StringToInteger(parts[2]);
      basket.startTime           = (datetime)StringToInteger(parts[3]);
      basket.peakProfit          = StringToDouble(parts[4]);
      basket.maxDrawdown         = StringToDouble(parts[5]);
      basket.finalProfit         = StringToDouble(parts[6]);
      basket.maxLayers           = (int)StringToInteger(parts[7]);
      basket.maxLots             = StringToDouble(parts[8]);
      basket.ticketCount         = (int)StringToInteger(parts[9]);
      basket.active              = ((int)StringToInteger(parts[10]) != 0);
      basket.finalized           = ((int)StringToInteger(parts[11]) != 0);

      TelemetryParseTicketList(parts[12], basket.ticketList);
      basket.ticketCount         = ArraySize(basket.ticketList);

      basket.entryStrength       = StringToDouble(parts[13]);
      basket.entrySecondStrength = StringToDouble(parts[14]);
      basket.entryStrengthGap    = StringToDouble(parts[15]);
      basket.entryROC            = StringToDouble(parts[16]);
      basket.entryStrengthDelta1 = StringToDouble(parts[17]);
      basket.entryStrengthDelta3 = StringToDouble(parts[18]);
      basket.entryStrengthDelta5 = StringToDouble(parts[19]);
      basket.entryADX            = StringToDouble(parts[20]);
      basket.entryATR            = StringToDouble(parts[21]);
      basket.entryAvgATR         = StringToDouble(parts[22]);
      basket.entryATRRatio       = StringToDouble(parts[23]);
      basket.entryEMAFast        = StringToDouble(parts[24]);
      basket.entryEMASlow        = StringToDouble(parts[25]);
      basket.entrySpread         = StringToDouble(parts[26]);
      basket.entryState          = parts[27];
      basket.exitReason          = parts[28];

      if(magic != 0 && basket.magic != magic) continue;

      if(basket.active)
         g_telemetryBasket = basket;
      else if(basket.finalized)
         TelemetryStoreBasketToHistory(basket);
   }
   FileClose(handle);
}

void TelemetryMigrateLegacyCSV()
{
   string lines[];
   int lineCount = 0;

   int oldHandle = FileOpen(g_statsFile, FILE_TXT|FILE_READ|FILE_SHARE_READ);
   if(oldHandle == INVALID_HANDLE) return;

   if(!FileIsEnding(oldHandle))
      FileReadString(oldHandle);

   while(!FileIsEnding(oldHandle))
   {
      string line = FileReadString(oldHandle);
      if(line != "")
      {
         ArrayResize(lines, lineCount + 1);
         lines[lineCount] = line;
         lineCount++;
      }
   }
   FileClose(oldHandle);

   if(lineCount == 0) return;

   string openTickets[];
   string openData[];
   int openCount = 0;

   string closeData[];
   int closeCount = 0;

   for(int i = 0; i < lineCount; i++)
   {
      string fields[];
      int fieldCount = StringSplit(lines[i], ',', fields);

      if(fieldCount < 5) continue;

      string event = fields[4];

      if(event == "TRADE_OPEN")
      {
         string ticket = fields[3];
         int foundIdx = -1;
         for(int j = 0; j < openCount; j++)
         {
            if(openTickets[j] == ticket)
            {
               foundIdx = j;
               break;
            }
         }

         if(foundIdx == -1)
         {
            ArrayResize(openTickets, openCount + 1);
            ArrayResize(openData, openCount + 1);
            openTickets[openCount] = ticket;
            openData[openCount] = lines[i];
            openCount++;
         }
         else
         {
            openData[foundIdx] = lines[i];
         }
      }
      else if(event != "BASKET_START" &&
              event != "BASKET_CLOSE" &&
              event != "VALUE" &&
              event != "ERROR" &&
              fields[3] != "0")
      {
         ArrayResize(closeData, closeCount + 1);
         closeData[closeCount] = lines[i];
         closeCount++;
      }
   }

   string legacyFile = StringSubstr(g_statsFile, 0, StringLen(g_statsFile) - 4) + "_legacy.csv";
   FileMove(g_statsFile, 0, legacyFile, FILE_REWRITE|FILE_COMMON);

   int newHandle = FileOpen(g_statsFile, FILE_CSV|FILE_READ|FILE_WRITE|FILE_SHARE_READ, ',');
   if(newHandle == INVALID_HANDLE) return;

   FileWrite(newHandle,
      "EntryTime", "ExitTime", "Symbol", "Magic", "Ticket", "Type", "Lots",
      "EntryPrice", "ExitPrice", "Profit", "Duration", "Strategy", "Comment",
      "MFE", "MAE", "MFE_Points", "MAE_Points", "BasketID", "BasketPeakProfit",
      "BasketMaxDrawdown", "ProfitCapture", "BasketMaxLayers", "BasketMaxLots", "ExitReason");

   for(int i = 0; i < closeCount; i++)
   {
      string closeFields[];
      StringSplit(closeData[i], ',', closeFields);

      if(ArraySize(closeFields) < 7) continue;

      string ticket      = closeFields[3];
      string exitTime    = closeFields[0];
      string symbol      = closeFields[1];
      int    magic       = (int)StringToInteger(closeFields[2]);
      string type        = closeFields[5];
      string exitPrice   = closeFields[6];
      string profit      = (ArraySize(closeFields) > 7) ? closeFields[7] : "0.00";
      string duration    = (ArraySize(closeFields) > 8) ? closeFields[8] : "0";
      string strategy    = (ArraySize(closeFields) > 9) ? closeFields[9] : "";
      string comment     = (ArraySize(closeFields) > 10) ? closeFields[10] : "";
      string mfe         = (ArraySize(closeFields) > 11) ? closeFields[11] : "";
      string mae         = (ArraySize(closeFields) > 12) ? closeFields[12] : "";
      string mfePoints   = (ArraySize(closeFields) > 13) ? closeFields[13] : "";
      string maePoints   = (ArraySize(closeFields) > 14) ? closeFields[14] : "";
      string basketId    = (ArraySize(closeFields) > 15) ? closeFields[15] : "";
      string peakProfit  = (ArraySize(closeFields) > 16) ? closeFields[16] : "";
      string maxDrawdown = (ArraySize(closeFields) > 17) ? closeFields[17] : "";
      string profitCap   = (ArraySize(closeFields) > 18) ? closeFields[18] : "";
      string maxLayers   = (ArraySize(closeFields) > 19) ? closeFields[19] : "";
      string maxLots     = (ArraySize(closeFields) > 20) ? closeFields[20] : "";
      string exitReason  = closeFields[4];

      string entryTime  = "";
      string entryPrice = "";

      for(int j = 0; j < openCount; j++)
      {
         if(openTickets[j] == ticket)
         {
            string openFields[];
            StringSplit(openData[j], ',', openFields);

            if(ArraySize(openFields) >= 7)
            {
               entryTime  = openFields[0];
               entryPrice = openFields[6];
            }
            break;
         }
      }

      FileWrite(newHandle,
         entryTime, exitTime, symbol, magic, ticket, type, "",
         entryPrice, exitPrice, profit, (int)StringToInteger(duration),
         strategy, comment, mfe, mae, mfePoints, maePoints,
         basketId, peakProfit, maxDrawdown, profitCap,
         (int)StringToInteger(maxLayers), maxLots, exitReason);
   }

   FileClose(newHandle);
}

void TelemetryInit(string eaName = "", int magic = 0)
{
   if(eaName == "") eaName = WindowExpertName();
   eaName = TelemetryCleanFileName(eaName);

   string prefix =
         eaName + "_"
       + Symbol() + "_"
       + TelemetryTimeframe();

   g_statsFile      = prefix + "_Stats.csv";
   g_summaryFile    = prefix + "_Summary.csv";
   g_diagnosticFile = prefix + "_Diagnostics.csv";
   g_basketStateFile = prefix + "_BasketState.csv";

   bool headerWritten = false;
   int checkHandle = FileOpen(g_statsFile, FILE_TXT|FILE_READ|FILE_SHARE_READ);

   if(checkHandle != INVALID_HANDLE)
   {
      if(FileSize(checkHandle) > 0)
      {
         string firstLine = FileReadString(checkHandle);

         if(StringFind(firstLine, "Event") != -1 && StringFind(

Показано первые 50% кода (символов: 25406)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
2 540,60₽ ≈ $31.05