Overall Statistics
Total Trades
10001
Average Win
0.23%
Average Loss
-0.42%
Compounding Annual Return
-2.105%
Drawdown
74.300%
Expectancy
-0.008
Net Profit
-24.843%
Sharpe Ratio
0.05
Probabilistic Sharpe Ratio
0.006%
Loss Rate
36%
Win Rate
64%
Profit-Loss Ratio
0.55
Alpha
-0.042
Beta
0.753
Annual Standard Deviation
0.245
Annual Variance
0.06
Information Ratio
-0.286
Tracking Error
0.21
Treynor Ratio
0.016
Total Fees
$17439.43
namespace QuantConnect
{
    public partial class BootCampTask : QCAlgorithm
    {
        public override void Initialize()
        {
            SetStartDate(2002, 3, 1);
        	SetEndDate(2020, 05, 25);
        	SetCash(100000);
        	UniverseSettings.Resolution = Resolution.Hour;
        	AddUniverseSelection(new LiquidValueUniverseSelectionModel());
        	
        	//1. Create an instance of the LongShortEYAlphaModelLongShortEYAlphaModel()
        	SetAlpha(new LongShortEYAlphaModel());
        	SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
        	SetExecution(new ImmediateExecutionModel());
        	SetRiskManagement(new MaximumDrawdownPercentPerSecurity(0.02m));
        }
        
    }
    
    public class LiquidValueUniverseSelectionModel : FundamentalUniverseSelectionModel
    {
    	private int _lastMonth = -1;    
    	
    	public LiquidValueUniverseSelectionModel()
    		: base(true, null, null)
    	{
    	}
    	
    	public override IEnumerable<Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable<CoarseFundamental> coarse)
    	{
        	if (_lastMonth == algorithm.Time.Month)
        	{
            	return Universe.Unchanged;
        	}
        	
        	_lastMonth = algorithm.Time.Month;
        	
        	var sortedByDollarVolume = coarse
        		.Where(x => x.HasFundamentalData)
        		.OrderByDescending(x => x.DollarVolume);
        	
        	return sortedByDollarVolume
        		.Take(5)
        		.Select(x => x.Symbol);
    	}
    	
    	public override IEnumerable<Symbol> SelectFine(QCAlgorithm algorithm, IEnumerable<FineFundamental> fine)
    	{
        	var sortedByYields = fine.OrderByDescending(x => x.ValuationRatios.EarningYield);
        
        	var universe = sortedByYields.Take(2).Concat(sortedByYields.TakeLast(2));
        	
        	return universe.Select(x => x.Symbol);
    	}
    }
    
    // Define the LongShortEYAlphaModel class 
    public class LongShortEYAlphaModel : AlphaModel
    {
    	private int _lastMonth = -1;
    	private List<Security> _activeSecurities = new List<Security>();
 
		public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data)
		{
			var insights = new List<Insight>();
			
        	//2. If statement to emit signals once a month
        	if(_lastMonth == algorithm.Time.Month){
        		return insights;
        	}
        	_lastMonth = algorithm.Time.Month;
        	//3. Use foreach to emit insights with insight directions 
        	foreach (var security in _activeSecurities){
        		if (data.ContainsKey(security.Symbol)) {
					var yield = security.Fundamentals.ValuationRatios.EarningYield;
					var direction = (InsightDirection) Math.Sign(yield);
					insights.Add(Insight.Price(security.Symbol, TimeSpan.FromDays(28), direction)); 
        		}
        	}
        	
        	// based on whether earnings yield is greater or less than zero once a month
        	return insights;
    	}
    	
    	public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes) {
        	// Handle security changes in from your universe model.
        	foreach (var added in changes.AddedSecurities){
        		_activeSecurities.Add(added);
        	}
        	
        	foreach (var removed in changes.RemovedSecurities){
        		_activeSecurities.Remove(removed);
        	}
    	}
    }
}