开云体育

ctrl + shift + ? for shortcuts
© 2025 开云体育

Re: Define “NOT for AM-settled” SPX option contracts

 

Oh, I remember now. A few days ago IBKR screwed up something with AM vs PM expiration chain data. Lots of people had an issue on that date and could not trade. I think there was a separate thread about that. First time I saw an issue like that at IBKR. They knew about it (I called to inquire) but probably didn't fix it. I wonder if the issue you are getting is for that specific date?


On Tue, Jan 21, 2025, 10:20?PM Lewis_Tang via <lewis91960127=[email protected]> wrote:
Thanks leop for your reply. I did use "SPXW" (and always use it) in the tradingClass specification. The following was exactly how I define the option contract :
opt_contract = Option(symbol='SPX', lastTradeDateOrContractMonth='20250116', strike=6005.0, right='C', multiplier=100, exchange='SMART', currency='USD', tradingClass='SPXW')
?
And after ib.qualifyContracts(opt_contract), I print the contents of opt_contract and got the following :
Option(conId=750912933, symbol='SPX', lastTradeDateOrContractMonth='20250117', strike=6005.0, right='C', multiplier='100', exchange='SMART', currency='USD', localSymbol='SPXW ?250116C06005000', tradingClass='SPXW')
?
Then, I tried to find out why the lastTradeDateOrContractMonth between the above two (20250116 vs 20250117) and later I noticed that 202250116 was a trade day where both AM and PM settlement existed for SPX/SPXW. I therefore searched over the web and noticed in Reddit that some traders suggested never trade AM-settled SPX options as the settlement time is set at the morning of next day. As my algo trades 0DTE SPX and expects settlement price to be set at market close on the same day, so this is why I do not want to trade AM-settled SPX options.


Re: Define “NOT for AM-settled” SPX option contracts

 

Thanks leop for your reply. I did use "SPXW" (and always use it) in the tradingClass specification. The following was exactly how I define the option contract :
opt_contract = Option(symbol='SPX', lastTradeDateOrContractMonth='20250116', strike=6005.0, right='C', multiplier=100, exchange='SMART', currency='USD', tradingClass='SPXW')
?
And after ib.qualifyContracts(opt_contract), I print the contents of opt_contract and got the following :
Option(conId=750912933, symbol='SPX', lastTradeDateOrContractMonth='20250117', strike=6005.0, right='C', multiplier='100', exchange='SMART', currency='USD', localSymbol='SPXW ?250116C06005000', tradingClass='SPXW')
?
Then, I tried to find out why the lastTradeDateOrContractMonth between the above two (20250116 vs 20250117) and later I noticed that 202250116 was a trade day where both AM and PM settlement existed for SPX/SPXW. I therefore searched over the web and noticed in Reddit that some traders suggested never trade AM-settled SPX options as the settlement time is set at the morning of next day. As my algo trades 0DTE SPX and expects settlement price to be set at market close on the same day, so this is why I do not want to trade AM-settled SPX options.


Inconsistent expiry date obtained from ib.reqTickers()

 

I defined option contract as follows :

opt_contract = Option(‘SPX’, ’20250121’, 6015, ‘P’, ‘SMART’, currency=‘USD’, tradingClass=‘SPXW’)

?

Then, I wish to get the contract's current bid/ask prices, so I used reqTickers() as follows :

tick_details = ib.reqTickers(opt_contract)

?

For error tracing purpose, I used to print the tick_details contents. Here it is :

