CloseAllOpenPositions not sending to IB Controller

Hello,

I'm using the IB Controller (1.3.8) alongside TWS (972.1) and when using the CloseAllOpenPositions method, it doesn't work for any open positions.

So if I don't specify any symbol parameters, i.e.

ibc.CloseAllOpenPositions();

Then it sends the appropriate market orders to the IB Controller, however they all generate an Error (200 - No security definition found)
2019-11-13%2017_04_18-AmiBroker%20-%20%5BRSG-ASX%20-%20RESOLUTE%20FPO%20-%201-minute%5D

So I'm assuming this is because the currency doesn't get specified, and so if I manually call CloseAllOpenPositions for each symbol with the currency appended to it, it just doesn't get sent to the IB Controller:

ibc = GetTradingInterface("IB");
openPositions = ibc.GetPositionList();

for (i = 0; (ordSymbol = StrExtract(openPositions, i)) != ""; i++) {
	orderSymbol = ordSymbol + "-AUD";
	ibc.CloseAllOpenPositions(orderSymbol);
	AlertIf(True, "", "Closing Symbol: " + orderSymbol, 0, 2);
}

The alert output shows the correct security definitions, as these are the exact same definitions used when placing orders.
2019-11-13%2017_09_36-AmiBroker%20-%20%5BRSG-ASX%20-%20RESOLUTE%20FPO%20-%201-minute%5D

I seem to recall CloseAllOpenPositions() working about a month prior, however TWS hasn't been updated since September, neither have I updated my IB Controller nor AmiBroker. Any ideas?

Thanks

IBController can only send order requests. Whenever TWS actually closes or not depends on TWS. If an error occurred, it should be listed in ERRORS page.

You are using "SMART" exchange. It may be problematic if the very same symbol is traded on multiple markets, then TWS may not understand which market to use and reject.

Understood, however using the full symbol name the order doesn't even go through to the IB Controller, nothing comes up under the 'Pending' and 'Executions' tabs and there is no message/error. This is also easily replicated by placing an order like so:

Copy

ibc.PlaceOrder("VODl-SMART-CFD-GBP", "Buy", 100, "MKT", 0, 0, "GTC", True);

Which opens an order just fine, however using the exact same symbol code for closing a position:

Copy

ibc.CloseAllOpenPositions("VODl-SMART-CFD-GBP");

Yields no results at all. Nothing in IB Controller, nothing in TWS.

