#property copyright "Copyright Š 2005, David W. Thomas"
#property link      "mailto:davidwt@usa.net"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Yellow
#property indicator_color2 DeepSkyBlue
#property indicator_color3 Red

extern bool SoundAlert = true;
extern int FastMAPeriod = 12;
extern int SlowMAPeriod = 26;
extern int SignalMAPeriod = 9;
double g_ibuf_88[];
double g_ibuf_92[];
double g_ibuf_96[];
double gd_100 = 0.0;
double gd_108 = 0.0;

int init() {
   IndicatorDigits(MarketInfo(Symbol(), MODE_DIGITS) + 1.0);
   SetIndexStyle(2, DRAW_LINE, STYLE_SOLID, 2);
   SetIndexBuffer(2, g_ibuf_88);
   SetIndexDrawBegin(0, SlowMAPeriod);
   SetIndexStyle(1, DRAW_LINE, STYLE_SOLID, 2);
   SetIndexBuffer(1, g_ibuf_92);
   SetIndexDrawBegin(1, SlowMAPeriod + SignalMAPeriod);
   SetIndexStyle(0, DRAW_HISTOGRAM, STYLE_SOLID, 2);
   SetIndexBuffer(0, g_ibuf_96);
   SetIndexDrawBegin(2, SlowMAPeriod + SignalMAPeriod);
   IndicatorShortName("MACD(" + FastMAPeriod + "," + SlowMAPeriod + "," + SignalMAPeriod + ")");
   SetIndexLabel(0, "MACD");
   SetIndexLabel(1, "Signal");
   gd_100 = 2.0 / (SignalMAPeriod + 1.0);
   gd_108 = 1.0 - gd_100;
   return (0);
}

int deinit() {
   return (0);
}

int start() {
   int li_4 = IndicatorCounted();
   if (li_4 < 0) return (-1);
   if (li_4 > 0) li_4--;
   int li_0 = Bars - li_4;
   for (int li_8 = li_0; li_8 >= 0; li_8--) {
      g_ibuf_88[li_8] = iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE, li_8) - iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE, li_8);
      g_ibuf_92[li_8] = gd_100 * g_ibuf_88[li_8] + gd_108 * (g_ibuf_92[li_8 + 1]);
      g_ibuf_96[li_8] = 2.0 * (g_ibuf_88[li_8] - g_ibuf_92[li_8]);
   }
   
   if (SoundAlert) runAlerts();
   
   return (0);
}

void runAlerts() {
   static int AlertPrevTime = 0;
   if (Time[0] <= AlertPrevTime) {
      return;
   }
   
   string msg = Symbol() + " MACD lines have crossed";
   if ((g_ibuf_92[1] <= g_ibuf_88[1] && g_ibuf_92[0] > g_ibuf_88[0])
      || (g_ibuf_92[1] >= g_ibuf_88[1] && g_ibuf_92[0] < g_ibuf_88[0])) {
      AlertPrevTime = Time[0];
      Alert(msg);
   }

   return;

}