Ticker(contract=Option(conId=750913196, symbol='SPX', lastTradeDateOrContractMonth='20250122', strike=6015.0, right='P', multiplier='100', exchange='SMART', currency='USD', localSymbol='SPXW? 250121P06015000', tradingClass='SPXW'), time=datetime.datetime(2025, 1, 21, 14, 48, 54, 103595, tzinfo=datetime.timezone.utc), minTick=0.05, bid=6.4, bidSize=54.0, bidExchange='C', ask=6.5, askSize=2.0, askExchange='C', last=6.6, lastSize=4.0, volume=2238.0, high=14.05, low=6.45, close=27.7, halted=0.0, bidGreeks=OptionComputation(tickAttrib=0, impliedVol=0.21785950015907832, delta=-0.7116085792422059, optPrice=6.400000095367432, pvDividend=0.0, gamma=0.009767866599599677, vega=0.5477427109390766, theta=-0.0, undPrice=6035.17), askGreeks=OptionComputation(tickAttrib=0, impliedVol=0.22130962943480934, delta=-0.7085997644685299, optPrice=6.599999904632568, pvDividend=0.0, gamma=0.009662509828098607, vega=0.5504154854592325, theta=-0.0, undPrice=6035.17), lastGreeks=OptionComputation(tickAttrib=0, impliedVol=0.2021892365912554, delta=-0.7263385475706803, optPrice=6.599999904632568, pvDividend=0.0, gamma=0.010261604472690885, vega=0.5340398776862891, theta=-0.0, undPrice=6035.17), modelGreeks=OptionComputation(tickAttrib=0, impliedVol=0.21812797350188606, delta=-0.2774263862329315, optPrice=6.0125608711161505, pvDividend=0.0, gamma=0.009575647492098521, vega=0.5376558371343124, theta=-6.0125608711161505, undPrice=6035.34), bboExchange='c70003', snapshotPermissions=3)

?

As seen, the expiry date in my contract definition was 20250121, but the reqTickers() returned 20250122.

I then check IB's contract spec (by right-clicking the relevant contract on TWS and select "Details") and go the following :

?

As seen from the pic, everything is normal, i.e. conId was 750913196, strike was 6015, right was PUT, expiration and last trading date was both 20250121 and the tradingClass was correct (i.e. SPXW).

Anyone had experienced the same and how you solve this issue ? Is there a problem with ib.reqTickers() ? If so, any idea what should be used to replace ib.reqTickers()?

?


Re: Does ib_insync work with TWS 10.30?

 

During the weekend, there is high chance of maintenance including scheduled downtime, so verify here before doing tests. That is probably what happened to you.


Re: Does ib_insync work with TWS 10.30?

 

Thanks for the response. I just tried again now and it works with TWS 10.30. When I tried originally, it was over the weekend, which is when I usually run those scripts. Will try again next weekend.


Re: Define “NOT for AM-settled” SPX option contracts

 

One of the contract fields has SPX vs SPXW. You want to filter so you only have SPXW.


On Tue, Jan 21, 2025, 8:41?AM Lewis_Tang via <lewis91960127=[email protected]> wrote:
Sorry, the subject title was badly written. Should be “How to define afternoon-settled SPX options”


Re: Does ib_insync work with TWS 10.30?

 

Hi Rajeshh, I am still on ib-insync as well but my scripts work even after migration to 10.30, even orders, fills and adjustments, although I use the Gateway instead of TWS. I suggest to try Gateway and see what happens. Also remember to adjust API Settings again, sometimes they get lost with the update


Re: Define “NOT for AM-settled” SPX option contracts

 

Sorry, the subject title was badly written. Should be “How to define afternoon-settled SPX options”


Define “NOT for AM-settled” SPX option contracts

 

When defining an option contract in python, what code should I write in the script to ensure that I am trading SPX option contracts that are PM-settled instead of AM-settled (I don’t want to trade AM-settled SPX options but not sure my code would finally point to it instead of PM-settled one)


Re: record and replay ib_async session (data only)?

 

