itchfeed 1.0.3__py3-none-any.whl → 1.0.4__py3-none-any.whl
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.
- itch/__init__.py +2 -1
- itch/messages.py +55 -0
- {itchfeed-1.0.3.dist-info → itchfeed-1.0.4.dist-info}/METADATA +75 -1
- itchfeed-1.0.4.dist-info/RECORD +9 -0
- itchfeed-1.0.3.dist-info/RECORD +0 -9
- {itchfeed-1.0.3.dist-info → itchfeed-1.0.4.dist-info}/WHEEL +0 -0
- {itchfeed-1.0.3.dist-info → itchfeed-1.0.4.dist-info}/licenses/LICENSE +0 -0
- {itchfeed-1.0.3.dist-info → itchfeed-1.0.4.dist-info}/top_level.txt +0 -0
itch/__init__.py
CHANGED
itch/messages.py
CHANGED
@@ -35,6 +35,13 @@ class MarketMessage(object):
|
|
35
35
|
def __repr__(self):
|
36
36
|
return repr(self.decode())
|
37
37
|
|
38
|
+
def pack(self) -> bytes:
|
39
|
+
"""
|
40
|
+
Packs the message into bytes using the defined message_pack_format.
|
41
|
+
This method should be overridden by subclasses to include specific fields.
|
42
|
+
"""
|
43
|
+
pass
|
44
|
+
|
38
45
|
def set_timestamp(self, ts1: int, ts2: int):
|
39
46
|
"""
|
40
47
|
Reconstructs a 6-byte timestamp (48 bits) from two 32-bit unsigned integers.
|
@@ -1598,3 +1605,51 @@ messages: Dict[bytes, Type[MarketMessage]] = {
|
|
1598
1605
|
b"N": RetailPriceImprovementIndicator,
|
1599
1606
|
b"O": DLCRMessage,
|
1600
1607
|
}
|
1608
|
+
|
1609
|
+
|
1610
|
+
def create_message(message_type: bytes, **kwargs) -> Type[MarketMessage]:
|
1611
|
+
"""
|
1612
|
+
Creates a new message of a given type with specified attributes.
|
1613
|
+
|
1614
|
+
This function simplifies the process of message creation by handling
|
1615
|
+
the instantiation and attribute setting for any valid message type.
|
1616
|
+
It's particularly useful for simulating trading environments or
|
1617
|
+
generating test data without manually packing and unpacking bytes.
|
1618
|
+
|
1619
|
+
Args:
|
1620
|
+
message_type (bytes):
|
1621
|
+
A single-byte identifier for the message type (e.g., b'A'
|
1622
|
+
for AddOrderNoMPIAttributionMessage).
|
1623
|
+
**kwargs:
|
1624
|
+
Keyword arguments representing the attributes of the message.
|
1625
|
+
These must match the attributes expected by the message class
|
1626
|
+
(e.g., `stock_locate`, `timestamp`, `price`).
|
1627
|
+
|
1628
|
+
Returns:
|
1629
|
+
MarketMessage:
|
1630
|
+
An instance of the corresponding message class, populated with
|
1631
|
+
the provided attributes.
|
1632
|
+
|
1633
|
+
Raises:
|
1634
|
+
ValueError:
|
1635
|
+
If the `message_type` is not found in the registered messages.
|
1636
|
+
"""
|
1637
|
+
message_class = messages.get(message_type)
|
1638
|
+
if not message_class:
|
1639
|
+
raise ValueError(f"Unknown message type: {message_type.decode()}")
|
1640
|
+
|
1641
|
+
# Create a new instance without calling __init__
|
1642
|
+
# __init__ is for unpacking, not creating
|
1643
|
+
instance = message_class.__new__(message_class)
|
1644
|
+
|
1645
|
+
# Set attributes from kwargs
|
1646
|
+
for key, value in kwargs.items():
|
1647
|
+
if key == 'timestamp':
|
1648
|
+
# Timestamps are 48-bit, so we need to mask the original value
|
1649
|
+
value &= ((1 << 48) - 1)
|
1650
|
+
setattr(instance, key, value)
|
1651
|
+
|
1652
|
+
# Set the message_type attribute on the instance, as it's used by pack()
|
1653
|
+
instance.message_type = message_type
|
1654
|
+
|
1655
|
+
return instance
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: itchfeed
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.4
|
4
4
|
Summary: Simple parser for ITCH messages
|
5
5
|
Home-page: https://github.com/bbalouki/itch
|
6
6
|
Download-URL: https://pypi.org/project/itchfeed/
|
@@ -52,6 +52,8 @@ Dynamic: summary
|
|
52
52
|
* [Usage](#usage)
|
53
53
|
* [Parsing from a Binary File](#parsing-from-a-binary-file)
|
54
54
|
* [Parsing from Raw Bytes](#parsing-from-raw-bytes)
|
55
|
+
* [Creating Messages Programmatically](#creating-messages-programmatically)
|
56
|
+
* [Example with Real-World Sample Data](#example-with-real-world-sample-data)
|
55
57
|
* [Interpreting Market Data (Conceptual Overview)](#interpreting-market-data-conceptual-overview)
|
56
58
|
* [Supported Message Types](#supported-message-types)
|
57
59
|
* [Data Representation](#data-representation)
|
@@ -211,6 +213,78 @@ while not message_queue.empty():
|
|
211
213
|
|
212
214
|
```
|
213
215
|
|
216
|
+
### Creating Messages Programmatically
|
217
|
+
|
218
|
+
In addition to parsing, `itch` provides a simple way to create ITCH message objects from scratch. This is particularly useful for:
|
219
|
+
- **Testing:** Generating specific message sequences to test your own downstream applications.
|
220
|
+
- **Simulation:** Building custom market simulators that produce ITCH-compliant data streams.
|
221
|
+
- **Data Generation:** Creating custom datasets for analysis or backtesting.
|
222
|
+
|
223
|
+
The `create_message` function is the primary tool for this purpose. It takes a `message_type` and keyword arguments corresponding to the desired message attributes.
|
224
|
+
|
225
|
+
Here's a basic example of how to create a `SystemEventMessage` to signal the "Start of Messages":
|
226
|
+
|
227
|
+
```python
|
228
|
+
from itch.messages import create_message, SystemEventMessage
|
229
|
+
|
230
|
+
# Define the attributes for the message
|
231
|
+
event_attributes = {
|
232
|
+
"stock_locate": 1,
|
233
|
+
"tracking_number": 2,
|
234
|
+
"timestamp": 1651500000 * 1_000_000_000,
|
235
|
+
"event_code": b"O"
|
236
|
+
}
|
237
|
+
|
238
|
+
# Create the message object
|
239
|
+
system_event_message = create_message(b"S", **event_attributes)
|
240
|
+
|
241
|
+
# You can now work with this object just like one from the parser
|
242
|
+
print(isinstance(system_event_message, SystemEventMessage))
|
243
|
+
# Expected output: True
|
244
|
+
|
245
|
+
print(system_event_message)
|
246
|
+
# Expected output: SystemEventMessage(description='System Event Message', event_code='O', message_format='!HHHIc', message_pack_format='!cHHHIc', message_size=12, message_type='S', price_precision=4, stock_locate=1, timestamp=86311638581248, tracking_number=2)
|
247
|
+
```
|
248
|
+
|
249
|
+
### Example with Real-World Sample Data
|
250
|
+
|
251
|
+
You can also use the sample data provided in `tests/data.py` to create messages, simulating a more realistic scenario.
|
252
|
+
|
253
|
+
```python
|
254
|
+
from itch.messages import create_message, AddOrderNoMPIAttributionMessage
|
255
|
+
from tests.data import TEST_DATA
|
256
|
+
|
257
|
+
# Get the sample data for an "Add Order" message (type 'A')
|
258
|
+
add_order_data = TEST_DATA[b"A"]
|
259
|
+
|
260
|
+
# Create the message
|
261
|
+
add_order_message = create_message(b"A", **add_order_data)
|
262
|
+
|
263
|
+
# Verify the type
|
264
|
+
print(isinstance(add_order_message, AddOrderNoMPIAttributionMessage))
|
265
|
+
# Expected output: True
|
266
|
+
|
267
|
+
# Access its attributes
|
268
|
+
print(f"Stock: {add_order_message.stock.decode().strip()}")
|
269
|
+
# Expected output: Stock: AAPL
|
270
|
+
|
271
|
+
print(f"Price: {add_order_message.decode_price('price')}")
|
272
|
+
# Expected output: Price: 150.1234
|
273
|
+
|
274
|
+
# Test all message types in the sample data
|
275
|
+
for message_type, sample_data in TEST_DATA.items():
|
276
|
+
print(f"Creating message of type {message_type}")
|
277
|
+
message = create_message(message_type, **sample_data)
|
278
|
+
print(f"Created message: {message}")
|
279
|
+
print(f"Packed message: {message.pack()}")
|
280
|
+
print(f"Message size: {message.message_size}")
|
281
|
+
print(f"Message Attributes: {message.get_attributes()}")
|
282
|
+
assert len(message.pack()) == message.message_size
|
283
|
+
print()
|
284
|
+
```
|
285
|
+
|
286
|
+
By leveraging `create_message`, you can build robust test suites for your trading algorithms, compliance checks, or data analysis pipelines without needing a live data feed.
|
287
|
+
|
214
288
|
## Interpreting Market Data (Conceptual Overview)
|
215
289
|
|
216
290
|
Parsing individual ITCH messages is the first step; understanding market dynamics often requires processing and correlating a sequence of these messages. This library provides the tools to decode messages, but interpreting their collective meaning requires building further logic.
|
@@ -0,0 +1,9 @@
|
|
1
|
+
itch/__init__.py,sha256=M9Jirj4-XXdaCoTcU2_g89z7JHK8mDtJflTFf9HnU-k,205
|
2
|
+
itch/indicators.py,sha256=-Ed2M8I60xGQ1bIPZCGCKGb8ayT87JAnIaosfiBimXI,6542
|
3
|
+
itch/messages.py,sha256=lm5pKQ00ETMbTij9HqaYVrN08JJdQe-mZKB_C7IAetU,63934
|
4
|
+
itch/parser.py,sha256=BOrkGsmRkcYnXSf5S9yqrwzP0jqtkH5mGCpWCeiWNTg,6155
|
5
|
+
itchfeed-1.0.4.dist-info/licenses/LICENSE,sha256=f2u79rUzh-UcYH0RN0Ph0VvVYHBkYlVxtguhKmrHqsw,1089
|
6
|
+
itchfeed-1.0.4.dist-info/METADATA,sha256=HYjteeevesrGUcrjvuNlW2P-0B9k8jtL0qdovoaLZT0,33793
|
7
|
+
itchfeed-1.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
8
|
+
itchfeed-1.0.4.dist-info/top_level.txt,sha256=xwsOYShvy3gc1rfyitCTgSxBZDGG1y6bfQxkdhIGmEM,5
|
9
|
+
itchfeed-1.0.4.dist-info/RECORD,,
|
itchfeed-1.0.3.dist-info/RECORD
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
itch/__init__.py,sha256=m8ulOH0nET4yLoKcqWJA-VjOEZldGo932t95rHOZh4w,204
|
2
|
-
itch/indicators.py,sha256=-Ed2M8I60xGQ1bIPZCGCKGb8ayT87JAnIaosfiBimXI,6542
|
3
|
-
itch/messages.py,sha256=UHr4eBTtgiLg9vO53GpciAxiAO9AD9uCu8Xz3WnfadM,61927
|
4
|
-
itch/parser.py,sha256=BOrkGsmRkcYnXSf5S9yqrwzP0jqtkH5mGCpWCeiWNTg,6155
|
5
|
-
itchfeed-1.0.3.dist-info/licenses/LICENSE,sha256=f2u79rUzh-UcYH0RN0Ph0VvVYHBkYlVxtguhKmrHqsw,1089
|
6
|
-
itchfeed-1.0.3.dist-info/METADATA,sha256=nfZbTBXUq5Ghq1xhls4fttblPNlpRGtqZth1h8lnx-4,30699
|
7
|
-
itchfeed-1.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
8
|
-
itchfeed-1.0.3.dist-info/top_level.txt,sha256=xwsOYShvy3gc1rfyitCTgSxBZDGG1y6bfQxkdhIGmEM,5
|
9
|
-
itchfeed-1.0.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|