Overall Statistics |
Total Trades 468 Average Win 4.99% Average Loss -1.56% Compounding Annual Return 648.350% Drawdown 22.200% Expectancy 0.791 Net Profit 1128.959% Sharpe Ratio 2.475 Loss Rate 57% Win Rate 43% Profit-Loss Ratio 3.19 Alpha 0.645 Beta 0.335 Annual Standard Deviation 0.637 Annual Variance 0.405 Information Ratio -1.316 Tracking Error 0.915 Treynor Ratio 4.707 Total Fees $0.00 |
namespace QuantConnect { public static class RollingWindowExtensions { public static bool CrossAbove(this RollingWindow<decimal> window1, RollingWindow<decimal> window2, decimal tolerance = 0m) { return window1[0] > window2[0] * (1 + tolerance) && window1[1] < window2[1] * (1 - tolerance); } public static bool CrossBelow(this RollingWindow<decimal> window1, RollingWindow<decimal> window2, decimal tolerance = 0m) { return window1[0] < window2[0] * (1 - tolerance) && window1[1] > window2[1] * (1 + tolerance); } public static bool Rising(this RollingWindow<decimal> window, int lookback = 1, decimal tolerance = 0m) { return window[0] > window[lookback] * (1 + tolerance); } public static bool Falling(this RollingWindow<decimal> window, int lookback = 1, decimal tolerance = 0m) { return window[0] < window[lookback] * (1 - tolerance); } } }
namespace QuantConnect { public class EmaCrossesAlgorithm : QCAlgorithm { // private const string Market = "fxcm"; // private const int DefaultQuantity = 25000; private const int PeriodFast = 20; private const int PeriodSlow = 8; private Symbol _symbol = QuantConnect.Symbol.Create("ETHUSD", SecurityType.Crypto, Market.GDAX); private ExponentialMovingAverage _emaFast; private ExponentialMovingAverage _emaSlow; private RollingWindow<decimal> _emaFastHistory = new RollingWindow<decimal>(PeriodFast + 1); private RollingWindow<decimal> _emaSlowHistory = new RollingWindow<decimal>(PeriodSlow + 1); decimal leverage = 0.95m; string stockHeld=""; public override void Initialize() { SetStartDate(2017, 1, 1); SetEndDate(2018, 3, 31); SetCash(10000); SetBenchmark(_symbol); AddCrypto(_symbol, Resolution.Hour); _emaFast = EMA(_symbol, PeriodFast); _emaSlow = EMA(_symbol, PeriodSlow); } public override void OnData(Slice data) { // Add ema values to rolling windows, so we can access previous ema values _emaFastHistory.Add(_emaFast); _emaSlowHistory.Add(_emaSlow); if (!_emaSlow.IsReady) return; var bar = data[_symbol] as TradeBar; if (bar == null) return; if (Portfolio[_symbol].IsLong) { // Long exit: EmaSlow is falling if (_emaSlowHistory.Falling(PeriodSlow)) { Liquidate(); } } // else if (Portfolio[_symbol].IsShort) // { // // Short exit: EmaSlow is rising // if (_emaSlowHistory.Rising(PeriodSlow)) // { // Order(_symbol, 0.95m); // } else { // Long entry: EmaFast crosses above EmaSlow and EmaSlow not falling if (_emaSlowHistory.CrossAbove(_emaFastHistory) ) { SetHoldings(_symbol, leverage); stockHeld=_symbol; } // Short entry: EmaFast crosses below EmaSlow and EmaSlow not rising if (_emaSlowHistory.CrossBelow(_emaFastHistory) && !_emaSlowHistory.Rising(PeriodSlow)) { Liquidate(); } } } } }