//| Color RSI.mq4 |

//| mladen |

//+------------------------------------------------------------------+

//RSI_Color_RSI_v1.01_maxsig

//add. SignalScreanMultiplier (sig.history)

#property copyright "mladen"

#property link ""


#property indicator_separate_window

#property indicator_buffers 8

#property indicator_minimum 0

#property indicator_maximum 100

#property indicator_color1 DimGray

#property indicator_color2 Green

#property indicator_color3 Red

#property indicator_color4 Yellow

#property indicator_color5 Blue

#property indicator_width2 2

#property indicator_width3 2


#property indicator_level1 70

#property indicator_level2 50

#property indicator_level3 30

#property indicator_levelcolor DarkSlateGray

#property indicator_levelstyle 2


#define SignalName    "RSISignal"




//---- input parameters

//

//

//

//


extern int    RSIPeriod = 8;

extern int    Sig_Period = 8;

extern int    PriceType = 0;

extern string timeFrame = "Current time frame";

extern int    overBought = 80;

extern int    overSold = 20;

extern bool   showArrows = true;

extern int    MaxArrowsScreensX = 1000;

extern int    UpArrow_Code = 233;

extern int    DownArrow_Code = 234;

extern int    Arrow_Size = 3;


extern bool alertsOn = true;

extern bool alertsMessage = true;

extern bool alertsSound = false;

extern bool alertsEmail = true;

extern int  repaintSignalStep = 0;

extern int  repaintSignalPrice = 0;


//---- buffers

//

//

//

//

//


double RSIBuffer[];

double Upper[];

double Lower[];

double Prices[];

double SigBuffer[];

double Upper_Sig[];

double Lower_Sig[];


//

//

//

//

//


int TimeFrame;

datetime TimeArray[];

int    maxArrows;

int    SignalGap;

string prevSignal;

int    prevBar;



//+------------------------------------------------------------------+

//| |

//+------------------------------------------------------------------+


int init()

{
    string shortName = "RSI (";

    SetIndexBuffer(0, RSIBuffer);

    SetIndexBuffer(1, Upper);

    SetIndexBuffer(2, Lower);

    SetIndexBuffer(3, Upper_Sig);

    SetIndexBuffer(4, Lower_Sig);

    SetIndexLabel(0, "RSI");

    SetIndexLabel(1, NULL);

    SetIndexLabel(2, NULL);

    SetIndexStyle(1, DRAW_LINE);

    SetIndexStyle(2, DRAW_LINE);

    SetIndexStyle(3, DRAW_LINE, STYLE_DOT);

    SetIndexStyle(4, DRAW_LINE, STYLE_DOT);

//

//

//

//

//


    TimeFrame = stringToTimeFrame(timeFrame);

    if (TimeFrame != Period())
        shortName = shortName + TimeFrameToString(TimeFrame) + ",";

    shortName = shortName + PriceTypeToString(PriceType);

    if (overBought < overSold)
        overBought = overSold;

    if (overBought < 100)
        shortName = shortName + "," + overBought;

    if (overSold > 0)
        shortName = shortName + "," + overSold;

    IndicatorShortName(shortName + ") (" + RSIPeriod + ")");

    return(0);
}


//

//

//

//

//


int deinit()

{
    DeleteArrows();

    return(0);
}


//+------------------------------------------------------------------+

//| |

//+------------------------------------------------------------------+


int start()

