Overall Statistics
Total Trades
10
Average Win
0.20%
Average Loss
-0.10%
Compounding Annual Return
0.795%
Drawdown
0.400%
Expectancy
1.417
Net Profit
0.714%
Sharpe Ratio
0.908
Loss Rate
20%
Win Rate
80%
Profit-Loss Ratio
2.02
Alpha
0
Beta
0
Annual Standard Deviation
0.009
Annual Variance
0
Information Ratio
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$11.96
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;

namespace QuantConnect 
{   
    /*
    *   QuantConnect University: Full Basic Template:
    *
    *   The underlying QCAlgorithm class is full of helper methods which enable you to use QuantConnect.
    *   We have explained some of these here, but the full algorithm can be found at:
    *   https://github.com/QuantConnect/QCAlgorithm/blob/master/QuantConnect.Algorithm/QCAlgorithm.cs
    */
    public class BasicTemplateAlgorithm : QCAlgorithm
    {
    	
    	 private readonly Dictionary<string, SymbolData> Data = new Dictionary<string, SymbolData>();
        //Initialize the data and resolution you require for your strategy:
        
        SecurityChanges _changes = SecurityChanges.None;
        
        private Boolean doLongEntry; 
        private Boolean CrossExit = true;
        private Boolean EarlyExit = false;
        private decimal exitProfit =200;
        private decimal MRMentry = 80;
       
        private Boolean junktrace = false;
        private string strtrace = "";
        
        public override void Initialize() 
        {
			
            //Start and End Date range for the backtest:
            UniverseSettings.Resolution = Resolution.Hour;
            SetStartDate(2014, 1, 1);         
            SetEndDate(DateTime.Now.Date.AddDays(-1));
            
            //Cash allocation
            SetCash(100000);
            AddUniverse(CoarseSelectionFunction);
            
                	 
            
            
            doLongEntry 	= true;
            //doShortEntry	= true;
            
        }
        
         // sort the data by daily dollar volume and take the top 5 symbols
        public static IEnumerable<Symbol> CoarseSelectionFunction(IEnumerable<CoarseFundamental> coarse)
        {
            // sort descending by daily dollar volume
            var sortedByDollarVolume = coarse.OrderByDescending(x => x.DollarVolume);
            // take the top 5 entries from our sorted collection
            var top5 = sortedByDollarVolume.Take(450);
            // we need to return only the symbols
            return top5.Select(x => x.Symbol);
        }

        //Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol.
        //private DateTime previous;
        private int mycount;
        
        public void OnData(TradeBars data) 
        {   
            //Log ( " :> " + data.Count + "<" + Data.Count + ">" + Time.ToString("u")  );
            foreach (var symbolData in Data.Values)
        	{
        		//Log (symbolData.Symbol + " :> " +Time.ToString("u")  );
        		if (!Securities.ContainsKey(symbolData.Symbol)) continue;
        		if (!data.ContainsKey(symbolData.Symbol)) continue;
        		if (!symbolData.IsReady) continue;
        		
        		proc_doLongProfit(symbolData);
        		
        		if (symbolData.Done) continue; 
        		
        		 symbolData.Done = true;
        		 proc_doLongEntry(symbolData);
        		 
        		 proc_doLongExit(symbolData);	
        		 proc_doShortExit(symbolData);
        		 
        		 symbolData.lastSma = symbolData.SMA;
          		 symbolData.lastSlow = symbolData.slowSMA;
        		
        	
        	}
        	
        	if (mycount != Data.Count)	
        	{
        		Log ("Data universe count " + Data.Count);
        		mycount = Data.Count;
        	}
        	
        
            
        }
        
