Overall Statistics
Total Trades
331
Average Win
5.08%
Average Loss
-34.48%
Compounding Annual Return
80.505%
Drawdown
88.500%
Expectancy
0.133
Net Profit
114241.053%
Sharpe Ratio
1.262
Probabilistic Sharpe Ratio
17.268%
Loss Rate
1%
Win Rate
99%
Profit-Loss Ratio
0.15
Alpha
0.753
Beta
5.304
Annual Standard Deviation
0.995
Annual Variance
0.99
Information Ratio
1.293
Tracking Error
0.898
Treynor Ratio
0.237
Total Fees
$0.00
Estimated Strategy Capacity
$190000.00
Lowest Capacity Asset
SPX500USD 8I
using System.Linq;
using System.Collections.Generic;
using MathNet.Numerics.Statistics;
using System.Collections.Concurrent;
namespace QuantConnect.CSharp.Algorithms
{   

    public class ScalpingAlgorithm : QCAlgorithm
    {

	 	private SimpleMovingAverage ema;
	 	private SimpleMovingAverage fma;
		//private RateOfChange roc;
		private RateOfChange rocvix;
	 	private string symbol = "SPX500USD";
		private Delay delayrocvix;
	 	
		decimal lastPrice;
		decimal lastQuantity=0m;
		decimal tppp; //$ delta for taking profit based on KDE
		DateTime vixtime;
        decimal maxProfit;
        MyRollingWindow<double> ws;
        Symbol _vix;

		decimal vix;
		decimal currentKDE;
		const double sigma = 0.03d;
		bool printt = false;

		private List<Symbol> symbols;
		private ArmsIndex t;
        public override void Initialize() 
        {
            SetStartDate(2010, 1, 1); 
        	//SetEndDate(2010, 6, 1);      
            //SetEndDate(DateTime.Now);
            SetCash(10000);

            AddSecurity(SecurityType.Cfd, symbol, Resolution.Minute, Market.Oanda, false, 100m, true);
            _vix = AddData<Fred>(Fred.CBOE.VIX).Symbol;
            SetBenchmark(symbol); 

            fma = new SimpleMovingAverage(9);
            ema = new SimpleMovingAverage(20);
           
            ws = new MyRollingWindow<double>(4*60);
            rocvix = new RateOfChange(Int32.Parse(GetParameter("rocvix")));
			delayrocvix = new Delay(1).Of(rocvix);
			RegisterIndicator(symbol,fma,Resolution.Daily);
			RegisterIndicator(symbol,ema,Resolution.Daily);//, data => data.Value);
			SetWarmup(60*100);
			tppp=decimal.Parse(GetParameter("tppp"));
			foreach(var b in History<QuoteBar>(symbol, 201, Resolution.Daily).ToList())
			{
				fma.Update(new IndicatorDataPoint(b.Time, b.Close));
				ema.Update(new IndicatorDataPoint(b.Time, b.Close));
			}
			foreach(var b in History<QuantConnect.DataSource.Fred>(_vix, 21, Resolution.Daily).ToList())
			{
				rocvix.Update(new IndicatorDataPoint(b.Time, b.Value));
				vix = b.Value;
				vixtime=b.Time;
			}
			foreach(var b in History<QuoteBar>(symbol, 4*60+1, Resolution.Minute).ToList())
			{
	            lastPrice=b.Price;
	            ws.Add((double)lastPrice);//-llastPrice));
			}
			Log("vix "+vix);
			Log("vixtime "+vixtime);
			Log("rocvix "+rocvix.Current.Value);
			Log("rocvix-delay "+delayrocvix.Current.Value);
			Log("fma" + fma);
			Log("ema" + ema);
			//SetBrokerageModel(new MyBrokerageModel(AccountType.Margin)/*BrokerageName.OandaBrokerage, AccountType.Margin*/);
            SetBrokerageModel(BrokerageName.OandaBrokerage, AccountType.Margin);
            UniverseSettings.Resolution = Resolution.Daily;
			            
            AddUniverse(CoarseSelectionFunction,SelectFine);
	    }
	    
