architect-py 3.2.0__tar.gz → 3.2.2__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 (150) hide show
  1. architect_py-3.2.2/PKG-INFO +191 -0
  2. architect_py-3.2.2/README.md +166 -0
  3. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/__init__.py +1 -1
  4. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/async_client.py +23 -13
  5. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/client.py +16 -12
  6. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/client_protocol.py +3 -2
  7. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/__init__.py +0 -3
  8. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/client.py +1 -20
  9. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/user_id_query.py +1 -0
  10. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Cpty/CptyRequest.py +4 -3
  11. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Cpty/CptyResponse.py +20 -3
  12. architect_py-3.2.2/architect_py/grpc_client/Cpty/CptyStatus.py +48 -0
  13. architect_py-3.2.2/architect_py/grpc_client/Cpty/CptyStatusRequest.py +45 -0
  14. architect_py-3.2.2/architect_py/grpc_client/Cpty/CptysRequest.py +37 -0
  15. architect_py-3.2.2/architect_py/grpc_client/Cpty/CptysResponse.py +27 -0
  16. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Folio/AccountSummary.py +28 -3
  17. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Health/HealthCheckRequest.py +4 -1
  18. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Health/HealthCheckResponse.py +6 -1
  19. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/Ticker.py +13 -2
  20. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Oms/Order.py +12 -1
  21. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Orderflow/OrderflowRequest.py +1 -0
  22. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/definitions.py +117 -66
  23. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/grpc_client.py +27 -29
  24. architect_py-3.2.2/architect_py/grpc_client/grpc_server.py +54 -0
  25. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/scalars.py +7 -7
  26. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/tests/conftest.py +13 -2
  27. architect_py-3.2.2/architect_py/tests/test_accounts.py +31 -0
  28. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/tests/test_order_sending.py +9 -5
  29. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/tests/test_subscriptions.py +11 -9
  30. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/tests/test_symbology.py +9 -2
  31. {architect_py-3.2.0 → architect_py-3.2.2}/pyproject.toml +2 -4
  32. architect_py-3.2.0/PKG-INFO +0 -213
  33. architect_py-3.2.0/README.md +0 -187
  34. {architect_py-3.2.0 → architect_py-3.2.2}/LICENSE +0 -0
  35. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/base_model.py +0 -0
  36. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/cancel_all_orders_mutation.py +0 -0
  37. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/cancel_order_mutation.py +0 -0
  38. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/create_jwt.py +0 -0
  39. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/enums.py +0 -0
  40. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/exceptions.py +0 -0
  41. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/fragments.py +0 -0
  42. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_account_history_query.py +0 -0
  43. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_account_query.py +0 -0
  44. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_account_summaries_query.py +0 -0
  45. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_account_summary_query.py +0 -0
  46. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_candle_snapshot_query.py +0 -0
  47. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_execution_info_query.py +0 -0
  48. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_execution_infos_query.py +0 -0
  49. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_fills_query.py +0 -0
  50. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_first_notice_date_query.py +0 -0
  51. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_future_series_query.py +0 -0
  52. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_historical_orders_query.py +0 -0
  53. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_l_1_book_snapshot_query.py +0 -0
  54. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_l_1_book_snapshots_query.py +0 -0
  55. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_l_2_book_snapshot_query.py +0 -0
  56. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_market_status_query.py +0 -0
  57. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_open_orders_query.py +0 -0
  58. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_product_info_query.py +0 -0
  59. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/get_product_infos_query.py +0 -0
  60. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/input_types.py +0 -0
  61. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/juniper_base_client.py +0 -0
  62. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/list_accounts_query.py +0 -0
  63. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/place_order_mutation.py +0 -0
  64. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/search_symbols_query.py +0 -0
  65. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/subscribe_candles.py +0 -0
  66. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/subscribe_orderflow.py +0 -0
  67. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/subscribe_trades.py +0 -0
  68. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/graphql_client/user_email_query.py +0 -0
  69. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Accounts/AccountsRequest.py +0 -0
  70. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Accounts/AccountsResponse.py +0 -0
  71. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Accounts/__init__.py +0 -0
  72. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Algo/AlgoOrderForTwapAlgo.py +0 -0
  73. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Algo/CreateAlgoOrderRequestForTwapAlgo.py +0 -0
  74. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Algo/ModifyAlgoOrderRequestForTwapAlgo.py +0 -0
  75. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Algo/__init__.py +0 -0
  76. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Cpty/__init__.py +0 -0
  77. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Folio/AccountHistoryRequest.py +0 -0
  78. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Folio/AccountHistoryResponse.py +0 -0
  79. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Folio/AccountSummariesRequest.py +0 -0
  80. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Folio/AccountSummariesResponse.py +0 -0
  81. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Folio/AccountSummaryRequest.py +0 -0
  82. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Folio/HistoricalFillsRequest.py +0 -0
  83. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Folio/HistoricalFillsResponse.py +0 -0
  84. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Folio/HistoricalOrdersRequest.py +0 -0
  85. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Folio/HistoricalOrdersResponse.py +0 -0
  86. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Folio/__init__.py +0 -0
  87. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Health/__init__.py +0 -0
  88. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/ArrayOfL1BookSnapshot.py +0 -0
  89. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/Candle.py +0 -0
  90. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/HistoricalCandlesRequest.py +0 -0
  91. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/HistoricalCandlesResponse.py +0 -0
  92. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/L1BookSnapshot.py +0 -0
  93. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/L1BookSnapshotRequest.py +0 -0
  94. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/L1BookSnapshotsRequest.py +0 -0
  95. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/L2BookSnapshot.py +0 -0
  96. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/L2BookSnapshotRequest.py +0 -0
  97. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/L2BookUpdate.py +0 -0
  98. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/Liquidation.py +0 -0
  99. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/MarketStatus.py +0 -0
  100. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/MarketStatusRequest.py +0 -0
  101. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/SubscribeCandlesRequest.py +0 -0
  102. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/SubscribeCurrentCandlesRequest.py +0 -0
  103. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/SubscribeL1BookSnapshotsRequest.py +0 -0
  104. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/SubscribeL2BookUpdatesRequest.py +0 -0
  105. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/SubscribeLiquidationsRequest.py +0 -0
  106. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/SubscribeManyCandlesRequest.py +0 -0
  107. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/SubscribeTickersRequest.py +0 -0
  108. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/SubscribeTradesRequest.py +0 -0
  109. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/TickerRequest.py +0 -0
  110. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/TickerUpdate.py +0 -0
  111. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/TickersRequest.py +0 -0
  112. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/TickersResponse.py +0 -0
  113. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/Trade.py +0 -0
  114. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Marketdata/__init__.py +0 -0
  115. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Oms/Cancel.py +0 -0
  116. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Oms/CancelAllOrdersRequest.py +0 -0
  117. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Oms/CancelAllOrdersResponse.py +0 -0
  118. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Oms/CancelOrderRequest.py +0 -0
  119. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Oms/OpenOrdersRequest.py +0 -0
  120. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Oms/OpenOrdersResponse.py +0 -0
  121. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Oms/PendingCancelsRequest.py +0 -0
  122. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Oms/PendingCancelsResponse.py +0 -0
  123. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Oms/PlaceOrderRequest.py +0 -0
  124. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Oms/__init__.py +0 -0
  125. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Orderflow/Dropcopy.py +0 -0
  126. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Orderflow/DropcopyRequest.py +0 -0
  127. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Orderflow/Orderflow.py +0 -0
  128. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Orderflow/SubscribeOrderflowRequest.py +0 -0
  129. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Orderflow/__init__.py +0 -0
  130. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Symbology/PruneExpiredSymbolsRequest.py +0 -0
  131. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Symbology/PruneExpiredSymbolsResponse.py +0 -0
  132. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Symbology/SubscribeSymbology.py +0 -0
  133. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Symbology/SymbologyRequest.py +0 -0
  134. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Symbology/SymbologySnapshot.py +0 -0
  135. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Symbology/SymbologyUpdate.py +0 -0
  136. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Symbology/SymbolsRequest.py +0 -0
  137. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Symbology/SymbolsResponse.py +0 -0
  138. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Symbology/UploadSymbologyRequest.py +0 -0
  139. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Symbology/UploadSymbologyResponse.py +0 -0
  140. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/Symbology/__init__.py +0 -0
  141. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/grpc_client/__init__.py +0 -0
  142. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/tests/__init__.py +0 -0
  143. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/tests/test_book_building.py +0 -0
  144. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/tests/test_client.py +0 -0
  145. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/tests/test_grpc_client.py +0 -0
  146. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/tests/test_rounding.py +0 -0
  147. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/tests/test_snapshots.py +0 -0
  148. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/utils/nearest_tick.py +0 -0
  149. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/utils/nearest_tick_2.py +0 -0
  150. {architect_py-3.2.0 → architect_py-3.2.2}/architect_py/utils/price_bands.py +0 -0
