Overall Statistics
Total Orders
310
Average Win
1.12%
Average Loss
-0.68%
Compounding Annual Return
17.845%
Drawdown
35.000%
Expectancy
0.479
Start Equity
100000
End Equity
179705.17
Net Profit
79.705%
Sharpe Ratio
0.52
Sortino Ratio
0.691
Probabilistic Sharpe Ratio
17.738%
Loss Rate
44%
Win Rate
56%
Profit-Loss Ratio
1.65
Alpha
0.067
Beta
0.802
Annual Standard Deviation
0.233
Annual Variance
0.054
Information Ratio
0.261
Tracking Error
0.207
Treynor Ratio
0.151
Total Fees
$581.29
Estimated Strategy Capacity
$7900000.00
Lowest Capacity Asset
IEF SGNKIKYGE9NP
Portfolio Turnover
4.12%
#region imports
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Globalization;
    using System.Drawing;
    using QuantConnect;
    using QuantConnect.Algorithm.Framework;
    using QuantConnect.Algorithm.Framework.Selection;
    using QuantConnect.Algorithm.Framework.Alphas;
    using QuantConnect.Algorithm.Framework.Portfolio;
    using QuantConnect.Algorithm.Framework.Execution;
    using QuantConnect.Algorithm.Framework.Risk;
    using QuantConnect.Parameters;
    using QuantConnect.Benchmarks;
    using QuantConnect.Brokerages;
    using QuantConnect.Util;
    using QuantConnect.Interfaces;
    using QuantConnect.Algorithm;
    using QuantConnect.Indicators;
    using QuantConnect.Data;
    using QuantConnect.Data.Consolidators;
    using QuantConnect.Data.Custom;
    using QuantConnect.DataSource;
    using QuantConnect.Data.Fundamental;
    using QuantConnect.Data.Market;
    using QuantConnect.Data.UniverseSelection;
    using QuantConnect.Notifications;
    using QuantConnect.Orders;
    using QuantConnect.Orders.Fees;
    using QuantConnect.Orders.Fills;
    using QuantConnect.Orders.Slippage;
    using QuantConnect.Scheduling;
    using QuantConnect.Securities;
    using QuantConnect.Securities.Equity;
    using QuantConnect.Securities.Future;
    using QuantConnect.Securities.Option;
    using QuantConnect.Securities.Forex;
    using QuantConnect.Securities.Crypto;
    using QuantConnect.Securities.Interfaces;
    using QuantConnect.Storage;
    using QuantConnect.Data.Custom.AlphaStreams;
    using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm;
    using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm;
    using MathNet.Numerics;
    using MathNet.Numerics.LinearAlgebra;
#endregion

//Copied from this forum:
//href https://www.quantconnect.com/forum/discussion/695/adjusted-slope--exponential-slope----annualized-slope--r-squuared--adjusted-slope/p1

namespace QuantConnect.Algorithm.CSharp.Helpers
{
    public class AnnualizedExponentialSlopeIndicator : WindowIndicator<IndicatorDataPoint>
    {
        /// <summary>
        /// Array representing the time.
        /// </summary>
        private readonly double[] t;

        public AnnualizedExponentialSlopeIndicator(int period)
            : base("AESI(" + period + ")", period)
        {
            t = Vector<double>.Build.Dense(period, i => i + 1).ToArray();
        }

        public AnnualizedExponentialSlopeIndicator(string name, int period)
            : base(name, period)
        {
            t = Vector<double>.Build.Dense(period, i => i + 1).ToArray();
        }
        
        protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint input)
        {
            // Until the window is ready, the indicator returns the input value.
            if (window.Samples <= window.Size) return 0m;

            // Sort the window by time, convert the observations to double and transform it to an array
            var series = window
                .OrderBy(i => i.Time)
                .Select(i => Convert.ToDouble(Math.Log(Convert.ToDouble(i.Value))))
                .ToArray();
            // Fit OLS
            // solves y=a + b*x via linear regression
            // http://numerics.mathdotnet.com/Regression.html
            var ols = Fit.Line(x: t, y: series);
            var intercept = ols.Item1;
            var slope = ols.Item2;

            // compute rsquared
            var rsquared = GoodnessOfFit.RSquared(t.Select(x => intercept + slope * x), series);

            // anything this small can be viewed as flat
            if (double.IsNaN(slope) || Math.Abs(slope) < 1e-25) return 0m;

            // trading days per year for us equities
            const int dayCount = 252;

            // annualize dy/dt
            var annualSlope = ((Math.Pow(Math.Exp(slope), dayCount)) - 1) * 100;

            // scale with rsquared
            annualSlope = annualSlope * rsquared;

            if (annualSlope >= (double)decimal.MaxValue || annualSlope <= (double)decimal.MinValue)
            {
                annualSlope = 0;
            }
            return Convert.ToDecimal(annualSlope);
        }
    }
}
#region imports
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Globalization;
    using System.Drawing;
    using QuantConnect;
    using QuantConnect.Algorithm.Framework;
    using QuantConnect.Algorithm.Framework.Selection;
    using QuantConnect.Algorithm.Framework.Alphas;
    using QuantConnect.Algorithm.Framework.Portfolio;
    using QuantConnect.Algorithm.Framework.Execution;
    using QuantConnect.Algorithm.Framework.Risk;
    using QuantConnect.Parameters;
    using QuantConnect.Benchmarks;
    using QuantConnect.Brokerages;
    using QuantConnect.Util;
    using QuantConnect.Interfaces;
    using QuantConnect.Algorithm;
    using QuantConnect.Indicators;
    using QuantConnect.Data;
    using QuantConnect.Data.Consolidators;
    using QuantConnect.Data.Custom;
    using QuantConnect.DataSource;
    using QuantConnect.Data.Fundamental;
    using QuantConnect.Data.Market;
    using QuantConnect.Data.UniverseSelection;
    using QuantConnect.Notifications;
    using QuantConnect.Orders;
    using QuantConnect.Orders.Fees;
    using QuantConnect.Orders.Fills;
    using QuantConnect.Orders.Slippage;
    using QuantConnect.Scheduling;
    using QuantConnect.Securities;
    using QuantConnect.Securities.Equity;
    using QuantConnect.Securities.Future;
    using QuantConnect.Securities.Option;
    using QuantConnect.Securities.Forex;
    using QuantConnect.Securities.Crypto;
    using QuantConnect.Securities.Interfaces;
    using QuantConnect.Storage;
    using QuantConnect.Data.Custom.AlphaStreams;
    using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm;
    using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm;
#endregion



//Copied from this forum:
//href https://www.quantconnect.com/forum/discussion/695/adjusted-slope--exponential-slope----annualized-slope--r-squuared--adjusted-slope/p1

namespace QuantConnect.Algorithm.CSharp.Helpers
{
    public class CustomMomentumIndicator : TradeBarIndicator
    {
        private Symbol _symbol;
        private int _windowSize;
        public readonly AnnualizedExponentialSlopeIndicator AnnualizedSlope;
        public readonly ExponentialMovingAverage MovingAverage;
        public readonly GapIndicator Gap;
        public readonly AverageTrueRange Atr;

        public CustomMomentumIndicator(Symbol symbol, int annualizedSlopeWindow, int movingAverageWindow, int gapWindow, int atrWindow) : base($"CMI({symbol}, {annualizedSlopeWindow}, {movingAverageWindow}, {gapWindow})")
        {
            _symbol = symbol;
            AnnualizedSlope = new AnnualizedExponentialSlopeIndicator(annualizedSlopeWindow);
            MovingAverage = new ExponentialMovingAverage(movingAverageWindow);
            Gap = new GapIndicator(gapWindow);
            Atr = new AverageTrueRange(atrWindow);

            _windowSize = (new int[] { movingAverageWindow, annualizedSlopeWindow, gapWindow, atrWindow }).Max();
        }
        public Symbol Symbol { get { return _symbol; } }

