Overall Statistics
Total Trades
20
Average Win
0.25%
Average Loss
-0.48%
Compounding Annual Return
-0.720%
Drawdown
2.300%
Expectancy
-0.235
Net Profit
-1.140%
Sharpe Ratio
-0.553
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
0.53
Alpha
-0.008
Beta
0.009
Annual Standard Deviation
0.013
Annual Variance
0
Information Ratio
-0.903
Tracking Error
0.107
Treynor Ratio
-0.799
Total Fees
$109.47
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Data.Consolidators; 
using System.Collections; 
using QuantConnect.Securities;  
using QuantConnect.Models;  

namespace QuantConnect.Algorithm.Examples
{
    /// <summary>
    /// Algorithm that detects over night gaps
    /// </summary>
    public class GapAlgorithm : QCAlgorithm
    {
    	
        //parameters go here
        
    	const decimal StopLossPercent = 0.012m;
    	const decimal TakeProfitPercent = 1.0m;
    	
    	
    	//const decimal StopLossPercent = 0.025m;
    	//const decimal TakeProfitPercent = 0.08m;

        private OrderTicket CurrentOrder;
    	private OrderTicket StopLoss;
    	private OrderTicket ProfitTarget;
    	
    	
        // these are open/close minute bars
        // we'll set the open at the beginning of each day to detect gaps
        TradeBar open;
        // we'll set the close at the end of each day
        TradeBar close;
        private RateOfChangePercent ROCP_1_CFO ;
    	//private RateOfChange ROCPROCPyear;
    	//private ROCPRateOfChangePercent ROCPROCPyear;
        //Define required variables: 
        //int quantity = 1;
        decimal price = 0;
        decimal price_1 = 0;
        decimal price_01 = 1;
    	private string symbol="SPY";
    	
    	private string symbol_1="SPY";
        private  decimal gapChange=0.0m;
        private  decimal ROCP_CFO=0.0m;
        
        
        RollingWindow<TradeBar> _window = new RollingWindow<TradeBar>(2);
        //Set the consolidator period:
        private TimeSpan _barPeriod = TimeSpan.FromDays(1);
        
        //Consolidator Class:
        private Consolidator _consolidator;
        //Initialize the data and resolution you require for your strategy:
        
        /// <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()
        {
        	
        SetStartDate(2004, 01, 01);
            //SetStartDate(2009, 01, 01);//
          	//   SetStartDate(1998, 01, 01);
              //SetStartDate(2002, 07, 03);
            //SetStartDate(2016, 01, 03);
            //SetEndDate(2016, 02, 01);
       SetEndDate(2005, 08, 01);
            //SetEndDate(DateTime.Now.Date.AddDays(-1));
             //   SetEndDate(2016, 11, 05);
            
            AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);
            AddSecurity(SecurityType.Equity, symbol_1, Resolution.Minute);
            
            ROCP_1_CFO = new RateOfChangePercent("SPY", 5); // 252 trading days in a US year
            // RegisterIndicator(symbol,  Resolution.Minute, Field.Close);
            RegisterIndicator(symbol, ROCP_1_CFO, Resolution.Minute, Field.Close);
            
            //Resolution.Minute  Resolution.Hour  Tick   Second
            
