Overall Statistics
Total Trades
129
Average Win
0.32%
Average Loss
-0.88%
Compounding Annual Return
106.922%
Drawdown
36.400%
Expectancy
-0.264
Net Profit
213.138%
Sharpe Ratio
1.581
Loss Rate
46%
Win Rate
54%
Profit-Loss Ratio
0.37
Alpha
0.605
Beta
0.722
Annual Standard Deviation
0.438
Annual Variance
0.192
Information Ratio
1.318
Tracking Error
0.433
Treynor Ratio
0.96
Total Fees
$161.99
using System;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;

namespace QuantConnect 
{   

    public class StopLossExample : QCAlgorithm
    {
    	private SecurityChanges _changes;
    	
    	const decimal StopLossPercent = 0.05m;
    	const string Symbol = "SPY";
    	
        public IDictionary<string, decimal> symH = new Dictionary<string, decimal>();
        public IDictionary<string, decimal> symC = new Dictionary<string, decimal>();

        public IDictionary<string, decimal> ogsym = new Dictionary<string, decimal>();

    	public OrderTicket[] _CurrentOrder = null;        	
    	public OrderTicket[] _StopLoss = null;
    	
        public override void Initialize() 
        {
        	UniverseSettings.Resolution = Resolution.Daily;
        	
            SetStartDate(2016, 1, 1);         
            SetEndDate(DateTime.Now.Date.AddDays(-1));
            
            SetCash(25000);
            
            AddSecurity(SecurityType.Equity, Symbol, Resolution.Daily);
    
            // add a custom universe data source (defaults to usa-equity)
            AddUniverse<NyseTopGainers>("universe-nyse-top-gainers", Resolution.Daily, data =>
            {
                // define our selection criteria
                return from d in data
                       // pick top 2 gainers to bet against
                       where d.TopGainersRank >= 80
                       select d.Symbol;
            });            
            
        }

        public void OnData(TradeBars data, SecurityChanges changes) 
        {   
		  
		  
		  int i = 0;
		  int size = 0;
		  
          foreach (var security in _changes.AddedSecurities){ size++; }
       
		  OrderTicket[] _StopLoss = new OrderTicket[size];
		  OrderTicket[] _CurrentOrder = new OrderTicket[size];
		  
          foreach (var security in _changes.AddedSecurities)
          {
			symH[security.Symbol] = 0;
        	var currentPrice = security.Close;	
          	var qty = CalculateOrderQuantity(security.Symbol, 0.25);
          	
            // If no stock, enter position & set StopLoss
          if (!security.Invested) 
            {
                var quantity = (int)Math.Floor(Portfolio.Cash / currentPrice);
                _CurrentOrder[i] = Order(security.Symbol,  qty);
                _StopLoss[i] = StopMarketOrder(security.Symbol, qty, currentPrice * (1m - StopLossPercent));
            }else if (currentPrice > symH[security.Symbol])
            {
            	// If has stock, update StopLoss if necessary 
            	symH[security.Symbol] = currentPrice;
            	_StopLoss[i].Update( new UpdateOrderFields{ StopPrice = currentPrice * (1m - StopLossPercent) });
            }
            
            i++;
            
          }
          
        }
        
		public override void OnSecuritiesChanged(SecurityChanges changes)
        {
            _changes = changes;
            int i = 0;
		  int size = 0;
		 

          foreach (var security in _changes.AddedSecurities){ size++; }
          OrderTicket[] _CurrentOrder = new OrderTicket[size];
          OrderTicket[] _StopLoss = new OrderTicket[size];
          
            foreach (var security in changes.AddedSecurities)
            {
 				var qty = CalculateOrderQuantity(security.Symbol, 0.25);   
                var currentPrice = security.Close;
            	symC[security.Symbol] = security.Close;

                // enter positions on new securities
                if (!security.Invested && security.Close != 0)
                {
               //     var qty = CalculateOrderQuantity(security.Symbol, 0.25m);
               //     StopLimitOrder(security.Symbol, qty, (security.Price * 0.93m) , (security.Price * 1.03m) );
               //     MarketOnOpenOrder(security.Symbol, qty);
	
				//var quantity = (int)Math.Floor(Portfolio.Cash / currentPrice);
                _CurrentOrder[i] = Order(security.Symbol, qty);
                _StopLoss[i] = StopMarketOrder(security.Symbol, qty, currentPrice * (1m - StopLossPercent));
                Log("Enter  " + security.Symbol + " at " + security.Close);
                
                }
                
                i++;
            }
        
        
        }        
        
 		/// <summary>
        /// Custom data type that uses the wall street journal's top 100 nyse gainers
        /// html page as a live data source, and a csv file that contains the top 10
        /// nyse gainers since the beginning of 2009 until 2015/10/19
        /// </summary>
        public class NyseTopGainers : BaseData
        {
            public int TopGainersRank;

            public override DateTime EndTime
            {
                // define end time as exactly 1 day after Time
                get { return Time + QuantConnect.Time.OneDay; }
                set { Time = value - QuantConnect.Time.OneDay; }
            }

            private int count;
            private DateTime lastDate;
            public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLiveMode)
            {
                if (isLiveMode)
                {
                    // this is actually an html file, we'll handle the parsing accordingly
                    return new SubscriptionDataSource(@"http://www.wsj.com/mdc/public/page/2_3021-gainnyse-gainer.html", SubscriptionTransportMedium.RemoteFile);
                }else{
                	return new SubscriptionDataSource(@"http://www.wsj.com/mdc/public/page/2_3021-gainnyse-gainer-"+ date.Year + date.Month + date.Day + ".html?mod=mdc_pastcalendar", SubscriptionTransportMedium.RemoteFile);
                }
                
                // this has data from 2009.01.01 to 2015.10.19 for top 10 nyse gainers
                //return new SubscriptionDataSource(@"https://www.dropbox.com/s/vrn3p38qberw3df/nyse-gainers.csv?dl=1", SubscriptionTransportMedium.RemoteFile);
            }

            public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode)
            {


                if (lastDate != date)
                {
                    // reset our counter for the new day
                    lastDate = date;
                    count = 0;
                }

                // parse the html into a symbol

                if (!line.StartsWith(@"<a href=""/public/quotes/main.html?symbol="))
                {
                    // we're only looking for lines that contain the symbols
                    return null;
                }

                var lastCloseParen = line.LastIndexOf(")", StringComparison.Ordinal);
                var lastOpenParen = line.LastIndexOf("(", StringComparison.Ordinal);
                if (lastOpenParen == -1 || lastCloseParen == -1)
                {
                    return null;
                }

                var symbolString = line.Substring(lastOpenParen + 1, lastCloseParen - lastOpenParen - 1);
                return new NyseTopGainers
                {
                    Symbol = Symbol.Create(symbolString, SecurityType.Equity, Market.USA),
                    Time = date,
                    // the html has these in order, so we'll keep incrementing until a new day
                    TopGainersRank = ++count
                };
            }
            
        }//End of NyseTopGainers        
        
    }
}