        private int _lastMonth = -1;
        // sort the data by daily dollar volume and take the top 'NumberOfSymbols'
        public  IEnumerable<Symbol> CoarseSelectionFunction(IEnumerable<CoarseFundamental> coarse)
        {
        	//if (_lastMonth!=-1)
        	if ( Time.Year == _lastMonth)
            {
                return Universe.Unchanged;
            }

            var top =
                (from x in coarse
                 where x.HasFundamentalData && x.Volume > 0 && x.Price > 5
                 orderby x.DollarVolume descending
                 select x).Take(_numberOfSymbolsCoarse).ToList();

            // we need to return only the symbol objects
            symbols = top.Select(x => x.Symbol).ToList<Symbol>();
            

            _dollarVolumeBySymbol.Clear();
            foreach (var x in top)
            {
                _dollarVolumeBySymbol[x.Symbol] = x.DollarVolume;
            }

            // If no security has met the QC500 criteria, the universe is unchanged.
            // A new selection will be attempted on the next trading day as _lastMonth is not updated
            if (_dollarVolumeBySymbol.Count == 0)
            {
                return Universe.Unchanged;
            }

            return _dollarVolumeBySymbol.Keys;
        }
        
        private readonly Dictionary<Symbol, decimal> _dollarVolumeBySymbol = new Dictionary<Symbol, decimal>();
        private const int _numberOfSymbolsCoarse = 1000;
        private const int _numberOfSymbolsFine = 100;
         /// <summary>
        /// Performs fine selection for the QC500 constituents
        /// The company's headquarter must in the U.S.
        /// The stock must be traded on either the NYSE or NASDAQ
        /// At least half a year since its initial public offering
        /// The stock's market cap must be greater than 500 million
        /// </summary>
        public IEnumerable<Symbol> SelectFine(IEnumerable<FineFundamental> fine)
        {
            var filteredFine =
                (from x in fine
                 where x.CompanyReference.CountryId == "USA" &&
                       (x.CompanyReference.PrimaryExchangeID == "NYS" || x.CompanyReference.PrimaryExchangeID == "NAS") &&
                       (Time - x.SecurityReference.IPODate).Days > 180 &&
                       x.MarketCap > 500000000m
                 select x).ToList();

            var count = filteredFine.Count;

            // If no security has met the QC500 criteria, the universe is unchanged.
            // A new selection will be attempted on the next trading day as _lastMonth is not updated
            if (count == 0)
            {
                return Universe.Unchanged;
            }

            // Update _lastMonth after all QC500 criteria checks passed
            _lastMonth = Time.Year;

            var percent = _numberOfSymbolsFine / (double)count;

            // select stocks with top dollar volume in every single sector
            var topFineBySector =
                (from x in filteredFine
                 // Group by sector
                 group x by x.CompanyReference.IndustryTemplateCode into g
                 let y = from item in g
                         orderby _dollarVolumeBySymbol[item.Symbol] descending
                         select item
                 let c = (int)Math.Ceiling(y.Count() * percent)
                 select new { g.Key, Value = y.Take(c) }
                 ).ToDictionary(x => x.Key, x => x.Value);

            return topFineBySector.SelectMany(x => x.Value)
                .OrderByDescending(x => _dollarVolumeBySymbol[x.Symbol])
                .Take(_numberOfSymbolsFine)
                .Select(x => x.Symbol);
        }
        
        public override void OnData(Slice data)
        {
            if(data.ContainsKey(_vix))
            {
            	vix=data[_vix].Value;
            	vixtime=data[_vix].Time;
            	rocvix.Update(new IndicatorDataPoint(data[_vix].Time, vix));
            	if(IsWarmingUp) return;
            	Log("vix "+vix);
				Log("vixtime "+vixtime);
            }
        }
        public override void OnSecuritiesChanged(SecurityChanges changes)
		{
			var s = changes.AddedSecurities.Where(x=> x.Symbol.Value!="SPX500USD").Select(x => x.Symbol);
		    if (changes.AddedSecurities.Count > 0 && s.ToList().Count>0)
		    {
				t = TRIN(s,Resolution.Daily);
				foreach(var b in History<TradeBar>(s, 3, Resolution.Daily).ToList())
				{
					foreach(var c in b.Values)
					{
			            t.Update(c);
					}
				}
		    } 
		}
		
