140 lines
5.3 KiB
MQL5
140 lines
5.3 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| ModelSelection.mq5 |
|
|
//| Eugene |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Eugene"
|
|
#property link "https://www.mql5.com"
|
|
#property version "1.00"
|
|
#include <CategoricalHMM\CategoricalHMM.mqh>
|
|
#include <Graphics\Graphic.mqh>
|
|
//+------------------------------------------------------------------+
|
|
//| Script program start function |
|
|
//+------------------------------------------------------------------+
|
|
void OnStart()
|
|
{
|
|
int n_samples = 5000;
|
|
int n_states_true = 3;
|
|
int n_emissions = 6;
|
|
|
|
// --- 1. ИНИЦИАЛИЗАЦИЯ ИСТИННОЙ МОДЕЛИ ДЛЯ ГЕНЕРАЦИИ ---
|
|
matrix tr_true =
|
|
{
|
|
{0.8, 0.1, 0.1},
|
|
{0.05, 0.9, 0.05},
|
|
{0.1, 0.1, 0.8}
|
|
};
|
|
|
|
matrix e_true =
|
|
{
|
|
{1.0/6, 1.0/6, 1.0/6, 1.0/6, 1.0/6, 1.0/6},
|
|
{0.1, 0.1, 0.1, 0.1, 0.1, 0.5},
|
|
{0.4, 0.1, 0.1, 0.1, 0.1, 0.2}
|
|
};
|
|
|
|
vector y, states_true;
|
|
CCategoricalHMM gen_model(n_states_true, n_emissions, 42); // Seed 42
|
|
gen_model.Sample(n_samples, tr_true, e_true, y, states_true);
|
|
//VectorToCSV("Sample5000.csv",y);
|
|
|
|
// --- РАСЧЕТ ИСТИННОГО LOG-LIKELIHOOD ---
|
|
double true_ll = 0;
|
|
matrix p_true, fs_true, bs_true;
|
|
vector s_true;
|
|
|
|
// --- Вызываем Inference на истинных параметрах ---
|
|
gen_model.Inference(y, tr_true, e_true, p_true, true_ll, fs_true, bs_true, s_true);
|
|
|
|
PrintFormat("==================================================");
|
|
PrintFormat("TRUE MODEL LOG-LIKELIHOOD: %.2f", true_ll);
|
|
PrintFormat("==================================================");
|
|
|
|
// --- 2. ПОДБОР МОДЕЛИ (MODEL SELECTION) ---
|
|
int ns[] = {1,2, 3, 4, 5, 6, 7};
|
|
int n_fits = 10;
|
|
int n_points = ArraySize(ns);
|
|
double x_vals[], aic_vals[], bic_vals[]; // Массивы для графика
|
|
ArrayResize(x_vals, n_points);
|
|
ArrayResize(aic_vals, n_points);
|
|
ArrayResize(bic_vals, n_points);
|
|
|
|
Print("==================================================");
|
|
Print("HMM MODEL SELECTION ");
|
|
PrintFormat("True States: %d | Samples: %d", n_states_true, n_samples);
|
|
Print("==================================================");
|
|
|
|
for(int i = 0; i < ArraySize(ns); i++)
|
|
{
|
|
int n_curr = ns[i];
|
|
double best_ll = -DBL_MAX;
|
|
int n_params;
|
|
|
|
// --- Пробуем несколько случайных стартов для каждого N ---
|
|
for(int fit = 0; fit < n_fits; fit++)
|
|
{
|
|
CCategoricalHMM model(n_curr, n_emissions, fit);
|
|
n_params = model.GetParams();
|
|
|
|
// --- Обучаем (20 итераций для быстрой оценки) ---
|
|
if(!model.Fit(y, 20, 1e-4,false))
|
|
continue;
|
|
|
|
// --- Получаем Log-Likelihood ---
|
|
double current_ll = 0;
|
|
matrix p, fs, bs;
|
|
vector s;
|
|
if(model.Inference(y, model.m_TR, model.m_E, p, current_ll, fs, bs, s))
|
|
{
|
|
if(current_ll > best_ll)
|
|
best_ll = current_ll;
|
|
}
|
|
}
|
|
|
|
// --- Оценка информационных критериев для лучшей попытки в текущем N ---
|
|
CCategoricalHMM eval_model(n_curr, n_emissions);
|
|
double val_aic = eval_model.AIC(best_ll);
|
|
double val_bic = eval_model.BIC(best_ll, n_samples);
|
|
|
|
// --- Сохраняем данные для графика ---
|
|
x_vals[i] = n_curr;
|
|
aic_vals[i] = val_aic;
|
|
bic_vals[i] = val_bic;
|
|
|
|
PrintFormat("N=%d | LL: %.2f | AIC: %.2f | BIC: %.2f | n_params:%d",
|
|
n_curr, best_ll, val_aic, val_bic,n_params);
|
|
}
|
|
Print("==================================================");
|
|
|
|
// --- ВИЗУАЛИЗАЦИЯ ---
|
|
ChartSetInteger(0, CHART_SHOW, false);
|
|
|
|
CGraphic graphic;
|
|
ulong width = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
|
|
ulong height = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
|
|
|
|
if(ObjectFind(0, "HMM_Selection_Plot") < 0)
|
|
graphic.Create(0, "HMM_Selection_Plot", 0, 0, 0, int(width), int(height));
|
|
else
|
|
graphic.Attach(0, "HMM_Selection_Plot");
|
|
|
|
CCurve *curveAIC = graphic.CurveAdd(x_vals, aic_vals, ColorToARGB(clrDodgerBlue, 255), CURVE_POINTS_AND_LINES, "AIC");
|
|
curveAIC.LinesStyle(STYLE_SOLID);
|
|
|
|
CCurve *curveBIC = graphic.CurveAdd(x_vals, bic_vals, ColorToARGB(clrLimeGreen, 255), CURVE_POINTS_AND_LINES, "BIC");
|
|
curveBIC.LinesStyle(STYLE_SOLID);
|
|
|
|
graphic.BackgroundMainColor(ColorToARGB(clrBlack, 255));
|
|
graphic.BackgroundMainSize(24);
|
|
graphic.BackgroundMain("HMM Model Selection (AIC vs BIC)");
|
|
graphic.XAxis().Name("Number of States");
|
|
graphic.XAxis().NameSize(18);
|
|
graphic.YAxis().Name("AIC/BIC Value (Lower is Better)");
|
|
graphic.YAxis().NameSize(18);
|
|
graphic.CurvePlotAll();
|
|
graphic.Update();
|
|
Sleep(10000);
|
|
ChartSetInteger(0, CHART_SHOW, true);
|
|
graphic.Destroy();
|
|
ChartRedraw(0);
|
|
}
|
|
//+------------------------------------------------------------------+
|