| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using System;
using System.Collections.Generic;
using System.Linq;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// First full-fledged attempt at the ENF data backtesting
/// </summary>
public class ENF1 : QCAlgorithm
{
const string liveDataDownloadUrl = "...tbd...";
const string backtesFDataDownloadUrl = "...tbd...";
private DateTime lastOnDataTime = DateTime.MinValue;
/// <summary>
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
/// </summary>
public override void Initialize()
{
// Load the IKF Data Manager
var url = LiveMode ? liveDataDownloadUrl : liveDataDownloadUrl;
int records = ENFDataManager.LoadData(url);
Debug("ENFDataManager loaded " + records + " records.");
// Set Start and End dates for backtesting -- use our ENFDataManager data range
SetStartDate(2016,11,1);
SetEndDate(2016,11,18);
// Set cash for backtesting purposes
SetCash(100000);
// TODO: !!! ??Is this really necessary?? !!!
// Find more symbols here: http://quantconnect.com/data
AddSecurity(SecurityType.Equity, "SPY", Resolution.Hour);
UniverseSettings.Resolution = Resolution.Second;
AddUniverse(new PreMarketDailyUsEquityUniverse(UniverseSettings, SecurityInitializer, TimeSpan.FromMinutes(60), dateTime =>
{
// If we're LiveMode, then we need to reload the data each day
if (LiveMode)
{
ENFDataManager.LoadData(url);
}
// Return the list of symbols
var symbols = ENFDataManager.SymbolList(dateTime);
Debug("Universe selection trigger time: " + dateTime + " - Number of symbols: " + symbols.Count());
return symbols;
}));
}
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">Slice object keyed by symbol containing the stock data</param>
public void OnData(TradeBars data)
{
//if (lastOnDataTime.Date != data.Time.Date)
if( Time == new DateTime(Time.Year, Time.Month, Time.Day, 10, 0, 0) ||
Time == new DateTime(Time.Year, Time.Month, Time.Day, 13, 0, 0) ||
Time == new DateTime(Time.Year, Time.Month, Time.Day, 15, 30, 0))
{
Debug("OnData: Date: " + Time + " - Count: " + data.Count);
}
//if (Time.TimeOfDay == TimeSpan.FromHours(10))
//{
// Debug("OnData: Date: " + data.Time.Date + " - Count: " + data.Count);
//}
lastOnDataTime = data.Time;
}
}
}/*
* 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.
*/
// Clone of: CustomUniverseTriggerTimesAlgorithm
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Indicators;
using QuantConnect.Securities;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Specifies a universe which fires before us-equity market open each day
/// </summary>
public class PreMarketDailyUsEquityUniverse : UserDefinedUniverse
{
private readonly TimeSpan _timeBeforeMarketOpen;
public PreMarketDailyUsEquityUniverse(UniverseSettings universeSettings, ISecurityInitializer securityInitializer, TimeSpan timeBeforeMarketOpen, Func<DateTime, IEnumerable<string>> selector)
: base(CreateConfiguration(), universeSettings, securityInitializer, TimeSpan.MaxValue, selector)
{
_timeBeforeMarketOpen = timeBeforeMarketOpen;
}
// this configuration is used internally, so we'll create a us-equity configuration
private static SubscriptionDataConfig CreateConfiguration()
{
// use us-equity market hours for 'exchange is open' logic
var marketHoursDbEntry = MarketHoursDatabase.FromDataFolder().GetEntry(QuantConnect.Market.USA, null, SecurityType.Equity);
// this is the time zone the data is in, now in our case, our unvierse doesn't have 'data'
var dataTimeZone = marketHoursDbEntry.DataTimeZone;
var exchangeTimeZone = marketHoursDbEntry.ExchangeHours.TimeZone;
var symbol = Symbol.Create("pre-market-daily-us-equity-universe", SecurityType.Equity, QuantConnect.Market.USA);
return new SubscriptionDataConfig(typeof(Tick), symbol, Resolution.Daily, dataTimeZone, exchangeTimeZone, false, false, true);
}
/// <summary>
/// This funtion is used to determine at what times to fire the selection function
/// </summary>
/// <param name="startTimeUtc">The start of the interval (first date in backtest, launch time in live)</param>
/// <param name="endTimeUtc">The end of the interval (EOD last date in backtest, <see cref="Time.EndOfTime"/> in live</param>
/// <param name="marketHoursDatabase">A market hours database instance for resolving market hours</param>
/// <returns>The date time trigger times in UTC</returns>
public override IEnumerable<DateTime> GetTriggerTimes(DateTime startTimeUtc, DateTime endTimeUtc, MarketHoursDatabase marketHoursDatabase)
{
// convert times to local
var startTimeLocal = startTimeUtc.ConvertFromUtc(TimeZones.NewYork);
var endTimeLocal = endTimeUtc.ConvertFromUtc(TimeZones.NewYork);
// get the us-equity market hours
var exchangeHours = marketHoursDatabase.GetExchangeHours(QuantConnect.Market.USA, null, SecurityType.Equity);
// loop over each tradeable date in our time frame
foreach (var tradeableDate in Time.EachTradeableDay(exchangeHours, startTimeLocal, endTimeLocal))
{
// get the market open time for this date
var marketOpen = exchangeHours.GetNextMarketOpen(tradeableDate, false);
// subtract out how much time before market open we'd like to fire
yield return marketOpen - _timeBeforeMarketOpen;
}
}
}
}using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
namespace QuantConnect.Algorithm.CSharp
{
// Key data types for the data manager
public struct ENFDateSymbol
{
public DateTime Date;
public string Symbol;
}
public struct ENFSignal
{
public decimal? SignalStrength;
public decimal? Probability;
}
/// <summary>
/// First full-fledged attempt at the ENF data backtesting
/// </summary>
public static class ENFDataManager
{
private static SortedDictionary<ENFDateSymbol, ENFSignal[]> enfSignalData = new SortedDictionary<ENFDateSymbol, ENFSignal[]>(new DateSymbolComparer());
private static int lineCount = 0;
/// <summary>
/// Load the data from the URL passed to Initialize()
/// </summary>
/// <returns>The number of records</returns>
/// <param name="url">The Download URL to use to download the IKF CSV data</param>
public static int LoadData(string url)
{
if (string.IsNullOrEmpty(url)) throw new ArgumentNullException("url");
// Clear any previous data and reset counters
Initialize(url);
// Load the raw data into a buffer
//var buffer = DownloadData();
// Parse the buffer into our data structure
//ParseData(buffer);
//return enfSignalData.Count;
return 50;
}
public static IEnumerable<string> SymbolList(DateTime date)
{
List<string> symbols = new List<string>() { "BAC", "CHK", "WLL", "MRO", "VALE", "KMI", "PBR", "AEO", "RIG", "DNR",
"FCX", "QAS", "HAL", "SDRL", "WFT", "ECA", "VRX", "C", "X", "AKS",
"T", "DVN", "WPX", "JPM", "MT", "CLF", "F", "CMRE", "XOM", "COP",
"FB", "SIRI", "AAPL", "MU", "QQQ", "MSFT", "JD", "INTC", "FTR", "CSCO",
"TLT", "BRCD", "XIV", "JBLU", "HBAN", "CSX", "SPLK", "NFLX", "ADSK", "GRPO"
};
Random rnd = new Random();
symbols = symbols.OrderBy(x => rnd.Next()).Take(20).ToList();
return symbols;
}
private static void Initialize(string url)
{
DownloadUrl = url;
enfSignalData.Clear();
lineCount = 0;
}
public static DateTime FirstDate()
{
if (enfSignalData.Count < 1) throw new ApplicationException("No Data Loaded");
// Data should be sorted, so get the Date from the first record
DateTime firstDate = enfSignalData.First().Key.Date;
return firstDate;
}
public static DateTime LastDate()
{
if (enfSignalData.Count < 1) throw new ApplicationException("No Data Loaded");
// Data should be sorted, so get the Date from the last record
DateTime lastDate = enfSignalData.Last().Key.Date;
return lastDate;
}
private static string DownloadData()
{
string buffer = string.Empty;
using (var client = new WebClient())
{
buffer = client.DownloadString(DownloadUrl);
}
return buffer;
}
private static void ParseData(string buffer)
{
if (string.IsNullOrEmpty(buffer)) throw new ArgumentException("buffer");
string[] lines = buffer.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
if (lines.Count() < 1) throw new ApplicationException("No downloaded ENF data to parse.");
foreach (var line in lines)
{
lineCount++;
ParseLine(line);
}
}
private static void ParseLine(string line)
{
if (string.IsNullOrEmpty(line)) throw new ArgumentException("line");
string[] fields = line.Split(',');
if (fields.Count() != 14) throw new ApplicationException("Downloaded data (field count) line " + lineCount + " is invalid");
bool result;
DateTime date;
result = DateTime.TryParse(fields[0], out date);
if (!result) throw new ApplicationException("Downloaded data (field 0) line " + lineCount + " is invalid");
string symbol = fields[1];
int offset = 1;
for (int period = 1; period <= 6; period++)
{
string value1 = fields[period + offset];
string value2 = fields[period + offset + 1];
if (!(string.IsNullOrEmpty(value1) && string.IsNullOrEmpty(value2)))
{
decimal signalStrength;
result = decimal.TryParse(fields[period + offset], out signalStrength);
if (!result) throw new ApplicationException("Downloaded data (field " + (period + offset) + ") line " + lineCount + " is invalid");
decimal probability;
result = decimal.TryParse(fields[period + offset + 1], out probability);
if (!result) throw new ApplicationException("Downloaded data (field " + (period + offset + 1) + ") line " + lineCount + " is invalid");
AddData(date, symbol, period, signalStrength, probability);
}
offset += 1;
}
}
private static void AddData(DateTime dt, string symbol, int period, decimal signalStrength, decimal probability)
{
ENFDateSymbol ds = new ENFDateSymbol() { Date = dt, Symbol = symbol };
ENFSignal[] signals = null;
bool found = enfSignalData.TryGetValue(ds, out signals);
if (!found)
{
signals = new ENFSignal[6];
signals[period - 1] = new ENFSignal() { SignalStrength = signalStrength, Probability = probability };
enfSignalData.Add(ds, signals);
}
else
{
signals[period - 1] = new ENFSignal() { SignalStrength = signalStrength, Probability = probability };
}
}
public static string DownloadUrl { get; private set; }
}
public class DateSymbolComparer : IComparer<ENFDateSymbol>
{
public int Compare(ENFDateSymbol x, ENFDateSymbol y)
{
return ConcatValues(x).CompareTo(ConcatValues(y));
}
public string ConcatValues(ENFDateSymbol z)
{
return z.Date.ToString("yyyy-MM-dd") + "-" + z.Symbol;
}
}
}