		public void OnData(QuoteBars data) 
        {   
        	if(IsWarmingUp) return;
        	
        	if(!data.ContainsKey(symbol)) return;
			
			lastPrice=data[symbol].Price;
            ws.Add((double)lastPrice);
  
            if (!ws.IsReady) return;
            if(!printt)
            {
            	Log("vix "+vix);
				Log("vixtime "+vixtime);
				printt=true;
				Log("I'm ready ");
				
            }
            
            if ( IsMarketOpen(symbol) )
            {
				if ( Portfolio[symbol].Invested && lastQuantity>0 )
				{
					var profitPercent = Securities[symbol].Holdings.UnrealizedProfitPercent;
					maxProfit = Math.Max(profitPercent,maxProfit);

					if ( (lastPrice>currentKDE && profitPercent < maxProfit*decimal.Parse(GetParameter("tl")) && maxProfit>decimal.Parse(GetParameter("tp"))) )
					{	
						MarketOrder(symbol,-lastQuantity);
						lastQuantity=0;
						maxProfit=0;
					}
					else if( highvolatity())
					{	
						//STOP loss, market is changing direction
						MarketOrder(symbol,-lastQuantity);
						lastQuantity=0;
						maxProfit=0;
					}
				}

				if ( fma>ema && lastQuantity==0 && t<1.0m)
				{
					// if trending up	
					if(!highvolatity())
					{
						// if volatility is high
						int quantity = maxquantity();
						currentKDE=getKDE();
						if(data[symbol].Bid.Close<currentKDE-1.0m)
						{
							MarketOrder(symbol,quantity);
							lastQuantity=lastQuantity+quantity;
						}
					}
				}
            }
            
        }
        
        private bool highvolatity()
        {
        	return (delayrocvix.Current.Value > decimal.Parse(GetParameter("rocstop")) && delayrocvix.Current.Value<rocvix.Current.Value);
        }
        
        private int maxquantity()
        {
        	var totalPortfolioValue = Portfolio.TotalPortfolioValue;
			var margin = Portfolio.GetMarginRemaining(totalPortfolioValue);
			var freemargin = margin / 2;
			var marginperunit = (lastPrice*0.05m); //margin utilized per unit
			var unitsavailable = margin/marginperunit; //margin utilized per unit
			var maxquantity = Math.Round(unitsavailable*0.22m);
			return (int)maxquantity;
        }
        
        private decimal getKDE()
        {
    		
			double[,] k = KernelDensityEstimation(ws.ToArray(),sigma,ws.ToArray().Length);
			var m = 0d;
			var pp=0m;
			for (var ii=0; ii<k.Length/2-1; ii++)
			{
				if(k[ii,1]>m)
				{
					 m = k[ii,1];
					 pp=(decimal)k[ii,0];
				}
			}
			return pp;
        }
        
