Overall Statistics
using System;
using System.Collections;
using System.Collections.Generic; 
using System.Text;
using System.Linq;
using QuantConnect;
using QuantConnect.Models;

namespace QuantConnect.Indicator {
	
	public class ExponentialMovingAverage : QCAlgorithm {
		
		private int _period;
		private decimal _ema;
		//private int _samples;
		//private bool flag;
		//private Queue <decimal>_data = new Queue <decimal> ();
		
		public decimal EMA {
			get{ return _ema;}
		}
		
		/*public int Samples {
			get { return _samples; }
		}*/
		
		public decimal GetExpConst {
			get{ return (decimal) 2/(_period +1); }
		}
		
		public bool Ready {
			//get { return _data.Count >= _period; }
			get { return true; }
		}
		
		public ExponentialMovingAverage(int period, decimal initEma) {
			_period = period;
			_ema = initEma;
			//flag = false;
		}
		
		public decimal AddSample(decimal quote) {
			//_data.Enqueue(quote);
			//_samples++;

			/*if(_data.Count < _period) {
				return _data.Average();
			}
			else {
				if(!flag) {
					_ema = _data.Average();
					flag = true;
				}
				else {
					_ema = (1-GetExpConst) * _ema +GetExpConst * quote;
				}*/

				_ema = (1-GetExpConst) * _ema +GetExpConst * quote;
			//}
			
			return _ema;
		}
		
	}
}
using System;
using System.Collections;
using System.Collections.Generic; 
using System.Text;
using QuantConnect.Indicator;

namespace QuantConnect 
{
    using QuantConnect.Securities; 
    using QuantConnect.Models;
    
    public class QCUMovingAverageCross : QCAlgorithm, IAlgorithm {
        
        decimal price = 0;
        string symbol = "SPY";
        DateTime sampledToday = DateTime.Now;
        
        bool isRecession = false;
        bool wasRecession = false;
        int minDaysHeld = 60;
        int minDaysHeldShort = 15;
        DateTime earliestSellDate;
        DateTime earliestCoverDate;
        
        int shortQty;

        bool isFirstDay = true;
        
        ExponentialMovingAverage emaLong = new ExponentialMovingAverage(90, 68.37m);
        ExponentialMovingAverage ema365 = new ExponentialMovingAverage(365, 58.10m);
        
        public override void Initialize() {
            SetStartDate(1998, 01, 01);
            SetEndDate(2013, 12, 31);
            
            SetCash(100000);
            
            AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);
        }
        
        public void OnData(TradeBars data) {
            if (sampledToday.Date == data[symbol].Time.Date) return;
            
            if (isFirstDay) {
                isFirstDay = false;
                Order(symbol, (int)(Portfolio.Cash / data[symbol].Price));
            }
            
            price = Securities[symbol].Open;
            sampledToday = data[symbol].Time;
            
            // Plot("Custom Chart", symbol + " $", price);
            
            emaLong.AddSample(price);
            ema365.AddSample(price);
            
            Plot("Custom Chart", "EMA Long", emaLong.EMA);
            Plot("Custom Chart", "EMA 365", ema365.EMA);
            
            // Check for a recession
            if (emaLong.EMA < (ema365.EMA - 0.05m)) {
                isRecession = true;
            }
            else if (emaLong.EMA > (ema365.EMA + 0.05m)) {
                isRecession = false;
            }
            else {
                // Leave it the same...
            }
            
            if (isRecession) {
                if (!wasRecession) {
                    if (Portfolio.HoldStock) {
                        if (sampledToday.Date >= earliestSellDate.Date) {
                            Liquidate();
                            
                            Debug("-=[DEBUG][" + sampledToday.Date + "] Liquidated all holdings due to recession.");
                        }
                    }
                
                    shortQty = (int)((Portfolio.Cash / data[symbol].Price) * -1);
                    Order(symbol, shortQty);
                    
                    earliestCoverDate = sampledToday.Date.AddDays(minDaysHeldShort);
                    
                    wasRecession = true;
                    
                    Debug("-=[DEBUG][" + sampledToday.Date + "] Shorted SPY for " + shortQty);
                }
            }
            else if (!isRecession) {
                if (wasRecession) {
                    if ((Portfolio.HoldStock) && (sampledToday.Date >= earliestCoverDate.Date)) {
                        Order(symbol, (shortQty * -1));
                        
                        wasRecession = false;
                        
                        Debug("-=[DEBUG][" + sampledToday.Date + "] Bought to cover previous short sell.");
                    }
                }
                
                // Execute BUY order
                if (!Portfolio.HoldStock) {
                    int quantity = (int)(Portfolio.Cash / data[symbol].Price);
                    Order(symbol, quantity);
                    
                    earliestSellDate = sampledToday.Date.AddDays(minDaysHeld);
                    
                    Debug("-=[DEBUG][" + sampledToday.Date + "] Executed normal BUY order: " + quantity);
                }
            }
        }
    }
}