ScalerByLeo/Src/Scaler/MinMax/MinMaxBase.mqh
nique_372 1496207a00 mejoras
2026-09-16 18:20:12 -05:00

190 lines
5.4 KiB
MQL5

//+------------------------------------------------------------------+
//| MinMaxBase.mqh |
//| Copyright 2026, Leo. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Leo."
#property link "https://www.mql5.com/en/users/nique_372"
#property strict
#ifndef SCALERBYLEO_SRC_SCALER_MINMAX_MINMAXBASE_MQH
#define SCALERBYLEO_SRC_SCALER_MINMAX_MINMAXBASE_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "..\\ScalerBase.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| MaxMin Scaler Base |
//+------------------------------------------------------------------+
template<typename TFlt>
class MaxMinScalerBase : public ScalerBase
{
protected:
vector m_min_vals, m_diff, m_diff_inv;
virtual bool OnLoad() { return true; }
public:
MaxMinScalerBase() : ScalerBase() { m_prefix_file = "_min_max.csv"; }
//---
bool Save(string prefix_name, int extra_file_flags = FILE_COMMON);
bool LoadByFile(string prefix_name, int extra_file_flags = FILE_COMMON);
bool LoadByArr(const string &arr[]) override;
//---
bool Fit(const matrix<TFlt> &X);
};
//+------------------------------------------------------------------+
//| Save / Load |
//+------------------------------------------------------------------+
template<typename TFlt>
bool MaxMinScalerBase::Save(string prefix_name, int extra_file_flags = FILE_COMMON)
{
//---
m_file_name_out = prefix_name + m_prefix_file;
FileDelete(m_file_name_out);
ResetLastError();
//---
const int handle = FileOpen(m_file_name_out, FILE_WRITE | FILE_CSV | extra_file_flags);
if(handle == INVALID_HANDLE)
{
m_last_err = SCALERBYLEO_ERR_FILE_OPEN;
return false;
}
//---
FileWrite(handle, vector_to_string(m_diff));
FileWrite(handle, vector_to_string(m_min_vals));
FileWrite(handle, m_i_start);
FileWrite(handle, m_i_count);
//---
FileClose(handle);
return true;
}
//+------------------------------------------------------------------+
template<typename TFlt>
bool MaxMinScalerBase::LoadByFile(string prefix_name, int extra_file_flags = FILE_COMMON)
{
//---
m_file_name_out = prefix_name + m_prefix_file;
//---
ResetLastError();
const int handle = FileOpen(m_file_name_out, FILE_READ | FILE_CSV | extra_file_flags, "\n");
if(handle == INVALID_HANDLE)
{
m_last_err = SCALERBYLEO_ERR_FILE_OPEN;
return false;
}
//---
CStringFunc::ToVector<double, CStringConvert>(FileReadString(handle), m_diff, ',');
CStringFunc::ToVector<double, CStringConvert>(FileReadString(handle), m_min_vals, ',');
m_i_start = ulong(FileReadString(handle));
m_i_count = long(FileReadString(handle));
//---
m_diff_inv = 1.0 / m_diff;
//---
FileClose(handle);
return (m_loaded_scaler = OnLoad());
}
//+------------------------------------------------------------------+
template<typename TFlt>
bool MaxMinScalerBase::LoadByArr(const string &arr[])
{
if(ArraySize(arr) < 4)
{
m_last_err = SCALERBYLEO_ERR_INVALID_DATA;
return false;
}
//---
int p = 0;
CStringFunc::ToVector<double, CStringConvert>(arr[p++], m_diff, ',');
CStringFunc::ToVector<double, CStringConvert>(arr[p++], m_min_vals, ',');
m_i_start = ulong(arr[p++]);
m_i_count = long(arr[p++]);
//---
m_diff_inv = 1.0 / m_diff;
//---
return (m_loaded_scaler = OnLoad());
}
//+------------------------------------------------------------------+
//| Fit |
//+------------------------------------------------------------------+
template<typename TFlt>
bool MaxMinScalerBase::Fit(const matrix<TFlt> &X)
{
//---
const ulong total_cols = X.Cols();
const ulong rows = X.Rows();
if(total_cols == 0 || rows == 0)
{
m_last_err = SCALERBYLEO_ERR_EMPTY_INPUT;
return false;
}
if(m_i_start >= total_cols)
{
m_last_err = SCALERBYLEO_ERR_INVALID_RANGE;
return false;
}
//---
const ulong fs = SCALERBYLEO_SIZE(total_cols);
//---
m_min_vals.Resize(fs);
m_diff.Resize(fs);
m_diff_inv.Resize(fs);
//---
for(ulong c = 0; c < fs; c++)
{
//--- min max de la columa c
double min_v = DBL_MAX, max_v = -DBL_MAX;
for(ulong r = 0; r < rows; r++)
{
const double v = X[r][m_i_start + c];
if(v < min_v)
min_v = v;
if(v > max_v)
max_v = v;
}
//---
const double d = max_v - min_v;
if(d < SCALER_BASE_MIN_VALUE)
{
m_last_err = SCALERBYLEO_ERR_DEGENERATE_SCALE;
return false;
}
//---
m_min_vals[c] = min_v;
m_diff[c] = d;
m_diff_inv[c] = 1.0 / d;
}
//---
return (m_loaded_scaler = OnLoad());
}
}
#endif // SCALERBYLEO_SRC_SCALER_MINMAX_MINMAXBASE_MQH
//+------------------------------------------------------------------+