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) { // a new day! 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>() { "WINS", "CRBP", "EBR", "CC", "TWNKW", "EVI", "CYBE", "AMD", "AKS", "WLDN", "CWEI", "PQ", "GGB", "EXEL", "MTL", "FNSR", "WB", "NVDA", "X", "HZN", "SXCP", "ARCW", "WLB", "IDN", "HL", "NAV", "ORN", "HIQ", "OCLR", "QUAD", "AMBR", "CDZI", "NAK", "BOOM", "LEU", "YRD", "IESC", "HDSN", "NC", "SKY", "DLTH", "GV", "VEDL", "KEM", "RMR", "TWI", "MIME", "CARB", "SRT", "CASH" }; Random rnd = new Random((int) DateTime.Now.Ticks & 0x0000FFFF); 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; } } }