Overall Statistics
Total Trades
17
Average Win
20.89%
Average Loss
-5.65%
Compounding Annual Return
8.257%
Drawdown
18.200%
Expectancy
1.936
Net Profit
143.845%
Sharpe Ratio
0.758
Loss Rate
38%
Win Rate
62%
Profit-Loss Ratio
3.70
Alpha
0.054
Beta
0.327
Annual Standard Deviation
0.112
Annual Variance
0.013
Information Ratio
-0.061
Tracking Error
0.161
Treynor Ratio
0.26
Total Fees
$100.45
using System;
using System.Linq;
using QuantConnect.Indicators;
using QuantConnect.Models;
using QuantConnect.Data.Consolidators;

namespace QuantConnect.Algorithm.Examples
{
    /// <summary>
    /// 
    /// QuantConnect University: EMA + SMA Cross
    ///
    /// In this example we look at the canonical 15/30 day moving average cross. This algorithm
    /// will go long when the 15 crosses above the 30 and will liquidate when the 15 crosses
    /// back below the 30.
    /// </summary>
    /// A   AAOI   ADBE   AMH   ANTM   APO   ARI   ASB   AXP   BAC   BEAV   BG   CBG   
    ///CCL   CFG   CIM   COL   COMM   CTRP   CY   DGX   
    ///DK   DNKN   ETE   ETN   FOXA   FTV   GD   GEO   GMED   GNTX   GS   HBAN   HCA   HD   HUN   ILG   INVA   JBL   JPM   KBH   KEYS   KS   KT   LITE   LNC   LUK   LW   MA   MBLY   MEOH   MFC   MMC   MO   MRVL   MU   NCLH   NTRS   OCLR   OGE   ORCL   OSUR   PENN   PGNX   PH   PM   PTC   RLGY   RSG   RY   SEAS   SHOP   SKX   STI   STL   STX   TIME   TKR   TMHC   TRUE   TSLA   UNH   UNVR   VEEV   VIAV   WDC   WFC   WMGI   WNR   XXIA   ZION 
    /// BABA   BAC   BBY   BGCP   BOFI   BRCD   BX   C   CAKE   CCL   CFG   CHS   CIM  
    ///CMA   CMI   CRUS   CSCO   CXW   CY   DAN   DE   DGX   ETN   FB   FOX   FOXA   FTV  
    ///GD   GS   HBAN   HCA   HLT   HW   INVA   JD   JPM   KBH   KEM   KEY   KKR   LAZ   LITE   
    ///LNC   LUK   MAR   MASI   MBLY   MBT   MO   MOMO   MRVL   MS   MTB   MTZ   MU   NFLX  
    ///NTES   NTRS   NVDA   OZRK   PENN   PH   PM   PNC   PTC   REN   RF   RJF   RY   SCHW   
    ///SEAS   SHOP   SLM   STL   STLD   SYMC   TEL   TIME   TSLA   UNH   URI   USB   VEEV   
    ///VIAV   VLY   VMW   WDC   WMGI   WYNN   X   XPO   ZION 
    
    public class QCUMovingAverageCross : QCAlgorithm
    {
        private const string Symbol = "SPY";

        private ExponentialMovingAverage fast;
        private SimpleMovingAverage slow;
        private SimpleMovingAverage[] ribbon;

        public override void Initialize()
        {
            // set up our analysis span
            SetStartDate(2006, 01, 01);
            SetEndDate(2017, 03, 26 );

            // request SPY data with Hour resolution
            AddSecurity(SecurityType.Equity, Symbol, Resolution.Minute);

            // create a 89 day exponential moving average
            fast = EMA(Symbol, 89, Resolution.Daily); 
 
            // create a 100 day exponential moving average
            slow = SMA(Symbol, 140, Resolution.Daily);

            // the following lines produce a simple moving average ribbon, this isn't
            // actually used in the algorithm's logic, but shows how easy it is to make
            // indicators and plot them!
            
            // note how we can easily define these indicators to receive hourly data
            int ribbonCount = 7;
            int ribbonInterval = 15*8;
            ribbon = new SimpleMovingAverage[ribbonCount];
            
            for(int i = 0; i < ribbonCount; i++) 
            {
                ribbon[i] = SMA(Symbol, (i + 1)*ribbonInterval, Resolution.Hour);
            }
        }

        private DateTime previous;
        public void OnData(TradeBars data)
        {
            // a couple things to notice in this method:
            //  1. We never need to 'update' our indicators with the data, the engine takes care of this for us
            //  2. We can use indicators directly in math expressions
            //  3. We can easily plot many indicators at the same time

            // wait for our fast ema to fully initialize
            if (!fast.IsReady) return;

            // only once per day
            if (previous.Date == data.Time.Date) return;

            // define a small tolerance on our checks to avoid bouncing
            const decimal tolerance = 0.00015m;
            var holdings = Portfolio[Symbol].Quantity;

           

//////////////////////////
// we only want to go long if we're currently  flat
            if (holdings == 0 )
            {
                // if the slow is greater than the fast, we'll go long
                if (fast > slow * (1 + tolerance))
                {
                    Log("BUY  >> " + Securities[Symbol].Price);
                    SetHoldings(Symbol, 1.0);
                }
            }

            // we only want to liquidate if we're currently short
            // if the fast is less than the slow we'll liquidate our long
            if (holdings > 0 && fast <= slow)
            {
                Log("SELL >> " + Securities[Symbol].Price);
                Liquidate(Symbol);    
            }
            Plot(Symbol, "Price", data[Symbol].Price);
            Plot("Ribbon", "Price", data[Symbol].Price);
            
            // easily plot indicators, the series name will be the name of the indicator
            Plot(Symbol, fast, slow);
            Plot("Ribbon", ribbon);

            previous = data.Time;
        }
    }
}