314 lines
9 KiB
MQL5
314 lines
9 KiB
MQL5
|
//+------------------------------------------------------------------+
|
||
|
//| FormationContainers.mqh |
|
||
|
//| Copyright 2024, MetaQuotes Ltd. |
|
||
|
//| https://www.mql5.com |
|
||
|
//+------------------------------------------------------------------+
|
||
|
#property copyright "Copyright 2024, MetaQuotes Ltd."
|
||
|
#property link "https://www.mql5.com"
|
||
|
|
||
|
|
||
|
enum ENUM_FORMATION{
|
||
|
FORMATION_VALUE_GAP = 13,
|
||
|
FORMATION_ABSORBING = 12,
|
||
|
FORMATION_INSIDE_BAR = 22
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
|
||
|
class Formation{
|
||
|
public:
|
||
|
double _high_level_renge;
|
||
|
double _low_level_renge;
|
||
|
double _equator_renge;
|
||
|
bool _isUp;
|
||
|
bool _isTested;
|
||
|
ENUM_FORMATION _type_formation;
|
||
|
datetime _time;
|
||
|
|
||
|
Formation(){
|
||
|
this._high_level_renge = 0.0;
|
||
|
this._low_level_renge = 0.0;
|
||
|
this._type_formation = -1;
|
||
|
this._equator_renge = 0.0;
|
||
|
this._time = 0;
|
||
|
}
|
||
|
Formation(const Formation &form){
|
||
|
this._type_formation = form._type_formation;
|
||
|
this._isUp = form._isUp;
|
||
|
this._high_level_renge = form._high_level_renge;
|
||
|
this._low_level_renge = form._low_level_renge;
|
||
|
this._isTested = form._isTested;
|
||
|
this._time = form._time;
|
||
|
setEquator();
|
||
|
}
|
||
|
/*Formation operator=(const Formation &form){
|
||
|
Formation _new_form;
|
||
|
_new_form._type_formation = form._type_formation;
|
||
|
_new_form._isUp = form._isUp;
|
||
|
_new_form._high_level_renge = form._high_level_renge;
|
||
|
_new_form._low_level_renge = form._low_level_renge;
|
||
|
_new_form.setEquator();
|
||
|
|
||
|
return _new_form;
|
||
|
}*/
|
||
|
void setEquator(){
|
||
|
this._equator_renge = (this._high_level_renge + this._low_level_renge) / 2;
|
||
|
}
|
||
|
void Print(){
|
||
|
int digits = (int)::SymbolInfoInteger(NULL,SYMBOL_DIGITS);
|
||
|
string direction = (this._isUp ? "Up direct" : "Down direct");
|
||
|
string test = (this._isTested ? "Tested" : "Not tested");
|
||
|
::Print(::TimeToString(this._time,TIME_DATE|TIME_MINUTES),"\t",
|
||
|
::EnumToString(this._type_formation),"\t",
|
||
|
direction,"\t",
|
||
|
::DoubleToString(this._high_level_renge,digits),"\t",
|
||
|
::DoubleToString(this._low_level_renge,digits),"\t",
|
||
|
::DoubleToString(this._equator_renge,digits),"\t",
|
||
|
test);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
|
||
|
class FormArray{
|
||
|
Formation _array[];
|
||
|
uint _size;
|
||
|
uint _reserv;
|
||
|
|
||
|
public:
|
||
|
FormArray(){
|
||
|
::ArrayResize(this._array,0,64);
|
||
|
this._size = 0;
|
||
|
this._reserv = 64;
|
||
|
}
|
||
|
FormArray(const int size,const int reserv = 64){
|
||
|
::ArrayResize(this._array,size,reserv);
|
||
|
this._size = size;
|
||
|
this._reserv = reserv;
|
||
|
}
|
||
|
Formation *operator[](const uint index)const{
|
||
|
return at(index);
|
||
|
}
|
||
|
Formation *at(const uint index)const{
|
||
|
return ::GetPointer(this._array[index]);
|
||
|
}
|
||
|
/*Formation operator=(const Formation &form)const{
|
||
|
Formation _new_form;
|
||
|
_new_form._isUp = form._isUp;
|
||
|
_new_form._type_formation = form._type_formation;
|
||
|
_new_form._high_level_renge = form._high_level_renge;
|
||
|
_new_form.
|
||
|
}*/
|
||
|
void Print(){
|
||
|
::Print("[Time]\t[Type formation]\t[Direction]\t[Up level price]\t[Down level price]\t[Equator level price]\t[Tested]");
|
||
|
for(int i = 0,size = ::ArraySize(this._array);i < size;i++){
|
||
|
this._array[i].Print();
|
||
|
}
|
||
|
}
|
||
|
void append(const Formation &form){
|
||
|
if(this._reserv == 0){
|
||
|
::ArrayResize(this._array,this._size + 1,64);
|
||
|
this._array[this._size] = form;
|
||
|
this._size++;
|
||
|
this._reserv = 64;
|
||
|
}
|
||
|
else{
|
||
|
::ArrayResize(this._array,this._size + 1);
|
||
|
//::Print(this._size,"\t",::ArraySize(this._array),"\t",this._reserv);
|
||
|
this._array[this._size] = form;
|
||
|
this._size++;
|
||
|
if(this._reserv > 0)
|
||
|
this._reserv--;
|
||
|
}
|
||
|
}
|
||
|
void clear(){
|
||
|
::ArrayFree(this._array);
|
||
|
this._size = 0;
|
||
|
this._reserv = 64;
|
||
|
::ArrayResize(this._array,this._size,this._reserv);
|
||
|
}
|
||
|
void remove(const uint index){
|
||
|
::ArrayRemove(this._array,index,1);
|
||
|
this._size--;
|
||
|
}
|
||
|
uint size()const{
|
||
|
return this._size;
|
||
|
}
|
||
|
uint reserv()const{
|
||
|
return this._reserv;
|
||
|
}
|
||
|
void resize(const uint _new_size){
|
||
|
this._size = _new_size;
|
||
|
::ArrayResize(this._array,this._size,this._reserv);
|
||
|
}
|
||
|
void resize(const uint _new_size,const uint _new_reserv){
|
||
|
this._size = _new_size;
|
||
|
this._reserv = _new_reserv;
|
||
|
::ArrayResize(this._array,this._size,this._reserv);
|
||
|
}
|
||
|
void setReserv(const uint _new_reserv){
|
||
|
this._reserv = _new_reserv;
|
||
|
::ArrayResize(this._array,this._size,this._reserv);
|
||
|
this._reserv = _new_reserv;
|
||
|
}
|
||
|
bool isEmpty()const{
|
||
|
return (this._size == 0);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
/*
|
||
|
class Node{
|
||
|
public:
|
||
|
Formation item;
|
||
|
//int value;
|
||
|
|
||
|
Node *prev;
|
||
|
Node *next;
|
||
|
Node(){
|
||
|
this.item = Formation();
|
||
|
//this.value = 0;
|
||
|
this.prev = NULL;
|
||
|
this.next = NULL;
|
||
|
}
|
||
|
Node(const Formation &form){
|
||
|
this.item = new Formation(form);
|
||
|
//this.value = _value;
|
||
|
this.prev = NULL;
|
||
|
this.next = NULL;
|
||
|
}
|
||
|
Node(const Node &node){
|
||
|
this.item = node.item;
|
||
|
//this.value = node.value;
|
||
|
this.prev = NULL;
|
||
|
this.next = NULL;
|
||
|
}
|
||
|
void SetNextNode(Node *ptr_next);
|
||
|
void SetPrevNode(Node *ptr_prev);
|
||
|
Node *GetNextNode()const{
|
||
|
return this.next;
|
||
|
}
|
||
|
Node *GetPrevNode()const{
|
||
|
return this.prev;
|
||
|
}
|
||
|
/*Node operator=(const Node &node){
|
||
|
Node nNode;
|
||
|
nNode.item = node.item;
|
||
|
nNode.prev = NULL;
|
||
|
nNode.next = NULL;
|
||
|
|
||
|
return nNode;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void Node::SetNextNode(Node *ptr_next){
|
||
|
this.next = ptr_next;
|
||
|
}
|
||
|
void Node::SetPrevNode(Node *ptr_prev){
|
||
|
this.prev = ptr_prev;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
|
||
|
class FormationList{
|
||
|
private:
|
||
|
ulong _size;
|
||
|
|
||
|
public:
|
||
|
Node *head;
|
||
|
Node *tail;
|
||
|
FormationList(){
|
||
|
this._size = 0;
|
||
|
this.head = NULL;
|
||
|
this.tail = NULL;
|
||
|
}
|
||
|
FormationList(const Formation &form){
|
||
|
this._size = 1;
|
||
|
Node *node = new Node(form);
|
||
|
this.head = node;
|
||
|
this.tail = node;
|
||
|
}
|
||
|
FormationList(const FormationList &list){
|
||
|
this.head = list.head;
|
||
|
this.tail = list.tail;
|
||
|
}
|
||
|
void append(const Formation &form);
|
||
|
void insert(const ulong index, const Formation &form);
|
||
|
void shift(const Formation &form);
|
||
|
ulong size() const{
|
||
|
return this._size;
|
||
|
}
|
||
|
Node at(const ulong index);
|
||
|
Formation operator[](const ulong index);
|
||
|
};
|
||
|
|
||
|
void FormationList::append(const Formation &form){
|
||
|
|
||
|
|
||
|
Node *new_node = new Node(form);
|
||
|
this.tail.SetNextNode(new_node);
|
||
|
new_node.SetPrevNode(this.tail);
|
||
|
this.tail = new_node;
|
||
|
this._size++;
|
||
|
}
|
||
|
|
||
|
void FormationList::shift(const Formation &form){
|
||
|
|
||
|
Node *newNode = new Node(form);
|
||
|
this.head.prev = newNode;
|
||
|
newNode.next = this.head;
|
||
|
this.head = newNode;
|
||
|
this._size++;
|
||
|
}
|
||
|
|
||
|
void FormationList::insert(const ulong index,const Formation &form){
|
||
|
|
||
|
Node *current,*newNode;
|
||
|
current = at(index);
|
||
|
|
||
|
newNode = new Node(form);
|
||
|
newNode.next = current.next;
|
||
|
current.next = newNode;
|
||
|
newNode.prev = current;
|
||
|
this._size++;
|
||
|
|
||
|
}
|
||
|
|
||
|
Node FormationList::at(const ulong index){
|
||
|
Formation form;
|
||
|
Node *current;
|
||
|
if(index >= this._size / 2){
|
||
|
ulong count = this._size - 1;
|
||
|
current = this.tail;
|
||
|
for(;current != this.head.prev;){
|
||
|
if(count == index)
|
||
|
break;
|
||
|
else{
|
||
|
current = current.prev;
|
||
|
count--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
ulong count = 0;
|
||
|
current = this.head;
|
||
|
for(;current != this.tail.next;){
|
||
|
if(count == index)
|
||
|
break;
|
||
|
else{
|
||
|
current = current.next;
|
||
|
count++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return current;
|
||
|
}
|
||
|
|
||
|
Formation FormationList::operator[](const ulong index){
|
||
|
Node current = at(index);
|
||
|
return current.item;
|
||
|
}*/
|