/*------------------------------------------------------------------------------------
   Name: TMS-Osc Histo.mq4
   Copyright ｩ2010, Xaphod, http://forexwhiz.appspot.com
   
   Description: Tape chart of the Trading made Simple System Oscillator. 
                Similar to the TDI RSI Signal Line and Trade Signal Line.

   Change log: 
       2011-05-18. Xaphod, v1.04
          - Fix for repeated alerts
       2011-05-17. Xaphod, v1.03
          - Timestamp in email alert corrected
       2011-05-17. Xaphod, v1.02 
          - Alerts for bar 1 only. Prevents multiple alerts when MT4 reloads bars
       2011-05-16. Xaphod, v1.01 
          - No alerts after initialization
       2011-05-16. Xaphod, v1.00 
          - First Release 
-------------------------------------------------------------------------------------*/
// Indicator properties
#property copyright "Copyright ｩ 2010, Xaphod"
#property link      "http://forexwhiz.appspot.com"

#property indicator_separate_window
#property indicator_buffers 6
#property indicator_color1 CLR_NONE
#property indicator_width1 1
#property indicator_color2 CLR_NONE
#property indicator_width2 1
#property indicator_color3 CLR_NONE
#property indicator_width3 1
#property indicator_color4 Yellow
#property indicator_width4  4
#property indicator_color5 Green
#property indicator_width5  4
#property indicator_color6 Red
#property indicator_width6  4
#property indicator_maximum 1
#property indicator_minimum 0

//#include <xDebug.mqh>

// Constant definitions
#define INDICATOR_NAME "TMS-Osc Histo"
#define INDICATOR_VERSION "1.04"
#define INDICATOR_DISP_VC "1.04, ｩ2011, Xaphod"
// Signals
#define SIG_NO 0
#define SIG_UP 1
#define SIG_DN 2


// Indicator parameters
extern string    Indi.Version= INDICATOR_DISP_VC;
extern string    RSI.Settings="覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern int       RSI.Period=13;             // RSI Period
extern int       RSI.Price=PRICE_CLOSE;     // RSI Price Type: CLOSE=0, OPEN=1, HIGH=2, LOW=3, MEDIAN=4, TYPICAL=5, WEIGHTED=6
extern string    RSISignal.Settings="覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern int       RSISignal.Period=2;        // RSI Signal MA-Filter Period
extern int       RSISignal.Mode=MODE_SMA;   // MA-Filter Method: SMA=0, EMA=1, SMMA=2, LWMA=4
extern string    TradeSignal.Settings="覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern int       TradeSignal.Period=7;      // Trade Signal MA-Filter Period
extern int       TradeSignal.Mode=MODE_SMA; // MA-Filter Method: SMA=0, EMA=1, SMMA=2, LWMA=4
extern string    Alert.Settings="覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern bool      Alert.Popup=false;         // Popup window & sound on alert
extern bool      Alert.Email=false;         // Send email on alert
extern string    Alert.Subject="Default";   // Email Subject. If "Default" the subject is set by the indicator

// Global module varables
double gadRSI[];
double gadRSISig[];
double gadTradeSig[];
double gadTrendNo[];
double gadTrendUp[];
double gadTrendDn[];
bool gbInit;

//-----------------------------------------------------------------------------
// function: init()
// Description: Custom indicator initialization function.
//-----------------------------------------------------------------------------
int init() {
  SetIndexStyle(0, DRAW_LINE);
  SetIndexBuffer(0, gadRSI);
  SetIndexLabel(0,NULL);
  SetIndexStyle(1, DRAW_LINE);
  SetIndexBuffer(1, gadRSISig);
  SetIndexLabel(1,"RSI Signal");
  SetIndexStyle(2, DRAW_LINE);
  SetIndexBuffer(2, gadTradeSig);
  SetIndexLabel(2,"Trade Signal");   
  SetIndexStyle(3,DRAW_HISTOGRAM);
  SetIndexBuffer(3,gadTrendNo);
  SetIndexLabel(3,"Trend Level");
  SetIndexStyle(4,DRAW_HISTOGRAM);
  SetIndexBuffer(4,gadTrendUp);
  SetIndexLabel(4,"Trend Up");
  SetIndexStyle(5,DRAW_HISTOGRAM);
  SetIndexBuffer(5,gadTrendDn);
  SetIndexLabel(5,"Trend Down");
  
  IndicatorDigits(1);
  IndicatorShortName(INDICATOR_NAME);
  gbInit=True;
  return(0);
}


