Overall Statistics
Total Trades
542
Average Win
1.64%
Average Loss
-0.71%
Compounding Annual Return
-18.329%
Drawdown
25.000%
Expectancy
-0.087
Net Profit
-18.329%
Sharpe Ratio
-0.558
Loss Rate
72%
Win Rate
28%
Profit-Loss Ratio
2.30
Alpha
-0.025
Beta
1.551
Annual Standard Deviation
0.241
Annual Variance
0.058
Information Ratio
-0.351
Tracking Error
0.182
Treynor Ratio
-0.087
Total Fees
$1084.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, decimal tolerance = 0m)
        {
            return window[0] > window[1] * (1 + tolerance);
        }

        public static bool Falling(this RollingWindow<decimal> window, decimal tolerance = 0m)
        {
            return window[0] < window[1] * (1 - tolerance);
        }
    }
}
namespace QuantConnect 
{   
    public class EmaCrossesAlgorithm : QCAlgorithm
    {
        private const string Market = "fxcm";
        private const int DefaultQuantity = 25000;

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

        private ExponentialMovingAverage _emaFast;
        private ExponentialMovingAverage _emaSlow;

        private RollingWindow<decimal> _emaFastHistory = new RollingWindow<decimal>(2);
        private RollingWindow<decimal> _emaSlowHistory = new RollingWindow<decimal>(2);

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

            SetBenchmark(_symbol);

            AddForex(_symbol, Resolution.Hour, Market);

            _emaFast = EMA(_symbol, 5);
            _emaSlow = EMA(_symbol, 9);
        }

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

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