diff --git a/QuantConnect.InteractiveBrokersBrokerage.Tests/IBDataDownloaderTests.cs b/QuantConnect.InteractiveBrokersBrokerage.Tests/IBDataDownloaderTests.cs index b5b9c62..ba0cc3e 100644 --- a/QuantConnect.InteractiveBrokersBrokerage.Tests/IBDataDownloaderTests.cs +++ b/QuantConnect.InteractiveBrokersBrokerage.Tests/IBDataDownloaderTests.cs @@ -22,7 +22,7 @@ namespace QuantConnect.Tests.Brokerages.InteractiveBrokers { [TestFixture] - [Ignore("These tests require the IBGateway to be installed.")] + [Explicit("These tests require the IBGateway to be installed.")] public class IBDataDownloaderTests { [TestCase("ES", Resolution.Daily, 15)] diff --git a/QuantConnect.InteractiveBrokersBrokerage.ToolBox/IBDataDownloader.cs b/QuantConnect.InteractiveBrokersBrokerage.ToolBox/IBDataDownloader.cs index d856571..7446ff7 100644 --- a/QuantConnect.InteractiveBrokersBrokerage.ToolBox/IBDataDownloader.cs +++ b/QuantConnect.InteractiveBrokersBrokerage.ToolBox/IBDataDownloader.cs @@ -19,11 +19,9 @@ using QuantConnect.Data; using QuantConnect.Util; using QuantConnect.Securities; -using QuantConnect.Interfaces; using QuantConnect.Data.Market; using System.Collections.Generic; using QuantConnect.Configuration; -using QuantConnect.Lean.Engine.DataFeeds; using QuantConnect.Brokerages.InteractiveBrokers; namespace QuantConnect.ToolBox.IBDownloader @@ -33,6 +31,7 @@ namespace QuantConnect.ToolBox.IBDownloader /// public class IBDataDownloader : IDataDownloader, IDisposable { + private readonly MarketHoursDatabase _marketHoursDatabase = MarketHoursDatabase.FromDataFolder(); private readonly InteractiveBrokersBrokerage _brokerage; /// @@ -40,11 +39,20 @@ public class IBDataDownloader : IDataDownloader, IDisposable /// public IBDataDownloader() { - _brokerage = new InteractiveBrokersBrokerage(null, null, null); + _brokerage = new InteractiveBrokersBrokerage(null, null, null, + Config.Get("ib-account"), + Config.Get("ib-host", "LOCALHOST"), + Config.GetInt("ib-port", 4001), + Config.Get("ib-tws-dir"), + Config.Get("ib-version", InteractiveBrokersBrokerage.DefaultVersion), + Config.Get("ib-user-name"), + Config.Get("ib-password"), + Config.Get("ib-trading-mode"), + Config.GetValue("ib-agent-description", Brokerages.InteractiveBrokers.Client.AgentDescription.Individual), + loadExistingHoldings: false); _brokerage.Connect(); } - /// /// Get historical data enumerable for a single symbol, type and resolution given this start and end time (in UTC). /// @@ -74,8 +82,8 @@ public IEnumerable Get(DataDownloaderGetParameters dataDownloaderGetPa symbols = GetChainSymbols(symbol, true).ToList(); } - var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType); - var dataTimeZone = MarketHoursDatabase.FromDataFolder().GetDataTimeZone(symbol.ID.Market, symbol, symbol.SecurityType); + var exchangeHours = _marketHoursDatabase.GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType); + var dataTimeZone = _marketHoursDatabase.GetDataTimeZone(symbol.ID.Market, symbol, symbol.SecurityType); return symbols .Select(symbol => @@ -131,51 +139,6 @@ public void DownloadAndSave(List symbols, Resolution resolution, Securit writer.DownloadAndSave(_brokerage, symbols, startTimeUtc, endTimeUtc); } - /// - /// Groups a list of bars into a dictionary keyed by date - /// - /// - /// - private static SortedDictionary> GroupBarsByDate(IList bars) - { - var groupedBars = new SortedDictionary>(); - - foreach (var bar in bars) - { - var date = bar.Time.Date; - - if (!groupedBars.ContainsKey(date)) - groupedBars[date] = new List(); - - groupedBars[date].Add(bar); - } - - return groupedBars; - } - - #region Console Helper - - /// - /// Draw a progress bar - /// - /// - /// - /// - /// - private static void ProgressBar(long complete, long maxVal, long barSize, char progressCharacter) - { - - decimal p = (decimal)complete / (decimal)maxVal; - int chars = (int)Math.Floor(p / ((decimal)1 / (decimal)barSize)); - string bar = string.Empty; - bar = bar.PadLeft(chars, progressCharacter); - bar = bar.PadRight(Convert.ToInt32(barSize) - 1); - - Console.Write($"\r[{bar}] {(p * 100).ToStringInvariant("N2")}%"); - } - - #endregion - /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// diff --git a/QuantConnect.InteractiveBrokersBrokerage/InteractiveBrokersBrokerage.cs b/QuantConnect.InteractiveBrokersBrokerage/InteractiveBrokersBrokerage.cs index b42c48f..e3d5e38 100644 --- a/QuantConnect.InteractiveBrokersBrokerage/InteractiveBrokersBrokerage.cs +++ b/QuantConnect.InteractiveBrokersBrokerage/InteractiveBrokersBrokerage.cs @@ -340,8 +340,8 @@ public InteractiveBrokersBrokerage( userName, password, tradingMode, - agentDescription = IB.AgentDescription.Individual, - loadExistingHoldings = true, + agentDescription, + loadExistingHoldings, weeklyRestartUtcTime: weeklyRestartUtcTime); } @@ -4047,7 +4047,7 @@ public IEnumerable LookupSymbols(Symbol symbol, bool includeExpired, str symbol.ID.Market, symbol, symbol.SecurityType, - _algorithm.Portfolio.CashBook.AccountCurrency); + _algorithm != null ? _algorithm.Portfolio.CashBook.AccountCurrency : Currencies.USD); // setting up lookup request var contract = new Contract @@ -4069,7 +4069,14 @@ public IEnumerable LookupSymbols(Symbol symbol, bool includeExpired, str // IB requests for full option chains are rate limited and responses can be delayed up to a minute for each underlying, // so we fetch them from the OCC website instead of using the IB API. // For futures options, we fetch the option chain from CME. - symbols.AddRange(_algorithm.OptionChainProvider.GetOptionContractList(symbol, DateTime.Today)); + if (_algorithm != null) + { + symbols.AddRange(_algorithm.OptionChainProvider.GetOptionContractList(symbol, DateTime.Today)); + } + else + { + symbols.AddRange(Composer.Instance.GetPart().GetOptionContractList(symbol, DateTime.Today)); + } } else if (symbol.SecurityType == SecurityType.Future) { @@ -4600,6 +4607,12 @@ private void OnIbAutomaterOutputDataReceived(object sender, OutputDataReceivedEv return; } + if (e.Data.Contains("Waiting for 2FA confirmation", StringComparison.InvariantCultureIgnoreCase)) + { + OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Information, "2FA", + "Logging into account. Check phone for two-factor authentication verification...")); + } + Log.Trace($"InteractiveBrokersBrokerage.OnIbAutomaterOutputDataReceived(): {e.Data}"); }