Overall Statistics
namespace QuantConnect
{
    public class EMACrossLongAlgorithm : QCAlgorithm
    {
        // There's no need to create another instance of algorithm. We are already in the algorithm.
        // So we create all variables we need here.
        RollingWindow<TradeBar> History = new RollingWindow<TradeBar>(4);
        RollingWindow<decimal> _8EMAHistory = new RollingWindow<decimal>(3);
        RollingWindow<decimal> _8SMAHistory = new RollingWindow<decimal>(3);
        RollingWindow<decimal> _20EMAHistory = new RollingWindow<decimal>(3);
        
        public decimal AveragePriceSelector(BaseData data)
        {
            decimal emaMid = (_highEMA + _lowEMA) / 2;
            return emaMid;
        }

        string symbol = "PCLN";

        ExponentialMovingAverage _8EMA;
        SimpleMovingAverage _8SMA;
        ExponentialMovingAverage _20EMA;
        ExponentialMovingAverage _highEMA;
        ExponentialMovingAverage _lowEMA;
        RateOfChange roc;

        int fastMAPeriod = 8;
        int slowEmaPeriod = 20;

        //algorithm PnL settings
        decimal targetProfit = 0.001m; // 0.1% target
        decimal maximumLoss = 0.00041m; // 0.041% stop

        // Initialize function ----------------------------------------------------------------------------
        public override void Initialize() // backtest kickstart
        {
            SetStartDate(2012, 3, 12);
            SetEndDate(2015, 7, 28);
            SetCash(100000);
            AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);

            var fifteenConsolidator = ResolveConsolidator(symbol, TimeSpan.FromMinutes(15));

            _8EMA = new ExponentialMovingAverage(fastMAPeriod);
            _8SMA = new SimpleMovingAverage(fastMAPeriod);
            _20EMA = new ExponentialMovingAverage(slowEmaPeriod);
            _highEMA = new ExponentialMovingAverage(14);
            _lowEMA = new ExponentialMovingAverage(14);
            roc = new RateOfChange(18);

            RegisterIndicator(symbol, _8EMA, fifteenConsolidator, p => p.Value);
            RegisterIndicator(symbol, _8SMA, fifteenConsolidator, p => p.Value);
            RegisterIndicator(symbol, _20EMA, fifteenConsolidator, p => p.Value);
            RegisterIndicator(symbol, _highEMA, fifteenConsolidator, Field.High);
            RegisterIndicator(symbol, _lowEMA, fifteenConsolidator, Field.Low);
            RegisterIndicator(symbol, roc, fifteenConsolidator, AveragePriceSelector);

            fifteenConsolidator.DataConsolidated += (s, e) => OnDataFifteen((TradeBar)e); // ASK about this line and why it's like this
            PlotIndicator(symbol, _8EMA);
            PlotIndicator(symbol, _8SMA);
            PlotIndicator(symbol, _20EMA);
        }

        public bool MinimumProfitAchieved
        {
            get { return (Portfolio.TotalUnrealizedProfit / Portfolio.Cash) >= targetProfit; }
        }

        public bool MaximumLossAchieved
        {
            get { return (Portfolio.TotalUnrealizedProfit / Portfolio.Cash) <= -maximumLoss; }
        }

        // 15m timeframe handler -----------------------------------------------------------------------------

        private void OnDataFifteen(TradeBar consolidated) // OnData apparently not necessary, look up difference between TradeBars & TradeBar type
        {
            History.Add(consolidated);
            _8EMAHistory.Add(_8EMA);
            _8SMAHistory.Add(_8SMA);
            _20EMAHistory.Add(_20EMA);

            if (_8EMA.IsReady == false 
                || _8SMA.IsReady == false
                || _20EMA.IsReady == false
                || History.Count < 4
                || _8EMAHistory.Count < 3
                || _8SMAHistory.Count < 3
                || _20EMAHistory.Count < 3) // important criterion
                return;

            decimal profit = Portfolio.TotalUnrealizedProfit;
            decimal price = consolidated.Close;
            decimal high = consolidated.High;
            int holdings = Portfolio[symbol].Quantity;
            decimal HLCavg = (consolidated.High + consolidated.Low + consolidated.Close) / 3;
            decimal percentage = 0;

            //Algorithm Entry Section:==========================================
            //Entry Scenario Criteria ==========================================


            // CM Check - Scenario 1: 8EMA Crossover 20EMA

            // I replaced 'while' with 'if'. Tradebars will be coming, just check every tradebar.
	        if (Math.Abs(roc) > (decimal)0.0009) // Holdings will never be < 1. I think you meant 0.
	        {
	            if (holdings <= 0) // CONSOLIDATION CLAUSE CHECK
	            {
	                //Case 1: Standard EMA Crossover Quantitative Edge Trigger
	                if (_8EMA >= _20EMA)
	                {
	                    // Most recent bar is History[0]. So make sure this is what you meant.
	                    if (History[0].Close > History[1].Low || History[1].Close > History[2].Low)
	                    {
	                        if (HLCavg > History[0].Close || HLCavg > History[1].Close)
	                        {
	                            //percentage = 1.5m; 
	                            // Holdings should have values between -1 and 1. -- 1.5 is not correct.
	                            // if you meant 1.5%, then use 0.015 for holdings value. But let's go full size.
	                            percentage = 0.95m;
	                            SetHoldings(symbol, percentage);
	                        }
	                    }
	                }
	                
	                //Case 2: EMA/SMA Crossover Quantitative Edge Trigger | NEEDS REVISION
	                if (_8EMA < _20EMA)
		            {
		            	if (_8EMA >= _8SMA &&
		            		_8EMAHistory[0] > _8SMAHistory[0] &&
		            		_8EMAHistory[1] > _8SMAHistory[1])
		            	{
			            	if (History[0].Close > History[1].Low || History[1].Close > History[2].Low)
			            	{
			            		if (HLCavg > History[0].Close || HLCavg > History[1].Close)
			            		{
			            			percentage = 0.95m;
			            			SetHoldings(symbol, percentage);
			            		}
			            	}
		            	}
		            }
	          	}
	        }

            //Algorithm Exit Section:===========================================

            if (MinimumProfitAchieved)
            {
                //Order(symbol, -holdings);
                // Just use Liquidate
                // Or, equivalently SetHoldings(0). Or, close long and open short with SetHoldings(-1).
                Liquidate(symbol);
            }

            if (MaximumLossAchieved)
            {
                //Order(symbol, -holdings);
                Liquidate(symbol);
            }
        }
    }
}