Overall Statistics
Total Trades
16
Average Win
0%
Average Loss
0%
Compounding Annual Return
-3.742%
Drawdown
3.800%
Expectancy
0
Net Profit
-1.627%
Sharpe Ratio
-0.483
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
-0.177
Beta
7.192
Annual Standard Deviation
0.072
Annual Variance
0.005
Information Ratio
-0.755
Tracking Error
0.072
Treynor Ratio
-0.005
Total Fees
$129.09
using System.Collections.Concurrent;
using System;
using System.Collections.Generic;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Indicators;
using QuantConnect.Securities;
 
namespace QuantConnect
{
    /// <summary>
    /// In this algorithm we demonstrate how to perform some technical analysis as
    /// part of your coarse fundamental universe selection
    /// </summary>
    public class SpringDaySelectionAlgorithm : QCAlgorithm
    {
        //Trading vars
        public string benchmark = "SPY";           //Benchmark to compare results to
        public decimal max_trading_amount = 250000; //Total Portfolio Cash to spend
        public int max_long_positions = 25;           //Maximum long postions
        public const int min_price_to_trade = 4;   //Minimum  price
        public long min_volume_to_trade = 50000;  //Minimum daily volume
        public float max_amount_per_trade  = 0;   //The maximium dollar amount to use per trade
        public float max_target_percent = 0;        
        public float holdings_cnt = 0;            
        
        
        private RollingWindow<TradeBar> history;
       
       
         
         
        // tolerance to prevent bouncing
        const decimal Tolerance = 0.01m;
        private const int Count = 10;
        // use Buffer+Count to leave a little in cash
        private const decimal TargetPercent = 0.1m;
        private SecurityChanges _changes = SecurityChanges.None;
        // holds our coarse fundamental indicators by symbol
        private readonly ConcurrentDictionary<Symbol, SelectionData> _averages = new ConcurrentDictionary<Symbol, SelectionData>();
        
      // class used to improve readability of the coarse selection function
        private class SelectionData
        {
            public readonly SimpleMovingAverage Fast;
            public readonly SimpleMovingAverage Slow;
            public readonly SimpleMovingAverage Price;
            public readonly SimpleMovingAverage AverageVolume;
 
            public SelectionData()
            {
                Fast = new SimpleMovingAverage(10);
                Slow = new SimpleMovingAverage(45);
                Price = new SimpleMovingAverage(1);
                AverageVolume = new SimpleMovingAverage(45);
            }
 
            // computes an object score of how much large the fast is than the slow
            public decimal ScaledDelta
            {
                get { return (Fast - Slow)/((Fast + Slow)/2m); }
            }
 
            // updates the EMA50 and EMA100 indicators, returning true when they're both ready
            public bool Update(DateTime time, decimal value, decimal volume)
            {
                //return Fast.Update(time, value) && Slow.Update(time, value) && Price.Update(time, value) && AverageVolume.Update(time, volume);
                return Fast.Update(time, value) && Slow.Update(time, value) && Price.Update(time, value);
            }
             
        }  
        
     
        /// <summary>
        /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
        /// </summary>
         
        public override void Initialize()
        {
            UniverseSettings.Leverage = 1.0m;
            UniverseSettings.Resolution = Resolution.Daily;
 
            SetStartDate(2017, 11, 01);
            SetEndDate(2018, 04, 08);
            SetCash(max_trading_amount);
            history = new RollingWindow<TradeBar>(3);
            max_amount_per_trade = (float) max_trading_amount / (float) max_long_positions;
           
            
            
         AddUniverse(coarse =>
            {
                return (from cf in coarse
                        where cf.Price > 5  
                        where cf.Price < 7
                        where cf.Volume  > 250000
                        let avg = _averages.GetOrAdd(cf.Symbol, sym => new SelectionData())
                        where avg.Update(cf.EndTime, cf.Price, cf.Volume) // Update returns true when the indicators are ready, so don't accept until they are
                        where cf.Price > avg.Slow
                        where cf.Volume > avg.AverageVolume
                        where cf.HasFundamentalData
                        select cf.Symbol);
                        //select cf.Symbol).Take(Count);
                         
             });
         
        }     
 
       
        
         
        
       //===============Main Entry Point after the Coarse/Fine Selections==============
        public void OnData(TradeBars data)
        {
            int i1= 0;
            //Get the symbols that made it through the Selection and get their history
            
                foreach (var security in _changes.AddedSecurities) {     
                    i1++;
                    if (!data.ContainsKey(security.Symbol)) {
                         Debug( String.Format("Missing {0}", security.Symbol ));
                         RemoveSecurity(security.Symbol); //Not Working
                    }
                    else
                    {
                        //acceptableSymbols.Add(symbol); //Symbols with data
                        history.Add(data[security.Symbol]);
                        switch  (history.IsReady)
                        {
                			case false:
                				return;
                				
                			case true:
                				if(!security.Invested) {
	                    
                        			if ( (int)Securities.Count  <=  max_long_positions) { //If we are at max holdings  exit
                                   		int qty = (int) (max_amount_per_trade / (float) data[security.Symbol].Close);
                           				var newTicket = MarketOrder(security.Symbol, qty, asynchronous: true);
                           				Debug (String.Format("1Buy {0} {1} - OHLC[{2:0.00}, {3:0.00}, {4:0.00}, {5:0.00}, {6:0},{7:0}]",  
                        				data.Time.ToString("o"), security.Symbol, data[security.Symbol].Open,
                        				data[security.Symbol].High, data[security.Symbol].Low, data[security.Symbol].Close,
                        				data[security.Symbol].Volume,qty));
                        	
                        				for (int i2 = 0; i2 < 3; i2++) {
											Debug (String.Format("Hist {0} {1} - OHLC[{2:0.00}, {3:0.00}, {4:0.00}, {5:0.00}, {6:0}]",  
                        					data.Time.ToString("o"), security.Symbol, history[i2].Open,
                        					history[i2].High, history[i2].Low, history[i2].Close,
                        					history[i2].Volume));
										}
                        
                    				}
	                    
                				}
            					return;
                		
                       } // End of Case
                   	}
            
        		 Debug (String.Format("Total Symbols from Selection: {0}  data count: {1}",i1, data.Count));   
                 if (_changes == SecurityChanges.None) return;
                }     
        }
             
           
             
 
           
                
      
        
        
        
        /// Event fired each time the we add/remove securities from the data feed
        public override void OnSecuritiesChanged(SecurityChanges changes)  
        {
            _changes = changes;
        }
    }
}