The first problem that you encounter will not occur if you update the Financial Instrument.
Prior to revising 888, FinancialInstrument:::parse_id - which is used internally by twsInstrument - would count the "GOILG2" character must have root_id "GO", because it would see "ILG2" as a 4-character suffix similar to those used by Interactive Brokers for single stock futures. One way to do this is to use an underscore to separate root_id from suffix_id, so parse_id does not need to deal with an ambiguous identifier. So getContract("GOIL_G2") should have worked, and is still the recommended format for tool identifiers. However, if you update FinancialInstrument, it will work as it is.
> require("twsInstrument") > getContract("GOILG2") Connected with clientId 100. Checking to see if other 'type 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 bit more complicated. Basically, more than one contract was found that matches βZWH2β, and βwrongβ was used (pit-traded instead of electronic). Before moving on to the solution, let me give a little background.
The twsInstrument package was created with the intention of using Interactive Brokers to help me update the metadata of tools that I already had defined in the FinancialInstrument package.
He will need the information that he has and use it to collect additional information.
When you use getContract , it will first search locally for twsContract . If he cannot find it, then he will see if the instrument metadata has been defined in the FinancialInstrument:::.instrument Instrument environment. If so, the information will be used to create a twsContract that can be passed to IBrokers:::reqContractDetails , which will fill in the missing parts. If this is not a tool definition for this symbol, then FinancialInstrument:::parse_id will determine the information required by IBrokers:::reqContractDetails .
If Interactive Brokers has several contracts that match the information provided, this will return a list of all of them. Unfortunately, I did not understand this when I wrote twsInstrument. Thus, only the first element of the list will be used.
FWIW, API IB, seems to be trying to figure out which contract it returns in the first place, but it may actually be frustrating when it gives you another contract, depending on which contract you, for example, looked at, finally.
In your case, you request data for "ZWH2". The first contract that reqContractDetails returns will be a future that trades on "CBOT", but since you can see from the received error message that the data is not available. Which is because you really want someone who trades on ECBOT. Below is shown how to see a list of length 2 returned by IBrokers:::reqContractDetails .
require("IBrokers") fut <- twsContract() fut$symbol <- 'ZW' fut$sectype <- 'FUT' fut$expiry <- '201203' fut$currency <- 'USD' tws <- ConnectIB() reqContractDetails(tws, fut) twsDisconnect(tws)
A way to ensure that you get the desired contract is to use sufficient information that reqContractDetails does not find more than one match. eg.
> 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 tool primary_id tool based on the value "local" in twsContract . In this case, it is "ZW_MAR12". If you want the id - "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 can define a tool using only the FinancialInstrument package that provides the exchange:
future("ZW", currency("USD"), 5000, exchange='ECBOT') future_series("ZWH2") getBAT("ZWH2")
Finally, if you have version 233 or later twsInstrument, it will also work on the definition of the tool: twsInstrument(twsFUT("ZW", "ECBOT", "201203"))
I would answer sooner, but I often do not visit SO so often. You will get a faster answer about twsInstrument if you send your question either to the r-sig-finance list or directly to me (my email address is in the DESCRIPTION package file). Please note that twsInstrument is still under development.