187 lines
5.9 KiB
MQL5
187 lines
5.9 KiB
MQL5
/**
|
|
* @file MonotonicDeque - Fixed-capacity double-ended queue storage for monotonic rolling algorithms.
|
|
* @deps None
|
|
* @state Stateful (Maintains fixed-capacity indexed value storage with front and back access)
|
|
* @io Indexed double values -> Supports deque insertion, removal, and boundary access
|
|
* @note AI-assisted code. Independently review and test in a demo environment before live production trading.
|
|
*/
|
|
|
|
#ifndef __MONOTONIC_DEQUE_MQH__
|
|
#define __MONOTONIC_DEQUE_MQH__
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| CMonotonicDeque |
|
|
//| |
|
|
//| PURPOSE |
|
|
//| ------- |
|
|
//| Provides fixed-capacity deque storage for rolling algorithms. |
|
|
//| |
|
|
//| RESPONSIBILITIES |
|
|
//| ---------------- |
|
|
//| • Store indexed double values |
|
|
//| • Push values at the back |
|
|
//| • Remove values from front or back |
|
|
//| • Provide front and back access |
|
|
//| |
|
|
//| NON-RESPONSIBILITIES |
|
|
//| -------------------- |
|
|
//| • Monotonic ordering |
|
|
//| • Rolling minimum or maximum calculation |
|
|
//| • Stream event handling |
|
|
//+------------------------------------------------------------------+
|
|
class CMonotonicDeque
|
|
{
|
|
private:
|
|
|
|
double m_values[];
|
|
long m_indices[];
|
|
int m_capacity;
|
|
int m_count;
|
|
int m_head;
|
|
|
|
public:
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
CMonotonicDeque()
|
|
{
|
|
m_capacity = 0;
|
|
m_count = 0;
|
|
m_head = 0;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Initialize |
|
|
//+------------------------------------------------------------------+
|
|
bool Init(const int capacity)
|
|
{
|
|
if(capacity <= 0)
|
|
return(false);
|
|
|
|
if(ArrayResize(m_values, capacity) != capacity)
|
|
return(false);
|
|
|
|
if(ArrayResize(m_indices, capacity) != capacity)
|
|
return(false);
|
|
|
|
m_capacity = capacity;
|
|
m_count = 0;
|
|
m_head = 0;
|
|
|
|
return(true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Reset |
|
|
//+------------------------------------------------------------------+
|
|
void Reset()
|
|
{
|
|
m_count = 0;
|
|
m_head = 0;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Push Back |
|
|
//+------------------------------------------------------------------+
|
|
bool PushBack(const long index,
|
|
const double value)
|
|
{
|
|
if(m_capacity == 0 || m_count == m_capacity)
|
|
return(false);
|
|
|
|
int position = (m_head + m_count) % m_capacity;
|
|
|
|
m_indices[position] = index;
|
|
m_values[position] = value;
|
|
|
|
++m_count;
|
|
|
|
return(true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Pop Front |
|
|
//+------------------------------------------------------------------+
|
|
bool PopFront()
|
|
{
|
|
if(m_count == 0)
|
|
return(false);
|
|
|
|
m_head = (m_head + 1) % m_capacity;
|
|
--m_count;
|
|
|
|
return(true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Pop Back |
|
|
//+------------------------------------------------------------------+
|
|
bool PopBack()
|
|
{
|
|
if(m_count == 0)
|
|
return(false);
|
|
|
|
--m_count;
|
|
|
|
return(true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Front |
|
|
//+------------------------------------------------------------------+
|
|
bool Front(long &index,
|
|
double &value) const
|
|
{
|
|
if(m_count == 0)
|
|
return(false);
|
|
|
|
index = m_indices[m_head];
|
|
value = m_values[m_head];
|
|
|
|
return(true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Back |
|
|
//+------------------------------------------------------------------+
|
|
bool Back(long &index,
|
|
double &value) const
|
|
{
|
|
if(m_count == 0)
|
|
return(false);
|
|
|
|
int position = (m_head + m_count - 1) % m_capacity;
|
|
|
|
index = m_indices[position];
|
|
value = m_values[position];
|
|
|
|
return(true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Information |
|
|
//+------------------------------------------------------------------+
|
|
int Count() const
|
|
{
|
|
return(m_count);
|
|
}
|
|
|
|
int Capacity() const
|
|
{
|
|
return(m_capacity);
|
|
}
|
|
|
|
bool IsEmpty() const
|
|
{
|
|
return(m_count == 0);
|
|
}
|
|
|
|
bool IsFull() const
|
|
{
|
|
return(m_count == m_capacity);
|
|
}
|
|
};
|
|
|
|
#endif // __MONOTONIC_DEQUE_MQH__
|
|
//+------------------------------------------------------------------+
|