{
    int counted_bars = IndicatorCounted();

    int limit;

    int i, y;

    if (counted_bars < 0)
        return(-1);

    if (counted_bars > 0)
        counted_bars--;

    limit = MathMax(Bars - counted_bars, TimeFrame / Period());

    ArrayCopySeries(TimeArray, MODE_TIME, NULL, TimeFrame);

    ArrayResize(SigBuffer, Bars);

    ArraySetAsSeries(SigBuffer, true);

//

//

//

//

//

    for (i = 0, y = 0; i < limit; i++)

    {
        if (Time[i] < TimeArray[y])
            y++;

        RSIBuffer[i] = iRSI(NULL, TimeFrame, RSIPeriod, PriceType, y);
    }

    for (i = limit; i >= 0; i--)

    {
        if (RSIBuffer[i] > overBought)
        {
            Upper[i] = RSIBuffer[i]; Upper[i + 1] = RSIBuffer[i + 1];
        }

        else
        {
            Upper[i] = EMPTY_VALUE;

            if (Upper[i + 2] == EMPTY_VALUE)

                Upper[i + 1] = EMPTY_VALUE;
        }

        if (RSIBuffer[i] < overSold)
        {
            Lower[i] = RSIBuffer[i]; Lower[i + 1] = RSIBuffer[i + 1];
        }

        else
        {
            Lower[i] = EMPTY_VALUE;

            if (Lower[i + 2] == EMPTY_VALUE)

                Lower[i + 1] = EMPTY_VALUE;
        }
    }

// calc Signal Line

/* for(i=0,y=0; i<limit; i++)

   {

   if(Time[i]<TimeArray[y]) y++;

   SigBuffer[i] = iMAOnArray(RSIBuffer, 0,Sig_Period,0,MODE_SMA,y);

   }

 */

    for (i = limit; i >= 0; i--)

    {
        SigBuffer[i] = iMAOnArray(RSIBuffer, 0, Sig_Period, 0, MODE_SMA, i);

        if (SigBuffer[i] > RSIBuffer[i])
        {
            Upper_Sig[i] = SigBuffer[i]; Upper_Sig[i + 1] = SigBuffer[i + 1];
        }

        else
        {
            Upper_Sig[i] = EMPTY_VALUE;

            if (Upper_Sig[i + 2] == EMPTY_VALUE)

                Upper_Sig[i + 1] = EMPTY_VALUE;
        }

        if (SigBuffer[i] < RSIBuffer[i])
        {
            Lower_Sig[i] = SigBuffer[i]; Lower_Sig[i + 1] = SigBuffer[i + 1];
        }

        else
        {
            Lower_Sig[i] = EMPTY_VALUE;

            if (Lower_Sig[i + 2] == EMPTY_VALUE)

                Lower_Sig[i + 1] = EMPTY_VALUE;
        }
    }

//

//

//

//

//

    DeleteArrows();

    if (showArrows)

    {
        SignalGap = MathCeil(iATR(NULL, 0, 50, 0) / Point);

        for (i = WindowBarsPerChart() * MaxArrowsScreensX; i >= 0; i--)

        {
            if (RSIBuffer[i] > overBought && RSIBuffer[i + 1] < overBought)
                DrawArrow(i, "up");

            if (RSIBuffer[i] < overSold && RSIBuffer[i + 1] > overSold)
                DrawArrow(i, "down");

//

//

// should we try to repaint the previous alert signal

//

//

            if ((TimeFrame == Period()) && (repaintSignalStep > 0))

                if (prevBar == i + 1)

                {
                    double currPrice = iMA(NULL, 0, 1, 0, MODE_SMA, repaintSignalPrice, i);

                    double prevPrice = iMA(NULL, 0, 1, 0, MODE_SMA, repaintSignalPrice, i + 1);

//

//

//

//

//

                    if (prevSignal == "down")

                        if (RSIBuffer[i] < overSold)

                            if ((prevPrice - currPrice) / Point >= repaintSignalStep)

                            {
                                ObjectSet(StringConcatenate(SignalName, maxArrows), OBJPROP_TIME1, Time[i]);

                                ObjectSet(StringConcatenate(SignalName, maxArrows), OBJPROP_PRICE1, Low[i] - (SignalGap * Point));
                            }

                    if (prevSignal == "up")

                        if (RSIBuffer[i] > overBought)

                            if ((currPrice - prevPrice) / Point >= repaintSignalStep)

                            {
                                ObjectSet(StringConcatenate(SignalName, maxArrows), OBJPROP_TIME1, Time[i]);

                                ObjectSet(StringConcatenate(SignalName, maxArrows), OBJPROP_PRICE1, High[i] + (SignalGap * Point));
                            }
                }
        }
    }


//

//

//

//

    if (alertsOn)
    {
        if (RSIBuffer[0] > overBought && RSIBuffer[1] < overBought)
            doAlert(overBought + " line crossed up");

        if (RSIBuffer[0] < overSold && RSIBuffer[1] > overSold)
            doAlert(overBought + " line crossed down");
    }


//

//

//

//

//

    return(0);
}


//+------------------------------------------------------------------+

//| |

//+------------------------------------------------------------------+

//

//

//

//

//


void DrawArrow(int i, string type)

