Generic code snippet to trade with IB


#1

Hello Gurus,

I have a trading system which I backtested in AB and now would like to take it to the next level and trade with IB.

The system can go long and short and has dynamic long and short trailing stops.
As far as I understood, in order to trade with IB I need the application called IB controller, which I have installed.

My question is: Is there a generic code snippet that can be embedded into my (and in fact any) AFL code that can automatically open long/short positions at the required prices and close these positions when the trailing stops are reached? Something that directly translates the signals in the Buy/Sell Short/Cover arrays into PlaceOrder actions (and use the correct price arrays for the order price)?

To me this seems such a basic requirement (although I’m not saying that it is easy to do), that I am expecting that such a code snippet should exist and publicly available for a mature product.

If not, could I get at least some working example of how to implement trailing stops with IB?

Any help is appreciated.


#2

Check
http://AmiBroker.org/userkb


#3

Thanks for your answer, but I already went through it but does not shed any light to my question, so I still consider it as unanswered. If you think I’m wrong, then can you please point me to the exact section with this generic code?

In fact, I see a much bigger problem here. It seems that any AFL code will have to have 2 sections and look like this:

// Part 1 - simple high-level logic for buy/sell signals

// Part 2 - ugly and complex and low level order management code for a specific broker

What I don’t get is why do we actually need this second part at all. In the same way we have plugins for market data we should also have plugins for the execution broker side. The AFL code/logic is not market data provider dependent, so why make it execution broker dependent? Why not just have Part 1 and specify through some setting that I want the exec broker to be IB, and if a DLL is available (just as for the market data side), then I’m good to go?


#4

If you are asking how to implement trailing stops with IB you should first read Interactive Broker docs because trailing stop and all other stops are native (you just place the stop with broker). You are not “implementing” them. IB implemented them for you.

https://www.interactivebrokers.com/en/index.php?f=605

At that level of expertise, there are lots of reading ahead. And that what should be done first before trying to code anything.


#5

No, that’s not what I am asking, as I know how to place a trailing stop order.

In AFL is obviously not just a matter of calling the ibc.PlaceOrder() with the right params. Based on the example code snippets I have seen so far it seems that even to send the most basic entry order I need to add all kind of low level checks to see WHEN the order is supposed to be sent (like when Buy[i]==1), checks to avoid re-sending the same order, checks for connectivity, a.s.o. With a trailing stop I would assume there will be additional checks to see if we have a position open.

Come one: this is a really-really basic question. If there is no such code snippet, than either people don’t do automation using AB (and IB), or it is so hard that nobody wants to share such code for free. None of the options are appealing.

To be clear, just so that you don’t come again with some “please look up this or that link” type of answer, I don’t want help on placing one particular (type of) order, but instead I want to know if there is some reusable code that can reference the signal and price arrays from a very basic AFL system and create the required orders to be sent to IB, with all the required IB specific code to check connectivity, to handle errors, to ensure orders are not sent twice, etc, etc. Savvy?


#6

Seriously? That is how you are asking people for help? Do you expect people to rewrite things for you just because you don’t want to read existing docs and you don’t accept links?

Sorry, maybe AMiBroker is just not for you. It requires reading the docs. It requires doing things by yourself. There are plenty of practical examples in the very first link I have given. But you don’t want links so you apparently need to go to some other software.


#7

Thank you for your help, but those links were not useful.
Anybody out there who can actually help?


#8

Yes!!!, …YOU


#9

This is a vibrant community!

I have managed to place my first order using the auto-trading interface using the sample code from the IB controller help page, but not sure if this code, as it currently is, is fully correct. Consider this snippet:

