Overall Statistics
Total Trades
672
Average Win
1.30%
Average Loss
-1.25%
Compounding Annual Return
12.922%
Drawdown
14.900%
Expectancy
0.121
Net Profit
57.935%
Sharpe Ratio
0.857
Loss Rate
45%
Win Rate
55%
Profit-Loss Ratio
1.05
Alpha
0.186
Beta
-2.606
Annual Standard Deviation
0.156
Annual Variance
0.024
Information Ratio
0.729
Tracking Error
0.156
Treynor Ratio
-0.051
Total Fees
$1003.67
/*
 * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
 * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using QuantConnect.Data.Market;

namespace QuantConnect.Algorithm.Examples
{
    /// <summary>
    /// Basic template algorithm simply initializes the date range and cash
    /// </summary>
    public class VIXIntraDay : QCAlgorithm
    {
        string Symbol = null;
        int RollingSize = 5;
        RollingWindow<TradeBar> history = null;
        DateTime lastTrade = new DateTime();
        TradeBar entryBar = null;
        TradeBar firstBar = null;
        
        /// <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(2015, 1, 1);  //Set Start Date     
            //SetEndDate(2015, 10, 13); 
            SetCash(10000);             //Set Strategy Cash
            history = new RollingWindow<TradeBar>(RollingSize);
            Symbol = "VXX"; 
            // Find more symbols here: http://quantconnect.com/data
            AddSecurity(SecurityType.Equity, Symbol, Resolution.Minute);
            SetWarmup(TimeSpan.FromMinutes(RollingSize*2));
        }

        /// <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)
        {
        	if (IsWarmingUp) return;
			if (!data.ContainsKey(Symbol)) return;
			
            try
            {
                bool IsLong = true; 
                TradeBar b = data[Symbol];
                //Debug(">> " + b.Time.ToString()  );
                decimal price = 0;
                if (history.Count >= RollingSize ) {
                    if ( IsFirstTradingMin(b) == true )
                        firstBar = b;
                        
                    if ( IsExit(b, out price) == true) {
                        Liquidate();
                        entryBar = null;
                        Debug(">>Close>> " + b.Time.ToString() +   " " + Symbol +  " @" + price);
                    } else {
                        if ( IsEntry(b, out price, out IsLong ) == true) {
                            entryBar = b;
                            int qnt = (int) (Portfolio.Cash / price);
                            if ( IsLong == false)
                                qnt = -qnt;
                            MarketOrder(Symbol, qnt, false);
                            //SetHoldings(Symbol, 1.0);
                            Debug(">>BUY/sell>> " + b.Time.ToString() + " " + qnt + " " + Symbol +  " @" + price);
                        } // if
                    }
                   
                } // if
               
                if ( IsLastTradingMin(data[Symbol]) == true) {
                        history.Add(data[Symbol]);
                        //lastClose = data[Symbol];
                        //Debug("Add a bar " + b.Time.ToString() +" " + (history.Count >= RollingSize)  );
                }
            }
            catch (Exception ex)
            {
                Error("OnData: " + ex.Message + "\r\n\r\n" + ex.StackTrace);
            }
            
        } // OnData

        bool IsLastTradingMin(TradeBar b)
        {
            if ( b.Time.Hour==15 && b.Time.Minute == 59)
                return true;
            else
                return false;
        } // IsLastTradingMin

        bool IsFirstTradingMin(TradeBar b)
        {
            if ( b.Time.Hour==9 && b.Time.Minute == 31)
                return true;
            else
                return false;
        } // IsFirstTradingMin

        /// <summary>
        /// checks if this bar is good for entry
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        bool IsEntry( TradeBar b, out decimal entryPrice, out bool IsLong)
        {
            entryPrice = 0;
            IsLong = true;
            bool rtn = false;

            // check for Long entry VXX
            if ( Portfolio.Invested == false
                &&  (   b.Time.Date.DayOfWeek == DayOfWeek.Monday
                            //|| b.Time.Date.DayOfWeek == DayOfWeek.Tuesday
                        || b.Time.Date.DayOfWeek == DayOfWeek.Wednesday
                        || b.Time.Date.DayOfWeek == DayOfWeek.Thursday
                        || b.Time.Date.DayOfWeek == DayOfWeek.Friday 
                    )
                 && IsFirstTradingMin(b) == true
                 && history[0].Close > history[1].Close // vxx
                 && b.Close < history[0].Close * (decimal)1.01 // vxx open below the Close
                )
            {
                // enter
                //Debug("good day " + b.Time.ToString() +" " + history[0].Close + " " +  history[1].Close );  
                entryPrice = b.Close;
                IsLong = true; 
                rtn = true;
            } // if
            
            // check for Sort entry VXX
            if ( Portfolio.Invested == false
                &&  (   
                        b.Time.Date.DayOfWeek == DayOfWeek.Thursday
                        ||b.Time.Date.DayOfWeek == DayOfWeek.Friday 
                    )
                && history[0].Close < history[1].Close // vxx
                && firstBar.Close < history[0].Close //* (decimal)1.01  // vxx opens below the Close
                && b.Close < firstBar.Close * (decimal)1.01    
                && (b.Time.Hour==14  || b.Time.Hour==15 && b.Time.Minute<=30 ) // buy after 2pm
                )
            {
                // enter
                //Debug("good day " + b.Time.ToString() +" " + history[0].Close + " " +  history[1].Close );   
                entryPrice = b.Close;
                IsLong = false; 
                rtn = true;
            } // if
            
            
            return rtn;
        } // IsEntry

        bool IsExit( TradeBar b, out decimal exit )
        {
            exit = 0;
            bool rtn = false;
            if ( Portfolio.Invested == true && Portfolio[Symbol] != null  )
            {
                if ( // for Long exit
                     Portfolio[Symbol].IsLong==true && b.Time.Hour==10 && b.Time.Minute==45  
                     || 
                     // for short exit
                     Portfolio[Symbol].IsShort==true
                     && ( b.Time.Hour==15 && b.Time.Minute==59 // converts to MarketOnOpen for next day
                          ||  GettPercentGain(b, Symbol) <= -3
                        )
                    )
                {
                    rtn = true;
                    exit = b.Close; 
                }
                
            }
            return rtn;
        } // IsExit
        
        decimal GettPercentGain( TradeBar b, string ticker)
        {
            decimal rtn = 0;
        
            if ( Portfolio[ticker] != null )
            {
                rtn = (Portfolio[ticker].Price - Portfolio[ticker].AveragePrice) / Portfolio[ticker].AveragePrice*100;
                if (Portfolio[ticker].IsShort==true)
                    rtn = -rtn;
            }
            return rtn;
        } // GettPercentGain
    }
}
namespace QuantConnect.Algorithm.Examples 
{

    //
    //	Make sure to change "BasicTemplateAlgorithm" to your algorithm class name, and that all
    //	files use "public partial class" if you want to split up your algorithm namespace into multiple files.
    //

    //public partial class BasicTemplateAlgorithm : QCAlgorithm, IAlgorithm
    //{
    //  Extension functions can go here...(ones that need access to QCAlgorithm functions e.g. Debug, Log etc.)
    //}

    //public class Indicator 
    //{
    //  ...or you can define whole new classes independent of the QuantConnect Context
    //}
    public class RollingWin<T>  : IReadOnlyWindow<T>
    {
        // the backing list object used to hold the data
        public  List<T> _list;
        // read-write lock used for controlling access to the underlying list data structure
        //private readonly ReaderWriterLockSlim _listLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
        // the most recently removed item from the window (fell off the back)
        private T _mostRecentlyRemoved;
        // the total number of samples taken by this indicator
        private decimal _samples;
        // used to locate the last item in the window as an indexer into the _list
        private int _tail;

        /// <summary>
        ///     Initializes a new instance of the RollwingWindow class with the specified window size.
        /// </summary>
        /// <param name="size">The number of items to hold in the window</param>
        public RollingWin(int size)
        {
            if (size < 1)
            {
                throw new ArgumentException("RollingWindow must have size of at least 1.", "size");
            }
            _list = new List<T>(size);
        }

        /// <summary>
        ///     Gets the size of this window
        /// </summary>
        public int Size
        {
            get
            { 
                return _list.Capacity;
            }
        }

        /// <summary>
        ///     Gets the current number of elements in this window
        /// </summary>
        public int Count
        {
            get
            { 
                return _list.Count;
            }
        }

        /// <summary>
        ///     Gets the number of samples that have been added to this window over its lifetime
        /// </summary>
        public decimal Samples
        {
            get
            { 
                 return _samples;
            }
        }

        /// <summary>
        ///     Gets the most recently removed item from the window. This is the
        ///     piece of data that just 'fell off' as a result of the most recent
        ///     add. If no items have been removed, this will throw an exception.
        /// </summary>
        public T MostRecentlyRemoved
        {
            get
            {
                    if (!IsReady)
                    {
                        throw new InvalidOperationException("No items have been removed yet!");
                    }
                    return _mostRecentlyRemoved;
                

            }
        }

        /// <summary>
        ///     Indexes into this window, where index 0 is the most recently
        ///     entered value
        /// </summary>
        /// <param name="i">the index, i</param>
        /// <returns>the ith most recent entry</returns>
        public T this [int i]
        {
            get
            {
                    //_listLock.EnterReadLock();

                    if (i >= Count)
                    {
                        throw new ArgumentOutOfRangeException("i", i, string.Format("Must be between 0 and Count {0}", Count));
                    }
                    return _list[(Count + _tail - i - 1) % Count];
               
            }
            set
            {
                    if (i >= Count)
                    {
                        throw new ArgumentOutOfRangeException("i", i, string.Format("Must be between 0 and Count {0}", Count));
                    }
                    _list[(Count + _tail - i - 1) % Count] = value;
                
            }
        }

        /// <summary>
        ///     Gets a value indicating whether or not this window is ready, i.e,
        ///     it has been filled to its capacity and one has fallen off the back
        /// </summary>
        public bool IsReady
        {
            get
            { 
               return Samples > Size;
            }
        }

        /// <summary>
        ///     Returns an enumerator that iterates through the collection.
        /// </summary>
        /// <returns>
        ///     A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.
        /// </returns>
        /// <filterpriority>1</filterpriority>
        public IEnumerator<T> GetEnumerator()
        {
            // we make a copy on purpose so the enumerator isn't tied 
            // to a mutable object, well it is still mutable but out of scope
            var temp = new List<T>(Count);
            

                for (int i = 0; i < Count; i++)
                {
                    temp.Add(this[i]);
                }
                return temp.GetEnumerator();

        }

        /// <summary>
        ///     Returns an enumerator that iterates through a collection.
        /// </summary>
        /// <returns>
        ///     An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
        /// </returns>
        /// <filterpriority>2</filterpriority>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        /// <summary>
        ///     Adds an item to this window and shifts all other elements
        /// </summary>
        /// <param name="item">The item to be added</param>
        public void Add(T item)
        {
                _samples++;
                if (Size == Count)
                {
                    // keep track of what's the last element
                    // so we can reindex on this[ int ]
                    _mostRecentlyRemoved = _list[_tail];
                    _list[_tail] = item;
                    _tail = (_tail + 1) % Size;
                }
                else
                {
                    _list.Add(item);
                }
        }

        /// <summary>
        ///     Clears this window of all data
        /// </summary>
        public void Reset()
        {
            _samples = 0;
            _list.Clear();
        }
    }

}