        public override void Reset()
        {
            AnnualizedSlope.Reset();
            MovingAverage.Reset();
            Gap.Reset();
            Atr.Reset();
            base.Reset();
        }

        protected override decimal ComputeNextValue(TradeBar input)
        {
            AnnualizedSlope.Update(input.EndTime, input.Value);
            MovingAverage.Update(input.EndTime, input.Value);
            Gap.Update(input.EndTime, input.Value);
            Atr.Update(input);

            return AnnualizedSlope;
        }
        /// <summary>
        /// Are the indicators ready to be used?
        /// </summary>
        public override bool IsReady
        {
            get { return AnnualizedSlope.IsReady && MovingAverage.IsReady && Gap.IsReady && Atr.IsReady; }
        }
        /// <summary>
        /// Returns the Window of the indicator required to warm up indicator
        /// </summary>
        public int Window
        {
            get {return _windowSize;}
        }
        public new string ToDetailedString()
        {
            return $"Symbol:{_symbol} Slope:{AnnualizedSlope.ToDetailedString()} Average:{MovingAverage.ToDetailedString()} Gap:{Gap.ToDetailedString()} Atr:{Atr.ToDetailedString()} IsReady:{IsReady}";
        }
    }
}
#region imports
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Globalization;
    using System.Drawing;
    using QuantConnect;
    using QuantConnect.Algorithm.Framework;
    using QuantConnect.Algorithm.Framework.Selection;
    using QuantConnect.Algorithm.Framework.Alphas;
    using QuantConnect.Algorithm.Framework.Portfolio;
    using QuantConnect.Algorithm.Framework.Execution;
    using QuantConnect.Algorithm.Framework.Risk;
    using QuantConnect.Parameters;
    using QuantConnect.Benchmarks;
    using QuantConnect.Brokerages;
    using QuantConnect.Util;
    using QuantConnect.Interfaces;
    using QuantConnect.Algorithm;
    using QuantConnect.Indicators;
    using QuantConnect.Data;
    using QuantConnect.Data.Consolidators;
    using QuantConnect.Data.Custom;
    using QuantConnect.DataSource;
    using QuantConnect.Data.Fundamental;
    using QuantConnect.Data.Market;
    using QuantConnect.Data.UniverseSelection;
    using QuantConnect.Notifications;
    using QuantConnect.Orders;
    using QuantConnect.Orders.Fees;
    using QuantConnect.Orders.Fills;
    using QuantConnect.Orders.Slippage;
    using QuantConnect.Scheduling;
    using QuantConnect.Securities;
    using QuantConnect.Securities.Equity;
    using QuantConnect.Securities.Future;
    using QuantConnect.Securities.Option;
    using QuantConnect.Securities.Forex;
    using QuantConnect.Securities.Crypto;
    using QuantConnect.Securities.Interfaces;
    using QuantConnect.Storage;
    using QuantConnect.Data.Custom.AlphaStreams;
    using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm;
    using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm;
    using MathNet.Numerics;
    using MathNet.Numerics.Statistics;
#endregion



/// <summary>
///  Indicator to indicate the percentage (0.10 = 10%) of which a security gapped over the last period;
/// </summary>
namespace QuantConnect.Algorithm.CSharp.Helpers
{
    public class GapIndicator : WindowIndicator<IndicatorDataPoint>
    {
        public GapIndicator(int period)
            : base("GAP(" + period + ")", period)
        {
        }

        public GapIndicator(string name, int period)
            : base(name, period)
        {
        }
        public override bool IsReady
        {
            get { return Samples >= Period; }
        }

        protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint input)
        {
            if (window.Count < 3) return 0m;

            var diff = new double[window.Count];

            // load input data for regression
            for (int i = 0; i < window.Count - 1; i++)
            {
                diff[i] = (double)((window[i + 1] - window[i]) / (window[i] == 0 ? 1 : window[i].Value));
            }
            return (decimal) diff.MaximumAbsolute();
        }
    }
}
#region imports
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Globalization;
    using System.Drawing;
    using QuantConnect;
    using QuantConnect.Algorithm.Framework;
    using QuantConnect.Algorithm.Framework.Selection;
    using QuantConnect.Algorithm.Framework.Alphas;
    using QuantConnect.Algorithm.Framework.Portfolio;
    using QuantConnect.Algorithm.Framework.Execution;
    using QuantConnect.Algorithm.Framework.Risk;
    using QuantConnect.Parameters;
    using QuantConnect.Benchmarks;
    using QuantConnect.Brokerages;
    using QuantConnect.Util;
    using QuantConnect.Interfaces;
    using QuantConnect.Algorithm;
    using QuantConnect.Indicators;
    using QuantConnect.Data;
    using QuantConnect.Data.Consolidators;
    using QuantConnect.Data.Custom;
    using QuantConnect.DataSource;
    using QuantConnect.Data.Fundamental;
    using QuantConnect.Data.Market;
    using QuantConnect.Data.UniverseSelection;
    using QuantConnect.Notifications;
    using QuantConnect.Orders;
    using QuantConnect.Orders.Fees;
    using QuantConnect.Orders.Fills;
    using QuantConnect.Orders.Slippage;
    using QuantConnect.Scheduling;
    using QuantConnect.Securities;
    using QuantConnect.Securities.Equity;
    using QuantConnect.Securities.Future;
    using QuantConnect.Securities.Option;
    using QuantConnect.Securities.Forex;
    using QuantConnect.Securities.Crypto;
    using QuantConnect.Securities.Interfaces;
    using QuantConnect.Storage;
    using QuantConnect.Data.Custom.AlphaStreams;
    using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm;
    using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm;
#endregion

namespace QuantConnect.Algorithm.CSharp
{
    public class MarketRegimeFilter
    {
        private SimpleMovingAverage _spyMovingAverage200;

        private RateOfChange _bilROC21;
        private RateOfChange _iefROC21;

        public MarketRegimeFilter(SimpleMovingAverage spyMovingAverage200, RateOfChange bilROC21, RateOfChange iefROC21)
        {
            _spyMovingAverage200 = spyMovingAverage200;
            _bilROC21 = bilROC21;
            _iefROC21 = iefROC21;
        }
        
        // Checks if the SPY is over its 200d SMA
        public bool RiskON(decimal spyPrice){
            
            bool riskonSPY = false;

            if (spyPrice > _spyMovingAverage200){
                riskonSPY = true;
            }

            if (riskonSPY)
                return true;
            else
                return false;
        }

        // Checks if the iefROC21 is over its bilROC21 and is over 0.
        public bool TradeBonds(){
            
            bool tradeBonds = false;

            if (_iefROC21 > _bilROC21 && _iefROC21 > 0){
                tradeBonds = true;
            }

            if (tradeBonds)
                return true;
            else
                return false;
        }
    }
}
#region imports
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Globalization;
    using System.Drawing;
    using QuantConnect;
    using QuantConnect.Algorithm.Framework;
    using QuantConnect.Algorithm.Framework.Selection;
    using QuantConnect.Algorithm.Framework.Alphas;
    using QuantConnect.Algorithm.Framework.Portfolio;
    using QuantConnect.Algorithm.Framework.Execution;
    using QuantConnect.Algorithm.Framework.Risk;
    using QuantConnect.Parameters;
    using QuantConnect.Benchmarks;
    using QuantConnect.Brokerages;
    using QuantConnect.Util;
    using QuantConnect.Interfaces;
    using QuantConnect.Algorithm;
    using QuantConnect.Algorithm.CSharp.Helpers;
    using QuantConnect.Indicators;
    using QuantConnect.Data;
    using QuantConnect.Data.Consolidators;
    using QuantConnect.Data.Custom;
    using QuantConnect.DataSource;
    using QuantConnect.Data.Fundamental;
    using QuantConnect.Data.Market;
    using QuantConnect.Data.UniverseSelection;
    using QuantConnect.Notifications;
    using QuantConnect.Orders;
    using QuantConnect.Orders.Fees;
    using QuantConnect.Orders.Fills;
    using QuantConnect.Orders.Slippage;
    using QuantConnect.Scheduling;
    using QuantConnect.Securities;
    using QuantConnect.Securities.Equity;
    using QuantConnect.Securities.Future;
    using QuantConnect.Securities.Option;
    using QuantConnect.Securities.Forex;
    using QuantConnect.Securities.Crypto;
    using QuantConnect.Securities.Interfaces;
    using QuantConnect.Storage;
    using QuantConnect.Data.Custom.AlphaStreams;
    using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm;
    using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm;
#endregion

namespace QuantConnect.Algorithm.CSharp
{
    public class StocksOnTheMoveAlgorithm : QCAlgorithm
    {
        ///Momentum is calculated based on 90 past days annualized exponential regression slope;
        private int _annualizedSlopeWindow = 90;

        /// If the stock is below its 125 days moving average, sell it;
        private int _movingAverageWindow = 125;

        /// ATR window
        private int _atrWindow = 20;

        /// Daily Risk of each trade on the portfolio (0,5%)
        private const decimal RiskPerContractOnPortfolio = 0.015m;

        /// Total number of security symbols in the Universe
        private static int _universeSelectMaxStocks = 500;

        /// Holds our security custom indicators per symbol
        private Dictionary<Symbol, CustomMomentumIndicator> _customIndicators = new Dictionary<QuantConnect.Symbol, CustomMomentumIndicator>(_universeSelectMaxStocks);

        // If the SP500 is above the 200 days moving average we buy stocks, otherwise not; 
        private MarketRegimeFilter _marketRegimeFilter;

        //If the stock is not in the top 100/ 20% ranking, sell it;
        private int _topNStockOfSp500 = 20;

        ///If the stock gapped > 15% over period (100d) Do not buy: Maximum Gap in percentage
        private decimal _maximumGap = 0.15m;
        private int _gapWindow = 100;

        ///Minimum annualized slope before buying stock.
        private decimal _minimumAnnualizedSlope = 0m;

        ///Twice a month rebalance the positions sizes (risk);
        private bool _rebalanceWeek = false;
        public bool RebalanceWeek { get { return _rebalanceWeek; } }

        ///Broker fee to take into account to check if Cash is avalaible
        private const decimal BrokerFee = 0.005m;

        // Debug parameters
        private bool _isLogging = false;
        /// Is debugging set?
        public bool IsLooging { get { return _isLogging; } }
        public new void Log(string message)
        {
            if (IsLooging)
                base.Log(message);
        }


        /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm.
        public override void Initialize()
        {
            _isLogging = false;
            //Set trading window
            SetStartDate(2021, 1, 1);
            SetEndDate(DateTime.Now);

            //Set cash and brokermodel
            SetCash(100000);
            SetBrokerageModel(BrokerageName.QuantConnectBrokerage, AccountType.Margin);

            //Set Benchmark
            Security security = AddEquity("SPY", Resolution.Daily);
            SetBenchmark(security.Symbol);
            security = AddEquity("BIL", Resolution.Daily);
            security = AddEquity("IEF", Resolution.Daily);

            // Set the MarketRegimeFilter
            SimpleMovingAverage spyMovingAverage100 = SMA("SPY", 10, Resolution.Daily);
                        // Set Bonds ROC
            RateOfChange bilROC21 = ROC("BIL",21,Resolution.Daily);
            RateOfChange iefROC21 = ROC("IEF",21,Resolution.Daily);


            //Warm up SMA
            SetWarmUp(100);
            IEnumerable<TradeBar> history = History("SPY", 10, Resolution.Daily);
            foreach (TradeBar tradeBar in history)
            {
                spyMovingAverage100.Update(tradeBar.EndTime, tradeBar.Close);
            }
            history = History("BIL", 21, Resolution.Daily);
            foreach (TradeBar tradeBar in history)
            {
                bilROC21.Update(tradeBar.EndTime, tradeBar.Close);
            }
            history = History("IEF", 21, Resolution.Daily);
            foreach (TradeBar tradeBar in history)
            {
                iefROC21.Update(tradeBar.EndTime, tradeBar.Close);
            }

            _marketRegimeFilter = new MarketRegimeFilter(spyMovingAverage100,bilROC21,iefROC21);

            //Setup universe based on ETF: https://www.quantconnect.com/docs#Universes
            UniverseSettings.Resolution = Resolution.Daily;
            AddUniverse(Universe.ETF("OEF", Market.USA, UniverseSettings));

            //Trade only on Thursday at opening after 1 minutes
            Schedule.On(DateRules.Every(DayOfWeek.Thursday),
                TimeRules.AfterMarketOpen("SPY", 1), ScheduledOnThursday1MinuteAfterMarketOpen);
        }

