Overall Statistics
Total Trades
566
Average Win
1.23%
Average Loss
-0.59%
Compounding Annual Return
-8.442%
Drawdown
62.900%
Expectancy
-0.172
Net Profit
-39.795%
Sharpe Ratio
-0.25
Loss Rate
73%
Win Rate
27%
Profit-Loss Ratio
2.07
Alpha
-0.052
Beta
-0.041
Annual Standard Deviation
0.205
Annual Variance
0.042
Information Ratio
-0.113
Tracking Error
0.285
Treynor Ratio
1.264
Total Fees
$0.00
namespace QuantConnect.Algorithm.CSharp
{
    public class AlphaFiveEnergyUniverse : QCAlgorithm
    {
		private Dictionary<Symbol,AssetData> _universe = new Dictionary<Symbol,AssetData>();
        
        public override void Initialize()
        {
            //1. Required: Five years of backtest history
        	SetStartDate(2014, 1, 1);
        
        	//2. Required: Alpha Streams Models:
        	SetBrokerageModel(BrokerageName.AlphaStreams);
        
	        //3. Required: Significant AUM Capacity
	        SetCash(1000000);
	        
	        //4. Select Desired ETF Universe
	        // See more: https://www.quantconnect.com/docs/algorithm-reference/universes
	        UniverseSettings.Resolution = Resolution.Hour;
	        SetUniverseSelection(new EnergyETFUniverse());

	        //5. Set Relevent Benchmark
	        var reference = "XLE";
	        AddEquity(reference, Resolution.Hour);
	        SetBenchmark("SPY");
	
	        // Demonstration: Consolidation
	        // See more: https://www.quantconnect.com/docs/algorithm-reference/consolidating-data
	        Consolidate(reference, CalendarType.Weekly, ConsolidationDemo);
	        
	        // Demonstration: Scheduled Events
	        // See more: https://www.quantconnect.com/docs/algorithm-reference/scheduled-events
	        Schedule.On(DateRules.Every(DayOfWeek.Monday), TimeRules.AfterMarketOpen(reference, 30), ScheduleDemo);
	        
	        // --------
	        // Optional: Framework Algorithm Models
	        SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
	        SetExecution(new ImmediateExecutionModel());
	        // --------
        }

        /// 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)
        {
        	// Manually update the Indicators
        	foreach (var key in _universe.Keys)
        	{
        		if (data.Bars.ContainsKey(key))
        		{
        			_universe[key].update(data[key].EndTime, data[key].Close);
        		}
        	}
        }
        
        public override void OnSecuritiesChanged(SecurityChanges changes)
        {
        	foreach (var s in changes.AddedSecurities)
        	{
        		if (!_universe.ContainsKey(s.Symbol))
        		{
        			var history = History(s.Symbol, 30, Resolution.Hour);
        			_universe.Add(s.Symbol, new AssetData(s.Symbol,history));
        		}
        	}
        }
        
        public void ScheduleDemo()
        {
        	foreach (var s in ActiveSecurities.Values)
        	{
        		if (_universe[s.Symbol].IsReady() && _universe[s.Symbol].Deviating(s.Price))
        		{
        			EmitInsights(Insight.Price(s.Symbol, TimeSpan.FromDays(3), InsightDirection.Up));
        		}
        	}
        }
        
        public void ConsolidationDemo(TradeBar bar)
        {
        	Debug($"{Time} :: {bar.Time} {bar.Close}");
        }
    }
    
    public class AssetData
    {
    	private StandardDeviation _std = new StandardDeviation(30);
    	private SimpleMovingAverage _mean = new SimpleMovingAverage(7);
    	private Symbol _symbol;
    	
    	public AssetData(Symbol symbol, IEnumerable<TradeBar> history)
    	{
    		_symbol = symbol;
    		foreach (var bar in history)
    		{
    			update(bar.EndTime, bar.Close);
    		}
    	}
    	
    	public bool IsReady()
    	{
    		return _std.IsReady;
    	}
    	
    	public void update(DateTime time, decimal price)
    	{
    		_std.Update(time, price);
			_mean.Update(time, price);
    	}
    	
    	public bool Deviating(decimal price)
    	{
    		if (_std == 0)
    		{
    			return false;
    		}
    		return ((price - _mean) / _std) < -3;
    	}
    }
}