-
-
Notifications
You must be signed in to change notification settings - Fork 116
Futures Contract String #31
Comments
In coding up the solution, I see the problem that the contract object that comes through the message handler doesn't have m_contractMonth embedded. In that case I would do this.
or however you would embed that into dataTypes
replace this snippet with lines 1501-1503 in ezibpy.py |
I ran a script with the current code and I got these as
Are you sure there's a problem? |
btw - using this code also produce the correct contractStrings (even with 2029+ as exp year) ...
elif contractTuple[1] == "FUT":
exp = str(contractTuple[4])[:6]
exp = dataTypes["MONTH_CODES"][int(exp[4:6])] + exp[:4]
contractString = (contractTuple[0] + exp, contractTuple[1])
elif contractTuple[1] == "CASH":
... |
ok, down the rabbit hole we go! here is code to get contract strings for a list of futures that I use in my project. A little about this code: I use the continuous future (
Here are the results:
ESTX50, DAX, RTY, GBL, NIY, BTP, GBX are all wrong. I also will add that I ran into some errors when I tried to run |
Ok... Here's my code: import ezibpy
symbols = {
'PA': 'NYMEX', 'GC': 'NYMEX', 'AUD': 'GLOBEX', 'CAD': 'GLOBEX',
'JPY': 'GLOBEX', 'SI': 'NYMEX', 'HE': 'GLOBEX', 'UB': 'ECBOT',
'EMD': 'GLOBEX', 'ZB': 'ECBOT', 'ZN': 'ECBOT', 'ZS': 'ECBOT',
'CL': 'NYMEX', 'ESTX50': 'DTB', 'YM': 'ECBOT', 'DAX': 'DTB',
'HO': 'NYMEX', 'LE': 'GLOBEX', 'HG': 'NYMEX', 'PL': 'NYMEX',
'QM': 'NYMEX', 'GBP': 'GLOBEX', 'RTY': 'GLOBEX', 'NQ': 'GLOBEX',
'EUR': 'GLOBEX', 'RB': 'NYMEX', 'NG': 'NYMEX', 'GBL': 'DTB',
'ES': 'Globex', 'NIY': 'GLOBEX', 'BTP': 'DTB', 'GBX': 'DTB',
'SB': 'NYBOT', 'QO': 'NYMEX', 'CC': 'NYBOT', 'CT': 'NYBOT',
'KC': 'NYBOT', 'DX': 'NYBOT', 'CAC40': 'MONEP', 'NKD': 'GLOBEX',
'MNQ': 'GLOBEX'
}
ibc = ezibpy.ezIBpy()
ibc.connect(clientId=100, port=7497)
for symbol in symbols:
contfut_contract = ibc.createContract(
(symbol, "CONTFUT", symbols[symbol], '', '', '', ''))
expiry = ibc.contractDetails(contfut_contract)['m_contractMonth']
contract = ibc.createFuturesContract(
symbol, exchange=symbols[symbol], expiry=expiry)
contractString = ibc.contractString(contract)
print(contractString)
ibc.disconnect() Here's the output:
Looks ok to me. Have I missed something? I'm using this version: ...
elif contractTuple[1] == "FUT":
exp = str(contractTuple[4])[:6]
exp = dataTypes["MONTH_CODES"][int(exp[4:6])] + exp[:4]
contractString = (contractTuple[0] + exp, contractTuple[1])
elif contractTuple[1] == "CASH":
... |
This is the version I have - ezibpy.py lines 1497-1509
One problem with your code is that one MUST check that the returned contract object found a valid match. One easy way to do that is To highlight this, if you run your code above on ESTX50 you'll find that Adjustments I made to your code:
So far so good. However, there's still one thing that's a little dicey. We've seen that But if use that contract object to place an order, because it's safer to have the correct
and the results:
The difference between
I hope it makes sense why I would prefer to work with the latter object rather than the former. I hope this isn't too nitpicky. But IB can be very particular, so I want to do things in the safest way. If I use the |
The latest version (from github - still not on pypi) introduced Using this version, I ran this script: #!/usr/bin/env python
import ezibpy
symbols = {
'ZS': 'ECBOT', 'ZB': 'ECBOT', 'YM': 'ECBOT', 'UB': 'ECBOT', 'ZN': 'ECBOT',
'LE': 'GLOBEX', 'NKD': 'GLOBEX', 'NQ': 'GLOBEX', 'RTY': 'GLOBEX', 'MNQ': 'GLOBEX',
'HE': 'GLOBEX', 'AUD': 'GLOBEX', 'JPY': 'GLOBEX', 'GBP': 'GLOBEX', 'EUR': 'GLOBEX',
'CAD': 'GLOBEX', 'EMD': 'GLOBEX', 'ES': 'GLOBEX', 'KC': 'NYBOT', 'DX': 'NYBOT',
'CT': 'NYBOT', 'CC': 'NYBOT', 'SB': 'NYBOT', 'CL': 'NYMEX', 'HG': 'NYMEX',
'QO': 'NYMEX', 'QM': 'NYMEX', 'GC': 'NYMEX', 'PA': 'NYMEX', 'NG': 'NYMEX',
'HO': 'NYMEX', 'RB': 'NYMEX', 'PL': 'NYMEX',
'BTP': 'DTB', 'GBL': 'DTB', 'GBX': 'DTB', 'ESTX50': 'DTB', # in Euros
'NIY': 'GLOBEX', 'CAC40': 'MONEP', 'SI': 'NYMEX', 'DAX': 'DTB', # multipliers needed
}
ibc = ezibpy.ezIBpy()
ibc.connect(clientId=100, port=7497)
for symbol in symbols:
contract = ibc.createContinuousFuturesContract(symbol, symbols[symbol])
contractString = ibc.contractString(contract)
localSymbol = ibc.contractDetails(contract)["m_summary"]['m_localSymbol']
print(symbol, "\t", localSymbol, "\t", contractString)
ibc.disconnect() ...and I got this:
|
This is quite an improvement. And there is still one issue related to the
results:
|
I'm not sure why are you looking into Using
I'm not sure why IB does that for some contracts, while for others it returns the same expiration for both Unless you can prove me wrong, I'm closing this issue for now and pushing this version to PyPi 😁 |
The reason I use it is because for whatever reason, the
You'll also notice that the first object has This is what's causing the confusion for Technically speaking, If you want to truly standardize the nomenclature Does this make sense? (IB will let you search for a contract with a 6-digit YYYYMM string in expiry search field, and is smart enough to figure out that you're searching for a contract month and not an 8-digit expiry date, but it's not technically correct to call that datestring In my mind, the best way to solve this issue (and make the whole platform more robust) is the following:
|
There are a few issues with the formula contractString for futures. on line 1480 you have
localSymbol = contract.m_localSymbol
.There are two problems here:
some exchanges use a different syntax for m_localSymbol for example DAX which trades on DTB
details['m_localSymbol'] = 'FDAX JUN 19'
. Or the Dow Jones (YM trading on ECBOT) hasdetails['m_localSymbol'] = 'YM JUN 19'
. On line 1503 you have the codeexp = localSymbol[2:3] + self.localSymbolExpiry[localSymbol][:4]
. Thus the first term (localSymbol[2:3]
) in the DAX would be "A" and in "YM" would be " " (for which you have a backup).for symbols that have more than 2-character symbols, for example, RTY, localSymbol = "RTYM9" again the term
localSymbol[2:3]
is inappropriate here.As this is so important for futures, this is what I would recommend:
From what I can tell
details['m_contractMonth']
seems to be very reliable, slicing [-2:] would give you the best chance to get the correct letter code for expiry. If that's empty, then I would look to localSymbol, first checking for spaces. If there is no space uselocalSymbol[-2:-1]
. If there are spaces, I would try to parse it 'localSymbol.split()[1]' and then use that to lookup against 3-letter month codes.Unfortunately, if you want to standardize to using the expiry letter codes (which IS the correct choice), using m_expiry will sometimes lead you astray because the expiry date does not always happen in the month of coded expiration, for example, July gasoline m_expiry is 6/28. Many of the single month contracts have this problem. So mixing expiration day and expiration month can be confusing.
The text was updated successfully, but these errors were encountered: