Overall Statistics
Total Trades
496
Average Win
2.66%
Average Loss
-2.69%
Compounding Annual Return
9.783%
Drawdown
40.400%
Expectancy
0.100
Net Profit
66.407%
Sharpe Ratio
0.492
Loss Rate
45%
Win Rate
55%
Profit-Loss Ratio
0.99
Alpha
0.006
Beta
0.907
Annual Standard Deviation
0.256
Annual Variance
0.065
Information Ratio
-0.03
Tracking Error
0.215
Treynor Ratio
0.139
Total Fees
$0.00
/*
 * 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 TueThruThurs : QCAlgorithm
    {
        string Symbol = null;
        string LevSymbol = null;
        decimal leverage = 1.0m;
        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(2010, 11, 30);  //Set Start Date     
            SetEndDate(2016, 5, 13); 
            SetCash(50000);             //Set Strategy Cash
            SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin);
            //SetBrokerageModel(BrokerageName.TradierBrokerage, AccountType.Margin);
            UniverseSettings.MinimumTimeInUniverse = TimeSpan.FromDays(2190);
            UniverseSettings.FillForward = true;
            Symbol = "SPY"; 
            LevSymbol = "SPXL";
            // Find more symbols here: http://quantconnect.com/data
            AddSecurity(SecurityType.Equity, Symbol, Resolution.Minute);
            AddSecurity(SecurityType.Equity, LevSymbol, Resolution.Minute);
        }

        /// <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)
        {
            try
            {
                bool IsLong = true; 
                TradeBar b = data[Symbol];
                decimal price = 0;
                    if ( IsFirstTradingMin(b) == true )
                        firstBar = b;
                        
                    if ( IsExit(b, out price) == true)
                    {
                        Liquidate();
                        entryBar = null;
                        Log(">>Close>> " + b.Time.ToString() +   " " + Symbol +  " @" + price);
                    }
                    else
                    {
                        if ( IsEntry(b, out price, out IsLong ) == true)
                        {
                            entryBar = b;
                			TradeBar c = data[LevSymbol];
                			price = c.High;
                			decimal qnt = leverage;
                            if ( IsLong == false)
                                qnt = -leverage;
                            SetHoldings(LevSymbol, qnt);
                            //SetHoldings(Symbol, 1.0);
                            Log(">>BUY/sell>> " + b.Time.ToString() + " " + qnt + " " + Symbol +  " @" + price);
                        } // if
                    }
            }
            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;
        }

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

        /// <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.Tuesday
                        || b.Time.Date.DayOfWeek == DayOfWeek.Wednesday
                        || b.Time.Date.DayOfWeek == DayOfWeek.Thursday
                    )
                 && IsFirstTradingMin(b)
                )
            {
                // enter 
                entryPrice = b.Close;
                IsLong = true; 
                rtn = true;
            } // if
            
            // check for Short entry VXX
            // if ( Portfolio.Invested == false
            //     &&  (   
            //             b.Time.Date.DayOfWeek == DayOfWeek.Monday
            //             ||b.Time.Date.DayOfWeek == DayOfWeek.Friday 
            //         )  
            //     && (b.Time.Hour==14  || b.Time.Hour==15 && b.Time.Minute<=30 ) // short after 2pm
            //     )
            // {
            //     // enter short   
            //     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[LevSymbol] != null  )
            {
                if ( // for Long exit
                     Portfolio[LevSymbol].IsLong==true && b.Time.Hour==15 && b.Time.Minute==59  
                     //|| 
                     // for short exit
                     //Portfolio[LevSymbol].IsShort==true
                     //&& ( b.Time.Hour==15 && b.Time.Minute==59 // converts to MarketOnOpen for next day
                     //     ||  GettPercentGain(b, LevSymbol) <= -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();
        }
    }

}