//
//  "00-fxVolume_v100" -- show Volume[] of JPY/USD/EUR/GBP/CHF/AUD/NZD/CAD)
//
//    Ver. 1.00  2008/10/17(Fri)  initial version
// 
#property  copyright "00"
#property  link      "http://www.mql4.com/"

//---- indicator settings
#property  indicator_separate_window

#property  indicator_buffers  0

#property indicator_maximum  9.5
#property indicator_minimum  -0.5

#property  indicator_color1  DarkGray
#property  indicator_color2  DarkGray

#property  indicator_width1  1
#property  indicator_width2  1

#property  indicator_style1  STYLE_DOT
#property  indicator_style2  STYLE_DOT

//---- defines
#define N_FX  8

//---- indicator parameters
extern bool   bUseMinorPair  = false;    // use not only JPY/USD/EUR/GBP/CHF but also AUD/NZD/CAD
extern int    nAve           = 1;        // ave period
extern bool   bColorize      = false;    // colorize
extern int    fontSize       = 12;       // font size
extern string fontName       = "Arial";  // font name

//---- indicator buffers

//---- vars
string sIndicatorName  = "00-fxVolume_v100";
string sPrefix;
int    g_window;
string g_sFx[] = { "JPY", "USD", "EUR", "GBP", "CHF", "AUD", "NZD", "CAD" };
color  g_color[] = { Red, White, Aqua, Yellow, Magenta, Lime, Green, DodgerBlue };

//----------------------------------------------------------------------
void init()
{
    sPrefix = sIndicatorName;
    
    IndicatorShortName(sIndicatorName);
    
    nAve = MathMax(nAve, 1);
}

//----------------------------------------------------------------------
void deinit()
{
    int n = ObjectsTotal();
    for (int i = n - 1; i >= 0; i--) {
	string sName = ObjectName(i);
	if (StringFind(sName, sPrefix) == 0) {
	    ObjectDelete(sName);
	}
    }
}

//----------------------------------------------------------------------
void objRect(string sName, datetime ts, double ps, datetime te, double pe, color col)
{
    sName = sPrefix + sName;
    
    ObjectCreate(sName, OBJ_RECTANGLE, g_window, 0, 0);
    ObjectSet(sName, OBJPROP_TIME1, ts);
    ObjectSet(sName, OBJPROP_PRICE1, ps);
    ObjectSet(sName, OBJPROP_TIME2, te);
    ObjectSet(sName, OBJPROP_PRICE2, pe);
    ObjectSet(sName, OBJPROP_COLOR, col);
}

//----------------------------------------------------------------------
double MathClip(double v, double min, double max)
{
    return(MathMax(MathMin(v, max), min));
}

//----------------------------------------------------------------------
color colScale(color col, double scale)
{
    int r = MathClip(MathRound(((col >> 0)  & 0xff) * scale), 0, 255);
    int g = MathClip(MathRound(((col >> 8)  & 0xff) * scale), 0, 255);
    int b = MathClip(MathRound(((col >> 16) & 0xff) * scale), 0, 255);
    
    return((b << 16) | (g << 8) | r);
}

//----------------------------------------------------------------------
int clip255(double c)
{
    return(MathClip(MathRound(c), 0, 255));
}

//----------------------------------------------------------------------
color rgbToColor(double r, double g, double b)
{
    return((clip255(b) << 16) | (clip255(g) << 8) | clip255(r));
}

//----------------------------------------------------------------------
color getColor(double vol)
{
    int r, g, b;
    double c;
    
    if (vol <= 0.25) {
	c = vol / 0.25;
	r = 239 * c + 16;
	g = 64 * c + 4;
	b = 0;
    } else if (vol <= 0.5) {
	c = (vol - 0.25) / 0.25;
	r = 255 - 255 * c;
	g = 64;
	b = 255 * c;
    } else if (vol <= 0.75) {
	c = (vol - 0.50) / 0.25;
	r = 0;
	g = 64 + (255 - 64) * c;
	b = 255;
    } else {
	c = (vol - 0.75) / 0.25;
	r = 255 * c;
	g = 255;
	b = 255;
    }
    
    color col = rgbToColor(r, g, b);
    col = colScale(col, 0.25 + vol * 0.75);
    
    return(col);
}

//----------------------------------------------------------------------
void start()
{
    g_window = WindowFind(sIndicatorName);
    if (g_window < 0) {
	g_window = 1;
    }
    
    int w = MathMax(WindowBarsPerChart() / 2 / N_FX, 1);
    int xs = WindowFirstVisibleBar() - w * 2;
    
    double maxVol = 0;
    double volume[N_FX][N_FX];
    for (int y = 0; y < N_FX; y++) {
	for (int x = 0; x < N_FX; x++) {
	    if (x == y) {
		continue;
	    }
	    string sym = g_sFx[y] + g_sFx[x];
	    double vol = 0;
	    for (int i = 0; i < nAve; i++) {
		vol += iVolume(sym, 0, i + 1);
	    }
	    if (!bUseMinorPair && (x >= 5 || y >= 5)) {
		vol = 0;
	    }
	    volume[y][x] = vol;
	    if (vol > maxVol) {
		maxVol = vol;
	    }
	}
    }
    
    color col;
    for (y = 0; y < N_FX; y++) {
	for (x = 0; x < N_FX; x++) {
	    datetime ts = Time[xs - w * x];
	    datetime te = Time[xs - w * (x + 1)];
	    double ps = N_FX - y;
	    double pe = N_FX - y - 1;
	    double vol0 = volume[y][x];
	    double vol1 = volume[x][y];
	    if ((y == x && (bUseMinorPair || x < 5)) || vol1 > 0) {
		col = 0x040810;
	    } else if (vol0 <= 0) {
		col = 0x201008;
	    } else {
		if (bColorize) {
		    col = getColor(vol0 / maxVol);
		} else {
		    col = colScale(White, vol0 / maxVol);
		}
	    }
	    objRect("rect" + x + " " + y, ts, ps, te, pe, col);
	    
	    if (y == 0) {
		string sTextNameX = "text x" + x;
		string sTextNameY = "text y" + x;
		ObjectCreate(sTextNameX, OBJ_TEXT, g_window, 0, 0);
		ObjectCreate(sTextNameY, OBJ_TEXT, g_window, 0, 0);
		ObjectSetText(sTextNameX, g_sFx[x], fontSize, fontName, g_color[x]);
		ObjectSet(sTextNameX, OBJPROP_TIME1, Time[xs - w / 2 - x * w]);
		ObjectSet(sTextNameX, OBJPROP_PRICE1, N_FX + 1);
		
		ObjectSetText(sTextNameY, g_sFx[x], fontSize, fontName, g_color[x]);
		ObjectSet(sTextNameY, OBJPROP_TIME1, Time[xs + w / 2]);
		ObjectSet(sTextNameY, OBJPROP_PRICE1, N_FX - x);
	    }
	}
    }
}
