forked from rosh/MQL5Book
300 lines
7.2 KiB
MQL5
300 lines
7.2 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| IndBufArray.mqh |
| |
//| Copyright (c) 2016-2021, Marketeer |
| |
//| https://www.mql5.com/en/users/marketeer |
| |
//+------------------------------------------------------------------+
| |
| |
// helper defines which allows to not use read-accessors
| |
// by selecting proper operator[] overloads via SETTER/GETTER type
| |
#define SETTER int
| |
#define GETTER uint
| |
| |
class BufferGetter; // forward declaration, helper class
| |
| |
//+------------------------------------------------------------------+
| |
//| Indicator buffer holder |
| |
//+------------------------------------------------------------------+
| |
class Buffer // main indicator buffer class
| |
{
| |
protected:
| |
double buffer[]; // indicator buffer
| |
| |
int cursor; // position in the buffer
| |
| |
BufferGetter *instance; // helper object for reading values (optional)
| |
| |
public:
| |
Buffer(int i,
| |
const double empty = EMPTY_VALUE,
| |
const ENUM_INDEXBUFFER_TYPE type = INDICATOR_DATA,
| |
const bool asSeries = false)
| |
{
| |
SetIndexBuffer(i, buffer, type);
| |
ArraySetAsSeries(buffer, asSeries);
| |
ArrayInitialize(buffer, empty);
| |
instance = NULL;
| |
}
| |
| |
virtual ~Buffer()
| |
{
| |
if(CheckPointer(instance) == POINTER_DYNAMIC) delete instance;
| |
}
| |
| |
void series(const bool s)
| |
{
| |
ArraySetAsSeries(buffer, s);
| |
}
| |
| |
void empty(const double empty = EMPTY_VALUE, const int offset = 0, const int count = 0)
| |
{
| |
if(offset == 0 && count == 0)
| |
{
| |
ArrayInitialize(buffer, empty);
| |
}
| |
else
| |
{
| |
ArrayFill(buffer, offset, count, empty);
| |
}
| |
}
| |
| |
double operator[](GETTER b)
| |
{
| |
return buffer[b];
| |
}
| |
| |
Buffer *operator[](SETTER b)
| |
{
| |
cursor = (int)b;
| |
return &this;
| |
}
| |
| |
// writes data from the 'source' into this buffer
| |
int write(const double &source[], const int from = 0, const int to = 0, const int count = WHOLE_ARRAY)
| |
{
| |
ResetLastError();
| |
return ArrayCopy(buffer, source, to, from, count);
| |
}
| |
| |
// reads data from this buffer to the given 'target'
| |
int read(double &target[], const int from = 0, const int to = 0, const int count = WHOLE_ARRAY)
| |
{
| |
ResetLastError();
| |
return ArrayCopy(target, buffer, to, from, count);
| |
}
| |
| |
int copy(const int handle, const int bus, const int from, const int count)
| |
{
| |
ResetLastError();
| |
return CopyBuffer(handle, bus, from, count, buffer);
| |
}
| |
| |
double operator=(double x)
| |
{
| |
buffer[cursor] = x;
| |
return x;
| |
}
| |
| |
void set(const int b, const double v)
| |
{
| |
buffer[b] = v;
| |
}
| |
| |
void set(const int b, const double &array[])
| |
{
| |
for(int i = 0; i < ArraySize(array); i++)
| |
{
| |
buffer[b + i] = array[i];
| |
}
| |
}
| |
| |
BufferGetter *edit()
| |
{
| |
if(instance == NULL) instance = new BufferGetter(this);
| |
return instance;
| |
}
| |
| |
double operator+(double x) const
| |
{
| |
return buffer[cursor] + x;
| |
}
| |
| |
double operator-(double x) const
| |
{
| |
return buffer[cursor] - x;
| |
}
| |
| |
double operator*(double x) const
| |
{
| |
return buffer[cursor] * x;
| |
}
| |
| |
double operator/(double x) const
| |
{
| |
return buffer[cursor] / x;
| |
}
| |
| |
double operator+=(double x)
| |
{
| |
buffer[cursor] += x;
| |
return buffer[cursor];
| |
}
| |
| |
double operator-=(double x)
| |
{
| |
buffer[cursor] -= x;
| |
return buffer[cursor];
| |
}
| |
| |
double operator*=(double x)
| |
{
| |
buffer[cursor] *= x;
| |
return buffer[cursor];
| |
}
| |
| |
double operator/=(double x)
| |
{
| |
buffer[cursor] /= x;
| |
return buffer[cursor];
| |
}
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Indicator buffer read-accessor via operator[](int) overload |
| |
//+------------------------------------------------------------------+
| |
class BufferGetter // helper class to access buffer values 'directly'
| |
{
| |
private:
| |
Buffer *owner;
| |
int cursor;
| |
| |
public:
| |
BufferGetter(Buffer &o)
| |
{
| |
owner = &o;
| |
}
| |
| |
double operator[](int b)
| |
{
| |
return owner[(GETTER)b];
| |
}
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Manager class for array of indicator buffer holders |
| |
//+------------------------------------------------------------------+
| |
class BufferArray
| |
{
| |
protected:
| |
Buffer *array[];
| |
| |
public:
| |
BufferArray() { }
| |
| |
void add(const int m = 1,
| |
const ENUM_INDEXBUFFER_TYPE type = INDICATOR_DATA,
| |
const double empty = EMPTY_VALUE,
| |
const bool asSeries = false)
| |
{
| |
const int n = ArraySize(array);
| |
ArrayResize(array, n + m);
| |
for(int i = 0; i < m; ++i)
| |
{
| |
array[n + i] = new Buffer(n + i, empty, type, asSeries);
| |
}
| |
}
| |
| |
BufferArray(const int n, const bool asSeries = false, const double empty = EMPTY_VALUE)
| |
{
| |
ArrayResize(array, n);
| |
for(int i = 0; i < n; ++i)
| |
{
| |
array[i] = new Buffer(i, empty, INDICATOR_DATA, asSeries);
| |
}
| |
}
| |
| |
BufferArray(const int n,
| |
const ENUM_INDEXBUFFER_TYPE &types[],
| |
const double empty = EMPTY_VALUE,
| |
const bool asSeries = false)
| |
{
| |
ArrayResize(array, n);
| |
for(int i = 0; i < n; ++i)
| |
{
| |
array[i] = new Buffer(i, empty, types[i], asSeries);
| |
}
| |
}
| |
| |
virtual ~BufferArray()
| |
{
| |
const int n = ArraySize(array);
| |
for(int i = 0; i < n; ++i)
| |
{
| |
if(CheckPointer(array[i]) == POINTER_DYNAMIC)
| |
{
| |
delete array[i];
| |
}
| |
}
| |
ArrayResize(array, 0);
| |
}
| |
| |
Buffer *operator[](int n) const
| |
{
| |
if(n >= ArraySize(array))
| |
{
| |
Print("OOB:", n , " >= ", ArraySize(array));
| |
}
| |
return array[n];
| |
}
| |
| |
int size() const
| |
{
| |
return ArraySize(array);
| |
}
| |
| |
void empty(const double empty = EMPTY_VALUE)
| |
{
| |
const int n = ArraySize(array);
| |
for(int i = 0; i < n; ++i)
| |
{
| |
array[i].empty(empty);
| |
}
| |
}
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Read-accessor for array of indicator buffer holders/accessors |
| |
//+------------------------------------------------------------------+
| |
class BufferArrayGetter
| |
{
| |
private:
| |
BufferGetter *array[];
| |
| |
public:
| |
BufferArrayGetter(){};
| |
| |
BufferArrayGetter(const BufferArray &a)
| |
{
| |
bind(a);
| |
}
| |
| |
void bind(const BufferArray &a)
| |
{
| |
int n = a.size();
| |
ArrayResize(array, n);
| |
for(int i = 0; i < n; ++i)
| |
{
| |
array[i] = a[i].edit();
| |
}
| |
}
| |
| |
BufferGetter *operator[](int n) const
| |
{
| |
return array[n];
| |
}
| |
| |
virtual ~BufferArrayGetter()
| |
{
| |
ArrayResize(array, 0);
| |
}
| |
};
| |
//+------------------------------------------------------------------+
|