Overall Statistics |
Total Trades 1061 Average Win 0.26% Average Loss -0.18% Compounding Annual Return 13.428% Drawdown 12.800% Expectancy 0.099 Net Profit 8.750% Sharpe Ratio 0.979 Loss Rate 55% Win Rate 45% Profit-Loss Ratio 1.45 Alpha 0.123 Beta -0.094 Annual Standard Deviation 0.112 Annual Variance 0.012 Information Ratio -0.229 Tracking Error 0.163 Treynor Ratio -1.159 Total Fees $1159.28 |
using MathNet.Numerics.Distributions; using QuantConnect.Data; using QuantConnect.Data.Market; using QuantConnect.Data.UniverseSelection; using QuantConnect.Indicators; using QuantConnect.Orders; using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace QuantConnect.Algorithm.CSharp { public class BasicTemplateAlgorithm : QCAlgorithm { //Count the number of days that pass, so that the algo only executes every 2 weeks int countDay = 0; //Create a Dictionary to store each security and a rolling window of their closing price for the past 20 trading days Dictionary<Symbol, RollingWindow<decimal>> _storage = new Dictionary<Symbol, RollingWindow<decimal>>(); //Create a list to capture the stocks that are entered into the universe List<Symbol> top10Gainers = new List<Symbol>(); List<Symbol> top10Losers = new List<Symbol>(); //Create list to record the positive and negative price movers each iteration of the algo List<Symbol> recordPositiveChanges = new List<Symbol>(); List<Symbol> recordNegativeChanges = new List<Symbol>(); public override void Initialize() { SetStartDate(2012, 9, 01); SetEndDate(2013, 5, 01); SetCash(50000); UniverseSettings.Resolution = Resolution.Daily; AddUniverse(CoarseSelectionFunction); } public IEnumerable<Symbol> CoarseSelectionFunction(IEnumerable<CoarseFundamental> coarse) { ///Add each security in the coarse library to the dictionary, along with the price for that day to its rolling window ///if the security already exists in the Dictionary, just add that day's price to that security's ///Rolling window. foreach (var coarseItem in coarse) { if (!_storage.ContainsKey(coarseItem.Symbol)) { _storage.Add(coarseItem.Symbol, new RollingWindow<decimal>(20)); } _storage[coarseItem.Symbol].Add(coarseItem.Price); } //Create a list of the top 100 stocks by dollar volume and store by their symbol var findTop100 = (from coarseItem in coarse where _storage[coarseItem.Symbol].Count == 20 orderby coarseItem.DollarVolume descending select coarseItem.Symbol).Take(100); //Count how many days have passed countDay++; //Return empty / nothing until 20 days pass //Then, only return the universe if 1 week has passed yet if (!(countDay >= 20)) return new List<Symbol>(); else if (Time.DayOfWeek == DayOfWeek.Thursday) { //If 1 week has passed, then return a new universe //Clear out the universe list so it can be updated top10Gainers.Clear(); top10Losers.Clear(); //Create a list to contain the top 10 stocks with the highest positive price change top10Gainers = (from symbol in findTop100 let start = _storage[symbol][19] let end = _storage[symbol][0] let delta = (end - start) / start orderby delta descending select symbol).Take(10).ToList(); //Create a list to contain the top 10 stocks with the highest negative price change top10Losers = (from symbol in findTop100 let start = _storage[symbol][19] let end = _storage[symbol][0] let delta = (end - start) / start orderby delta ascending select symbol).Take(10).ToList(); //Create a universe which will be returned to include all stocks that need to be analyzed var universe = new List<Symbol>(); universe.AddRange(top10Gainers); universe.AddRange(top10Losers); return universe; } else return new List<Symbol>(); } public void OnData(TradeBars data) { // schedule an event to fire on certain days of the week if (Time.DayOfWeek == DayOfWeek.Friday) { Liquidate(); //Short stocks that are doing well, and long stocks that have not done well in the past 2 weeks //Then add the respective stocks to a list to be used the next iteration of the algo foreach (var security in top10Gainers) { //Order(security, -10); SetHoldings(security, -.07m); } foreach (var security in top10Losers) { //Order(security, 10); SetHoldings(security, .07m); } } //Console.WriteLine(Portfolio.Cash); } } }