synpath 0.1.0__tar.gz → 0.3.1__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.
Files changed (204) hide show
  1. synpath-0.3.1/Cargo.toml +19 -0
  2. {synpath-0.1.0 → synpath-0.3.1}/PKG-INFO +70 -61
  3. {synpath-0.1.0 → synpath-0.3.1}/README.md +40 -28
  4. synpath-0.3.1/bindings/python/Cargo.lock +551 -0
  5. synpath-0.3.1/bindings/python/Cargo.toml +20 -0
  6. synpath-0.3.1/bindings/python/src/kalshi.rs +175 -0
  7. synpath-0.3.1/bindings/python/src/lib.rs +403 -0
  8. synpath-0.3.1/bindings/python/src/objects.rs +158 -0
  9. synpath-0.3.1/bindings/python/src/polymarket.rs +394 -0
  10. synpath-0.3.1/bindings/python/src/pyjson.rs +41 -0
  11. synpath-0.3.1/bindings/python/src/router.rs +184 -0
  12. synpath-0.3.1/bindings/python/src/signing.rs +195 -0
  13. synpath-0.3.1/bindings/python/src/venues.rs +110 -0
  14. synpath-0.3.1/build_backend/synpath_build.py +80 -0
  15. synpath-0.3.1/crates/synpath-core/Cargo.lock +474 -0
  16. synpath-0.3.1/crates/synpath-core/Cargo.toml +16 -0
  17. synpath-0.3.1/crates/synpath-core/examples/decode_timing.rs +48 -0
  18. synpath-0.3.1/crates/synpath-core/src/book.rs +235 -0
  19. synpath-0.3.1/crates/synpath-core/src/kalshi.rs +169 -0
  20. synpath-0.3.1/crates/synpath-core/src/lib.rs +18 -0
  21. synpath-0.3.1/crates/synpath-core/src/opinion.rs +63 -0
  22. synpath-0.3.1/crates/synpath-core/src/polymarket.rs +241 -0
  23. synpath-0.3.1/crates/synpath-core/src/polymarket_us.rs +78 -0
  24. synpath-0.3.1/crates/synpath-core/src/router.rs +238 -0
  25. synpath-0.3.1/crates/synpath-core/src/signing.rs +371 -0
  26. synpath-0.3.1/crates/synpath-core/src/wire.rs +241 -0
  27. {synpath-0.1.0 → synpath-0.3.1}/pyproject.toml +19 -6
  28. {synpath-0.1.0 → synpath-0.3.1}/synpath/__init__.py +7 -2
  29. synpath-0.3.1/synpath/_native.py +32 -0
  30. {synpath-0.1.0 → synpath-0.3.1}/synpath/client.py +6 -1
  31. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/__main__.py +1 -0
  32. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/feeds.py +7 -0
  33. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/orders/routed.py +39 -9
  34. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/router.py +176 -31
  35. {synpath-0.1.0 → synpath-0.3.1}/synpath/ids.py +4 -4
  36. {synpath-0.1.0 → synpath-0.3.1}/synpath/matching.py +10 -3
  37. synpath-0.3.1/synpath/opinion.py +799 -0
  38. {synpath-0.1.0 → synpath-0.3.1}/synpath/server/serve.py +1 -1
  39. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/__init__.py +4 -0
  40. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/__main__.py +7 -1
  41. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/credentials.py +45 -1
  42. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/init.py +17 -0
  43. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/instruments.py +5 -0
  44. synpath-0.3.1/synpath/trading/opinion.py +760 -0
  45. synpath-0.3.1/synpath/trading/opinion_signing.py +174 -0
  46. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/polymarket_signing.py +46 -1
  47. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/types.py +7 -0
  48. {synpath-0.1.0 → synpath-0.3.1}/synpath/types.py +15 -1
  49. {synpath-0.1.0 → synpath-0.3.1}/synpath/ws/__init__.py +4 -0
  50. {synpath-0.1.0 → synpath-0.3.1}/synpath/ws/base.py +27 -7
  51. {synpath-0.1.0 → synpath-0.3.1}/synpath/ws/kalshi.py +34 -1
  52. synpath-0.3.1/synpath/ws/opinion.py +486 -0
  53. {synpath-0.1.0 → synpath-0.3.1}/synpath/ws/polymarket.py +28 -1
  54. {synpath-0.1.0 → synpath-0.3.1}/synpath/ws/polymarket_us.py +22 -4
  55. synpath-0.1.0/.env.example +0 -39
  56. synpath-0.1.0/.github/workflows/publish.yml +0 -48
  57. synpath-0.1.0/.github/workflows/tests.yml +0 -21
  58. synpath-0.1.0/.gitignore +0 -12
  59. synpath-0.1.0/assets/kalshi.png +0 -0
  60. synpath-0.1.0/assets/polymarket.png +0 -0
  61. synpath-0.1.0/assets/synpath-banner.png +0 -0
  62. synpath-0.1.0/clients/typescript/.gitignore +0 -5
  63. synpath-0.1.0/clients/typescript/example.ts +0 -77
  64. synpath-0.1.0/clients/typescript/package.json +0 -20
  65. synpath-0.1.0/clients/typescript/tsconfig.json +0 -11
  66. synpath-0.1.0/docs/api.md +0 -279
  67. synpath-0.1.0/docs/capabilities.md +0 -102
  68. synpath-0.1.0/docs/engine.md +0 -354
  69. synpath-0.1.0/docs/server.md +0 -146
  70. synpath-0.1.0/docs/streaming.md +0 -232
  71. synpath-0.1.0/docs/trading.md +0 -318
  72. synpath-0.1.0/examples/track_historical_book.py +0 -222
  73. synpath-0.1.0/tests/conftest.py +0 -118
  74. synpath-0.1.0/tests/samples/kalshi_candles.json +0 -1
  75. synpath-0.1.0/tests/samples/kalshi_events.json +0 -1
  76. synpath-0.1.0/tests/samples/kalshi_orderbook.json +0 -1
  77. synpath-0.1.0/tests/samples/kalshi_series.json +0 -1
  78. synpath-0.1.0/tests/samples/kalshi_trades.json +0 -1
  79. synpath-0.1.0/tests/samples/kalshi_trading_delete_events_orders.json +0 -1
  80. synpath-0.1.0/tests/samples/kalshi_trading_delete_events_orders_batched.json +0 -14
  81. synpath-0.1.0/tests/samples/kalshi_trading_delete_events_orders_id.json +0 -5
  82. synpath-0.1.0/tests/samples/kalshi_trading_delete_order_groups_id.json +0 -1
  83. synpath-0.1.0/tests/samples/kalshi_trading_get_account_endpoint_costs.json +0 -90
  84. synpath-0.1.0/tests/samples/kalshi_trading_get_account_limits.json +0 -12
  85. synpath-0.1.0/tests/samples/kalshi_trading_get_balance.json +0 -24
  86. synpath-0.1.0/tests/samples/kalshi_trading_get_fills.json +0 -25
  87. synpath-0.1.0/tests/samples/kalshi_trading_get_markets.json +0 -11805
  88. synpath-0.1.0/tests/samples/kalshi_trading_get_order_groups_id.json +0 -6
  89. synpath-0.1.0/tests/samples/kalshi_trading_get_orders.json +0 -136
  90. synpath-0.1.0/tests/samples/kalshi_trading_get_orders_id.json +0 -28
  91. synpath-0.1.0/tests/samples/kalshi_trading_get_orders_id_queue_position.json +0 -3
  92. synpath-0.1.0/tests/samples/kalshi_trading_get_positions.json +0 -25
  93. synpath-0.1.0/tests/samples/kalshi_trading_get_series_id.json +0 -39
  94. synpath-0.1.0/tests/samples/kalshi_trading_get_settlements.json +0 -4
  95. synpath-0.1.0/tests/samples/kalshi_trading_post_events_orders.json +0 -7
  96. synpath-0.1.0/tests/samples/kalshi_trading_post_events_orders_batched.json +0 -18
  97. synpath-0.1.0/tests/samples/kalshi_trading_post_events_orders_id_amend.json +0 -5
  98. synpath-0.1.0/tests/samples/kalshi_trading_post_events_orders_id_decrease.json +0 -5
  99. synpath-0.1.0/tests/samples/kalshi_trading_post_order_groups_create.json +0 -5
  100. synpath-0.1.0/tests/samples/kalshi_trading_put_order_groups_id_reset.json +0 -1
  101. synpath-0.1.0/tests/samples/kalshi_trading_put_order_groups_id_trigger.json +0 -1
  102. synpath-0.1.0/tests/samples/poly_book.json +0 -1
  103. synpath-0.1.0/tests/samples/poly_events.json +0 -1
  104. synpath-0.1.0/tests/samples/poly_market.json +0 -1
  105. synpath-0.1.0/tests/samples/poly_prices.json +0 -1
  106. synpath-0.1.0/tests/samples/poly_search.json +0 -1
  107. synpath-0.1.0/tests/samples/poly_trades.json +0 -1
  108. synpath-0.1.0/tests/samples/polymarket_signing_vectors.json +0 -9430
  109. synpath-0.1.0/tests/samples/polyus_bbo.json +0 -51
  110. synpath-0.1.0/tests/samples/polyus_book.json +0 -250
  111. synpath-0.1.0/tests/samples/polyus_closed_market.json +0 -133
  112. synpath-0.1.0/tests/samples/polyus_events.json +0 -2813
  113. synpath-0.1.0/tests/samples/polyus_market.json +0 -154
  114. synpath-0.1.0/tests/samples/polyus_prices.json +0 -29
  115. synpath-0.1.0/tests/samples/polyus_search.json +0 -364
  116. synpath-0.1.0/tests/samples/polyus_series.json +0 -26
  117. synpath-0.1.0/tests/samples/polyus_settlement.json +0 -5
  118. synpath-0.1.0/tests/samples/ws/kalshi_demo_transcript.jsonl +0 -208
  119. synpath-0.1.0/tests/samples/ws/polymarket_market_transcript.jsonl +0 -133
  120. synpath-0.1.0/tests/test_client.py +0 -171
  121. synpath-0.1.0/tests/test_contract.py +0 -844
  122. synpath-0.1.0/tests/test_engine.py +0 -685
  123. synpath-0.1.0/tests/test_engine_demo.py +0 -192
  124. synpath-0.1.0/tests/test_engine_orders.py +0 -593
  125. synpath-0.1.0/tests/test_engine_orders_demo.py +0 -258
  126. synpath-0.1.0/tests/test_feeds.py +0 -249
  127. synpath-0.1.0/tests/test_history_tracker.py +0 -86
  128. synpath-0.1.0/tests/test_history_types.py +0 -60
  129. synpath-0.1.0/tests/test_hosted.py +0 -136
  130. synpath-0.1.0/tests/test_hosted_auth.py +0 -32
  131. synpath-0.1.0/tests/test_init.py +0 -104
  132. synpath-0.1.0/tests/test_journal_v3.py +0 -166
  133. synpath-0.1.0/tests/test_kalshi.py +0 -1249
  134. synpath-0.1.0/tests/test_kalshi_demo.py +0 -285
  135. synpath-0.1.0/tests/test_kalshi_trading.py +0 -561
  136. synpath-0.1.0/tests/test_live.py +0 -536
  137. synpath-0.1.0/tests/test_polymarket.py +0 -639
  138. synpath-0.1.0/tests/test_polymarket_trading.py +0 -810
  139. synpath-0.1.0/tests/test_polymarket_us.py +0 -562
  140. synpath-0.1.0/tests/test_polymarket_us_trading.py +0 -624
  141. synpath-0.1.0/tests/test_remote_client.py +0 -231
  142. synpath-0.1.0/tests/test_risk_duplicates.py +0 -42
  143. synpath-0.1.0/tests/test_routed_limit.py +0 -291
  144. synpath-0.1.0/tests/test_routed_recovery.py +0 -176
  145. synpath-0.1.0/tests/test_router.py +0 -135
  146. synpath-0.1.0/tests/test_serve.py +0 -176
  147. synpath-0.1.0/tests/test_server.py +0 -430
  148. synpath-0.1.0/tests/test_server_trading.py +0 -616
  149. synpath-0.1.0/tests/test_trading_foundations.py +0 -395
  150. synpath-0.1.0/tests/test_venue_errors.py +0 -39
  151. synpath-0.1.0/tests/test_ws.py +0 -720
  152. synpath-0.1.0/tests/test_ws_grpc.py +0 -659
  153. synpath-0.1.0/tests/test_ws_live.py +0 -112
  154. {synpath-0.1.0 → synpath-0.3.1}/LICENSE +0 -0
  155. {synpath-0.1.0 → synpath-0.3.1}/synpath/__main__.py +0 -0
  156. {synpath-0.1.0 → synpath-0.3.1}/synpath/base.py +0 -0
  157. {synpath-0.1.0 → synpath-0.3.1}/synpath/bucket.py +0 -0
  158. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/__init__.py +0 -0
  159. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/alerts.py +0 -0
  160. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/engine.py +0 -0
  161. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/eod.py +0 -0
  162. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/events.py +0 -0
  163. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/fair_values.py +0 -0
  164. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/journal.py +0 -0
  165. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/ledger.py +0 -0
  166. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/orders/__init__.py +0 -0
  167. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/orders/base.py +0 -0
  168. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/orders/day.py +0 -0
  169. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/orders/iceberg.py +0 -0
  170. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/orders/manager.py +0 -0
  171. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/orders/oco.py +0 -0
  172. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/orders/peg.py +0 -0
  173. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/orders/stop.py +0 -0
  174. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/orders/taker.py +0 -0
  175. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/orders/twap.py +0 -0
  176. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/paper.py +0 -0
  177. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/reconcile.py +0 -0
  178. {synpath-0.1.0 → synpath-0.3.1}/synpath/engine/risk.py +0 -0
  179. {synpath-0.1.0 → synpath-0.3.1}/synpath/errors.py +0 -0
  180. {synpath-0.1.0 → synpath-0.3.1}/synpath/history.py +0 -0
  181. {synpath-0.1.0 → synpath-0.3.1}/synpath/hosted.py +0 -0
  182. {synpath-0.1.0 → synpath-0.3.1}/synpath/hosted_auth.py +0 -0
  183. {synpath-0.1.0 → synpath-0.3.1}/synpath/kalshi.py +0 -0
  184. {synpath-0.1.0 → synpath-0.3.1}/synpath/polymarket.py +0 -0
  185. {synpath-0.1.0 → synpath-0.3.1}/synpath/polymarket_us.py +0 -0
  186. {synpath-0.1.0 → synpath-0.3.1}/synpath/remote.py +0 -0
  187. {synpath-0.1.0 → synpath-0.3.1}/synpath/server/__init__.py +0 -0
  188. {synpath-0.1.0 → synpath-0.3.1}/synpath/server/__main__.py +0 -0
  189. {synpath-0.1.0 → synpath-0.3.1}/synpath/server/api.py +0 -0
  190. {synpath-0.1.0 → synpath-0.3.1}/synpath/server/errors.py +0 -0
  191. {synpath-0.1.0 → synpath-0.3.1}/synpath/server/local.py +0 -0
  192. {synpath-0.1.0 → synpath-0.3.1}/synpath/server/models.py +0 -0
  193. {synpath-0.1.0 → synpath-0.3.1}/synpath/server/store.py +0 -0
  194. {synpath-0.1.0 → synpath-0.3.1}/synpath/server/trading.py +0 -0
  195. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/base.py +0 -0
  196. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/errors.py +0 -0
  197. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/kalshi.py +0 -0
  198. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/limiter.py +0 -0
  199. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/money.py +0 -0
  200. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/polymarket.py +0 -0
  201. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/polymarket_us.py +0 -0
  202. {synpath-0.1.0 → synpath-0.3.1}/synpath/trading/polymarket_us_exchange.py +0 -0
  203. {synpath-0.1.0 → synpath-0.3.1}/synpath/ws/grpc.py +0 -0
  204. {synpath-0.1.0 → synpath-0.3.1}/synpath/ws/polymarket_us_exchange.py +0 -0
