326 lines
27 KiB
MQL5
326 lines
27 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| OptimizationProject.mqh |
|
|
//| Copyright 2025, Yuriy Bykov |
|
|
//| https://www.mql5.com/ru/users/antekov |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2025, Yuriy Bykov"
|
|
#property link "https://www.mql5.com/ru/articles/17328"
|
|
#property version "1.01"
|
|
|
|
#include "../Database/Database.mqh"
|
|
|
|
// Предварительное объявление класса проекта оптимизации
|
|
class COptimizationProject;
|
|
|
|
#include "OptimizationTask.mqh"
|
|
#include "OptimizationJob.mqh"
|
|
#include "OptimizationStage.mqh"
|
|
|
|
// Создание нового типа - указателя на функцию генерации строки
|
|
// параметров работы оптимизации (job), принимающей в качестве
|
|
// аргумента указатель на объект проекта оптимизации
|
|
typedef string (*TJobsTemplateFunc)(COptimizationProject*);
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Класс для проекта оптимизации |
|
|
//+------------------------------------------------------------------+
|
|
class COptimizationProject {
|
|
public:
|
|
string m_fileName; // Имя базы данных
|
|
|
|
// Свойства, напрямую сохраняемые в базе данных
|
|
ulong id_project; // Идентификатор проекта
|
|
string name; // Название
|
|
string version; // Версия
|
|
string description; // Описание
|
|
string status; // Статус
|
|
|
|
// Массивы всех этапов, работ и задач проекта
|
|
COptimizationStage* m_stages[]; // Этапы проекта
|
|
COptimizationJob* m_jobs[]; // Работы всех этапов проекта
|
|
COptimizationTask* m_tasks[]; // Задачи всех работ этапов проекта
|
|
|
|
// Свойства для текущего состояния процесса создания проекта
|
|
string m_symbol; // Текущий символ
|
|
string m_timeframe; // Текущий таймфрейм
|
|
|
|
COptimizationStage* m_stage; // Последний созданный этап (текущий этап)
|
|
COptimizationJob* m_job; // Последняя созданная работа (текущая работа)
|
|
COptimizationTask* m_task; // Последняя созданная задача (текущая задача)
|
|
|
|
|
|
// Методы
|
|
COptimizationProject(string p_fileName); // Конструктор
|
|
~COptimizationProject(); // Дестрктор
|
|
|
|
// Создание нового проекта в базе данных
|
|
COptimizationProject* COptimizationProject::Create(string p_name,
|
|
string p_version = "", string p_description = "", string p_status = "Done");
|
|
|
|
void Insert(); // Вставка записи в базу данных
|
|
void Update(); // Обновление записи в базе данных
|
|
|
|
// Добавление нового этапа в базу данных
|
|
COptimizationProject* AddStage(COptimizationStage* parentStage, string stageName, string stageExpertName,
|
|
string stageSymbol, string stageTimeframe, int stageOptimization, int stageModel,
|
|
datetime stageFromDate, datetime stageToDate,
|
|
int stageForwardMode, datetime stageForwardDate,
|
|
int stageDeposit = 10000, string stageCurrency = "USD",
|
|
int stageProfitInPips = 0, int stageLeverage = 200,
|
|
int stageExecutionMode = 0, int stageOptimizationCriterion = 7,
|
|
string stageStatus = "Done");
|
|
|
|
// Добавление новых работ в базу данных для заданных символов и таймфреймов
|
|
COptimizationProject* AddJobs(string p_symbols, string p_timeframes, TJobsTemplateFunc p_templateFunc);
|
|
COptimizationProject* AddJobs(string &p_symbols[], string &p_timeframes[], TJobsTemplateFunc p_templateFunc);
|
|
|
|
// Добавление новых задач в базу данных для заданных критериев оптимизации
|
|
COptimizationProject* AddTasks(string p_criterions);
|
|
COptimizationProject* AddTasks(string &p_criterions[]);
|
|
|
|
void Queue(); // Постановка проекта в очередь на выполненеие
|
|
|
|
// Преобразование строкового названия в таймфрейм
|
|
static ENUM_TIMEFRAMES StringToTimeframe(string s);
|
|
};
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Конструктор |
|
|
//+------------------------------------------------------------------+
|
|
COptimizationProject::COptimizationProject(string p_fileName) :
|
|
m_fileName(p_fileName), id_project(0) {
|
|
// Подключаемся к базе данных
|
|
if (DB::Connect(m_fileName)) {
|
|
// Начинаем транзакцию
|
|
DatabaseTransactionBegin(DB::Id());
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Деструктор |
|
|
//+------------------------------------------------------------------+
|
|
COptimizationProject::~COptimizationProject() {
|
|
// Если не возникло ошибок, то
|
|
if(DB::Res()) {
|
|
// Подтверждаем транзакцию
|
|
DatabaseTransactionCommit(DB::Id());
|
|
} else {
|
|
// Иначе отменяем транзакцию
|
|
DatabaseTransactionRollback(DB::Id());
|
|
}
|
|
// Закрываем соединение с базой данных
|
|
DB::Close();
|
|
|
|
// Удаляем созданные объекты задач, работ и этапов
|
|
FOREACH(m_tasks) {
|
|
delete m_tasks[i];
|
|
}
|
|
FOREACH(m_jobs) {
|
|
delete m_jobs[i];
|
|
}
|
|
FOREACH(m_stages) {
|
|
delete m_stages[i];
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Создание нового проекта в базе данных |
|
|
//+------------------------------------------------------------------+
|
|
COptimizationProject* COptimizationProject::Create(string p_name,
|
|
string p_version = "", string p_description = "", string p_status = "Done") {
|
|
// Устанавливаем переданные значения свойств
|
|
name = p_name;
|
|
version = p_version;
|
|
description = p_description;
|
|
status = p_status;
|
|
|
|
// Вставляем в базу данных
|
|
Insert();
|
|
|
|
return &this;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Вставка записи в базу данных |
|
|
//+------------------------------------------------------------------+
|
|
void COptimizationProject::Insert() {
|
|
string query = StringFormat("INSERT INTO projects "
|
|
" VALUES (NULL,'%s','%s','%s',NULL,'%s');",
|
|
name, version, description, status);
|
|
id_project = DB::Insert(query);
|
|
PrintFormat(__FUNCTION__" | %s -> %I64u", query, id_project);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Обновление записи в базе данных |
|
|
//+------------------------------------------------------------------+
|
|
void COptimizationProject::Update() {
|
|
string query = StringFormat("UPDATE projects "
|
|
" SET name='%s', version='%s',description='%s',status='%s' "
|
|
" WHERE id_project=%I64u;",
|
|
name, version, description, status, id_project);
|
|
DB::Execute(query);
|
|
PrintFormat(__FUNCTION__" | %s", query);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Добавление нового этапа в базу данных |
|
|
//+------------------------------------------------------------------+
|
|
COptimizationProject* COptimizationProject::AddStage(COptimizationStage* p_parentStage, string p_name, string p_expertName,
|
|
string p_symbol, string p_timeframe, int p_optimization, int p_model,
|
|
datetime p_fromDate, datetime p_toDate,
|
|
int p_forwardMode, datetime p_forwardDate,
|
|
int p_deposit = 10000, string p_currency = "USD",
|
|
int p_profitInPips = 0, int p_leverage = 200,
|
|
int p_executionMode = 0, int p_optimizationCriterion = 7,
|
|
string p_status = "Done") {
|
|
|
|
// Создаём новый объект этапа
|
|
m_stage = new COptimizationStage(0, &this, p_parentStage, p_name, p_expertName,
|
|
p_symbol, p_timeframe, p_optimization, p_model,
|
|
p_fromDate, p_toDate,
|
|
p_forwardMode, p_forwardDate,
|
|
p_deposit, p_currency,
|
|
p_profitInPips, p_leverage,
|
|
p_executionMode, p_optimizationCriterion,
|
|
p_status);
|
|
|
|
// Вставляем его в базу данных оптимизации
|
|
m_stage.Insert();
|
|
|
|
// Добавляем его в массив всех этапов
|
|
APPEND(m_stages, m_stage);
|
|
|
|
return &this;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Добавление новых работ в базу данных для заданных |
|
|
//| символов и таймфреймов в строках |
|
|
//+------------------------------------------------------------------+
|
|
COptimizationProject* COptimizationProject::AddJobs(string p_symbols, string p_timeframes,
|
|
TJobsTemplateFunc p_templateFunc) {
|
|
// Массив символов для стратегий
|
|
string symbols[];
|
|
StringReplace(p_symbols, ";", ",");
|
|
StringSplit(p_symbols, ',', symbols);
|
|
|
|
// Массив таймфреймов для стратегий
|
|
string timeframes[];
|
|
StringReplace(p_timeframes, ";", ",");
|
|
StringSplit(p_timeframes, ',', timeframes);
|
|
|
|
return AddJobs(symbols, timeframes, p_templateFunc);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Добавление новых работ в базу данных для заданных |
|
|
//| символов и таймфреймов в массивах |
|
|
//+------------------------------------------------------------------+
|
|
COptimizationProject* COptimizationProject::AddJobs(string &p_symbols[], string &p_timeframes[],
|
|
TJobsTemplateFunc p_templateFunc) {
|
|
// Для каждого символа
|
|
FOREACH_AS(p_symbols, m_symbol) {
|
|
// Для каждого таймфрейма
|
|
FOREACH_AS(p_timeframes, m_timeframe) {
|
|
// Получаем параметры для работы для данного символа и таймфрейма
|
|
string params = p_templateFunc(&this);
|
|
|
|
// Создаём новый объект работы
|
|
m_job = new COptimizationJob(0, m_stage, m_symbol, m_timeframe, params);
|
|
|
|
// Вставляем его в базу данных оптимизации
|
|
m_job.Insert();
|
|
|
|
// Добавляем его в массив всех работ
|
|
APPEND(m_jobs, m_job);
|
|
|
|
// Добавляем его в массив работ текущего этапа
|
|
APPEND(m_stage.jobs, m_job);
|
|
}
|
|
}
|
|
|
|
return &this;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Добавление новых задач в базу данных для заданных |
|
|
//| критериев оптимизации в одной строке |
|
|
//+------------------------------------------------------------------+
|
|
COptimizationProject* COptimizationProject::AddTasks(string p_criterions) {
|
|
// Массив для критериев оптимизации
|
|
string criterions[];
|
|
StringReplace(p_criterions, ";", ",");
|
|
StringSplit(p_criterions, ',', criterions);
|
|
|
|
return AddTasks(criterions);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Добавление новых задач в базу данных для заданных |
|
|
//| критериев оптимизации в массиве |
|
|
//+------------------------------------------------------------------+
|
|
COptimizationProject* COptimizationProject::AddTasks(string &p_criterions[]) {
|
|
// Для каждой работы текущего этапа
|
|
FOREACH_AS(m_stage.jobs, m_job) {
|
|
// Для каждого критерия оптимизации
|
|
FOREACH(p_criterions) {
|
|
// Создаём новый объект задачи для данной работы
|
|
m_task = new COptimizationTask(0, m_job, (int) p_criterions[i]);
|
|
|
|
// Вставляем его в базу данных оптимизации
|
|
m_task.Insert();
|
|
|
|
// Добавляем его в массив всех задач
|
|
APPEND(m_tasks, m_task);
|
|
|
|
// Добавляем его в массив задач текущей работы
|
|
APPEND(m_job.tasks, m_task);
|
|
}
|
|
}
|
|
|
|
return &this;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Постановка проекта в очередь на выполненеие |
|
|
//+------------------------------------------------------------------+
|
|
void COptimizationProject::Queue() {
|
|
status = "Queued";
|
|
Update();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Преобразование строкового названия в таймфрейм |
|
|
//+------------------------------------------------------------------+
|
|
static ENUM_TIMEFRAMES COptimizationProject::StringToTimeframe(string s) {
|
|
// Если в строке есть символ "_", то оставляем только символы, идущие после него
|
|
int pos = StringFind(s, "_");
|
|
if(pos != -1) {
|
|
s = StringSubstr(s, pos + 1);
|
|
}
|
|
|
|
// Переводим в верхний регистр
|
|
StringToUpper(s);
|
|
|
|
// Массивы соответствующих значений названий и таймфреймов
|
|
string keys[] = {"M1", "M2", "M3", "M4", "M5", "M6", "M10", "M12", "M15", "M20", "M30",
|
|
"H1", "H2", "H3", "H4", "H6", "H8", "H12", "D1", "W1", "MN1"
|
|
};
|
|
|
|
ENUM_TIMEFRAMES values[] = {PERIOD_M1, PERIOD_M2, PERIOD_M3, PERIOD_M4, PERIOD_M5, PERIOD_M6,
|
|
PERIOD_M10, PERIOD_M12, PERIOD_M15, PERIOD_M20, PERIOD_M30,
|
|
PERIOD_H1, PERIOD_H2, PERIOD_H3, PERIOD_H4, PERIOD_H6,
|
|
PERIOD_H8, PERIOD_H12, PERIOD_D1, PERIOD_W1, PERIOD_MN1
|
|
};
|
|
|
|
// Ищем соответствие и возвращаем, если нашли
|
|
FOREACH(keys) {
|
|
if(keys[i] == s) return values[i];
|
|
}
|
|
|
|
return PERIOD_CURRENT;
|
|
}
|
|
//+------------------------------------------------------------------+
|