//-----------------------------------------------------------------------------
// function: deinit()
// Description: Custom indicator deinitialization function.
//-----------------------------------------------------------------------------
int deinit() {
   return (0);
}


///-----------------------------------------------------------------------------
// function: start()
// Description: Custom indicator iteration function.
//-----------------------------------------------------------------------------
int start() {
  int iNewBars;
  int iCountedBars; 
  int i;
  static datetime tCurBar=0;
  
  // Get unprocessed ticks
  iCountedBars=IndicatorCounted();
  if(iCountedBars < 0) return (-1); 
  if(iCountedBars>0) iCountedBars--;
  iNewBars=Bars-iCountedBars;
  
  // Calc TMS signals
  for(i=iNewBars; i>=0; i--) {
    gadRSI[i] = iRSI(NULL,0,RSI.Period,RSI.Price,i); 
  }  
  for(i=iNewBars; i>=0; i--) {  
    gadRSISig[i]=iMAOnArray(gadRSI,0,RSISignal.Period,0,RSISignal.Mode,i);
    gadTradeSig[i]=iMAOnArray(gadRSI,0,TradeSignal.Period,0,TradeSignal.Mode,i);    
  }
  
  // Draw Histo
  for(i=iNewBars; i>=0; i--) {
    gadTrendNo[i]=EMPTY_VALUE;
    gadTrendUp[i]=EMPTY_VALUE;
    gadTrendDn[i]=EMPTY_VALUE;
  
    if (gadRSISig[i]>gadTradeSig[i])
      gadTrendUp[i]=1;
    else if (gadRSISig[i]<gadTradeSig[i])
      gadTrendDn[i]=1;
    else
      gadTrendNo[i]=1;
    
    // On new bar check for cross
    if (tCurBar<Time[i]) {
      tCurBar=Time[i];   
      if (!gbInit && i==0)
        SignalTMSCross(i+1);
    }
  }
  
  // Clear Init Flag
  if (gbInit)
    gbInit=False;  
  return(0);
}
//+------------------------------------------------------------------+


//-----------------------------------------------------------------------------
// function: SignalTMSCross()
// Description: 
//-----------------------------------------------------------------------------
void SignalTMSCross(int iBar) {
  static int iCurSig=SIG_NO;
  // Up signal 
  if (iCurSig!=SIG_UP && (gadRSISig[iBar] > gadTradeSig[iBar]) && (gadRSISig[iBar+1] < gadTradeSig[iBar+1])) {
    iCurSig=SIG_UP;
    DoAlert("LONG Signal!");
  }
  // Down signal
  else if (iCurSig!=SIG_DN && (gadRSISig[iBar] < gadTradeSig[iBar]) && (gadRSISig[iBar+1] > gadTradeSig[iBar+1])) {
    iCurSig=SIG_DN;
    DoAlert("SHORT Signal!");
  }
  return(0);  
}


//-----------------------------------------------------------------------------
// function: DoAlert()
// Description: Alert on signal
//-----------------------------------------------------------------------------
void DoAlert(string sAlertMsg) {
  // Do Alerts        
  sAlertMsg=Symbol()+", "+TF2Str(Period())+": "+sAlertMsg;
  if (Alert.Popup) Alert(sAlertMsg, ", ", INDICATOR_NAME," v",INDICATOR_VERSION);
  if (Alert.Email) {
    if (Alert.Subject=="Default") Alert.Subject=sAlertMsg;
    SendNotification(sAlertMsg);
    // SendNotification( Alert.Subject, "MT4 Alert! "+INDICATOR_NAME+"\n" + TimeToStr(Time[0],TIME_DATE|TIME_SECONDS )+"\n"+sAlertMsg);          
  }
}


//-----------------------------------------------------------------------------
// function: TF2Str()
// Description: Convert time-frame to a string
//-----------------------------------------------------------------------------
string TF2Str(int iPeriod) {
  switch(iPeriod) {
    case PERIOD_M1: return("M1");
    case PERIOD_M5: return("M5");
    case PERIOD_M15: return("M15");
    case PERIOD_M30: return("M30");
    case PERIOD_H1: return("H1");
    case PERIOD_H4: return("H4");
    case PERIOD_D1: return("D1");
    case PERIOD_W1: return("W1");
    case PERIOD_MN1: return("MN1");
    default: return("M"+iPeriod);
  }
}