@@ -0,0 +1,19 @@
1
+ # The Rust core under the Python API.
2
+ #
3
+ # crates/synpath-core pure Rust: no I/O, no Python. The hot paths live here.
4
+ # bindings/python PyO3 wrappers, built by maturin into `synpath._core`.
5
+ #
6
+ # Every piece here has a pure-Python twin in `synpath/`, and the test suite runs
7
+ # against both, so the two cannot drift apart.
8
+ [workspace]
9
+ members = ["crates/synpath-core", "bindings/python"]
10
+ resolver = "2"
11
+
12
+ [workspace.package]
13
+ edition = "2021"
14
+ license = "MIT"
15
+ repository = "https://github.com/Synpath-ai/synpath"
16
+
17
+ [profile.release]
18
+ lto = "fat"
19
+ codegen-units = 1
@@ -1,70 +1,68 @@
1
- Metadata-Version: 2.5
1
+ Metadata-Version: 2.4
2
2
  Name: synpath
3
- Version: 0.1.0
4
- Summary: One API for prediction markets. Kalshi and Polymarket, normalized, with every price labelled by source and time.
5
- Project-URL: Homepage, https://synpath.dev
6
- Project-URL: Documentation, https://synpath.dev/docs
7
- Project-URL: Repository, https://github.com/Synpath-ai/synpath
8
- Project-URL: Issues, https://github.com/Synpath-ai/synpath/issues
9
- Project-URL: Discord, https://discord.gg/QZzsHTpGA3
10
- Author: Synpath
11
- License: MIT
12
- License-File: LICENSE
13
- Keywords: kalshi,market-data,polymarket,prediction-markets,trading,unified-api
3
+ Version: 0.3.1
14
4
  Classifier: Development Status :: 3 - Alpha
15
5
  Classifier: Intended Audience :: Financial and Insurance Industry
16
6
  Classifier: License :: OSI Approved :: MIT License
17
7
  Classifier: Programming Language :: Python :: 3
18
8
  Classifier: Topic :: Office/Business :: Financial
19
- Requires-Python: >=3.10
20
- Requires-Dist: aiosqlite>=0.20
21
- Requires-Dist: cryptography>=42
22
- Requires-Dist: eth-account>=0.13
23
- Requires-Dist: fastapi>=0.110
24
9
  Requires-Dist: httpx>=0.27
25
10
  Requires-Dist: pydantic>=2.6
11
+ Requires-Dist: cryptography>=42
12
+ Requires-Dist: eth-account>=0.13
26
13
  Requires-Dist: pyjwt[crypto]>=2.8
27
- Requires-Dist: tomli>=2.0; python_version < '3.11'
28
- Requires-Dist: uvicorn[standard]>=0.27
29
14
  Requires-Dist: websockets>=13
15
+ Requires-Dist: aiosqlite>=0.20
16
+ Requires-Dist: fastapi>=0.110
17
+ Requires-Dist: uvicorn[standard]>=0.27
18
+ Requires-Dist: tomli>=2.0 ; python_full_version < '3.11'
19
+ Requires-Dist: pytest>=8 ; extra == 'dev'
20
+ Requires-Dist: respx>=0.21 ; extra == 'dev'
21
+ Requires-Dist: anyio>=4 ; extra == 'dev'
22
+ Requires-Dist: synpath[grpc] ; extra == 'dev'
23
+ Requires-Dist: grpcio>=1.60 ; extra == 'grpc'
24
+ Requires-Dist: grpcio-tools>=1.60 ; extra == 'grpc'
25
+ Requires-Dist: protobuf>=5.26 ; extra == 'grpc'
26
+ Requires-Dist: pyjwt[crypto]>=2.8 ; extra == 'grpc'
27
+ Requires-Dist: cryptography>=42 ; extra == 'grpc'
30
28
  Provides-Extra: dev
