#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 White
#property indicator_minimum - 100.0
#property indicator_maximum 100.0
#property indicator_level1 - 20.0
#property indicator_level2 20.0

#define NTFS 5
#define NSYMS 8
#define MAXPAIRS 64 // NSYMS^2

extern string note_0 = "AUD, CAD, CHF, EUR, GBP, JPY, NZD, USD";
extern int timeframe_1 = PERIOD_M15;
extern int timeframe_2 = PERIOD_M30;
extern int timeframe_3 = PERIOD_H1;
extern int timeframe_4 = PERIOD_H4;
extern int timeframe_5 = PERIOD_D1;
extern string note_1 = "1-RSI; 2-WPR; 3-Stoch; 4-BB%B";
extern int algo = 2;
extern string prefix = "2nb_";

double buf[];
int nPairs, tfs[NTFS], periods[NTFS];
string sym1, sym2, symsuf, sLabel, indName, pairs[MAXPAIRS];

string syms[NSYMS] = {"AUD", "CAD", "CHF", "EUR", "GBP", "JPY", "NZD", "USD"};

int init () {
  string s;

  Comment ("");
  sym1 = StringSubstr (Symbol (), 0, 3);
  sym2 = StringSubstr (Symbol (), 3, 3);
  symsuf = StringSubstr(Symbol (), 6, 0);
  sLabel = prefix + "PowerbarsFX_Spread" + "label_" + sym1 + sym2;
  indName = prefix + sym1 + sym2 + " MTF Spread";
  IndicatorBuffers (1);
  SetIndexStyle (0, DRAW_NONE);
  SetIndexBuffer (0, buf);
  IndicatorShortName (indName);
  IndicatorDigits (2);
  nPairs = 0;

  for (int i = 0; i < NSYMS; i ++) {
    for (int i2 = 0; i2 < NSYMS; i2 ++) {
      if (i != i2) {
        s = syms[i] + syms[i2] + symsuf;

        if (MarketInfo (s, MODE_TRADEALLOWED) > 0) {
          pairs[nPairs] = s;
          nPairs ++;
        }
      }
    }
  }

  tfs[0] = timeframe_1;
  tfs[1] = timeframe_2;
  tfs[2] = timeframe_3;
  tfs[3] = timeframe_4;
  tfs[4] = timeframe_5;

  for (i = 0; i < NTFS; i ++) {
    if (tfs[i] == 0) {
      tfs[i] = Period ();
    }

    switch (tfs[i]) {
      case PERIOD_M1:
        periods[i] = 30;
        break;
      case PERIOD_M5:
        periods[i] = 24;
        break;
      case PERIOD_M15:
        periods[i] = 24;
        break;
      case PERIOD_M30:
        periods[i] = 24;
        break;
      case PERIOD_H1:
        periods[i] = 24;
        break;
      case PERIOD_H4:
        periods[i] = 30;
        break;
      case PERIOD_D1:
        periods[i] = 20;
        break;
      case PERIOD_W1:
        periods[i] = 27;
        break;
      case PERIOD_MN1:
        periods[i] = 24;
    }
  }

  return (0);
}

int deinit () {
  return (0);
}

int start () {
  int c = IndicatorCounted ();
  int n, p, t, tf, ti, win;
  double v;
  string s;
  color clr;

  if (c < 0) {
    return (- 1);
  }

  win = WindowFind (indName);

  for (int i = (Bars - MathMax (c - 1, 0)) - 1; i >= 0; i --) {
    v = 0;
    ti = Time[i];

    for (int i2 = 0; i2 < NTFS; i2 ++) {
      tf = tfs[i2];
      p = periods[i2];
      t = iBarShift (Symbol (), tf, ti);
      v += strength (sym1, p, tf, t) - strength (sym2, p, tf, t);
    }

    v /= 5.0;
    buf[i] = v;
Comment (v);

    if (v < 0.0) {
      clr = getClr (255, 0, 0, 255, 255, 255, 0, 100, MathAbs (v));
    } else
    if (v > 0.0) {
      clr = getClr (0, 255, 0, 255, 255, 255, 0, 100, MathAbs (v));
    }

    if (i == 0) {
      ObjectDelete (sLabel);
      ObjectCreate (sLabel, OBJ_TEXT, win, TimeCurrent (), 0);
      ObjectSetText (sLabel, "                                 " + sym1 + sym2
      + ": " + DoubleToStr (v, 2), 10, "Segoe UI", clr);
    }

    s = prefix + "PowerbarsFX_Spread" + sym1 + sym2 + ti;
    ObjectDelete (s);
    ObjectCreate (s, OBJ_RECTANGLE, win, ti - Period (), v, ti, 0);
    ObjectSet (s, OBJPROP_BACK, TRUE);
    ObjectSet (s, OBJPROP_COLOR, clr);

    if (i == 0) {
      ObjectsRedraw ();
    }
  }

  return (0);
}

double bb (string sym, int tf, int per, double dev, int shift) {
   double l = iBands (sym, tf, per, dev, 0, PRICE_CLOSE, MODE_LOWER, shift);
   return (100.0 * (iClose (sym, tf, shift) - l)
   / (iBands (sym, tf, per, dev, 0, PRICE_CLOSE, MODE_UPPER, shift) - l));
}

double strength (string sym, int per, int tf, int shift) {
  double d = 0;
  int n = 0;
  double v;
  bool f;

  for (int i = 0; i < nPairs; i ++) {
    if (StringSubstr (pairs[i], 0, 3) == sym) {
      f = FALSE;
    } else
    if (StringSubstr (pairs[i], 3, 3) == sym) {
      f = TRUE;
    } else {
      continue;
    }

    switch (algo) {
      case 1:
        v = iRSI (pairs[i], tf, per, PRICE_CLOSE, shift);
        break;
      case 2:
        v = iWPR (pairs[i], tf, per, shift) + 100.0;
        break;
      case 3:
        v = iStochastic (pairs[i], tf, per, 3, 3, MODE_SMA, 0, MODE_MAIN, shift);
        break;
      case 4:
        v = bb (pairs[i], tf, per, 2, shift);
        break;
      default:
        v = 0;
    }

    if (f) {
      v = 100 - v;
    }

    d += v;
    n ++;
  }

  if (n < 1) {
    return (0.0);
  }

  return (d / n);
}

int rgb2color (int r, int g, int b) {
  return (MathMin (255, MathAbs (r))
  + 256.0 * MathMin (255, MathAbs (g))
  + 65536.0 * MathMin (255, MathAbs (b)));
}

int getClr (int r, int g, int b, int r2, int g2, int b2, double min, double max,
  double val) {
  double d = (max - val) / (max - min - 1);
  return (rgb2color (r - (r - r2) * d, g - (g - g2) * d, b - (b - b2) * d));
}