{
    string name;

    maxArrows++;

    name = StringConcatenate(SignalName, maxArrows, TimeFrame);

    ObjectCreate(name, OBJ_ARROW, 0, Time[i], 0);

    if (type == "down")

    {
        ObjectSet(name, OBJPROP_PRICE1, High[i] + (SignalGap * Point));

        ObjectSet(name, OBJPROP_ARROWCODE, DownArrow_Code);

        ObjectSet(name, OBJPROP_COLOR, Red);

        ObjectSet(name, OBJPROP_WIDTH, Arrow_Size);
    }

    else

    {
        ObjectSet(name, OBJPROP_PRICE1, Low[i] - (SignalGap * Point / 2));

        ObjectSet(name, OBJPROP_ARROWCODE, UpArrow_Code);

        ObjectSet(name, OBJPROP_COLOR, LimeGreen);

        ObjectSet(name, OBJPROP_WIDTH, Arrow_Size);
    }

    prevSignal = type;

    prevBar = i;
}

void DeleteArrows()

{
    while (maxArrows > 0)
    {
        ObjectDelete(StringConcatenate(SignalName, maxArrows, TimeFrame)); maxArrows--;
    }
}



//+------------------------------------------------------------------+

//| |

//+------------------------------------------------------------------+


void doAlert(string doWhat)

{
    static string   previousAlert = "nothing";

    static datetime previousTime;

    string          message;

    if (previousAlert != doWhat || previousTime != Time[0])
    {
        previousAlert = doWhat;

        previousTime = Time[0];

//

//

//

//

//

        message = StringConcatenate(Symbol(), " at ", TimeToStr(TimeLocal(), TIME_SECONDS), " RSI ", doWhat);

        if (alertsMessage)
            Alert(message);

        if (alertsSound)
            PlaySound("alert2.wav");

        if (alertsEmail)
            SendMail(StringConcatenate(Symbol(), " RSI crossing"), message);
    }
}


//+------------------------------------------------------------------+

//| |

//+------------------------------------------------------------------+

//

//

//

//

//


string PriceTypeToString(int pt)

{
    string answer;

    switch (pt)

    {
    case 0: answer = "Close"; break;

    case 1: answer = "Open"; break;

    case 2: answer = "High"; break;

    case 3: answer = "Low"; break;

    case 4: answer = "Median"; break;

    case 5: answer = "Typical"; break;

    case 6: answer = "Wighted"; break;

    default: answer = "Invalid price field requested";

        Alert(answer);
    }

    return(answer);
}

int stringToTimeFrame(string tfs)

{
    int tf = 0;

    tfs = StringUpperCase(tfs);

    if (tfs == "M1" || tfs == "1")
        tf = PERIOD_M1;

    if (tfs == "M5" || tfs == "5")
        tf = PERIOD_M5;

    if (tfs == "M15" || tfs == "15")
        tf = PERIOD_M15;

    if (tfs == "M30" || tfs == "30")
        tf = PERIOD_M30;

    if (tfs == "H1" || tfs == "60")
        tf = PERIOD_H1;

    if (tfs == "H4" || tfs == "240")
        tf = PERIOD_H4;

    if (tfs == "D1" || tfs == "1440")
        tf = PERIOD_D1;

    if (tfs == "W1" || tfs == "10080")
        tf = PERIOD_W1;

    if (tfs == "MN" || tfs == "43200")
        tf = PERIOD_MN1;

    if (tf < Period())
        tf = Period();

    return(tf);
}

string TimeFrameToString(int tf)

{
    string tfs = "Current time frame";

    switch (tf)
    {
    case PERIOD_M1: tfs = "M1"; break;

    case PERIOD_M5: tfs = "M5"; break;

    case PERIOD_M15: tfs = "M15"; break;

    case PERIOD_M30: tfs = "M30"; break;

    case PERIOD_H1: tfs = "H1"; break;

    case PERIOD_H4: tfs = "H4"; break;

    case PERIOD_D1: tfs = "D1"; break;

    case PERIOD_W1: tfs = "W1"; break;

    case PERIOD_MN1: tfs = "MN1";
    }

    return(tfs);
}


//

//

//

//

//


string StringUpperCase(string str)

{
    string s = str;

    int    lenght = StringLen(str) - 1;

   int char_;

    while (lenght >= 0)

    {
        char_ = StringGetChar(s, lenght);

//

//

//

//

//

        if ((char_ > 96 && char_ < 123) || (char_ > 223 && char_ < 256))

            s = StringSetChar(s, lenght, char_ - 32);

        else

        if (char_ > -33 && char_ < 0)

            s = StringSetChar(s, lenght, char_ + 224);

        lenght--;
    }

//

//

//

//

//

    return(s);
}


