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); } } } }