//--- VSA CONSTANTS
#define SIGNAL_STRONG      0
#define SIGNAL_WEAK        1
#define SIGNAL_NONE        -1

//--- ADV. VOLUMES CONSTANTS
#define VOLUME_LOW         0
#define VOLUME_HIGH        1
#define VOLUME_CHURN       2
#define VOLUME_THRUST      3
#define VOLUME_STRONGTEST  4
#define VOLUME_WEAKTEST    5
#define VOLUME_NONE        -1

//--- ALERT SYSTEM CONSTANTS
#define TRADE_LONG		   0
#define TRADE_SHORT		   1
#define TRADE_NONE		   -1 
#define ALERT_UPTRENDLINE_NEARBY 0
#define ALERT_DOWNTRENDLINE_NEARBY 1
#define ALERT_UPTRENDLINE_BROKEN 2
#define ALERT_DOWNTRENDLINE_BROKEN 3
#define ALERT_SUPPORT_NEARBY 4
#define ALERT_RESISTANCE_NEARBY 5
#define ALERT_RESISTANCE_BROKEN 6
#define ALERT_SUPPORT_BROKEN 7
#define ALERT_DT_UP 8
#define ALERT_DT_DOWN 9
#define ALERT_VSA_UP 10
#define ALERT_VSA_DOWN 11

//--- REVERSALS CONSTANTS
#define REVERSAL_UP        0
#define REVERSAL_DOWN      1
#define REVERSAL_NONE      -1

//--- CONGESTIONS CONSTANTS
#define CONGESTION_STRONG  0
#define CONGESTION_WEAK    1
#define CONGESTION_NONE    -1

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
  
datetime lastTime = 0;

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   // RUN ONLY AT BAR'S OPEN. ERASE CODE BELOW TO RUN EVERY TICK
   if (lastTime != iTime(NULL, 0, 1))
      lastTime = iTime(NULL, 0, 1);
   else
      return;
   //------------------------------------------------------------
     
   const string symbol = Symbol();
   const int timeframe = Period();
   
   //---------------------------------------------//
   // REPLACE ALERTS BY YOUR OWN CODE             //
   //---------------------------------------------//
   
   //--- VSA ALERTS
   
   int vsa_signal = IsVSASignal(symbol, timeframe, 1);
   
   // Strong VSA signal
   if (vsa_signal == SIGNAL_STRONG)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
      
      Alert(symbol + " " + IntegerToString(timeframe) + " - Strong VSA signal.");
   }
   
   // Weak VSA signal
   if (vsa_signal == SIGNAL_WEAK)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
     Alert(symbol + " " + IntegerToString(timeframe) + " - Weak VSA signal.");
   }
   
   //--- ADV. VOLUMES ALERTS
   
   int advolumes_bar = IsAdvancedVolumesBar(symbol, timeframe, 1);
   
   // Low volume bar
   if (advolumes_bar == VOLUME_LOW)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
     Alert(symbol + " " + IntegerToString(timeframe) + " - Low Volume bar.");
   }
   
   // High volume bar
   if (advolumes_bar == VOLUME_HIGH)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
      Alert(symbol + " " + IntegerToString(timeframe) + " - High Volume bar.");
   }
   
   // Churn bar
   if (advolumes_bar == VOLUME_CHURN)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
      Alert(symbol + " " + IntegerToString(timeframe) + " - Churn bar.");
   }
   
   // Thrust bar
   if (advolumes_bar == VOLUME_THRUST)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
      Alert(symbol + " " + IntegerToString(timeframe) + " - Thrust bar.");
   }
   
   // Strong test bar
   if (advolumes_bar == VOLUME_STRONGTEST)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
      Alert(symbol + " " + IntegerToString(timeframe) + " - Strong Test bar.");
   }
   
   // Weak test bar
   if (advolumes_bar == VOLUME_WEAKTEST)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
      Alert(symbol + " " + IntegerToString(timeframe) + " - Weak Test bar.");
   }
   
   //--- ALERT SYSTEM ALERTS
   
   double tp, sl, be, execprice, alertType;
   int alertsystem_signal = IsAlertSystem(symbol, timeframe, 1, tp, sl, be, execprice, alertType);
   
   // Long alert
   if (alertsystem_signal == TRADE_LONG) 
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
     
      Alert(symbol + " " + IntegerToString(timeframe) + " - LONG alert type ", DoubleToStr(alertType,0), " TP = ", tp, " SL = ", sl, " MOVE TO BE = ", be, " EXEC. PRICE = ", execprice);
   }
   
   // Short alert
   if (alertsystem_signal == TRADE_SHORT) 
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
     
      Alert(symbol + " " + IntegerToString(timeframe) + " - SHORT alert type ", DoubleToStr(alertType,0), " TP = ", tp, " SL = ", sl, " MOVE TO BE = ", be, " EXEC. PRICE = ", execprice);
   }
   
   //--- REVERSALS ALERTS
   
   int reversal_arrow = IsReversalArrow(symbol, timeframe, 1);
   
   // Up reversal
   if (reversal_arrow == REVERSAL_UP)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
      Alert(symbol + " " + IntegerToString(timeframe) + " - Up reversal arrow.");
   }
   
   // Down reversal
   if (reversal_arrow == REVERSAL_DOWN)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
      Alert(symbol + " " + IntegerToString(timeframe) + " - Down reversal arrow.");
   }
   
   //--- CONGESTIONS ALERTS
   
   int congestion_bar = IsCongestionBar(symbol, timeframe, 1);
   
   // Strong congestion
   if (congestion_bar == CONGESTION_STRONG)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
      Alert(symbol + " " + IntegerToString(timeframe) + " - Strong congestion.");
   }
   
   // Weak congestion
   if (congestion_bar == CONGESTION_WEAK)
   {
     /* 
         PLACE YOUR OWN CODE HERE...
               .....
     */
      Alert(symbol + " " + IntegerToString(timeframe) + " - Weak congestion.");
   }
   
  }
