tastytrade 11.1.0__tar.gz → 12.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tastytrade-11.1.0 → tastytrade-12.0.0}/.github/pull_request_template.md +1 -1
- {tastytrade-11.1.0 → tastytrade-12.0.0}/.github/workflows/python-app.yml +1 -2
- tastytrade-12.0.0/.python-version +1 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/Makefile +1 -1
- {tastytrade-11.1.0 → tastytrade-12.0.0}/PKG-INFO +15 -26
- {tastytrade-11.1.0 → tastytrade-12.0.0}/README.md +7 -20
- tastytrade-12.0.0/docs/account-streamer.rst +59 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/accounts.rst +6 -6
- tastytrade-12.0.0/docs/data-streamer.rst +73 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/index.rst +1 -2
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/instruments.rst +12 -12
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/market-data.rst +2 -2
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/market-sessions.rst +3 -3
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/orders.rst +16 -16
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/sessions.rst +5 -12
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/watchlists.rst +4 -4
- {tastytrade-11.1.0 → tastytrade-12.0.0}/pyproject.toml +9 -10
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/__init__.py +1 -1
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/account.py +48 -532
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/dxfeed/candle.py +2 -4
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/dxfeed/event.py +3 -3
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/dxfeed/quote.py +26 -3
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/instruments.py +54 -522
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/market_data.py +4 -52
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/market_sessions.py +6 -43
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/metrics.py +10 -67
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/order.py +4 -0
- tastytrade-12.0.0/tastytrade/search.py +29 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/session.py +112 -156
- tastytrade-12.0.0/tastytrade/streamer.py +696 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/utils.py +2 -85
- tastytrade-12.0.0/tastytrade/watchlists.py +182 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tests/conftest.py +7 -8
- tastytrade-12.0.0/tests/test_account.py +259 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tests/test_dxfeed.py +0 -3
- tastytrade-12.0.0/tests/test_instruments.py +115 -0
- tastytrade-12.0.0/tests/test_market_data.py +25 -0
- tastytrade-12.0.0/tests/test_market_sessions.py +28 -0
- tastytrade-12.0.0/tests/test_metrics.py +29 -0
- tastytrade-12.0.0/tests/test_search.py +17 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tests/test_session.py +3 -18
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tests/test_streamer.py +3 -35
- tastytrade-12.0.0/tests/test_watchlists.py +63 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/uv.lock +264 -795
- tastytrade-11.1.0/.python-version +0 -1
- tastytrade-11.1.0/docs/account-streamer.rst +0 -82
- tastytrade-11.1.0/docs/data-streamer.rst +0 -189
- tastytrade-11.1.0/docs/sync-async.rst +0 -27
- tastytrade-11.1.0/tastytrade/search.py +0 -47
- tastytrade-11.1.0/tastytrade/streamer.py +0 -886
- tastytrade-11.1.0/tastytrade/watchlists.py +0 -293
- tastytrade-11.1.0/tests/test_account.py +0 -419
- tastytrade-11.1.0/tests/test_instruments.py +0 -201
- tastytrade-11.1.0/tests/test_market_data.py +0 -37
- tastytrade-11.1.0/tests/test_market_sessions.py +0 -43
- tastytrade-11.1.0/tests/test_metrics.py +0 -45
- tastytrade-11.1.0/tests/test_search.py +0 -24
- tastytrade-11.1.0/tests/test_watchlists.py +0 -109
- {tastytrade-11.1.0 → tastytrade-12.0.0}/.github/CONTRIBUTING.md +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/.github/FUNDING.yml +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/.github/workflows/python-publish-test.yml +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/.github/workflows/python-publish.yml +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/.gitignore +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/.readthedocs.yaml +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/LICENSE +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/Makefile +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/account.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/dxfeed.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/instruments.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/market-data.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/market-sessions.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/metrics.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/order.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/search.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/session.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/streamer.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/utils.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/api/watchlists.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/conf.py +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/img/netliq.png +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/installation.rst +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/docs/make.bat +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/dxfeed/__init__.py +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/dxfeed/greeks.py +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/dxfeed/profile.py +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/dxfeed/summary.py +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/dxfeed/theoprice.py +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/dxfeed/timeandsale.py +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/dxfeed/trade.py +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/dxfeed/underlying.py +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tastytrade/py.typed +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tests/__init__.py +0 -0
- {tastytrade-11.1.0 → tastytrade-12.0.0}/tests/test_utils.py +0 -0
|
@@ -5,8 +5,8 @@ Fixes ...
|
|
|
5
5
|
|
|
6
6
|
## Pre-merge checklist
|
|
7
7
|
- [ ] Code formatted correctly (check with `make lint`)
|
|
8
|
-
- [ ] Code implemented for both sync and async
|
|
9
8
|
- [ ] Passing tests locally (check with `make test`, make sure you have `TT_REFRESH`, `TT_SECRET`, and `TT_ACCOUNT` environment variables set)
|
|
10
9
|
- [ ] New tests added (if applicable)
|
|
10
|
+
- [ ] Docs updated (if applicable)
|
|
11
11
|
|
|
12
12
|
Please note that, in order to pass the tests, you'll need to set up your Tastytrade credentials as repository secrets on your local fork. Read more at CONTRIBUTING.md.
|
|
@@ -13,7 +13,6 @@ jobs:
|
|
|
13
13
|
max-parallel: 1
|
|
14
14
|
matrix:
|
|
15
15
|
python-version:
|
|
16
|
-
- "3.10"
|
|
17
16
|
- "3.11"
|
|
18
17
|
- "3.12"
|
|
19
18
|
- "3.13"
|
|
@@ -39,7 +38,7 @@ jobs:
|
|
|
39
38
|
uv run mypy tastytrade/
|
|
40
39
|
- name: Test with pytest
|
|
41
40
|
run: |
|
|
42
|
-
uv run pytest --cov=tastytrade --cov-report=term-missing tests/ --cov-fail-under=95
|
|
41
|
+
uv run pytest --cov=tastytrade --cov-report=term-missing tests/ --cov-fail-under=95 -v
|
|
43
42
|
env:
|
|
44
43
|
TT_REFRESH_SANDBOX: ${{ secrets.TT_REFRESH_SANDBOX }}
|
|
45
44
|
TT_SECRET_SANDBOX: ${{ secrets.TT_SECRET_SANDBOX }}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -11,7 +11,7 @@ lint:
|
|
|
11
11
|
uv run mypy tastytrade/
|
|
12
12
|
|
|
13
13
|
test:
|
|
14
|
-
uv run pytest --cov=tastytrade --cov-report=term-missing tests/ --cov-fail-under=95
|
|
14
|
+
uv run pytest --cov=tastytrade --cov-report=term-missing tests/ --cov-fail-under=95 -v
|
|
15
15
|
|
|
16
16
|
docs:
|
|
17
17
|
uv run -m sphinx -T -b html -d docs/_build/doctrees -D language=en docs/ docs/_build/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tastytrade
|
|
3
|
-
Version:
|
|
4
|
-
Summary: An unofficial,
|
|
3
|
+
Version: 12.0.0
|
|
4
|
+
Summary: An unofficial, typed, asynchronous Python SDK for Tastytrade!
|
|
5
5
|
Project-URL: Homepage, https://github.com/tastyware/tastytrade
|
|
6
6
|
Project-URL: Documentation, https://tastyworks-api.rtfd.io
|
|
7
7
|
Project-URL: Funding, https://github.com/sponsors/tastyware
|
|
@@ -32,7 +32,9 @@ License: MIT License
|
|
|
32
32
|
License-File: LICENSE
|
|
33
33
|
Classifier: Development Status :: 5 - Production/Stable
|
|
34
34
|
Classifier: Environment :: Console
|
|
35
|
+
Classifier: Framework :: AnyIO
|
|
35
36
|
Classifier: Framework :: AsyncIO
|
|
37
|
+
Classifier: Framework :: Trio
|
|
36
38
|
Classifier: Intended Audience :: Developers
|
|
37
39
|
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
38
40
|
Classifier: Intended Audience :: Information Technology
|
|
@@ -44,7 +46,6 @@ Classifier: Operating System :: Unix
|
|
|
44
46
|
Classifier: Programming Language :: Python
|
|
45
47
|
Classifier: Programming Language :: Python :: 3
|
|
46
48
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
47
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
48
49
|
Classifier: Programming Language :: Python :: 3.11
|
|
49
50
|
Classifier: Programming Language :: Python :: 3.12
|
|
50
51
|
Classifier: Programming Language :: Python :: 3.13
|
|
@@ -52,11 +53,12 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
52
53
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
53
54
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
54
55
|
Classifier: Typing :: Typed
|
|
55
|
-
Requires-Python: >=3.
|
|
56
|
+
Requires-Python: >=3.11
|
|
57
|
+
Requires-Dist: anyio>=4.12.1
|
|
58
|
+
Requires-Dist: httpx-ws>=0.7.2
|
|
56
59
|
Requires-Dist: httpx>=0.28.1
|
|
57
60
|
Requires-Dist: pandas-market-calendars>=5.1.1
|
|
58
|
-
Requires-Dist: pydantic>=2.
|
|
59
|
-
Requires-Dist: websockets>=15.0.1
|
|
61
|
+
Requires-Dist: pydantic>=2.12.0
|
|
60
62
|
Description-Content-Type: text/markdown
|
|
61
63
|
|
|
62
64
|
[](https://tastyworks-api.readthedocs.io/en/latest/?badge=latest)
|
|
@@ -71,8 +73,7 @@ A simple, reverse-engineered SDK for Tastytrade built on their (now mostly publi
|
|
|
71
73
|
## Features
|
|
72
74
|
|
|
73
75
|
- Up to 10x less code than using the API directly
|
|
74
|
-
-
|
|
75
|
-
- Powerful websocket implementation for account alerts and data streaming, with support for auto-reconnection and reconnection callbacks
|
|
76
|
+
- Powerful websocket implementation for account alerts and data streaming
|
|
76
77
|
- 100% typed, with Pydantic models for all JSON responses from the API
|
|
77
78
|
- 95%+ unit test coverage
|
|
78
79
|
- Comprehensive documentation
|
|
@@ -126,8 +127,8 @@ Note that this is asynchronous code, so you can't run it as is unless you're usi
|
|
|
126
127
|
```python
|
|
127
128
|
from tastytrade import Account
|
|
128
129
|
|
|
129
|
-
account = Account.get(session)[0]
|
|
130
|
-
positions = account.get_positions(session)
|
|
130
|
+
account = (await Account.get(session))[0]
|
|
131
|
+
positions = await account.get_positions(session)
|
|
131
132
|
print(positions[0])
|
|
132
133
|
```
|
|
133
134
|
|
|
@@ -135,18 +136,6 @@ print(positions[0])
|
|
|
135
136
|
>>> CurrentPosition(account_number='5WX01234', symbol='IAU', instrument_type=<InstrumentType.EQUITY: 'Equity'>, underlying_symbol='IAU', quantity=Decimal('20'), quantity_direction='Long', close_price=Decimal('37.09'), average_open_price=Decimal('37.51'), average_yearly_market_close_price=Decimal('37.51'), average_daily_market_close_price=Decimal('37.51'), multiplier=1, cost_effect=<PriceEffect.CREDIT: 'Credit'>, is_suppressed=False, is_frozen=False, realized_day_gain=Decimal('7.888'), realized_day_gain_date=datetime.date(2023, 5, 19), realized_today=Decimal('-0.512'), realized_today_date=datetime.date(2023, 5, 19), created_at=datetime.datetime(2023, 3, 31, 14, 38, 32, 58000, tzinfo=datetime.timezone.utc), updated_at=datetime.datetime(2023, 5, 19, 16, 56, 51, 920000, tzinfo=datetime.timezone.utc), mark=None, mark_price=None, restricted_quantity=Decimal('0'), expires_at=None, fixing_price=None, deliverable_type=None)
|
|
136
137
|
```
|
|
137
138
|
|
|
138
|
-
## Sync/async wrappers
|
|
139
|
-
|
|
140
|
-
The code from above can be rewritten asynchronously:
|
|
141
|
-
|
|
142
|
-
```python
|
|
143
|
-
from tastytrade import Account
|
|
144
|
-
|
|
145
|
-
account = (await Account.a_get(session))[0]
|
|
146
|
-
positions = await account.a_get_positions(session)
|
|
147
|
-
print(positions[0])
|
|
148
|
-
```
|
|
149
|
-
|
|
150
139
|
## Placing an order
|
|
151
140
|
|
|
152
141
|
```python
|
|
@@ -155,8 +144,8 @@ from tastytrade import Account
|
|
|
155
144
|
from tastytrade.instruments import Equity
|
|
156
145
|
from tastytrade.order import NewOrder, OrderAction, OrderTimeInForce, OrderType
|
|
157
146
|
|
|
158
|
-
account = Account.get(session, '5WX01234')
|
|
159
|
-
symbol = Equity.get(session, 'USO')
|
|
147
|
+
account = await Account.get(session, '5WX01234')
|
|
148
|
+
symbol = await Equity.get(session, 'USO')
|
|
160
149
|
leg = symbol.build_leg(Decimal('5'), OrderAction.BUY_TO_OPEN) # buy to open 5 shares
|
|
161
150
|
|
|
162
151
|
order = NewOrder(
|
|
@@ -165,7 +154,7 @@ order = NewOrder(
|
|
|
165
154
|
legs=[leg], # you can have multiple legs in an order
|
|
166
155
|
price=Decimal('-10') # limit price, $10/share debit for a total value of $50
|
|
167
156
|
)
|
|
168
|
-
response = account.place_order(session, order, dry_run=True) # a test order
|
|
157
|
+
response = await account.place_order(session, order, dry_run=True) # a test order
|
|
169
158
|
print(response)
|
|
170
159
|
```
|
|
171
160
|
|
|
@@ -181,7 +170,7 @@ from tastytrade.dxfeed import Greeks
|
|
|
181
170
|
from tastytrade.instruments import get_option_chain
|
|
182
171
|
from tastytrade.utils import get_tasty_monthly
|
|
183
172
|
|
|
184
|
-
chain = get_option_chain(session, 'SPLG')
|
|
173
|
+
chain = await get_option_chain(session, 'SPLG')
|
|
185
174
|
exp = get_tasty_monthly() # 45 DTE expiration!
|
|
186
175
|
subs_list = [chain[exp][0].streamer_symbol]
|
|
187
176
|
|
|
@@ -10,8 +10,7 @@ A simple, reverse-engineered SDK for Tastytrade built on their (now mostly publi
|
|
|
10
10
|
## Features
|
|
11
11
|
|
|
12
12
|
- Up to 10x less code than using the API directly
|
|
13
|
-
-
|
|
14
|
-
- Powerful websocket implementation for account alerts and data streaming, with support for auto-reconnection and reconnection callbacks
|
|
13
|
+
- Powerful websocket implementation for account alerts and data streaming
|
|
15
14
|
- 100% typed, with Pydantic models for all JSON responses from the API
|
|
16
15
|
- 95%+ unit test coverage
|
|
17
16
|
- Comprehensive documentation
|
|
@@ -65,8 +64,8 @@ Note that this is asynchronous code, so you can't run it as is unless you're usi
|
|
|
65
64
|
```python
|
|
66
65
|
from tastytrade import Account
|
|
67
66
|
|
|
68
|
-
account = Account.get(session)[0]
|
|
69
|
-
positions = account.get_positions(session)
|
|
67
|
+
account = (await Account.get(session))[0]
|
|
68
|
+
positions = await account.get_positions(session)
|
|
70
69
|
print(positions[0])
|
|
71
70
|
```
|
|
72
71
|
|
|
@@ -74,18 +73,6 @@ print(positions[0])
|
|
|
74
73
|
>>> CurrentPosition(account_number='5WX01234', symbol='IAU', instrument_type=<InstrumentType.EQUITY: 'Equity'>, underlying_symbol='IAU', quantity=Decimal('20'), quantity_direction='Long', close_price=Decimal('37.09'), average_open_price=Decimal('37.51'), average_yearly_market_close_price=Decimal('37.51'), average_daily_market_close_price=Decimal('37.51'), multiplier=1, cost_effect=<PriceEffect.CREDIT: 'Credit'>, is_suppressed=False, is_frozen=False, realized_day_gain=Decimal('7.888'), realized_day_gain_date=datetime.date(2023, 5, 19), realized_today=Decimal('-0.512'), realized_today_date=datetime.date(2023, 5, 19), created_at=datetime.datetime(2023, 3, 31, 14, 38, 32, 58000, tzinfo=datetime.timezone.utc), updated_at=datetime.datetime(2023, 5, 19, 16, 56, 51, 920000, tzinfo=datetime.timezone.utc), mark=None, mark_price=None, restricted_quantity=Decimal('0'), expires_at=None, fixing_price=None, deliverable_type=None)
|
|
75
74
|
```
|
|
76
75
|
|
|
77
|
-
## Sync/async wrappers
|
|
78
|
-
|
|
79
|
-
The code from above can be rewritten asynchronously:
|
|
80
|
-
|
|
81
|
-
```python
|
|
82
|
-
from tastytrade import Account
|
|
83
|
-
|
|
84
|
-
account = (await Account.a_get(session))[0]
|
|
85
|
-
positions = await account.a_get_positions(session)
|
|
86
|
-
print(positions[0])
|
|
87
|
-
```
|
|
88
|
-
|
|
89
76
|
## Placing an order
|
|
90
77
|
|
|
91
78
|
```python
|
|
@@ -94,8 +81,8 @@ from tastytrade import Account
|
|
|
94
81
|
from tastytrade.instruments import Equity
|
|
95
82
|
from tastytrade.order import NewOrder, OrderAction, OrderTimeInForce, OrderType
|
|
96
83
|
|
|
97
|
-
account = Account.get(session, '5WX01234')
|
|
98
|
-
symbol = Equity.get(session, 'USO')
|
|
84
|
+
account = await Account.get(session, '5WX01234')
|
|
85
|
+
symbol = await Equity.get(session, 'USO')
|
|
99
86
|
leg = symbol.build_leg(Decimal('5'), OrderAction.BUY_TO_OPEN) # buy to open 5 shares
|
|
100
87
|
|
|
101
88
|
order = NewOrder(
|
|
@@ -104,7 +91,7 @@ order = NewOrder(
|
|
|
104
91
|
legs=[leg], # you can have multiple legs in an order
|
|
105
92
|
price=Decimal('-10') # limit price, $10/share debit for a total value of $50
|
|
106
93
|
)
|
|
107
|
-
response = account.place_order(session, order, dry_run=True) # a test order
|
|
94
|
+
response = await account.place_order(session, order, dry_run=True) # a test order
|
|
108
95
|
print(response)
|
|
109
96
|
```
|
|
110
97
|
|
|
@@ -120,7 +107,7 @@ from tastytrade.dxfeed import Greeks
|
|
|
120
107
|
from tastytrade.instruments import get_option_chain
|
|
121
108
|
from tastytrade.utils import get_tasty_monthly
|
|
122
109
|
|
|
123
|
-
chain = get_option_chain(session, 'SPLG')
|
|
110
|
+
chain = await get_option_chain(session, 'SPLG')
|
|
124
111
|
exp = get_tasty_monthly() # 45 DTE expiration!
|
|
125
112
|
subs_list = [chain[exp][0].streamer_symbol]
|
|
126
113
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
Account Streamer
|
|
2
|
+
================
|
|
3
|
+
|
|
4
|
+
Basic usage
|
|
5
|
+
-----------
|
|
6
|
+
|
|
7
|
+
The account streamer is used to track account-level updates, such as order fills, watchlist updates and quote alerts.
|
|
8
|
+
Typically, you'll want a separate task running for the account streamer, which can then notify your application about important events.
|
|
9
|
+
|
|
10
|
+
Here's an example of setting up an account streamer to continuously wait for events and print them:
|
|
11
|
+
|
|
12
|
+
.. code-block:: python
|
|
13
|
+
|
|
14
|
+
from tastytrade import Account, AlertStreamer, Watchlist
|
|
15
|
+
|
|
16
|
+
async with AlertStreamer(session) as streamer:
|
|
17
|
+
# changes in public watchlists
|
|
18
|
+
await streamer.subscribe_public_watchlists()
|
|
19
|
+
# quote alerts configured by the user
|
|
20
|
+
await streamer.subscribe_quote_alerts()
|
|
21
|
+
|
|
22
|
+
async for wl in streamer.listen(Watchlist):
|
|
23
|
+
print(wl)
|
|
24
|
+
|
|
25
|
+
Probably the most important information the account streamer handles is order fills. We can listen just for orders like so:
|
|
26
|
+
|
|
27
|
+
.. code-block:: python
|
|
28
|
+
|
|
29
|
+
from tastytrade.order import PlacedOrder
|
|
30
|
+
|
|
31
|
+
async with AlertStreamer(session) as streamer:
|
|
32
|
+
# updates to balances, orders, and positions
|
|
33
|
+
accounts = await Account.get(session)
|
|
34
|
+
await streamer.subscribe_accounts(accounts)
|
|
35
|
+
|
|
36
|
+
async for order in streamer.listen(PlacedOrder):
|
|
37
|
+
print(order)
|
|
38
|
+
|
|
39
|
+
Auto-retries
|
|
40
|
+
------------
|
|
41
|
+
|
|
42
|
+
Often, account streamer connections should be long-lived and persistent. While the SDK doesn't provide this functionality itself, it's pretty trivial to build with just a few lines of code:
|
|
43
|
+
|
|
44
|
+
.. code-block:: python
|
|
45
|
+
|
|
46
|
+
from anyio import sleep
|
|
47
|
+
from httpx_ws import HTTPXWSException
|
|
48
|
+
|
|
49
|
+
tries, max_tries = 0, 3
|
|
50
|
+
while (tries := tries + 1) <= max_tries:
|
|
51
|
+
try:
|
|
52
|
+
async with AlertStreamer(session) as streamer:
|
|
53
|
+
print("Yay! Connected!")
|
|
54
|
+
...
|
|
55
|
+
except* HTTPXWSException:
|
|
56
|
+
print("Oh no! Disconnected!")
|
|
57
|
+
await sleep(tries ** 2)
|
|
58
|
+
|
|
59
|
+
Now we have persistence, exponential backoff, and disconnect/reconnect hooks--easy!
|
|
@@ -8,19 +8,19 @@ The easiest way to get an account is to grab all accounts associated with a spec
|
|
|
8
8
|
.. code-block:: python
|
|
9
9
|
|
|
10
10
|
from tastytrade import Account
|
|
11
|
-
accounts = Account.get(session)
|
|
11
|
+
accounts = await Account.get(session)
|
|
12
12
|
|
|
13
13
|
You can also get a specific account by its unique ID:
|
|
14
14
|
|
|
15
15
|
.. code-block:: python
|
|
16
16
|
|
|
17
|
-
account = Account.get(session, '5WX01234')
|
|
17
|
+
account = await Account.get(session, '5WX01234')
|
|
18
18
|
|
|
19
19
|
The ``get_balances`` function can be used to obtain information about the current buying power and cash balance:
|
|
20
20
|
|
|
21
21
|
.. code-block:: python
|
|
22
22
|
|
|
23
|
-
balance = account.get_balances(session)
|
|
23
|
+
balance = await account.get_balances(session)
|
|
24
24
|
print(balance)
|
|
25
25
|
|
|
26
26
|
>>> AccountBalance(account_number='5WX01234', cash_balance=Decimal('87.055'), long_equity_value=Decimal('4046.05'), short_equity_value=Decimal('0.0'), long_derivative_value=Decimal('0.0'), short_derivative_value=Decimal('0.0'), long_futures_value=Decimal('0.0'), short_futures_value=Decimal('0.0'), long_futures_derivative_value=Decimal('0.0'), short_futures_derivative_value=Decimal('0.0'), long_margineable_value=Decimal('0.0'), short_margineable_value=Decimal('0.0'), margin_equity=Decimal('4133.105'), equity_buying_power=Decimal('87.055'), derivative_buying_power=Decimal('87.055'), day_trading_buying_power=Decimal('0.0'), futures_margin_requirement=Decimal('0.0'), available_trading_funds=Decimal('0.0'), maintenance_requirement=Decimal('4048.85'), maintenance_call_value=Decimal('0.0'), reg_t_call_value=Decimal('0.0'), day_trading_call_value=Decimal('0.0'), day_equity_call_value=Decimal('0.0'), net_liquidating_value=Decimal('4133.105'), cash_available_to_withdraw=Decimal('87.06'), day_trade_excess=Decimal('87.06'), pending_cash=Decimal('0.0'), pending_cash_effect=<PriceEffect.NONE: 'None'>, long_cryptocurrency_value=Decimal('0.0'), short_cryptocurrency_value=Decimal('0.0'), cryptocurrency_margin_requirement=Decimal('0.0'), unsettled_cryptocurrency_fiat_amount=Decimal('0.0'), unsettled_cryptocurrency_fiat_effect=<PriceEffect.NONE: 'None'>, closed_loop_available_balance=Decimal('87.06'), equity_offering_margin_requirement=Decimal('0.0'), long_bond_value=Decimal('0.0'), bond_margin_requirement=Decimal('0.0'), snapshot_date=datetime.date(2023, 11, 28), reg_t_margin_requirement=Decimal('4048.85'), futures_overnight_margin_requirement=Decimal('0.0'), futures_intraday_margin_requirement=Decimal('0.0'), maintenance_excess=Decimal('87.055'), pending_margin_interest=Decimal('0.0'), effective_cryptocurrency_buying_power=Decimal('87.055'), updated_at=datetime.datetime(2023, 11, 28, 20, 54, 33, 556000, tzinfo=datetime.timezone.utc), apex_starting_day_margin_equity=None, buying_power_adjustment=None, buying_power_adjustment_effect=None, time_of_day=None)
|
|
@@ -29,7 +29,7 @@ To obtain information about current positions:
|
|
|
29
29
|
|
|
30
30
|
.. code-block:: python
|
|
31
31
|
|
|
32
|
-
positions = account.get_positions(session)
|
|
32
|
+
positions = await account.get_positions(session)
|
|
33
33
|
print(positions[0])
|
|
34
34
|
|
|
35
35
|
>>> CurrentPosition(account_number='5WX01234', symbol='BRK/B', instrument_type=<InstrumentType.EQUITY: 'Equity'>, underlying_symbol='BRK/B', quantity=Decimal('10'), quantity_direction='Long', close_price=Decimal('361.34'), average_open_price=Decimal('339.63'), multiplier=1, cost_effect='Credit', is_suppressed=False, is_frozen=False, realized_day_gain=Decimal('18.5'), realized_today=Decimal('279.15'), created_at=datetime.datetime(2023, 3, 31, 14, 35, 40, 138000, tzinfo=datetime.timezone.utc), updated_at=datetime.datetime(2023, 8, 10, 15, 42, 7, 482000, tzinfo=datetime.timezone.utc), mark=None, mark_price=None, restricted_quantity=Decimal('0'), expires_at=None, fixing_price=None, deliverable_type=None, average_yearly_market_close_price=Decimal('339.63'), average_daily_market_close_price=Decimal('361.34'), realized_day_gain_effect=<PriceEffect.CREDIT: 'Credit'>, realized_day_gain_date=datetime.date(2023, 8, 10), realized_today_effect=<PriceEffect.CREDIT: 'Credit'>, realized_today_date=datetime.date(2023, 8, 10))
|
|
@@ -38,7 +38,7 @@ To fetch a list of past transactions:
|
|
|
38
38
|
|
|
39
39
|
.. code-block:: python
|
|
40
40
|
|
|
41
|
-
history = account.get_history(session, start_date=date(2024, 1, 1))
|
|
41
|
+
history = await account.get_history(session, start_date=date(2024, 1, 1))
|
|
42
42
|
print(history[-1])
|
|
43
43
|
|
|
44
44
|
>>> Transaction(id=280070508, account_number='5WX01234', transaction_type='Trade', transaction_sub_type='Sell to Close', description='Sold 10 BRK/B @ 384.04', executed_at=datetime.datetime(2024, 1, 26, 15, 51, 53, 685000, tzinfo=datetime.timezone.utc), transaction_date=datetime.date(2024, 1, 26), value=Decimal('3840.4'), value_effect=<PriceEffect.CREDIT: 'Credit'>, net_value=Decimal('3840.35'), net_value_effect=<PriceEffect.CREDIT: 'Credit'>, is_estimated_fee=True, symbol='BRK/B', instrument_type=<InstrumentType.EQUITY: 'Equity'>, underlying_symbol='BRK/B', action='Sell to Close', quantity=Decimal('10.0'), price=Decimal('384.04'), regulatory_fees=Decimal('0.042'), regulatory_fees_effect=<PriceEffect.DEBIT: 'Debit'>, clearing_fees=Decimal('0.008'), clearing_fees_effect=<PriceEffect.DEBIT: 'Debit'>, commission=Decimal('0.0'), commission_effect=<PriceEffect.NONE: 'None'>, proprietary_index_option_fees=Decimal('0.0'), proprietary_index_option_fees_effect=<PriceEffect.NONE: 'None'>, ext_exchange_order_number='12271026815307', ext_global_order_number=2857, ext_group_id='0', ext_group_fill_id='0', ext_exec_id='0', exec_id='123_40126000126350300000', exchange='JNS', order_id=305250635, exchange_affiliation_identifier='', leg_count=1, destination_venue='JANE_STREET_EQUITIES_A', other_charge=None, other_charge_effect=None, other_charge_description=None, reverses_id=None, cost_basis_reconciliation_date=None, lots=None, agency_price=None, principal_price=None)
|
|
@@ -48,7 +48,7 @@ We can also view portfolio P/L over time (and even plot it!):
|
|
|
48
48
|
.. code-block:: python
|
|
49
49
|
|
|
50
50
|
import matplotlib.pyplot as plt
|
|
51
|
-
nl = account.get_net_liquidating_value_history(session, time_back='1m') # past 1 month
|
|
51
|
+
nl = await account.get_net_liquidating_value_history(session, time_back='1m') # past 1 month
|
|
52
52
|
plt.plot([n.time for n in nl], [n.close for n in nl])
|
|
53
53
|
plt.show()
|
|
54
54
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
Data Streamer
|
|
2
|
+
=============
|
|
3
|
+
|
|
4
|
+
Basic usage
|
|
5
|
+
-----------
|
|
6
|
+
|
|
7
|
+
The streamer is a websocket connection to dxfeed (the Tastytrade data provider) that allows you to subscribe to real-time data for quotes, greeks, and more.
|
|
8
|
+
You can create a streamer using an active production session:
|
|
9
|
+
|
|
10
|
+
.. code-block:: python
|
|
11
|
+
|
|
12
|
+
from tastytrade import DXLinkStreamer
|
|
13
|
+
async with DXLinkStreamer(session) as streamer:
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
Once you've created the streamer, you can subscribe/unsubscribe to events, like ``Quote``:
|
|
17
|
+
|
|
18
|
+
.. code-block:: python
|
|
19
|
+
|
|
20
|
+
from tastytrade.dxfeed import Quote
|
|
21
|
+
subs_list = ['SPY'] # you can add more symbols here!
|
|
22
|
+
|
|
23
|
+
async with DXLinkStreamer(session) as streamer:
|
|
24
|
+
await streamer.subscribe(Quote, subs_list)
|
|
25
|
+
quotes = {}
|
|
26
|
+
async for quote in streamer.listen(Quote):
|
|
27
|
+
quotes[quote.event_symbol] = quote
|
|
28
|
+
if len(quotes) >= len(subs_list):
|
|
29
|
+
break
|
|
30
|
+
print(quotes)
|
|
31
|
+
|
|
32
|
+
>>> [{'SPY': Quote(event_symbol='SPY', event_time=0, sequence=0, time_nano_part=0, bid_time=0, bid_exchange_code='Q', bid_price=411.58, bid_size=400.0, ask_time=0, ask_exchange_code='Q', ask_price=411.6, ask_size=1313.0), 'SPX': Quote(event_symbol='SPX', event_time=0, sequence=0, time_nano_part=0, bid_time=0, bid_exchange_code='\x00', bid_price=4122.49, bid_size='NaN', ask_time=0, ask_exchange_code='\x00', ask_price=4123.65, ask_size='NaN')}]
|
|
33
|
+
|
|
34
|
+
We can also use the streamer to stream greeks for options symbols:
|
|
35
|
+
|
|
36
|
+
.. code-block:: python
|
|
37
|
+
|
|
38
|
+
from tastytrade.dxfeed import Greeks
|
|
39
|
+
from tastytrade.instruments import get_option_chain
|
|
40
|
+
from tastytrade.utils import get_tasty_monthly
|
|
41
|
+
|
|
42
|
+
chain = await get_option_chain(session, 'SPLG')
|
|
43
|
+
exp = get_tasty_monthly() # 45 DTE expiration!
|
|
44
|
+
subs_list = [chain[exp][0].streamer_symbol]
|
|
45
|
+
|
|
46
|
+
async with DXLinkStreamer(session) as streamer:
|
|
47
|
+
await streamer.subscribe(Greeks, subs_list)
|
|
48
|
+
greeks = await streamer.get_event(Greeks)
|
|
49
|
+
print(greeks)
|
|
50
|
+
|
|
51
|
+
>>> Greeks(event_symbol='.SPLG230616C23', event_time=0, event_flags=0, index=7235129486797176832, time=1684559855338, sequence=0, price=26.3380972233688, volatility=0.396983376650804, delta=0.999999999996191, gamma=4.81989763184255e-12, theta=-2.5212017514875e-12, rho=0.01834504287973133, vega=3.7003015672215e-12)
|
|
52
|
+
|
|
53
|
+
Auto-retries
|
|
54
|
+
------------
|
|
55
|
+
|
|
56
|
+
Often, streamer connections should be long-lived and persistent. While the SDK doesn't provide this functionality itself, it's pretty trivial to build with just a few lines of code:
|
|
57
|
+
|
|
58
|
+
.. code-block:: python
|
|
59
|
+
|
|
60
|
+
from anyio import sleep
|
|
61
|
+
from httpx_ws import HTTPXWSException
|
|
62
|
+
|
|
63
|
+
tries, max_tries = 0, 3
|
|
64
|
+
while (tries := tries + 1) <= max_tries:
|
|
65
|
+
try:
|
|
66
|
+
async with DXLinkStreamer(session) as streamer:
|
|
67
|
+
print("Yay! Connected!")
|
|
68
|
+
...
|
|
69
|
+
except* HTTPXWSException:
|
|
70
|
+
print("Oh no! Disconnected!")
|
|
71
|
+
await sleep(tries ** 2)
|
|
72
|
+
|
|
73
|
+
Now we have persistence, exponential backoff, and disconnect/reconnect hooks--easy!
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
Tastytrade Python SDK
|
|
18
18
|
=====================
|
|
19
19
|
|
|
20
|
-
A
|
|
20
|
+
A typed, async SDK for Tastytrade built on their public API. This will allow you to create trading algorithms for whatever strategies you may have quickly and painlessly in Python.
|
|
21
21
|
|
|
22
22
|
.. tip::
|
|
23
23
|
Want to see the SDK in action? Check out `tastytrade-cli <https://github.com/tastyware/tastytrade-cli>`_, a CLI for Tastytrade that showcases many of the SDK's features.
|
|
@@ -32,7 +32,6 @@ A simple, reverse-engineered, sync/async SDK for Tastytrade built on their (now
|
|
|
32
32
|
|
|
33
33
|
installation
|
|
34
34
|
sessions
|
|
35
|
-
sync-async
|
|
36
35
|
accounts
|
|
37
36
|
instruments
|
|
38
37
|
orders
|
|
@@ -22,9 +22,9 @@ Note that ETFs and indices are treated as equities for the purposes of the API.
|
|
|
22
22
|
|
|
23
23
|
from tastytrade.instruments import Equity, FutureOption
|
|
24
24
|
|
|
25
|
-
equities = Equity.get(session, ['SPY', 'AAPL'])
|
|
25
|
+
equities = await Equity.get(session, ['SPY', 'AAPL'])
|
|
26
26
|
print(equities[0].is_etf, equities[0].description)
|
|
27
|
-
future_option = FutureOption.get(session, './GCJ4 OG4G4 240223P1915')
|
|
27
|
+
future_option = await FutureOption.get(session, './GCJ4 OG4G4 240223P1915')
|
|
28
28
|
print(future_option.exchange)
|
|
29
29
|
|
|
30
30
|
>>> (False, 'APPLE INC')
|
|
@@ -42,10 +42,10 @@ The symbol structure for options and futures options is somewhat complex, so you
|
|
|
42
42
|
from tastytrade.instruments import get_option_chain, get_future_option_chain
|
|
43
43
|
from tastytrade.utils import get_tasty_monthly
|
|
44
44
|
|
|
45
|
-
chain = get_option_chain(session, 'SPLG')
|
|
45
|
+
chain = await get_option_chain(session, 'SPLG')
|
|
46
46
|
exp = get_tasty_monthly() # 45 DTE expiration!
|
|
47
47
|
print(chain[exp][0])
|
|
48
|
-
future_chain = get_future_option_chain(session, '/MCL')
|
|
48
|
+
future_chain = await get_future_option_chain(session, '/MCL')
|
|
49
49
|
print(future_chain.keys()) # print all expirations
|
|
50
50
|
|
|
51
51
|
>>> instrument_type=<InstrumentType.EQUITY_OPTION: 'Equity Option'> symbol='SPLG 240315C00024000' active=True strike_price=Decimal('24.0') root_symbol='SPLG' underlying_symbol='SPLG' expiration_date=datetime.date(2024, 3, 15) exercise_style='American' shares_per_contract=100 option_type=<OptionType.CALL: 'C'> option_chain_type='Standard' expiration_type='Regular' settlement_type='PM' stops_trading_at=datetime.datetime(2024, 3, 15, 20, 0, tzinfo=datetime.timezone.utc) market_time_instrument_collection='Equity Option' days_to_expiration=38 expires_at=datetime.datetime(2024, 3, 15, 20, 0, tzinfo=datetime.timezone.utc) is_closing_only=False listed_market=None halted_at=None old_security_number=None streamer_symbol='.SPLG240315C24'
|
|
@@ -57,12 +57,12 @@ Alternatively, ``NestedOptionChain`` and ``NestedFutureOptionChain`` provide a s
|
|
|
57
57
|
|
|
58
58
|
from tastytrade.instruments import NestedOptionChain
|
|
59
59
|
|
|
60
|
-
chain = NestedOptionChain.get(session, 'SPY')
|
|
60
|
+
chain = await NestedOptionChain.get(session, 'SPY')
|
|
61
61
|
print(chain.expirations[0].strikes[0])
|
|
62
62
|
|
|
63
63
|
>>> Strike(strike_price=Decimal('437.0'), call='SPY 240417C00437000', put='SPY 240417P00437000', call_streamer_symbol='.SPY240417C437', put_streamer_symbol='.SPY240417P437')
|
|
64
64
|
|
|
65
|
-
Each expiration contains a list of these strikes, which have the associated put and call symbols that can then be used to fetch option objects via ``Option.get_options()
|
|
65
|
+
Each expiration contains a list of these strikes, which have the associated put and call symbols that can then be used to fetch option objects via ``Option.get_options()``, as well as dxfeed symbols for use with the streamer.
|
|
66
66
|
|
|
67
67
|
Placing trades
|
|
68
68
|
--------------
|
|
@@ -76,7 +76,7 @@ This makes placing new trades across a wide variety of instruments surprisingly
|
|
|
76
76
|
from tastytrade.order import *
|
|
77
77
|
from datetime import date
|
|
78
78
|
|
|
79
|
-
chain = get_future_option_chain(session, '/MCL')
|
|
79
|
+
chain = await get_future_option_chain(session, '/MCL')
|
|
80
80
|
put = chain[date(2024, 3, 15)][286]
|
|
81
81
|
call = chain[date(2024, 3, 15)][187]
|
|
82
82
|
|
|
@@ -85,13 +85,13 @@ This makes placing new trades across a wide variety of instruments surprisingly
|
|
|
85
85
|
order_type=OrderType.LIMIT,
|
|
86
86
|
legs=[
|
|
87
87
|
# two parameters: quantity and order action
|
|
88
|
-
put.build_leg(
|
|
89
|
-
call.build_leg(
|
|
88
|
+
put.build_leg(1, OrderAction.SELL_TO_OPEN),
|
|
89
|
+
call.build_leg(1, OrderAction.SELL_TO_OPEN)
|
|
90
90
|
],
|
|
91
91
|
price=Decimal('1.25') # price is always per quantity, not total
|
|
92
92
|
)
|
|
93
93
|
# assuming an initialized account
|
|
94
|
-
account.place_order(session, order, dry_run=False)
|
|
94
|
+
await account.place_order(session, order, dry_run=False)
|
|
95
95
|
|
|
96
96
|
That's it! We just sold a micro crude oil futures strangle in a few lines of code.
|
|
97
97
|
Note that price is per quantity, not the price for the entire order! So if the legs looked like this:
|
|
@@ -99,8 +99,8 @@ Note that price is per quantity, not the price for the entire order! So if the l
|
|
|
99
99
|
.. code-block:: python
|
|
100
100
|
|
|
101
101
|
legs=[
|
|
102
|
-
put.build_leg(
|
|
103
|
-
call.build_leg(
|
|
102
|
+
put.build_leg(2, OrderAction.SELL_TO_OPEN),
|
|
103
|
+
call.build_leg(2, OrderAction.SELL_TO_OPEN)
|
|
104
104
|
]
|
|
105
105
|
|
|
106
106
|
the price would still be ``Decimal('1.25')``, and the total credit collected would be $2.50. This holds true for ratio spreads, so a 4:2 ratio spread should be priced as a 2:1 ratio spread.
|
|
@@ -10,7 +10,7 @@ Fortunately, Tastytrade has endpoints that make fetching data for one-time use a
|
|
|
10
10
|
from tastytrade.market_data import get_market_data
|
|
11
11
|
from tastytrade.order import InstrumentType
|
|
12
12
|
|
|
13
|
-
data = get_market_data(session, "SPY", InstrumentType.EQUITY)
|
|
13
|
+
data = await get_market_data(session, "SPY", InstrumentType.EQUITY)
|
|
14
14
|
print(data)
|
|
15
15
|
|
|
16
16
|
>>> symbol='SPY' instrument_type=<InstrumentType.EQUITY: 'Equity'> updated_at=datetime.datetime(2025, 4, 28, 21, 46, 48, 84000, tzinfo=TzInfo(UTC)) bid_size=Decimal('2.0') ask_size=Decimal('4.0') mark=Decimal('549.96') close_price_type=<ClosePriceType.FINAL: 'Final'> prev_close=Decimal('550.64') prev_close_price_type=<ClosePriceType.FINAL: 'Final'> summary_date=datetime.date(2025, 4, 28) prev_close_date=datetime.date(2025, 4, 25) halt_start_time=-1 halt_end_time=-1 ask=Decimal('550.0') beta=Decimal('1.009463163') bid=Decimal('549.9') close=Decimal('550.85') day_high_price=Decimal('553.55') day_low_price=Decimal('545.02') dividend_amount=Decimal('1.695528') dividend_frequency=Decimal('4.0') high_limit_price=Decimal('606.41') last=Decimal('549.96') last_mkt=Decimal('550.85') low_limit_price=Decimal('496.16') mid=Decimal('549.95') open=Decimal('551.39') volume=Decimal('47417792.0') year_low_price=Decimal('481.8') year_high_price=Decimal('613.23')
|
|
@@ -21,7 +21,7 @@ You can also fetch data for multiple symbols at once:
|
|
|
21
21
|
|
|
22
22
|
from tastytrade.market_data import get_market_data_by_type
|
|
23
23
|
|
|
24
|
-
data = get_market_data_by_type(
|
|
24
|
+
data = await get_market_data_by_type(
|
|
25
25
|
session,
|
|
26
26
|
indices=["SPX", "VIX"],
|
|
27
27
|
cryptocurrencies=["ETH/USD", "BTC/USD"],
|
|
@@ -10,7 +10,7 @@ The ``get_market_sessions`` function can be used to obtain information about the
|
|
|
10
10
|
.. code-block:: python
|
|
11
11
|
|
|
12
12
|
from tastytrade.market_sessions import ExchangeType, get_market_sessions
|
|
13
|
-
get_market_sessions(session, exchanges=[ExchangeType.NYSE])
|
|
13
|
+
await get_market_sessions(session, exchanges=[ExchangeType.NYSE])
|
|
14
14
|
|
|
15
15
|
>>> [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=<MarketStatus.CLOSED: 'Closed'>)]
|
|
16
16
|
|
|
@@ -19,7 +19,7 @@ The ``get_market_holidays`` function can be used to obtain information about mar
|
|
|
19
19
|
.. code-block:: python
|
|
20
20
|
|
|
21
21
|
from tastytrade.market_sessions import get_market_holidays
|
|
22
|
-
calendar = Market.get_market_holidays(session)
|
|
22
|
+
calendar = await Market.get_market_holidays(session)
|
|
23
23
|
print(calendar.half_days)
|
|
24
24
|
print(calendar.holidays)
|
|
25
25
|
|
|
@@ -32,7 +32,7 @@ I case you only want to extract the market status, this is one way to do it:
|
|
|
32
32
|
|
|
33
33
|
from tastytrade.market_sessions import ExchangeType, MarketStatus, get_market_sessions
|
|
34
34
|
|
|
35
|
-
market_sessions = get_market_sessions(session, exchanges=[ExchangeType.NYSE, ExchangeType.CME])
|
|
35
|
+
market_sessions = await get_market_sessions(session, exchanges=[ExchangeType.NYSE, ExchangeType.CME])
|
|
36
36
|
print([ms.status != MarketStatus.CLOSED for ms in market_sessions])
|
|
37
37
|
|
|
38
38
|
>>> [False, False]
|