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.