Overall Statistics
Total Trades
65
Average Win
0.22%
Average Loss
-0.14%
Compounding Annual Return
-65.812%
Drawdown
3.800%
Expectancy
-0.411
Net Profit
-1.941%
Sharpe Ratio
-4.159
Loss Rate
77%
Win Rate
23%
Profit-Loss Ratio
1.57
Alpha
0.113
Beta
-2.764
Annual Standard Deviation
0.232
Annual Variance
0.054
Information Ratio
-4.35
Tracking Error
0.311
Treynor Ratio
0.349
Total Fees
$122.82
using QuantConnect.Algorithm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Securities;
using QuantConnect.Brokerages;

namespace QuantConnect
{
    public class Earnings : QCAlgorithm
    {
        // the changes from the previous universe selection
        private SecurityChanges _changes = SecurityChanges.None;
        // only used in backtest for caching the file results
        private readonly Dictionary<DateTime, List<string>> _backtestSymbolsPerDay = new Dictionary<DateTime, List<string>>();
        List<Security> toOpen = new List<Security>();
        List<Security> toClose = new List<Security>();

        public override void Initialize(){
            // this sets the resolution for data subscriptions added by our universe
            UniverseSettings.Resolution = Resolution.Tick;

            // set our start and end for backtest mode
            SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage);
            SetStartDate(2017, 08, 18);
            SetEndDate(2017, 08, 24);

            var vxxEquity = AddEquity("SPY", Resolution.Minute);
            // Schedule events
            Schedule.On(DateRules.EveryDay("SPY"), TimeRules.AfterMarketOpen("SPY", 5), () => {
                OpenPositions();
            });
            Schedule.On(DateRules.EveryDay("SPY"), TimeRules.AfterMarketOpen("SPY", 10), () => {
                ClosePositions();
            });

            // define a new custom universe that will trigger each day at midnight
            AddUniverse("my-dropbox-universe", Resolution.Daily, dateTime =>
            {
                const string liveUrl = @"https://www.dropbox.com/s/7qqb9zxz7q2n5ib/live_stocks.csv?dl=1";
                const string backtestUrl = @"https://www.dropbox.com/s/fx7n5abh04aqcbs/backtest_stocks.csv?dl=1";
                var url = LiveMode ? liveUrl : backtestUrl;
                using (var client = new WebClient())
                {
                    // handle live mode file format
                    if (LiveMode)
                    {
                        // fetch the file from dropbox
                        var file = client.DownloadString(url);
                        // if we have a file for today, break apart by commas and return symbols
                        if (file.Length > 0) return file.ToCsv();
                        // no symbol today, leave universe unchanged
                        return Universe.Unchanged;
                    }

                    // backtest - first cache the entire file
                    if (_backtestSymbolsPerDay.Count == 0)
                    {
                        // fetch the file from dropbox only if we haven't cached the result already
                        var file = client.DownloadString(url);

                        // split the file into lines and add to our cache
                        foreach (var line in file.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            var csv = line.ToCsv();
                            var date = DateTime.ParseExact(csv[0], "yyyyMMdd", null);
                            var symbols = csv.Skip(1).ToList();
                            _backtestSymbolsPerDay[date] = symbols;
                        }
                    }

                    // if we have symbols for this date return them, else specify Universe.Unchanged
                    List<string> result;
                    if (_backtestSymbolsPerDay.TryGetValue(dateTime.Date, out result))
                    {
                        return result;
                    }
                    return Universe.Unchanged;
                }
            });
        }

        public void OnData(TradeBars data){}

        public override void OnSecuritiesChanged(SecurityChanges changes) {
            Debug("In on securities changed");
            foreach (Security sec in changes.RemovedSecurities) {
                if (sec.Invested) {
                    Debug(String.Format("Adding {0} to list for removal", sec.Symbol.ToString()));
                    toClose.Add(sec);
                }
            }
            foreach (Security sec in changes.AddedSecurities){
                Debug(String.Format("Adding {0} to list for opening", sec.Symbol.ToString()));
                toOpen.Add(sec);
            }
        }

        public void OpenPositions()
        {
            // Create Market Order and trailing stop order
            var weighting = 1m / toOpen.Count;
            foreach (Security sec in toOpen)
            {
                SetHoldings(sec.Symbol, weighting);
            }
        }

        public override void OnOrderEvent(OrderEvent fill)
        {
            string message = String.Format("Order {0} {1} x {2} at {3} commission={4} OrderId={5}",
                  fill.Status.ToString(),
                  fill.FillQuantity,
                  fill.Symbol,
                  fill.FillPrice,
                  fill.OrderFee,
                  fill.OrderId);
            Debug(message);

            if (fill.Status.ToString() == "Filled")
            {
                if (Securities[fill.Symbol].Invested)
                {
                    Debug("How do I submit the trailing stop loss");
                    // LimitOrder(fill.Symbol, -1*fill.FillQuantity, [STOP TRAILING PERCENT], "TRAILINGSTOPLOSS");
                }
            }
        }
        

        public void ClosePositions()
        {
            // Close any remaining
            foreach (Security sec in toClose)
            {
                SetHoldings(sec.Symbol, 0);
            }
        }
    }
}