        public  double[,] KernelDensityEstimation(double[] data, double sigma, int nsteps)
    	{
	        // probability density function (PDF) signal analysis
	        // Works like ksdensity in mathlab. 
	        // KDE performs kernel density estimation (KDE)on one - dimensional data
	        // http://en.wikipedia.org/wiki/Kernel_density_estimation
	
	        // Input:   -data: input data, one-dimensional
	        //          -sigma: bandwidth(sometimes called "h")
	        //          -nsteps: optional number of abscis points.If nsteps is an
	        //          array, the abscis points will be taken directly from it. (default 100)
	        // Output:  -x: equispaced abscis points
	        //          -y: estimates of p(x)
	
	        // This function is part of the Kernel Methods Toolbox(KMBOX) for MATLAB. 
	        // http://sourceforge.net/p/kmbox
	        // Converted to C# code by ksandric
	
	        double[,] result = new double[nsteps, 2];
	        double[] x = new double[nsteps], y = new double[nsteps];
	
	        double MAX = Double.MinValue, MIN = Double.MaxValue;
	        int N = data.Length; // number of data points
	
	        // Find MIN MAX values in data
	        for (int i = 0; i < N; i++)
	        {
	            if (MAX < data[i])
	            {
	                MAX = data[i];
	            }
	            if (MIN > data[i])
	            {
	                MIN = data[i];
	            }
	        }
	
	        // Like MATLAB linspace(MIN, MAX, nsteps);
	        x[0] = MIN;
	        for (int i = 1; i < nsteps; i++)
	        {
	            x[i] = x[i - 1] + ((MAX - MIN) / nsteps);
	        }
	
	        // kernel density estimation
	        double c = 1.0 / (Math.Sqrt(2 * Math.PI * sigma * sigma));
	        for (int i = 0; i < N; i++)
	        {
	            for (int j = 0; j < nsteps; j++)
	            {
	                y[j] = y[j] + 1.0 / N * c * Math.Exp(-(data[i] - x[j]) * (data[i] - x[j]) / (2 * sigma * sigma));
	            }
	        }
	
	        // compilation of the X,Y to result. Good for creating plot(x, y)
	        for (int i = 0; i < nsteps; i++)
	        {
	            result[i, 0] = x[i];
	            result[i, 1] = y[i];
	        }
	        return result;
	    }
    }
    
}
/*
 * 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;
using System.Collections.Generic;
using System.Threading;
using static QuantConnect.StringExtensions;

namespace QuantConnect.Indicators
{
    /// <summary>
    ///     This is a window that allows for list access semantics,
    ///     where this[0] refers to the most recent item in the
    ///     window and this[Count-1] refers to the last item in the window
    /// </summary>
    /// <typeparam name="T">The type of data in the window</typeparam>
    public class MyRollingWindow<T> : IReadOnlyWindow<T>
    {
        // the backing list object used to hold the data
        private readonly 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 MyRollingWindow(int size)
        {
            if (size < 1)
            {
                throw new ArgumentException("RollingWindow must have size of at least 1.", nameof(size));
            }
            _list = new List<T>(size);
            Size = size;
        }

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

        /// <summary>
        ///     Gets the current number of elements in this window
        /// </summary>
        public int Count
        {
            get
            {
                try
                {
                    _listLock.EnterReadLock();
                    return _list.Count;
                }
                finally
                {
                    _listLock.ExitReadLock();
                }
            }
        }

        /// <summary>
        ///     Gets the number of samples that have been added to this window over its lifetime
        /// </summary>
        public decimal Samples
        {
            get
            {
                try
                {
                    _listLock.EnterReadLock();
                    return _samples;
                }
                finally
                {
                    _listLock.ExitReadLock();
                }
            }
        }

        /// <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
            {
                try
                {
                    _listLock.EnterReadLock();

                    if (Samples <= Size)
                    {
                        throw new InvalidOperationException("No items have been removed yet!");
                    }
                    return _mostRecentlyRemoved;
                }
                finally
                {
                    _listLock.ExitReadLock();
                }

            }
        }
        
        
        /// <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[] ToArray()
        {
        	return _list.ToArray();
        }

        /// <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
            {
                try
                {
                    _listLock.EnterReadLock();

                    if (Count == 0)
                    {
                        throw new ArgumentOutOfRangeException(nameof(i), "Rolling window is empty");
                    }
                    else if (i > Size - 1 || i < 0)
                    {
                        throw new ArgumentOutOfRangeException(nameof(i), i,
                            Invariant($"Index must be between 0 and {Size - 1} (rolling window is of size {Size})")
                        );
                    }
                    else if (i > Count - 1)
                    {
                        throw new ArgumentOutOfRangeException(nameof(i), i,
                            Invariant($"Index must be between 0 and {Count - 1} (entry {i} does not exist yet)")
                        );
                    }

                    return _list[(Count + _tail - i - 1) % Count];
                }
                finally
                {
                    _listLock.ExitReadLock();
                }
            }
            set
            {
                try
                {
                    _listLock.EnterWriteLock();

                    if (i < 0 || i > Count - 1)
                    {
                        throw new ArgumentOutOfRangeException(nameof(i), i, Invariant($"Must be between 0 and {Count - 1}"));
                    }
                    _list[(Count + _tail - i - 1) % Count] = value;
                }
                finally
                {
                    _listLock.ExitWriteLock();
                }
            }
        }

        /// <summary>
        ///     Gets a value indicating whether or not this window is ready, i.e,
        ///     it has been filled to its capacity
        /// </summary>
        public bool IsReady
        {
            get
            {
                try
                {
                    _listLock.EnterReadLock();
                    return Samples >= Size;
                }
                finally
                {
                    _listLock.ExitReadLock();
                }
            }
        }

        /// <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);
            try
            {
                _listLock.EnterReadLock();

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

        }

        /// <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)
        {
            try
            {
                _listLock.EnterWriteLock();

                _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);
                }
            }
            finally
            {
                _listLock.ExitWriteLock();
            }
        }

        /// <summary>
        ///     Clears this window of all data
        /// </summary>
        public void Reset()
        {
            try
            {
                _listLock.EnterWriteLock();

                _samples = 0;
                _list.Clear();
                _tail = 0;
            }
            finally
            {
                _listLock.ExitWriteLock();
            }
        }
    }
}