Overall Statistics
Total Trades
5039
Average Win
0.28%
Average Loss
-0.32%
Compounding Annual Return
28.718%
Drawdown
14.400%
Expectancy
0.041
Net Profit
83.625%
Sharpe Ratio
1.308
Loss Rate
44%
Win Rate
56%
Profit-Loss Ratio
0.86
Alpha
0.285
Beta
-0.057
Annual Standard Deviation
0.21
Annual Variance
0.044
Information Ratio
0.357
Tracking Error
0.242
Treynor Ratio
-4.837
Total Fees
$18681.87
/*
 * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
 * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

using System;
using System.Collections.Generic;

namespace QuantConnect.Indicators
{
    /// <summary>
    ///     Represents the Hull moving average indicator (HMA).
    ///     The Hull Moveing Average is a LWMA applied to difference of two Price LWMA
    ///     For example a HMA of period 4 is calucalted as follows:
    ///         TMP = 2 * FastLWMA(Price) - SlowLWMA(Price)
    ///         HMA(4) = HullLWMA(TMP)
    ///     
    ///     As default:
    ///         The slow LWMA period is the HMA period squared
    ///         The fast LWMA period is the half of the slow EMA period
    ///         
    /// </summary>
    public class HullMovingAverage : Indicator
    {

        private readonly int _periodHMA;
        private readonly int _periodSlowLWMA;
        private readonly int _periodFastLWMA;

        decimal slowLWMA;
        decimal fastLWMA;

        decimal previousSlowLWMA;
        decimal previousfastLWMA;

        Queue<decimal> windowSlowLWMA = new Queue<decimal>();
        Queue<decimal> windowFastLWMA = new Queue<decimal>();
        Queue<decimal> windowHMA = new Queue<decimal>();


        /// <summary>
        ///     Initializes a new instance of the HullMovingAverage class with the specified name and Hull period
        /// </summary>
        /// <param name="name">The name of this indicator.</param>
        /// <param name="period">The period of the HMA.</param>
        public HullMovingAverage(string name, int period)
            : base(name)
        {
            _periodHMA = period;
            _periodSlowLWMA = (int)System.Math.Pow(period, 2);
            _periodFastLWMA = _periodSlowLWMA / 2;
        }

        /// <summary>
        ///     Initializes a new instance of the HullMovingAverage class with the specified name and Hull period
        /// </summary>
        /// <param name="name">The name of this indicator.</param>
        /// <param name="HMAperiod">The HMA aperiod.</param>
        /// <param name="SlowLWMAPeriod">The slow LWMA period.</param>
        /// <param name="FastWMAPeriod">The fast LWMA period.</param>
        public HullMovingAverage(string name, int HMAperiod, int SlowLWMAPeriod, int FastWMAPeriod)
            :base(name)
        {
            _periodHMA = HMAperiod;
            _periodSlowLWMA = SlowLWMAPeriod;
            _periodFastLWMA = FastWMAPeriod;
        }

        /// <summary>
        ///     Estimate LWMA based in the last observation, the LWMA period and the windows with the previous values.
        /// </summary>
        /// <param name="lastInput">The last observation.</param>
        /// <param name="period">The LWMA period.</param>
        /// <param name="window">The previos values window.</param>
        /// <returns>A new value for the LWMA</returns>
        private decimal _LWMA(decimal lastInput, int period, Queue<decimal> window)
        {
            decimal denominator = period * (period + 1) / 2;
            window.Enqueue(lastInput);

            if (window.Count > period)
            {
                window.Dequeue();
                decimal numerator = 0;
                for (int i = 0; i < window.Count; i++)
                {
                    numerator += window.ToArray()[i] * (decimal)(i + 1);
                }
                return numerator / denominator;
            }
            else
            {
                return lastInput;
            }
        }

        /// <summary>
        ///     Gets a flag indicating when this indicator is ready and fully initialized
        /// </summary>
        public override bool IsReady
        {
            get { return Samples > _periodSlowLWMA + _periodHMA; }
        }

        /// <summary>
        ///     Computes the next value of this indicator from the given state
        /// </summary>
        /// <param name="input">The input given to the indicator</param>
        /// <returns>A new value for this indicator</returns>
        protected override decimal ComputeNextValue(IndicatorDataPoint input)
        {
            // our first data point just return identity
            if (!this.IsReady)
            {
                return input;
            }
            decimal TMP = 2 * _LWMA(input, _periodFastLWMA, windowFastLWMA) - _LWMA(input, _periodSlowLWMA, windowSlowLWMA);
            return _LWMA(TMP, _periodHMA, windowHMA);
        }
    }
}
using System;
using System.Collections.Generic;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Securities;
using QuantConnect.Securities.Equity;


namespace QuantConnect
{
    public class EMACrossingHMA : QCAlgorithm
    {
    /* +--------------------------------------------+
     * |Control Panel - Making overfitting easier   |
     * +--------------------------------------------+*/
        int HMAPeriod = 4;                  // The Hull Moving Average period
        int slowEMAPeriod = 15;             // A Slow EMA period
        static int lookbackWindow = 45;     // Channel lookback used to estimate the uppenr and lower bands
    /* +--------------------------------------------+*/

        string symbol = "SPY";
        HullMovingAverage HMA;
        ExponentialMovingAverage slowEMA;
        CompositeIndicator<IndicatorDataPoint> signal;
        Resolution resolution = Resolution.Minute;
        RollingWindow<decimal> Band = new RollingWindow<decimal>(lookbackWindow);

        // A failed try
        DonchianChannel Channel = new DonchianChannel("myChannel", 10);

        public override void Initialize()
        {
            SetStartDate(2013, 1, 1);
            SetEndDate(2015, 5, 31);
            SetCash(25000);

            AddSecurity(SecurityType.Equity, symbol, resolution);

            slowEMA = EMA(symbol, slowEMAPeriod, resolution);

            HMA = new HullMovingAverage("HMA(" + symbol + ")", HMAPeriod);   // Why is the name needed?
            Func<BaseData, decimal> selector = null;                         // I really don't know what this does, but make it work :P
            RegisterIndicator(symbol, HMA, resolution, selector);
            signal = HMA.Minus(slowEMA);
        }


        public void OnData(TradeBars data)
        {
            // I tried to use something like:
            // Channel.Of(signal);
            // but didn't work.
            if (!slowEMA.IsReady || !HMA.IsReady) return;
            if (Band.IsReady)
            {   
                // Estimating the upper and lower channel band.
                // Is there a better way?
                decimal upperBand = decimal.MinValue;
                decimal lowerBand = decimal.MaxValue;
                for (int i = 0; i < Band.Count; i++)
                {
                    upperBand = Math.Max(Band[i], upperBand);
                    lowerBand = Math.Min(Band[i], lowerBand);
                }

                // Defining the signals
                bool longSignal = signal < lowerBand;
                bool shortSignal = signal > upperBand;

                // If we don't hold any position
                if (!Portfolio[symbol].HoldStock)
                {
                    if (longSignal) SetHoldings(symbol, 1);
                    if (shortSignal) SetHoldings(symbol, -1);
                }
                // If we have hold some position
                else
                {
                    if (Portfolio[symbol].IsLong && shortSignal) Liquidate(symbol);
                    if (Portfolio[symbol].IsShort && longSignal) Liquidate(symbol);
                }
                Band.Add(signal);   // Update the channel.
            }
            else Band.Add(signal);  // Update the channel window until is ready.
        }
    }
}