public void Connect() { if (!IsConnected) { try { Client.ClientSocket.eConnect(Hostname, Port, ClientId); Reader = new IB.EReader(Client.ClientSocket, Signal); Reader.Start(); new Thread(() => { while (Client.ClientSocket.IsConnected()) { Signal.waitForSignal(); Reader.processMsgs(); } }) { IsBackground = true }.Start(); IsConnected = Client.ClientSocket.IsConnected(); } catch (Exception e) { string errorMsg = "Please check your connection attributes"; ErrorHandler(-1, -1, errorMsg, e); } } }
/** * @brief Creates socket connection to TWS/IBG. */ public void eConnect(string host, int port, int clientId, bool extraAuth) { if (isConnected) { wrapper.error(IncomingMessage.NotValid, EClientErrors.AlreadyConnected.Code, EClientErrors.AlreadyConnected.Message); return; } try { tcpStream = createClientStream(host, port); this.port = port; socketTransport = new ESocket(tcpStream); this.clientId = clientId; this.extraAuth = extraAuth; sendConnectRequest(); if (!AsyncEConnect) { var eReader = new EReader(this, eReaderSignal); while (serverVersion == 0 && eReader.putMessageToQueue()) { eReaderSignal.waitForSignal(); eReader.processMsgs(); } } } catch (ArgumentNullException ane) { wrapper.error(ane); } catch (SocketException se) { wrapper.error(se); } catch (EClientException e) { var cmp = (e as EClientException).Err; wrapper.error(-1, cmp.Code, cmp.Message); } catch (Exception e) { wrapper.error(e); } }
public virtual bool Connect(int p_socketPort, int p_brokerConnectionClientID) { Utils.Logger.Info($"ClientSocket.eConnect(127.0.0.1, {p_socketPort}, {p_brokerConnectionClientID}, false)"); ClientSocket.eConnect("127.0.0.1", p_socketPort, p_brokerConnectionClientID, false); //Create a reader to consume messages from the TWS. The EReader will consume the incoming messages and put them in a queue m_eReader = new EReader(ClientSocket, Signal); m_eReader.Start(); //Once the messages are in the queue, an additional thread need to fetch them. This is a very long running Thread, always waiting for all messages (Price, historicalData, etc.). This Thread calls the IbWrapper Callbacks. new Thread(() => { try { while (ClientSocket.IsConnected()) { Signal.waitForSignal(); // the reader thread will sign the Signal m_eReader.processMsgs(); } } catch (Exception e) { if (Utils.MainThreadIsExiting.IsSet) return; // if App is exiting gracefully, this Exception is not a problem Utils.Logger.Error("Exception caught in Gateway Thread that is fetching messages. " + e.Message + " ,InnerException: " + ((e.InnerException != null) ? e.InnerException.Message : "")); throw; // else, rethrow. This will Crash the App, which is OK. Without IB connection, there is no point to continue the VBroker App. } }) { IsBackground = true }.Start(); /*************************************************************************************************************************************************/ /* One (although primitive) way of knowing if we can proceed is by monitoring the order's nextValidId reception which comes down automatically after connecting. */ /*************************************************************************************************************************************************/ //This is returned at Connection: //Account list: U1****6 //Next Valid Id: 1 DateTime startWaitConnection = DateTime.UtcNow; while (NextOrderId <= 0) { Thread.Sleep(100); if ((DateTime.UtcNow - startWaitConnection).TotalSeconds > 5.0) { return false; } } return true; }
/** * @brief Establishes a connection to the designated THost. * After establishing a connection succesfully, the Host will provide the next valid order id, server's current time, managed accounts and open orders among others depending on the Host version. * @param host the Host's IP address. Leave blank for localhost. * @param port the Host's port. 7496 by default for the TWS, 4001 by default on the Gateway. * @param clientId Every API client program requires a unique id which can be any integer. Note that up to eight clients can be connected simultaneously to a single Host. * @sa EWrapper, EWrapper::nextValidId, EWrapper::currentTime */ public void eConnect(string host, int port, int clientId) { if (isConnected) { wrapper.error(IncomingMessage.NotValid, EClientErrors.AlreadyConnected.Code, EClientErrors.AlreadyConnected.Message); return; } try { tcpClient = new TcpClient(host, port); tcpClientStream = tcpClient.GetStream(); tcpWriter = new BinaryWriter(tcpClientStream); reader = new EReader(this, new BinaryReader(tcpClientStream)); try { tcpWriter.Write(UTF8Encoding.UTF8.GetBytes(Constants.ClientVersion.ToString())); tcpWriter.Write(Constants.EOL); } catch (IOException) { wrapper.error("Could not establish connection. Make sure the TWS is enabled to accept socket clients!"); throw; } // Receive the response from the remote device. serverVersion = reader.ReadInt(); if (!CheckServerVersion(MinServerVer.MIN_VERSION, "")) { ReportUpdateTWS(""); return; } if (serverVersion >= 20) { string twsTime = reader.ReadString(); Console.WriteLine("TWS time: " + twsTime); } if (serverVersion >= 3) { tcpWriter.Write(UTF8Encoding.UTF8.GetBytes(clientId.ToString())); tcpWriter.Write(Constants.EOL); } reader.Start(); while (!reader.IsAlive()) ; isConnected = true; } catch (ArgumentNullException ane) { wrapper.error(ane); } catch (SocketException se) { wrapper.error(se); } catch (Exception e) { wrapper.error(e); } }
/** * @brief Closes the socket connection and terminates its thread. */ public void eDisconnect() { if(tcpWriter == null) { return; } isConnected = false; serverVersion = 0; if (tcpWriter != null) { tcpWriter.Close(); tcpWriter = null; tcpClientStream.Close(); tcpWriter = null; } if (reader != null) { try { reader.Interrupt(); reader = null; } catch (Exception) { throw; } } wrapper.connectionClosed(); }
public void eConnect(string host, int port, int clientId, bool extraAuth) { if (isConnected) { wrapper.error(IncomingMessage.NotValid, EClientErrors.AlreadyConnected.Code, EClientErrors.AlreadyConnected.Message); return; } try { tcpStream = createClientStream(host, port); this.port = port; socketTransport = new ESocket(tcpStream); this.clientId = clientId; this.extraAuth = extraAuth; sendConnectRequest(); if (!AsyncEConnect) { var eReader = new EReader(this, eReaderSignal); while (serverVersion == 0 && eReader.putMessageToQueue()) { eReaderSignal.waitForSignal(); eReader.processMsgs(); } } } catch (ArgumentNullException ane) { wrapper.error(ane); } catch (SocketException se) { wrapper.error(se); } catch (EClientException e) { var cmp = (e as EClientException).Err; wrapper.error(-1, cmp.Code, cmp.Message); } catch (Exception e) { wrapper.error(e); } }
/// <summary> /// Connects the client to the IB gateway /// </summary> public override void Connect() { if (IsConnected) return; // we're going to receive fresh values for both of these collections, so clear them _accountHoldings.Clear(); _accountProperties.Clear(); var attempt = 1; const int maxAttempts = 65; while (true) { try { Log.Trace("InteractiveBrokersBrokerage.Connect(): Attempting to connect ({0}/{1}) ...", attempt, maxAttempts); // we're going to try and connect several times, if successful break _client.ClientSocket.eConnect(_host, _port, _clientId); // create the message processing thread var signal = new EReaderMonitorSignal(); var reader = new EReader(_client.ClientSocket, signal); reader.Start(); var messageProcessingThread = new Thread(() => { Log.Trace("IB message processing thread started."); while (_client.ClientSocket.IsConnected()) { try { signal.waitForSignal(); reader.processMsgs(); } catch (Exception error) { // error in message processing thread, log error and disconnect Log.Error("Error in message processing thread: " + error); } } Log.Trace("IB message processing thread ended."); }) { IsBackground = true }; messageProcessingThread.Start(); // pause for a moment to receive next valid ID message from gateway if (!_waitForNextValidId.WaitOne(15000)) { Log.Trace("InteractiveBrokersBrokerage.Connect(): Operation took longer than 15 seconds."); // no response, disconnect and retry _client.ClientSocket.eDisconnect(); messageProcessingThread.Join(); // max out at 65 attempts to connect ~1 minute if (attempt++ < maxAttempts) { Thread.Sleep(1000); continue; } throw new TimeoutException("InteractiveBrokersBrokerage.Connect(): Operation took longer than 15 seconds."); } Log.Trace("IB next valid id received."); if (!_client.Connected) throw new Exception("InteractiveBrokersBrokerage.Connect(): Connection returned but was not in connected state."); break; } catch (Exception err) { // max out at 65 attempts to connect ~1 minute if (attempt++ < maxAttempts) { Thread.Sleep(1000); continue; } // we couldn't connect after several attempts, log the error and throw an exception Log.Error(err); // add a blurb about TWS for connection refused errors if (err.Message.Contains("Connection refused")) { throw new Exception(err.Message + ". Be sure to logout of Trader Workstation. " + "IB only allows one active log in at a time. " + "This can also be caused by requiring two-factor authentication. " + "Be sure to disable this in IB Account Management > Security > SLS Opt out.", err); } throw; } } // define our event handler, this acts as stop to make sure when we leave Connect we have downloaded the full account EventHandler<IB.AccountDownloadEndEventArgs> clientOnAccountDownloadEnd = (sender, args) => { Log.Trace("InteractiveBrokersBrokerage.AccountDownloadEnd(): Finished account download for " + args.Account); _accountHoldingsResetEvent.Set(); }; _client.AccountDownloadEnd += clientOnAccountDownloadEnd; // we'll wait to get our first account update, we need to be absolutely sure we // have downloaded the entire account before leaving this function var firstAccountUpdateReceived = new ManualResetEvent(false); EventHandler<IB.UpdateAccountValueEventArgs> clientOnUpdateAccountValue = (sender, args) => { firstAccountUpdateReceived.Set(); }; _client.UpdateAccountValue += clientOnUpdateAccountValue; // first we won't subscribe, wait for this to finish, below we'll subscribe for continuous updates _client.ClientSocket.reqAccountUpdates(true, _account); // wait to see the first account value update firstAccountUpdateReceived.WaitOne(2500); // take pause to ensure the account is downloaded before continuing, this was added because running in // linux there appears to be different behavior where the account download end fires immediately. Thread.Sleep(2500); if (!_accountHoldingsResetEvent.WaitOne(15000)) { throw new TimeoutException("InteractiveBrokersBrokerage.GetAccountHoldings(): Operation took longer than 15 seconds."); } // remove our end handler _client.AccountDownloadEnd -= clientOnAccountDownloadEnd; _client.UpdateAccountValue -= clientOnUpdateAccountValue; }
internal void TestVbGatewayConnection() { Utils.Logger.Debug("TestVbGatewayConnection() BEGIN"); // start c:\Jts\StartIBGateway.bat // IBGateway this version works: Build 952.1a, Aug 18, 2015 3:38:07 PM // c:\Jts\StartIBGateway.bat // this works too. Stable: Build 952.2h, Jan 29, 2016 4:40:48 PM // c:\Jts\952\jars\StartIBGateway.bat , or simple "javaw.exe -cp jts.jar;total.jar ibgateway.GWClient" command line works // Latest (not Stable) doesn't work c:\Jts\955\jars\StartIBGateway.bat or simple "javaw.exe -cp jts4launch.jar;total.jar ibgateway.GWClient" command line doesn't work, although the ibgateway.GWClient is there. Buggy. // see for samples: "g:\temp\_programmingTemp\TWS API_972.12(2016-02-26)\samples\CSharp\IBSamples\Program.cs" BrokerWrapperIb testImpl = new BrokerWrapperIb(); EClientSocket client = testImpl.ClientSocket; int portID = (int)GatewayUserPort.GyantalMain; // the IBGateways ports on Release Linux and Developer Windows local should be the same. client.eConnect("127.0.0.1", portID, 0, false); // it uses connectionID=0, which may be not good. Real VBroker uses 41 and 42 userIDs. //Create a reader to consume messages from the TWS. The EReader will consume the incoming messages and put them in a queue var reader = new EReader(client, testImpl.Signal); reader.Start(); //Once the messages are in the queue, an additional thread need to fetch them new Thread(() => { while (client.IsConnected()) { testImpl.Signal.waitForSignal(); reader.processMsgs(); } }) { IsBackground = true }.Start(); /*************************************************************************************************************************************************/ /* One (although primitive) way of knowing if we can proceed is by monitoring the order's nextValidId reception which comes down automatically after connecting. */ /*************************************************************************************************************************************************/ while (testImpl.NextOrderId <= 0) { } Console.WriteLine("Connection seems to be OK. Requesting Account Summary..."); /*** Requesting managed accounts***/ client.reqManagedAccts(); /*** Requesting accounts' summary ***/ Thread.Sleep(2000); client.reqAccountSummary(9001, "All", AccountSummaryTags.GetAllTags()); /*** Subscribing to an account's information. Only one at a time! ***/ Thread.Sleep(6000); Console.WriteLine("Disconnecting..."); client.eDisconnect(); }