@@ -0,0 +1,191 @@
1
+ Metadata-Version: 2.3
2
+ Name: architect-py
3
+ Version: 3.2.2
4
+ Summary: Client library for the Architect trading platform.
5
+ Author: Architect Financial Technologies, Inc.
6
+ Author-email: hello@architect.xyz
7
+ Requires-Python: >=3.10,<4
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: License :: OSI Approved :: Apache Software License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Requires-Dist: asyncio (>=3)
17
+ Requires-Dist: dnspython (>=2.0)
18
+ Requires-Dist: gql[httpx] (>=3.5.0,<4.0.0)
19
+ Requires-Dist: grpcio (>=1.66.1)
20
+ Requires-Dist: msgspec (>=0.19,<0.20)
21
+ Requires-Dist: pydantic (>=2.10,<3.0)
22
+ Requires-Dist: websockets (>=11)
23
+ Description-Content-Type: text/markdown
24
+
25
+ # [![Architect](https://avatars.githubusercontent.com/u/116864654?s=29&v=2)](https://architect.co) architect_py
26
+ [![PyPI version](https://img.shields.io/pypi/v/architect-py.svg)](https://pypi.org/project/architect-py/)
27
+
28
+ A Python API for [Architect](https://architect.co).
29
+
30
+ Just some of the features of this API:
31
+ symbology, market snapshots, past trades, account queries, order management (including sending advanced algos!), and market feed subscriptions.
32
+
33
+ This repo heavily uses type hinting, so using a type checker such as Pylance or mypy is suggestible to reduce potential for error.
34
+
35
+
36
+ ## Example usage
37
+
38
+ `AsyncClient` and `Client` are the entryways into making calls to the Architect backend.
39
+ Note that the sync `Client` does not have access to any subscription functions, because they are async by nature.
40
+
41
+
42
+ ```python
43
+ import asyncio
44
+
45
+ from architect_py.async_client import AsyncClient
46
+ from architect_py.scalars import TradableProduct
47
+
48
+ async def main():
49
+ c = await AsyncClient.connect(
50
+ host="<your installation domain>", # e.g. app.architect.co for the brokerage
51
+ api_key="<api key>",
52
+ api_secret="<api secret>"
53
+ paper_trading=True,
54
+ )
55
+ print(await c.who_am_i())
56
+
57
+ series = await async_client.get_cme_futures_series("ES CME Futures")
58
+ front_ES_future = series[0][1]
59
+
60
+ s = c.subscribe_trades_stream(front_ES_future)
61
+ async for trade in s:
62
+ print(trade)
63
+
64
+ asyncio.run(main())
65
+ ```
66
+
67
+ ```python
68
+ from architect_py.client import Client
69
+
70
+ def main():
71
+ c = Client(
72
+ host="<your installation domain>",
73
+ api_key="<api key>",
74
+ api_secret="<api secret>"
75
+ paper_trading=True,
76
+ )
77
+ print(c.who_am_i())
78
+
79
+ print(client.get_account_summaries())
80
+
81
+ print(client.search_symbols("ES"))
82
+ ```
83
+
84
+ While the AsyncClient is the recommended way to use the Architect API, the Client instead without any familiarity with `async/await`.
85
+ The sync clients and async clients usage is identical, except one removes the `await` before the call. The only exception to this is that the sync client does not support any subscriptions, because they are inherently asynchronous.
86
+
87
+ Check the `examples` folder or the `architect_py/tests` folders for example usages.
88
+
89
+
90
+ ## Function Breakdown
91
+
92
+
93
+ The `async` client has the following functions
94
+
95
+ ### 🚀 Initialization
96
+
97
+ - **`connect`**: The main way to create an AsyncClient object.
98
+ - **`__init__`**: Users should not be using this constructor directly, unless they do not want to use any subscription methods.
99
+
100
+ ---
101
+
102
+ ### 🔍 Symbology
103
+
104
+ - **`search_symbols`**: Search for symbols in the Architect database.
105
+ - **`get_product_info`**: Get the product information (product_type, underlying, multiplier, etc.) for a symbol.
106
+ - **`get_product_infos`**: Get the product information (product_type, underlying, multiplier, etc.) for a list of symbols.
107
+ - **`get_execution_info`**: Get the execution information (tick_size, step_size, margin, etc.) for a symbol.
108
+ - **`get_execution_infos`**: Get the execution information (tick_size, step_size, etc.) for a list of symbols.
109
+ - **`get_cme_first_notice_date`**: Get the first notice date for a CME future.
110
+ - **`get_future_series`**: Get the series of futures for a given series symbol.
111
+ - **`get_expiration_from_CME_name`**: Get the expiration date from a CME future name.
112
+ - **`get_cme_futures_series`**: Get the futures in a series from the CME.
113
+ - **`get_cme_future_from_root_month_year`**: Get the symbol for a CME future from the root, month, and year.
114
+
115
+ ---
116
+
117
+ ### 👤 Account Management
118
+
119
+ - **`who_am_i`**: Gets the user_id and user_email for the user that the API key belongs to.
120
+ - **`list_accounts`**: List accounts for the user that the API key belongs to.
121
+ - **`get_account_summary`**: Gets the account summary for the given account.
122
+ - **`get_account_summaries`**: Gets the account summaries for the given accounts and trader.
123
+ - **`get_account_history`**: Gets the account history for the given account and dates.
124
+
125
+ ---
126
+
127
+ ### 📑 Order Management
128
+
129
+ - **`get_open_orders`**: Returns a list of open orders for the user that match the filters.
130
+ - **`get_all_open_orders`**: Returns a list of all open orders for the user.
131
+ - **`get_historical_orders`**: Gets the historical orders that match the filters.
132
+ - **`get_order`**: Returns the OrderFields object for the specified order.
133
+ - **`get_orders`**: Returns a list of OrderFields objects for the specified orders.
134
+ - **`get_fills`**: Returns a list of fills for the given filters.
135
+
136
+ ---
137
+
138
+ ### 📈 Market Data
139
+
140
+ - **`get_market_status`**: Returns market status for symbol (ie if it is quoting and trading).
141
+ - **`get_market_snapshot`**: This is an alias for l1_book_snapshot.
142
+ - **`get_market_snapshots`**: This is an alias for l1_book_snapshot.
143
+ - **`get_historical_candles`**: Gets the historical candles for a symbol.
144
+ - **`get_l1_book_snapshot`**: Gets the L1 book snapshot for a symbol.
145
+ - **`get_l1_book_snapshots`**: Gets the L1 book snapshots for a list of symbols.
146
+ - **`get_l2_book_snapshot`**: Gets the L2 book snapshot for a symbol.
147
+ - **`subscribe_l1_book_stream`**: Subscribe to the stream of L1BookSnapshots for a symbol.
148
+ - **`subscribe_l2_book_stream`**: Subscribe to the stream of L2BookUpdates for a symbol.
149
+ - **`subscribe_l1_book`**: Returns a L1BookSnapshot object that is constantly updating in the background.
150
+ - **`subscribe_l2_book`**: Returns a L2BookSnapshot object that is constantly updating in the background.
151
+ - **`subscribe_trades_stream`**: Subscribe to a stream of trades for a symbol.
152
+ - **`subscribe_candles_stream`**: Subscribe to a stream of candles for a symbol.
153
+
154
+ ---
155
+
156
+ ### 📝 Order Entry and Cancellation
157
+
158
+ - **`send_limit_order`**: Sends a regular limit order.
159
+ - **`send_market_pro_order`**: Sends a market-order like limit price based on the BBO.
160
+ - **`cancel_order`**: Cancels an order by order id.
161
+ - **`cancel_all_orders`**: Cancels all open orders.
162
+
163
+
164
+ ### Running examples from this package
165
+
166
+ Clone this repository to run examples in the `examples` directory. This package
167
+ uses poetry for dependency management. To enter a poetry virtual environment, make
168
+ sure you have [poetry](https://python-poetry.org/docs/) installed and run the
169
+ following from the repository root.
170
+
171
+ ```bash
172
+ poetry shell
173
+ poetry install --sync
174
+
175
+ export ARCHITECT_HOST="<your installation domain>"
176
+ export ARCHITECT_API_KEY="<api key>"
177
+ export ARCHITECT_API_SECRET="<api secret>"
178
+
179
+ python -m examples.trades
180
+ ```
181
+
182
+ You can exit the poetry shell by running `exit`. Environment variables set
183
+ within the shell are not persisted.
184
+
185
+
186
+ ## API keys for the brokerage
187
+
188
+ API keys/secrets for the brokerage can be generated on the [user account page](https://app.architect.co/user/account).
189
+
190
+
191
+
@@ -0,0 +1,166 @@
1
+ # [![Architect](https://avatars.githubusercontent.com/u/116864654?s=29&v=2)](https://architect.co) architect_py
2
+ [![PyPI version](https://img.shields.io/pypi/v/architect-py.svg)](https://pypi.org/project/architect-py/)
3
+
4
+ A Python API for [Architect](https://architect.co).
5
+
6
+ Just some of the features of this API:
7
+ symbology, market snapshots, past trades, account queries, order management (including sending advanced algos!), and market feed subscriptions.
8
+
9
+ This repo heavily uses type hinting, so using a type checker such as Pylance or mypy is suggestible to reduce potential for error.
10
+
11
+
12
+ ## Example usage
13
+
14
+ `AsyncClient` and `Client` are the entryways into making calls to the Architect backend.
15
+ Note that the sync `Client` does not have access to any subscription functions, because they are async by nature.
16
+
17
+
18
+ ```python
19
+ import asyncio
20
+
21
+ from architect_py.async_client import AsyncClient
22
+ from architect_py.scalars import TradableProduct
23
+
24
+ async def main():
25
+ c = await AsyncClient.connect(
26
+ host="<your installation domain>", # e.g. app.architect.co for the brokerage
27
+ api_key="<api key>",
28
+ api_secret="<api secret>"
29
+ paper_trading=True,
30
+ )
31
+ print(await c.who_am_i())
32
+
33
+ series = await async_client.get_cme_futures_series("ES CME Futures")
34
+ front_ES_future = series[0][1]
35
+
36
+ s = c.subscribe_trades_stream(front_ES_future)
37
+ async for trade in s:
38
+ print(trade)
39
+
40
+ asyncio.run(main())
41
+ ```
42
+
43
+ ```python
44
+ from architect_py.client import Client
45
+
46
+ def main():
47
+ c = Client(
48
+ host="<your installation domain>",
49
+ api_key="<api key>",
50
+ api_secret="<api secret>"
51
+ paper_trading=True,
52
+ )
53
+ print(c.who_am_i())
54
+
55
+ print(client.get_account_summaries())
56
+
57
+ print(client.search_symbols("ES"))
58
+ ```
59
+
60
+ While the AsyncClient is the recommended way to use the Architect API, the Client instead without any familiarity with `async/await`.
61
+ The sync clients and async clients usage is identical, except one removes the `await` before the call. The only exception to this is that the sync client does not support any subscriptions, because they are inherently asynchronous.
62
+
63
+ Check the `examples` folder or the `architect_py/tests` folders for example usages.
64
+
65
+
66
+ ## Function Breakdown
67
+
68
+
69
+ The `async` client has the following functions
70
+
71
+ ### 🚀 Initialization
72
+
73
+ - **`connect`**: The main way to create an AsyncClient object.
74
+ - **`__init__`**: Users should not be using this constructor directly, unless they do not want to use any subscription methods.
75
+
76
+ ---
77
+
78
+ ### 🔍 Symbology
79
+
80
+ - **`search_symbols`**: Search for symbols in the Architect database.
81
+ - **`get_product_info`**: Get the product information (product_type, underlying, multiplier, etc.) for a symbol.
82
+ - **`get_product_infos`**: Get the product information (product_type, underlying, multiplier, etc.) for a list of symbols.
83
+ - **`get_execution_info`**: Get the execution information (tick_size, step_size, margin, etc.) for a symbol.
84
+ - **`get_execution_infos`**: Get the execution information (tick_size, step_size, etc.) for a list of symbols.
85
+ - **`get_cme_first_notice_date`**: Get the first notice date for a CME future.
86
+ - **`get_future_series`**: Get the series of futures for a given series symbol.
87
+ - **`get_expiration_from_CME_name`**: Get the expiration date from a CME future name.
88
+ - **`get_cme_futures_series`**: Get the futures in a series from the CME.
89
+ - **`get_cme_future_from_root_month_year`**: Get the symbol for a CME future from the root, month, and year.
90
+
91
+ ---
92
+
93
+ ### 👤 Account Management
94
+
95
+ - **`who_am_i`**: Gets the user_id and user_email for the user that the API key belongs to.
96
+ - **`list_accounts`**: List accounts for the user that the API key belongs to.
97
+ - **`get_account_summary`**: Gets the account summary for the given account.
98
+ - **`get_account_summaries`**: Gets the account summaries for the given accounts and trader.
99
+ - **`get_account_history`**: Gets the account history for the given account and dates.
100
+
101
+ ---
102
+
103
+ ### 📑 Order Management
104
+
105
+ - **`get_open_orders`**: Returns a list of open orders for the user that match the filters.
106
+ - **`get_all_open_orders`**: Returns a list of all open orders for the user.
107
+ - **`get_historical_orders`**: Gets the historical orders that match the filters.
108
+ - **`get_order`**: Returns the OrderFields object for the specified order.
109
+ - **`get_orders`**: Returns a list of OrderFields objects for the specified orders.
110
+ - **`get_fills`**: Returns a list of fills for the given filters.
111
+
112
+ ---
113
+
114
+ ### 📈 Market Data
115
+
116
+ - **`get_market_status`**: Returns market status for symbol (ie if it is quoting and trading).
117
+ - **`get_market_snapshot`**: This is an alias for l1_book_snapshot.
118
+ - **`get_market_snapshots`**: This is an alias for l1_book_snapshot.
119
+ - **`get_historical_candles`**: Gets the historical candles for a symbol.
120
+ - **`get_l1_book_snapshot`**: Gets the L1 book snapshot for a symbol.
121
+ - **`get_l1_book_snapshots`**: Gets the L1 book snapshots for a list of symbols.
122
+ - **`get_l2_book_snapshot`**: Gets the L2 book snapshot for a symbol.
123
+ - **`subscribe_l1_book_stream`**: Subscribe to the stream of L1BookSnapshots for a symbol.
124
+ - **`subscribe_l2_book_stream`**: Subscribe to the stream of L2BookUpdates for a symbol.
125
+ - **`subscribe_l1_book`**: Returns a L1BookSnapshot object that is constantly updating in the background.
126
+ - **`subscribe_l2_book`**: Returns a L2BookSnapshot object that is constantly updating in the background.
127
+ - **`subscribe_trades_stream`**: Subscribe to a stream of trades for a symbol.
128
+ - **`subscribe_candles_stream`**: Subscribe to a stream of candles for a symbol.
129
+
130
+ ---
131
+
132
+ ### 📝 Order Entry and Cancellation
133
+
134
+ - **`send_limit_order`**: Sends a regular limit order.
135
+ - **`send_market_pro_order`**: Sends a market-order like limit price based on the BBO.
136
+ - **`cancel_order`**: Cancels an order by order id.
137
+ - **`cancel_all_orders`**: Cancels all open orders.
138
+
139
+
140
+ ### Running examples from this package
141
+
142
+ Clone this repository to run examples in the `examples` directory. This package
143
+ uses poetry for dependency management. To enter a poetry virtual environment, make
144
+ sure you have [poetry](https://python-poetry.org/docs/) installed and run the
145
+ following from the repository root.
146
+
147
+ ```bash
148
+ poetry shell
149
+ poetry install --sync
150
+
151
+ export ARCHITECT_HOST="<your installation domain>"
152
+ export ARCHITECT_API_KEY="<api key>"
153
+ export ARCHITECT_API_SECRET="<api secret>"
154
+
155
+ python -m examples.trades
156
+ ```
157
+
158
+ You can exit the poetry shell by running `exit`. Environment variables set
159
+ within the shell are not persisted.
160
+
161
+
162
+ ## API keys for the brokerage
163
+
164
+ API keys/secrets for the brokerage can be generated on the [user account page](https://app.architect.co/user/account).
165
+
166
+
@@ -1,2 +1,2 @@
1
- __version__ = "3.2.0"
1
+ __version__ = "3.2.2"
2
2
  # this is automatically updated by poetry-dynamic-versioning, see README.md
@@ -15,6 +15,7 @@ The individual graphql types are subject to change, so it is not recommended to
15
15
  """
16
16
 
17
17
  import asyncio
18
+ import functools
18
19
  import logging
19
20
  from datetime import date, datetime
20
21
  from decimal import Decimal
@@ -160,9 +161,9 @@ class AsyncClient:
160
161
  **kwargs: Any,
161
162
  ):
162
163
  """
163
- Users should not be using this constructor directly, unless they do not want to use any subscription methods.
164
+ Users should essentially never be using this constructor directly.
164
165
 
165
- Use the create method instead.
166
+ Use the connect method instead.
166
167
  See self.connect for arg explanations
167
168
  """
168
169
 
@@ -198,6 +199,14 @@ class AsyncClient:
198
199
  api_key=api_key, api_secret=api_secret, host=host, port=_port, **kwargs
199
200
  )
200
201
 
202
+ async def enable_orderflow(self):
203
+ """
204
+ Load and cache product and execution info so that the SDK can send orders.
205
+
206
+ CR alee: determine if this is better than @functools.lru_cache
207
+ """
208
+ pass
209
+
201
210
  # ------------------------------------------------------------
202
211
  # Symbology
203
212
  # ------------------------------------------------------------
@@ -425,9 +434,8 @@ class AsyncClient:
425
434
  (user_id, user_email)
426
435
  """
427
436
  user_id = await self.graphql_client.user_id_query()
428
- email = await self.graphql_client.user_email_query()
429
437
 
430
- return user_id.user_id, email.user_email
438
+ return user_id.user_id, user_id.user_email
431
439
 
432
440
  async def list_accounts(self) -> Sequence[AccountWithPermissionsFields]:
433
441
  """
@@ -736,15 +744,15 @@ class AsyncClient:
736
744
  Returns:
737
745
  a list of CandleFields for the specified candles
738
746
  """
739
-
740
- return await self.grpc_client.request(
741
- HistoricalCandlesRequest,
747
+ request = HistoricalCandlesRequest(
742
748
  symbol=symbol,
743
749
  candle_width=candle_width,
744
750
  start_date=start,
745
751
  end_date=end,
746
752
  )
747
753
 
754
+ return await self.grpc_client.request(request)
755
+
748
756
  async def get_l1_book_snapshot(
749
757
  self,
750
758
  symbol: str,
@@ -921,9 +929,8 @@ class AsyncClient:
921
929
  """
922
930
  Subscribe to a stream of trades for a symbol.
923
931
  """
924
- return self.grpc_client.subscribe(
925
- SubscribeTradesRequest, symbol=symbol, venue=venue
926
- )
932
+ request = SubscribeTradesRequest(symbol=symbol, venue=venue)
933
+ return self.grpc_client.subscribe(request)
927
934
 
928
935
  def subscribe_candles_stream(
929
936
  self,
@@ -934,12 +941,12 @@ class AsyncClient:
934
941
  """
935
942
  Subscribe to a stream of candles for a symbol.
936
943
  """
937
- return self.grpc_client.subscribe(
938
- SubscribeCandlesRequest,
944
+ request = SubscribeCandlesRequest(
939
945
  symbol=str(symbol),
940
946
  venue=venue,
941
947
  candle_widths=candle_widths,
942
948
  )
949
+ return self.grpc_client.subscribe(request)
943
950
 
944
951
  # ------------------------------------------------------------
945
952
  # Order Entry and Cancellation
@@ -948,6 +955,7 @@ class AsyncClient:
948
955
  async def send_limit_order(
949
956
  self,
950
957
  *,
958
+ id: Optional[str] = None,
951
959
  symbol: TradableProduct,
952
960
  execution_venue: Optional[str],
953
961
  odir: OrderDir,
@@ -1026,7 +1034,7 @@ class AsyncClient:
1026
1034
  quantity,
1027
1035
  order_type,
1028
1036
  time_in_force,
1029
- None,
1037
+ id,
1030
1038
  trader,
1031
1039
  account,
1032
1040
  limit_price,
@@ -1041,6 +1049,7 @@ class AsyncClient:
1041
1049
  async def send_market_pro_order(
1042
1050
  self,
1043
1051
  *,
1052
+ id: Optional[str] = None,
1044
1053
  symbol: TradableProduct,
1045
1054
  execution_venue: str,
1046
1055
  odir: OrderDir,
@@ -1117,6 +1126,7 @@ class AsyncClient:
1117
1126
  limit_price = tick_round_method(limit_price, tick_size)
1118
1127
 
1119
1128
  return await self.send_limit_order(
1129
+ id=id,
1120
1130
  symbol=symbol,
1121
1131
  execution_venue=execution_venue,
1122
1132
  odir=odir,
@@ -24,6 +24,8 @@ class Client(AsyncClientProtocol):
24
24
  This class is a wrapper around the AsyncClient class that allows you to call async methods synchronously.
25
25
  This does not work for subscription based methods.
26
26
 
27
+ This Client takes control of the event loop, which you can pass in.
28
+
27
29
  One can find the function definition in the AsyncClient class.
28
30
 
29
31
  The AsyncClient is more performant and powerful, so it is recommended to use that class if possible.
@@ -48,18 +50,6 @@ class Client(AsyncClientProtocol):
48
50
  loop: Optional[AbstractEventLoop] = None,
49
51
  **kwargs,
50
52
  ):
51
- super().__setattr__(
52
- "client",
53
- AsyncClient(
54
- api_key=api_key,
55
- api_secret=api_secret,
56
- host=host,
57
- paper_trading=paper_trading,
58
- _i_know_what_i_am_doing=True,
59
- **kwargs,
60
- ),
61
- )
62
-
63
53
  if loop is None:
64
54
  try:
65
55
  loop = asyncio.get_running_loop()
@@ -68,6 +58,20 @@ class Client(AsyncClientProtocol):
68
58
  asyncio.set_event_loop(loop)
69
59
  super().__setattr__("_loop", loop)
70
60
 
61
+ async_client = loop.run_until_complete(
62
+ AsyncClient.connect(
63
+ api_key=api_key,
64
+ api_secret=api_secret,
65
+ host=host,
66
+ paper_trading=paper_trading,
67
+ **kwargs,
68
+ )
69
+ )
70
+ super().__setattr__(
71
+ "client",
72
+ async_client,
73
+ )
74
+
71
75
  if "ipykernel" in sys.modules:
72
76
  # for jupyter notebooks
73
77
  import atexit
@@ -19,6 +19,7 @@ class AsyncClientProtocol:
19
19
  def cancel_order(self, order_id: str) -> CancelFields: ...
20
20
  @staticmethod
21
21
  def connect(*, api_key: str, api_secret: str, paper_trading: bool, host: str = 'app.architect.co', grpc_endpoint: str = 'cme.marketdata.architect.co', _port: Optional[int] = None, **kwargs: Any) -> AsyncClient: ...
22
+ def enable_orderflow(self) -> Any: ...
22
23
  def get_account_history(self, account: str, from_inclusive: Optional[datetime] = None, to_exclusive: Optional[datetime] = None) -> Sequence[AccountSummaryFields]: ...
23
24
  def get_account_summaries(self, accounts: Optional[list[str]] = None, trader: Optional[str] = None) -> Sequence[AccountSummaryFields]: ...
24
25
  def get_account_summary(self, account: str) -> AccountSummaryFields: ...
@@ -47,6 +48,6 @@ class AsyncClientProtocol:
47
48
  def get_product_infos(self, symbols: Optional[list[str]]) -> Sequence[ProductInfoFields]: ...
48
49
  def list_accounts(self) -> Sequence[AccountWithPermissionsFields]: ...
49
50
  def search_symbols(self, search_string: Optional[str] = None, execution_venue: Optional[str] = None, offset: int = 0, limit: int = 20) -> list[TradableProduct]: ...
50
- def send_limit_order(self, *, symbol: TradableProduct, execution_venue: Optional[str], odir: OrderDir, quantity: Decimal, limit_price: Decimal, order_type: OrderType = OrderType.LIMIT, time_in_force: TimeInForce = TimeInForce.DAY, good_til_date: Optional[datetime] = None, price_round_method: Optional[TickRoundMethod] = None, account: Optional[str] = None, trader: Optional[str] = None, post_only: bool = False, trigger_price: Optional[Decimal] = None) -> OrderFields: ...
51
- def send_market_pro_order(self, *, symbol: TradableProduct, execution_venue: str, odir: OrderDir, quantity: Decimal, time_in_force: TimeInForce = TimeInForce.DAY, account: Optional[str] = None, fraction_through_market: Decimal = Decimal('0.001')) -> OrderFields: ...
51
+ def send_limit_order(self, *, id: Optional[str] = None, symbol: TradableProduct, execution_venue: Optional[str], odir: OrderDir, quantity: Decimal, limit_price: Decimal, order_type: OrderType = OrderType.LIMIT, time_in_force: TimeInForce = TimeInForce.DAY, good_til_date: Optional[datetime] = None, price_round_method: Optional[TickRoundMethod] = None, account: Optional[str] = None, trader: Optional[str] = None, post_only: bool = False, trigger_price: Optional[Decimal] = None) -> OrderFields: ...
52
+ def send_market_pro_order(self, *, id: Optional[str] = None, symbol: TradableProduct, execution_venue: str, odir: OrderDir, quantity: Decimal, time_in_force: TimeInForce = TimeInForce.DAY, account: Optional[str] = None, fraction_through_market: Decimal = Decimal('0.001')) -> OrderFields: ...
52
53
  def who_am_i(self) -> tuple[str, str]: ...
@@ -160,7 +160,6 @@ from .subscribe_orderflow import (
160
160
  SubscribeOrderflowOrderflowOrderStale,
161
161
  )
162
162
  from .subscribe_trades import SubscribeTrades, SubscribeTradesTrades
163
- from .user_email_query import UserEmailQuery, UserEmailQueryUser
164
163
  from .user_id_query import UserIdQuery, UserIdQueryUser
165
164
 
166
165
  __all__ = [
@@ -282,8 +281,6 @@ __all__ = [
282
281
  "SubscribeTradesTrades",
283
282
  "TimeInForce",
284
283
  "Upload",
285
- "UserEmailQuery",
286
- "UserEmailQueryUser",
287
284
  "UserIdQuery",
288
285
  "UserIdQueryUser",
289
286
  ]
@@ -58,7 +58,6 @@ if TYPE_CHECKING:
58
58
  SubscribeOrderflowOrderflowOrderStale,
59
59
  )
60
60
  from .subscribe_trades import SubscribeTradesTrades
61
- from .user_email_query import UserEmailQueryUser
62
61
  from .user_id_query import UserIdQueryUser
63
62
 
64
63
 
@@ -75,6 +74,7 @@ class GraphQLClient(JuniperBaseClient):
75
74
  query UserIdQuery {
76
75
  user {
77
76
  userId
77
+ userEmail
78
78
  }
79
79
  }
80
80
  """
@@ -86,25 +86,6 @@ class GraphQLClient(JuniperBaseClient):
86
86
  data = self.get_data(response)
87
87
  return UserIdQuery.model_validate(data).user
88
88
 
89
- async def user_email_query(self, **kwargs: Any) -> "UserEmailQueryUser":
90
- from .user_email_query import UserEmailQuery
91
-
92
- query = gql(
93
- """
94
- query UserEmailQuery {
95
- user {
96
- userEmail
97
- }
98
- }
99
- """
100
- )
101
- variables: Dict[str, object] = {}
102
- response = await self.execute(
103
- query=query, operation_name="UserEmailQuery", variables=variables, **kwargs
104
- )
105
- data = self.get_data(response)
106
- return UserEmailQuery.model_validate(data).user
107
-
108
89
  async def search_symbols_query(
109
90
  self,
110
91
  search_string: Union[Optional[str], "UnsetType"] = UNSET,
@@ -12,6 +12,7 @@ class UserIdQuery(BaseModel):
12
12
 
13
13
  class UserIdQueryUser(BaseModel):
14
14
  user_id: str = Field(alias="userId")
15
+ user_email: str = Field(alias="userEmail")
15
16
 
16
17
 
17
18
  UserIdQuery.model_rebuild()
@@ -4,9 +4,9 @@
4
4
  from __future__ import annotations
5
5
  from architect_py.grpc_client.Cpty.CptyResponse import (
6
6
  CptyResponse,
7
- Any,
7
+ Symbology,
8
8
  ReconcileOrder,
9
- ReconcileOpenOrder,
9
+ ReconcileOpenOrders,
10
10
  UpdateAccountSummary,
11
11
  )
12
12
 
@@ -60,8 +60,9 @@ CptyRequest = Annotated[
60
60
  ]
61
61
 
62
62
  CptyRequest_rpc_method = "duplex_stream"
63
+ UnannotatedCptyRequest = Login | Logout | PlaceOrder | CancelOrder
63
64
  CptyRequestResponseType = CptyResponse
64
65
  CptyRequestUnannotatedResponseType = (
65
- dict[str, Any] | ReconcileOrder | ReconcileOpenOrder | UpdateAccountSummary
66
+ Symbology | ReconcileOrder | ReconcileOpenOrders | UpdateAccountSummary
66
67
  )
67
68
  CptyRequest_route = "/json.architect.Cpty/Cpty"
@@ -46,7 +46,24 @@ class UpdateAccountSummary(Struct, omit_defaults=True, tag_field="t", tag="as"):
46
46
  return f"UpdateAccountSummary(account={self.account},is_snapshot={self.is_snapshot},timestamp={self.timestamp},timestamp_ns={self.timestamp_ns},balances={self.balances},positions={self.positions},statistics={self.statistics})"
47
47
 
48
48
 
49
- class ReconcileOpenOrder(Struct, omit_defaults=True, tag_field="t", tag="oo"):
49
+ class Symbology(Struct, omit_defaults=True, tag_field="t", tag="xs"):
50
+ execution_info: Dict[str, Dict[str, definitions.ExecutionInfo]]
51
+
52
+ # below is a constructor that takes all field titles as arguments for convenience
53
+ @classmethod
54
+ def new(
55
+ cls,
56
+ execution_info: Dict[str, Dict[str, definitions.ExecutionInfo]],
57
+ ):
58
+ return cls(
59
+ execution_info,
60
+ )
61
+
62
+ def __str__(self) -> str:
63
+ return f"Symbology(execution_info={self.execution_info})"
64
+
65
+
66
+ class ReconcileOpenOrders(Struct, omit_defaults=True, tag_field="t", tag="oo"):
50
67
  orders: List[Order]
51
68
  snapshot_for_account: Optional[definitions.AccountIdOrName] = None
52
69
 
@@ -63,7 +80,7 @@ class ReconcileOpenOrder(Struct, omit_defaults=True, tag_field="t", tag="oo"):
63
80
  )
64
81
 
65
82
  def __str__(self) -> str:
66
- return f"ReconcileOpenOrder(orders={self.orders},snapshot_for_account={self.snapshot_for_account})"
83
+ return f"ReconcileOpenOrders(orders={self.orders},snapshot_for_account={self.snapshot_for_account})"
67
84
 
68
85
 
69
86
  class ReconcileOrder(Order, omit_defaults=True, tag_field="t", tag="ro"):
@@ -71,6 +88,6 @@ class ReconcileOrder(Order, omit_defaults=True, tag_field="t", tag="ro"):
71
88
 
72
89
 
73
90
  CptyResponse = Annotated[
74
- Union[Dict[str, Any], ReconcileOrder, ReconcileOpenOrder, UpdateAccountSummary],
91
+ Union[Symbology, ReconcileOrder, ReconcileOpenOrders, UpdateAccountSummary],
75
92
  Meta(title="CptyResponse"),
76
93
  ]