Overall Statistics
Total Trades
12898
Average Win
0.17%
Average Loss
-0.16%
Compounding Annual Return
7267639.429%
Drawdown
2.800%
Expectancy
0.578
Net Profit
15835844.526%
Sharpe Ratio
24.515
Loss Rate
24%
Win Rate
76%
Profit-Loss Ratio
1.07
Alpha
11.088
Beta
0.496
Annual Standard Deviation
0.455
Annual Variance
0.207
Information Ratio
24.245
Tracking Error
0.455
Treynor Ratio
22.461
using System;
using System.Collections;
using System.Collections.Generic;
namespace QuantConnect
{
    
    public class emovingaverage
    {
        private int _period;
        private decimal _EMA;
        private int _samples;
        
        public emovingaverage(int period) {
            this._period = period;
            this._samples = 0;
        }
        
        public void AddSample(decimal price) {
            
            if (_samples == 0) {
                _EMA = price;
            } else {
                _EMA = (1m / _period) * price + ((_period - 1m) / _period) * _EMA;
            }
            
            _samples++;
        }
        
        public decimal getEMA() {
            return _EMA;
        }
    }
}                        
using System;
using System.Collections;
using System.Collections.Generic;
namespace QuantConnect
{
    
    public class macd
    {
        
        private int _period_long;
        private int _period_short;
        private decimal _divergence;
        private emovingaverage ema_short;
        private emovingaverage ema_long;
        
        public macd(int period_long, int period_short) {
            _period_short = period_short;
            _period_long = period_long;
            ema_short = new emovingaverage(_period_short);
            ema_long = new emovingaverage(_period_long);
        }
        
        public void AddSample(decimal price) {
            ema_short.AddSample(price);
            ema_long.AddSample(price);
            _divergence = ema_long.getEMA() - ema_short.getEMA();
        }
        
        public decimal getDiv() {
            return _divergence;
        }
    }
}                        
//Import Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
namespace QuantConnect
{
    //Create SMA class
    public class smovingaverage
    {
        //Declare Variables
        private int _period;
        private int _slope_period;
        private decimal _SMA;
        private decimal _SMASlope;
        private decimal[] _SMAHistory;
        private decimal[] _prices;
        private int _samples;
        
        //Constructor
        public smovingaverage(int period, int slope_period) {
            this._period = period;
            this._slope_period = slope_period;
            this._samples = 0;
            this._prices = new decimal[_period];
            this._SMAHistory = new decimal[_slope_period];
        }
        
        //Adds a sample to SMA and calculates new values
        public void AddSample(decimal price) {
            
            //If SMA is not full
            if (_samples < _period) {
                _prices[_samples] = price;
                _SMA = 0;
                for(int i = 0; i < _samples; i++) {
                    _SMA = _SMA + _prices[i];
                }
                _SMA = _SMA / (_samples + 1);
                
            }
            //SMA is full, must shift values
            else if (_samples >= _period) {
                _SMA = _SMA - (_prices[0] / _period) + (price / _period);
                for (int i = 0; i < _period - 1 ; i++) {
                    _prices[i] = _prices[i+1];
                }
                _prices[_period - 1] = price;
            }
            
            //SMA change before full is set to 0 to avoid erratic behavior
            if (_samples < _slope_period) {
                
                _SMAHistory[_samples] = _SMA;
                _SMASlope = 0;
                
            }
            //SMA change over time calculated
            else if (_samples >= _slope_period) {
                
                _SMASlope = (_SMA - _SMAHistory[_slope_period - 1]) / _slope_period;
                
                for (int i = 0; i < _slope_period - 1 ; i++) {
                    _SMAHistory[i] = _SMAHistory[i+1];
                }
                _SMAHistory[_slope_period - 1] = _SMA;
            }
            
            _samples++;
        }
        
        public decimal getSMASlope() {
            return _SMASlope;
        }
        
        public decimal getSMA() {
            return _SMA;
        }
        
    }
}                        
using System;
using System.Collections;
using System.Collections.Generic;
namespace QuantConnect 
{   
    /*
    *   QuantConnect University: Full Basic Template:
    *
    *   The underlying QCAlgorithm class is full of helper methods which enable you to use QuantConnect.
    *   We have explained some of these here, but the full algorithm can be found at:
    *   https://github.com/QuantConnect/QCAlgorithm/blob/master/QuantConnect.Algorithm/QCAlgorithm.cs
    */
    public class MACD_Trader : QCAlgorithm
    {
        string symbol = "CMG";
        private int _bars;
        macd M = new macd(26,12);
        macd S = new macd(18,8);
        
        //Initialize the data and resolution you require for your strategy:
        public override void Initialize()
        {
			
			_bars = 0;
            //Start and End Date range for the backtest:
            SetStartDate(2014, 1, 1);
            SetEndDate(DateTime.Now.Date.AddDays(-1)); 
            
            //Cash allocation
            SetCash(25000);
            
            
            //Add as many securities as you like. All the data will be passed into the event handler:
            AddSecurity(SecurityType.Equity, symbol, Resolution.Second);
        }
        
        private int orderCount;
        private DateTime previous;
        //Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol.
        public void OnData(TradeBars data) 
        {   
            // "TradeBars" object holds many "TradeBar" objects: it is a dictionary indexed by the symbol:
            // 
            //  e.g.  data["MSFT"] data["GOOG"]
            
            decimal price = data[symbol].Close;
            int holdings = Portfolio[symbol].Quantity;
            
            _bars++;
            if (_bars < 55) return;
            if (previous.Date != data.Time.Date) {
                orderCount = 0;
            }
            
            if (orderCount > 97) {
                Liquidate();
                return;
            }
            
            if (holdings == 0 || holdings < 0) {
                if (M.getDiv() > 0) {
                    if(S.getDiv() > M.getDiv()) {
                        orderCount = orderCount + 1;
                        SetHoldings(symbol, 1.0);
                    }
                }
            } else if (holdings > 0) {
                if (S.getDiv() < 0) {
                    orderCount = orderCount + 1;
                    Liquidate(symbol);
                }
            }
            
            M.AddSample(price);
            S.AddSample(price);
            
            previous = data.Time;
        }
        
    }
}