//+------------------------------------------------------------------+

//--- VSA: Check if VSA signal is strong, weak, or if there was no signal
int IsVSASignal(string symbol, int timeframe, int s)
{
   const int History = 500;
   
   double dSignal = iCustom(symbol, timeframe, "AT-VSA", DEF_KEY, false, 0, true, false, false, "-", History, true, "-", 
                    false, true, false, 200, clrBlue, clrBlue, clrBlue, clrBlue, clrBlue, clrBlue, "-", "-", "-", "-", "-", false, 
                    false, false, false, false, "-", true, true, true, true, true, "-", false, true, 27, s);
   
   if(dSignal == 1)
      return SIGNAL_STRONG;
   else if (dSignal == -1)
      return SIGNAL_WEAK;
   
   return SIGNAL_NONE;
}

//--- ADVANCED VOLUMES: Check if there was an Advanced Volumes bar
int IsAdvancedVolumesBar(string symbol, int timeframe, int s)
{
   const int History = 500;
   int nMaPeriod;
   
   if (timeframe <= PERIOD_H4) 
      nMaPeriod = 50;
   else
      nMaPeriod = 20;
   
   // Low Volume
   if (iCustom(symbol, timeframe, "AT-AdvancedVolumes", DEF_KEY, false, 0, History, nMaPeriod, false, "-", false, false, false, false,
       false, false, false, "-", true, 0, s) != EMPTY_VALUE)
      return VOLUME_LOW;
      
   // High Volume
   if (iCustom(symbol, timeframe, "AT-AdvancedVolumes", DEF_KEY, false, 0, History, nMaPeriod, false, "-", false, false, false, false,
       false, false, false, "-", true, 1, s) != EMPTY_VALUE)
      return VOLUME_HIGH;
      
   // Churn
   if (iCustom(symbol, timeframe, "AT-AdvancedVolumes", DEF_KEY, false, 0, History, nMaPeriod, false, "-", false, false, false, false,
       false, false, false, "-", true, 2, s) != EMPTY_VALUE)
      return VOLUME_CHURN;
      
   // Weak test
   if (iCustom(symbol, timeframe, "AT-AdvancedVolumes", DEF_KEY, false, 0, History, nMaPeriod, false, "-", false, false, false, false,
       false, false, false, "-", true, 3, s) != EMPTY_VALUE)
      return VOLUME_WEAKTEST;
      
   // Strong test
   if (iCustom(symbol, timeframe, "AT-AdvancedVolumes", DEF_KEY, false, 0, History, nMaPeriod, false, "-", false, false, false, false,
       false, false, false, "-", true, 4, s) != EMPTY_VALUE)
      return VOLUME_STRONGTEST;
      
   // Thrust bar
   if (iCustom(symbol, timeframe, "AT-AdvancedVolumes", DEF_KEY, false, 0, History, nMaPeriod, false, "-", false, false, false, false,
       false, false, false, "-", true, 5, s) != EMPTY_VALUE)
      return VOLUME_THRUST;
      
   // None
   return VOLUME_NONE;
}
         
