Overall Statistics
Total Trades
226
Average Win
0.01%
Average Loss
-0.01%
Compounding Annual Return
50.132%
Drawdown
1.600%
Expectancy
-0.296
Net Profit
7.385%
Sharpe Ratio
5.93
Probabilistic Sharpe Ratio
98.098%
Loss Rate
59%
Win Rate
41%
Profit-Loss Ratio
0.71
Alpha
0.054
Beta
1.014
Annual Standard Deviation
0.074
Annual Variance
0.006
Information Ratio
1.334
Tracking Error
0.044
Treynor Ratio
0.434
Total Fees
$237.05
Estimated Strategy Capacity
$9100000.00
using System.Reflection;
namespace QuantConnect
{
	public partial class BootCampTask : QCAlgorithm
	{
        public override void Initialize()
        {
            SetStartDate(2016, 12, 28); 
            SetEndDate(2017, 3, 1); 
            SetCash(100000);              
           
            UniverseSettings.Resolution = Resolution.Hour;
            SetUniverseSelection(new MyUniverseSelectionModel());
            SetAlpha(new ConstantAlphaModel(InsightType.Price, InsightDirection.Up, TimeSpan.FromDays(1), 0.025, null));
            SetPortfolioConstruction(new SectorWeightingPortfolioConstructionModel(Resolution.Daily));
            SetExecution(new ImmediateExecutionModel());
        }
    }
	
	public class MyUniverseSelectionModel : FundamentalUniverseSelectionModel
	{
		public MyUniverseSelectionModel()
			: base(true)
		{
		}
		
		public override IEnumerable<Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable<CoarseFundamental> coarse)
		{
		    return 
		    	(from c in coarse
		        where c.HasFundamentalData && c.Price > 0   
		        orderby c.DollarVolume descending   
				select c.Symbol).Take(100);         
		}
		
		public override IEnumerable<Symbol> SelectFine(QCAlgorithm algorithm, IEnumerable<FineFundamental> fine)
		{
			var technology = new List<FineFundamental>();
			technology.AddRange(
				(from f in fine 
				where f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology
				orderby f.MarketCap descending select f).Take(3)
			);
			var financialServices = new List<FineFundamental>(); 
			financialServices.AddRange(
				(from f in fine 
				where f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.FinancialServices
				orderby f.MarketCap descending select f).Take(2)
			);
			var consumerDefensive = new List<FineFundamental>();
			consumerDefensive.AddRange( 
				(from f in fine
				where f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerDefensive
				orderby f.MarketCap descending select f).Take(1)
			);

			var selection = new List<Symbol>();
			selection.AddRange(technology.Select(f=> f.Symbol)); 
			selection.AddRange(financialServices.Select(f=> f.Symbol)); 
			selection.AddRange(consumerDefensive.Select(f=> f.Symbol)); 
			return selection;
		}
	}
    public class SectorWeightingPortfolioConstructionModel : EqualWeightingPortfolioConstructionModel
    {
        private readonly Dictionary<int, List<Symbol>> symbolBySectorCode = new Dictionary<int, List<Symbol>>();
		private readonly Dictionary<Insight, double> result = new Dictionary<Insight, double>(); 
		private decimal sectorBuyingPower = 0;

        public SectorWeightingPortfolioConstructionModel(Resolution resolution)
            : base(resolution)
        {
        }

        public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
        {
            foreach (var security in changes.AddedSecurities)
            {	
            	//1. When new assets are added to the universe, save the Morningstar Sector Code for each security to the variable sectorCode
                var sectorCode = security.Fundamentals?.AssetClassification?.MorningstarSectorCode;
                
                //2. If there is a sectorCode and it is not in the symbolBySectorCode dictionary, save the values as a list 
            	// and append the security symbol as the value in the symbolBySectorCode dictionary 
                if (sectorCode.HasValue)
				{
				    if (!symbolBySectorCode.ContainsKey(sectorCode.Value))
				    {
				        symbolBySectorCode[sectorCode.Value] = new List<Symbol>();
				    }
				    // If a sectorCode exists in the mapping, Add the security Symbol to the dictionary
				    symbolBySectorCode[sectorCode.Value].Add(security.Symbol);
				}
            }
            
            
            foreach (var security in changes.RemovedSecurities)
            {
            	//3. For securities that are removed, save their MorningStar sector code to sectorCode 
                var sectorCode = security.Fundamentals?.AssetClassification?.MorningstarSectorCode;
            	
            	//4. If the saved sectorCode is in the symbolBySectorCode dictionary, remove the sectorCode.
            	// If the saved symbol is a value in the symbolBySectorCode dictionary, remove the symbol
            	if (sectorCode.HasValue)
            	{
            		symbolBySectorCode[sectorCode.Value].Remove(security.Symbol);
            	}
            }
			// We use the super() function to avoid using the base class name explicity
            base.OnSecuritiesChanged(algorithm, changes);
        }    	
    }
}