Overall Statistics
Total Trades
216
Average Win
2.21%
Average Loss
-0.64%
Compounding Annual Return
15.804%
Drawdown
10.400%
Expectancy
0.240
Net Profit
15.804%
Sharpe Ratio
0.815
Loss Rate
72%
Win Rate
28%
Profit-Loss Ratio
3.46
Alpha
0.139
Beta
0.109
Annual Standard Deviation
0.161
Annual Variance
0.026
Information Ratio
1.076
Tracking Error
0.187
Treynor Ratio
1.204
Total Fees
$432.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 = 5;
        private const int PeriodSlow = 9;

        private Symbol _symbol = QuantConnect.Symbol.Create("EURUSD", SecurityType.Forex, Market);

        private ExponentialMovingAverage _emaFast;
        private ExponentialMovingAverage _emaSlow;

        private RollingWindow<decimal> _emaFastHistory = new RollingWindow<decimal>(PeriodFast + 1);
        private RollingWindow<decimal> _emaSlowHistory = new RollingWindow<decimal>(PeriodSlow + 1);

        public override void Initialize()
        {
            SetStartDate(2015, 1, 1);
            SetEndDate(2015, 12, 31);
            SetCash(10000);

            SetBenchmark(_symbol);

            AddForex(_symbol, Resolution.Hour, Market);

            _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))
                {
                    Order(_symbol, -DefaultQuantity);
                }
            }
            else if (Portfolio[_symbol].IsShort)
            {
                // Short exit: EmaSlow is rising
                if (_emaSlowHistory.Rising(PeriodSlow))
                {
                    Order(_symbol, DefaultQuantity);
                }
            }
            else
            {
                // Long entry: EmaFast crosses above EmaSlow and EmaSlow not falling
                if (_emaFastHistory.CrossAbove(_emaSlowHistory) && !_emaSlowHistory.Falling(PeriodSlow))
                {
                    Order(_symbol, DefaultQuantity);
                }

                // Short entry: EmaFast crosses below EmaSlow and EmaSlow not rising
                if (_emaFastHistory.CrossBelow(_emaSlowHistory) && !_emaSlowHistory.Rising(PeriodSlow))
                {
                    Order(_symbol, -DefaultQuantity);
                }
            }
        }
    }
}