//#include extern MqlRates rates[]; input group "Orderflow configurations" input ENUM_TIMEFRAMES inpOrderflowtf=PERIOD_CURRENT; class COrderflow /*:public CCore*/{ protected: int orderflowCurrent; //latest orderflow flag -1 for BEARISH, 1 for BULLISH double latestBullishRoot, latestBearishRoot; enum CISDOrderblocks{BEARISHORDERBLOCK=-1, ORDERBLOCKNONE=0, BULLISHORDERBLOCK=1}; //CQueue orderblocks; //array //latest cisd bool isCISD; public: //getters int getOrderflow(){return orderflowCurrent;}; bool whatWasOrderflow(int index, int &orderflowFlag, double &bearishRoot, double &bullishRoot); //asking for orderflow from the history bool whenWasCISD(int &index, int &flag, int bias=0); //asking when was the last CISD bool isCISDBySwings(int &flag); bool isGap(); bool wasGap(double &range, double &lowerBand, double &upperBand); bool initialize(); void update(); }; bool COrderflow::initialize(void){ if(latestBearishRoot!=0 && latestBullishRoot!=0){ //already initialized Print("roots already loaded!"); return true; } int bullishRootIdx=0, bearishRootIdx=0; for(int i=1; i rates[i].open; bool currBearish = rates[i].close < rates[i].open; bool prevBullish = rates[i+1].close > rates[i+1].open; bool prevBearish = rates[i+1].close < rates[i+1].open; // Bullish candle after bearish → start of bullish move → bullish root if(currBullish && prevBearish && latestBullishRoot==0){ rates[i].open < rates[i+1].close ? latestBullishRoot=rates[i].open : latestBullishRoot=rates[i+1].close; //avoiding the gap trap bullishRootIdx=i; } // Bearish candle after bullish → start of bearish move → bearish root if(currBearish && prevBullish && latestBearishRoot==0){ rates[i].open > rates[i+1].close ? latestBearishRoot=rates[i].open : latestBearishRoot=rates[i+1].close; //avoiding the gap trap bearishRootIdx=i; } if(latestBullishRoot!=0 && latestBearishRoot!=0){ Print("roots successfully loaded"); break; } } if(latestBullishRoot==0 || latestBearishRoot==0){ Print("failed to load one of roots"); return false; } if(rates[1].close > latestBearishRoot){ orderflowCurrent=1; } else if(rates[1].close < latestBullishRoot){ orderflowCurrent=-1; } else{ // closing in between — the most recently formed root decides orderflowCurrent = (bullishRootIdx < bearishRootIdx) ? 1 : -1; } return true; } bool COrderflow::whatWasOrderflow(const int index,int &orderflowFlag, double &bearishRoot, double &bullishRoot){ if(bearishRoot!=0||bullishRoot!=0) { Print("Reference provided is already loaded, reset it before proceeding"); Sleep(200); bullishRoot=0; bearishRoot=0; } int bullishRootIdx=0, bearishRootIdx=0; for(int i=index; i rates[i].open; bool currBearish = rates[i].close < rates[i].open; bool prevBullish = rates[i+1].close > rates[i+1].open; bool prevBearish = rates[i+1].close < rates[i+1].open; // Bullish candle after bearish → start of bullish move → bullish root if(currBullish && prevBearish && bullishRoot==0){ rates[i].open < rates[i+1].close ? bullishRoot=rates[i].open : bullishRoot=rates[i+1].close; //avoiding the gap trap bullishRootIdx=i; } // Bearish candle after bullish → start of bearish move → bearish root if(currBearish && prevBullish && bearishRoot==0){ rates[i].open > rates[i+1].close ? bearishRoot=rates[i].open : bearishRoot=rates[i+1].close; //avoiding the gap trap bearishRootIdx=i; } if(bullishRoot!=0 && bearishRoot!=0) break; } if(bullishRoot==0 || bearishRoot==0) return false; if(rates[index].close > bearishRoot){ orderflowFlag=1; } else if(rates[index].close < bullishRoot){ orderflowFlag=-1; } else{ // closing in between — the most recently formed root decides orderflowFlag = (bullishRootIdx < bearishRootIdx) ? 1 : -1; } return true; } void COrderflow::update(void){ if(orderflowCurrent==0){ Print("There was NULL Orderflow, trying to initialize right now.. "); COrderflow::initialize(); } if(orderflowCurrent==1){ //the current orderflow is bullish if(rates[1].closerates[2].open){ //receiving first-time opposing candle // rates[1].open>rates[2].close ? latestBearishRoot=rates[1].open : latestBearishRoot=rates[2].close; } if(rates[1].close>rates[1].open // && rates[2].closerates[2].close ? latestBullishRoot=rates[2].close : latestBullishRoot=rates[1].open; } } if(orderflowCurrent==-1){ //the current orderflow is bearish if(rates[1].close>latestBearishRoot){ //cisd isCISD=true; orderflowCurrent=1; } if(rates[1].close>rates[1].open // && rates[2].closerates[2].close ? latestBullishRoot=rates[2].close : latestBullishRoot=rates[1].open; } if(rates[1].closerates[2].open){ //receiving first-time opposing candle // rates[1].open>rates[2].close ? latestBearishRoot=rates[1].open : latestBearishRoot=rates[2].close; } } }