31
- Requires-Dist: anyio>=4; extra == 'dev'
32
- Requires-Dist: cryptography>=42; extra == 'dev'
33
- Requires-Dist: grpcio-tools>=1.60; extra == 'dev'
34
- Requires-Dist: grpcio>=1.60; extra == 'dev'
35
- Requires-Dist: protobuf>=5.26; extra == 'dev'
36
- Requires-Dist: pyjwt[crypto]>=2.8; extra == 'dev'
37
- Requires-Dist: pytest>=8; extra == 'dev'
38
- Requires-Dist: respx>=0.21; extra == 'dev'
39
29
  Provides-Extra: engine
40
30
  Provides-Extra: grpc
41
- Requires-Dist: cryptography>=42; extra == 'grpc'
42
- Requires-Dist: grpcio-tools>=1.60; extra == 'grpc'
43
- Requires-Dist: grpcio>=1.60; extra == 'grpc'
44
- Requires-Dist: protobuf>=5.26; extra == 'grpc'
45
- Requires-Dist: pyjwt[crypto]>=2.8; extra == 'grpc'
46
31
  Provides-Extra: server
47
32
  Provides-Extra: trading
48
33
  Provides-Extra: ws
49
- Description-Content-Type: text/markdown
34
+ License-File: LICENSE
35
+ Summary: One API for prediction markets. Kalshi and Polymarket, normalized, with every price labelled by source and time.
36
+ Keywords: prediction-markets,kalshi,polymarket,unified-api,trading,market-data
37
+ Author: Synpath
38
+ License: MIT
39
+ Requires-Python: >=3.10
40
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
41
+ Project-URL: Discord, https://synpath.dev/discord
42
+ Project-URL: Documentation, https://synpath.dev/docs
43
+ Project-URL: Homepage, https://synpath.dev
44
+ Project-URL: Issues, https://github.com/Synpath-ai/synpath/issues
45
+ Project-URL: Repository, https://github.com/Synpath-ai/synpath
50
46
 
