/// <summary> /// Creates a new InteractiveBrokersBrokerage from the specified values /// </summary> /// <param name="orderMapping">An instance of IOrderIDMapping used to fetch Order objects by brokerage ID</param> /// <param name="account">The Interactive Brokers account name</param> /// <param name="host">host name or IP address of the machine where TWS is running. Leave blank to connect to the local host.</param> /// <param name="port">must match the port specified in TWS on the Configure>API>Socket Port field.</param> /// <param name="agentDescription">Used for Rule 80A describes the type of trader.</param> public InteractiveBrokersBrokerage(IOrderIDMapping orderMapping, string account, string host, int port, IB.AgentDescription agentDescription = IB.AgentDescription.Individual) : base("Interactive Brokers Brokerage") { _orderMapping = orderMapping; _account = account; _host = host; _port = port; _clientID = IncrementClientID(); _agentDescription = agentDescription; _client = new IB.IBClient(); // set up event handlers _client.UpdatePortfolio += HandlePortfolioUpdates; _client.OrderStatus += HandleOrderStatusUpdates; _client.UpdateAccountValue += HandleUpdateAccountValue; _client.Error += HandleError; // we need to wait until we receive the next valid id from the server _client.NextValidId += (sender, e) => { // only grab this id when we initialize, and we'll manually increment it here to avoid threading issues if (_nextValidID == 0) { _nextValidID = e.OrderId; _waitForNextValidID.Set(); } Log.Trace("InteractiveBrokersBrokerage.HandleNextValidID(): " + e.OrderId); }; }
/// <summary> /// Gets the execution details matching the filter /// </summary> /// <returns>A list of executions matching the filter</returns> public List <IB.ExecDetailsEventArgs> GetExecutions(string symbol, IB.SecurityType?type, string exchange, DateTime?timeSince, IB.ActionSide?side) { var filter = new IB.ExecutionFilter { AcctCode = _account, ClientId = _clientID, Exchange = exchange, SecurityType = type ?? IB.SecurityType.Undefined, Symbol = symbol, Time = timeSince ?? DateTime.MinValue, Side = side ?? IB.ActionSide.Undefined }; var details = new List <IB.ExecDetailsEventArgs>(); using (var client = new IB.IBClient()) { client.Connect(_host, _port, IncrementClientID()); var manualResetEvent = new ManualResetEvent(false); int requestID = GetNextRequestID(); // define our event handlers EventHandler <IB.ExecutionDataEndEventArgs> clientOnExecutionDataEnd = (sender, args) => { if (args.RequestId == requestID) { manualResetEvent.Set(); } }; EventHandler <IB.ExecDetailsEventArgs> clientOnExecDetails = (sender, args) => { if (args.RequestId == requestID) { details.Add(args); } }; client.ExecDetails += clientOnExecDetails; client.ExecutionDataEnd += clientOnExecutionDataEnd; // no need to be fancy with request id since that's all this client does is 1 request client.RequestExecutions(requestID, filter); if (!manualResetEvent.WaitOne(5000)) { throw new TimeoutException("InteractiveBrokersBrokerage.GetExecutions(): Operation took longer than 1 second."); } // remove our event handlers client.ExecDetails -= clientOnExecDetails; client.ExecutionDataEnd -= clientOnExecutionDataEnd; } return(details); }
/// <summary> /// Creates a new InteractiveBrokersBrokerage from the specified values /// </summary> /// <param name="account">The Interactive Brokers account name</param> /// <param name="host">host name or IP address of the machine where TWS is running. Leave blank to connect to the local host.</param> /// <param name="port">must match the port specified in TWS on the Configure>API>Socket Port field.</param> /// <param name="agentDescription">Used for Rule 80A describes the type of trader.</param> public InteractiveBrokersBrokerage(string account, string host, int port, IB.AgentDescription agentDescription = IB.AgentDescription.Individual) : base("Interactive Brokers Brokerage") { _account = account; _host = host; _port = port; _clientID = Interlocked.Increment(ref _nextClientID); _agentDescription = agentDescription; _client = new IB.IBClient(); }
/// <summary> /// Gets the execution details matching the filter /// </summary> /// <returns>A list of executions matching the filter</returns> public List<IB.ExecDetailsEventArgs> GetExecutions(string symbol, IB.SecurityType? type, string exchange, DateTime? timeSince, IB.ActionSide? side) { var filter = new IB.ExecutionFilter { AcctCode = _account, ClientId = _clientID, Exchange = exchange, SecurityType = type ?? IB.SecurityType.Undefined, Symbol = symbol, Time = timeSince ?? DateTime.MinValue, Side = side ?? IB.ActionSide.Undefined }; var details = new List<IB.ExecDetailsEventArgs>(); using (var client = new IB.IBClient()) { client.Connect(_host, _port, IncrementClientID()); var manualResetEvent = new ManualResetEvent(false); int requestID = GetNextRequestID(); // define our event handlers EventHandler<IB.ExecutionDataEndEventArgs> clientOnExecutionDataEnd = (sender, args) => { if (args.RequestId == requestID) manualResetEvent.Set(); }; EventHandler<IB.ExecDetailsEventArgs> clientOnExecDetails = (sender, args) => { if (args.RequestId == requestID) details.Add(args); }; client.ExecDetails += clientOnExecDetails; client.ExecutionDataEnd += clientOnExecutionDataEnd; // no need to be fancy with request id since that's all this client does is 1 request client.RequestExecutions(requestID, filter); if (!manualResetEvent.WaitOne(5000)) { throw new TimeoutException("InteractiveBrokersBrokerage.GetExecutions(): Operation took longer than 1 second."); } // remove our event handlers client.ExecDetails -= clientOnExecDetails; client.ExecutionDataEnd -= clientOnExecutionDataEnd; } return details; }
/// <summary> /// Creates a new InteractiveBrokersBrokerage from the specified values /// </summary> /// <param name="orderProvider">An instance of IOrderProvider used to fetch Order objects by brokerage ID</param> /// <param name="securityProvider">The security provider used to give access to algorithm securities</param> /// <param name="account">The Interactive Brokers account name</param> /// <param name="host">host name or IP address of the machine where TWS is running. Leave blank to connect to the local host.</param> /// <param name="port">must match the port specified in TWS on the Configure>API>Socket Port field.</param> /// <param name="agentDescription">Used for Rule 80A describes the type of trader.</param> public InteractiveBrokersBrokerage(IOrderProvider orderProvider, ISecurityProvider securityProvider, string account, string host, int port, IB.AgentDescription agentDescription = IB.AgentDescription.Individual) : base("Interactive Brokers Brokerage") { _orderProvider = orderProvider; _securityProvider = securityProvider; _account = account; _host = host; _port = port; _clientID = IncrementClientID(); _agentDescription = agentDescription; _client = new IB.IBClient(); // set up event handlers _client.UpdatePortfolio += HandlePortfolioUpdates; _client.OrderStatus += HandleOrderStatusUpdates; _client.UpdateAccountValue += HandleUpdateAccountValue; _client.Error += HandleError; _client.TickPrice += HandleTickPrice; _client.TickSize += HandleTickSize; _client.CurrentTime += HandleBrokerTime; // we need to wait until we receive the next valid id from the server _client.NextValidId += (sender, e) => { // only grab this id when we initialize, and we'll manually increment it here to avoid threading issues if (_nextValidID == 0) { _nextValidID = e.OrderId; _waitForNextValidID.Set(); } Log.Trace("InteractiveBrokersBrokerage.HandleNextValidID(): " + e.OrderId); }; }