            //Setup Consolidator bar bar
            _consolidator = new Consolidator(_barPeriod);
        }

        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">TradeBars IDictionary object with your stock data</param>
        public void OnData(TradeBars data)
        {
        	
        	
        	
            //Date gets updated until the consolidator period and then returns true:
            if (_consolidator.Update(data["SPY"]))
            { 
                var bar = _consolidator.Bar;
                _window.Add(bar);
                if (!_window.IsReady) return;
                //Log("T: " + bar.Time.ToShortTimeString() + " O: " + bar.Open.ToString("C") + " H: " + bar.High.ToString("C") + " L: " + bar.Low.ToString("C") + " C: " + bar.Close.ToString("C"));
               //Log("T: " + bar.Time.ToShortTimeString() + " O: " + bar.Open.ToString("C") + " H: " + bar.High.ToString("C") + " L: " + bar.Low.ToString("C") + " C: " + bar.Close.ToString("C"));
                //Log("T: " + bar.Time.ToShortTimeString() + " O: " + bar.Open.ToString("C") + " H: " + bar.High.ToString("C") + " L: " + bar.Low.ToString("C") + " C: " + bar.Close.ToString("C"));
                //Console.WriteLine(" _window[0].High", _window[0].High);
                
                //Log( " H: " + _window[0].High.ToString("C") );
              
            }
      
            // populate our opening price variable
            if (open == null || open.Time.Date != Time.Date)
            {
                // when TryGetValue succeeds it will populate the 'open'
                // variable with our first minute bar of the day (at 9:31, the bar that spans from 9:30->9:31)
                // if it fails then 'open' will have a value of null
                data.TryGetValue("SPY", out open);
            
                if (open != null && close != null && open.Time.Date != close.Time.Date)
                {
                    // The close of yesterday is greater than the open today.
                    // Gap_Down = Close[1] > Open[0]
                    //bool gapDown = close.Close > open.Open;
                    //decimal gapChange = open.Open/close.Close - 1m;
                    gapChange = open.Open/close.Close - 1m;
                    

                }
            }
            

            if (!_window.IsReady) return;
            price = data[symbol].Close;
            price_1 = data[symbol_1].Close;
           //Get fresh cash balance: Set purchase quantity to equivalent 10% of portfolio.
            decimal cash = Portfolio.Cash;
            
            int holdings = Portfolio[symbol_1].Quantity;
            
            
            ROCP_CFO = price / open.Open-1.0m;
            //if (ROCP_CFO.IsReady && gapChange > 0.003m  && ROCP_CFO > 0.0005m && Time.TimeOfDay == new TimeSpan(9, 37, 0) )
            //if (ROCP_CFO.IsReady && gapChange > 0.003m  && ROCP_CFO > 0.25m && Time.TimeOfDay == new TimeSpan(9, 37, 0) )
            
            if (( gapChange > 0.003m  && Time.TimeOfDay == new TimeSpan(9, 36, 0) )
            && ( ROCP_CFO>0.001m && price  > _window[0].High ) && ((holdings < 0 || holdings == 0)))
            {
                   Console.WriteLine(Time + " - GapUp: " + gapChange.ToString("0.000") );
                   Console.WriteLine(Time + " - CFO:   " + ROCP_CFO);
                   
                   
                   //quantity = Convert.ToInt32((cash * 1.0m)/ price_1);
                   // Calculate quantity based on available cash
            	   var quantity = (int) (Portfolio.Cash / price_1);
            	   
                   //Console.WriteLine(Time + " -Quantity:   " + quantity);
                            //Now go long: Short-EMA crossed above long-EMA by sufficient margin
                   //SetHoldings(symbol_1, 1.0m);
                   
                   price_01=price_1;
                   
                   
                   Log( "Pre_order: " + quantity);
                   
                   Log( "Pre_order: " + holdings);
                   
                   CurrentOrder = Order(symbol_1,  quantity);
                   //Log(Time.ToShortDateString() + "> Go Long >  Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString() + " Samples: " + ROCP_CFO.Samples); 


            	  // Set StopLoss order
                   StopLoss = StopMarketOrder(symbol_1, -quantity, price_1 * (1m - StopLossPercent));
                   
                   // Set Profit Target 
                   ProfitTarget = LimitOrder(symbol_1, -quantity,  price_1 * (1m + TakeProfitPercent));
           	            
           	            
                   Log( "ROCP_1_CFO: " + ROCP_1_CFO );
                   
                   
                   
                   Log( "holdings: " + holdings );
                   Log( "PT order id: " + ProfitTarget.OrderId);
                   Log( "StopLoss order id: " + StopLoss.OrderId);
            }
            
            
            
            if (Time.TimeOfDay == new TimeSpan(9, 40, 0) && ((holdings != 0)))
            {
            	
            	  // Set StopLoss order
                   //StopLoss = StopMarketOrder(symbol_1, -Convert.ToInt32(0.5m* holdings), price_1 * (1m - StopLossPercent));
                   
                   // Set Profit Target 
                   //ProfitTarget = LimitOrder(symbol_1, -Convert.ToInt32(0.5m* holdings),  price_1 * (1m + TakeProfitPercent));

 
                   Log( "Stop loss : " + holdings);
                   
                   
            	  // Set StopLoss order
                   // StopLoss = StopMarketOrder(symbol_1, -1* holdings, price_01 * (1m - StopLossPercent));
                   
                   // Set Profit Target 
                   // ProfitTarget = LimitOrder(symbol_1, -1* holdings,  price_01 * (1m + TakeProfitPercent));
           	            	 
       
                   Log( "holdings: " + holdings );
                  // Log( "PT order id: " + ProfitTarget.OrderId);
                  // Log( "StopLoss order id: " + StopLoss.OrderId);
                   
            }
            
            
            //if (( gapChange < -0.003m  && Time.TimeOfDay == new TimeSpan(9, 36, 0) )
            //&& ( Math.Abs(ROCP_CFO) > 0.003m && price  < Math.Min (_window[0].Low, _window[1].Low)) && (( holdings == 0)))
            //{
            //        Console.WriteLine(Time + " - GapUp: " + gapChange.ToString("0.000") );
            //        Console.WriteLine(Time + " - CFO:   " + ROCP_CFO);
                            //Now go long: Short-EMA crossed above long-EMA by sufficient margin
            //       CurrentOrder = Order(symbol_1, Math.Sign(ROCP_CFO) * quantity);
                   // Log(Time.ToShortDateString() + "> Go Long >  Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString() + " Samples: " + ROCP_CFO.Samples); 
       
                   // Set StopLoss order
           //        StopLoss = StopMarketOrder(symbol, -1* Math.Sign(ROCP_CFO) * quantity, price * (1m - StopLossPercent));
                   // Set Profit Target 
           //        ProfitTarget = LimitOrder(symbol, -1*Math.Sign(ROCP_CFO) * quantity, price * (1m + TakeProfitPercent));
           	 
           //        Log( "ROCP_1_CFO: " + ROCP_1_CFO );
           // }
           
            //if ( ( ROCP_1_CFO > 0.25m && price  > _window[0].Close ) && ((holdings < 0 || holdings == 0)))
            //{
            //       Console.WriteLine(Time + " - GapUp: " + gapChange.ToString("0.000") );
            //       Console.WriteLine(Time + " - CFO:   " + ROCP_CFO);
                            //Now go long: Short-EMA crossed above long-EMA by sufficient margin
            //       Order(symbol, Math.Abs(holdings) + quantity);
                   //Log(Time.ToShortDateString() + "> Go Long >  Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString() + " Samples: " + ROCP_CFO.Samples); 
       
            //}
            
            
            // Log( "Outside H: " + _window[0].High.ToString("C") );
            // we get our last minute bar at 4:00, market is closed,
            // save it into our 'close' variable
            if (Time.TimeOfDay.TotalHours == 16)
            {
                // when TryGetValue succeeds it will populate the 'close'
                // variable with our final minute bar of the day (at $:00)
                // if it fails then 'close' will have a value of null
                data.TryGetValue("SPY", out close);
            }
            
            // at 3:58 liquidate
            if (Portfolio.Invested && Time.TimeOfDay == new TimeSpan(15, 58, 0)  && (holdings != 0))
            {
                Console.WriteLine(Time + " EOD order:   "  + holdings );
                Log( "3:58pm holdings: " + holdings );
                Liquidate();
            }
        }