    	 public override void OnSecuritiesChanged(SecurityChanges changes)
        {
            _changes = changes;
            Boolean addSecurity = true;
            SymbolData sd;
            foreach (var removed in changes.RemovedSecurities)
        	{
            
            	try	{ sd = Data[removed.Symbol];} catch {continue;}
            	if (removed.Invested) 
            		{
            		sd.needsRemoving = true;
            		Log ("Open pos. Not wanting to be Removed " + removed.Symbol);
            		//continue;
            		Liquidate(removed.Symbol);
            		}
            	bool z=false ;
        		if ( strtrace == removed.Symbol) z = true;
        		if ( strtrace == "") z = true;
            	if (junktrace && z) Log ("Removing " + removed.Symbol);
            	Data.Remove(removed.Symbol);
        	}
            
             foreach (var security in _changes.AddedSecurities)
            {
                foreach (var symbolData in Data.Values)
                {
                	if (security.Symbol == symbolData.Symbol) addSecurity = false;
                }
               if (Data.Count >300 ) addSecurity = false;
               // if (Data.security.Contains(security.Symbol)) continue;
                if (addSecurity) {
                	Data.Add(security.Symbol, new SymbolData(security.Symbol, this));
                	var history = History(security.Symbol,1400 );
                	foreach (var tradeBar in history)
            		{
            			sd = Data[security.Symbol];
            			sd.MRM.Update(tradeBar.EndTime, tradeBar.Close);
            			sd.SMA.Update(tradeBar.EndTime, tradeBar.Close);
            			sd.slowSMA.Update(tradeBar.EndTime, tradeBar.Close);
            		}
                }
                bool z=false ;
        		if ( strtrace == security.Symbol) z = true;
        		if ( strtrace == "") z = true;
                if (junktrace && z) Log ("addcount = " + Data.Count + " ; " + security.Symbol);
                //Data.Add(symbol, new SymbolData(symbol, this));
                //Log("addChange " + security.Symbol);
            }
            junktrace = true;
        }
        
      void proc_doLongEntry(SymbolData d)	
      {
    	
    	if (!doLongEntry)return;
    	if(Portfolio[d.Symbol].Invested)	return;
      	bool crossLong = false;	
      	if (d.lastSma < d.lastSlow && d.SMA > d.slowSMA)
      	{
      		crossLong = true;
      	}
      	//Log (d.Symbol + " : " +Time.ToString("u") + " Cross " + crossLong + " , " + d.MRM );
        if (d.MRM > MRMentry)
        //if ( MRMentry !=0)
        	{
        	if ( crossLong)	{
        		//Order(d.Symbol,100000);
        		try{
        		SetHoldings(d.Symbol, 0.1m);
        		bool z=false ;
        		if ( strtrace == d.Symbol) z = true;
        		if ( strtrace == "") z = true;
        		if (z)	Log (d.Symbol + " : " +"Long Entry");
        		}
        		catch	{Log ("oops");}
        		}
        	}	
      }
      
        
      
      void proc_doLongExit(SymbolData d)	
      	{
      	if(!Portfolio[d.Symbol].Invested)	return;
      	if(!Portfolio[d.Symbol].IsLong) 	return;
      	bool crossShort = false;
      	if (d.lastSma > d.lastSlow && d.SMA < d.slowSMA) crossShort = true;
      	if 	(Portfolio[d.Symbol].UnrealizedProfit > exitProfit)	{
        	Order(d.Symbol,-100000);
        	Log (d.Symbol + " : " +"LLong profit");	
        }
        else	{
        	if (d.SMA > d.Security.Close && EarlyExit)	{		
        		//Order(d.Symbol,-100000);
        		SetHoldings(d.Symbol, 0m);
        		bool z=false ;
        		if ( strtrace == d.Symbol) z = true;
        		if ( strtrace == "") z = true;
        		if (z)	Log (d.Symbol + " : " +"Long sma exit");
        	}
        	if (d.SMA > d.Security.Close && CrossExit && crossShort)	{		
        		//Order(d.Symbol,-100000);
        		SetHoldings(d.Symbol, 0m);
        		bool z=false ;
        		if ( strtrace == d.Symbol) z = true;
        		if ( strtrace == "") z = true;
        		if (z)	Log (d.Symbol + " : " +"Long cross sma exit");
        	}
        }
      }
      
