Overall Statistics
Total Trades
470
Average Win
0.30%
Average Loss
-0.48%
Compounding Annual Return
-6.138%
Drawdown
18.800%
Expectancy
-0.137
Net Profit
-14.559%
Sharpe Ratio
-1.021
Loss Rate
47%
Win Rate
53%
Profit-Loss Ratio
0.64
Alpha
-0.049
Beta
-0.019
Annual Standard Deviation
0.049
Annual Variance
0.002
Information Ratio
-0.856
Tracking Error
0.137
Treynor Ratio
2.595
Total Fees
$470.00
namespace QuantConnect
{
    internal enum MarketRegime
    {
        Bearish = -1,
        Uncertain = 0,
        Bullish = 1
    }

    public class RsiMaStrategy : QCAlgorithm
    {
        private Security _appl;
        private SimpleMovingAverage _smoothedRSI;
        private RelativeStrengthIndex _rsi;
        private RollingWindow<IndicatorDataPoint> _rsiLag;

        private CompositeIndicator<IndicatorDataPoint> _marketRegimeIndicator;

        private const decimal _tol = 0.0001m;

        public override void Initialize()
        {
            SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage);

            // backtest parameters
            SetStartDate(2015, 01, 01);
            SetEndDate(DateTime.Today);

            // cash allocation
            SetCash(10000);

            _appl = AddEquity("AAPL");
            _rsi = new RelativeStrengthIndex(14);
            _smoothedRSI = new SimpleMovingAverage(4).Of(_rsi);
            _rsiLag = new RollingWindow<IndicatorDataPoint>(2);

            var fiveMinuteConsolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(5));
            fiveMinuteConsolidator.DataConsolidated += FiveMinuteConsolidator_DataConsolidated;
            SubscriptionManager.AddConsolidator(_appl.Symbol, fiveMinuteConsolidator);

            _marketRegimeIndicator = SMA(_appl.Symbol, 5, Resolution.Daily).Minus(SMA(_appl.Symbol, 200, Resolution.Daily));

            Schedule.On(DateRules.EveryDay(), TimeRules.BeforeMarketClose(_appl.Symbol, 4), () =>
            {
                CloseOpenPositions(_appl);
            });

            SetWarmUp(TimeSpan.FromDays(100));
        }

        private void CloseOpenPositions(Security security)
        {
            if (security.Invested)
            {
                Liquidate(security.Symbol);
            }
        }

        private MarketRegime GetMarketRegime()
        {
            MarketRegime marketregime = MarketRegime.Uncertain;
            if (Math.Abs(_marketRegimeIndicator) > _tol)
            {
                marketregime = (MarketRegime)Math.Sign(_marketRegimeIndicator);
            }
            return marketregime;
        }

        private void FiveMinuteConsolidator_DataConsolidated(object sender, TradeBar e)
        {
            _rsi.Update(new IndicatorDataPoint
            {
                Time = e.Time,
                Value = e.Value
            });
            _rsiLag.Add(_rsi.Current);

            if (!_marketRegimeIndicator.IsReady || !_rsiLag.IsReady) return; 

            if (_appl.Invested)
            {
                ExitLogic();
            }
            else
            {
                EntryLogic();
            }
        }

        private void ExitLogic()
        {
            var bullishRSIExit = _rsiLag[1] > 55 && _rsiLag[0] < 55;
            var bearishRSIExit = _rsiLag[1] < 45 && _rsiLag[0] > 45;
            if (   (GetMarketRegime() == MarketRegime.Bullish && bullishRSIExit)
                || (GetMarketRegime() == MarketRegime.Bearish && bearishRSIExit))
            {
                Liquidate(_appl.Symbol);
            }
        }

        private void EntryLogic()
        {
            var bullishRSIEntry = _rsiLag[1] < 30 && _rsiLag[0] > 30;
            var bearishRSIEntry = _rsiLag[1] > 70 && _rsiLag[0] < 70;
            if (GetMarketRegime() == MarketRegime.Bullish && bullishRSIEntry)
            {
                SetHoldings(_appl.Symbol, 1);
            }
            else if (GetMarketRegime() == MarketRegime.Bearish && bearishRSIEntry)
            {
                SetHoldings(_appl.Symbol, -1);
            }
        }

        public override void OnData(Slice data)
        {
        }
    }
}