//
//  "00-fxVolume_v102" -- show Volume[] of JPY/USD/EUR/GBP/CHF/AUD/NZD/CAD)
//
//    Ver. 1.00  2008/10/17(Fri)  initial version
//    Ver. 1.01  2008/12/02(Tue)  added wMin
//    Ver. 1.02  2010/05/29(Sat)  sSymPrefix, sSymPostfix
// 
//
#property copyright  "00mql4@gmail.com"
#property link       "http://00mql4.blogspot.com/"

//---- indicator settings
#property  indicator_separate_window

#property  indicator_buffers  0

#property indicator_maximum  10.1
#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 int    wMin            = 0;
extern bool   bColorize       = false;          // colorize
extern int    fontSize        = 12;             // font size for fx
extern string fontName        = "Arial";        // font name for fx
extern int    serverFontSize  = 10;             // font size for server
extern string serverFontName  = "Arial Black";  // font name for server
extern string sSymPrefix      = "";             // symbol prefix, "xx" for "xxUSDJPY"
extern string sSymPostfix     = "";             // symbol postfix, "yy" for "USDJPYyy"

//---- indicator buffers

//---- vars
string sIndicatorName  = "00-fxVolume_v102";
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 };
string g_sPair[N_FX][N_FX];

//----------------------------------------------------------------------
void init()
{
    sPrefix = sIndicatorName;
    
    IndicatorShortName(sIndicatorName);
    
    nAve = MathMax(nAve, 1);
    
    if (sSymPrefix == "" && sSymPostfix == "") {
	// for 121sec
	if (StringFind(AccountServer(), "121") >= 0) {
	    sSymPostfix = ".";
	}
    }
    for (int y = 0; y < N_FX; y++) {
	for (int x = 0; x < N_FX; x++) {
	    g_sPair[y][x] = sSymPrefix + g_sFx[y] + g_sFx[x] + sSymPostfix;
	}
    }
}

//----------------------------------------------------------------------
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);
}

//----------------------------------------------------------------------
datetime getTime(int x)
{
    datetime t;
    
    if (x >= 0) {
	t = Time[x];
    } else {
	t = Time[0] - Period() * 60 * x;
    }
    
    return(t);
}

//----------------------------------------------------------------------
void objLine(string sName, int win, datetime ts, double ps, datetime te, double pe, color col,
	     int width = 1, int style = STYLE_SOLID, bool bBack = false, bool bRay = false)
{
    ObjectCreate(sName, OBJ_TREND, win, 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);
    ObjectSet(sName, OBJPROP_WIDTH,  width);
    ObjectSet(sName, OBJPROP_STYLE,  style);
    ObjectSet(sName, OBJPROP_BACK,   bBack);
    ObjectSet(sName, OBJPROP_RAY,    bRay);
}	    

//----------------------------------------------------------------------
void objText(string sName, int win, int t, int p, string text, color col, int fontSize = 10, string fontName = "Arial")
{
    sName = sPrefix + sName;
    
    ObjectCreate(sName, OBJ_TEXT, win, 0, 0);
    ObjectSetText(sName, text, fontSize, fontName, col);
    ObjectSet(sName, OBJPROP_TIME1, t);
    ObjectSet(sName, OBJPROP_PRICE1, p);
}

//----------------------------------------------------------------------
void start()
{
    g_window = WindowFind(sIndicatorName);
    if (g_window < 0) {
	g_window = 1;
    }
    
    int w = MathMax(WindowBarsPerChart() / 2 / N_FX, 1);
    if (wMin > 0) {
	w = MathMax(w, wMin);
    }
    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_sPair[y][x];
	    double vol = 0;
	    double tmp = 0;
	    for (int i = 0; i < nAve; i++) {
		vol += iVolume(sym, 0, i + 1);
		tmp += iClose(sym, 0, i + 1);  // to access history data
	    }
	    if (!bUseMinorPair && (x >= 5 || y >= 5)) {
		vol = 0;
	    }
	    volume[y][x] = vol;
	    if (vol > maxVol) {
		maxVol = vol;
	    }
	}
    }
    
    int nFxValid = 0;
    int nFxTotal = 0;
    color col;
    for (y = 0; y < N_FX; y++) {
	for (x = 0; x < N_FX; x++) {
	    datetime ts = getTime(xs - w * x);
	    datetime te = getTime(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 (x == y || (vol0 <= 0 && vol1 > 0)) {
		col = 0;
	    } else if (vol0 <= 0) {
		col = 0x201008;
	    } else {
		if (vol0 > 0 && vol1 <= 0) {
		    nFxValid++;
		}
		if (bColorize) {
		    col = getColor(vol0 / maxVol);
		} else {
		    col = colScale(White, vol0 / maxVol);
		}
	    }
	    if (x != y && (bUseMinorPair || (x < 5 && y < 5))) {
		nFxTotal++;
	    }
	    
	    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, getTime(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, getTime(xs + w / 2));
		ObjectSet(sTextNameY, OBJPROP_PRICE1, N_FX - x);
	    }
	}
    }
    nFxTotal /= 2;
    
    objLine(sPrefix + "x", g_window, getTime(xs -  N_FX * w) , 0, getTime(xs), N_FX, Gray, 1);
    objText(sPrefix + "n", g_window, getTime(xs + w / 2), N_FX + 1, nFxValid + "/" + nFxTotal, DarkOrange, fontSize + 2);
    objText(sPrefix + "s", g_window, getTime(xs - w * 2), N_FX + 2, AccountServer(), White, serverFontSize, serverFontName);
    
    WindowRedraw();
}
