//+------------------------------------------------------------------+
//|                                         BuFu_TrendsAndSignal.mq4 |
//|                                                         Mark1213 |
//+------------------------------------------------------------------+

//concept derived from BuFu_Trend_Signals.v1.2

#property copyright "Mark1213"
#property link      ""

#property indicator_separate_window
#property indicator_minimum -1
#property indicator_maximum 1

#property indicator_buffers 4
#property indicator_color1 Green
#property indicator_color2 Red
#property indicator_color3 Yellow
#property indicator_color4 White

double UpTrendBuffer[];
double DownTrendBuffer[];
double NoTrendBuffer[];
double SignalBuffer[];

extern int cci_trend_cci_period = 236;
extern int cci_entry_cci_period = 61;
extern int cci_trend_period = 2;

extern int has_ma_method = 1;
extern int has_ma_period = 40;
extern int has_ma_method2 = 1;
extern int has_ma_period2 = 1;

int cci_line_size_1 = 2;
int cci_line_size_2 = 3;
int cci_line_size_3 = 2;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
    SetIndexStyle(0,DRAW_HISTOGRAM, 0, 2);
    SetIndexBuffer(0,UpTrendBuffer);
    SetIndexEmptyValue(0,0.0);
    SetIndexLabel(0,"UpTrend");
    
    SetIndexStyle(1,DRAW_HISTOGRAM, 0, 2);
    SetIndexBuffer(1,DownTrendBuffer);
    SetIndexEmptyValue(1,0.0);
    SetIndexLabel(1,"DownTrend");
    
    SetIndexStyle(2,DRAW_HISTOGRAM, 0, 2);
    SetIndexBuffer(2,NoTrendBuffer);
    SetIndexEmptyValue(2,0.0);
    SetIndexLabel(2,"NoTrend");
    
    SetIndexStyle(3,DRAW_LINE, 0, 2);
    SetIndexBuffer(3,SignalBuffer);
    SetIndexLabel(3,"Signal");    

    return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
    int counted_bars=IndicatorCounted();
    
    int bar_index = 0;
    
    if(counted_bars < 0) return(-1);
    if(counted_bars > 0) counted_bars--;

    int limit = Bars - counted_bars;
    
    string cci_name="DoublecciWoody_v2";
    int trend_up_cci_index = 0;
    int trend_down_cci_index = 1;
    int entry_cci_index = 5;
    int trend_neutral_cci_index= 2;
    
    string has_name="Heiken_Ashi_Smoothed_v2";
    int has_open_avg_index = 2;
    int has_close_avg_index = 3;
    
    for(bar_index = limit; bar_index >= 0; bar_index--)
    {
        double trend_up_cci_v = iCustom(Symbol(), 0, cci_name,
                cci_trend_cci_period, cci_entry_cci_period, cci_trend_period,
                cci_line_size_1, cci_line_size_2, cci_line_size_3,
                trend_up_cci_index, bar_index
                );
    
        double trend_down_cci_v = iCustom(Symbol(), 0, cci_name,
                cci_trend_cci_period, cci_entry_cci_period, cci_trend_period,
                cci_line_size_1, cci_line_size_2, cci_line_size_3,
                trend_down_cci_index, bar_index
                );
    
        double trend_neutral_cci_v = iCustom(Symbol(), 0, cci_name,
                cci_trend_cci_period, cci_entry_cci_period, cci_trend_period,
                cci_line_size_1, cci_line_size_2, cci_line_size_3,
                trend_neutral_cci_index, bar_index
                );    
        
        double entry_cci_v = iCustom(Symbol(), 0, cci_name,
                cci_trend_cci_period, cci_entry_cci_period, cci_trend_period,
                cci_line_size_1, cci_line_size_2, cci_line_size_3,
                entry_cci_index, bar_index
                );
    
        double has_close_avg_v = iCustom(Symbol(), 0, has_name,
                has_ma_method, has_ma_period, has_ma_method2, has_ma_period2,
                has_close_avg_index, bar_index
                );
    
        double has_open_avg_v = iCustom(Symbol(), 0, has_name,
                has_ma_method, has_ma_period, has_ma_method2, has_ma_period2,
                has_open_avg_index, bar_index
                );    
    
        bool has_is_up = false;
        if(has_open_avg_v < has_close_avg_v) { has_is_up = true; }
        
        bool has_is_down = false;
        if(has_open_avg_v > has_close_avg_v) { has_is_down = true; }
    
        bool cci_trending = true;
        if(trend_neutral_cci_v != 0.0) { cci_trending = false; }
    
        if(cci_trending && trend_up_cci_v > 0.0 && entry_cci_v > 0.0 && has_is_up)
        {//up trend
            UpTrendBuffer[bar_index] = 1.0;
            DownTrendBuffer[bar_index] = 0.0;
            NoTrendBuffer[bar_index] = 0.0;
        }
        else if(cci_trending && trend_down_cci_v < 0.0 && entry_cci_v < 0.0 && has_is_down)
        {//down trend
            UpTrendBuffer[bar_index] = 0.0;
            DownTrendBuffer[bar_index] = 1.0;
            NoTrendBuffer[bar_index] = 0.0;
        }
        else
        {//no trend
            UpTrendBuffer[bar_index] = 0.0;
            DownTrendBuffer[bar_index] = 0.0;
            NoTrendBuffer[bar_index] = 1.0;
        }
        
        double has_close_avg_v1 = iCustom(Symbol(), 0, has_name,
                has_ma_method, has_ma_period, has_ma_method2, has_ma_period2,
                has_close_avg_index, bar_index+1
                );
    
        double has_open_avg_v1 = iCustom(Symbol(), 0, has_name,
                has_ma_method, has_ma_period, has_ma_method2, has_ma_period2,
                has_open_avg_index, bar_index+1
                );            
        
        bool has1_is_up = false;
        if(has_open_avg_v1 < has_close_avg_v1) { has1_is_up = true; }
        
        bool has1_is_down = false;
        if(has_open_avg_v1 > has_close_avg_v1) { has1_is_down = true; }
        
        if(has_is_up && has1_is_down && cci_trending && trend_up_cci_v > 0.0 && entry_cci_v > 0.0 )
        {//buy signal
            SignalBuffer[bar_index] = 1.0;
        }
        else if(has_is_down && has1_is_up && cci_trending && trend_down_cci_v < 0.0 && entry_cci_v < 0.0)
        {//sell signal
            SignalBuffer[bar_index] = -1.0;
        }
        else
        {//no signal
            SignalBuffer[bar_index] = 0.0;
        }
    }
    return(0);
}
//+------------------------------------------------------------------+