//+------------------------------------------------------------------+
//|                                           TDSequentialByGP2X.mq4 |
//|                                           Copyright © 2006, GP2X |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, GP2X"
#property link      ""

#property indicator_chart_window
#property indicator_buffers 0

#define STATUS_NONE 0
#define STATUS_BUY_SETUP 1
#define STATUS_BUY_COUNTDOWN 2
#define STATUS_SELL_SETUP -1
#define STATUS_SELL_COUNTDOWN -2

//---- input parameters
extern int SPACE = 8;
extern color BuyColor = Aqua;
extern color SellColor = Red;

int countDown, setupStartPos;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   ObjectsDeleteAll();
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start() {
   int status = STATUS_NONE;
   setupStartPos = 0;
   countDown = 0;
   int i;
      for (i=Bars-12;i>=0;i--) {
         status = checkSetup(i, status);
         
         if (status == STATUS_BUY_SETUP)
            status = confirmBuyInterSec(i);
         if (status == STATUS_BUY_COUNTDOWN)
            status = continueBuyCountDown(i);
         if (status == STATUS_SELL_SETUP)
            status = confirmSellInterSec(i);
         if (status == STATUS_SELL_COUNTDOWN)
            status = continueSellCountDown(i);         
      }
   return(0);
}

int checkSetup(int barPos, int oldStatus) {
   int status = oldStatus, i;
   bool isSetup;
   if (oldStatus!=STATUS_BUY_SETUP && oldStatus!=STATUS_BUY_COUNTDOWN) {
      isSetup = true;
      for (i=barPos;i<barPos+9;i++) {
         isSetup = Close[i]<Close[i+4];
         if (!isSetup) break;
      }      
      if (isSetup && MathMin(Low[barPos], Low[barPos+1])<MathMin(Low[barPos+2], Low[barPos+3])) { //New Buy Setup
         setupStartPos = barPos+8;
         for (i=1;i<=9;i++) {
            drawNumber(i, barPos+9-i);
         }
         status = STATUS_BUY_SETUP;
      }
   }
   if (oldStatus!=STATUS_SELL_SETUP && oldStatus!=STATUS_SELL_COUNTDOWN) {
      isSetup = true;
      for (i=barPos;i<barPos+9;i++) {
         isSetup = Close[i]>Close[i+4];
         if (!isSetup) break;
      }
      if (isSetup && MathMax(High[barPos], High[barPos+1])>MathMax(High[barPos+2], High[barPos+3])) { //Sell Setup
         setupStartPos = barPos+8;
         for (i=1;i<=9;i++) {
            drawNumber(-i, barPos+9-i);         
         }
         status = STATUS_SELL_SETUP;
      }
   }
   return (status);
}

int confirmBuyInterSec(int barPos) {
   int status;
   bool isIs = false;
   isIs = isBuyInterSec(barPos, setupStartPos);
   if (!isIs && barPos==setupStartPos-8)
      //Also look at bar 8th
      isIs = isBuyInterSec(barPos+1, barPos+8);
   if (isIs) {
      countDown = 0;
      status = STATUS_BUY_COUNTDOWN; 
   }
   else
      status = STATUS_BUY_SETUP;
   return (status);
}


bool isBuyInterSec(int fromBar, int toBar) {
   bool result = false;
   int i;
   for (i=fromBar+3;i<=toBar;i++) {
      if (High[fromBar]>=Low[i]) {
         result = true;
         break;
      }
   }
   return (result);
}

int confirmSellInterSec(int barPos) {
   int status;
   bool isIs = false;
   isIs = isSellInterSec(barPos, setupStartPos);
   if (!isIs && barPos==setupStartPos-8)
      //Also look at bar 8th
      isIs = isSellInterSec(barPos+1, barPos+8);
   if (isIs) {
      countDown = 0;
      status = STATUS_SELL_COUNTDOWN; 
   }
   else
      status = STATUS_SELL_SETUP;
   return (status);
}

bool isSellInterSec(int fromBar, int toBar) {
   bool result = false;
   int i;
   for (i=fromBar+3;i<=toBar;i++) {
      if (Low[fromBar]<=High[i]) {
         result = true;
         break;
      }
   }
   return (result);
}

int continueBuyCountDown(int barPos) {
   int status = STATUS_BUY_COUNTDOWN;
   if (Close[barPos]<=Low[barPos+2]) {
      countDown++;
      drawNumber(countDown, barPos);
      if (countDown==13)
         status = STATUS_NONE;
   }
   return (status);
}

int continueSellCountDown(int barPos) {
   int status = STATUS_SELL_COUNTDOWN;
   if (Close[barPos]>=High[barPos+2]) {
      countDown--;
      drawNumber(countDown, barPos);
      if (countDown==-13)
         status = STATUS_NONE;
   }
   return (status);
}

void drawNumber(double number, int barPos) {
   double drawPrice;
   int drawColor;
   string drawText = DoubleToStr(MathAbs(number), 0);
   string objName = "TXT" + TimeToStr(Time[barPos]);
   ObjectDelete(objName);
   if (number>0) {
      drawPrice = Low[barPos]-SPACE*Point;
      drawColor = BuyColor;
   }
   else {
      drawPrice = High[barPos]+SPACE*Point;
      drawColor = SellColor;
   }
   //Print ("Draw", number);
   ObjectCreate(objName, OBJ_TEXT, 0, Time[barPos], drawPrice);
   ObjectSetText(objName, drawText, 7, "Arial", drawColor);
}

//+------------------------------------------------------------------+