Using Autotrader with IB with multiple accounts

I have been using Amibroker and autotrader code for years.

Recently I added an IB sub account and it places the buy or short orders okay but does not sell or cover (existing positions). It appears that the position is not recognized in the specific account. (I am trading from the main account not the sub account, if that's the problem?)

When placing orders I define which account, which seems to work:

orderID = ib.PlaceOrder(sTicker, "Buy", pContracts, "MKT", 0, 0, "GTC", True, tickMult, "outsideRTH",Account="U686XXXX");

but then the system doesn't cover existing positions, this code from my formula:

ibc 		= GetTradingInterface( "IB" );
ibc.setAccount("U686XXXX");
PositionNum	= ibc.GetPositionSize( sTicker );

I recently added the setAccount(XXX) hoping it would tell the system where to look but no luck.

The IB Controller says
Accounts available U363XXXA, U363XXXX, U686XXXX
Using FA account U3638969

I assume I want it to say Using account U686XXXX, but I don't know how.

(fyi U363XXXX is the sub account which I do NOT want the orders to be placed in)

any ideas on what I am doing wrong?

One thing I've noticed, is that there can often be a lag between sending the ibc.SetAccount() command and the IBC actually having then changed to use the required account.

If you keep your eye on the IBC Account Information tab as the code is running, you should see the Account Code change when the SetAccount command is executed, and it will need to be on the new Account Number before the code sends the GetPositionSize command. If not, (ie if there's a delay) you'll get the sort of symptom you're experiencing.

image

If you are seeing a delay, then one way to hold up the process while the account changes is this:

AccountNo = "U363XXX";
ibc.SetAccount(AccountNo);

Count = 0;
while (ibc.GetAccountValue("AccountCode") != AccountNo AND Count < 10) 
{
	ibc.Sleep(500);
	Count++;
}
if (ibc.GetAccountValue("AccountCode") != AccountNo)
	Error ("IBC cannot switch to " + AccountNo);
3 Likes

Just wanted to say I really appreciated this post. I've been having a problem where the first time I ran my code the Account wouldn't switch how I expected it to, but when I ran the code again the account had switched. I looked up "IBController SetAccount lag" and it brought me here and your code snippet solved my issue. Thanks very much!

1 Like

TWS in general does not respond immediately. The whole process is asynchronous. When you call any TWS API function it sends request to TWS and TWS sends request to actual Interactive Brokers servers. Then it takes time for request to be handled by IB and response is sent back by IB to TWS and then to application using TWS API.
Depending on request type you it can take fraction of second or even 2 seconds for IB to respond. Especially portfolio / account stats are sent with 2+ second delay. The same can be seen in TWS itself (the time it takes for Account page to update).

Appropriate code should NOT WAIT for the response. It is bad code. Calling Sleep is WRONG.

Instead you should send request and DO NOT wait at all - just terminate (end). Only when next time your code is executed (and it will be executed periodically because of RT updates and/or forced update via RequestTimedRefresh), check the status / account code.

Also when you are trading multiple accounts instead of switching accounts over and over, use SetInfoAccount to set account for information and for trading pass actual account number to make a trade via parameter in PlaceOrder, see:

PlaceOrder( string Ticker, string Action, number Quantity, string Type, number LimitPrice, number StopPrice, string TimeInForce, bool Transmit, [optional] number TickSize = 100, [optional] string Attributes = "", [optional] string ParentID = "", [optional] string OCAGroup, [optional] number OCAType, [optional] string FAParams, [optional] string Account)

Also you should keep position sizes in static variables, rather than querying GetPositionValue because TWS is very slow to update position values. Static variables are immediate.

2 Likes

No, what I wrote was a Function Prototype (a formal declaration of function showing formal parameters and extra information about types)

So [optional] is just a NOTE in the function prototype that given parameter is OPTIONAL (i.e. can be skipped if not used and no parameters are coming after). This is notation used by Microsoft OLE spec.
Optional parameters must still be included if you want to use some argument that comes AFTER in the argument list.

When you are calling the function you should NOT include any extra strings, just the VALUE that you are passing so, correct use would look as follows:

ibc.PlaceOrder("MSFT", 
"BUY", 100, "LMT", 27, 0, 
"GTD 20051215 17:00:00 GMT", True, 100, 
"", "", "", "", "", /* empty strings */
"U12345A" ); // "U12345A" is actual account number (last arg)

Note that optional arguments that we don't use are still passed (as empty strings) because we are using the very last argument and order of arguments must NOT be changed.

1 Like

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.