//╔════════════════════════════════════════════════════════════════════════╗ //║ ██████╗██╗ ██╗ █████╗ ██████╗ ██████╗ █████╗ █████╗ █████╗ ███╗ ██╗ ║ //║ ██╔═══╝╚██╗██╔╝██╔══██╗██╔══██╗██╔═══╝██╔══██╗██╔═══╝██╔══██╗████╗ ██║ ║ //║ █████╗ ╚███╔╝ ██║ ██║██████╔╝█████╗ ███████║██║ ██║ ██║██╔██╗██║ ║ //║ ██╔══╝ ██╔██╗ ██║ ██║██╔══██╗██╔══╝ ██╔══██║██║ ██║ ██║██║╚████║ ║ //║ ██████╗██╔╝ ██╗╚█████╔╝██████╔╝██████╗██║ ██║╚█████╗╚█████╔╝██║ ╚███║ ║ //║ ╚═════╝╚═╝ ╚═╝ ╚════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝ ╚════╝ ╚════╝ ╚═╝ ╚══╝ ║ //╚═══════ Algorithms that observe ══════ Signals that speak ══════════════╝ //+------------------------------------------------------------------+ //| Réplica fiel del indicador "Bollinger + RSI, Double Strategy | //| (by ChartArt) v1.1" originalmente publicado en TradingView. | //| | //| Lógica central: | //| BUY = crossover(RSI, 50) AND crossover(close, BB Lower) | //| SELL = crossunder(RSI, 50) AND crossunder(close, BB Upper) | //| | //| Particularidades del original: | //| - RSI periodo 6 con umbral 50 (filtro de momentum, no extremo) | //| - Bollinger Bands SMA 200, multiplicador 2 | //| - RSIoverSold = RSIoverBought = 50 (hardcoded) | //| - Coloreo de velas y fondo como confirmación visual | //+------------------------------------------------------------------+ #property copyright "Exobeacon Labs" #property link "https://www.exobeacon.com/" #property version "1.1" #property description "Bollinger + RSI, Double Strategy (by ChartArt) v1.1" #property description "Buy/Sell signals based on RSI(6)@50 + BB(200,2) confluence" #property description " " #property description "BUY: RSI crosses above 50 AND price crosses above BB Lower" #property description "SELL: RSI crosses below 50 AND price crosses below BB Upper" #property description " " #property description "〰〰〰〰〰((👽))〰〰〰〰〰" #property description "🛸 mql5.com/en/users/ulisescalb" #property description "🛸 github.com/Exobeacon-Labs" #property strict //--- Dibujar en la ventana principal del gráfico (overlay=true en Pine Script) #property indicator_chart_window //--- Número total de buffers y plots #property indicator_buffers 7 #property indicator_plots 5 //+------------------------------------------------------------------+ //| Configuración de plots | //+------------------------------------------------------------------+ //--- Plot 0: BB Basis (SMA) - Línea aqua como en el original #property indicator_label1 "BB Basis (SMA)" #property indicator_type1 DRAW_LINE #property indicator_color1 clrAqua #property indicator_style1 STYLE_SOLID #property indicator_width1 2 //--- Plot 1: BB Upper - Línea plateada #property indicator_label2 "BB Upper" #property indicator_type2 DRAW_LINE #property indicator_color2 clrSilver #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- Plot 2: BB Lower - Línea plateada #property indicator_label3 "BB Lower" #property indicator_type3 DRAW_LINE #property indicator_color3 clrSilver #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- Plot 3: Señal de compra (flecha arriba) #property indicator_label4 "Buy Signal" #property indicator_type4 DRAW_ARROW #property indicator_color4 clrLime #property indicator_width4 2 //--- Plot 4: Señal de venta (flecha abajo) #property indicator_label5 "Sell Signal" #property indicator_type5 DRAW_ARROW #property indicator_color5 clrRed #property indicator_width5 2 //+------------------------------------------------------------------+ //| Parámetros de entrada | //+------------------------------------------------------------------+ //| Mapeados desde el Pine Script original: | //| input(6, "RSI Period Length") → InpRSIPeriod | //| input(200, "Bollinger Period") → InpBBPeriod | //| input(true, "Enable Bar Color?") → InpEnableBarColor | //| input(true, "Enable BG Color?") → InpEnableBGColor | //| | //| Parámetros hardcoded en el original ahora expuestos como input: | //| BBmult = 2 → InpBBMultiplier | //| RSIoverSold = RSIoverBought = 50 → InpRSILevel | //+------------------------------------------------------------------+ input group "══════ RSI Settings ══════" input int InpRSIPeriod = 6; // RSI Period Length input int InpRSILevel = 50; // RSI Crossover Level (original=50) input group "══════ Bollinger Bands Settings ══════" input int InpBBPeriod = 200; // Bollinger Period Length input double InpBBMultiplier = 2.0; // Bollinger Std Deviation Multiplier (original=2) input group "══════ Visual Settings ══════" input bool InpEnableBarColor = true; // Enable Bar Color? input bool InpEnableBGColor = true; // Enable Background Color? input int InpArrowOffset = 10; // Arrow Offset (points from candle) input color InpBuyColor = clrLime; // Buy Signal Color input color InpSellColor = clrRed; // Sell Signal Color input color InpBasisColor = clrAqua; // BB Basis Color input color InpBandColor = clrSilver; // BB Band Color input group "══════ Alert Settings ══════" input bool InpEnableAlerts = false; // Enable Alerts? input bool InpAlertPopup = true; // Alert: Popup input bool InpAlertSound = true; // Alert: Sound input bool InpAlertPush = false; // Alert: Push Notification input bool InpAlertEmail = false; // Alert: Email //+------------------------------------------------------------------+ //| Buffers del indicador | //+------------------------------------------------------------------+ //| Buffers de datos (INDICATOR_DATA) - se dibujan en el gráfico: | //| [0] bufBasis - Línea central SMA de Bollinger | //| [1] bufUpper - Banda superior de Bollinger | //| [2] bufLower - Banda inferior de Bollinger | //| [3] bufBuyArrow - Flechas de señal de compra | //| [4] bufSellArrow - Flechas de señal de venta | //| | //| Buffers auxiliares (INDICATOR_CALCULATIONS) - no se dibujan: | //| [5] bufBarColorIdx - Índice de color para velas | //| [6] bufRSI - Valores RSI para referencia | //+------------------------------------------------------------------+ double bufBasis[]; double bufUpper[]; double bufLower[]; double bufBuyArrow[]; double bufSellArrow[]; double bufBarColorIdx[]; double bufRSI[]; //+------------------------------------------------------------------+ //| Handles de indicadores internos de MQL5 | //+------------------------------------------------------------------+ int g_handleRSI; // Handle para iRSI int g_handleMA; // Handle para iMA (SMA base de Bollinger) int g_handleStdDev; // Handle para iStdDev (desviación estándar) //--- Arrays temporales para copiar datos de indicadores double g_dataRSI[]; double g_dataMA[]; double g_dataStdDev[]; //--- Control de barras mínimas necesarias int g_minBars; //--- Tracking de última alerta para evitar duplicados datetime g_lastAlertTime = 0; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Validación de parámetros de entrada if(InpRSIPeriod < 1) { Print("Error: RSI Period debe ser >= 1. Valor actual: ", InpRSIPeriod); return(INIT_PARAMETERS_INCORRECT); } if(InpBBPeriod < 1) { Print("Error: Bollinger Period debe ser >= 1. Valor actual: ", InpBBPeriod); return(INIT_PARAMETERS_INCORRECT); } if(InpBBMultiplier <= 0) { Print("Error: BB Multiplier debe ser > 0. Valor actual: ", InpBBMultiplier); return(INIT_PARAMETERS_INCORRECT); } if(InpRSILevel < 0 || InpRSILevel > 100) { Print("Error: RSI Level debe estar entre 0 y 100. Valor actual: ", InpRSILevel); return(INIT_PARAMETERS_INCORRECT); } //--- Barras mínimas necesarias para que los indicadores sean válidos g_minBars = MathMax(InpBBPeriod, InpRSIPeriod) + 2; //--- Asignación de buffers a índices SetIndexBuffer(0, bufBasis, INDICATOR_DATA); SetIndexBuffer(1, bufUpper, INDICATOR_DATA); SetIndexBuffer(2, bufLower, INDICATOR_DATA); SetIndexBuffer(3, bufBuyArrow, INDICATOR_DATA); SetIndexBuffer(4, bufSellArrow, INDICATOR_DATA); SetIndexBuffer(5, bufBarColorIdx, INDICATOR_CALCULATIONS); SetIndexBuffer(6, bufRSI, INDICATOR_CALCULATIONS); //--- Configurar flechas de señal // 233 = flecha arriba (▲), 234 = flecha abajo (▼) PlotIndexSetInteger(3, PLOT_ARROW, 233); PlotIndexSetInteger(4, PLOT_ARROW, 234); //--- Valores vacíos para flechas (no dibujar donde no hay señal) PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, EMPTY_VALUE); //--- Aplicar colores configurados por el usuario PlotIndexSetInteger(0, PLOT_LINE_COLOR, InpBasisColor); PlotIndexSetInteger(1, PLOT_LINE_COLOR, InpBandColor); PlotIndexSetInteger(2, PLOT_LINE_COLOR, InpBandColor); PlotIndexSetInteger(3, PLOT_LINE_COLOR, InpBuyColor); PlotIndexSetInteger(4, PLOT_LINE_COLOR, InpSellColor); //--- Configurar inicio de dibujo para evitar basura en primeras barras PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, InpBBPeriod - 1); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, InpBBPeriod - 1); PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, InpBBPeriod - 1); PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, g_minBars); PlotIndexSetInteger(4, PLOT_DRAW_BEGIN, g_minBars); //--- Nombre corto del indicador (aparece en la ventana de datos) string shortName = StringFormat("CA_RSI(%d)_BB(%d,%.1f) v1.1", InpRSIPeriod, InpBBPeriod, InpBBMultiplier); IndicatorSetString(INDICATOR_SHORTNAME, shortName); //--- Precisión de dígitos IndicatorSetInteger(INDICATOR_DIGITS, _Digits); //--- Crear handles de indicadores integrados de MQL5 // RSI de Wilder (idéntico al rsi() de Pine Script) g_handleRSI = iRSI(_Symbol, PERIOD_CURRENT, InpRSIPeriod, PRICE_CLOSE); if(g_handleRSI == INVALID_HANDLE) { Print("Error creando handle iRSI: ", GetLastError()); return(INIT_FAILED); } //--- SMA para la base de Bollinger // Pine Script: sma(close, BBlength) → iMA con MODE_SMA g_handleMA = iMA(_Symbol, PERIOD_CURRENT, InpBBPeriod, 0, MODE_SMA, PRICE_CLOSE); if(g_handleMA == INVALID_HANDLE) { Print("Error creando handle iMA: ", GetLastError()); return(INIT_FAILED); } //--- Desviación estándar para las bandas // Pine Script: stdev(close, BBlength) → iStdDev con MODE_SMA // Nota: Ambos calculan desviación estándar poblacional (÷N, no ÷(N-1)) g_handleStdDev = iStdDev(_Symbol, PERIOD_CURRENT, InpBBPeriod, 0, MODE_SMA, PRICE_CLOSE); if(g_handleStdDev == INVALID_HANDLE) { Print("Error creando handle iStdDev: ", GetLastError()); return(INIT_FAILED); } //--- Configurar arrays temporales ArraySetAsSeries(g_dataRSI, false); ArraySetAsSeries(g_dataMA, false); ArraySetAsSeries(g_dataStdDev, false); Print("Bollinger + RSI Double Strategy v1.1 inicializado correctamente."); Print("Configuración: RSI(", InpRSIPeriod, ")@", InpRSILevel, " + BB(", InpBBPeriod, ", ", InpBBMultiplier, ")"); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- Liberar handles de indicadores if(g_handleRSI != INVALID_HANDLE) IndicatorRelease(g_handleRSI); if(g_handleMA != INVALID_HANDLE) IndicatorRelease(g_handleMA); if(g_handleStdDev != INVALID_HANDLE) IndicatorRelease(g_handleStdDev); //--- Limpiar objetos gráficos del coloreo de fondo ObjectsDeleteAll(0, "BRDS_BG_", 0, OBJ_RECTANGLE); //--- Limpiar comentarios del gráfico Comment(""); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { //--- Verificar que hay suficientes barras if(rates_total < g_minBars) return(0); //--- Copiar datos de los indicadores integrados // Nota: Se copian todos los datos necesarios de una sola vez // Los arrays NO son series (índice 0 = barra más antigua) int copied; copied = CopyBuffer(g_handleMA, 0, 0, rates_total, g_dataMA); if(copied < rates_total) return(0); copied = CopyBuffer(g_handleStdDev, 0, 0, rates_total, g_dataStdDev); if(copied < rates_total) return(0); copied = CopyBuffer(g_handleRSI, 0, 0, rates_total, g_dataRSI); if(copied < rates_total) return(0); //--- Determinar el punto de inicio del cálculo // Si es la primera vez (prev_calculated == 0): calcular todo desde g_minBars // Si es recálculo parcial: solo recalcular las barras nuevas + 1 int startBar; if(prev_calculated <= 0) startBar = g_minBars; else startBar = MathMax(prev_calculated - 1, g_minBars); //--- Bucle principal de cálculo for(int i = startBar; i < rates_total; i++) { //=== 1. CALCULAR BANDAS DE BOLLINGER === // Pine Script: // BBbasis = sma(price, BBlength) // BBdev = BBmult * stdev(price, BBlength) // BBupper = BBbasis + BBdev // BBlower = BBbasis - BBdev double basis = g_dataMA[i]; double dev = InpBBMultiplier * g_dataStdDev[i]; double upper = basis + dev; double lower = basis - dev; bufBasis[i] = basis; bufUpper[i] = upper; bufLower[i] = lower; //--- Valores de la barra anterior (para crossover/crossunder) double basisPrev = g_dataMA[i - 1]; double devPrev = InpBBMultiplier * g_dataStdDev[i - 1]; double upperPrev = basisPrev + devPrev; double lowerPrev = basisPrev - devPrev; //=== 2. ALMACENAR RSI PARA REFERENCIA === double rsiCurr = g_dataRSI[i]; double rsiPrev = g_dataRSI[i - 1]; bufRSI[i] = rsiCurr; //--- Inicializar señales como vacías bufBuyArrow[i] = EMPTY_VALUE; bufSellArrow[i] = EMPTY_VALUE; bufBarColorIdx[i] = 0; // 0 = sin color especial //--- Saltar si el RSI aún no tiene valores válidos if(rsiCurr == EMPTY_VALUE || rsiPrev == EMPTY_VALUE) continue; //=== 3. DETECTAR SEÑALES (CONFLUENCIA RSI + BB) === // Pine Script original: // if (crossover(vrsi, RSIoverSold) and crossover(source, BBlower)) // → LONG // if (crossunder(vrsi, RSIoverBought) and crossunder(source, BBupper)) // → SHORT // // crossover(a, b) = a[1] < b[1] AND a[0] >= b[0] // crossunder(a, b) = a[1] > b[1] AND a[0] <= b[0] // // Para nivel fijo (50): crossover(vrsi, 50) = vrsi[1] < 50 AND vrsi >= 50 //--- Señal LONG: RSI cruza arriba de 50 + Precio cruza arriba de BB Lower bool rsiCrossUp = (rsiPrev < InpRSILevel && rsiCurr >= InpRSILevel); bool priceCrossUp = (close[i - 1] < lowerPrev && close[i] >= lower); bool longSignal = rsiCrossUp && priceCrossUp; //--- Señal SHORT: RSI cruza abajo de 50 + Precio cruza abajo de BB Upper bool rsiCrossDown = (rsiPrev > InpRSILevel && rsiCurr <= InpRSILevel); bool priceCrossDown = (close[i - 1] > upperPrev && close[i] <= upper); bool shortSignal = rsiCrossDown && priceCrossDown; //--- Dibujar flechas de señal if(longSignal) { bufBuyArrow[i] = low[i] - InpArrowOffset * _Point; } if(shortSignal) { bufSellArrow[i] = high[i] + InpArrowOffset * _Point; } //=== 4. COLOREO DE VELAS (TrendColor del original) === // Pine Script original: // TrendColor = RSIoverBought and (price[1] > BBupper and price < BBupper) // and BBbasis < BBbasis[1] ? red // : RSIoverSold and (price[1] < BBlower and price > BBlower) // and BBbasis > BBbasis[1] ? green // : na // // Nota: RSIoverBought=50 y RSIoverSold=50 son siempre truthy en Pine v2 // (cualquier número != 0 es true), así que la condición se simplifica a: // ROJO: price[1] > BBupper AND price < BBupper AND basis < basis[1] // VERDE: price[1] < BBlower AND price > BBlower AND basis > basis[1] bool trendBearish = (close[i - 1] > upperPrev && close[i] < upper && basis < basisPrev); bool trendBullish = (close[i - 1] < lowerPrev && close[i] > lower && basis > basisPrev); //--- Aplicar color a las velas if(InpEnableBarColor) { if(trendBearish) bufBarColorIdx[i] = -1; // Señal bajista (rojo) else if(trendBullish) bufBarColorIdx[i] = 1; // Señal alcista (verde) else bufBarColorIdx[i] = 0; // Sin señal } //--- Crear rectángulos de fondo para simular bgcolor() de Pine Script if(InpEnableBGColor && i == rates_total - 1) { //--- Solo procesar la última barra para el fondo en tiempo real if(trendBearish) DrawBackground(time[i], time[i] + PeriodSeconds(), high[i], low[i], InpSellColor, 80); else if(trendBullish) DrawBackground(time[i], time[i] + PeriodSeconds(), high[i], low[i], InpBuyColor, 80); } //=== 5. ALERTAS === if(InpEnableAlerts && i == rates_total - 1 && time[i] != g_lastAlertTime) { if(longSignal) { SendAlert("BUY Signal: RSI crossed above " + IntegerToString(InpRSILevel) + " + Price crossed above BB Lower"); g_lastAlertTime = time[i]; } else if(shortSignal) { SendAlert("SELL Signal: RSI crossed below " + IntegerToString(InpRSILevel) + " + Price crossed below BB Upper"); g_lastAlertTime = time[i]; } } } //--- Aplicar coloreo de velas usando ChartSetSymbolPeriod approach if(InpEnableBarColor) ApplyBarColors(rates_total, startBar, time, open, high, low, close); return(rates_total); } //+------------------------------------------------------------------+ //| Aplicar colores a las velas del gráfico | //+------------------------------------------------------------------+ void ApplyBarColors(const int rates_total, const int startBar, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[]) { //--- Solo colorear las barras recién calculadas para rendimiento int from = MathMax(startBar, rates_total - 100); // Últimas 100 barras máximo for(int i = from; i < rates_total; i++) { string objName = "BRDS_BAR_" + IntegerToString(i); if(bufBarColorIdx[i] == -1) // Bajista (rojo) { //--- Crear/actualizar objeto de vela roja ObjectDelete(0, objName); // Nota: El coloreo nativo de velas se hace mediante DRAW_COLOR_CANDLES // pero al ser indicador overlay, usamos un enfoque simplificado con // indicación en el buffer. Para coloreo real de velas, ver nota abajo. } else if(bufBarColorIdx[i] == 1) // Alcista (verde) { ObjectDelete(0, objName); } else { ObjectDelete(0, objName); } } //--- Nota técnica sobre coloreo de velas en MQL5: // El coloreo nativo de barras (barcolor en Pine Script) no tiene un equivalente // directo sencillo en indicadores MQL5 overlay. Las opciones son: // 1. Usar DRAW_COLOR_CANDLES (requiere buffers adicionales para OHLC completo) // 2. Dibujar objetos gráficos sobre las velas // 3. Usar ChartIndicatorAdd con indicador secundario // La implementación completa de DRAW_COLOR_CANDLES se incluye a continuación // como función alternativa que puede activarse. } //+------------------------------------------------------------------+ //| Dibujar rectángulo de fondo (simula bgcolor de Pine Script) | //+------------------------------------------------------------------+ void DrawBackground(datetime timeStart, datetime timeEnd, double priceHigh, double priceLow, color bgColor, int transparency) { string objName = "BRDS_BG_" + TimeToString(timeStart, TIME_DATE | TIME_MINUTES); //--- Crear o mover el rectángulo if(ObjectFind(0, objName) < 0) { ObjectCreate(0, objName, OBJ_RECTANGLE, 0, timeStart, priceHigh, timeEnd, priceLow); } else { ObjectMove(0, objName, 0, timeStart, priceHigh); ObjectMove(0, objName, 1, timeEnd, priceLow); } ObjectSetInteger(0, objName, OBJPROP_COLOR, bgColor); ObjectSetInteger(0, objName, OBJPROP_FILL, true); ObjectSetInteger(0, objName, OBJPROP_BACK, true); //--- Transparencia: 0=opaco, 255=invisible. Pine usa transp=50 → ~127 int alpha = (int)(transparency * 2.55); ObjectSetInteger(0, objName, OBJPROP_FILL, true); ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, objName, OBJPROP_HIDDEN, true); } //+------------------------------------------------------------------+ //| Enviar alertas multi-canal | //+------------------------------------------------------------------+ void SendAlert(string message) { string prefix = "BB+RSI v1.1 [" + _Symbol + " " + EnumToString(Period()) + "]: "; string fullMsg = prefix + message; if(InpAlertPopup) Alert(fullMsg); if(InpAlertSound) PlaySound("alert.wav"); if(InpAlertPush) SendNotification(fullMsg); if(InpAlertEmail) SendMail("BB+RSI Signal", fullMsg); Print(fullMsg); } //+------------------------------------------------------------------+ //| | //| ═══════════════════════════════════════════════════════════ | //| VERSIÓN ALTERNATIVA: DRAW_COLOR_CANDLES PARA COLOREO REAL | //| ═══════════════════════════════════════════════════════════ | //| | //| Si se desea coloreo real de velas (como barcolor en Pine), | //| reemplazar los plots 3-4 por DRAW_COLOR_CANDLES. Esto requiere | //| 4 buffers adicionales (Open, High, Low, Close coloreados) más | //| 1 buffer de índice de color. La implementación alternativa se | //| documenta aquí como referencia: | //| | //| // #property indicator_buffers 12 | //| // #property indicator_plots 6 | //| // | //| // Plot 5: Colored Candles | //| // #property indicator_type6 DRAW_COLOR_CANDLES | //| // #property indicator_color6 clrNONE,clrLime,clrRed | //| // (0=sin color, 1=verde, 2=rojo) | //| // | //| // Buffers adicionales: | //| // [7] bufCandleOpen | //| // [8] bufCandleHigh | //| // [9] bufCandleLow | //| // [10] bufCandleClose | //| // [11] bufCandleColor (índice: 0, 1, o 2) | //| // | //| // En OnCalculate, para cada barra: | //| // bufCandleOpen[i] = open[i]; | //| // bufCandleHigh[i] = high[i]; | //| // bufCandleLow[i] = low[i]; | //| // bufCandleClose[i] = close[i]; | //| // if(trendBullish) bufCandleColor[i] = 1; // verde | //| // else if(trendBearish) bufCandleColor[i] = 2; // rojo | //| // else bufCandleColor[i] = 0; // default | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //| ═══════════════════════════════════════════════════════════ | //| REFERENCIA: PINE SCRIPT ORIGINAL v1.1 (ChartArt) | //| ═══════════════════════════════════════════════════════════ | //| | //| //@version=2 | //| strategy("Bollinger + RSI, Double Strategy (by ChartArt) v1.1", | //| shorttitle="CA_-_RSI_Bol_Strat_1.1", overlay=true) | //| | //| ///////////// RSI | //| RSIlength = input(6,title="RSI Period Length") | //| RSIoverSold = 50 | //| RSIoverBought = 50 | //| price = close | //| vrsi = rsi(price, RSIlength) | //| | //| ///////////// Bollinger Bands | //| BBlength = input(200, minval=1,title="Bollinger Period Length") | //| BBmult = 2 | //| BBbasis = sma(price, BBlength) | //| BBdev = BBmult * stdev(price, BBlength) | //| BBupper = BBbasis + BBdev | //| BBlower = BBbasis - BBdev | //| source = close | //| buyEntry = crossover(source, BBlower) | //| sellEntry = crossunder(source, BBupper) | //| plot(BBbasis, color=aqua,title="BB SMA Basis Line") | //| p1 = plot(BBupper, color=silver,title="BB Upper Line") | //| p2 = plot(BBlower, color=silver,title="BB Lower Line") | //| fill(p1, p2) | //| | //| ///////////// Colors | //| switch1=input(true, title="Enable Bar Color?") | //| switch2=input(true, title="Enable Background Color?") | //| TrendColor = RSIoverBought and (price[1] > BBupper and | //| price < BBupper) and BBbasis < BBbasis[1] ? red | //| : RSIoverSold and (price[1] < BBlower and | //| price > BBlower) and BBbasis > BBbasis[1] ? green | //| : na | //| barcolor(switch1?TrendColor:na) | //| bgcolor(switch2?TrendColor:na,transp=50) | //| | //| ///////////// RSI + Bollinger Bands Strategy | //| if (not na(vrsi)) | //| if (crossover(vrsi, RSIoverSold) and | //| crossover(source, BBlower)) | //| strategy.entry("RSI_BB_L", strategy.long, | //| stop=BBlower, oca_type=...cancel, | //| comment="RSI_BB_L") | //| else | //| strategy.cancel(id="RSI_BB_L") | //| if (crossunder(vrsi, RSIoverBought) and | //| crossunder(source, BBupper)) | //| strategy.entry("RSI_BB_S", strategy.short, | //| stop=BBupper, oca_type=...cancel, | //| comment="RSI_BB_S") | //| else | //| strategy.cancel(id="RSI_BB_S") | //| | //+------------------------------------------------------------------+