//what we simply do right here is // read candlestick momentum by // #1 comparing upper vs lower wick // #2 closure beyond prev candle //--REQUIREMENTS extern MqlRates rates[]; #include //CqueuecandlesticksCollection; class CCandlestick{ protected: enum closure {CLOSEDBELOW=-1, CLOSEDNONE=0, CLOSEDABOVE=1}; CQueue candleClosureCollection; enum relativeMomentum {MOMENTUMDOWN=-1,MOMENTUMEQUAL=0, MOMENTUMUP=1}; CQueue candleRelMomentumCollection;//array of rel momentum (up vs down) int m_latestCandleBias; void coreLogic(); public: //methods of accessing the protected int getLatestCandleBias(){return m_latestCandleBias;}; bool getCandleCollection(int &dstArray[], bool modeClosure=false); //array of closure DSA //array of relative momentum DSA //updating the data bool wasWhat(int candleIndex, int &bias); //returning the bias of the specific candle bool wasWhat(int startIndex, int count,/*&dsa, */bool asSeries=true); //try to fill the array with history data void update(void); //run this inside OnTick() double getUpperSize(int candleIndex=1); double getLowerSize(int candleIndex=1); bool isBull(int candleIndex=1); bool isBear(int candleIndex=1); bool isOpposingCandle(int &flag, const int index=1); //checks whether bool isEngulfing(int &flag, const int index); bool isInsideBar(int &flag, const int index); }; void CCandlestick::coreLogic(void){ } bool CCandlestick::isBull(int candleIndex=1){ return rates[candleIndex].close>rates[candleIndex].open; } bool CCandlestick::isBear(int candleIndex=1){ return rates[candleIndex].closeArraySize(rates)){ Print("ATTENTION: candleIndex requested is far from reach, wait while fetching some data"); } else //if the Index is reachable double lowerSize = MathAbs(rates[candleIndex].low-MathMin(rates[candleIndex].close,rates[candleIndex].open)); double upperSize = MathAbs(rates[candleIndex].high-MathMax(rates[candleIndex].close,rates[candleIndex].open)); return false; } void CCandlestick::update(void){ //fill the array //run the core logic here double lowerSize = MathAbs(rates[1].low-MathMin(rates[1].close,rates[1].open)); double upperSize = MathAbs(rates[1].high-MathMax(rates[1].close,rates[1].open)); //Momentum check if(lowerSize>upperSize){ if(!candleRelMomentumCollection.Enqueue(MOMENTUMUP)){ Print("Failed to register a candles parameter, retrying.."); candleRelMomentumCollection.Enqueue(MOMENTUMUP); } } else if(lowerSizerates[2].high || rates[1].closerates[2].high || rates[1].low0){return true;} // else {//failed to copy // //log failure to copy // return false; // } // } // // else{ //chose to copy closure // if(candleClosureCollection.CopyTo(dstArray)>0){return true;} // else {//failed to copy // //log failure to copy // return false; // } // } //} bool CCandlestick::isOpposingCandle(int &flag, const int index=1){ if(rates[index].close>rates[index].open //bull && rates[index+1].closerates[index+1].open){ //pred by bull flag=-1; return true; } return false; } bool CCandlestick::isEngulfing(int &flag,const int index=1){ if(rates[index].high>rates[index+1].high && rates[index].lowrates[index+1].low){ //not breaking any of prev candle' extremes if(CCandlestick::isBull(index)){ // assigning flag to bullish engulfing flag=1; return true; } else if(CCandlestick::isBear(index)){ //bearish engulfing flag=-1; return true; } } //else return false; }