158 lines
14 KiB
MQL5
158 lines
14 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Stage3.mqh |
|
|
//| Copyright 2024-2025, Yuriy Bykov |
|
|
//| https://www.mql5.com/ru/users/antekov |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2024-2025, Yuriy Bykov"
|
|
#property link "https://www.mql5.com/ru/articles/17328"
|
|
#property description "Советник, сохраняющий сформированную нормированную группу стратегий "
|
|
#property description "в библиотеку групп с заданным именем."
|
|
|
|
#property version "1.05"
|
|
|
|
#ifndef __NAME__
|
|
#define __NAME__ "EmptyStrategy"
|
|
#endif
|
|
|
|
#include "../Virtual/VirtualAdvisor.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Входные параметры |
|
|
//+------------------------------------------------------------------+
|
|
sinput int idTask_ = 38; // - Идентификатор задачи оптимизации
|
|
sinput string fileName_ = "article.16373.db.sqlite"; // - Файл с основной базой данных
|
|
|
|
input group "::: Отбор в группу"
|
|
input string passes_ = ""; // - Идентификаторы проходов через запятую
|
|
|
|
input group "::: Сохранение в библиотеку"
|
|
input string groupName_ = "SimpleVolumes_v.1.20_2023.01.01"; // - Название версии (если пустое - не сохранять)
|
|
input string advFileName_ = "SimpleVolumes-27183.test.db.sqlite"; // - Название базы данных эксперта
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double expectedDrawdown_ = 10; // - Максимальный риск (%)
|
|
double fixedBalance_ = 10000; // - Используемый депозит (0 - использовать весь) в валюте счета
|
|
double scale_ = 1.00; // - Масштабирующий множитель для группы
|
|
|
|
ulong magic_ = 27183; // - Magic
|
|
|
|
CVirtualAdvisor *expert; // Объект эксперта
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit() {
|
|
// Устанавливаем параметры в классе управления капиталом
|
|
CMoney::DepoPart(expectedDrawdown_ / 10.0);
|
|
CMoney::FixedBalance(fixedBalance_);
|
|
CVirtualAdvisor::TesterInit(idTask_, fileName_);
|
|
|
|
// Строка инициализации с наборами параметров стратегий
|
|
string strategiesParams = NULL;
|
|
|
|
// Если соединение с основной базой данных установлено, то
|
|
if(DB::Connect(fileName_)) {
|
|
// Формируем запрос на получение проходов с указанными идетификаторами
|
|
string query = (passes_ == "" ?
|
|
StringFormat("SELECT DISTINCT FIRST_VALUE(p.params) OVER (PARTITION BY p.id_task ORDER BY custom_ontester DESC) AS params "
|
|
" FROM passes p "
|
|
" WHERE p.id_task IN ("
|
|
" SELECT pt.id_task "
|
|
" FROM tasks t "
|
|
" JOIN "
|
|
" jobs j ON j.id_job = t.id_job "
|
|
" JOIN "
|
|
" stages s ON s.id_stage = j.id_stage "
|
|
" JOIN "
|
|
" jobs pj ON pj.id_stage = s.id_parent_stage "
|
|
" JOIN "
|
|
" tasks pt ON pt.id_job = pj.id_job "
|
|
" WHERE t.id_task = %d "
|
|
" ) ", idTask_)
|
|
: StringFormat("SELECT params"
|
|
" FROM passes "
|
|
" WHERE id_pass IN (%s);", passes_)
|
|
);
|
|
|
|
Print(query);
|
|
int request = DatabasePrepare(DB::Id(), query);
|
|
|
|
if(request != INVALID_HANDLE) {
|
|
// Структура для чтения результатов
|
|
struct Row {
|
|
string params;
|
|
} row;
|
|
|
|
// Для всех строк результата запроса, соединяем строки инициализации
|
|
while(DatabaseReadBind(request, row)) {
|
|
strategiesParams += row.params + ",";
|
|
}
|
|
}
|
|
DB::Close();
|
|
}
|
|
|
|
// Если наборов параметрв не найдено, то прерываем тестирование
|
|
if(strategiesParams == NULL) {
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
// Подготавливаем строку инициализации для эксперта с группой из нескольких стратегий
|
|
string expertParams = StringFormat(
|
|
"class CVirtualAdvisor(\n"
|
|
" class CVirtualStrategyGroup(\n"
|
|
" [\n"
|
|
" %s\n"
|
|
" ],%f\n"
|
|
" ),\n"
|
|
" class CVirtualRiskManager(\n"
|
|
" 0,0,0,0,0,0,0,0,0,0,0,0,0"
|
|
" )\n"
|
|
" ,%d,%s,%d\n"
|
|
")",
|
|
strategiesParams, scale_,
|
|
magic_, __NAME__, true
|
|
);
|
|
|
|
PrintFormat(__FUNCTION__" | Expert Params:\n%s", expertParams);
|
|
|
|
// Создаем эксперта, работающего с виртуальными позициями
|
|
expert = NEW(expertParams);
|
|
|
|
// Если эксперт не создан, то возвращаем ошибку
|
|
if(!expert) return INIT_FAILED;
|
|
|
|
// Успешная инициализация
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick() {
|
|
expert.Tick();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason) {
|
|
if(!!expert) delete expert;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Результат тестирования |
|
|
//+------------------------------------------------------------------+
|
|
double OnTester(void) {
|
|
// Обрабатываем завершение прохода в объекте эксперта
|
|
double res = expert.Tester();
|
|
|
|
// Если имя группы не пустое, то сохраняем проход в библиотеку
|
|
if(groupName_ != "") {
|
|
expert.Export(groupName_, advFileName_);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
//+------------------------------------------------------------------+
|