51
47
  <div align="center">
52
48
 
53
49
  <img src="https://raw.githubusercontent.com/Synpath-ai/synpath/main/assets/synpath-banner.png" alt="Synpath: one API for every prediction market" width="100%">
54
50
 
55
- # Synpath – One API for prediction markets
51
+ # Synpath – One API for prediction markets <a href="https://x.com/Synpath_Dev"><img src="https://img.shields.io/twitter/url?url=https%3A%2F%2Fx.com%2FSynpath_Dev&style=social&label=Follow" alt="Follow @Synpath_Dev on X" height="28"></a>
56
52
 
57
53
  **Build on prediction markets without building against each one.**<br/>
58
- One open-source API across Kalshi, Polymarket and Polymarket US: market data, order entry, live streams, and an execution engine that remembers what it sent. In-process from Python, over REST and WebSocket from anywhere.
54
+ One open-source API across Kalshi, Polymarket, Polymarket US and Opinion: market data, order entry, live streams, and an execution engine that remembers what it sent. In-process from Python, over REST and WebSocket from anywhere.
59
55
 
60
56
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"></a>
61
- <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10%2B-blue.svg" alt="Python 3.10+"></a>
62
- <a href="https://discord.gg/QZzsHTpGA3"><img src="https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white" alt="Discord"></a>
57
+ <a href="https://pepy.tech/projects/synpath"><img src="https://img.shields.io/pepy/dt/synpath?label=Total%20Downloads&color=blue" alt="Total Downloads"></a>
58
+ <a href="https://synpath.dev/discord"><img src="https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white" alt="Discord"></a>
63
59
 
64
60
  </div>
65
61
 
