//+------------------------------------------------------------------+
//| message |
//+------------------------------------------------------------------+
string SignalMessage(int signalType, datetime barTime)
{
string side = «BUY»;
if(signalType < 0) side = «SELL»;
return(«ADX/Stoch » + side +
" | " + Symbol() +
" | TF=" + IntegerToString(Period()) +
" | bar=" + TimeToStr(barTime, TIME_DATE|TIME_MINUTES));
}
//+------------------------------------------------------------------+
//| evaluate main signal on closed bar |
//| returns: 1=buy, -1=sell, 0=none |
//+------------------------------------------------------------------+
int EvaluateMainSignal(int barIndex)
{
if(barIndex < 1) return(0);
if(barIndex + 1 >= Bars) return(0);
if(!al) return(0);
double a = iStochastic(NULL, 0, Kperiod, Dperiod, slowing, method, price_field, MODE_MAIN, barIndex);
double b = iStochastic(NULL, 0, Kperiod, Dperiod, slowing, method, price_field, MODE_MAIN, barIndex + 1);
double po = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_PLUSDI, barIndex);
double p1 = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_PLUSDI, barIndex + 1);
double mo = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_MINUSDI, barIndex);
double m1 = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_MINUSDI, barIndex + 1);
bool buySignal = false;
bool sellSignal = false;
if(iBuy)
{
if(a > b && a < 80 && po > p1 && po > mo)
buySignal = true;
}
if(iSell)
{
if(a < b && a > 20 && mo > m1 && po < mo)
sellSignal = true;
}
if(buySignal && !sellSignal) return(1);
if(sellSignal && !buySignal) return(-1);
return(0);
}
//+------------------------------------------------------------------+
//| draw history arrows |
//+------------------------------------------------------------------+
void BuildHistoryArrows()
{
if(!DrawHistoricalArrows) return;
if(Bars < 10) return;
int maxBar = Bars — 2; // because barIndex+1 is used
if(HistoryBarsToDraw > 0 && HistoryBarsToDraw < maxBar)
maxBar = HistoryBarsToDraw;
for(int bar = maxBar; bar >= 1; bar--)
{
int sig = EvaluateMainSignal(bar);
if(sig != 0)
CreatePriceArrow(sig, bar);
}
WindowRedraw();
}
//+------------------------------------------------------------------+
//| start |
//+------------------------------------------------------------------+
int start()
{
int counted_bars = IndicatorCounted();
if(counted_bars < 0) return(-1);
if(counted_bars > 0) counted_bars--;
int limit = Bars — counted_bars;
if(counted_bars == 0) limit -= 2;
if(limit < 0) limit = 0;
//---- fill stochastic plot buffers
for(int q = limit; q >= 0; q--)
{
Stoch[q] = iStochastic(NULL, 0, Kperiod, Dperiod, slowing, method, price_field, MODE_MAIN, q);
Signal[q] = iStochastic(NULL, 0, Kperiod, Dperiod, slowing, method, price_field, MODE_SIGNAL, q);
}
//---- manual ADX calculation for subwindow buffers
int starti = limit;
int i = starti;
while(i >= 0)
{
double price_low = Low[i];
double price_high = High[i];
double pdm = price_high — High[i + 1];
double mdm = Low[i + 1] — price_low;
if(pdm < 0) pdm = 0;
if(mdm < 0) mdm = 0;
if(pdm == mdm)
{
pdm = 0;
mdm = 0;
}
else if(pdm < mdm) pdm = 0;
else if(mdm < pdm) mdm = 0;
double num1 = MathAbs(price_high — price_low);
double num2 = MathAbs(price_high — Close[i + 1]);
double num3 = MathAbs(price_low — Close[i + 1]);
double tr = MathMax(num1, num2);
tr = MathMax(tr, num3);
if(tr == 0.0)
{
PlusSdiBuffer[i] = 0.0;
MinusSdiBuffer[i] = 0.0;
}
else
{
PlusSdiBuffer[i] = 100.0 * pdm / tr;
MinusSdiBuffer[i] = 100.0 * mdm / tr;
}
i--;
}
for(i = 0; i <= limit; i++)
PlusDiBuffer[i] = iMAOnArray(PlusSdiBuffer, Bars, ADXPeriod, 0, MODE_EMA, i);
for(i = 0; i <= limit; i++)
MinusDiBuffer[i] = iMAOnArray(MinusSdiBuffer, Bars, ADXPeriod, 0, MODE_EMA, i);
i = starti;
while(i >= 0)
{
double div = MathAbs(PlusDiBuffer[i] + MinusDiBuffer[i]);
if(div == 0.0) TempBuffer[i] = 0.0;
else TempBuffer[i] = 100.0 * (MathAbs(PlusDiBuffer[i] — MinusDiBuffer[i]) / div);
i--;
}
for(i = 0; i < limit; i++)
ADXBuffer[i] = iMAOnArray(TempBuffer, Bars, ADXPeriod, 0, MODE_EMA, i);
//---- one-time rebuild of history on load / TF change
if(!g_historyBuilt)
{
BuildHistoryArrows();
g_historyBuilt = true;
}
//---- live signal only on new bar (closed candle signal = bar 1)
if(!IsNewBar())
return(0);
int sig = EvaluateMainSignal(1);
if(sig != 0)
{
datetime signalBarTime = Time[1];
if(!(g_lastAlertBarTime == signalBarTime && g_lastAlertType == sig))
{
CreatePriceArrow(sig, 1);
SendAllNotifications(SignalMessage(sig, signalBarTime));
g_lastAlertBarTime = signalBarTime;
g_lastAlertType = sig;
}
}
return(0);
}
//+------------------------------------------------------------------+



MihaMM