public void ClientSellsMarketOrder() { bool orderFilled = false; var manualResetEvent = new ManualResetEvent(false); var ib = new InteractiveBrokersBrokerage(); ib.Connect(); ib.OrderEvent += (sender, args) => { orderFilled = true; manualResetEvent.Set(); }; // sell a single share var order = new Order("AAPL", SecurityType.Equity, -1, OrderType.Market, DateTime.UtcNow); ib.PlaceOrder(order); manualResetEvent.WaitOne(2500); var orderFromIB = AssertOrderOpened(orderFilled, ib, order); Assert.AreEqual(OrderType.Market, orderFromIB.Type); }
public void InitializeBrokerage() { // grabs account info from configuration var securityProvider = new SecurityProvider(); securityProvider[Symbols.USDJPY] = new Security( SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), new SubscriptionDataConfig( typeof(TradeBar), Symbols.USDJPY, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, false, false, false ), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance ); _interactiveBrokersBrokerage = new InteractiveBrokersBrokerage(new QCAlgorithm(), new OrderProvider(_orders), securityProvider); _interactiveBrokersBrokerage.Connect(); }
public void FutureSubscriptions() { using (var ib = new InteractiveBrokersBrokerage(new QCAlgorithm(), new OrderProvider(), new SecurityProvider(), new AggregationManager(), TestGlobals.MapFileProvider)) { ib.Connect(); var gotEsData = false; var gotHsiData = false; var cancelationToken = new CancellationTokenSource(); var es = Symbols.CreateFuturesCanonicalSymbol("ES"); var firstEs = ib.LookupSymbols(es, includeExpired: false).First(); ProcessFeed( ib.Subscribe(GetSubscriptionDataConfig <TradeBar>(firstEs, Resolution.Second), (s, e) => { gotEsData = true; }), cancelationToken, (tick) => Log(tick)); // non USD quote currency, HDK var hsi = Symbols.CreateFuturesCanonicalSymbol("HSI"); var firstHsi = ib.LookupSymbols(hsi, includeExpired: false).First(); ProcessFeed( ib.Subscribe(GetSubscriptionDataConfig <TradeBar>(firstHsi, Resolution.Second), (s, e) => { gotHsiData = true; }), cancelationToken, (tick) => Log(tick)); Thread.Sleep(2000); cancelationToken.Cancel(); cancelationToken.Dispose(); Assert.IsTrue(gotEsData); Assert.IsTrue(gotHsiData); } }
public void GetsTickData() { using (var ib = new InteractiveBrokersBrokerage(new QCAlgorithm(), new OrderProvider(), new SecurityProvider(), new AggregationManager(), new LocalDiskMapFileProvider())) { ib.Connect(); var gotUsdData = false; var gotEurData = false; var cancelationToken = new CancellationTokenSource(); ProcessFeed( ib.Subscribe(GetSubscriptionDataConfig <TradeBar>(Symbols.AAPL, Resolution.Second), (s, e) => { gotUsdData = true; }), cancelationToken, (tick) => Log(tick)); ProcessFeed( ib.Subscribe(GetSubscriptionDataConfig <TradeBar>(Symbols.SPY, Resolution.Second), (s, e) => { gotEurData = true; }), cancelationToken, (tick) => Log(tick)); Thread.Sleep(2000); cancelationToken.Cancel(); cancelationToken.Dispose(); Assert.IsTrue(gotUsdData); Assert.IsTrue(gotEurData); } }
/// <summary> /// Creates a new IBrokerage instance and set ups the environment for the brokerage /// </summary> /// <param name="job">The job packet to create the brokerage for</param> /// <param name="algorithm">The algorithm instance</param> /// <returns>A new brokerage instance</returns> public override IBrokerage CreateBrokerage(LiveNodePacket job, IAlgorithm algorithm) { var errors = new List <string>(); // read values from the brokerage datas var useTws = Config.GetBool("ib-use-tws"); var port = Config.GetInt("ib-port", 4001); var host = Config.Get("ib-host", "127.0.0.1"); var twsDirectory = Config.Get("ib-tws-dir", "C:\\Jts"); var ibControllerDirectory = Config.Get("ib-controller-dir", "C:\\IBController"); var account = Read <string>(job.BrokerageData, "ib-account", errors); var userID = Read <string>(job.BrokerageData, "ib-user-name", errors); var password = Read <string>(job.BrokerageData, "ib-password", errors); var agentDescription = Read <AgentDescription>(job.BrokerageData, "ib-agent-description", errors); if (errors.Count != 0) { // if we had errors then we can't create the instance throw new Exception(string.Join(Environment.NewLine, errors)); } // launch the IB gateway InteractiveBrokersGatewayRunner.Start(ibControllerDirectory, twsDirectory, userID, password, useTws); var ib = new InteractiveBrokersBrokerage(algorithm.Transactions, algorithm.Portfolio, account, host, port, agentDescription); Composer.Instance.AddPart <IDataQueueHandler>(ib); return(ib); }
public void GetsTickData() { InteractiveBrokersGatewayRunner.StartFromConfiguration(); var ib = new InteractiveBrokersBrokerage(new QCAlgorithm(), new OrderProvider(), new SecurityProvider()); ib.Connect(); ib.Subscribe(null, new List <Symbol> { Symbols.USDJPY, Symbols.EURGBP }); Thread.Sleep(1000); var gotUsdData = false; var gotEurData = false; for (int i = 0; i < 20; i++) { foreach (var tick in ib.GetNextTicks()) { Console.WriteLine("{0}: {1} - {2} @ {3}", tick.Time, tick.Symbol, tick.Price, ((Tick)tick).Quantity); gotUsdData |= tick.Symbol == Symbols.USDJPY; gotEurData |= tick.Symbol == Symbols.EURGBP; } } Assert.IsTrue(gotUsdData); Assert.IsTrue(gotEurData); InteractiveBrokersGatewayRunner.Stop(); }
public void InitializeBrokerage() { Log.LogHandler = new NUnitLogHandler(); // grabs account info from configuration var securityProvider = new SecurityProvider(); securityProvider[Symbols.USDJPY] = new Security( SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), new SubscriptionDataConfig( typeof(TradeBar), Symbols.USDJPY, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, false, false, false ), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); _interactiveBrokersBrokerage = new InteractiveBrokersBrokerage( new QCAlgorithm(), new OrderProvider(_orders), securityProvider, new AggregationManager(), TestGlobals.MapFileProvider); _interactiveBrokersBrokerage.Connect(); }
private InteractiveBrokersBrokerage GetBrokerage() { // grabs account info from configuration var securityProvider = new SecurityProvider(); securityProvider[Symbols.USDJPY] = new Security( SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), new SubscriptionDataConfig( typeof(TradeBar), Symbols.USDJPY, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, false, false, false ), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null, new SecurityCache() ); var brokerage = new InteractiveBrokersBrokerage( new QCAlgorithm(), new OrderProvider(_orders), securityProvider, new AggregationManager()); brokerage.Connect(); return(brokerage); }
public void ClientPlacesMarketOrder() { bool orderFilled = false; var manualResetEvent = new ManualResetEvent(false); var ib = new InteractiveBrokersBrokerage(); ib.Connect(); ib.Client.RequestOpenOrders(); ib.OrderEvent += (sender, args) => { orderFilled = true; manualResetEvent.Set(); }; const int buyQuantity = 1; //ib.PlaceOrder(new Order("AAPL", SecurityType.Equity, buyQuantity, OrderType.Market, DateTime.Now)); var order = new Order("AAPL", SecurityType.Equity, buyQuantity, OrderType.Market, DateTime.Now); ib.PlaceOrder(order); manualResetEvent.WaitOne(2500); var orderFromIB = AssertOrderOpened(orderFilled, ib, order); Assert.AreEqual(OrderType.Market, orderFromIB.Type); }
public void ClientCancelsLimitOrder() { OrderStatus status = OrderStatus.New; var manualResetEvent = new ManualResetEvent(false); var ib = new InteractiveBrokersBrokerage(); ib.Connect(); ib.OrderEvent += (sender, args) => { status = args.Status; manualResetEvent.Set(); }; // try to sell a single share at a ridiculous price, we'll cancel this later var order = new Order("AAPL", SecurityType.Equity, -1, OrderType.Limit, DateTime.UtcNow, 100000); ib.PlaceOrder(order); manualResetEvent.WaitOne(2500); ib.CancelOrder(order); manualResetEvent.Reset(); manualResetEvent.WaitOne(2500); Assert.AreEqual(OrderStatus.Canceled, status); }
public void GetsTickData() { InteractiveBrokersGatewayRunner.StartFromConfiguration(); var ib = new InteractiveBrokersBrokerage(new OrderProvider()); ib.Connect(); ib.Subscribe(null, new Dictionary <SecurityType, List <string> > { { SecurityType.Forex, new List <string> { "USDJPY", "EURGBP" } } }); Thread.Sleep(1000); for (int i = 0; i < 10; i++) { foreach (var tick in ib.GetNextTicks()) { Console.WriteLine("{0}: {1} - {2} @ {3}", tick.Time, tick.Symbol, tick.Price, ((Tick)tick).Quantity); } } InteractiveBrokersGatewayRunner.Stop(); }
public void InitializeBrokerage() { InteractiveBrokersGatewayRunner.Start(Config.Get("ib-controller-dir"), Config.Get("ib-tws-dir"), Config.Get("ib-user-name"), Config.Get("ib-password"), Config.Get("ib-trading-mode"), Config.GetBool("ib-use-tws") ); // grabs account info from configuration var securityProvider = new SecurityProvider(); securityProvider[Symbols.USDJPY] = new Security( SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), new SubscriptionDataConfig( typeof(TradeBar), Symbols.USDJPY, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, false, false, false ), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance ); _interactiveBrokersBrokerage = new InteractiveBrokersBrokerage(new QCAlgorithm(), new OrderProvider(_orders), securityProvider); _interactiveBrokersBrokerage.Connect(); }
/// <summary> /// Initializes a new instance of the <see cref="IBDataDownloader"/> class /// </summary> public IBDataDownloader() { var mapFileProvider = Composer.Instance.GetExportedValueByTypeName <IMapFileProvider>( Config.Get("map-file-provider", "LocalDiskMapFileProvider")); _brokerage = new InteractiveBrokersBrokerage(null, null, null, null, mapFileProvider); _brokerage.Connect(); }
public void InitializeBrokerage() { InteractiveBrokersGatewayRunner.Start(Config.Get("ib-account")); // grabs account info from configuration _interactiveBrokersBrokerage = new InteractiveBrokersBrokerage(new OrderMapping(_orders)); _interactiveBrokersBrokerage.Connect(); }
public void ClientPlacesStopLimitOrder() { bool orderFilled = false; var manualResetEvent = new ManualResetEvent(false); var ib = new InteractiveBrokersBrokerage(); ib.Connect(); decimal aapl = 100m; decimal delta = 85.0m; // if we can't get a price then make the delta huge ib.OrderEvent += (sender, args) => { orderFilled = true; aapl = args.FillPrice; delta = 0.02m; manualResetEvent.Set(); }; // get the current market price, couldn't get RequestMarketData to fire tick events int id = 0; ib.PlaceOrder(new Order("AAPL", SecurityType.Equity, 1, OrderType.Market, DateTime.UtcNow) { Id = ++id }); manualResetEvent.WaitOne(2000); manualResetEvent.Reset(); Assert.IsTrue(orderFilled); orderFilled = false; // make a box around the current price +- a little const int quantity = 1; var order = new Order("AAPL", SecurityType.Equity, +quantity, OrderType.StopMarket, DateTime.Now, aapl - delta) { Id = ++id }; ib.PlaceOrder(order); ib.PlaceOrder(new Order("AAPL", SecurityType.Equity, -quantity, OrderType.StopMarket, DateTime.Now, aapl + delta) { Id = ++id }); manualResetEvent.WaitOne(1000); var orderFromIB = AssertOrderOpened(orderFilled, ib, order); Assert.AreEqual(OrderType.StopMarket, orderFromIB.Type); }
public void CreateExpectedFutureContractsWithDifferentCurrencies() { using (var ib = new InteractiveBrokersBrokerage(new QCAlgorithm(), new OrderProvider(), new SecurityProvider(), new AggregationManager(), TestGlobals.MapFileProvider)) { ib.Connect(); Assert.IsTrue(ib.IsConnected); var tickersByMarket = new Dictionary <string, string[]> { { Market.HKFE, new[] { "HSI" } }, { Market.CME, new[] { "ACD", "AJY", "ANE" } }, { Market.CBOT, new[] { "ZC" } } }; foreach (var kvp in tickersByMarket) { var market = kvp.Key; var tickers = kvp.Value; foreach (var ticker in tickers) { var currentSymbol = Symbol.Create(ticker, SecurityType.Future, market); var symbolsFound = ib.LookupSymbols(currentSymbol, false); Assert.IsNotEmpty(symbolsFound); foreach (var symbol in symbolsFound) { Log.Trace($"Symbol found in IB: {symbol}"); } } } } }
public void InitializeBrokerage() { _factory = new InteractiveBrokersBrokerageFactory(); // grabs account info from configuration var job = new LiveNodePacket() { BrokerageData = _factory.BrokerageData }; _interactiveBrokersBrokerage = (InteractiveBrokersBrokerage)_factory.CreateBrokerage(job, InteractiveBrokersBrokerageFactoryTests.AlgorithmDependency); _interactiveBrokersBrokerage.Connect(); }
public void InitializeBrokerage() { InteractiveBrokersGatewayRunner.Start(Config.Get("ib-controller-dir"), Config.Get("ib-tws-dir"), Config.Get("ib-user-name"), Config.Get("ib-password"), Config.GetBool("ib-use-tws") ); // grabs account info from configuration _interactiveBrokersBrokerage = new InteractiveBrokersBrokerage(new OrderProvider(_orders)); _interactiveBrokersBrokerage.Connect(); }
private static Order AssertOrderOpened(bool orderFilled, InteractiveBrokersBrokerage ib, Order order) { // if the order didn't fill check for it as an open order if (!orderFilled) { // find the right order and return it foreach (var openOrder in ib.GetOpenOrders()) { if (openOrder.BrokerId.Any(id => order.BrokerId.Any(x => x == id))) { return(openOrder); } } Assert.Fail("The order was not filled and was unable to be located via GetOpenOrders()"); } Assert.Pass("The order was successfully filled!"); return(null); }
public void GetsTickDataAfterDisconnectionConnectionCycle() { using (var ib = new InteractiveBrokersBrokerage(new QCAlgorithm(), new OrderProvider(), new SecurityProvider())) { ib.Connect(); ib.Subscribe(null, new List <Symbol> { Symbols.USDJPY, Symbols.EURGBP }); ib.Disconnect(); Thread.Sleep(2000); for (var i = 0; i < 20; i++) { foreach (var tick in ib.GetNextTicks()) // we need to make sure we consumer the already sent data, if any { Console.WriteLine("{0}: {1} - {2} @ {3}", tick.Time, tick.Symbol, tick.Price, ((Tick)tick).Quantity); } } ib.Connect(); Thread.Sleep(2000); var gotUsdData = false; var gotEurData = false; for (var i = 0; i < 20; i++) { foreach (var tick in ib.GetNextTicks()) { Console.WriteLine("{0}: {1} - {2} @ {3}", tick.Time, tick.Symbol, tick.Price, ((Tick)tick).Quantity); gotUsdData |= tick.Symbol == Symbols.USDJPY; gotEurData |= tick.Symbol == Symbols.EURGBP; } } Assert.IsTrue(gotUsdData); Assert.IsTrue(gotEurData); } }
/// <summary> /// Initializes a new instance of the <see cref="IBDataDownloader"/> class /// </summary> public IBDataDownloader() { _brokerage = new InteractiveBrokersBrokerage(null, null, null, null); _brokerage.Connect(); }
public void Teardown() { try { // give the tear down a header so we can easily find it in the logs Log.Trace("-----"); Log.Trace("InteractiveBrokersBrokerageTests.Teardown(): Starting teardown..."); Log.Trace("-----"); var canceledResetEvent = new ManualResetEvent(false); var filledResetEvent = new ManualResetEvent(false); _interactiveBrokersBrokerage.OrderStatusChanged += (sender, orderEvent) => { if (orderEvent.Status == OrderStatus.Filled) { filledResetEvent.Set(); } if (orderEvent.Status == OrderStatus.Canceled) { canceledResetEvent.Set(); } }; // cancel all open orders Log.Trace("InteractiveBrokersBrokerageTests.Teardown(): Canceling open orders..."); var orders = _interactiveBrokersBrokerage.GetOpenOrders(); foreach (var order in orders) { _interactiveBrokersBrokerage.CancelOrder(order); canceledResetEvent.WaitOne(3000); canceledResetEvent.Reset(); } Log.Trace("InteractiveBrokersBrokerageTests.Teardown(): Liquidating open positions..."); // liquidate all positions var holdings = _interactiveBrokersBrokerage.GetAccountHoldings(); foreach (var holding in holdings.Where(x => x.Quantity != 0)) { //var liquidate = new MarketOrder(holding.Symbol, (int) -holding.Quantity, DateTime.UtcNow, type: holding.Type); //_interactiveBrokersBrokerage.PlaceOrder(liquidate); //filledResetEvent.WaitOne(3000); //filledResetEvent.Reset(); } var openOrdersText = _interactiveBrokersBrokerage.GetOpenOrders().Select(x => x.Symbol.ToString() + " " + x.Quantity); Log.Trace("InteractiveBrokersBrokerageTests.Teardown(): Open orders: " + string.Join(", ", openOrdersText)); //Assert.AreEqual(0, actualOpenOrderCount, "Failed to verify that there are zero open orders."); var holdingsText = _interactiveBrokersBrokerage.GetAccountHoldings().Where(x => x.Quantity != 0).Select(x => x.Symbol.ToString() + " " + x.Quantity); Log.Trace("InteractiveBrokersBrokerageTests.Teardown(): Account holdings: " + string.Join(", ", holdingsText)); //Assert.AreEqual(0, holdingsCount, "Failed to verify that there are zero account holdings."); _interactiveBrokersBrokerage.Dispose(); _interactiveBrokersBrokerage = null; _orders.Clear(); } finally { InteractiveBrokersGatewayRunner.Stop(); } }
public void ClientConnects() { var ib = new InteractiveBrokersBrokerage(); ib.Connect(); }
/// <summary> /// Downloads the financial advisor configuration /// </summary> /// <param name="client">The IB client</param> /// <returns>true if successfully completed</returns> public bool Load(InteractiveBrokersClient client) { var faResetEvent = new AutoResetEvent(false); var xmlGroups = string.Empty; var xmlProfiles = string.Empty; var xmlAliases = string.Empty; EventHandler <ReceiveFaEventArgs> handler = (sender, e) => { switch (e.FaDataType) { case Constants.FaAliases: xmlAliases = e.FaXmlData; break; case Constants.FaGroups: xmlGroups = e.FaXmlData; break; case Constants.FaProfiles: xmlProfiles = e.FaXmlData; break; } faResetEvent.Set(); }; client.ReceiveFa += handler; // request FA Aliases Log.Trace("InteractiveBrokersBrokerage.DownloadFinancialAdvisorConfiguration(): requesting FA Aliases"); client.ClientSocket.requestFA(Constants.FaAliases); if (!faResetEvent.WaitOne(2000)) { Log.Trace("InteractiveBrokersBrokerage.DownloadFinancialAdvisorConfiguration(): Download FA Aliases failed. Operation took longer than 2 seconds."); return(false); } // request FA Groups Log.Trace("InteractiveBrokersBrokerage.DownloadFinancialAdvisorConfiguration(): requesting FA Groups"); client.ClientSocket.requestFA(Constants.FaGroups); if (!faResetEvent.WaitOne(2000)) { Log.Trace("InteractiveBrokersBrokerage.DownloadFinancialAdvisorConfiguration(): Download FA Groups failed. Operation took longer than 2 seconds."); return(false); } // request FA Profiles Log.Trace("InteractiveBrokersBrokerage.DownloadFinancialAdvisorConfiguration(): requesting FA Profiles"); client.ClientSocket.requestFA(Constants.FaProfiles); if (!faResetEvent.WaitOne(2000)) { Log.Trace("InteractiveBrokersBrokerage.DownloadFinancialAdvisorConfiguration(): Download FA Profiles failed. Operation took longer than 2 seconds."); return(false); } client.ReceiveFa -= handler; // load FA configuration var serializer = new XmlSerializer(typeof(List <AccountAlias>), new XmlRootAttribute("ListOfAccountAliases")); using (var stringReader = new StringReader(xmlAliases)) { _accountAliases = (List <AccountAlias>)serializer.Deserialize(stringReader); Log.Trace("InteractiveBrokersBrokerage.DownloadFinancialAdvisorConfiguration(): FA Aliases found: " + _accountAliases.Count); } serializer = new XmlSerializer(typeof(List <Group>), new XmlRootAttribute("ListOfGroups")); using (var stringReader = new StringReader(xmlGroups)) { _accountGroups = (List <Group>)serializer.Deserialize(stringReader); Log.Trace("InteractiveBrokersBrokerage.DownloadFinancialAdvisorConfiguration(): FA Groups found: " + _accountGroups.Count); } serializer = new XmlSerializer(typeof(List <AllocationProfile>), new XmlRootAttribute("ListOfAllocationProfiles")); using (var stringReader = new StringReader(xmlProfiles)) { _allocationProfiles = (List <AllocationProfile>)serializer.Deserialize(stringReader); Log.Trace("InteractiveBrokersBrokerage.DownloadFinancialAdvisorConfiguration(): FA Profiles found: " + _allocationProfiles.Count); } // save the master account code var entry = _accountAliases.FirstOrDefault(x => InteractiveBrokersBrokerage.IsMasterAccount(x.Account)); if (entry == null) { throw new Exception("The Financial Advisor master account was not found."); } MasterAccount = entry.Account; return(true); }
public void CreatesExpectedFuturesContracts() { var symbolMapper = new InteractiveBrokersSymbolMapper(); using (var ib = new InteractiveBrokersBrokerage(new QCAlgorithm(), new OrderProvider(), new SecurityProvider(), new AggregationManager())) { ib.Connect(); Assert.IsTrue(ib.IsConnected); var ibMarkets = new Dictionary <string, string> { { Market.CME, "GLOBEX" }, { Market.NYMEX, "NYMEX" }, { Market.COMEX, "NYMEX" }, { Market.CBOT, "ECBOT" }, { Market.ICE, "NYBOT" }, { Market.CBOE, "CFE" } }; var tickersByMarket = new Dictionary <string, string[]> { { Market.CBOE, new[] { "VX" } }, { Market.CBOT, new[] { "AW", //"BCF", //"BWF", "EH", "F1U", "KE", "TN", "UB", "YM", "ZB", "ZC", "ZF", "ZL", "ZM", "ZN", "ZO", "ZS", "ZT", "ZW", } }, { Market.CME, new[] { "6A", "6B", "6C", "6E", "6J", "6L", "6M", "6N", "6R", "6S", "6Z", //"ACD", //"AJY", //"ANE", "BIO", "BTC", "CB", //"CJY", //"CNH", "CSC", //"DC", "DY", "E7", //"EAD", //"ECD", //"EI", "EMD", "ES", //"ESK", "GD", "GDK", "GE", "GF", //"GNF", "HE", //"IBV", "J7", //"LBS", "LE", "NKD", "NQ", "RTY", } }, { Market.COMEX, new[] { //"AUP", //"EDP", "GC", "HG", "SI", } }, { Market.ICE, new[] { "B", "CC", "CT", "DX", "G", "KC", "OJ", "SB", } }, { Market.NYMEX, new[] { //"1S", //"22", //"A0D", //"A0F", //"A1L", //"A1M", //"A1R", //"A32", //"A3G", //"A7E", //"A7I", //"A7Q", //"A8J", //"A8K", //"A8O", //"A91", //"A9N", //"AA6", //"AA8", //"ABS", "ABT", //"AC0", //"AD0", //"ADB", //"AE5", //"AGA", //"AJL", //"AJS", //"AKL", //"AKZ", //"APS", //"AR0", "ARE", //"AVZ", //"AYV", //"AYX", //"AZ1", //"B0", //"B7H", "BK", //"BOO", //"BR7", "BZ", "CL", //"CRB", //"CSW", "CSX", //"CU", //"D1N", //"DCB", //"E6", //"EN", //"EPN", //"EVC", "EWG", //"EWN", "EXR", //"FO", "FRC", //"FSS", //"GCU", //"HCL", "HH", "HO", "HP", "HRC", //"HTT", "NG", "PA", "PL", "RB", //"YO", } } }; foreach (var kvp in tickersByMarket) { var market = kvp.Key; var tickers = kvp.Value; foreach (var ticker in tickers) { var contract = new Contract { Symbol = symbolMapper.GetBrokerageRootSymbol(ticker), Currency = Currencies.USD, Exchange = null, SecType = "FUT" }; Log.Trace($"Market: {market} - Future Ticker: {ticker}"); var results = ib.FindContracts(contract, contract.Symbol); foreach (var contractDetails in results.Where(x => ibMarkets.Values.Contains(x.Contract.Exchange))) { var message = $" - ContractDetails: {contractDetails.Contract} {contractDetails.ContractMonth}"; Log.Trace(message); Assert.AreEqual(ibMarkets[market], contractDetails.Contract.Exchange, message); } } } } }