using RSI and Bollinger Bands

Created at 18 Dec 2023, 12:28
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
ER

eric_haiara

Joined 03.01.2017

using RSI and Bollinger Bands
18 Dec 2023, 12:28


can someone tell my why i not able to get open positions using this code when i am using 1 year of data when i am doing backtesting

 

……………………………………………………..

using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;

namespace RSI_and_BollingerBands_Retracement
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class RSIAndBollingerBandsRetracement : Robot
    {
        [Parameter("Periods", DefaultValue = 20, Group = "Bollinger Bands")]
        public int BbPeriods { get; set; }

        [Parameter("Standard Deviation", DefaultValue = 2, Group = "Bollinger Bands")]
        public double BbStdDev { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Simple, Group = "Bollinger Bands")]
        public MovingAverageType BbMaType { get; set; }

        [Parameter("Source", Group = "Bollinger Bands")]
        public DataSeries BbSource { get; set; }

        [Parameter("RSI Periods", DefaultValue = 14, Group = "RSI")]
        public int RsiPeriods { get; set; }

        [Parameter("RSI Source", Group = "RSI")]
        public DataSeries RsiSource { get; set; }

        [Parameter("Overbought Level", DefaultValue = 70, Group = "RSI")]
        public int RsiOverboughtLevel { get; set; }

        [Parameter("Oversold Level", DefaultValue = 30, Group = "RSI")]
        public int RsiOversoldLevel { get; set; }

        [Parameter("Volume", DefaultValue = 10000, Group = "Trade")]
        public int Volume { get; set; }

        [Parameter("Robot Label", DefaultValue = "RSI and BB", Group = "Orders management")]
        public string RobotLabel { get; set; }

        private BollingerBands BollingerBands;
        private RelativeStrengthIndex Rsi;

        protected override void OnStart()
        {
            BollingerBands = Indicators.BollingerBands(BbSource, BbPeriods, BbStdDev, BbMaType);
            Rsi = Indicators.RelativeStrengthIndex(RsiSource, RsiPeriods);
        }

    
        private bool IsDivergence(DataSeries prices, int bbPeriods, DataSeries rsiValues)
        {
         // Calculate Bollinger Bands for the specified period
            var bollingerBands = Indicators.BollingerBands(prices, bbPeriods, BbStdDev, BbMaType);// Get the last two Bollinger Bands top values
            
                     
            var bbTop1 = bollingerBands.Top[bollingerBands.Top.Count - 2];
            var bbTop2 = bollingerBands.Top[bollingerBands.Top.Count - 1];
            var rsi1 = rsiValues[rsiValues.Count - 2];
            var rsi2 = rsiValues[rsiValues.Count - 1];
          
            // Check for bearish divergence
            if (rsi1 > rsi2 && bbTop1 < bbTop2)
            {
              return true;
            }

            // Check for bullish divergence
           if (rsi1 < rsi2 && bbTop1 > bbTop2)
            {
              return true;
            }

             return false;
          }

        protected override void OnBar()
        {
            var i = Bars.Count - 1;
            var prevBbTop = BollingerBands.Top[i - 2];
            var prevBbBottom = BollingerBands.Bottom[i - 2];
            var prevRsi = Rsi.Result[i - 2];
            if (double.IsNaN(prevBbTop) || double.IsNaN(prevBbBottom) || double.IsNaN(prevRsi))
                return;

            var prevClose = Bars.ClosePrices[i - 2];
            var prevHighOverBbTop = prevClose > prevBbTop;
            var prevLowBelowBbBottom = prevClose < prevBbBottom;

            if (prevHighOverBbTop && prevLowBelowBbBottom)
                return;

            var isClosedCandleUp = Bars.ClosePrices[i - 1] > Bars.OpenPrices[i - 1];

            var bbTop = BollingerBands.Top.LastValue;
            var bbBottom = BollingerBands.Bottom.LastValue;
            var bbMain = BollingerBands.Main.LastValue;
            
 
            // Check for divergence
            var isDivergence = IsDivergence(Bars.ClosePrices, BbPeriods, Rsi.Result);
            if (isDivergence)
                return;

          if (prevHighOverBbTop && Bars.HighPrices.Last(1) > bbTop && Bars.HighPrices.Last(2) < bbTop &&
               prevRsi > RsiOverboughtLevel && IsDivergence(Bars.ClosePrices, BbPeriods, Rsi.Result))
             {
               var stopLossPips = (bbTop - bbMain) / Symbol.PipSize;
               OpenPosition(TradeType.Sell, stopLossPips);
             }

          else if (prevLowBelowBbBottom && Bars.LowPrices.Last(1) < bbBottom && Bars.LowPrices.Last(2) > bbBottom && 
             prevRsi < RsiOversoldLevel && IsDivergence(Bars.ClosePrices, BbPeriods, Rsi.Result))
            {
               var stopLossPips = (bbMain - bbBottom) / Symbol.PipSize;
                OpenPosition(TradeType.Buy, stopLossPips);
             }

        }

        private void OpenPosition(TradeType side, double stopLossPips)
        {
            if (Positions.Any(p => p.SymbolName == SymbolName && p.Label == RobotLabel))
             return;
            ExecuteMarketOrder(side, SymbolName, Volume, RobotLabel, stopLossPips, null);
        }


        protected override void OnTick()
        {
            var openedPosition = Positions.FirstOrDefault(p => p.SymbolName == SymbolName && p.Label == RobotLabel);
            if (openedPosition == null)
                return;

            if (openedPosition.TradeType == TradeType.Sell && Bid <= BollingerBands.Bottom.LastValue)
            {
                ClosePosition(openedPosition);
            }
            else if (openedPosition.TradeType == TradeType.Buy && Bid >= BollingerBands.Top.LastValue)
            {
                ClosePosition(openedPosition);
            }
          }
         }
        }


@eric_haiara