        // SECURITY RANKING, SELL, REBALANCE AND BUY
        private void ScheduledOnThursday1MinuteAfterMarketOpen()
        {
            if (IsWarmingUp) return;

            // First, we order by slope and we take top 20% ranked
            var sortedEquityListBySlope = _customIndicators.Where(x => x.Value.IsReady)
            .OrderByDescending(x => x.Value.AnnualizedSlope)
            .Take(_topNStockOfSp500)
            .ToList();
            // Second, we filter by minimum slope, above moving average and max gap
            sortedEquityListBySlope = sortedEquityListBySlope
            .Where(x => x.Value.AnnualizedSlope > _minimumAnnualizedSlope
                && Securities[x.Key].Price > x.Value.MovingAverage
                && x.Value.Gap < _maximumGap).ToList();

            //Sell if security is not in list
            foreach (var security in Portfolio.Values.Where(x => x.Invested))
            {
                var symbolHold = security.Symbol;
                if (!sortedEquityListBySlope.Exists(x => x.Value.Symbol == symbolHold))
                {
                    Liquidate(symbolHold);
                }
            }

            bool riskON = _marketRegimeFilter.RiskON(Securities["SPY"].Price);

            //Twice a month rebalance the positions sizes (risk);
            if (RebalanceWeek) {
                _rebalanceWeek = false;
                var risk = Portfolio.TotalPortfolioValue * RiskPerContractOnPortfolio;

                foreach (var security in Portfolio.Values.Where(x => x.Invested))
                {
                    var symbolHold = security.Symbol;
                    var quantityHold = security.Quantity;
                    var priceHold = Securities[symbolHold].Price;

                    foreach (var customIndicator in sortedEquityListBySlope.Where(x => x.Key == symbolHold))
                    {
                        var numberStocks = (int)Math.Floor(risk / customIndicator.Value.Atr);
                        if (Math.Abs(quantityHold - numberStocks) > 0 && quantityHold > 1)
                        {
                            // Sell or Buy the stocks diff
                            if (quantityHold > numberStocks)
                            {
                                Sell(symbolHold, (quantityHold - numberStocks));
                            }
                            else
                            {
                                //If the MarketRegimeIndicator indicator is RiskON, we buy stocks, otherwise not;
                                if (riskON)
                                {
                                    if (quantityHold < numberStocks)
                                    {
                                        // free cash invested in bonds
                                        if (Portfolio.ContainsKey("IEF"))
                                            if (Portfolio["IEF"].Quantity > 0)
                                                Liquidate("IEF");

                                        decimal portfolioCashBalance = Portfolio.TotalPortfolioValue - Portfolio.TotalHoldingsValue;
                                        
                                        // Do we have cash to trade?
                                        if (portfolioCashBalance > ((numberStocks - quantityHold) * priceHold + (numberStocks - quantityHold) * priceHold * BrokerFee))
                                        {
                                            Order(symbolHold, (numberStocks - quantityHold));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else { _rebalanceWeek = true; }

            //If the MarketRegimeIndicator indicator is RiskON, we buy stocks, otherwise not;
            if (riskON)
            {
                foreach (var customIndicatorItem in sortedEquityListBySlope)
                {
                    CustomMomentumIndicator customIndicator = customIndicatorItem.Value;
                    var symbol = customIndicator.Symbol;
                    var inPortfolio = false;
                    foreach (var security in Portfolio.Values.Where(x => x.Invested))
                    {
                        if (security.Symbol == symbol)
                        {
                            inPortfolio = true;
                        }
                    }
                    if (!inPortfolio)
                    {
                        var risk = Portfolio.TotalPortfolioValue * RiskPerContractOnPortfolio;
                        var numberStocks = (int)Math.Floor(risk / customIndicator.Atr);
                        var price = Securities[symbol].Price;
                        if (numberStocks > 0)
                        {
                            // free cash invested in bonds
                            if (Portfolio.ContainsKey("IEF"))
                                if (Portfolio["IEF"].Quantity > 0) 
                                    Liquidate("IEF");
                            decimal portfolioCashBalance = Portfolio.TotalPortfolioValue - Portfolio.TotalHoldingsValue;
                            // Do we have cash to trade?
                            if (portfolioCashBalance > (numberStocks * price + (numberStocks * price) * BrokerFee))
                            {
                                Order(symbol, numberStocks);
                            }
                        }
                    }
                }
            }

            // Buy Bonds with remaing cash
            if (_marketRegimeFilter.TradeBonds()){
                if (Securities["IEF"].Price > 0){
                    int numberStocks = (int) Math.Floor((Portfolio.TotalPortfolioValue - Portfolio.TotalHoldingsValue  - (Portfolio.TotalPortfolioValue - Portfolio.TotalHoldingsValue)*BrokerFee) / Securities["IEF"].Price);
                    if (numberStocks > 0) { 
                        Order("IEF", numberStocks);
                    }
                }
            }
            else {
                // we free cash invested in bonds
                if (Portfolio.ContainsKey("IEF")){
                    if (Portfolio["IEF"].Quantity > 0) {
                        Liquidate("IEF");
                    }
                }
            }
        }

        // creating custom indicators for each symbol
        public override void OnSecuritiesChanged(SecurityChanges changes)
        {
            if (changes.AddedSecurities.Count > 0)
            {
                    foreach (Security security in changes.AddedSecurities)
                {
                    if (!_customIndicators.ContainsKey(security.Symbol) && ((security.Symbol.Value != "SPY") || (security.Symbol.Value != "IEF") || (security.Symbol.Value != "BIL")))
                    {
                        var customIndicator = new CustomMomentumIndicator(security.Symbol, _annualizedSlopeWindow, _movingAverageWindow, _gapWindow, _atrWindow);
                        //warm up indicator
                        var history = History(security.Symbol, customIndicator.Window, Resolution.Daily);
                        foreach (TradeBar tradeBar in history)
                            customIndicator.Update(tradeBar);

                        _customIndicators.Add(security.Symbol, customIndicator);
                        RegisterIndicator(security.Symbol, customIndicator, Resolution.Daily);
                    }
                }
            }
            if (changes.RemovedSecurities.Count > 0)
            {
                foreach (var security in changes.RemovedSecurities)
                {
                    if (security.Invested)
                    {
                        Liquidate(security.Symbol);
                    }
                    if (_customIndicators.ContainsKey(security.Symbol))
                    {
                        _customIndicators.Remove(security.Symbol);
                    }
                }
            }
        }
    }
}