//--- ALERT SYSTEM: Check if there was an Alert System signal, and fill TP, SL, BE and Execution Price in referenced variables
int IsAlertSystem(string symbol, int timeframe, int s, double &dTp, double &dSl, double &dBe, double &dStopOrder, double &alertType)
{
	dTp = iCustom(symbol, timeframe, "AT-AlertSystem", DEF_KEY, "-", false, 0, true, true, false, true, false, false, true, 0, 11, "Arial", clrBlue, clrRed, 
	      false, "-", true, "-", true, true, true, 15, "-", true, true, false, true, true, true, true, "-", true, true, "-", "-", clrRed, clrForestGreen, 
	      "-", true, 3, s);
	dSl = iCustom(symbol, timeframe, "AT-AlertSystem", DEF_KEY, "-", false, 0, true, true, false, true, false, false, true, 0, 11, "Arial", clrBlue, clrRed, 
	      false, "-", true, "-", true, true, true, 15, "-", true, true, false, true, true, true, true, "-", true, true, "-", "-", clrRed, clrForestGreen, 
	      "-", true, 4, s);
   dBe = iCustom(symbol, timeframe, "AT-AlertSystem", DEF_KEY, "-", false, 0, true, true, false, true, false, false, true, 0, 11, "Arial", clrBlue, clrRed, 
	      false, "-", true, "-", true, true, true, 15, "-", true, true, false, true, true, true, true, "-", true, true, "-", "-", clrRed, clrForestGreen, 
	      "-", true, 5, s);
   dStopOrder = iCustom(symbol, timeframe, "AT-AlertSystem", DEF_KEY, "-", false, 0, true, true, false, true, false, false, true, 0, 11, "Arial", clrBlue, clrRed, 
	      false, "-", true, "-", true, true, true, 15, "-", true, true, false, true, true, true, true, "-", true, true, "-", "-", clrRed, clrForestGreen, 
	      "-", true, 6, s);
   alertType = iCustom(symbol, timeframe, "AT-AlertSystem", DEF_KEY, "-", false, 0, true, true, false, true, false, false, true, 0, 11, "Arial", clrBlue, clrRed, 
	      false, "-", true, "-", true, true, true, 15, "-", true, true, false, true, true, true, true, "-", true, true, "-", "-", clrRed, clrForestGreen, 
	      "-", true, 7, s);
	
	if (dTp != EMPTY_VALUE)
	{
	    dTp = NormalizeDouble(dTp, Digits());
	    dSl = NormalizeDouble(dSl, Digits());
	    dBe = NormalizeDouble(dBe, Digits());
	    dStopOrder = NormalizeDouble(dStopOrder, Digits());
	    
   	 if (dTp > dSl)
   	 {
   		return TRADE_LONG;
   	 }
   	 else
   	 {
   		return TRADE_SHORT;
   	 }
   }
	 
	return TRADE_NONE;
}

//--- REVERSALS: Check if there was a Reversal arrow
int IsReversalArrow(string symbol, int timeframe, int s)
{
   const int sensitivity = 7;
   
   if (iCustom(symbol, timeframe, "AT-Reversals", DEF_KEY, "-", false, false, false, "-", false, sensitivity, "-", 
       false, 0, 12, clrBlue, "-", false, true, 0, s) != EMPTY_VALUE)
      return REVERSAL_UP;
      
   if (iCustom(symbol, timeframe, "AT-Reversals", DEF_KEY, "-", false, false, false, "-", false, sensitivity, "-", 
       false, 0, 12, clrBlue, "-", false, true, 1, s) != EMPTY_VALUE)
      return REVERSAL_DOWN;
   
   return REVERSAL_NONE;
}

//--- CONGESTIONS: Check if there was a Congestion bar
int IsCongestionBar(string symbol, int timeframe, int s)
{
   if (iCustom(symbol, timeframe, "AT-Congestions", DEF_KEY, false, 0, true, "-", 1000, 0, true, 3, false, true, 0, 0.5,
       100, 0, 1.5, 1.3, 70, "-", false, false, false, false, false, false, "-", clrCornflowerBlue, clrDarkGray, clrPeru, 
       C'223,172,38', "-", true, 0, s) != EMPTY_VALUE)
      return CONGESTION_STRONG;
      
   if (iCustom(symbol, timeframe, "AT-Congestions", DEF_KEY, false, 0, true, "-", 1000, 0, true, 3, false, true, 0, 0.5,
       100, 0, 1.5, 1.3, 70, "-", false, false, false, false, false, false, "-", clrCornflowerBlue, clrDarkGray, clrPeru, 
       C'223,172,38', "-", true, 1, s) != EMPTY_VALUE)
      return CONGESTION_WEAK;
      
   return CONGESTION_NONE;
}