        // If the StopLoss or ProfitTarget is filled, cancel the other
        // If you don't do this, then  the ProfitTarget or StopLoss order will remain outstanding
        // indefinitely, which will cause very bad behaviors in your algorithm
        public override void OnOrderEvent(OrderEvent orderEvent)
		{
			// Ignore OrderEvents that are not closed
			if (!orderEvent.Status.IsClosed())
			{
				return;
			}
			
			// Defensive check
			if (ProfitTarget == null || StopLoss == null)
			{
				return;
			}
			
			var filledOrderId = orderEvent.OrderId;

			// If the ProfitTarget order was filled, close the StopLoss order
			if (ProfitTarget.OrderId == filledOrderId)
			{
                Console.WriteLine(Time +" ProfitTarget is filled " +ProfitTarget.OrderId + "Filled Order is  " + filledOrderId );
                Log( "ProfitTarget is filled " +ProfitTarget.OrderId );
				StopLoss.Cancel();
			}

			// If the StopLoss order was filled, close the ProfitTarget
			if (StopLoss.OrderId == filledOrderId)
			{   
				Console.WriteLine(Time +  " StopLoss Order is filled " +StopLoss.OrderId + "Filled Order is  " + filledOrderId );
                Log( "StopLoss Order is filled " +StopLoss.OrderId );
				ProfitTarget.Cancel();
			}
			
		}
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using QuantConnect.Securities;
using QuantConnect.Models;

namespace QuantConnect 
{
    