Hey Neal,?
?
Yeah, I was thinking your end result would be something similar to a script that reads each line of each text file and loads them into a dataframe. From there you would loop the dataframe and consume its data as inputs to your algo's logic. Reading the dataframe record by record would then serve as your data feed.?
?
Otherwise, I would ask GPT what programming languages (that you're familiar with), python libraries, tools, etc., that a trader can use to back-test a strategy and go from there.
?
I'm personally an Excel guy so I tend to import the text files into Excel and create various IF,AND,OR formulas to identify the instant some number of conditions are met and then compare that instance's stock price to the stock price some 5, 10, etc., seconds into the future. That approach can be helpful but certainly has its weaknesses.
?


Re: record and replay ib_async session (data only)?

 

Some guy 555,
?
In my case I want to be able to "replay" all the level2 history, not periodic snapshots. ?This itself won't be too hard to do by capturing the deltas sent by TWS. ?I expect the main coding issue will be integrating whatever I do it into my existing code (which I would have to do even with your script). ?So probably better for me to just roll my own. ?If I encounter unexpected obstacles, I may come back and ask to see your code. ?Thank you,
?
-Neal
?


Re: record and replay ib_async session (data only)?

 

Hey Neal,?
?
If you're interested, I have a script that scrapes and saves Level 2 DOM data to a text file. The script's basic layout is where Level 2 DOM ticker is captured to a globally accessible dataframe via the TickerUpdate event. The script's main body runs on a 15 second loop, where every 15 seconds the dataframe is copied and then exported. I copy the dataframe before exporting as I found that exporting it whilst receiving incoming tickers sometimes resulted in access issues to the dataframe. I should mention that the df kept expanding throughout the day and trimming it periodically also resulted in access issues. I asked ChatGPT for some code to overcome the struggles and it provided me a custom data class that essentially creates a dataframe that trims itself whenever records are added to it. Any records older than 60 seconds are trimmed. Setting the object up as a custom data class enabled the self-trimming behavior without suffering from the access issues.?
?
Now that I'm thinking about it, perhaps I could stop copying the dataframe as well in the main loop. I'll probably leave it as it. I find Python can be real finicky and delicate at times. Anywhoozle, the script has some extra things in it too that I would have to clean up, but if you're interested i'll do that and post what i got.?


Re: Is it possible to get pre-market bid/ask?

 

Hey Code Block,?
?
I have level 2 data and get the same output as you during non-market hours. There's also this relevant bit in the IB documentation:
?
Frozen---2---Frozen market data is the last data recorded at market close. In TWS, Frozen data is displayed in gray numbers. When you set the market data type to Frozen, you are asking TWS to send the last available quote when there is not one currently available. For instance, if a market is currently closed and real time data is requested, -1 values will commonly be returned for the bid and ask prices to indicate there is no current bid/ask data available. TWS will often show a ‘frozen’ bid/ask which represents the last value recorded by the system. To receive the last know bid/ask price before the market close, switch to market data type 2 from the API before requesting market data. API frozen data requires TWS/IBG v.962 or higher and the same market data subscriptions necessary for real time streaming data.
?
For reference, here's a link to documentation's text: https://ibkrcampus.com/campus/ibkr-api-page/twsapi-doc/#delayed-market-data


Re: Does ib_insync work with TWS 10.30?

 

No idea, but it sounds like a great time to switch over to ib_async.


Does ib_insync work with TWS 10.30?

 

Hello folks -?
I am still using ib_insync. I was using my code fine with TWS 10.19. This week I saw a message in TWS on startup asking to upgrade to TWS 10.30 as 10.19 will not be supported past March. When I start TWS 10.30 now, I see my code does not work anymore. It just sort of hangs. Below is what I get when I hit Ctrl-C to exit the program.
When I went back to TWS 10.19, the code started running again. Has anyone else tried with TWS 10.30?
?
Thanks
?
?
Traceback (most recent call last):
? File "c:\Users\rajes\tws\testib_insync.py", line 434, in <module>
? ? ib.qualifyContracts(contract)
? File "C:\Users\rajes\AppData\Local\Programs\Python\Python39\lib\site-packages\ib_insync\ib.py", line 570, in qualifyContracts
? ? return self._run(self.qualifyContractsAsync(*contracts))
? File "C:\Users\rajes\AppData\Local\Programs\Python\Python39\lib\site-packages\ib_insync\ib.py", line 318, in _run
? ? return util.run(*awaitables, timeout=self.RequestTimeout)
? File "C:\Users\rajes\AppData\Local\Programs\Python\Python39\lib\site-packages\ib_insync\util.py", line 341, in run
? ? result = loop.run_until_complete(task)
? File "C:\Users\rajes\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 629, in run_until_complete
? ? self.run_forever()
? File "C:\Users\rajes\AppData\Local\Programs\Python\Python39\lib\asyncio\windows_events.py", line 316, in run_forever
? ? super().run_forever()
? File "C:\Users\rajes\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 596, in run_forever
? ? self._run_once()
? File "C:\Users\rajes\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 1854, in _run_once
? ? event_list = self._selector.select(timeout)
? File "C:\Users\rajes\AppData\Local\Programs\Python\Python39\lib\asyncio\windows_events.py", line 434, in select
? ? self._poll(timeout)
? File "C:\Users\rajes\AppData\Local\Programs\Python\Python39\lib\asyncio\windows_events.py", line 783, in _poll
? ? status = _overlapped.GetQueuedCompletionStatus(self._iocp, ms)
KeyboardInterrupt
Task was destroyed but it is pending!
task: <Task pending name='Task-12' coro=<IB.qualifyContractsAsync() running at C:\Users\rajes\AppData\Local\Programs\Python\Python39\lib\site-packages\ib_insync\ib.py:1798> wait_for=<_GatheringFuture pending cb=[<TaskWakeupMethWrapper object at 0x0000023AA11C5F40>()]>>


Re: Ambiguous Contract on qualifyContracts for SPXW Option

 

I got the same issue on when my bot traded on 0DTE SPX on 20250108 (i.e. fire an option trade every morning that expires at day-end), and my bot could not trade on that day because IB had set both the expiry and last trade day to 20250109 (instead of 20250108) in the relevant contract spec. I then simply skip trading for that day and restart trading on 10 Jan, and things went normally, believing that such extra holiday would not happen too frequently.
?
However, yesterday (20250117), my bot got similar (not the same) as the above error. When I define an option contract by :
leg1 = Option('SPX', '20250117', 6035, 'C', 'SMART', currency='USD', multiplier=100, tradingClass='SPXW')
?
The contents of the above leg1 AFTER passing to ib.qualifyContracts() was (I used to print the leg1 contents for error tracing purpose) :
Option(conId=736830804, symbol='SPX', lastTradeDateOrContractMonth='20250118', strike=6035.0, right='C', multiplier='100', exchange='SMART', currency='USD', localSymbol='SPXW ?250117C06035000', tradingClass='SPXW')
?
As you can see, the returned lastTradeDateOrContractMonth became '20250118'.? Any idea why there is a discrepancy in the expiry date? and how to fix it ?
?
Thanks a million in advance


Re: record and replay ib_async session (data only)?

 

?
After poking around I now believe that it would be fairly hard to implement a mechanism for recording and replaying an ib_async session for the purposes of capturing data.
?
For anybody who understands reasonably well how ib_async works (unlike me, apparently :-), that's probably pretty obvious. ?The basic reason is that the IB.Client and IB.Wrapper classes (which, respectively send messages to TWS and receive messages from TWS) are not so easily decoupled. ?I'd be happy to expand on this if anyone is actually interested in the details..
?
-Neal
?
?


Re: Migration from ib_insync to ib_async

 

On Wed, Jan 15, 2025 at 10:58 PM, Mel wrote:
I like having both since I have a ton of code that I don't want to delete, but may never use so why change it all and test.
Do you mean you have code that use both ib_insync and ib_async ? If the migration is so ease why import both and use both in code?
?


Re: Migration from ib_insync to ib_async

 

开云体育

I found just replacing the ib_insync with ib_async worked fine.? I use virtual environments so I created a new one, did pip install of async and copied the code I was using over.? I like having both since I have a ton of code that I don't want to delete, but may never use so why change it all and test.





-------- Original message --------
From: "pythontrader via groups.io" <ali@...>
Date: 2025-01-15 1:24 p.m. (GMT-08:00)
Subject: [ib-async] Migration from ib_insync to ib_async

Greetings,

I am planning to migrate a code base from ib_insync to ib_async.

I would like to consult with this forum to understand the scope of the migration. Specifically, should I prepare for an extensive code migration, or is it as simple as running a pip install and replacing all imports of ib_insync with ib_async?

Thank you for your insights!


Re: record and replay ib_async session (data only)?

 

?
For the record, something like the following is sufficient to record a session, that is, to record the messages passed between TWS and ib_async, presumably for later "playback", in a pickle file.
?
To implement playback via ib_async will surely take more thought. ? Ib_async would be modified so that, instead of connecting to TWS, the Connection class opens the saved pickle file, then starts playing back the saved messages from TWS to ib_async. ? The application that is using this modified ib_async would have to be built specifically to consume the data that ib_async generates from these messages, without making calls that cause ib_async to send messages to TWS . ? What I haven't yet looked into is the extent to which ib_async itself makes its own calls to TWS, and the extent to which the playback would have to synchronize itself around any such calls.
?
-Neal
?
# """ wrap connection.Connection to save TWS <-> ib_async messages, for later playback
# """

import atexit
import datetime
import inspect
import logging
import pickle
from functools import wraps
from typing import BinaryIO

import ib_async
from ib_async.connection import Connection

logger = logging.getLogger(__name__)


def _now():
return datetime.datetime.now().astimezone()


# method decorator

def
_pickle(method):

_dump_name = method.__name__

if inspect.iscoroutinefunction(method):

@wraps(method)
async def wrapper(self, *args):
pickle.dump((_now(), _dump_name, *args), self._pickle_file)
return await method(self, *args)

else:

@wraps(method)
def wrapper(self, *args):
pickle.dump((_now(), _dump_name, *args), self._pickle_file)
return method(self, *args)

return wrapper


class PickleConnection(Connection):
_pickle_file: BinaryIO

def __init__(self):
self._open_pickle_file()
super().__init__()

def _open_pickle_file(self) -> None:
timestamp = _now().strftime("%Y_%m_%d_%H_%M_%S")
filename = f"connection_{timestamp}.pkl"
atexit.register(self._close_pickle_file)
self._pickle_file = open(filename, "wb+")

def _close_pickle_file(self):
if not self._pickle_file.closed:
self._pickle_file.close()

@_pickle
async def connectAsync(self, host: str, port: int) -> None:
await super().connectAsync(host, port)

@_pickle
def disconnect(self) -> None:
super().disconnect()

@_pickle
def sendMsg(self, msg: bytes) -> None:
super().sendMsg(msg)

@_pickle
def connection_lost(self, exc) -> None:
super().connection_lost(exc)
self._pickle_file.flush()

@_pickle
def data_received(self, data: bytes) -> None:
super().data_received(data)

# patch ib_async to use PickleConnection instead of Connection

ib_async.connection.Connection = PickleConnection
ib_async.client.Connection = PickleConnection

# SCRIPT TO DUMP PKL FILE

# # !/usr/bin/env python3
#
# import datetime
# import sys
# import pickle
#
# filename = sys.argv[1]
#
# time: datetime.datetime
# method_name: str
#
# with open(filename, "rb") as fr:
#
# try:
# while True:
# time, method_name, *args = pickle.load(fr)
# timestamp = time.strftime("%H:%M:%S:%f")[:-1]
# match method_name:
# case "data_received" | "sendMsg":
# assert len(args) == 1
# args = f"{len(args[0])}b"
# case _:
# args = ", ".join(map(str, args))
# print(f"{timestamp}: {method_name}({args})")
# except EOFError:
# pass