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