Overall Statistics |
Total Trades 137 Average Win 8.82% Average Loss -3.01% Compounding Annual Return 11.893% Drawdown 24.800% Expectancy 0.389 Net Profit 125.836% Sharpe Ratio 0.651 Loss Rate 65% Win Rate 35% Profit-Loss Ratio 2.93 Alpha 0.068 Beta 0.393 Annual Standard Deviation 0.161 Annual Variance 0.026 Information Ratio 0.061 Tracking Error 0.174 Treynor Ratio 0.267 Total Fees $1522.77 |
using System; using QuantConnect.Indicators; namespace QuantConnect.Algorithm.CSharp { public enum CrossingMovingAveragesSignals { Bullish = 1, FastCrossSlowFromAbove = -2, Bearish = -1, FastCrossSlowFromBelow = 2, } public class CrossingMovingAverages { CompositeIndicator<IndicatorDataPoint> _moving_average_difference; public CrossingMovingAveragesSignals Signal { get; private set; } private bool _isReady; int _lastSignal; public bool IsReady { get { return _isReady; } } public CrossingMovingAverages(IndicatorBase<IndicatorDataPoint> fast_moving_average, IndicatorBase<IndicatorDataPoint> slow_moving_average) { _moving_average_difference = fast_moving_average.Minus(slow_moving_average); _moving_average_difference.Updated += ma_Updated; } private void ma_Updated(object sender, IndicatorDataPoint updated) { if (!_isReady) { _isReady = _moving_average_difference.Right.IsReady; return; } var actualSignal = Math.Sign(_moving_average_difference); if (actualSignal == _lastSignal || _lastSignal == 0) { Signal = (CrossingMovingAveragesSignals)actualSignal; } else if (_lastSignal == -1 && actualSignal == 1) { Signal = CrossingMovingAveragesSignals.FastCrossSlowFromBelow; } else if (_lastSignal == 1 && actualSignal == -1) { Signal = CrossingMovingAveragesSignals.FastCrossSlowFromAbove; } _lastSignal = actualSignal; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using QuantConnect.Brokerages; using QuantConnect.Data; using QuantConnect.Indicators; namespace QuantConnect.Algorithm.CSharp { public class HullMA:QCAlgorithm { private int hullMaPeriod = 4; private int slowEmaPeriod = 15; private ExponentialMovingAverage slowEma; private IndicatorBase<IndicatorDataPoint> hullMa; private CrossingMovingAverages MovingAverageCross; private Symbol symbol; public override void Initialize() { // Set the basic algorithm parameters. SetStartDate(2010, 01, 01); SetEndDate(2017, 03, 30); SetCash(100000); symbol = AddEquity("AAPL", Resolution.Daily).Symbol; // ================================== // Hull Moving Average implementation var slowLWMA = LWMA(symbol, (int) (hullMaPeriod * 1m / 2)); var fastLWMA = LWMA(symbol, hullMaPeriod); var HMA = new LinearWeightedMovingAverage((int) Math.Sqrt(hullMaPeriod * 1d)); hullMa = HMA.Of(fastLWMA.Times(2).Minus(slowLWMA)); // ================================== slowEma = EMA(symbol, slowEmaPeriod); MovingAverageCross = new CrossingMovingAverages(hullMa, slowEma); } public override void OnData(Slice slice) { if (!slice.ContainsKey(symbol) || !MovingAverageCross.IsReady) return; var signal = MovingAverageCross.Signal; if (signal == CrossingMovingAveragesSignals.FastCrossSlowFromAbove || signal == CrossingMovingAveragesSignals.FastCrossSlowFromBelow) { if ((Portfolio[symbol].IsLong && signal == CrossingMovingAveragesSignals.FastCrossSlowFromAbove) || (Portfolio[symbol].IsShort && signal == CrossingMovingAveragesSignals.FastCrossSlowFromBelow)) { Liquidate(symbol); } else if (!Portfolio[symbol].Invested) { SetHoldings(symbol, 1*Math.Sign((int)signal)); } } } public override void OnEndOfDay() { Plot("Hull Moving Average", "AAPL", Securities[symbol].Close); if (hullMa.IsReady) Plot("Hull Moving Average", "Hull Moving Average", hullMa.Current.Value); if (slowEma.IsReady) Plot("Hull Moving Average", "EMA", slowEma.Current.Value); } } }