erdewit / ib_insync

Python sync/async framework for Interactive Brokers API
BSD 2-Clause "Simplified" License
2.8k stars 743 forks source link

Timeout when connecting from wsl2 to windows-based TWS #529

Closed yarimiz closed 1 year ago

yarimiz commented 1 year ago

I've been facing an issue where a connection between a code that runs in WSL2 (ubuntu 22.04) and a TWS running on Windows 10 is disconnected due to timeout.

Connecting to the same TWS using the same code but directly from Windows (without WSL) works flawlessly.

In TWS settings, I have enabled connections from 172.18.240.1.

Log is as follows

2022-11-21 19:24:14,360 ib_insync.client INFO Connecting to 172.18.240.1:7496 with clientId 999...
2022-11-21 19:24:14,362 ib_insync.client INFO Connected
2022-11-21 19:24:18,363 ib_insync.client INFO Disconnecting
2022-11-21 19:24:18,364 ib_insync.client ERROR API connection failed: TimeoutError()
atakanokan commented 1 year ago

This stackoverflow page has more information on how to access Windows host from within WSL2: https://superuser.com/questions/1679757/how-to-access-windows-localhost-from-wsl2

Same result as the accepted answer states: the ping command doesn't work but the nc command does.

 ~$ ping "$(hostname).local"
PING  (172.28.208.1) 56(84) bytes of data.
^C
--- ping statistics ---
58 packets transmitted, 0 received, 100% packet loss, time 59242ms

~$ nc -zv "$(hostname).local" 7496
Connection to XXX.local (172.28.208.1) 7496 port [tcp/*] succeeded!
ben1628 commented 1 year ago

In case anybody is still looking for a solution on this, after google this for a while and try multiple solutions, this is the solution that seem to work

https://learn.microsoft.com/en-us/windows/wsl/networking

To Simplify

In wsl2:

Obtain the necessary IP addresses by running this command from your Linux distribution: Ip route

default via xxx.xx.xxx.x dev eth0 proto kernel 172.34.142.0/20 dev eth0 proto kernel scope link src yyy.yy.yyy.y

Under Windows 10/11:

Open TWS/IBGateway, goto configure/API, uncheck Allow connections from localhost only and then add yyy.yy.yyy.y as one of the trusted IPs. Note the Socket port number as well.

Back to wsl2:

In your python notebook/source, do the following

from ib_insync import *
#util.startLoop()  # uncomment this line when in a notebook

ib = IB()
ib.connect('xxx.xx.xxx.x', 7497, clientId=1)
...

Note the following:

1/ the ip address changes when you reboot wsl2, so you have to repeat these steps

2/ the xxx.xx.xxx.x also appear as nameserver in /etc/resolve.conf in linux, you can use shell script or python to read that and use it in your python code.

3/ Much easier setup for us (windows users) since we don't have to install any messy GUI display in wsl2 in order to run tws/ibgateway in linux.

sean-silverpine commented 1 year ago

@ben1628 I'm having the same issue and I followed your steps. I'm using the nameserver address from resolv.conf and I've added the two IP addresses from ip route in the IB API trusted IPs. I restarted TWS and retried many times and I continue to get the TimeoutError.

2023-01-19 21:03:53,434 ib_insync.client INFO Connecting to 172.21.240.1:7497 with clientId 1...
2023-01-19 21:03:53,434 ib_insync.client INFO Connected
2023-01-19 21:03:57,438 ib_insync.client INFO Disconnecting
2023-01-19 21:03:57,439 ib_insync.client ERROR API connection failed: TimeoutError()
2023-01-19 21:03:57,439 ib_insync.client INFO Disconnected.

Was there any other step that helped you find a solution?

ben1628 commented 1 year ago

@ben1628 I'm having the same issue and I followed your steps. I'm using the nameserver address from resolv.conf and I've added the two IP addresses from ip route in the IB API trusted IPs. I restarted TWS and retried many times and I continue to get the TimeoutError.

2023-01-19 21:03:53,434 ib_insync.client INFO Connecting to 172.21.240.1:7497 with clientId 1...
2023-01-19 21:03:53,434 ib_insync.client INFO Connected
2023-01-19 21:03:57,438 ib_insync.client INFO Disconnecting
2023-01-19 21:03:57,439 ib_insync.client ERROR API connection failed: TimeoutError()
2023-01-19 21:03:57,439 ib_insync.client INFO Disconnected.

Was there any other step that helped you find a solution?

I modify the comment above, does that helps? It's working fine for me

sean-silverpine commented 1 year ago

@ben1628 , No, I've tried many times with your steps and I continue to get the TimeoutError after getting connected. It seems that TWS is not allowing the connection. I've checked the trusted IPs against the values in IP route many times. Any other ideas?

ben1628 commented 1 year ago

Try this:Add 127.0.0.1 as trusted IP in TWS and then ib.connect(127.0.0.1)

Sent from Outlook for iOShttps://aka.ms/o0ukef


From: Sean Beebe @.> Sent: Saturday, January 21, 2023 1:22:22 PM To: erdewit/ib_insync @.> Cc: ben1628 @.>; Mention @.> Subject: Re: [erdewit/ib_insync] Timeout when connecting from wsl2 to windows-based TWS (Issue #529)

@ben1628https://github.com/ben1628 , No, I've tried many times with your steps and I continue to get the TimeoutError after getting connected. It seems that TWS is not allowing the connection. I've checked the trusted IPs against the values in IP route many times. Any other ideas?

— Reply to this email directly, view it on GitHubhttps://github.com/erdewit/ib_insync/issues/529#issuecomment-1399305173, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AHJERBSPYSWSCJHUS5DJ4NTWTQSN5ANCNFSM6AAAAAASG4MDTQ. You are receiving this because you were mentioned.Message ID: @.***>

nick-reinstein commented 1 year ago

I am also getting TimeoutError after putting the xxx stuff in the code and the yyy stuff in TWS, i have tried with 127.0.0.1 and the result from "ip route".

Afte a few seconds TWS asks if I would like to accept the connection, I reply 'Yes' but nothing seems to happen, the app still has a TimeoutError even if I sleep long enough to get that TWS prompt first