4

When downloading data from interactive brokers some future contracts can be downloaded properly others not.

R console command:

icegasoil_feb <- getContract("GOILG2")

Connected with clientId 100.
Error in buildIBcontract(symbol = instrument, tws = tws, addIBslot = addIBslot,  : 
 Could not create valid twsContract.
GOI may not be a valid CASH. Disconnected.

Next error when using getBAT is :

getBAT("ZWH2")

Connected with clientId 120.
waiting for TWS reply on ZW ............failed.
waiting for TWS reply on ZW ....failed.
waiting for TWS reply on ZW ....failed.
Disconnecting ... 
NULL
Failure:

1: In errorHandler(con, verbose, OK = c(165, 300, 366, 2104, 2106,  :
  Historical Market Data Service error message:No data of type DayChart is available for 

the exchange 'CBOT' and the security type 'Futures' and '5 d' and '1 min'
able for the exchange 'CBOT' and the security type 'Futures' and '5 d' and '1 min'
FXQuantTrader
  • 6,821
  • 3
  • 36
  • 67
  • Please feel free to e-mail questions about twsInstrument directly to me for a faster response. My e-mail address is in the DESCRIPTION file of the package. – GSee Jan 26 '12 at 03:09

1 Answers1

4

The first problem you encountered will not occur if you update FinancialInstrument.

Prior to revision 888, FinancialInstrument:::parse_id -- which is used internally by twsInstrument -- would have thought a Symbol like "GOILG2" should have a root_id of "GO" because it would have seen "ILG2" as a 4 character suffix similar to the ones that Interactive Brokers uses for single stock futures. One way around this is to use an underscore to separate the root_id from the suffix_id so that parse_id does not have to deal with an ambiguous id. So, getContract("GOIL_G2") should have worked, and is still the recommended format for instrument ids. That said, if you update FinancialInstrument, it will work as is.

> require("twsInstrument")
> getContract("GOILG2")
Connected with clientId 100.
Checking to see if other 'type's have a pre-defined currency.
Request complete: GOIL FUT USD.
Disconnected.
List of 16
$ conId          : chr "34134707"
$ symbol         : chr "GOIL"
$ sectype        : chr "FUT"
$ exch           : chr "IPE"
$ primary        : chr ""
$ expiry         : chr "20120210"
$ strike         : chr "0"
$ currency       : chr "USD"
$ right          : chr ""
$ local          : chr "GOILG2"
$ multiplier     : chr "100"
$ combo_legs_desc: chr ""
$ comboleg       : chr ""
$ include_expired: chr "0"
$ secIdType      : chr ""
$ secId          : chr ""

The second problem is a little trickier. Basically, more than one contract was found that corresponds to "ZWH2" and the "wrong" one was used (pit-traded instead of the electronic). Before getting to the solution, allow me to give a little background.

The twsInstrument package was built with the intention of using Interactive Brokers to help me update the metadata of instruments that I had already defined with the FinancialInstrument package.

It will take what information it has and use that to gather more information.

When you use getContract it will first search locally for the twsContract. If it cannot find it, then it will see if instrument metadata has been defined in the FinancialInstrument:::.instrument environment. If so, that information will be used to create a shell of a twsContract that can be passed to IBrokers:::reqContractDetails, which will fill in the missing parts. If there is no instrument definition for this Symbol, then FinancialInstrument:::parse_id will figure out the information required by IBrokers:::reqContractDetails.

If Interactive Brokers has several contracts that match the info given, it will return a list of all of them. Unfortunately, I did not realize this when I wrote twsInstrument. So, only the first element of the list will be used.

FWIW, the IB API does appear to try to be smart about which contract it returns first, but that can actually cause frustrations when it is giving you a different contract depending on which contract you looked at last, for example.

In your case, you are asking for data on "ZWH2". The first contract that reqContractDetails returns will be the future that trades on "CBOT", but as you can see from the error message you got, that data is not available. That's because you really want the one that trades on "ECBOT". The following shows how to see the list of length 2 that IBrokers:::reqContractDetails returns.

require("IBrokers")
fut <- twsContract()
fut$symbol <- 'ZW'
fut$sectype <- 'FUT'
fut$expiry <- '201203'
fut$currency <- 'USD'
tws <- ConnectIB()
reqContractDetails(tws, fut)
twsDisconnect(tws)

The way to ensure that you get the contract you want is to use enough information that reqContractDetails does not find more than one match. e.g.

> define_futures("ZW", "ECBOT", "201203")
Connected with clientId 100.
Request complete: ZW FUT USD.
Disconnected.
[1] "ZW_MAR12"

> getBAT("ZW_MAR12")
Connected with clientId 120.
waiting for TWS reply on ZW ....... done.
Pausing 10 seconds between requests ...
waiting for TWS reply on ZW .... done.
Pausing 10 seconds between requests ...
waiting for TWS reply on ZW .... done.
Pausing 10 seconds between requests ...
Disconnecting ... 
[1] "ZW_MAR12"

define_futures makes the primary_id of the instrument based off the value of "local" in the twsContract. In this case, it is "ZW_MAR12". If you want the id to be "ZWH2", you can change it with FinancialInstrument:::instrument_attr

> instrument_attr("ZW_MAR12", "primary_id", "ZWH2")
>  # Now your original code will work
> getBAT("ZWH2")
Connected with clientId 120.
waiting for TWS reply on ZW ....... done.
Pausing 10 seconds between requests ...
waiting for TWS reply on ZW .... done.
Pausing 10 seconds between requests ...
waiting for TWS reply on ZW .... done.
Pausing 10 seconds between requests ...
Disconnecting ... 
[1] "ZWH2"

Alternatively, you could define the instrument using only the FinancialInstrument package making sure to provide the exchange:

future("ZW", currency("USD"), 5000, exchange='ECBOT')
future_series("ZWH2")
getBAT("ZWH2")

Finally, if you have revision 233 or later of twsInstrument, the following will also work to define the instrument: twsInstrument(twsFUT("ZW", "ECBOT", "201203"))

I would have responded sooner, but I don't visit SO all that often. You'll get a quicker response about twsInstrument if you send your question to either the r-sig-finance list, or directly to me (my e-mail address is in the DESCRIPTION file of the package). Please note that twsInstrument is still under development.

GSee
  • 48,880
  • 13
  • 125
  • 145