@@ -215,6 +215,86 @@ def get_hist_option(
215215 body : DataFrame = TickBody .parse (hist_msg , header , body_data )
216216 return body
217217
218+ def get_opt_at_time (
219+ self ,
220+ req : OptionReqType ,
221+ root : str ,
222+ exp : date ,
223+ strike : float ,
224+ right : OptionRight ,
225+ date_range : DateRange ,
226+ ms_of_day : int = 0 ,
227+ ) -> pd .DataFrame :
228+ """
229+ Returns the last datatype of the request at a provided millisecond of the day.
230+
231+ :param req: The request type.
232+ :param root: The root symbol.
233+ :param exp: The expiration date. Must be after the start of `date_range`.
234+ :param strike: The strike price in USD, rounded to 1/10th of a cent.
235+ :param right: The right of an option.
236+ :param date_range: The dates to fetch.
237+ :param ms_of_day: The time of day in milliseconds.
238+
239+ :return: The requested data as a pandas DataFrame.
240+ :raises ResponseError: If the request failed.
241+ """
242+ assert self ._server is not None , _NOT_CONNECTED_MSG
243+ # format data
244+ strike = _format_strike (strike )
245+ exp_fmt = _format_date (exp )
246+ start_fmt = _format_date (date_range .start )
247+ end_fmt = _format_date (date_range .end )
248+
249+ # send request
250+ hist_msg = f"MSG_CODE={ MessageType .AT_TIME .value } &START_DATE={ start_fmt } &END_DATE={ end_fmt } &root={ root } &exp={ exp_fmt } &strike={ strike } &right={ right .value } &sec={ SecType .OPTION .value } &req={ req .value } &IVL={ ms_of_day } \n "
251+ self ._server .sendall (hist_msg .encode ("utf-8" ))
252+
253+ # parse response header
254+ header_data = self ._server .recv (20 )
255+ header : Header = Header .parse (hist_msg , header_data )
256+
257+ # parse response body
258+ body_data = self ._recv (header .size , progress_bar = False )
259+ body : DataFrame = TickBody .parse (hist_msg , header , body_data )
260+ return body
261+
262+ def get_stk_at_time (
263+ self ,
264+ req : OptionReqType ,
265+ root : str ,
266+ date_range : DateRange ,
267+ ms_of_day : int = 0 ,
268+ ) -> pd .DataFrame :
269+ """
270+ Returns the last datatype of the request at a provided millisecond of the day.
271+
272+ :param req: The request type.
273+ :param root: The root symbol.
274+ :param date_range: The dates to fetch.
275+ :param ms_of_day: The time of day in milliseconds.
276+
277+ :return: The requested data as a pandas DataFrame.
278+ :raises ResponseError: If the request failed.
279+ """
280+ assert self ._server is not None , _NOT_CONNECTED_MSG
281+ # format data
282+ start_fmt = _format_date (date_range .start )
283+ end_fmt = _format_date (date_range .end )
284+
285+ # send request
286+ hist_msg = f"MSG_CODE={ MessageType .AT_TIME .value } &START_DATE={ start_fmt } &END_DATE={ end_fmt } &root={ root } &sec={ SecType .OPTION .value } &req={ req .value } &IVL={ ms_of_day } \n "
287+ self ._server .sendall (hist_msg .encode ("utf-8" ))
288+
289+ # parse response header
290+ header_data = self ._server .recv (20 )
291+ header : Header = Header .parse (hist_msg , header_data )
292+
293+ # parse response body
294+ body_data = self ._recv (header .size , progress_bar = False )
295+ body : DataFrame = TickBody .parse (hist_msg , header , body_data )
296+ return body
297+
218298 def get_hist_stock (
219299 self ,
220300 req : StockReqType ,
0 commit comments