tickrush 0.1.0__cp312-cp312-macosx_11_0_arm64.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.
tickrush/__init__.py ADDED
@@ -0,0 +1,24 @@
1
+ from .tickrush import (
2
+ ExchangePrices,
3
+ MarketBook,
4
+ MarketDefinition,
5
+ MarketDefinitionRunner,
6
+ PricesIterator,
7
+ PriceSize,
8
+ Runner,
9
+ StartingPrices,
10
+ iter_prices_file,
11
+ )
12
+
13
+ __version__ = "0.1.0"
14
+ __all__ = [
15
+ "iter_prices_file",
16
+ "MarketBook",
17
+ "MarketDefinition",
18
+ "MarketDefinitionRunner",
19
+ "Runner",
20
+ "ExchangePrices",
21
+ "StartingPrices",
22
+ "PriceSize",
23
+ "PricesIterator",
24
+ ]
Binary file
tickrush/tickrush.pyi ADDED
@@ -0,0 +1,166 @@
1
+ import datetime
2
+ from typing import Optional
3
+
4
+ class PriceSize:
5
+ price: float
6
+ size: float
7
+ def __getitem__(self, key: str) -> float: ...
8
+ def __repr__(self) -> str: ...
9
+
10
+ class ExchangePrices:
11
+ @property
12
+ def available_to_back(self) -> list[PriceSize]: ...
13
+ @property
14
+ def available_to_lay(self) -> list[PriceSize]: ...
15
+ @property
16
+ def traded_volume(self) -> list[PriceSize]: ...
17
+
18
+ class StartingPrices:
19
+ @property
20
+ def near_price(self) -> Optional[float | str]: ...
21
+ @property
22
+ def far_price(self) -> Optional[float | str]: ...
23
+ @property
24
+ def actual_sp(self) -> Optional[float | str]: ...
25
+ @property
26
+ def back_stake_taken(self) -> list[PriceSize]: ...
27
+ @property
28
+ def lay_liability_taken(self) -> list[PriceSize]: ...
29
+
30
+ class MarketDefinitionRunner:
31
+ selection_id: int
32
+ sort_priority: int
33
+ status: str
34
+ handicap: float
35
+ adjustment_factor: Optional[float]
36
+ removal_date: Optional[str]
37
+ name: Optional[str]
38
+ bsp: Optional[float]
39
+
40
+ class MarketDefinition:
41
+ @property
42
+ def event_id(self) -> Optional[str]: ...
43
+ @property
44
+ def event_type_id(self) -> Optional[str]: ...
45
+ @property
46
+ def event_name(self) -> Optional[str]: ...
47
+ @property
48
+ def market_type(self) -> Optional[str]: ...
49
+ @property
50
+ def country_code(self) -> Optional[str]: ...
51
+ @property
52
+ def venue(self) -> Optional[str]: ...
53
+ @property
54
+ def race_type(self) -> Optional[str]: ...
55
+ @property
56
+ def name(self) -> Optional[str]: ...
57
+ @property
58
+ def timezone(self) -> Optional[str]: ...
59
+ @property
60
+ def betting_type(self) -> Optional[str]: ...
61
+ @property
62
+ def regulators(self) -> list[str]: ...
63
+ @property
64
+ def runners(self) -> list[MarketDefinitionRunner]: ...
65
+ @property
66
+ def market_time(self) -> Optional[datetime.datetime]: ...
67
+ @property
68
+ def open_date(self) -> Optional[datetime.datetime]: ...
69
+ @property
70
+ def suspend_time(self) -> Optional[datetime.datetime]: ...
71
+ @property
72
+ def settled_time(self) -> Optional[datetime.datetime]: ...
73
+ @property
74
+ def bsp_market(self) -> bool: ...
75
+ @property
76
+ def persistence_enabled(self) -> bool: ...
77
+ @property
78
+ def each_way_divisor(self) -> Optional[float]: ...
79
+ @property
80
+ def turn_in_play_enabled(self) -> bool: ...
81
+ @property
82
+ def discount_allowed(self) -> bool: ...
83
+ @property
84
+ def market_base_rate(self) -> float: ...
85
+ @property
86
+ def bet_delay(self) -> int: ...
87
+ @property
88
+ def number_of_winners(self) -> int: ...
89
+ @property
90
+ def number_of_active_runners(self) -> int: ...
91
+ @property
92
+ def bsp_reconciled(self) -> bool: ...
93
+ @property
94
+ def complete(self) -> bool: ...
95
+ @property
96
+ def cross_matching(self) -> bool: ...
97
+ @property
98
+ def in_play(self) -> bool: ...
99
+ @property
100
+ def runners_voidable(self) -> bool: ...
101
+ @property
102
+ def status(self) -> str: ...
103
+ @property
104
+ def version(self) -> int: ...
105
+
106
+ class Runner:
107
+ selection_id: int
108
+ handicap: float
109
+ adjustment_factor: Optional[float]
110
+ last_price_traded: Optional[float]
111
+ total_matched: float
112
+ @property
113
+ def status(self) -> Optional[str]: ...
114
+ @property
115
+ def removal_date(self) -> Optional[str]: ...
116
+ @property
117
+ def ex(self) -> ExchangePrices: ...
118
+ @property
119
+ def sp(self) -> StartingPrices: ...
120
+
121
+ class MarketBook:
122
+ streaming_unique_id: Optional[int]
123
+ @property
124
+ def market_id(self) -> str: ...
125
+ @property
126
+ def publish_time(self) -> datetime.datetime: ...
127
+ @property
128
+ def publish_time_epoch(self) -> int: ...
129
+ @property
130
+ def status(self) -> str: ...
131
+ @property
132
+ def bet_delay(self) -> int: ...
133
+ @property
134
+ def bsp_reconciled(self) -> bool: ...
135
+ @property
136
+ def complete(self) -> bool: ...
137
+ @property
138
+ def cross_matching(self) -> bool: ...
139
+ @property
140
+ def inplay(self) -> bool: ...
141
+ @property
142
+ def number_of_active_runners(self) -> int: ...
143
+ @property
144
+ def number_of_runners(self) -> int: ...
145
+ @property
146
+ def number_of_winners(self) -> int: ...
147
+ @property
148
+ def runners_voidable(self) -> bool: ...
149
+ @property
150
+ def total_matched(self) -> float: ...
151
+ @property
152
+ def version(self) -> int: ...
153
+ @property
154
+ def last_match_time(self) -> Optional[int]: ...
155
+ @property
156
+ def market_definition(self) -> Optional[MarketDefinition]: ...
157
+ @property
158
+ def runners(self) -> list[Runner]: ...
159
+ def to_dict(self) -> dict: ...
160
+
161
+ class PricesIterator:
162
+ def __iter__(self) -> PricesIterator: ...
163
+ def __next__(self) -> MarketBook: ...
164
+ def __len__(self) -> int: ...
165
+
166
+ def iter_prices_file(path: str) -> PricesIterator: ...
@@ -0,0 +1,94 @@
1
+ Metadata-Version: 2.4
2
+ Name: tickrush
3
+ Version: 0.1.0
4
+ Classifier: License :: OSI Approved :: MIT License
5
+ Classifier: Programming Language :: Rust
6
+ Classifier: Programming Language :: Python :: 3.10
7
+ Classifier: Programming Language :: Python :: 3.11
8
+ Classifier: Programming Language :: Python :: 3.12
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ License-File: LICENSE
11
+ Summary: High-performance Betfair price stream reader
12
+ Author-email: Maurice Berk <maurice@mauriceberk.com>
13
+ License: MIT
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
16
+ Project-URL: Repository, https://github.com/mberk/tickrush
17
+
18
+ # tickrush
19
+
20
+ `tickrush` is a performance-first ingestion layer for saved Betfair Exchange price stream data.
21
+ Its sole purpose is to get historical Betfair `MarketBook` updates into `flumine` as fast as possible.
22
+
23
+ ## Installation
24
+
25
+ Initial releases are available from GitHub. A PyPI release will follow shortly.
26
+
27
+ ```
28
+ pip install git+https://github.com/mberk/tickrush.git
29
+ ```
30
+
31
+ Python >=3.10 required.
32
+ A Rust toolchain is required to build the PyO3 extension.
33
+
34
+ ## Usage
35
+
36
+ To use `tickrush` when running a `flumine` simulation simply apply a trivial monkey-patch to `HistoricalStream.create_generator`.
37
+ Here is an illustration using the `flumine` `LowestLayer` example strategy:
38
+
39
+
40
+ ```python
41
+ # Store original create_generator for restoration
42
+ _original_create_generator = HistoricalStream.create_generator
43
+
44
+ # Monkey-patch HistoricalStream to use tickrush
45
+ HistoricalStream.create_generator = tickrush.create_generator
46
+
47
+ client = clients.SimulatedClient()
48
+
49
+ framework = FlumineSimulation(client=client)
50
+
51
+ markets = ["tests/resources/PRO-1.170258213"]
52
+
53
+ strategy = LowestLayer(
54
+ market_filter={"markets": markets},
55
+ max_order_exposure=1000,
56
+ max_selection_exposure=105,
57
+ context={"stake": 2},
58
+ )
59
+ framework.add_strategy(strategy)
60
+
61
+ framework.run()
62
+
63
+ # Restore original
64
+ HistoricalStream.create_generator = _original_create_generator
65
+ ```
66
+
67
+ ## Intent
68
+
69
+ `tickrush` is obsessively focused on minimising the time taken to:
70
+
71
+ - parse archived Betfair stream messages
72
+ - produce `MarketBook` objects consumable by `flumine`
73
+ - access fields on said `MarketBook` objects
74
+
75
+ Everything else is deliberately out of scope.
76
+
77
+ ## Technology
78
+
79
+ - Rust parser exposed via PyO3
80
+ - Low-allocation decoding of Betfair stream messages
81
+ - Efficient runner- and price-level cache reuse
82
+ - Thin Python surface designed to integrate directly with `flumine`
83
+
84
+ ## Roadmap
85
+
86
+ Planned future work includes:
87
+ - A compact proprietary file format for even more efficient parsing
88
+ - Offering a range of stripped down `MarketBook`-like objects to avoid unnecessarily constructing unused fields
89
+ - Switching to a pure C extension to minimise `getter` overhead
90
+
91
+ ## Status
92
+
93
+ This project is under active development and not yet API-stable.
94
+
@@ -0,0 +1,7 @@
1
+ tickrush/__init__.py,sha256=74p5zc7qvm9qmfc_Hx4OEZArGV2AEAQov09u-GSd394,431
2
+ tickrush/tickrush.cpython-312-darwin.so,sha256=sN3siGfQPdcBa2M8P_EUQBPH3lQpAwc1b22BRv1p1S8,742784
3
+ tickrush/tickrush.pyi,sha256=IecVHRlNe1R006uAhpvvpmzmT5HNlH3NJ6oloxEDXZA,4680
4
+ tickrush-0.1.0.dist-info/METADATA,sha256=0O-LSJnWnnYWscjzp3vRTCfZP4Nxt4uN8Uxxci3zHGg,2819
5
+ tickrush-0.1.0.dist-info/WHEEL,sha256=qr8B0oB3ZR0cwIaW0mxUADH9b4sNRMHcgJlpYNTDAPw,105
6
+ tickrush-0.1.0.dist-info/licenses/LICENSE,sha256=TN_37r1AEIqgRyYWwlnUZa7erd4oed870BuxtKTDz_k,1069
7
+ tickrush-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.11.5)
3
+ Root-Is-Purelib: false
4
+ Tag: cp312-cp312-macosx_11_0_arm64
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Maurice Berk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.