Overall Statistics
Total Trades
200
Average Win
1.78%
Average Loss
-0.08%
Compounding Annual Return
5.447%
Drawdown
9.300%
Expectancy
0.175
Net Profit
5.445%
Sharpe Ratio
0.434
Loss Rate
95%
Win Rate
5%
Profit-Loss Ratio
22.38
Alpha
0.065
Beta
-0.077
Annual Standard Deviation
0.145
Annual Variance
0.021
Information Ratio
0.152
Tracking Error
0.221
Treynor Ratio
-0.812
Total Fees
$240.93
/* using the close>HMA 
consolidated minute bar minutes bar
 */



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 HullMA : QCAlgorithm
    {
        private const string Symbol = "SPY";
        public HullMovingAverage HMA;
        TradeBar _spyMinutes;
        //Initialize the data and resolution you require for your strategy:
        public override void Initialize() 
        {
			
            //Start and End Date range for the backtest:
            SetStartDate(2015, 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.Minute);
            
            HMA = new HullMovingAverage(Symbol+"_HMA_",40);
            var minConsolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(30));
            
            // attach our event handler. the event handler is a function that will be called each time we produce
            // a new consolidated piece of data.
            minConsolidator.DataConsolidated += OnFiveMinutes;

            // this call adds our daily consolidator to the manager to receive updates from the engine
            SubscriptionManager.AddConsolidator(Symbol, minConsolidator);
            
            RegisterIndicator(Symbol,HMA,minConsolidator,Field.Close);
            
        }
        
        private void OnFiveMinutes(object sender, TradeBar consolidated)
        {
            _spyMinutes = consolidated;
            //Log(consolidated.Time.ToString("o") + " >> " + Symbol  + ">> LONG  >> 100 >> " + Portfolio[Symbol].Quantity);
            
            // if you want code to run every five minutes then you can run it inside of here
        }
        
        //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"]
            
            // wait for our slow ema to fully initialize
            if (!HMA.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*0.00015m;
            var holdings = Portfolio[Symbol].Quantity;

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

            // we only want to liquidate if we're currently long
            // if the fast is less than the slow we'll liquidate our long
            if (holdings > 0 && Securities[Symbol].Price < HMA)
            {
                Log("SELL >> " + Securities[Symbol].Price + HMA);
               // Liquidate(Symbol);
                SetHoldings(Symbol, -1);   
            }
        }
    }
    
        public class HullMovingAverage : IndicatorBase<IndicatorDataPoint>
    {
        private readonly LinearWeightedMovingAverage _fast;
        private readonly LinearWeightedMovingAverage _slow;
        private readonly LinearWeightedMovingAverage _smooth;

        public HullMovingAverage(string name, int period)
            : base(name)
        {
            var nsquared = period*period;
            _fast = new LinearWeightedMovingAverage(nsquared/2);
            _slow = new LinearWeightedMovingAverage(nsquared);
            _smooth = new LinearWeightedMovingAverage(period);
        }

        public override bool IsReady
        {
            get { return _smooth.IsReady; }
        }

        protected override decimal ComputeNextValue(IndicatorDataPoint input)
        {
            _fast.Update(input);
            _slow.Update(input);
            _smooth.Update(input.Time, 2*_fast - _slow);
            return _smooth;
        }
    }
}