From 2b244a9605f3666aa29a7f9b54e2522001e8e219 Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Sun, 9 Feb 2025 08:57:55 +0100 Subject: [PATCH 01/14] Added market_sessions module --- tastytrade/market_sessions.py | 145 ++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 tastytrade/market_sessions.py diff --git a/tastytrade/market_sessions.py b/tastytrade/market_sessions.py new file mode 100644 index 0000000..d97e537 --- /dev/null +++ b/tastytrade/market_sessions.py @@ -0,0 +1,145 @@ +from datetime import date, datetime +from typing import Optional, List + +from tastytrade.session import Session +from tastytrade.utils import TastytradeJsonDataclass + + +class MarketTimeSessionsNext(TastytradeJsonDataclass): + """Dataclass for data inside the 'next-session' field.""" + close_at: datetime + close_at_ext: Optional[datetime] = None + instrument_collection: str + open_at: datetime + session_date: date + start_at: datetime + + +class MarketTimeSessionsPrevious(TastytradeJsonDataclass): + """Dataclass for data inside the 'previous-session' field.""" + close_at: datetime + close_at_ext: Optional[datetime] = None + instrument_collection: str + open_at: datetime + session_date: date + start_at: datetime + + +class MarketTimeSessionsCurrent(TastytradeJsonDataclass): + """ + Dataclass representing the current session and any nested + 'next' or 'previous' session info. + + NOTE: The JSON you showed places `close-at` etc. under + next-session/previous-session, not at the top level. + Here, we treat 'close_at', 'open_at', etc. as the + ones from 'next_session', purely as an example. + """ + close_at: Optional[datetime] = None + close_at_ext: Optional[datetime] = None + instrument_collection: str + open_at: Optional[datetime] = None + start_at: Optional[datetime] = None + next_session: Optional[MarketTimeSessionsNext] = None + previous_session: Optional[MarketTimeSessionsPrevious] = None + state: str = "" + + +class MarketTimeSessionsResponse(TastytradeJsonDataclass): + """ + Top-level container for the API response, which holds + multiple MarketTimeSessionsCurrent items. + """ + items: List[MarketTimeSessionsCurrent] + + +class MarketCalendarData(TastytradeJsonDataclass): + """ + Represents a data structure holding market half-days and holidays, + each being a list of ISO-format date strings that get parsed into Python 'date' objects. + """ + market_half_days: List[date] + market_holidays: List[date] + + +async def a_get_market_time_sessions(session: Session, instrument_collections: list[str]) -> list[MarketTimeSessionsCurrent]: + """ + Retrieves a list of session timings for a date range. + + :param session: active user session to use + :param instrument_collection: The instrument collection to get market sessions for. Available values : Equity, CME, CFE, Smalls. + + Example: + import tastytrade.market_sessions as Market + mt = await Market.a_get_market_time_sessions(session=session, instrument_collections=['Equity','CME']) + """ + data = await session._a_get( + "/market-time/sessions/current", params = "".join(f"&instrument-collections[]={inst}" for inst in instrument_collections) + ) + return [MarketTimeSessionsCurrent(**i) for i in data["items"]] + + +def get_market_time_sessions(session: Session, instrument_collections: list[str]) -> list[MarketTimeSessionsCurrent]: + """ + Retrieves market metrics for the given symbols. + + :param session: active user session to use + :param instrument_collection: The instrument collection to get market sessions for. Available values : Equity, CME, CFE, Smalls. + + Example: + import tastytrade.market_sessions as Market + mt = Market.get_market_time_sessions(session=session, instrument_collections=['Equity','CME]) + """ + data = session._get("/market-time/sessions/current", params = "".join(f"&instrument-collections[]={inst}" for inst in instrument_collections)) + return [MarketTimeSessionsCurrent(**i) for i in data["items"]] + + +async def a_get_market_time_equity_holidays(session: Session) -> MarketCalendarData: + """ + Retrieves market calendar for half days and holidays. + + :param session: active user session to use + """ + data = await session._a_get("/market-time/equities/holidays") + return MarketCalendarData(**data) + + +def get_market_time_equity_holidays(session: Session) -> MarketCalendarData: + """ + Retrieves market calendar for half days and holidays. + + :param session: active user session to use + """ + data = session._get("/market-time/equities/holidays") + return MarketCalendarData(**data) + + +async def a_get_market_state(session: Session, instrument_collections: list[str]) -> list: + """ + Retrieves market state (Open/Closed). + + :param session: active user session to use + :param instrument_collection: The instrument collection to get market sessions for. Available values : Equity, CME, CFE, Smalls. + + Example: + s = await Market.a_get_market_state(session=session, instrument_collections=['Equity','CME','CFE','Smalls']) + Returns ['Closed', 'Closed', 'Closed', 'Closed'] when all markets are closed. + """ + data = await a_get_market_time_sessions(session=session, instrument_collections=instrument_collections) + return [s.state for s in data] + + +def get_market_state(session: Session, instrument_collections: list[str]) -> list: + """ + Retrieves market state (Open/Closed). + + :param session: active user session to use + :param instrument_collection: The instrument collection to get market sessions for. Available values : Equity, CME, CFE, Smalls. + + Example: + s = Market.get_market_state(session=session, instrument_collections=['Equity','CME','CFE','Smalls']) + Returns ['Closed', 'Closed', 'Closed', 'Closed'] when all markets are closed. + """ + data = get_market_time_sessions(session=session, instrument_collections=instrument_collections) + return [s.state for s in data] + From e66d5d3d461e5fe3948700dc3b30a7153259908c Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Sun, 9 Feb 2025 09:12:30 +0100 Subject: [PATCH 02/14] Added tests for market_sessions module --- tests/test_market_sessions.py | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/test_market_sessions.py diff --git a/tests/test_market_sessions.py b/tests/test_market_sessions.py new file mode 100644 index 0000000..31e08e9 --- /dev/null +++ b/tests/test_market_sessions.py @@ -0,0 +1,37 @@ +from datetime import date + +from tastytrade import Session +from tastytrade.market_sessions import ( + a_get_market_time_sessions, + a_get_market_time_equity_holidays, + a_get_market_state, + get_market_time_sessions, + get_market_time_equity_holidays, + get_market_state, +) + + +async def test_get_market_time_sessions_async(session: Session): + await a_get_market_time_sessions(session, instrument_collections=['Equity','CME','CFE','Smalls']) + + +async def test_get_market_time_equity_holidays_async(session: Session): + await a_get_market_time_equity_holidays(session) + + +async def test_get_market_state_async(session: Session): + await a_get_market_state(session, instrument_collections=['Equity','CME','CFE','Smalls']) + + +def test_get_market_time_sessions(session: Session): + get_market_time_sessions(session, instrument_collections=['Equity','CME','CFE','Smalls']) + + +def test_get_market_time_equity_holidays(session: Session): + get_market_time_equity_holidays(session) + + +def test_get_market_state(session: Session): + get_market_state(session, instrument_collections=['Equity','CME','CFE','Smalls']) + + From 70772d3826ac8209faee2f453c0476e1b888695e Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Sun, 9 Feb 2025 09:17:52 +0100 Subject: [PATCH 03/14] Fixed imports --- tests/test_market_sessions.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_market_sessions.py b/tests/test_market_sessions.py index 31e08e9..0362ac0 100644 --- a/tests/test_market_sessions.py +++ b/tests/test_market_sessions.py @@ -1,5 +1,3 @@ -from datetime import date - from tastytrade import Session from tastytrade.market_sessions import ( a_get_market_time_sessions, From 0bdbfa35eeaf25f624489c355942124f1f7fad1e Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Sun, 9 Feb 2025 11:30:39 +0100 Subject: [PATCH 04/14] Formating --- tastytrade/market_sessions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tastytrade/market_sessions.py b/tastytrade/market_sessions.py index d97e537..abcc758 100644 --- a/tastytrade/market_sessions.py +++ b/tastytrade/market_sessions.py @@ -142,4 +142,3 @@ def get_market_state(session: Session, instrument_collections: list[str]) -> lis """ data = get_market_time_sessions(session=session, instrument_collections=instrument_collections) return [s.state for s in data] - From 54374c0acbf819954a6eb417cab56c58f04adf47 Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Wed, 12 Feb 2025 15:27:56 +0100 Subject: [PATCH 05/14] Ammended: comments --- tastytrade/market_sessions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tastytrade/market_sessions.py b/tastytrade/market_sessions.py index abcc758..796d3ec 100644 --- a/tastytrade/market_sessions.py +++ b/tastytrade/market_sessions.py @@ -139,6 +139,7 @@ def get_market_state(session: Session, instrument_collections: list[str]) -> lis Example: s = Market.get_market_state(session=session, instrument_collections=['Equity','CME','CFE','Smalls']) Returns ['Closed', 'Closed', 'Closed', 'Closed'] when all markets are closed. + Other values seen short before market opening: ['Pre-market', 'Open', 'Open', 'Pre-market'] """ data = get_market_time_sessions(session=session, instrument_collections=instrument_collections) return [s.state for s in data] From 11c97f6fbf7360356c84baa546ba882679dd75f5 Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Fri, 14 Feb 2025 17:54:23 +0100 Subject: [PATCH 06/14] Renamed instrument_collections / Added string enum for MarketState --- tastytrade/market_sessions.py | 35 ++++++++++++++++++++++------------- tests/test_market_sessions.py | 8 ++++---- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/tastytrade/market_sessions.py b/tastytrade/market_sessions.py index 796d3ec..8036063 100644 --- a/tastytrade/market_sessions.py +++ b/tastytrade/market_sessions.py @@ -1,4 +1,5 @@ from datetime import date, datetime +from enum import Enum from typing import Optional, List from tastytrade.session import Session @@ -62,7 +63,13 @@ class MarketCalendarData(TastytradeJsonDataclass): market_holidays: List[date] -async def a_get_market_time_sessions(session: Session, instrument_collections: list[str]) -> list[MarketTimeSessionsCurrent]: +class MarketState(str, Enum): + open = "Open" + closed = "Closed" + pre_market = "Pre-market" + + +async def a_get_market_time_sessions(session: Session, exchanges: list[str]) -> list[MarketTimeSessionsCurrent]: """ Retrieves a list of session timings for a date range. @@ -71,15 +78,15 @@ async def a_get_market_time_sessions(session: Session, instrument_collections: l Example: import tastytrade.market_sessions as Market - mt = await Market.a_get_market_time_sessions(session=session, instrument_collections=['Equity','CME']) + mt = await Market.a_get_market_time_sessions(session=session, exchanges=['Equity','CME']) """ data = await session._a_get( - "/market-time/sessions/current", params = "".join(f"&instrument-collections[]={inst}" for inst in instrument_collections) + "/market-time/sessions/current", params = "".join(f"&instrument-collections[]={inst}" for inst in exchanges) ) return [MarketTimeSessionsCurrent(**i) for i in data["items"]] -def get_market_time_sessions(session: Session, instrument_collections: list[str]) -> list[MarketTimeSessionsCurrent]: +def get_market_time_sessions(session: Session, exchanges: list[str]) -> list[MarketTimeSessionsCurrent]: """ Retrieves market metrics for the given symbols. @@ -88,9 +95,9 @@ def get_market_time_sessions(session: Session, instrument_collections: list[str] Example: import tastytrade.market_sessions as Market - mt = Market.get_market_time_sessions(session=session, instrument_collections=['Equity','CME]) + mt = Market.get_market_time_sessions(session=session, exchanges=['Equity','CME]) """ - data = session._get("/market-time/sessions/current", params = "".join(f"&instrument-collections[]={inst}" for inst in instrument_collections)) + data = session._get("/market-time/sessions/current", params = "".join(f"&instrument-collections[]={inst}" for inst in exchanges)) return [MarketTimeSessionsCurrent(**i) for i in data["items"]] @@ -114,7 +121,7 @@ def get_market_time_equity_holidays(session: Session) -> MarketCalendarData: return MarketCalendarData(**data) -async def a_get_market_state(session: Session, instrument_collections: list[str]) -> list: +async def a_get_market_state(session: Session, exchanges: list[str]) -> list: """ Retrieves market state (Open/Closed). @@ -124,12 +131,13 @@ async def a_get_market_state(session: Session, instrument_collections: list[str] Example: s = await Market.a_get_market_state(session=session, instrument_collections=['Equity','CME','CFE','Smalls']) Returns ['Closed', 'Closed', 'Closed', 'Closed'] when all markets are closed. + Other values seen short before market opening: ['Pre-market', 'Open', 'Open', 'Pre-market'] """ - data = await a_get_market_time_sessions(session=session, instrument_collections=instrument_collections) - return [s.state for s in data] - + data = await a_get_market_time_sessions(session=session, exchanges=exchanges) + enum_states = [MarketState(s.state) for s in data] + return [st.value for st in enum_states] -def get_market_state(session: Session, instrument_collections: list[str]) -> list: +def get_market_state(session: Session, exchanges: list[str]) -> list: """ Retrieves market state (Open/Closed). @@ -141,5 +149,6 @@ def get_market_state(session: Session, instrument_collections: list[str]) -> lis Returns ['Closed', 'Closed', 'Closed', 'Closed'] when all markets are closed. Other values seen short before market opening: ['Pre-market', 'Open', 'Open', 'Pre-market'] """ - data = get_market_time_sessions(session=session, instrument_collections=instrument_collections) - return [s.state for s in data] + data = get_market_time_sessions(session=session, exchanges=exchanges) + enum_states = [MarketState(s.state) for s in data] + return [st.value for st in enum_states] \ No newline at end of file diff --git a/tests/test_market_sessions.py b/tests/test_market_sessions.py index 0362ac0..6d7f085 100644 --- a/tests/test_market_sessions.py +++ b/tests/test_market_sessions.py @@ -10,7 +10,7 @@ async def test_get_market_time_sessions_async(session: Session): - await a_get_market_time_sessions(session, instrument_collections=['Equity','CME','CFE','Smalls']) + await a_get_market_time_sessions(session, exchanges=['Equity','CME','CFE','Smalls']) async def test_get_market_time_equity_holidays_async(session: Session): @@ -18,11 +18,11 @@ async def test_get_market_time_equity_holidays_async(session: Session): async def test_get_market_state_async(session: Session): - await a_get_market_state(session, instrument_collections=['Equity','CME','CFE','Smalls']) + await a_get_market_state(session, exchanges=['Equity','CME','CFE','Smalls']) def test_get_market_time_sessions(session: Session): - get_market_time_sessions(session, instrument_collections=['Equity','CME','CFE','Smalls']) + get_market_time_sessions(session, exchanges=['Equity','CME','CFE','Smalls']) def test_get_market_time_equity_holidays(session: Session): @@ -30,6 +30,6 @@ def test_get_market_time_equity_holidays(session: Session): def test_get_market_state(session: Session): - get_market_state(session, instrument_collections=['Equity','CME','CFE','Smalls']) + get_market_state(session, exchanges=['Equity','CME','CFE','Smalls']) From 709ff54b53f083d4ad4b443f0d782095add59d36 Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Fri, 14 Feb 2025 18:07:29 +0100 Subject: [PATCH 07/14] Added: Docstring --- tastytrade/market_sessions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tastytrade/market_sessions.py b/tastytrade/market_sessions.py index 8036063..ef0a65b 100644 --- a/tastytrade/market_sessions.py +++ b/tastytrade/market_sessions.py @@ -64,6 +64,9 @@ class MarketCalendarData(TastytradeJsonDataclass): class MarketState(str, Enum): + """ + Represents a data structure holding valid market states. + """ open = "Open" closed = "Closed" pre_market = "Pre-market" From ff4eb1cfcaeed73bb2acab5faa1a1c1031adbaaa Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Fri, 14 Feb 2025 22:06:57 +0100 Subject: [PATCH 08/14] Added: MarketState "Extended" --- tastytrade/market_sessions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tastytrade/market_sessions.py b/tastytrade/market_sessions.py index ef0a65b..3a3f08d 100644 --- a/tastytrade/market_sessions.py +++ b/tastytrade/market_sessions.py @@ -70,6 +70,7 @@ class MarketState(str, Enum): open = "Open" closed = "Closed" pre_market = "Pre-market" + extended = "Extended" async def a_get_market_time_sessions(session: Session, exchanges: list[str]) -> list[MarketTimeSessionsCurrent]: @@ -151,6 +152,7 @@ def get_market_state(session: Session, exchanges: list[str]) -> list: s = Market.get_market_state(session=session, instrument_collections=['Equity','CME','CFE','Smalls']) Returns ['Closed', 'Closed', 'Closed', 'Closed'] when all markets are closed. Other values seen short before market opening: ['Pre-market', 'Open', 'Open', 'Pre-market'] + Extended market hours: ['Extended', 'Open', 'Open', 'Closed'] """ data = get_market_time_sessions(session=session, exchanges=exchanges) enum_states = [MarketState(s.state) for s in data] From 696bbf38852e3ceb44196981e5b829f7ae31e4e3 Mon Sep 17 00:00:00 2001 From: Graeme Holliday Date: Sat, 15 Feb 2025 15:06:56 -0500 Subject: [PATCH 09/14] clean up code --- tastytrade/market_sessions.py | 154 +++++++++++++--------------------- tests/test_market_sessions.py | 42 +++++----- 2 files changed, 77 insertions(+), 119 deletions(-) diff --git a/tastytrade/market_sessions.py b/tastytrade/market_sessions.py index 3a3f08d..d2066d6 100644 --- a/tastytrade/market_sessions.py +++ b/tastytrade/market_sessions.py @@ -1,23 +1,40 @@ from datetime import date, datetime from enum import Enum -from typing import Optional, List +from typing import Optional + +from pydantic import Field from tastytrade.session import Session from tastytrade.utils import TastytradeJsonDataclass -class MarketTimeSessionsNext(TastytradeJsonDataclass): - """Dataclass for data inside the 'next-session' field.""" - close_at: datetime - close_at_ext: Optional[datetime] = None - instrument_collection: str - open_at: datetime - session_date: date - start_at: datetime +class ExchangeType(str, Enum): + """ + Contains the valid exchanges to get market sessions for. + """ + + CME = "CME" + CFE = "CFE" + NYSE = "Equity" + SMALL = "Smalls" + +class MarketStatus(str, Enum): + """ + Contains the valid market status values. + """ + + OPEN = "Open" + CLOSED = "Closed" + PRE_MARKET = "Pre-market" + EXTENDED = "Extended" + + +class MarketSessionSnapshot(TastytradeJsonDataclass): + """ + Dataclass containing information about the upcoming or previous market session. + """ -class MarketTimeSessionsPrevious(TastytradeJsonDataclass): - """Dataclass for data inside the 'previous-session' field.""" close_at: datetime close_at_ext: Optional[datetime] = None instrument_collection: str @@ -26,86 +43,63 @@ class MarketTimeSessionsPrevious(TastytradeJsonDataclass): start_at: datetime -class MarketTimeSessionsCurrent(TastytradeJsonDataclass): +class MarketSession(TastytradeJsonDataclass): """ - Dataclass representing the current session and any nested - 'next' or 'previous' session info. - - NOTE: The JSON you showed places `close-at` etc. under - next-session/previous-session, not at the top level. - Here, we treat 'close_at', 'open_at', etc. as the - ones from 'next_session', purely as an example. + Dataclass representing the current session as well as the next and previous sessions. """ + close_at: Optional[datetime] = None close_at_ext: Optional[datetime] = None instrument_collection: str open_at: Optional[datetime] = None start_at: Optional[datetime] = None - next_session: Optional[MarketTimeSessionsNext] = None - previous_session: Optional[MarketTimeSessionsPrevious] = None - state: str = "" - - -class MarketTimeSessionsResponse(TastytradeJsonDataclass): - """ - Top-level container for the API response, which holds - multiple MarketTimeSessionsCurrent items. - """ - items: List[MarketTimeSessionsCurrent] + next_session: Optional[MarketSessionSnapshot] = None + previous_session: Optional[MarketSessionSnapshot] = None + status: MarketStatus = Field(alias="state") class MarketCalendarData(TastytradeJsonDataclass): """ - Represents a data structure holding market half-days and holidays, - each being a list of ISO-format date strings that get parsed into Python 'date' objects. + Dataclass containing information about market holidays and shortened days. """ - market_half_days: List[date] - market_holidays: List[date] - -class MarketState(str, Enum): - """ - Represents a data structure holding valid market states. - """ - open = "Open" - closed = "Closed" - pre_market = "Pre-market" - extended = "Extended" + market_half_days: list[date] + market_holidays: list[date] -async def a_get_market_time_sessions(session: Session, exchanges: list[str]) -> list[MarketTimeSessionsCurrent]: +async def a_get_market_sessions( + session: Session, exchanges: list[ExchangeType] +) -> list[MarketSession]: """ - Retrieves a list of session timings for a date range. + Retrieves a list of session timings for the given exchanges. :param session: active user session to use - :param instrument_collection: The instrument collection to get market sessions for. Available values : Equity, CME, CFE, Smalls. - - Example: - import tastytrade.market_sessions as Market - mt = await Market.a_get_market_time_sessions(session=session, exchanges=['Equity','CME']) + :param exchanges: the list of exchanges to get market sessions for """ data = await session._a_get( - "/market-time/sessions/current", params = "".join(f"&instrument-collections[]={inst}" for inst in exchanges) + "/market-time/sessions/current", + params={"instrument-collections[]": [e.value for e in exchanges]}, ) - return [MarketTimeSessionsCurrent(**i) for i in data["items"]] + return [MarketSession(**i) for i in data["items"]] -def get_market_time_sessions(session: Session, exchanges: list[str]) -> list[MarketTimeSessionsCurrent]: +def get_market_sessions( + session: Session, exchanges: list[ExchangeType] +) -> list[MarketSession]: """ - Retrieves market metrics for the given symbols. + Retrieves a list of session timings for the given exchanges. :param session: active user session to use - :param instrument_collection: The instrument collection to get market sessions for. Available values : Equity, CME, CFE, Smalls. - - Example: - import tastytrade.market_sessions as Market - mt = Market.get_market_time_sessions(session=session, exchanges=['Equity','CME]) + :param exchanges: the list of exchanges to get market sessions for """ - data = session._get("/market-time/sessions/current", params = "".join(f"&instrument-collections[]={inst}" for inst in exchanges)) - return [MarketTimeSessionsCurrent(**i) for i in data["items"]] + data = session._get( + "/market-time/sessions/current", + params={"instrument-collections[]": [e.value for e in exchanges]}, + ) + return [MarketSession(**i) for i in data["items"]] -async def a_get_market_time_equity_holidays(session: Session) -> MarketCalendarData: +async def a_get_market_holidays(session: Session) -> MarketCalendarData: """ Retrieves market calendar for half days and holidays. @@ -115,7 +109,7 @@ async def a_get_market_time_equity_holidays(session: Session) -> MarketCalendarD return MarketCalendarData(**data) -def get_market_time_equity_holidays(session: Session) -> MarketCalendarData: +def get_market_holidays(session: Session) -> MarketCalendarData: """ Retrieves market calendar for half days and holidays. @@ -123,37 +117,3 @@ def get_market_time_equity_holidays(session: Session) -> MarketCalendarData: """ data = session._get("/market-time/equities/holidays") return MarketCalendarData(**data) - - -async def a_get_market_state(session: Session, exchanges: list[str]) -> list: - """ - Retrieves market state (Open/Closed). - - :param session: active user session to use - :param instrument_collection: The instrument collection to get market sessions for. Available values : Equity, CME, CFE, Smalls. - - Example: - s = await Market.a_get_market_state(session=session, instrument_collections=['Equity','CME','CFE','Smalls']) - Returns ['Closed', 'Closed', 'Closed', 'Closed'] when all markets are closed. - Other values seen short before market opening: ['Pre-market', 'Open', 'Open', 'Pre-market'] - """ - data = await a_get_market_time_sessions(session=session, exchanges=exchanges) - enum_states = [MarketState(s.state) for s in data] - return [st.value for st in enum_states] - -def get_market_state(session: Session, exchanges: list[str]) -> list: - """ - Retrieves market state (Open/Closed). - - :param session: active user session to use - :param instrument_collection: The instrument collection to get market sessions for. Available values : Equity, CME, CFE, Smalls. - - Example: - s = Market.get_market_state(session=session, instrument_collections=['Equity','CME','CFE','Smalls']) - Returns ['Closed', 'Closed', 'Closed', 'Closed'] when all markets are closed. - Other values seen short before market opening: ['Pre-market', 'Open', 'Open', 'Pre-market'] - Extended market hours: ['Extended', 'Open', 'Open', 'Closed'] - """ - data = get_market_time_sessions(session=session, exchanges=exchanges) - enum_states = [MarketState(s.state) for s in data] - return [st.value for st in enum_states] \ No newline at end of file diff --git a/tests/test_market_sessions.py b/tests/test_market_sessions.py index 6d7f085..25c8cd2 100644 --- a/tests/test_market_sessions.py +++ b/tests/test_market_sessions.py @@ -1,35 +1,33 @@ +from pytest import fixture + from tastytrade import Session from tastytrade.market_sessions import ( - a_get_market_time_sessions, - a_get_market_time_equity_holidays, - a_get_market_state, - get_market_time_sessions, - get_market_time_equity_holidays, - get_market_state, + ExchangeType, + a_get_market_sessions, + a_get_market_holidays, + get_market_sessions, + get_market_holidays, ) -async def test_get_market_time_sessions_async(session: Session): - await a_get_market_time_sessions(session, exchanges=['Equity','CME','CFE','Smalls']) - - -async def test_get_market_time_equity_holidays_async(session: Session): - await a_get_market_time_equity_holidays(session) - - -async def test_get_market_state_async(session: Session): - await a_get_market_state(session, exchanges=['Equity','CME','CFE','Smalls']) +@fixture +def exchanges() -> list[ExchangeType]: + return [ExchangeType.NYSE, ExchangeType.CME, ExchangeType.CFE, ExchangeType.SMALL] -def test_get_market_time_sessions(session: Session): - get_market_time_sessions(session, exchanges=['Equity','CME','CFE','Smalls']) +async def test_get_market_sessions_async( + session: Session, exchanges: list[ExchangeType] +): + await a_get_market_sessions(session, exchanges=exchanges) -def test_get_market_time_equity_holidays(session: Session): - get_market_time_equity_holidays(session) +async def test_get_market_holidays_async(session: Session): + await a_get_market_holidays(session) -def test_get_market_state(session: Session): - get_market_state(session, exchanges=['Equity','CME','CFE','Smalls']) +def test_get_market_sessions(session: Session, exchanges: list[ExchangeType]): + get_market_sessions(session, exchanges=exchanges) +def test_get_market_holidays(session: Session): + get_market_holidays(session) From fb35a2f03cab634fcbddc2a92bc05c58a8860a30 Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Sun, 16 Feb 2025 21:57:16 +0100 Subject: [PATCH 10/14] Added: Docfile --- docs/market_sessions.rst | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 docs/market_sessions.rst diff --git a/docs/market_sessions.rst b/docs/market_sessions.rst new file mode 100644 index 0000000..db3adf8 --- /dev/null +++ b/docs/market_sessions.rst @@ -0,0 +1,53 @@ +Market Sessions +=============== + +A market time sessiom object contains information about the current state of specific markets. It can be used to get the market opening and closing times and state. + +The dataclass represents the current session and any nested 'next' or 'previous' session info. + +The ``get_market_sessions`` function can be used to obtain information about the current: + +.. code-block:: python + + import tastytrade.market_sessions as Market + from tastytrade.market_sessions import ExchangeType + mt = Market.get_market_sessions(session=session, exchanges=[ExchangeType.NYSE, ExchangeType.CME, ExchangeType.CFE, ExchangeType.SMALL]) + print("Market time sessions:") + print(mt) + +>>> [MarketTimeSessionsCurrent(close_at=None, close_at_ext=None, instrument_collection='Equity', open_at=None, start_at=None, next_session=MarketTimeSessionsNext(close_at=datetime.datetime(2025, 2, 18, 21, 0, tzinfo=TzInfo(UTC)), close_at_ext=datetime.datetime(2025, 2, 19, 1, 0, tzinfo=TzInfo(UTC)), instrument_collection='Equity', open_at=datetime.datetime(2025, 2, 18, 14, 30, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 18), start_at=datetime.datetime(2025, 2, 18, 13, 15, tzinfo=TzInfo(UTC))), previous_session=MarketTimeSessionsPrevious(close_at=datetime.datetime(2025, 2, 14, 21, 0, tzinfo=TzInfo(UTC)), close_at_ext=datetime.datetime(2025, 2, 15, 1, 0, tzinfo=TzInfo(UTC)), instrument_collection='Equity', open_at=datetime.datetime(2025, 2, 14, 14, 30, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 14), start_at=datetime.datetime(2025, 2, 14, 13, 15, tzinfo=TzInfo(UTC))), state='Closed'), MarketTimeSessionsCurrent(close_at=None, close_at_ext=None, instrument_collection='CME', open_at=None, start_at=None, next_session=MarketTimeSessionsNext(close_at=datetime.datetime(2025, 2, 18, 22, 0, tzinfo=TzInfo(UTC)), close_at_ext=None, instrument_collection='CME', open_at=datetime.datetime(2025, 2, 16, 23, 0, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 16), start_at=datetime.datetime(2025, 2, 16, 22, 50, tzinfo=TzInfo(UTC))), previous_session=MarketTimeSessionsPrevious(close_at=datetime.datetime(2025, 2, 14, 22, 0, tzinfo=TzInfo(UTC)), close_at_ext=None, instrument_collection='CME', open_at=datetime.datetime(2025, 2, 13, 23, 0, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 14), start_at=datetime.datetime(2025, 2, 13, 22, 50, tzinfo=TzInfo(UTC))), state='Closed')] + +The ``get_market_holidays`` function can be used to obtain information about markets half_days and market holidays: + +.. code-block:: python + + calendar_data = Market.get_market_time_equity_holidays(session=session) + print("Market half days") + print(calendar_data.market_half_days) # list of datetime.date objects + print("Market holidays") + print(calendar_data.market_holidays) # list of datetime.date objects + +Market half days: +>>> [datetime.date(2015, 12, 24), datetime.date(2016, 11, 25), datetime.date(2017, 7, 3), datetime.date(2017, 11, 24), datetime.date(2018, 7, 3), datetime.date(2018, 11, 23), datetime.date(2018, 12, 24), datetime.date(2019, 7, 3), datetime.date(2019, 11, 29), datetime.date(2019, 12, 24), datetime.date(2020, 11, 27), datetime.date(2020, 12, 24), datetime.date(2021, 11, 26), datetime.date(2022, 11, 25), datetime.date(2023, 7, 3), datetime.date(2023, 11, 24), datetime.date(2024, 7, 3), datetime.date(2024, 11, 29), datetime.date(2024, 12, 24), datetime.date(2025, 7, 3), datetime.date(2025, 11, 28), datetime.date(2025, 12, 24), datetime.date(2026, 11, 27), datetime.date(2026, 12, 24), datetime.date(2027, 7, 2), datetime.date(2027, 11, 26), datetime.date(2027, 12, 23), datetime.date(2028, 7, 3), datetime.date(2028, 11, 24), datetime.date(2028, 12, 22), datetime.date(2029, 7, 3)] + +Market holidays: +>>> [datetime.date(2015, 12, 25), datetime.date(2016, 1, 1), datetime.date(2016, 1, 18), datetime.date(2016, 2, 15), datetime.date(2016, 3, 25), datetime.date(2016, 5, 30), datetime.date(2016, 7, 4), datetime.date(2016, 9, 5), datetime.date(2016, 11, 24), datetime.date(2016, 12, 26), datetime.date(2017, 1, 2), datetime.date(2017, 1, 16), datetime.date(2017, 2, 20), datetime.date(2017, 4, 14), datetime.date(2017, 5, 29), datetime.date(2017, 7, 4), datetime.date(2017, 9, 4), datetime.date(2017, 11, 23), datetime.date(2017, 12, 25), datetime.date(2018, 1, 1), datetime.date(2018, 1, 15), datetime.date(2018, 2, 19), datetime.date(2018, 3, 30), datetime.date(2018, 5, 28), datetime.date(2018, 7, 4), datetime.date(2018, 9, 3), datetime.date(2018, 11, 22), datetime.date(2018, 12, 5), datetime.date(2018, 12, 25), datetime.date(2019, 1, 1), datetime.date(2019, 1, 21), datetime.date(2019, 2, 18), datetime.date(2019, 4, 19), datetime.date(2019, 5, 27), datetime.date(2019, 7, 4), datetime.date(2019, 9, 2), datetime.date(2019, 11, 28), datetime.date(2019, 12, 25), datetime.date(2020, 1, 1), datetime.date(2020, 1, 20), datetime.date(2020, 2, 17), datetime.date(2020, 4, 10), datetime.date(2020, 5, 25), datetime.date(2020, 7, 3), datetime.date(2020, 9, 7), datetime.date(2020, 11, 26), datetime.date(2020, 12, 25), datetime.date(2021, 1, 1), datetime.date(2021, 1, 18), datetime.date(2021, 2, 15), datetime.date(2021, 4, 2), datetime.date(2021, 5, 31), datetime.date(2021, 7, 5), datetime.date(2021, 9, 6), datetime.date(2021, 11, 25), datetime.date(2021, 12, 24), datetime.date(2022, 1, 17), datetime.date(2022, 2, 21), datetime.date(2022, 4, 15), datetime.date(2022, 5, 30), datetime.date(2022, 6, 20), datetime.date(2022, 7, 4), datetime.date(2022, 9, 5), datetime.date(2022, 11, 24), datetime.date(2022, 12, 26), datetime.date(2023, 1, 2), datetime.date(2023, 1, 16), datetime.date(2023, 2, 20), datetime.date(2023, 4, 7), datetime.date(2023, 5, 29), datetime.date(2023, 6, 19), datetime.date(2023, 7, 4), datetime.date(2023, 9, 4), datetime.date(2023, 11, 23), datetime.date(2023, 12, 25), datetime.date(2024, 1, 1), datetime.date(2024, 1, 15), datetime.date(2024, 2, 19), datetime.date(2024, 3, 29), datetime.date(2024, 5, 27), datetime.date(2024, 6, 19), datetime.date(2024, 7, 4), datetime.date(2024, 9, 2), datetime.date(2024, 11, 28), datetime.date(2024, 12, 25), datetime.date(2025, 1, 1), datetime.date(2025, 1, 9), datetime.date(2025, 1, 20), datetime.date(2025, 2, 17), datetime.date(2025, 4, 18), datetime.date(2025, 5, 26), datetime.date(2025, 6, 19), datetime.date(2025, 7, 4), datetime.date(2025, 9, 1), datetime.date(2025, 11, 27), datetime.date(2025, 12, 25), datetime.date(2026, 1, 1), datetime.date(2026, 1, 19), datetime.date(2026, 2, 16), datetime.date(2026, 4, 3), datetime.date(2026, 5, 25), datetime.date(2026, 6, 19), datetime.date(2026, 7, 3), datetime.date(2026, 9, 7), datetime.date(2026, 11, 26), datetime.date(2026, 12, 25), datetime.date(2027, 1, 1), datetime.date(2027, 1, 18), datetime.date(2027, 2, 15), datetime.date(2027, 3, 26), datetime.date(2027, 5, 31), datetime.date(2027, 6, 18), datetime.date(2027, 7, 5), datetime.date(2027, 9, 6), datetime.date(2027, 11, 25), datetime.date(2027, 12, 24), datetime.date(2028, 1, 17), datetime.date(2028, 2, 21), datetime.date(2028, 4, 14), datetime.date(2028, 5, 29), datetime.date(2028, 6, 19), datetime.date(2028, 7, 4), datetime.date(2028, 9, 4), datetime.date(2028, 11, 23), datetime.date(2028, 12, 25), datetime.date(2029, 1, 1), datetime.date(2029, 1, 15), datetime.date(2029, 2, 19), datetime.date(2029, 3, 30), datetime.date(2029, 5, 28), datetime.date(2029, 6, 19), datetime.date(2029, 7, 4), datetime.date(2029, 9, 3)] + + +I case you only want to extract the market status, this is one way to do it: + +.. code-block:: python + + import tastytrade.market_sessions as Market + from tastytrade.market_sessions import ExchangeType, MarketStatus + + def get_market_state(session: Session, exchanges: list[ExchangeType]) -> list: + data = Market.get_market_sessions(session=session, exchanges=exchanges) + enum_states = [MarketStatus(s.status) for s in data] + return [st.value for st in enum_states] + + s = get_market_state(session=session, exchanges=[ExchangeType.NYSE, ExchangeType.CME, ExchangeType.CFE, ExchangeType.SMALL]) + print(s) + +When all markets are closed: +>>> ['Closed', 'Closed', 'Closed', 'Closed'] \ No newline at end of file From d922098117b242acc7a8ae13ed66e869630bc851 Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Sun, 16 Feb 2025 22:00:28 +0100 Subject: [PATCH 11/14] Fixed: Typo --- docs/market_sessions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/market_sessions.rst b/docs/market_sessions.rst index db3adf8..02009b3 100644 --- a/docs/market_sessions.rst +++ b/docs/market_sessions.rst @@ -1,7 +1,7 @@ Market Sessions =============== -A market time sessiom object contains information about the current state of specific markets. It can be used to get the market opening and closing times and state. +A market time session object contains information about the current state of specific markets. It can be used to get the market opening and closing times and state. The dataclass represents the current session and any nested 'next' or 'previous' session info. From e9db9f1359dd830f2aadddbfd701423e88e0c730 Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Mon, 17 Feb 2025 10:37:58 +0100 Subject: [PATCH 12/14] Adjusted: Doc test case --- docs/market_sessions.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/market_sessions.rst b/docs/market_sessions.rst index 02009b3..ab667db 100644 --- a/docs/market_sessions.rst +++ b/docs/market_sessions.rst @@ -11,12 +11,11 @@ The ``get_market_sessions`` function can be used to obtain information about the import tastytrade.market_sessions as Market from tastytrade.market_sessions import ExchangeType - mt = Market.get_market_sessions(session=session, exchanges=[ExchangeType.NYSE, ExchangeType.CME, ExchangeType.CFE, ExchangeType.SMALL]) + mt = Market.get_market_sessions(session=session, exchanges=[ExchangeType.NYSE]) print("Market time sessions:") print(mt) ->>> [MarketTimeSessionsCurrent(close_at=None, close_at_ext=None, instrument_collection='Equity', open_at=None, start_at=None, next_session=MarketTimeSessionsNext(close_at=datetime.datetime(2025, 2, 18, 21, 0, tzinfo=TzInfo(UTC)), close_at_ext=datetime.datetime(2025, 2, 19, 1, 0, tzinfo=TzInfo(UTC)), instrument_collection='Equity', open_at=datetime.datetime(2025, 2, 18, 14, 30, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 18), start_at=datetime.datetime(2025, 2, 18, 13, 15, tzinfo=TzInfo(UTC))), previous_session=MarketTimeSessionsPrevious(close_at=datetime.datetime(2025, 2, 14, 21, 0, tzinfo=TzInfo(UTC)), close_at_ext=datetime.datetime(2025, 2, 15, 1, 0, tzinfo=TzInfo(UTC)), instrument_collection='Equity', open_at=datetime.datetime(2025, 2, 14, 14, 30, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 14), start_at=datetime.datetime(2025, 2, 14, 13, 15, tzinfo=TzInfo(UTC))), state='Closed'), MarketTimeSessionsCurrent(close_at=None, close_at_ext=None, instrument_collection='CME', open_at=None, start_at=None, next_session=MarketTimeSessionsNext(close_at=datetime.datetime(2025, 2, 18, 22, 0, tzinfo=TzInfo(UTC)), close_at_ext=None, instrument_collection='CME', open_at=datetime.datetime(2025, 2, 16, 23, 0, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 16), start_at=datetime.datetime(2025, 2, 16, 22, 50, tzinfo=TzInfo(UTC))), previous_session=MarketTimeSessionsPrevious(close_at=datetime.datetime(2025, 2, 14, 22, 0, tzinfo=TzInfo(UTC)), close_at_ext=None, instrument_collection='CME', open_at=datetime.datetime(2025, 2, 13, 23, 0, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 14), start_at=datetime.datetime(2025, 2, 13, 22, 50, tzinfo=TzInfo(UTC))), state='Closed')] - +>>> [MarketSession(close_at=None, close_at_ext=None, instrument_collection='Equity', open_at=None, start_at=None, next_session=MarketSessionSnapshot(close_at=datetime.datetime(2025, 2, 18, 21, 0, tzinfo=TzInfo(UTC)), close_at_ext=datetime.datetime(2025, 2, 19, 1, 0, tzinfo=TzInfo(UTC)), instrument_collection='Equity', open_at=datetime.datetime(2025, 2, 18, 14, 30, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 18), start_at=datetime.datetime(2025, 2, 18, 13, 15, tzinfo=TzInfo(UTC))), previous_session=MarketSessionSnapshot(close_at=datetime.datetime(2025, 2, 14, 21, 0, tzinfo=TzInfo(UTC)), close_at_ext=datetime.datetime(2025, 2, 15, 1, 0, tzinfo=TzInfo(UTC)), instrument_collection='Equity', open_at=datetime.datetime(2025, 2, 14, 14, 30, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 14), start_at=datetime.datetime(2025, 2, 14, 13, 15, tzinfo=TzInfo(UTC))), status=)] The ``get_market_holidays`` function can be used to obtain information about markets half_days and market holidays: .. code-block:: python From 6fba87d2512ea7901b7eceaecd6d1c229e05bb5c Mon Sep 17 00:00:00 2001 From: Joern Blohm Date: Mon, 17 Feb 2025 10:39:57 +0100 Subject: [PATCH 13/14] Fix: formating --- docs/market_sessions.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/market_sessions.rst b/docs/market_sessions.rst index ab667db..a6e785f 100644 --- a/docs/market_sessions.rst +++ b/docs/market_sessions.rst @@ -26,10 +26,8 @@ The ``get_market_holidays`` function can be used to obtain information about mar print("Market holidays") print(calendar_data.market_holidays) # list of datetime.date objects -Market half days: >>> [datetime.date(2015, 12, 24), datetime.date(2016, 11, 25), datetime.date(2017, 7, 3), datetime.date(2017, 11, 24), datetime.date(2018, 7, 3), datetime.date(2018, 11, 23), datetime.date(2018, 12, 24), datetime.date(2019, 7, 3), datetime.date(2019, 11, 29), datetime.date(2019, 12, 24), datetime.date(2020, 11, 27), datetime.date(2020, 12, 24), datetime.date(2021, 11, 26), datetime.date(2022, 11, 25), datetime.date(2023, 7, 3), datetime.date(2023, 11, 24), datetime.date(2024, 7, 3), datetime.date(2024, 11, 29), datetime.date(2024, 12, 24), datetime.date(2025, 7, 3), datetime.date(2025, 11, 28), datetime.date(2025, 12, 24), datetime.date(2026, 11, 27), datetime.date(2026, 12, 24), datetime.date(2027, 7, 2), datetime.date(2027, 11, 26), datetime.date(2027, 12, 23), datetime.date(2028, 7, 3), datetime.date(2028, 11, 24), datetime.date(2028, 12, 22), datetime.date(2029, 7, 3)] -Market holidays: >>> [datetime.date(2015, 12, 25), datetime.date(2016, 1, 1), datetime.date(2016, 1, 18), datetime.date(2016, 2, 15), datetime.date(2016, 3, 25), datetime.date(2016, 5, 30), datetime.date(2016, 7, 4), datetime.date(2016, 9, 5), datetime.date(2016, 11, 24), datetime.date(2016, 12, 26), datetime.date(2017, 1, 2), datetime.date(2017, 1, 16), datetime.date(2017, 2, 20), datetime.date(2017, 4, 14), datetime.date(2017, 5, 29), datetime.date(2017, 7, 4), datetime.date(2017, 9, 4), datetime.date(2017, 11, 23), datetime.date(2017, 12, 25), datetime.date(2018, 1, 1), datetime.date(2018, 1, 15), datetime.date(2018, 2, 19), datetime.date(2018, 3, 30), datetime.date(2018, 5, 28), datetime.date(2018, 7, 4), datetime.date(2018, 9, 3), datetime.date(2018, 11, 22), datetime.date(2018, 12, 5), datetime.date(2018, 12, 25), datetime.date(2019, 1, 1), datetime.date(2019, 1, 21), datetime.date(2019, 2, 18), datetime.date(2019, 4, 19), datetime.date(2019, 5, 27), datetime.date(2019, 7, 4), datetime.date(2019, 9, 2), datetime.date(2019, 11, 28), datetime.date(2019, 12, 25), datetime.date(2020, 1, 1), datetime.date(2020, 1, 20), datetime.date(2020, 2, 17), datetime.date(2020, 4, 10), datetime.date(2020, 5, 25), datetime.date(2020, 7, 3), datetime.date(2020, 9, 7), datetime.date(2020, 11, 26), datetime.date(2020, 12, 25), datetime.date(2021, 1, 1), datetime.date(2021, 1, 18), datetime.date(2021, 2, 15), datetime.date(2021, 4, 2), datetime.date(2021, 5, 31), datetime.date(2021, 7, 5), datetime.date(2021, 9, 6), datetime.date(2021, 11, 25), datetime.date(2021, 12, 24), datetime.date(2022, 1, 17), datetime.date(2022, 2, 21), datetime.date(2022, 4, 15), datetime.date(2022, 5, 30), datetime.date(2022, 6, 20), datetime.date(2022, 7, 4), datetime.date(2022, 9, 5), datetime.date(2022, 11, 24), datetime.date(2022, 12, 26), datetime.date(2023, 1, 2), datetime.date(2023, 1, 16), datetime.date(2023, 2, 20), datetime.date(2023, 4, 7), datetime.date(2023, 5, 29), datetime.date(2023, 6, 19), datetime.date(2023, 7, 4), datetime.date(2023, 9, 4), datetime.date(2023, 11, 23), datetime.date(2023, 12, 25), datetime.date(2024, 1, 1), datetime.date(2024, 1, 15), datetime.date(2024, 2, 19), datetime.date(2024, 3, 29), datetime.date(2024, 5, 27), datetime.date(2024, 6, 19), datetime.date(2024, 7, 4), datetime.date(2024, 9, 2), datetime.date(2024, 11, 28), datetime.date(2024, 12, 25), datetime.date(2025, 1, 1), datetime.date(2025, 1, 9), datetime.date(2025, 1, 20), datetime.date(2025, 2, 17), datetime.date(2025, 4, 18), datetime.date(2025, 5, 26), datetime.date(2025, 6, 19), datetime.date(2025, 7, 4), datetime.date(2025, 9, 1), datetime.date(2025, 11, 27), datetime.date(2025, 12, 25), datetime.date(2026, 1, 1), datetime.date(2026, 1, 19), datetime.date(2026, 2, 16), datetime.date(2026, 4, 3), datetime.date(2026, 5, 25), datetime.date(2026, 6, 19), datetime.date(2026, 7, 3), datetime.date(2026, 9, 7), datetime.date(2026, 11, 26), datetime.date(2026, 12, 25), datetime.date(2027, 1, 1), datetime.date(2027, 1, 18), datetime.date(2027, 2, 15), datetime.date(2027, 3, 26), datetime.date(2027, 5, 31), datetime.date(2027, 6, 18), datetime.date(2027, 7, 5), datetime.date(2027, 9, 6), datetime.date(2027, 11, 25), datetime.date(2027, 12, 24), datetime.date(2028, 1, 17), datetime.date(2028, 2, 21), datetime.date(2028, 4, 14), datetime.date(2028, 5, 29), datetime.date(2028, 6, 19), datetime.date(2028, 7, 4), datetime.date(2028, 9, 4), datetime.date(2028, 11, 23), datetime.date(2028, 12, 25), datetime.date(2029, 1, 1), datetime.date(2029, 1, 15), datetime.date(2029, 2, 19), datetime.date(2029, 3, 30), datetime.date(2029, 5, 28), datetime.date(2029, 6, 19), datetime.date(2029, 7, 4), datetime.date(2029, 9, 3)] From d3cf92a19d32b3dce9cdefdf2609daf089a9530e Mon Sep 17 00:00:00 2001 From: Graeme Holliday Date: Mon, 17 Feb 2025 10:52:04 -0500 Subject: [PATCH 14/14] update docs --- docs/index.rst | 1 + ...arket_sessions.rst => market-sessions.rst} | 38 +++++++------------ tastytrade/market_sessions.py | 14 +++---- 3 files changed, 21 insertions(+), 32 deletions(-) rename docs/{market_sessions.rst => market-sessions.rst} (84%) diff --git a/docs/index.rst b/docs/index.rst index 293bb63..bc0c43e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -38,6 +38,7 @@ A simple, reverse-engineered, sync/async SDK for Tastytrade built on their (now account-streamer data-streamer backtest + market-sessions watchlists .. toctree:: diff --git a/docs/market_sessions.rst b/docs/market-sessions.rst similarity index 84% rename from docs/market_sessions.rst rename to docs/market-sessions.rst index a6e785f..9ac5692 100644 --- a/docs/market_sessions.rst +++ b/docs/market-sessions.rst @@ -5,46 +5,34 @@ A market time session object contains information about the current state of spe The dataclass represents the current session and any nested 'next' or 'previous' session info. -The ``get_market_sessions`` function can be used to obtain information about the current: +The ``get_market_sessions`` function can be used to obtain information about the current session: .. code-block:: python - import tastytrade.market_sessions as Market - from tastytrade.market_sessions import ExchangeType - mt = Market.get_market_sessions(session=session, exchanges=[ExchangeType.NYSE]) - print("Market time sessions:") - print(mt) + from tastytrade.market_sessions import ExchangeType, get_market_sessions + get_market_sessions(session, exchanges=[ExchangeType.NYSE]) >>> [MarketSession(close_at=None, close_at_ext=None, instrument_collection='Equity', open_at=None, start_at=None, next_session=MarketSessionSnapshot(close_at=datetime.datetime(2025, 2, 18, 21, 0, tzinfo=TzInfo(UTC)), close_at_ext=datetime.datetime(2025, 2, 19, 1, 0, tzinfo=TzInfo(UTC)), instrument_collection='Equity', open_at=datetime.datetime(2025, 2, 18, 14, 30, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 18), start_at=datetime.datetime(2025, 2, 18, 13, 15, tzinfo=TzInfo(UTC))), previous_session=MarketSessionSnapshot(close_at=datetime.datetime(2025, 2, 14, 21, 0, tzinfo=TzInfo(UTC)), close_at_ext=datetime.datetime(2025, 2, 15, 1, 0, tzinfo=TzInfo(UTC)), instrument_collection='Equity', open_at=datetime.datetime(2025, 2, 14, 14, 30, tzinfo=TzInfo(UTC)), session_date=datetime.date(2025, 2, 14), start_at=datetime.datetime(2025, 2, 14, 13, 15, tzinfo=TzInfo(UTC))), status=)] -The ``get_market_holidays`` function can be used to obtain information about markets half_days and market holidays: + +The ``get_market_holidays`` function can be used to obtain information about markets half days and holidays: .. code-block:: python - calendar_data = Market.get_market_time_equity_holidays(session=session) - print("Market half days") - print(calendar_data.market_half_days) # list of datetime.date objects - print("Market holidays") - print(calendar_data.market_holidays) # list of datetime.date objects + from tastytrade.market_sessions import get_market_holidays + calendar = Market.get_market_holidays(session) + print(calendar.half_days) + print(calendar.holidays) >>> [datetime.date(2015, 12, 24), datetime.date(2016, 11, 25), datetime.date(2017, 7, 3), datetime.date(2017, 11, 24), datetime.date(2018, 7, 3), datetime.date(2018, 11, 23), datetime.date(2018, 12, 24), datetime.date(2019, 7, 3), datetime.date(2019, 11, 29), datetime.date(2019, 12, 24), datetime.date(2020, 11, 27), datetime.date(2020, 12, 24), datetime.date(2021, 11, 26), datetime.date(2022, 11, 25), datetime.date(2023, 7, 3), datetime.date(2023, 11, 24), datetime.date(2024, 7, 3), datetime.date(2024, 11, 29), datetime.date(2024, 12, 24), datetime.date(2025, 7, 3), datetime.date(2025, 11, 28), datetime.date(2025, 12, 24), datetime.date(2026, 11, 27), datetime.date(2026, 12, 24), datetime.date(2027, 7, 2), datetime.date(2027, 11, 26), datetime.date(2027, 12, 23), datetime.date(2028, 7, 3), datetime.date(2028, 11, 24), datetime.date(2028, 12, 22), datetime.date(2029, 7, 3)] - >>> [datetime.date(2015, 12, 25), datetime.date(2016, 1, 1), datetime.date(2016, 1, 18), datetime.date(2016, 2, 15), datetime.date(2016, 3, 25), datetime.date(2016, 5, 30), datetime.date(2016, 7, 4), datetime.date(2016, 9, 5), datetime.date(2016, 11, 24), datetime.date(2016, 12, 26), datetime.date(2017, 1, 2), datetime.date(2017, 1, 16), datetime.date(2017, 2, 20), datetime.date(2017, 4, 14), datetime.date(2017, 5, 29), datetime.date(2017, 7, 4), datetime.date(2017, 9, 4), datetime.date(2017, 11, 23), datetime.date(2017, 12, 25), datetime.date(2018, 1, 1), datetime.date(2018, 1, 15), datetime.date(2018, 2, 19), datetime.date(2018, 3, 30), datetime.date(2018, 5, 28), datetime.date(2018, 7, 4), datetime.date(2018, 9, 3), datetime.date(2018, 11, 22), datetime.date(2018, 12, 5), datetime.date(2018, 12, 25), datetime.date(2019, 1, 1), datetime.date(2019, 1, 21), datetime.date(2019, 2, 18), datetime.date(2019, 4, 19), datetime.date(2019, 5, 27), datetime.date(2019, 7, 4), datetime.date(2019, 9, 2), datetime.date(2019, 11, 28), datetime.date(2019, 12, 25), datetime.date(2020, 1, 1), datetime.date(2020, 1, 20), datetime.date(2020, 2, 17), datetime.date(2020, 4, 10), datetime.date(2020, 5, 25), datetime.date(2020, 7, 3), datetime.date(2020, 9, 7), datetime.date(2020, 11, 26), datetime.date(2020, 12, 25), datetime.date(2021, 1, 1), datetime.date(2021, 1, 18), datetime.date(2021, 2, 15), datetime.date(2021, 4, 2), datetime.date(2021, 5, 31), datetime.date(2021, 7, 5), datetime.date(2021, 9, 6), datetime.date(2021, 11, 25), datetime.date(2021, 12, 24), datetime.date(2022, 1, 17), datetime.date(2022, 2, 21), datetime.date(2022, 4, 15), datetime.date(2022, 5, 30), datetime.date(2022, 6, 20), datetime.date(2022, 7, 4), datetime.date(2022, 9, 5), datetime.date(2022, 11, 24), datetime.date(2022, 12, 26), datetime.date(2023, 1, 2), datetime.date(2023, 1, 16), datetime.date(2023, 2, 20), datetime.date(2023, 4, 7), datetime.date(2023, 5, 29), datetime.date(2023, 6, 19), datetime.date(2023, 7, 4), datetime.date(2023, 9, 4), datetime.date(2023, 11, 23), datetime.date(2023, 12, 25), datetime.date(2024, 1, 1), datetime.date(2024, 1, 15), datetime.date(2024, 2, 19), datetime.date(2024, 3, 29), datetime.date(2024, 5, 27), datetime.date(2024, 6, 19), datetime.date(2024, 7, 4), datetime.date(2024, 9, 2), datetime.date(2024, 11, 28), datetime.date(2024, 12, 25), datetime.date(2025, 1, 1), datetime.date(2025, 1, 9), datetime.date(2025, 1, 20), datetime.date(2025, 2, 17), datetime.date(2025, 4, 18), datetime.date(2025, 5, 26), datetime.date(2025, 6, 19), datetime.date(2025, 7, 4), datetime.date(2025, 9, 1), datetime.date(2025, 11, 27), datetime.date(2025, 12, 25), datetime.date(2026, 1, 1), datetime.date(2026, 1, 19), datetime.date(2026, 2, 16), datetime.date(2026, 4, 3), datetime.date(2026, 5, 25), datetime.date(2026, 6, 19), datetime.date(2026, 7, 3), datetime.date(2026, 9, 7), datetime.date(2026, 11, 26), datetime.date(2026, 12, 25), datetime.date(2027, 1, 1), datetime.date(2027, 1, 18), datetime.date(2027, 2, 15), datetime.date(2027, 3, 26), datetime.date(2027, 5, 31), datetime.date(2027, 6, 18), datetime.date(2027, 7, 5), datetime.date(2027, 9, 6), datetime.date(2027, 11, 25), datetime.date(2027, 12, 24), datetime.date(2028, 1, 17), datetime.date(2028, 2, 21), datetime.date(2028, 4, 14), datetime.date(2028, 5, 29), datetime.date(2028, 6, 19), datetime.date(2028, 7, 4), datetime.date(2028, 9, 4), datetime.date(2028, 11, 23), datetime.date(2028, 12, 25), datetime.date(2029, 1, 1), datetime.date(2029, 1, 15), datetime.date(2029, 2, 19), datetime.date(2029, 3, 30), datetime.date(2029, 5, 28), datetime.date(2029, 6, 19), datetime.date(2029, 7, 4), datetime.date(2029, 9, 3)] - I case you only want to extract the market status, this is one way to do it: .. code-block:: python - import tastytrade.market_sessions as Market - from tastytrade.market_sessions import ExchangeType, MarketStatus + from tastytrade.market_sessions import ExchangeType, MarketStatus, get_market_sessions - def get_market_state(session: Session, exchanges: list[ExchangeType]) -> list: - data = Market.get_market_sessions(session=session, exchanges=exchanges) - enum_states = [MarketStatus(s.status) for s in data] - return [st.value for st in enum_states] - - s = get_market_state(session=session, exchanges=[ExchangeType.NYSE, ExchangeType.CME, ExchangeType.CFE, ExchangeType.SMALL]) - print(s) + market_sessions = get_market_sessions(session, exchanges=[ExchangeType.NYSE, ExchangeType.CME]) + print([ms.status != MarketStatus.CLOSED for ms in market_sessions]) -When all markets are closed: ->>> ['Closed', 'Closed', 'Closed', 'Closed'] \ No newline at end of file +>>> [False, False] diff --git a/tastytrade/market_sessions.py b/tastytrade/market_sessions.py index d2066d6..941fc91 100644 --- a/tastytrade/market_sessions.py +++ b/tastytrade/market_sessions.py @@ -58,13 +58,13 @@ class MarketSession(TastytradeJsonDataclass): status: MarketStatus = Field(alias="state") -class MarketCalendarData(TastytradeJsonDataclass): +class MarketCalendar(TastytradeJsonDataclass): """ Dataclass containing information about market holidays and shortened days. """ - market_half_days: list[date] - market_holidays: list[date] + half_days: list[date] = Field(alias="market-half-days") + holidays: list[date] = Field(alias="market-holidays") async def a_get_market_sessions( @@ -99,21 +99,21 @@ def get_market_sessions( return [MarketSession(**i) for i in data["items"]] -async def a_get_market_holidays(session: Session) -> MarketCalendarData: +async def a_get_market_holidays(session: Session) -> MarketCalendar: """ Retrieves market calendar for half days and holidays. :param session: active user session to use """ data = await session._a_get("/market-time/equities/holidays") - return MarketCalendarData(**data) + return MarketCalendar(**data) -def get_market_holidays(session: Session) -> MarketCalendarData: +def get_market_holidays(session: Session) -> MarketCalendar: """ Retrieves market calendar for half days and holidays. :param session: active user session to use """ data = session._get("/market-time/equities/holidays") - return MarketCalendarData(**data) + return MarketCalendar(**data)