#property indicator_separate_window #property strict #property indicator_buffers 5 #property indicator_color1 clrRed #property indicator_color2 clrGreen #property indicator_color3 clrBlack enum TIMEFRAMES { PeriodCurrent = PERIOD_CURRENT, // Actual PeriodM1 = PERIOD_M1, // М1 PeriodM5 = PERIOD_M5, // М5 PeriodM15 = PERIOD_M15, // М15 PeriodM30 = PERIOD_M30, // M30 PeriodH1 = PERIOD_H1, // H1 PeriodH4 = PERIOD_H4, // H4 PeriodD1 = PERIOD_D1, // D1 PeriodW1 = PERIOD_W1, // W1 PeriodMN = PERIOD_MN1 // MN1 }; enum AlertBar { Current = 0, // En la barra actual Closed = 1 // Solo en bares cerrados }; enum Mode { ReturnBars = -2, CalculateRSI = -1, Normal = 0 }; input TIMEFRAMES i_ePeriod = PERIOD_M5; // Periodo de tiempo input int RsiPeriod = 4; // RSI período input ENUM_MA_METHOD MaType = MODE_EMA; // Tipo MA input int MaPeriod = 2; // Período MA input bool Interpolate = false; // Interpolación input string arrowsIdentifier = "SBNR arrows"; // ID de flecha input color arrowsUpColor = clrLime; // Color flecha arriba input color arrowsDnColor = clrRed; // Color flecha abajo input AlertBar i_eAlertBar = Closed; // Alerta input bool alertsSound = TRUE; // Alerta sonora input bool alertsMessage = FALSE; // Notificaciones push input bool alertsEmail = FALSE; // Notificaciones email double RSIBuffer[]; double MABuffer[]; double StatusBuffer[],BUY[],SELL[]; string g_sIndicatorName; bool g_bCalculateRSI = FALSE; bool g_bReturnBars = FALSE; ENUM_TIMEFRAMES g_ePeriod; datetime g_dtLastBarTime; int OnInit() { g_ePeriod = (ENUM_TIMEFRAMES) i_ePeriod; if(i_ePeriod == PeriodCurrent) g_ePeriod = (ENUM_TIMEFRAMES) _Period; //IndicatorBuffers(5); SetIndexBuffer(0, RSIBuffer); SetIndexLabel(0, ""); SetIndexBuffer(1, MABuffer); SetIndexLabel(1, ""); SetIndexBuffer(2, StatusBuffer); SetIndexLabel(2, ""); SetIndexBuffer(3, BUY); SetIndexStyle(3,DRAW_NONE); SetIndexBuffer(4, SELL); SetIndexStyle(4,DRAW_NONE); if ((Mode) g_ePeriod == CalculateRSI) { g_bCalculateRSI = TRUE; return (INIT_SUCCEEDED); } if ((Mode) g_ePeriod == ReturnBars) { g_bReturnBars = TRUE; return (INIT_SUCCEEDED); } g_sIndicatorName = WindowExpertName(); IndicatorShortName("Bams-bung " + PeriodToString()); return (INIT_SUCCEEDED); } void OnDeinit(const int nReason) { RemoveAllArrows(); } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { int nOtherPeriodShift; if (prev_calculated < 0) return (0); int nStartBar = MathMin(Bars - prev_calculated, Bars - 1); if (g_bReturnBars) { RSIBuffer[0] = nStartBar + 1; return (rates_total); } if (g_ePeriod > Period()) nStartBar = (int) MathMax(nStartBar, MathMin(Bars - 1, iCustom(NULL, g_ePeriod, g_sIndicatorName, ReturnBars, 0, 0) * g_ePeriod / Period())); if (g_bCalculateRSI) { for (int i = 0; i < nStartBar; i++) RSIBuffer[i] = iRSI(NULL, 0, RsiPeriod, PRICE_CLOSE, i); for (int i = 0; i < nStartBar; i++) MABuffer[i] = iMAOnArray(RSIBuffer, 0, MaPeriod, 0, MaType, i); return (rates_total); } for (int i = nStartBar; i >= 0; i--) { if(i > Bars - 2) continue; nOtherPeriodShift = iBarShift(NULL, g_ePeriod, Time[i] - Time[i] % g_ePeriod, true); if(nOtherPeriodShift == -1) continue; RSIBuffer[i] = iCustom(NULL, g_ePeriod, g_sIndicatorName, CalculateRSI, RsiPeriod, MaType, MaPeriod, 0, nOtherPeriodShift); MABuffer[i] = iCustom(NULL, g_ePeriod, g_sIndicatorName, CalculateRSI, RsiPeriod, MaType, MaPeriod, 1, nOtherPeriodShift); StatusBuffer[i] = StatusBuffer[i + 1]; if (RSIBuffer[i] > MABuffer[i]) StatusBuffer[i] = 1; if (RSIBuffer[i] < MABuffer[i]) StatusBuffer[i] = -1; RemoveArrow(Time[i]); if (StatusBuffer[i] != StatusBuffer[i + 1]) { if (StatusBuffer[i] == 1.0) { DrawArrow(i, arrowsUpColor, 233, 0); BUY[i]=Low[i]; } if (StatusBuffer[i] == -1.0) { DrawArrow(i, arrowsDnColor, 234, 1); SELL[i]=High[i]; } } if (g_ePeriod <= Period() || (i > 0 &&nOtherPeriodShift == iBarShift(NULL, g_ePeriod, Time[i - 1]))) continue; if (Interpolate) { datetime dtOlderBarTime = iTime(_Symbol, g_ePeriod, nOtherPeriodShift); int nFirstCurrBarInOlder; for (nFirstCurrBarInOlder = 1; i + nFirstCurrBarInOlder < Bars && Time[i + nFirstCurrBarInOlder] >= dtOlderBarTime; nFirstCurrBarInOlder++) { } double fTemp = 1.0 / nFirstCurrBarInOlder; for (int j = 1; j < nFirstCurrBarInOlder; j++) { RSIBuffer[i + j] = j * fTemp * (RSIBuffer[i + nFirstCurrBarInOlder]) + (1.0 - j * fTemp) * RSIBuffer[i]; MABuffer[i + j] = j * fTemp * (MABuffer[i + nFirstCurrBarInOlder]) + (1.0 - j * fTemp) * MABuffer[i]; } } } if (alertsMessage || alertsSound || alertsEmail) { int nAlertBar = (int) i_eAlertBar; if (StatusBuffer[nAlertBar] != StatusBuffer[nAlertBar + 1]) { if (StatusBuffer[nAlertBar] == 1.0) SendAlert("Trend UP"); if (StatusBuffer[nAlertBar] == -1.0) SendAlert("Trend DOWN"); } } return (rates_total); } void DrawArrow(int i, color cColor, int nArrowCode, bool bUp) { string sName = arrowsIdentifier + ":" + TimeToString(Time[i]); double fVerticalShift = 3.0 * iATR(NULL, 0, 20, i) / 4.0; ObjectCreate(sName, OBJ_ARROW, 0, Time[i], 0); ObjectSet(sName, OBJPROP_ARROWCODE, nArrowCode); ObjectSet(sName, OBJPROP_COLOR, cColor); if (bUp) { ObjectSet(sName, OBJPROP_PRICE1, High[i] + fVerticalShift); return; } ObjectSet(sName, OBJPROP_PRICE1, Low[i] - fVerticalShift); } void RemoveAllArrows() { string sName; string sPrefix = arrowsIdentifier + ":"; int nPrefixLen = StringLen(sPrefix); for (int i = ObjectsTotal() - 1; i >= 0; i--) { sName = ObjectName(i); if(StringSubstr(sName, 0, nPrefixLen) == sPrefix) ObjectDelete(sName); } } void RemoveArrow(datetime dtTime) { string sName = arrowsIdentifier + ":" + TimeToString(dtTime); ObjectDelete(sName); } void SendAlert(string sAlertMessage) { if (g_dtLastBarTime != Time[0]) { g_dtLastBarTime = Time[0]; string sMessage = StringConcatenate(Symbol(), " at ", TimeToStr(TimeLocal(), TIME_SECONDS), " Signal Arrow ", sAlertMessage); if(alertsMessage) Alert(sMessage); if(alertsEmail) SendMail(StringConcatenate(Symbol(), "Signal Arrow"), sMessage); if(alertsSound) PlaySound("alert2.wav"); } } string PeriodToString() { switch (g_ePeriod) { case PERIOD_M1: return ("M(1)"); case PERIOD_M5: return ("M(5)"); case PERIOD_M15: return ("M(15)"); case PERIOD_M30: return ("M(30)"); case PERIOD_H1: return ("H(1)"); case PERIOD_H4: return ("H(4)"); case PERIOD_D1: return ("D(1)"); case PERIOD_W1: return ("W(1)"); case PERIOD_MN1: return ("MN(1)"); } return ("Unknown timeframe"); }