Overall Statistics
Total Trades
644
Average Win
0.26%
Average Loss
-0.07%
Compounding Annual Return
3.950%
Drawdown
2.300%
Expectancy
-0.014
Net Profit
4.082%
Sharpe Ratio
0.781
Loss Rate
78%
Win Rate
22%
Profit-Loss Ratio
3.56
Alpha
0.033
Beta
0.219
Annual Standard Deviation
0.042
Annual Variance
0.002
Information Ratio
0.731
Tracking Error
0.043
Treynor Ratio
0.151
Total Fees
$1288.00
namespace QuantConnect 
{
    /*
    *   QuantConnect University: 50-10 EMA - Exponential Moving Average Cross
    *   
    *   The classic exponential moving average cross implementation using a custom class.
    *   The algorithm uses allows for a safety margin so you can reduce the "bounciness" 
    *   of the trading to confirm the crossing.
    */
    public class QCUMovingAverageCross : QCAlgorithm 
    { 
        // Define required variables:
        int quantity = 0;
        decimal price = 0;
        decimal tolerance = 0m; //0.1% safety margin in prices to avoid bouncing.
        Symbol symbol = QuantConnect.Symbol
            .Create("USDJPY", SecurityType.Forex, Market.Oanda);
        
        // Set up the EMA Class:
        // ExponentialMovingAverage emaShort;
        // ExponentialMovingAverage emaLong;
        SimpleMovingAverage emaShort;
        SimpleMovingAverage emaLong;
        
        //Initialize the data and resolution you require for your strategy:
        public override void Initialize() 
        {          
            SetStartDate(2016, 01, 04);
            SetCash(25000);
        
        	var forex = AddForex(symbol, Resolution.Minute);
        	
            var minConsolidator = new QuoteBarConsolidator(TimeSpan.FromMinutes(30));
            minConsolidator.DataConsolidated += OnThirtyMinutes;
            
            emaShort = new SimpleMovingAverage(10);
            emaLong = new SimpleMovingAverage(50);
            
            RegisterIndicator(symbol, emaShort, TimeSpan.FromMinutes(30));
            RegisterIndicator(symbol, emaLong, TimeSpan.FromMinutes(30));
            SubscriptionManager.AddConsolidator(symbol, minConsolidator);
        }
        
        public void OnData(TradeBars data) 
        {
            // NOP
        }
        
        private void OnThirtyMinutes(object sender, QuoteBar bar)
        {
        	//Wait until EMA's are ready:
            if (!emaShort.IsReady || !emaLong.IsReady) return;
        
            //Only take one data point per day (opening price)
            price = bar.Close;
        
            //Get fresh cash balance: Set purchase quantity to equivalent 10% of portfolio.
            var cash = Portfolio.Cash;
            var holdings = Portfolio[symbol].Quantity;
            
            var longCond = price > emaShort && price > emaLong && (price-emaLong)<60;
            var shortCond = price < emaShort && price < emaLong && (emaLong-price)<60;
            
            //If we're long, or flat: check if EMA crossed negative: and crossed outside our safety margin:
            if (holdings >= 0 && shortCond) 
            {
                quantity = holdings > 0 ? -20000 : -10000;
                MarketOrder(symbol, quantity);
                Log(Time.ToShortDateString() + " > Go Short > Holdings: " + holdings + " Quantity:" + quantity + " price: " +price+ " maShort: " + emaShort.Samples+" maLong: "+emaLong.Samples);
            }    
                
            //If we're short, or flat: check if EMA crossed positive: and crossed outside our safety margin:
            if (holdings <= 0 && longCond)
            {
                quantity = holdings < 0 ? 20000 : 10000;
                MarketOrder(symbol, quantity);
                Log(Time.ToShortDateString() + "> Go Long >  Holdings: " + holdings + " Quantity:" + quantity + " price: " +price+ " maShort: " + emaShort.Samples+" maLong: "+emaLong.Samples); 
            }
        }
    }
}