2026-09-12 19:41:52 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| ClasesBases.mqh |
|
| | | //| Copyright 2025, Niquel Mendoza. |
|
| | | //| https://www.mql5.com |
|
| | | //+------------------------------------------------------------------+
|
| | | #property copyright "Copyright 2025, Niquel Mendoza."
|
| | | #property link "https://www.mql5.com"
|
| | | #property strict
|
| | |
|
| | | #ifndef MQLARTICLES_UTILS_FA_CLASESBASES_MQH
|
| | | #define MQLARTICLES_UTILS_FA_CLASESBASES_MQH
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Includes |
|
| | | //+------------------------------------------------------------------+
|
| | | //--- (Eventos basicos | CManagerBase | CSpecializedManager | CLoggerBase)
|
| | | #include "Events.mqh"
|
| | |
|
| | | //--- (CBarControler | CBarControlerFast | CAtr | CAtrOptimized | CAtrOptimizedZero | CAtrOptimizedNonZero |
|
| | | // CAtrUltraOptimized | CDiff | CDiffAtr | CDiffPoints)
|
| | | //#include "DiffCalc.mqh"
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Class to detect if the PC has been suspended |
|
| | | //+------------------------------------------------------------------+
|
| | | class CSuspendChecker
|
| | | {
|
| | | private:
|
| | | uint m_lastTick; // Last recorded tick
|
| | | uchar m_threshold; // Threshold in minutes
|
| | | datetime m_last_time_revised;
|
| | |
|
| | | public:
|
| | | // Constructor, sets the time threshold
|
| | | CSuspendChecker()
|
| | |
|
| | | {
|
| | | m_threshold = 2;
|
| | | m_lastTick = GetTickCount64Minutes; // Initialize with current time
|
| | | m_last_time_revised = TimeCurrent();
|
| | | }
|
| | |
|
| | | // Checks if there has been a suspension
|
| | | bool CheckForSuspend(const bool flag_new_day, const datetime curr_time)
|
| | | {
|
| | | if(TESTER_FLAG)
|
| | | return false;
|
| | |
|
| | | const uint currentTick = GetTickCount64Minutes;
|
| | | m_last_time_revised = curr_time;
|
| | | m_lastTick = currentTick; // Update the last tick
|
| | |
|
| | | // If the difference exceeds the threshold, the PC was likely suspended
|
| | | if(!flag_new_day && (currentTick - m_lastTick) > m_threshold)
|
| | | return true;
|
| | |
|
| | | return false;
|
| | | }
|
| | |
|
| | | inline datetime GetLasTimeRevised()
|
| | | {
|
| | | return this.m_last_time_revised;
|
| | | }
|
| | |
|
| | | inline void Threshold(uchar new_minutes)
|
| | | {
|
| | | m_threshold = new_minutes;
|
| | | }
|
| | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| CConversions Class: price ↔ pixels ↔ bars |
|
| | | //+------------------------------------------------------------------+
|
| | | class CGraphConversion
|
| | | {
|
| | | private:
|
| | | double valor_1_unidad_precio_a_px;
|
| | | double valor_1_px_a_unidad_precio;
|
| | | double valor_1_barra_a_px;
|
| | | double valor_1_px_a_barra;
|
| | | long chart_id;
|
| | | public:
|
| | | CGraphConversion(long chartID = 0) : chart_id(chartID) { }
|
| | | // Price → pixels
|
| | | inline int PrecioAPixeles(double distancia_precio)
|
| | | {
|
| | | return (int)(distancia_precio * this.valor_1_unidad_precio_a_px);
|
| | | }
|
| | |
|
| | | // Pixels → price
|
| | | inline double PixelesAPrecio(int pixeles)
|
| | | {
|
| | | return pixeles * this.valor_1_px_a_unidad_precio;
|
| | | }
|
| | |
|
| | | // Bars → pixels
|
| | | inline int BarrasAPixeles(double num_barras)
|
| | | {
|
| | | return (int)(num_barras * this.valor_1_barra_a_px);
|
| | | }
|
| | |
|
| | | // Pixels → bars
|
| | | inline double PixelesABarras(int pixeles)
|
| | | {
|
| | | return pixeles * this.valor_1_px_a_barra;
|
| | | }
|
| | |
|
| | | // Update scale
|
| | | void Update()
|
| | | {
|
| | | // Vertical scale (price)
|
| | | double precio_max = ChartGetDouble(chart_id, CHART_PRICE_MAX);
|
| | | double precio_min = ChartGetDouble(chart_id, CHART_PRICE_MIN);
|
| | | double dist_precio = MathAbs(precio_max - precio_min);
|
| | | int chart_height_px = (int)ChartGetInteger(chart_id, CHART_HEIGHT_IN_PIXELS);
|
| | | int chart_width_px = (int)ChartGetInteger(chart_id, CHART_WIDTH_IN_PIXELS);
|
| | | if(chart_height_px > 0 && dist_precio > 0)
|
| | | {
|
| | | this.valor_1_unidad_precio_a_px = (double)chart_height_px / dist_precio;
|
| | | this.valor_1_px_a_unidad_precio = dist_precio / (double)chart_height_px;
|
| | | }
|
| | | // Horizontal scale (bars)
|
| | | int barras_horizontal = (int)ChartGetInteger(chart_id, CHART_WIDTH_IN_BARS);
|
| | | if(chart_width_px > 0 && barras_horizontal > 0)
|
| | | {
|
| | | this.valor_1_barra_a_px = (double)chart_width_px / (double)barras_horizontal;
|
| | | this.valor_1_px_a_barra = (double)barras_horizontal / (double)chart_width_px;
|
| | | }
|
| | | }
|
| | |
|
| | | // Automatic handling of zoom and chart changes
|
| | | void OnEvent(const int id,
|
| | | const long & lparam,
|
| | | const double & dparam,
|
| | | const string & sparam)
|
| | | {
|
| | | if(id != CHARTEVENT_CHART_CHANGE)
|
| | | return;
|
| | | if(lparam == 49 || lparam == 2)
|
| | | Update();
|
| | | }
|
| | |
|
| | | // Extra method to get current dimensions
|
| | | void ImprimirDimensionesChart()
|
| | | {
|
| | | int chart_width = (int)ChartGetInteger(chart_id, CHART_WIDTH_IN_PIXELS);
|
| | | int chart_height = (int)ChartGetInteger(chart_id, CHART_HEIGHT_IN_PIXELS);
|
| | | int barras_horizontal = (int)ChartGetInteger(chart_id, CHART_WIDTH_IN_BARS);
|
| | | PrintFormat("Current chart dimensions: width=%d px, height=%d px, visible bars=%d",
|
| | | chart_width, chart_height, barras_horizontal);
|
| | | }
|
| | | };
|
| | |
|
| | | CGraphConversion manager_graph;
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | #endif // MQLARTICLES_UTILS_FA_CLASESBASES_MQH
|
| | | //+------------------------------------------------------------------+
|