//
// "00-PerfectOrder_v101.mq4" -- dir of 5SMA/14SMA/23SMA/50SMA/75SMA/100SMA/200SMA
//
//    Ver. 1.00  2008/10/12(Sun)   initial version
//    Ver. 1.01  2008/10/17(Fri)   EMA fibo step, use Open[] instead of Close[]
// 
#property  copyright "00 - 00mql4@gmail.com"
#property  link      "http://www.mql4.com/"

//---- indicator settings
#property  indicator_chart_window

#property  indicator_buffers  4

#property  indicator_color1  DodgerBlue
#property  indicator_color2  Crimson
#property  indicator_color3  Blue
#property  indicator_color4  Red

#property  indicator_width1  1
#property  indicator_width2  1
#property  indicator_width3  1
#property  indicator_width4  1

#property  indicator_style1  STYLE_SOLID
#property  indicator_style2  STYLE_SOLID
#property  indicator_style3  STYLE_SOLID
#property  indicator_style4  STYLE_SOLID

//---- defines
#define N_AVE  8

//---- indicator parameters
extern bool bPerfect      = false;
extern int  nAve0         = 21;
extern int  nAve1         = 34;
extern int  nAve2         = 55;
extern int  nAve3         = 89;
extern int  nAve4         = 144;
extern int  nAve5         = 233;
extern int  nAve6         = 377;
extern int  nAve7         = 610;
extern int  maMethod      = MODE_EMA;
extern int  appliedPrice  = PRICE_OPEN;

//---- indicator buffers
double BufferLongSignal[];   // 0: long signal, up arrow
double BufferShortSignal[];  // 1: short signal, down arrow
double BufferLongLevel[];    // 2: long level
double BufferShortLevel[];   // 3: short level

//---- vars
string  sIndicatorName  = "00-PerfectOrder_v101";
int     g_nAve[N_AVE];
int     markLong     = 233;
int     markShort    = 234;
double  c0 = 2.2;
double  c1 = 2.0;
double  c2 = 1.8;
double  c3 = 1.6;
double  c4 = 1.4;
double  c5 = 1.2;
double  c6 = 1.0;
double  cTotal;

//----------------------------------------------------------------------
void init()
{
    IndicatorShortName(sIndicatorName);
    
    SetIndexBuffer(0, BufferLongSignal);
    SetIndexBuffer(1, BufferShortSignal);
    SetIndexBuffer(2, BufferLongLevel);
    SetIndexBuffer(3, BufferShortLevel);
    
    SetIndexLabel(0, "Long signal");
    SetIndexLabel(1, "Short signal");
    SetIndexLabel(2, "Long level");
    SetIndexLabel(3, "Short level");
    
    SetIndexStyle(0, DRAW_ARROW);
    SetIndexStyle(1, DRAW_ARROW);
    SetIndexStyle(2, DRAW_LINE);
    SetIndexStyle(3, DRAW_LINE);
    
    SetIndexArrow(0, markLong);
    SetIndexArrow(1, markShort);
    
    g_nAve[0] = nAve0;
    g_nAve[1] = nAve1;
    g_nAve[2] = nAve2;
    g_nAve[3] = nAve3;
    g_nAve[4] = nAve4;
    g_nAve[5] = nAve5;
    g_nAve[6] = nAve6;
    g_nAve[7] = nAve7;
    
    SetIndexDrawBegin(0, g_nAve[N_AVE - 1]);
    SetIndexDrawBegin(1, g_nAve[N_AVE - 1]);
    SetIndexDrawBegin(2, g_nAve[N_AVE - 1]);
    SetIndexDrawBegin(3, g_nAve[N_AVE - 1]);
    
    cTotal = c0 + c1 + c2 + c3 + c4 + c5 + c6;
}

//----------------------------------------------------------------------
void start()
{
    int counted_bars = IndicatorCounted();
    int limit = Bars - MathMax(counted_bars - 1, 0);
    
    double a[N_AVE];
    for (int i = limit - 1; i >= 0; i--) {
	for (int j = 0; j < N_AVE; j++) {
	    a[j] = iMA(NULL, 0, g_nAve[j], 0, maMethod, appliedPrice, i);
	}
	
	// long
	if (a[0] > a[1] && a[1] > a[2] && a[2] > a[3] && a[3] > a[4] && a[4] > a[5] && a[5] > a[6] && a[6] > a[7]) {
	    BufferLongSignal[i] = a[0];
	} else {
	    BufferLongSignal[i] = EMPTY_VALUE;
	}
	if (bPerfect) {
	    BufferLongLevel[i] = (BufferLongSignal[i] != EMPTY_VALUE);
	} else {
	    int longLevel = 0;
	    if (a[6] > a[7]) longLevel += c6;
	    if (a[5] > a[6]) longLevel += c5;
	    if (a[4] > a[5]) longLevel += c4;
	    if (a[3] > a[4]) longLevel += c3;
	    if (a[2] > a[3]) longLevel += c2;
	    if (a[1] > a[2]) longLevel += c1;
	    if (a[0] > a[1]) longLevel += c0;
	    BufferLongLevel[i] = longLevel / cTotal;
	}
	
	// short
	if (a[0] < a[1] && a[1] < a[2] && a[2] < a[3] && a[3] < a[4] && a[4] < a[5] && a[5] < a[6] && a[6] < a[7]) {
	    BufferShortSignal[i] = a[0];
	} else {
	    BufferShortSignal[i] = EMPTY_VALUE;
	}
	if (bPerfect) {
	    BufferShortLevel[i] = (BufferShortSignal[i] != EMPTY_VALUE);
	} else {
	    int shortLevel = 0;
	    if (a[6] < a[7]) shortLevel += c6;
	    if (a[5] < a[6]) shortLevel += c5;
	    if (a[4] < a[5]) shortLevel += c4;
	    if (a[3] < a[4]) shortLevel += c3;
	    if (a[2] < a[3]) shortLevel += c2;
	    if (a[1] < a[2]) shortLevel += c1;
	    if (a[0] < a[1]) shortLevel += c0;
	    BufferShortLevel[i] = shortLevel / cTotal;
	}
    }
}
