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 CHANGED
@@ -6,5 +6,6 @@ __author__ = "Bertin Balouki SIMYELI"
6
6
  __copyright__ = "2025 Bertin Balouki SIMYELI"
7
7
  __email__ = "bertin@bbstrader.com"
8
8
  __license__ = "MIT"
9
- __version__ = "1.0.0"
9
+ __version__ = "1.0.4"
10
+
10
11
 
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
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,,
@@ -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,,