if (LastValue(Buy))
{
  ibc = GetTradingInterface("IB"); 

  if (ibc.IsConnected()) 
  {
    if (ibc.GetPositionSize(Name())
    { 
        ibc.PlaceOrder(Name(), "Buy", 100, "MKT", 0, 0, "Day", True); 
    } 
  } 
}

Two issues here:

  1. As far as I understood, the AFL code can execute more often than just receiving a bar, which means the above code could run one after the other quickly (that is two times), due to a bar coming in and say a scrolling happening. If this is true, than GetPositionSize() would return 0 in the second run if the order placed in the first run did not get the change to fill yet. The result would be sending two orders. Similar case is when a limit order is sent but did not fill, and in the meanwhile a new bar is coming in (if we work say on 1 minute charts).
  2. GetPositionSize() returns the position displayed in TWS portfolio window, which means that if the same symbol is also manually traded then this logic will not work, as one could already have a position in the given symbol, opened manually.

Any thoughts how to address this? (no links please)


#10

Hi Zaxxon

Happy to help you out, but as others have said, your reluctance to read the documentation will hold you back. The Amibroker documentation is very comprehensive and will answer almost all your questions.

The best way to implement auto trading is through the Analyser, where you can auto-repeat execution of the runs at whatever interval you trade. So if you’re trading 5 minute bars, set it to auto repeat every 5 minutes. That will avoid submitting multiple orders on the same bar.

You can detect if there is no position already open, and that no order exists for the symbol before submitting a new one, by using a similar construct to the following:

fSymbol = NAME();
if ( ibc.GetPositionSize( fSymbol ) == 0 AND NOT StrFind(ibc.GetPendingList( 1, "" ), fSymbol)) 
{ 
	ibc.PlaceOrder( fSymbol, "Buy", LastValue(PositionQty), "MKT", 0, 0, "Day", True ); 
}

This may not be exactly what you are after, but should hopefully help you on the way to figure it out for your own particular use case.

Hope that helps. Let us know how you go from here.


#11

Thank you for the help!

I read the article “Using New Analysis window”, but I don’t understand how this can be applied to real trading. This window seems to be about back-testing the AFL with various time intervals. To trade for real, do I need to do a “walk forward”? Can you please explain? So far I have been testing directly on the chart window by applying my AFL on the chart, for one symbol. Of course at some point I will want to run the same AFL over multiple symbols to trade for real, so the question is how do I do that? (Links accepted)

Regarding the code snippet: I am also trading manually in TWS, but ibc.GetPositionSize(fSymbol) is returning the cumulative position (as shown in TWS), isn’t it? So this won’t work.

Yesterday I also had an issue with the ibc.GetPendingList(…) part. In effect, I placed a short sell order, and the IB controller displayed it with error 404, which translates to “Shares for this order are not immediately available for short sale. The order will be held while we attempt to locate the shares.” (<-- this is from the IB documentation)
To my greatest surprise, ibc.GetPendingList(…) did not return this order, and ibc.IsOrderPending(orderId) returned false! I noticed that only after the order was released by IB did it appear in the controller as a pending order. As a result, I ended up sending double orders. What I had to do was to use ibc.GetLastError(orderId) to check the last error on this order, and handle this special case, and it worked (that is, no double orders). What is worrisome though is that IB has lots of error codes and I am not sure which ones will affect the controller’s behavior. And what is more worrisome is that in fact this situation is not an error at all and I am not sure why IB controller changes the order’s status to “Error”, whereas in TWS the order is not displayed with an error.

For making my AFL not to interfere with manual trading in TWS I still have to think of a solution.

Just out of curiosity: Roughly how many lines of code should I expect that I have to write to make a bulletproof order entry system? So far I have written over 100 and it only handles a few IB errors. I just want to know the magnitude: 100s of lines, 1000s?


#12

The way I’ve used the Analyser in the past for auto-trading is by using the Explore feature. That will run your code once each for all the symbols that are included in the Analyser Filter settings. Set the Range to 1 recent bar to get results for just the latest bar. Then in the code, you can have a section for the order management that is conditional on it only being executed during an Explore. That will avoid it executing when used on a chart, for example.

// Your buy and sell signal generation code here

if (Status("action") == actionExplore)
{
    // Your auto-trading code here
}

You can then set the Analyser to auto-repeat the Explore at whatever interval you need to re-Explore for signals (drop-down menu next to “wrench” button):

image

To start the process, click Explore.

I’m not sure if there is a way the IB Controller can tell the difference between an automatically placed order and a manually placed one. I know there is an Order Ref field you can use in TWS to differentiate, but I don’t think that can be set or accessed through the IB Controller.

As to how many lines of code you’ll need, it’s hard to say. Every strategy is different. The more edge cases you need to cater for, the more code you’ll need.

Hope that helps.


Does Amibroker support trades thru IB and data from IQ Feed?
#13

Thanks again for your help. I have some additional questions for you, or anybody that wants to help.

  1. Analysis window: How do I set my parameters for the AFL that is currently used? Is it also possible to have different values for the same parameter for different symbols that are active in this window?

  2. Analysis window: Is it possible to temporarily suspend execution of the AFL for a certain set of symbols and then re-enable later? Suppose a news comes in for one of them and I want to pause the AFL, but just for that one symbol.

  3. Trading hours: Is there a way to retrieve the trading hours for a product in the AFL code? Is there a way to know if a product is currently trading?

  4. Recovery: If for whatever reason I have to restart IB controller and/or AmiBroker, will IB controller recover my current orders? For example, I could have some limit orders pending with IB - will those be visible after such a restart? I have read something about this pending list being cleared after IB controller restarts. I will certainly try this out myself, but just wanted to see what I should expect.

  5. Logging: I have been using the _TRACE command to log important decisions/actions taken by my strategy. I can see them in the Log window, but is there a file where this info is written so it can be analysed offline? (I also want to keep a history of these events)


#14
  1. Parameters are set via the parameters button:
    image
    It’s one set of parameters per formula. If you wanted individual symbol parameters you’d have to store them separately and call them in to your strategy conditional on the symbol being processed. This article has an example.

  2. Yes, the Analyser Filter has an Exclude tab. If you created a watchlist of the symbols you wanted to exclude you could set that watchlist on this tab.
    image

  3. You could detect the times from historic price data using something like:

BarTime = TimeNum();
BarDay = Day();
StartTime = ValueWhen(BarDay != Ref(BarDay, -1), BarTime);
EndTime = ValueWhen(BarDay != Ref(BarDay, 1), BarTime);
  1. If the orders exist in IB, the Controller should be able to detect them. I’m not sure why a restart would affect that.

  2. If you use DebugView, you can save the Trace output to a file.


#15

Please check this link

http://www.amibroker.com/members/library/detail.php?id=1225

In the above link there is an AFL “AutoTrader Basic Flow”. The code takes care of order management - the code ensures that no order is repeated, checks for pending orders, checks for existing positions, cancels pending order if your trading system generates a reversal signal/order, etc ,
All you need to do is change your trading system as per your requirement and make few modifications to accommodate your trading system. But please do paper trade and then implement.