IBController is open source software, you can go on download the source and see what is happening inside. In short, when you call CloseAllOpenPositions and specify the symbol, it goes thru Portfolio list (what you see in "Portfolio" page) and compares the symbol that you specified with what is seen in Porfolio list. And only if there is a perfect match between them, it is sending either Sell or Buy market order (depending if you were long or short. That's all. That is all "magic" inside. Nothing else. So the only reason for not sending orders is a MISMATCH between symbol that you pass to CloseAllOpenPositions and positions displayed in the Portfolio list.

In other words: it is crucial what you have in "Portfolio" tab (send a screenshot).

8

If I try calling ibc.CloseAllOpenPositions("VODl-SMART-CFD"); then I get the Error (200): No security definition has been found for the request.

If I then try calling ibc.CloseAllOpenPositions("VODl-SMART-CFD-GBP"); it just doesn't go to IB Controller at all.

According to the IB Controller docs then the symbology is defined as SYMBOL-EXCHANGE-TYPE-CURRENCY, and that's exactly what I'm using.

This is untested, could you please try:

ibc.CloseAllOpenPositions("VODl@SMART//CFD////GBP");

Thanks for trying, but nope, still nothing.

Did you try that syntax directly or parsed the ticker string in TickerToContract from Wrapper.cpp file because CloseAllOpenPositions() function in BrokerIBDlg.cpp requires correct oFullSymbol for it to be able to interact with IB TWS API and execute.

Another possibility is that CString oCurrent = poList->GetPositionSymbol( iItem ); is unable to assign correct Symbol to oCurrent, hence there is a mismatch with your actual Position Symbols and PlaceOrder() does not get executed from the CloseAllOpenPositions() function.

The reason for mentioning that symbol syntax is because you've stated previously that ibc.PlaceOrder works however not ibc.CloseAllOpenPositions. Error 200 indicates that TWS is unable to recognize the Symbol that you're sending from IBC. Anyways, this is very strange!

If I try calling ibc.CloseAllOpenPositions("VODl-SMART-CFD"); then I get the Error (200): No security definition has been found for the request.

Obviously this can't work because when you don't specify currency it uses "USD" which in this case isn't correct (should be GBP)

If I then try calling ibc.CloseAllOpenPositions("VODl-SMART-CFD-GBP"); it just doesn't go to IB Controller at all.

So, as I said, if it does not go, there is a mismatch between what TWS sends as Portfolio item and what you are requesting. I suspect that it might be something either a typo, I mean did you really meant lowercase l instead of uppercase I in the symbol name? Or there is an issue with upper/lowercase because generally all symbols are supposed to be uppercase.

Drawing clues from what Tomasz just wrote, since you're referring to this CFD, please use:

ibc.CloseAllOpenPositions("VOD-LSE-CFD-GBP");

Also consider searching the IB Contract and Symbol Database > Advanced > Symbol > Search > Check details, and use Symbol not the Local name.

Yes. That's what's displayed in the IB Stock description, and that's what's displayed in the IB Controller under the Portfolio tab.
1
2 (portfolio tab)
And you stated earlier that

Clearly there is no mismatch here, evident in the fact that calling ibc.CloseAllOpenPositions("VODl-SMART-CFD"); DOES go through to the IB Controller yet returns the 200 Error.

3

Nope. Tried both, neither work.

Tried that too, still nothing (and regardless I don't believe this is an issue with that little L at the end of the symbol name as the same issue was occurring with ASX stocks, which don't have a suffix with them). In addition, when I try ibc.PlaceOrder("VOD-SMART-CFD-GBP", "Buy", 1000, "MKT", 0, 0, "GTC", True); it gives me the 200 Error.

I do appreciate the support thus far

There is a mismatch. You did not specify currency and you got the error message from TWS. There is no VODl CFD traded in US dollars.

Then why, when I specify the currency (as I clearly said in my very first post), it doesn't go to the IB Controller at all?

Because of the mismatch. I already tried to tell you 2 times. As I said, IBController is open source. You can check it yourself what happens. In your case there is a mismatch between string that you pass and string that is generated out of Portfolio tab from TWS data. Relevant part is int CBrokerIBDlg::CloseAllOpenPositions( LPCTSTR pszTicker ) method in BrokerIBDlg.cpp, lines 1260...1267:

			CString oCurrent = poList->GetPositionSymbol( iItem );
			int iSize = poList->GetPositionSize( iItem );

			CString oAccount = poList->GetPositionAccount( iItem );

			if( pszTicker == NULL ||
				oCurrent == oFullSymbol ) // This HAS TO BE PERFECT MATCH!
			{
				if( iSize != 0 )
				{
					PlaceOrder( 0, oCurrent, iSize > 0 ? "SELL" : "BUY", "MKT", abs( iSize ), 0, 0, "DAY", TRUE, 0, "", 0, "", 0, g_oWrapper.IsFAAccount(oAccount) ? "" : "All;;AvailableEquity", oAccount );
				}
			}

Commented line does the string comparison, if anything is not matching, the order will NOT be placed. From your description (the fact that it goes if you don't specify currency) it seems that currency is missing in oCurrent variable.

I have analysed it further and the fix is to add single line line in CString CIBPortfolioList::GetPositionSymbol(int iItem) method in IBPortfolioList.cpp line 169:

ctr.currency = GetItemText( iItem, 5 ); // added line

CString oSymbol = g_oWrapper.ContractToTicker( ctr );
2 Likes

I have made this change and compiled it so you can try
http://www.amibroker.com/at/1400/BrokerIB_140.zip

(unzip and replace BrokerIB.exe inside AmiBroker directory)

Note: I did not test this change extensively. Use at your own risk. Try it on the demo first.

1 Like

Yep, perfect, that's fixed it. Much appreciated Tomasz.

Hi Tomasz,

I had similar problem and followed everything you mentioned. I have updated my broker.IB with zip you had attached.

yet, I have same problem. when I trade Nasdaq future, it works(NQ) however when I try to trade any stock, say tesla, this line doesn't work. here is my paramtrigger code for close all position for given position.

ibc.CloseAllOpenPositions(Name());

// this line works if chart is added on MNQU0-GLOBEX-FUT which is nasdaq contract. however it doestn work when chart is loaded with TESLA candles. I tried this line, same issue

 ticker = "TSLA";  
ibc.CloseAllOpenPositions(ticker);

also tried

ticker=name();
ibc.CloseAllOpenPositions(ticker);`

none of them worked :(.
I hope I dont have to write subs strings method for each stocks I want to trade. please help. I am really stuck here

@Tomasz- Egerly waiting for your support and guidance. Please suggest.

Everything that I had to say about this was in post #15 and #16

There is nothing more to add. Follow advice given already. I don't have time or desire to repeat over and over what was already said.

IBController is OPEN SOURCE freeware, it is provided "as-is". I don't charge any money for it. It was targeted for people knowing what they are doing and people who can figure it out. No spoon feeding, no hand holding.

2 Likes