    /*
    *   TimeSpanConsolidator Helper Routine: Assemble generic timespan bar lengths: e.g. 10 minutes:
    *
    *   1. Setup the new Consolidator class with the timespan period:
    *   var _consolidator = new Consolidator(TimeSpan.FromMinutes(10));
    *
    *   2. Add in the data with the update routine. It will return true when bar ready
    *   if (_consolidator.Update(data["MSFT"])) {   UseBar    }
    */
    public class Consolidator 
    {
        private TradeBar _resultBar;
        private TradeBar _workingBar;
        private DateTime _start;
        private TimeSpan _period;
        
        //Result:
        public TradeBar Bar
        {
            get
            {
                return _resultBar;
            }
        }
        
        //Constructor: Set the period we'd like to scan
        public Consolidator(TimeSpan span) 
        {
            this._period = span;
            this._resultBar = new TradeBar();
            this._workingBar = new TradeBar(new DateTime(), "", Decimal.Zero, Decimal.MinValue, Decimal.MaxValue, 0, 0);
        }
        
        //Submit this bar, return true if we've started a new one.
        public bool Update(TradeBar newBar)
        {
            //Intialize:
            if (_start == new DateTime()) 
            {
                _start = newBar.Time;
            }
            
            //While we're less than end date, keep adding to this bar:
            if (newBar.Time < (_start + _period))
            {
                //Building bar:
                AddToBar(newBar);
                return false;
            } 
            else 
            {
                //Completed bar: start new one:
                _resultBar = _workingBar;
                //Create a new bar:
                _workingBar = new TradeBar(newBar.Time, newBar.Symbol, Decimal.Zero, Decimal.MinValue, Decimal.MaxValue, 0, 0);
                //Start of this bar:
                _start = newBar.Time;
                AddToBar(newBar);
                return true;
            }
        }
        
        //Add to a tradebar
        private void AddToBar(TradeBar newBar)
        {
            //Add this data to working bar:
            if (_workingBar.Time == new DateTime()) _workingBar.Time = newBar.Time;
            if (_workingBar.Symbol == "") _workingBar.Symbol = newBar.Symbol;
            if (_workingBar.Open == Decimal.Zero) _workingBar.Open = newBar.Open;
            if (newBar.High > _workingBar.High) _workingBar.High = newBar.High;
            if (newBar.Low < _workingBar.Low) _workingBar.Low = newBar.Low;
            _workingBar.Close = newBar.Close;
            _workingBar.Volume = newBar.Volume;
        }
    }

}