      void proc_doLongProfit(SymbolData d)	
      	{
      	
      	if(!Portfolio[d.Symbol].Invested)	return;
      	if(!Portfolio[d.Symbol].IsLong) 	return;
      
      	if 	(Portfolio[d.Symbol].UnrealizedProfit > exitProfit)	{
        	//Order(d.Symbol,-100000);
        	SetHoldings(d.Symbol, 0m);
        	bool z=false ;
        	if ( strtrace == d.Symbol) z = true;
        	if ( strtrace == "") z = true;
        	if (z)	Log (d.Symbol + " : " +"Long profit");	
        }
      }
      
      void proc_doShortExit(SymbolData d)	
      	{
      	if(!Portfolio[d.Symbol].Invested)	return;
      	if(!Portfolio[d.Symbol].IsShort) 	return;
      	bool crossLong = false;	
      	if (d.lastSma < d.lastSlow && d.SMA > d.slowSMA) crossLong = true;
      	if 	(Portfolio[d.Symbol].UnrealizedProfit > exitProfit)	{
        	Order(d.Symbol,100000);
        	Log (d.Symbol + " : " +"Short profit");	
        }
        else	{
        	if (d.SMA < d.Security.Close  && EarlyExit)	{		
        		Order(d.Symbol,100000);
        		Log (d.Symbol + " : " +"Short sma exit");
        	}
        	if (d.SMA < d.Security.Close  && CrossExit && crossLong)	{		
        		Order(d.Symbol,100000);
        		Log (d.Symbol + " : " +"Short cross sma exit");
        	}
        }
      }
      
      
    }
    
    
    public class SymbolData
    {
    	public readonly string Symbol;
    	public readonly Security Security;
    	public readonly SimpleMovingAverage SMA;
    	public readonly SimpleMovingAverage slowSMA;
    	public readonly RateOfChange ROC;
    	public readonly MomersionIndicator MRM;
    	public Boolean Done;
    	public decimal   lastSlow;
    	public decimal	 lastSma;
    	public int Position;
    	public DateTime lastBarTime;
    	public Boolean needsRemoving = false;
    	
    	//public readonly Identity Close;
    	
    	public SymbolData(string symbol, QCAlgorithm algorithm)
    	{
    		Symbol = symbol;
    		Security = algorithm.Securities[symbol];
    		var consolidator = new TradeBarConsolidator(TimeSpan.FromHours(4));
    		consolidator.DataConsolidated += mynewbar;
    		SMA = new SimpleMovingAverage(14);
    		slowSMA = new SimpleMovingAverage(21);
    		ROC = new RateOfChange(14);
    		MRM = new MomersionIndicator(5,21);
    		algorithm.RegisterIndicator(symbol, SMA, consolidator, Field.Close);
    		algorithm.RegisterIndicator(symbol, slowSMA, consolidator, Field.Close);
    		algorithm.RegisterIndicator(symbol, ROC, consolidator, Field.Close);
    		algorithm.RegisterIndicator(symbol, MRM, consolidator, Field.Close);
    		
    		  	
    		
    	}
    	
    	public void mynewbar(Object o, TradeBar bar)
    		{	
    		Done = false;
    		}
    	
    	public bool IsReady
            {
                get { return  SMA.IsReady && slowSMA.IsReady && MRM.IsReady  ; }
            }
    }
    
    
    
    
}
namespace QuantConnect {

    //
    //	Make sure to change "BasicTemplateAlgorithm" to your algorithm class name, and that all
    //	files use "public partial class" if you want to split up your algorithm namespace into multiple files.
    //

    //public partial class BasicTemplateAlgorithm : QCAlgorithm, IAlgorithm
    //{
    //  Extension functions can go here...(ones that need access to QCAlgorithm functions e.g. Debug, Log etc.)
    //}

    //public class Indicator 
    //{
    //  ...or you can define whole new classes independent of the QuantConnect Context
    //}
    
   

}