//+------------------------------------------------------------------+ //| 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; }*/