Overall Statistics
Total Trades
2799
Average Win
0.11%
Average Loss
-0.18%
Compounding Annual Return
10.769%
Drawdown
27.800%
Expectancy
0.011
Net Profit
26.183%
Sharpe Ratio
0.585
Probabilistic Sharpe Ratio
23.498%
Loss Rate
38%
Win Rate
62%
Profit-Loss Ratio
0.63
Alpha
-0.058
Beta
0.667
Annual Standard Deviation
0.181
Annual Variance
0.033
Information Ratio
-1.083
Tracking Error
0.129
Treynor Ratio
0.159
Total Fees
$2880.80
Estimated Strategy Capacity
$870000.00
/*
	This program was developed by Quantify and is a template program.
	Usage and marketing of this program is permitted.
	
	www.quantify-co.com
*/

namespace QuantConnect.Algorithm.CSharp
{
    public class BeginnerTemplate : QCAlgorithm
    {
    	// BACKTESTING PARAMETERS
    	// =================================================================================================================
    	
    	// general settings:
    	
    	// set starting cash
    	private int starting_cash = 100000;
    	
    	// backtesting start date time:
    	// date setting variables
    	private int start_year = 2019;
    	private int start_month = 1;
    	private int start_day = 1;
    	
    	// backtesting end date time:
    	// determines whether there is a specified end date
    	// if false it will go to the current date (if 'true' it will go to the specified date)
    	private bool enable_end_date = false;
    	// date setting variables
    	private int end_year = 2020;
    	private int end_month = 1;
    	private int end_day = 1;
    	
    	
    	// universe settings:
    	
    	// number of symbols you want to be observed by the universe at any given time
    	// updates based on the universe resolution set
    	// recommended universe resolution is daily
    	private int totalNumberOfStocks = 20;
    	
    	// data update resolution
    	// changes how often the data updates and algorithm looks for entry
    	// determines how often the function OnData runs
    	// list of resolutions:
    	// Resolution.Tick; Resolution.Second; Resolution.Minute; Resolution.Hour; Resolution.Daily
    	private readonly Resolution resolution = Resolution.Hour;
    	
    	// stock list
    	// list of stocks you want in the universe
    	// used in manual selection of universe
    	// set selection_type = false for activation
    	private readonly String[] manual_universe = new String[]{"SPY", "AAPL"};
    	
    	// use manual of automatic universe selection
    	// set to false for manual and true for automatic
    	private readonly bool selection_type = true;
    	
    	// position settings:
    	
    	// percent of portfolio to enter a position with
    	// note this value is 1 / totalNumberOfStocks
    	private decimal position_percent_portfolio = 0.05m;
    	
    	
    	// indicator settings:
    	
    	// sets the period of the EMA fast indicator
    	private readonly int ema_fast_length = 10;
    	
    	// sets the period of the EMA slow indicator
    	private readonly int ema_slow_length = 20;
    	
    	// =================================================================================================================
		
		// creates new universe variable setting
		private List<StockData> universe = new List<StockData>();
		
		// security changes variable
		private SecurityChanges securityChanges = SecurityChanges.None;
		
        public override void Initialize()
        {
        	// set start date
            SetStartDate(start_year, start_month, start_day);
            // set end date
            if(enable_end_date)
            	SetEndDate(end_year, end_month, end_day);
            // set starting cash
            SetCash(starting_cash);
            
            if(selection_type) {
	            // universe updater w/ highest performing stocks
	            AddUniverse(CoarseFilterFunction, FineSelectionFunction);
            } else {
	            foreach(string s in manual_universe)
	            	AddEquity(s, resolution);
            }
        }

		// filter based on CoarseFundamental
	    public IEnumerable<Symbol> CoarseFilterFunction(IEnumerable<CoarseFundamental> coarse) {
	    	// returns the highest DollarVolume stocks
	    	// returns "totalNumberOfStocks" amount of stocks
	        return (from stock in coarse
        			orderby stock.DollarVolume descending  
        			select stock.Symbol).Take(totalNumberOfStocks);
        	return Universe.Unchanged;
	    }
	    
	    // filter based on FineFundamental
	    public IEnumerable<Symbol> FineSelectionFunction(IEnumerable<FineFundamental> fine) {
	        return (from f in fine
	        	select f.Symbol).Take(totalNumberOfStocks);
	    }

        // OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        // Slice object keyed by symbol containing the stock data
        public override void OnData(Slice data) {
        	// loops through each stock in universe
        	foreach(StockData sd in universe) {
        		// condition where fast ema < slow ema
        		// makes sure position is not already open
        		if(sd.ema_fast < sd.ema_slow && !Portfolio[sd.ticker].Invested) {
        			SetHoldings(sd.ticker, position_percent_portfolio);
        		} else if(sd.ema_slow < sd.ema_fast && Portfolio[sd.ticker].Invested) {
        			// liquidates ticker if condition not met and position is open
        			Liquidate(sd.ticker);
        		}
        	}
        }
        
        // OnSecuritiesChanged runs when the universe updates current securities
        public override void OnSecuritiesChanged(SecurityChanges changes) {
            securityChanges = changes;
            // remove stocks from list that get removed from universe
            foreach (var security in securityChanges.RemovedSecurities) {
            	List<StockData> stockDatas = universe.Where(x=>x.ticker == security.Symbol).ToList();
            	if (stockDatas.Count >= 1) {
            		// check to see if position is open and if so close position
            		if(Portfolio[stockDatas.First().ticker].Invested) {
            			// closes position
            			Liquidate(stockDatas.First().ticker);
            		}
            		// removes stock from list if it is removed from the universe
                	universe.Remove(stockDatas.First());
            	}
            }
            
            // add new securities to universe list
            foreach(var security in securityChanges.AddedSecurities) {
            	// create StockData variable for security
            	StockData sd = new StockData();
            	// initalize all indicators
            	sd.ticker = security.Symbol;
            	sd.ema_fast = EMA(sd.ticker, ema_fast_length, resolution);
            	sd.ema_slow = EMA(sd.ticker, ema_slow_length, resolution);
            	// add historical data to tickers
            	// we use ema_slow_length since it will always be greater than ema_fast_length
            	var history = History(sd.ticker, ema_slow_length, resolution);
            	foreach(var bar in history) {
            		sd.ema_fast.Update(bar.EndTime, bar.Close);
            		sd.ema_slow.Update(bar.EndTime, bar.Close);
            	}
            	// add stockdata to universe
            	universe.Add(sd);
            }
        }
		
		// default class containing all ticker information
		public class StockData {
			// stock ticker
			public string ticker = "";
			// defines EMA fast
			public ExponentialMovingAverage ema_fast;
			// defines EMA slow
			public ExponentialMovingAverage ema_slow;
			// DEFINE OTHER INDICATORS
		}
    }
}