mirror of
https://github.com/softwaredevelop/mql5.git
synced 2026-08-24 09:48:05 +00:00
refactor: 3.10
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| PivotPoint_Calculator.mqh |
|
//| PivotPoint_Calculator.mqh |
|
||||||
//| Engine for calculating various Pivot Point types. |
|
//| Engine for calculating various Pivot Point types. |
|
||||||
//| Copyright 2026, xxxxxxxx |
|
//| Copyright 2026, xxxxxxxx|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
#property copyright "Copyright 2026, xxxxxxxx"
|
#property copyright "Copyright 2026, xxxxxxxx"
|
||||||
|
#property version "3.10"
|
||||||
|
|
||||||
enum ENUM_PIVOT_TYPE
|
enum ENUM_PIVOT_TYPE
|
||||||
{
|
{
|
||||||
@@ -25,6 +26,7 @@ struct PivotLevels
|
|||||||
double PP;
|
double PP;
|
||||||
double R1, R2, R3;
|
double R1, R2, R3;
|
||||||
double S1, S2, S3;
|
double S1, S2, S3;
|
||||||
|
datetime period_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
//+==================================================================+
|
//+==================================================================+
|
||||||
@@ -36,7 +38,7 @@ protected:
|
|||||||
ENUM_PIVOT_TYPE m_type;
|
ENUM_PIVOT_TYPE m_type;
|
||||||
ENUM_PIVOT_SOURCE m_source;
|
ENUM_PIVOT_SOURCE m_source;
|
||||||
|
|
||||||
// Cache for optimization
|
// Cache for O(1) performance
|
||||||
datetime m_last_calc_time;
|
datetime m_last_calc_time;
|
||||||
PivotLevels m_last_levels;
|
PivotLevels m_last_levels;
|
||||||
|
|
||||||
@@ -55,6 +57,7 @@ bool CPivotPointCalculator::Init(ENUM_PIVOT_TYPE type, ENUM_PIVOT_SOURCE source)
|
|||||||
{
|
{
|
||||||
m_type = type;
|
m_type = type;
|
||||||
m_source = source;
|
m_source = source;
|
||||||
|
m_last_calc_time = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,66 +66,69 @@ bool CPivotPointCalculator::Init(ENUM_PIVOT_TYPE type, ENUM_PIVOT_SOURCE source)
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
bool CPivotPointCalculator::CalculateLevels(datetime current_time, ENUM_TIMEFRAMES tf, PivotLevels &out_levels)
|
bool CPivotPointCalculator::CalculateLevels(datetime current_time, ENUM_TIMEFRAMES tf, PivotLevels &out_levels)
|
||||||
{
|
{
|
||||||
// 1. Identify the start time of the HTF bar containing current_time
|
int current_bar_shift = iBarShift(_Symbol, tf, current_time, false);
|
||||||
datetime htf_time = iTime(_Symbol, tf, iBarShift(_Symbol, tf, current_time));
|
if(current_bar_shift < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Optimization: If we already calculated for this HTF bar, return cached
|
datetime htf_time = iTime(_Symbol, tf, current_bar_shift);
|
||||||
|
if(htf_time == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Optimization: Return cached result if same HTF bar
|
||||||
if(htf_time == m_last_calc_time && m_last_calc_time != 0)
|
if(htf_time == m_last_calc_time && m_last_calc_time != 0)
|
||||||
{
|
{
|
||||||
out_levels = m_last_levels;
|
out_levels = m_last_levels;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. We need the PREVIOUS completed HTF bar data
|
// Fetch completed previous HTF bar data
|
||||||
int htf_index = iBarShift(_Symbol, tf, current_time) + 1;
|
int htf_index = current_bar_shift + 1;
|
||||||
|
|
||||||
double O, H, L, C;
|
|
||||||
|
|
||||||
double o_arr[1], h_arr[1], l_arr[1], c_arr[1];
|
double o_arr[1], h_arr[1], l_arr[1], c_arr[1];
|
||||||
|
|
||||||
if(CopyOpen(_Symbol, tf, htf_index, 1, o_arr)<=0 ||
|
if(CopyOpen(_Symbol, tf, htf_index, 1, o_arr) <= 0 ||
|
||||||
CopyHigh(_Symbol, tf, htf_index, 1, h_arr)<=0 ||
|
CopyHigh(_Symbol, tf, htf_index, 1, h_arr) <= 0 ||
|
||||||
CopyLow(_Symbol, tf, htf_index, 1, l_arr)<=0 ||
|
CopyLow(_Symbol, tf, htf_index, 1, l_arr) <= 0 ||
|
||||||
CopyClose(_Symbol, tf, htf_index, 1, c_arr)<=0)
|
CopyClose(_Symbol, tf, htf_index, 1, c_arr) <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
O = o_arr[0];
|
double O = o_arr[0];
|
||||||
H = h_arr[0];
|
double H = h_arr[0];
|
||||||
L = l_arr[0];
|
double L = l_arr[0];
|
||||||
C = c_arr[0];
|
double C = c_arr[0];
|
||||||
|
|
||||||
// Heikin Ashi Transformation if requested
|
// Heikin Ashi Transformation
|
||||||
if(m_source == PIVOT_SRC_HEIKIN_ASHI)
|
if(m_source == PIVOT_SRC_HEIKIN_ASHI)
|
||||||
{
|
{
|
||||||
double ha_close = (O + H + L + C) / 4.0;
|
double ha_close = (O + H + L + C) / 4.0;
|
||||||
|
|
||||||
double po_arr[1], pc_arr[1];
|
double po_arr[1], pc_arr[1];
|
||||||
CopyOpen(_Symbol, tf, htf_index+1, 1, po_arr);
|
if(CopyOpen(_Symbol, tf, htf_index + 1, 1, po_arr) > 0 &&
|
||||||
CopyClose(_Symbol, tf, htf_index+1, 1, pc_arr);
|
CopyClose(_Symbol, tf, htf_index + 1, 1, pc_arr) > 0)
|
||||||
double ha_open = (po_arr[0] + pc_arr[0]) / 2.0;
|
{
|
||||||
|
double ha_open = (po_arr[0] + pc_arr[0]) / 2.0;
|
||||||
|
double ha_high = MathMax(H, MathMax(ha_open, ha_close));
|
||||||
|
double ha_low = MathMin(L, MathMin(ha_open, ha_close));
|
||||||
|
|
||||||
double ha_high = MathMax(H, MathMax(ha_open, ha_close));
|
O = ha_open;
|
||||||
double ha_low = MathMin(L, MathMin(ha_open, ha_close));
|
H = ha_high;
|
||||||
|
L = ha_low;
|
||||||
O = ha_open;
|
C = ha_close;
|
||||||
H = ha_high;
|
}
|
||||||
L = ha_low;
|
|
||||||
C = ha_close;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Calculate Formulas
|
|
||||||
double range = H - L;
|
double range = H - L;
|
||||||
|
|
||||||
switch(m_type)
|
switch(m_type)
|
||||||
{
|
{
|
||||||
case PIVOT_CLASSIC:
|
case PIVOT_CLASSIC:
|
||||||
out_levels.PP = (H + L + C) / 3.0;
|
out_levels.PP = (H + L + C) / 3.0;
|
||||||
out_levels.R1 = 2 * out_levels.PP - L;
|
out_levels.R1 = 2.0 * out_levels.PP - L;
|
||||||
out_levels.S1 = 2 * out_levels.PP - H;
|
out_levels.S1 = 2.0 * out_levels.PP - H;
|
||||||
out_levels.R2 = out_levels.PP + range;
|
out_levels.R2 = out_levels.PP + range;
|
||||||
out_levels.S2 = out_levels.PP - range;
|
out_levels.S2 = out_levels.PP - range;
|
||||||
out_levels.R3 = H + 2 * (out_levels.PP - L);
|
out_levels.R3 = H + 2.0 * (out_levels.PP - L);
|
||||||
out_levels.S3 = L - 2 * (H - out_levels.PP);
|
out_levels.S3 = L - 2.0 * (H - out_levels.PP);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIVOT_FIBONACCI:
|
case PIVOT_FIBONACCI:
|
||||||
@@ -136,13 +142,13 @@ bool CPivotPointCalculator::CalculateLevels(datetime current_time, ENUM_TIMEFRAM
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PIVOT_WOODIE:
|
case PIVOT_WOODIE:
|
||||||
out_levels.PP = (H + L + 2 * C) / 4.0;
|
out_levels.PP = (H + L + 2.0 * C) / 4.0;
|
||||||
out_levels.R1 = 2 * out_levels.PP - L;
|
out_levels.R1 = 2.0 * out_levels.PP - L;
|
||||||
out_levels.S1 = 2 * out_levels.PP - H;
|
out_levels.S1 = 2.0 * out_levels.PP - H;
|
||||||
out_levels.R2 = out_levels.PP + range;
|
out_levels.R2 = out_levels.PP + range;
|
||||||
out_levels.S2 = out_levels.PP - range;
|
out_levels.S2 = out_levels.PP - range;
|
||||||
out_levels.R3 = H + 2 * (out_levels.PP - L);
|
out_levels.R3 = H + 2.0 * (out_levels.PP - L);
|
||||||
out_levels.S3 = L - 2 * (H - out_levels.PP);
|
out_levels.S3 = L - 2.0 * (H - out_levels.PP);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIVOT_CAMARILLA:
|
case PIVOT_CAMARILLA:
|
||||||
@@ -159,29 +165,30 @@ bool CPivotPointCalculator::CalculateLevels(datetime current_time, ENUM_TIMEFRAM
|
|||||||
{
|
{
|
||||||
double X;
|
double X;
|
||||||
if(C < O)
|
if(C < O)
|
||||||
X = H + 2 * L + C;
|
X = H + 2.0 * L + C;
|
||||||
else
|
else
|
||||||
if(C > O)
|
if(C > O)
|
||||||
X = 2 * H + L + C;
|
X = 2.0 * H + L + C;
|
||||||
else
|
else
|
||||||
X = H + L + 2 * C;
|
X = H + L + 2.0 * C;
|
||||||
|
|
||||||
out_levels.PP = X / 4.0;
|
out_levels.PP = X / 4.0;
|
||||||
out_levels.R1 = X / 2.0 - L;
|
out_levels.R1 = X / 2.0 - L;
|
||||||
out_levels.S1 = X / 2.0 - H;
|
out_levels.S1 = X / 2.0 - H;
|
||||||
out_levels.R2 = 0;
|
out_levels.R2 = EMPTY_VALUE;
|
||||||
out_levels.S2 = 0;
|
out_levels.S2 = EMPTY_VALUE;
|
||||||
out_levels.R3 = 0;
|
out_levels.R3 = EMPTY_VALUE;
|
||||||
out_levels.S3 = 0;
|
out_levels.S3 = EMPTY_VALUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Cache
|
out_levels.period_start = htf_time;
|
||||||
|
|
||||||
|
// Store Cache
|
||||||
m_last_calc_time = htf_time;
|
m_last_calc_time = htf_time;
|
||||||
m_last_levels = out_levels;
|
m_last_levels = out_levels;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//+------------------------------------------------------------------+
|
|
||||||
|
|||||||
Reference in New Issue
Block a user