Skip to content
This repository was archived by the owner on Nov 18, 2024. It is now read-only.

Commit 039bfe5

Browse files
committed
Open interest streaming, bug fixes, enum fixes.
1 parent 66ff3ba commit 039bfe5

File tree

2 files changed

+19
-21
lines changed

2 files changed

+19
-21
lines changed

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "thetadata"
7-
version = "0.7.5.2"
7+
version = "0.7.6"
88
authors = [
99
{ name="Adler Weber", email="[email protected]" },
1010
{ name="Bailey Danseglio", email="[email protected]" },

thetadata/client.py

+18-20
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,9 @@ def _format_date(dt: date) -> str:
5959

6060

6161
class Trade:
62-
"""Trade"""
62+
"""Trade representing all values provided by the Thetadata stream."""
6363
def __init__(self):
64-
"""from_bytes
65-
"""
64+
"""Dummy constructor"""
6665
self.ms_of_day = 0
6766
self.sequence = 0
6867
self.size = 0
@@ -72,8 +71,7 @@ def __init__(self):
7271
self.date = None
7372

7473
def from_bytes(self, data: bytearray):
75-
"""from_bytes
76-
"""
74+
"""Deserializes a trade."""
7775
view = memoryview(data)
7876
parse_int = lambda d: int.from_bytes(d, "big")
7977
self.ms_of_day = parse_int(view[0:4])
@@ -86,16 +84,16 @@ def from_bytes(self, data: bytearray):
8684
self.date = date(year=int(date_raw[0:4]), month=int(date_raw[4:6]), day=int(date_raw[6:8]))
8785

8886
def to_string(self) -> str:
87+
"""String representation of a trade."""
8988
return 'ms_of_day: ' + str(self.ms_of_day) + ' sequence: ' + str(self.sequence) + ' size: ' + str(self.size) + \
9089
' condition: ' + str(self.condition.name) + ' price: ' + str(self.price) + ' exchange: ' + \
9190
str(self.exchange.value[1]) + ' date: ' + str(self.date)
9291

9392

9493
class Quote:
95-
"""Quote"""
94+
"""Quote representing all values provided by the Thetadata stream."""
9695
def __init__(self):
97-
"""from_bytes
98-
"""
96+
"""Dummy constructor"""
9997
self.ms_of_day = 0
10098
self.bid_size = 0
10199
self.bid_exchange = Exchange.OPRA
@@ -108,8 +106,7 @@ def __init__(self):
108106
self.date = None
109107

110108
def from_bytes(self, data: bytes):
111-
"""from_bytes
112-
"""
109+
"""Deserializes a trade."""
113110
view = memoryview(data)
114111
parse_int = lambda d: int.from_bytes(d, "big")
115112
mult = _pt_to_price_mul[parse_int(view[36:40])]
@@ -126,6 +123,7 @@ def from_bytes(self, data: bytes):
126123
self.date = date(year=int(date_raw[0:4]), month=int(date_raw[4:6]), day=int(date_raw[6:8]))
127124

128125
def to_string(self) -> str:
126+
"""String representation of a quote."""
129127
return 'ms_of_day: ' + str(self.ms_of_day) + ' bid_size: ' + str(self.bid_size) + ' bid_exchange: ' + \
130128
str(self.bid_exchange.value[1]) + ' bid_price: ' + str(self.bid_price) + ' bid_condition: ' + \
131129
str(self.bid_condition.name) + ' ask_size: ' + str(self.ask_size) + ' ask_exchange: ' +\
@@ -134,40 +132,37 @@ def to_string(self) -> str:
134132

135133

136134
class OpenInterest:
137-
"""Trade"""
135+
"""Open Interest"""
138136
def __init__(self):
139-
"""from_bytes
140-
"""
137+
"""Dummy constructor"""
141138
self.open_interest = 0
142139
self.date = None
143140

144141
def from_bytes(self, data: bytearray):
145-
"""from_bytes
146-
"""
142+
"""Deserializes open interest."""
147143
view = memoryview(data)
148144
parse_int = lambda d: int.from_bytes(d, "big")
149145
self.open_interest = parse_int(view[0:4])
150146
date_raw = str(parse_int(view[4:8]))
151147
self.date = date(year=int(date_raw[0:4]), month=int(date_raw[4:6]), day=int(date_raw[6:8]))
152148

153149
def to_string(self) -> str:
150+
"""String representation of open interest."""
154151
return 'open_interest: ' + str(self.open_interest) + ' date: ' + str(self.date)
155152

156153

157154
class Contract:
158155
"""Contract"""
159156
def __init__(self):
160-
"""from_bytes
161-
"""
157+
"""Dummy constructor"""
162158
self.root = ""
163159
self.exp = None
164160
self.strike = None
165161
self.isCall = False
166162
self.isOption = False
167163

168164
def from_bytes(self, data: bytes):
169-
"""from_bytes
170-
"""
165+
"""Deserializes a contract."""
171166
view = memoryview(data)
172167
parse_int = lambda d: int.from_bytes(d, "big")
173168
# parse
@@ -185,12 +180,13 @@ def from_bytes(self, data: bytes):
185180
self.strike = parse_int(view[root_len + 9: root_len + 13]) / 1000.0
186181

187182
def to_string(self) -> str:
183+
"""String representation of open interest."""
188184
return 'root: ' + self.root + ' isOption: ' + str(self.isOption) + ' exp: ' + str(self.exp) + \
189185
' strike: ' + str(self.strike) + ' isCall: ' + str(self.isCall)
190186

191187

192188
class StreamMsg:
193-
"""Msg"""
189+
"""Stream Msg"""
194190
def __init__(self):
195191
self.type = StreamMsgType.ERROR
196192
self.trade = Trade()
@@ -272,6 +268,8 @@ def connect(self):
272268
def connect_stream(self, callback):
273269
"""Initiate a connection with the Theta Terminal Stream server on `localhost`.
274270
Requests can only be made inside this generator aka the `with client.connect_stream()` block.
271+
Responses to the provided callback method are recycled, meaning that if you send data received
272+
in the callback method to another thread, you must create a copy of it first.
275273
276274
:raises ConnectionRefusedError: If the connection failed.
277275
:raises TimeoutError: If the timeout is set and has been reached.

0 commit comments

Comments
 (0)