66
- **🆕 New: Every Kalshi order book, every tick.**<br/>
67
- Full-depth books and trades for every past Kalshi trade. Query any moment in under a minute. **[Get the data →](https://synpath.dev/tick-data)**
62
+ **🆕 New: Smart order routing across Kalshi and Polymarket.**<br/>
63
+ One order, both order books combined, filled from the cheapest price after fees. **[See how it works →](https://www.synpath.dev/docs/concepts/buckets)**
64
+
65
+ ⭐ **If Synpath saves you time, [star it on GitHub](https://github.com/Synpath-ai/synpath).** It's how other traders find it.
68
66
 
69
67
  ---
70
68
 
@@ -75,10 +73,11 @@ Full-depth books and trades for every past Kalshi trade. Query any moment in und
75
73
  | <img src="assets/kalshi.png" width="20" height="20" alt="Kalshi"> | [Kalshi](https://kalshi.com) | `kalshi` | ✓ | ✓ | WebSocket | one book per market, both sides read it |
76
74
  | <img src="assets/polymarket.png" width="20" height="20" alt="Polymarket"> | [Polymarket](https://polymarket.com) | `polymarket` | ✓ | ✓ | WebSocket | one book per outcome token |
77
75
  | <img src="assets/polymarket.png" width="20" height="20" alt="Polymarket US"> | [Polymarket US](https://polymarket.us) | `polymarket_us` | ✓ | ✓ retail and exchange APIs | WebSocket and gRPC | one book per market, both sides read it |
76
+ | | [Opinion](https://opinion.trade) | `opinion` | ✓ | ✓ not yet live-tested | WebSocket (API key) | one book per outcome token |
78
77
 
79
78
  ## Why Synpath
80
79
 
81
- - **Liquidity is fragmented. Your time shouldn't be.** The same market trades on Kalshi, Polymarket and Polymarket US, each with its own API, units and quirks. Synpath gives you one interface for all of them, and smart order routing buys from whichever book is cheapest. Spend your time on alpha, not plumbing.
80
+ - **Liquidity is fragmented. Your time shouldn't be.** The same market trades on Kalshi, Polymarket, Polymarket US and Opinion, each with its own API, units and quirks. Synpath gives you one interface for all of them, and smart order routing buys from whichever book is cheapest. Spend your time on alpha, not plumbing.
82
81
 
83
82
  - **Traders deserve advanced order types.** Stops, trailing stops, icebergs, OCO, brackets, TWAP and pegs, on every venue, even where the exchange has none. Orders are journaled before they're sent, so a crash never places one twice.
84
83
 
@@ -91,7 +90,7 @@ pip install synpath # market data, order entry, streams, the engine
91
90
  pip install "synpath[grpc]" # + Polymarket US exchange gRPC streams
92
91
  ```
93
92
 
94
- Python 3.10 or newer.
93
+ Python 3.10 or newer. The hot paths (order books, reading the venues' book streams, order signing and the order router) run on a Rust core that ships prebuilt inside the wheel for Linux, macOS and Windows; nothing else to install.
95
94
 
96
95
  **Hosted API.** Run `synpath login`, then `synpath keys create`. It serves tick-level Kalshi order book and trade history, and cross-venue market matching. Trading stays on your machine: Synpath never holds your keys or funds.
97
96
 
@@ -124,7 +123,7 @@ fee.estimate(price=0.50, contracts=100) # 1.75
124
123
  **Same code, every venue**
125
124
 
126
125
  ```python
127
- for venue_id in synpath.exchanges: # ['kalshi', 'polymarket', 'polymarket_us']
126
+ for venue_id in synpath.exchanges: # ['kalshi', 'polymarket', 'polymarket_us', 'opinion']
128
127
  with synpath.exchange(venue_id) as venue:
129
128
  page = venue.fetch_markets(limit=5)
130
129
 
@@ -157,18 +156,26 @@ async with PolymarketMarketStream() as stream:
157
156
  print(event.market_id, event.side, event.best_bid, event.best_ask)
158
157
  ```
159
158
 
160
- **The engine, and the orders the venues do not hold**
159
+ **Smart order routing: one order across Kalshi and Polymarket**
161
160
 
162
161
  ```python
163
- from synpath.engine import Engine, EngineConfig, RiskConfig
164
- from synpath import OrderType
165
-
166
- async with Engine({"kalshi": kalshi}, EngineConfig(journal_path="trading.db"),
167
- risk=RiskConfig(max_order_contracts=Decimal("100"))) as engine:
162
+ from synpath import Bucket, BucketMember, OrderType, PolymarketTrading
163
+ from synpath.engine import Engine, EngineConfig
164
+
165
+ creds = load_credentials()
166
+ async with KalshiTrading(require("kalshi", creds)) as kalshi, \
167
+ PolymarketTrading(require("polymarket", creds)) as poly, \
168
+ Engine({"kalshi": kalshi, "polymarket": poly}, EngineConfig(journal_path="trading.db")) as engine:
169
+ # The same market on both venues; flip=True where a venue asks the question the other way round
170
+ bucket = await engine.save_bucket(Bucket(book="alpha", name="Fed cut in December", members=[
171
+ BucketMember(market_id="kalshi:KXFEDDECISION-26DEC-C25"),
172
+ BucketMember(market_id="polymarket:2252244", flip=True),
173
+ ]))
174
+ # Both order books combined, each level net of fees, filled from the cheapest price outward
168
175
  await engine.submit(OrderRequest(
169
- market_id=market.id, side=Side.SELL, amount=Decimal("20"),
170
- type=OrderType.TRAILING_STOP, stop_price=Decimal("0.40"),
171
- params={"trail": "0.03"}, book="alpha",
176
+ market_id=bucket.market_id, side=Side.BUY, amount=Decimal("500"),
177
+ type=OrderType.MARKET, price=Decimal("0.45"), # the worst price you accept
178
+ book="alpha",
172
179
  ))
173
180
  ```
174
181
 
@@ -189,27 +196,28 @@ npx openapi-typescript openapi.json --default-non-nullable false -o src/synpath.
189
196
 
190
197
  ## Documentation
191
198
 
192
- - [CLI](https://synpath.dev/docs/quickstart): hosted data API sign-in and keys versus local venue trading server setup
193
- - [Unified API](https://synpath.dev/docs/sdks/python): methods, data structures, identifiers, paging, status, errors
194
- - [Capabilities](https://synpath.dev/docs/concepts/exchanges): what each venue can and cannot answer
195
- - [HTTP server](https://synpath.dev/docs/api-reference): routes, envelopes, typed client generation, trading routes with per-account keys, mounting behind your own auth
196
- - [Trading](https://synpath.dev/docs/concepts/orders): credentials, `Decimal` money, order entry on Kalshi, Polymarket and Polymarket US
197
- - [Streaming](https://synpath.dev/docs/ws-api-reference): WebSocket and gRPC books, trades, orders and fills as self-healing event streams
198
- - [Engine](docs/engine.md): a journal written before anything is sent, pre-trade risk, a ledger, reconciliation, a kill switch, the order types the venues do not hold, buckets that route one order across venues, paper trading
199
- - [TypeScript client](https://synpath.dev/docs/sdks/typescript): generate a typed client from the OpenAPI document, place through cancel without Python
199
+ See the [API Reference](https://www.synpath.dev/docs) for detailed documentation and more examples.
200
200
 
201
201
  ## Development
202
202
 
203
203
  ```bash
204
204
  git clone https://github.com/Synpath-ai/synpath
205
205
  cd synpath
206
- pip install -e ".[dev]"
206
+ pip install -e ".[dev]" # builds the Rust core too: needs a Rust toolchain (rustup.rs)
207
207
 
208
208
  pytest # offline, against recorded venue payloads
209
209
  pytest -m live # market data against the real venues
210
210
  pytest -m demo # order entry on a venue's demo environment
211
+ SYNPATH_PURE_PYTHON=1 pytest # the same tests on the pure-Python fallback
212
+ cargo test -p synpath-core # the Rust core on its own
211
213
  ```
212
214
 
215
+ The Rust core lives in `crates/synpath-core` (pure Rust) and
216
+ `bindings/python` (its PyO3 wrapper, built as `synpath._core`). Every class
217
+ it provides has a pure-Python twin with the same interface, and the library
218
+ uses the twin when the extension is not built. Venue adapters are plain
219
+ Python: adding a venue needs no Rust.
220
+
213
221
  The `demo` tests place and cancel real orders on a demo exchange with the
214
222
  credentials in your environment, and leave the account flat. `python -m
215
223
  synpath.trading doctor` says which venues are configured without printing a
@@ -217,8 +225,9 @@ secret.
217
225
 
218
226
  ## Prior Art
219
227
 
220
- [ccxt](https://github.com/ccxt/ccxt) set the conventions this library follows. [pmxt](https://github.com/pmxt-dev/pmxt) got to prediction markets first.
228
+ [ccxt](https://github.com/ccxt/ccxt) set the conventions this library follows.
221
229
 
222
230
  ## License
223
231
 
224
232
  MIT
233
+
@@ -2,19 +2,21 @@
2
2
 
3
3
  <img src="https://raw.githubusercontent.com/Synpath-ai/synpath/main/assets/synpath-banner.png" alt="Synpath: one API for every prediction market" width="100%">
4
4
 
5
- # Synpath – One API for prediction markets
5
+ # Synpath – One API for prediction markets <a href="https://x.com/Synpath_Dev"><img src="https://img.shields.io/twitter/url?url=https%3A%2F%2Fx.com%2FSynpath_Dev&style=social&label=Follow" alt="Follow @Synpath_Dev on X" height="28"></a>
6
6
 
7
7
  **Build on prediction markets without building against each one.**<br/>
8
- One open-source API across Kalshi, Polymarket and Polymarket US: market data, order entry, live streams, and an execution engine that remembers what it sent. In-process from Python, over REST and WebSocket from anywhere.
8
+ One open-source API across Kalshi, Polymarket, Polymarket US and Opinion: market data, order entry, live streams, and an execution engine that remembers what it sent. In-process from Python, over REST and WebSocket from anywhere.
9
9
 
10
10
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"></a>
11
- <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10%2B-blue.svg" alt="Python 3.10+"></a>
12
- <a href="https://discord.gg/QZzsHTpGA3"><img src="https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white" alt="Discord"></a>
11
+ <a href="https://pepy.tech/projects/synpath"><img src="https://img.shields.io/pepy/dt/synpath?label=Total%20Downloads&color=blue" alt="Total Downloads"></a>
12
+ <a href="https://synpath.dev/discord"><img src="https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white" alt="Discord"></a>
13
13
 
14
14
  </div>
15
15
 
16
- **🆕 New: Every Kalshi order book, every tick.**<br/>
17
- Full-depth books and trades for every past Kalshi trade. Query any moment in under a minute. **[Get the data →](https://synpath.dev/tick-data)**
16
+ **🆕 New: Smart order routing across Kalshi and Polymarket.**<br/>
17
+ One order, both order books combined, filled from the cheapest price after fees. **[See how it works →](https://www.synpath.dev/docs/concepts/buckets)**
18
+
19
+ ⭐ **If Synpath saves you time, [star it on GitHub](https://github.com/Synpath-ai/synpath).** It's how other traders find it.
18
20
 
19
21
  ---
20
22
 
@@ -25,10 +27,11 @@ Full-depth books and trades for every past Kalshi trade. Query any moment in und
25
27
  | <img src="assets/kalshi.png" width="20" height="20" alt="Kalshi"> | [Kalshi](https://kalshi.com) | `kalshi` | ✓ | ✓ | WebSocket | one book per market, both sides read it |
26
28
  | <img src="assets/polymarket.png" width="20" height="20" alt="Polymarket"> | [Polymarket](https://polymarket.com) | `polymarket` | ✓ | ✓ | WebSocket | one book per outcome token |
27
29
  | <img src="assets/polymarket.png" width="20" height="20" alt="Polymarket US"> | [Polymarket US](https://polymarket.us) | `polymarket_us` | ✓ | ✓ retail and exchange APIs | WebSocket and gRPC | one book per market, both sides read it |
30
+ | | [Opinion](https://opinion.trade) | `opinion` | ✓ | ✓ not yet live-tested | WebSocket (API key) | one book per outcome token |
28
31
 
29
32
  ## Why Synpath
30
33
 
31
- - **Liquidity is fragmented. Your time shouldn't be.** The same market trades on Kalshi, Polymarket and Polymarket US, each with its own API, units and quirks. Synpath gives you one interface for all of them, and smart order routing buys from whichever book is cheapest. Spend your time on alpha, not plumbing.
34
+ - **Liquidity is fragmented. Your time shouldn't be.** The same market trades on Kalshi, Polymarket, Polymarket US and Opinion, each with its own API, units and quirks. Synpath gives you one interface for all of them, and smart order routing buys from whichever book is cheapest. Spend your time on alpha, not plumbing.
32
35
 
33
36
  - **Traders deserve advanced order types.** Stops, trailing stops, icebergs, OCO, brackets, TWAP and pegs, on every venue, even where the exchange has none. Orders are journaled before they're sent, so a crash never places one twice.
34
37
 
@@ -41,7 +44,7 @@ pip install synpath # market data, order entry, streams, the engine
41
44
  pip install "synpath[grpc]" # + Polymarket US exchange gRPC streams
42
45
  ```
43
46
 
44
- Python 3.10 or newer.
47
+ Python 3.10 or newer. The hot paths (order books, reading the venues' book streams, order signing and the order router) run on a Rust core that ships prebuilt inside the wheel for Linux, macOS and Windows; nothing else to install.
45
48
 
46
49
  **Hosted API.** Run `synpath login`, then `synpath keys create`. It serves tick-level Kalshi order book and trade history, and cross-venue market matching. Trading stays on your machine: Synpath never holds your keys or funds.
47
50
 
@@ -74,7 +77,7 @@ fee.estimate(price=0.50, contracts=100) # 1.75
74
77
  **Same code, every venue**
75
78
 
76
79
  ```python
77
- for venue_id in synpath.exchanges: # ['kalshi', 'polymarket', 'polymarket_us']
80
+ for venue_id in synpath.exchanges: # ['kalshi', 'polymarket', 'polymarket_us', 'opinion']
78
81
  with synpath.exchange(venue_id) as venue:
79
82
  page = venue.fetch_markets(limit=5)
80
83
 
@@ -107,18 +110,26 @@ async with PolymarketMarketStream() as stream:
107
110
  print(event.market_id, event.side, event.best_bid, event.best_ask)
108
111
  ```
109
112
 
110
- **The engine, and the orders the venues do not hold**
113
+ **Smart order routing: one order across Kalshi and Polymarket**
111
114
 
112
115
  ```python
113
- from synpath.engine import Engine, EngineConfig, RiskConfig
114
- from synpath import OrderType
115
-
116
- async with Engine({"kalshi": kalshi}, EngineConfig(journal_path="trading.db"),
117
- risk=RiskConfig(max_order_contracts=Decimal("100"))) as engine:
116
+ from synpath import Bucket, BucketMember, OrderType, PolymarketTrading
117
+ from synpath.engine import Engine, EngineConfig
118
+
119
+ creds = load_credentials()
120
+ async with KalshiTrading(require("kalshi", creds)) as kalshi, \
121
+ PolymarketTrading(require("polymarket", creds)) as poly, \
122
+ Engine({"kalshi": kalshi, "polymarket": poly}, EngineConfig(journal_path="trading.db")) as engine:
123
+ # The same market on both venues; flip=True where a venue asks the question the other way round
124
+ bucket = await engine.save_bucket(Bucket(book="alpha", name="Fed cut in December", members=[
125
+ BucketMember(market_id="kalshi:KXFEDDECISION-26DEC-C25"),
126
+ BucketMember(market_id="polymarket:2252244", flip=True),
127
+ ]))
128
+ # Both order books combined, each level net of fees, filled from the cheapest price outward
118
129
  await engine.submit(OrderRequest(
119
- market_id=market.id, side=Side.SELL, amount=Decimal("20"),
120
- type=OrderType.TRAILING_STOP, stop_price=Decimal("0.40"),
121
- params={"trail": "0.03"}, book="alpha",
130
+ market_id=bucket.market_id, side=Side.BUY, amount=Decimal("500"),
131
+ type=OrderType.MARKET, price=Decimal("0.45"), # the worst price you accept
132
+ book="alpha",
122
133
  ))
123
134
  ```
124
135
 
@@ -139,27 +150,28 @@ npx openapi-typescript openapi.json --default-non-nullable false -o src/synpath.
139
150
 
140
151
  ## Documentation
141
152
 
142
- - [CLI](https://synpath.dev/docs/quickstart): hosted data API sign-in and keys versus local venue trading server setup
143
- - [Unified API](https://synpath.dev/docs/sdks/python): methods, data structures, identifiers, paging, status, errors
144
- - [Capabilities](https://synpath.dev/docs/concepts/exchanges): what each venue can and cannot answer
145
- - [HTTP server](https://synpath.dev/docs/api-reference): routes, envelopes, typed client generation, trading routes with per-account keys, mounting behind your own auth
146
- - [Trading](https://synpath.dev/docs/concepts/orders): credentials, `Decimal` money, order entry on Kalshi, Polymarket and Polymarket US
147
- - [Streaming](https://synpath.dev/docs/ws-api-reference): WebSocket and gRPC books, trades, orders and fills as self-healing event streams
148
- - [Engine](docs/engine.md): a journal written before anything is sent, pre-trade risk, a ledger, reconciliation, a kill switch, the order types the venues do not hold, buckets that route one order across venues, paper trading
149
- - [TypeScript client](https://synpath.dev/docs/sdks/typescript): generate a typed client from the OpenAPI document, place through cancel without Python
153
+ See the [API Reference](https://www.synpath.dev/docs) for detailed documentation and more examples.
150
154
 
151
155
  ## Development
152
156
 
153
157
  ```bash
154
158
  git clone https://github.com/Synpath-ai/synpath
155
159
  cd synpath
156
- pip install -e ".[dev]"
160
+ pip install -e ".[dev]" # builds the Rust core too: needs a Rust toolchain (rustup.rs)
157
161
 
158
162
  pytest # offline, against recorded venue payloads
159
163
  pytest -m live # market data against the real venues
160
164
  pytest -m demo # order entry on a venue's demo environment
165
+ SYNPATH_PURE_PYTHON=1 pytest # the same tests on the pure-Python fallback
166
+ cargo test -p synpath-core # the Rust core on its own
161
167
  ```
162
168
 
169
+ The Rust core lives in `crates/synpath-core` (pure Rust) and
170
+ `bindings/python` (its PyO3 wrapper, built as `synpath._core`). Every class
171
+ it provides has a pure-Python twin with the same interface, and the library
172
+ uses the twin when the extension is not built. Venue adapters are plain
173
+ Python: adding a venue needs no Rust.
174
+
163
175
  The `demo` tests place and cancel real orders on a demo exchange with the
164
176
  credentials in your environment, and leave the account flat. `python -m
165
177
  synpath.trading doctor` says which venues are configured without printing a
@@ -167,7 +179,7 @@ secret.
167
179
 
168
180
  ## Prior Art
169
181
 
170
- [ccxt](https://github.com/ccxt/ccxt) set the conventions this library follows. [pmxt](https://github.com/pmxt-dev/pmxt) got to prediction markets first.
182
+ [ccxt](https://github.com/ccxt/ccxt) set the conventions this library follows.
171
183
 
172
184
  ## License
173
185