architect-py 5.1.5__py3-none-any.whl → 5.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. architect_py/__init__.py +24 -4
  2. architect_py/async_client.py +66 -57
  3. architect_py/async_cpty.py +422 -0
  4. architect_py/client.pyi +2 -34
  5. architect_py/grpc/models/Accounts/ResetPaperAccountRequest.py +59 -0
  6. architect_py/grpc/models/Accounts/ResetPaperAccountResponse.py +20 -0
  7. architect_py/grpc/models/Boss/OptionsTransactionsRequest.py +42 -0
  8. architect_py/grpc/models/Boss/OptionsTransactionsResponse.py +27 -0
  9. architect_py/grpc/models/OptionsMarketdata/OptionsChain.py +5 -5
  10. architect_py/grpc/models/OptionsMarketdata/OptionsChainGreeks.py +5 -5
  11. architect_py/grpc/models/OptionsMarketdata/OptionsChainGreeksRequest.py +5 -1
  12. architect_py/grpc/models/OptionsMarketdata/OptionsChainRequest.py +5 -1
  13. architect_py/grpc/models/OptionsMarketdata/OptionsContract.py +45 -0
  14. architect_py/grpc/models/OptionsMarketdata/OptionsContractGreeksRequest.py +40 -0
  15. architect_py/grpc/models/OptionsMarketdata/OptionsContractRequest.py +40 -0
  16. architect_py/grpc/models/OptionsMarketdata/OptionsExpirations.py +4 -1
  17. architect_py/grpc/models/OptionsMarketdata/OptionsExpirationsRequest.py +8 -1
  18. architect_py/grpc/models/OptionsMarketdata/OptionsGreeks.py +58 -0
  19. architect_py/grpc/models/OptionsMarketdata/OptionsWraps.py +28 -0
  20. architect_py/grpc/models/OptionsMarketdata/OptionsWrapsRequest.py +40 -0
  21. architect_py/grpc/models/__init__.py +11 -1
  22. architect_py/grpc/models/definitions.py +37 -86
  23. architect_py/grpc/orderflow.py +3 -7
  24. architect_py/grpc/server.py +1 -3
  25. architect_py/tests/test_order_entry.py +120 -1
  26. architect_py/tests/test_positions.py +208 -17
  27. {architect_py-5.1.5.dist-info → architect_py-5.2.0.dist-info}/METADATA +1 -1
  28. {architect_py-5.1.5.dist-info → architect_py-5.2.0.dist-info}/RECORD +41 -30
  29. examples/external_cpty.py +72 -66
  30. examples/funding_rate_mean_reversion_algo.py +4 -4
  31. examples/order_sending.py +3 -3
  32. examples/orderflow_channel.py +75 -56
  33. examples/stream_l1_marketdata.py +3 -1
  34. examples/stream_l2_marketdata.py +3 -1
  35. examples/tutorial_async.py +3 -2
  36. examples/tutorial_sync.py +4 -3
  37. scripts/add_imports_to_inits.py +6 -2
  38. scripts/generate_functions_md.py +2 -1
  39. {architect_py-5.1.5.dist-info → architect_py-5.2.0.dist-info}/WHEEL +0 -0
  40. {architect_py-5.1.5.dist-info → architect_py-5.2.0.dist-info}/licenses/LICENSE +0 -0
  41. {architect_py-5.1.5.dist-info → architect_py-5.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,422 @@
1
+ import asyncio
2
+ import logging
3
+ import uuid
4
+ from datetime import datetime
5
+ from decimal import Decimal
6
+ from typing import AsyncIterable, Dict, Optional, Sequence, Union
7
+
8
+ import grpc
9
+ import msgspec
10
+
11
+ from .grpc.client import dec_hook
12
+ from .grpc.models.Cpty.CptyRequest import (
13
+ CancelOrder,
14
+ Login,
15
+ Logout,
16
+ PlaceOrder,
17
+ UnannotatedCptyRequest,
18
+ )
19
+ from .grpc.models.Cpty.CptyResponse import (
20
+ ReconcileOpenOrders,
21
+ Symbology,
22
+ UpdateAccountSummary,
23
+ )
24
+ from .grpc.models.definitions import (
25
+ AccountIdOrName,
26
+ AccountPosition,
27
+ AccountStatistics,
28
+ CptyLoginRequest,
29
+ CptyLogoutRequest,
30
+ ExecutionInfo,
31
+ FillKind,
32
+ OrderDir,
33
+ OrderId,
34
+ OrderRejectReason,
35
+ UserId,
36
+ )
37
+ from .grpc.models.Oms.Cancel import Cancel
38
+ from .grpc.models.Oms.Order import Order
39
+ from .grpc.models.Orderflow.OrderflowRequest import (
40
+ OrderflowRequestUnannotatedResponseType,
41
+ TaggedCancelReject,
42
+ TaggedFill,
43
+ TaggedOrderAck,
44
+ TaggedOrderCanceled,
45
+ TaggedOrderOut,
46
+ TaggedOrderReject,
47
+ )
48
+ from .grpc.models.Orderflow.SubscribeOrderflowRequest import SubscribeOrderflowRequest
49
+ from .grpc.utils import encoder
50
+
51
+ FILLS_NS = uuid.UUID("c4b64693-40d2-5613-8d13-bf35b89f92e0")
52
+
53
+
54
+ class AsyncCpty:
55
+ """
56
+ To implement an external cpty, subclass `AsyncCpty` and implement the callback
57
+ stubs `on_login`, `on_place_order`, etc. Use provided methods `ack_order`,
58
+ `out_order`, etc. to drive orderflow events to consumers.
59
+
60
+ Call `add_execution_info` to add execution info for a symbol.
61
+
62
+ Call `serve` to start the server and wait for termination.
63
+
64
+ For manual control of the grpc server, create your own `grpc.aio.Server`
65
+ and call `_add_method_handlers` to add the method handlers.
66
+
67
+ You can use as much or as little of this helper as desired.
68
+ """
69
+
70
+ def __init__(self, execution_venue: str):
71
+ self.execution_venue = execution_venue
72
+ self.execution_venue_fills_ns = uuid.uuid5(FILLS_NS, execution_venue)
73
+ self.execution_info: Dict[str, Dict[str, ExecutionInfo]] = {}
74
+ self.cpty_notifications: dict[int, CptyNotifications] = {}
75
+ self.orderflow_subscriptions: dict[int, OrderflowSubscription] = {}
76
+ self.next_subscription_id = 1
77
+
78
+ def add_execution_info(self, symbol: str, execution_info: ExecutionInfo):
79
+ """
80
+ Add execution info for a symbol.
81
+ """
82
+ self.execution_info[self.execution_venue][symbol] = execution_info
83
+
84
+ async def on_login(self, _request: CptyLoginRequest):
85
+ raise NotImplementedError
86
+
87
+ async def on_logout(self, _request: CptyLogoutRequest):
88
+ raise NotImplementedError
89
+
90
+ async def on_place_order(self, _order: Order):
91
+ """
92
+ Called when the cpty receives an order to place.
93
+
94
+ Call `ack_order` or `reject_order` to advance the order state;
95
+ otherwise, the order will be left in the `PENDING` state.
96
+ """
97
+ raise NotImplementedError
98
+
99
+ async def on_cancel_order(
100
+ self, _cancel: Cancel, _original_order: Optional[Order] = None
101
+ ):
102
+ """
103
+ Called when the cpty receives a cancel order request.
104
+
105
+ Call `reject_cancel` if there's a problem with canceling the order;
106
+ make sure to reference the `cancel.cancel_id` to identify the cancel.
107
+
108
+ Args:
109
+ cancel: The cancel order request.
110
+ original_order: The original order that was cancelled, if the OMS knows it.
111
+ """
112
+ raise NotImplementedError
113
+
114
+ async def get_open_orders(self) -> Sequence[Order]:
115
+ """
116
+ Get all open orders. This is called at least once per client
117
+ connection/login. Return a list of known open orders.
118
+ """
119
+ return []
120
+
121
+ def ack_order(self, order_id: OrderId, *, exchange_order_id: Optional[str] = None):
122
+ """
123
+ Acknowledge an order has reached the exchange.
124
+
125
+ Optionally, provide the exchange order id to correlate with the order;
126
+ this helps with order reconciliation.
127
+ """
128
+ order_ack = TaggedOrderAck(order_id, exchange_order_id)
129
+ self._put_orderflow_event(order_ack)
130
+
131
+ def reject_order(
132
+ self,
133
+ order_id: OrderId,
134
+ *,
135
+ reject_reason: OrderRejectReason,
136
+ reject_message: Optional[str] = None,
137
+ ):
138
+ """
139
+ Reject an order.
140
+ """
141
+ order_reject = TaggedOrderReject(order_id, reject_reason, reject_message)
142
+ self._put_orderflow_event(order_reject)
143
+
144
+ def out_order(self, order_id: OrderId, *, canceled: bool = False):
145
+ """
146
+ Notify that an order is outed. If it was outed because of a cancel,
147
+ pass `canceled=True`. For all other reasons, pass `canceled=False`.
148
+ """
149
+ if canceled:
150
+ order_out = TaggedOrderCanceled(order_id)
151
+ else:
152
+ order_out = TaggedOrderOut(order_id)
153
+ self._put_orderflow_event(order_out)
154
+
155
+ def fill_order(
156
+ self,
157
+ *,
158
+ dir: OrderDir,
159
+ exchange_fill_id: str,
160
+ # if not provided, a suitable uuiv5 will be generated from the exchange_fill_id
161
+ fill_id: Optional[str] = None,
162
+ fill_kind: FillKind = FillKind.Normal,
163
+ price: Decimal,
164
+ quantity: Decimal,
165
+ symbol: str,
166
+ trade_time: datetime,
167
+ account: AccountIdOrName,
168
+ is_taker: bool,
169
+ fee: Optional[Decimal] = None,
170
+ fee_currency: Optional[str] = None,
171
+ order_id: OrderId,
172
+ trader: Optional[UserId] = None,
173
+ ):
174
+ """
175
+ Notify that an order has been filled, either partially or in full.
176
+ """
177
+ now = datetime.now()
178
+ if fill_id is None:
179
+ fill_id = str(uuid.uuid5(self.execution_venue_fills_ns, exchange_fill_id))
180
+ self._put_orderflow_event(
181
+ TaggedFill(
182
+ dir,
183
+ fill_id,
184
+ fill_kind,
185
+ price,
186
+ quantity,
187
+ symbol,
188
+ int(trade_time.timestamp()),
189
+ trade_time.microsecond * 1000,
190
+ self.execution_venue,
191
+ account,
192
+ 1 if is_taker else 0,
193
+ int(now.timestamp()),
194
+ now.microsecond * 1000,
195
+ fee,
196
+ fee_currency,
197
+ order_id,
198
+ trader,
199
+ exchange_fill_id,
200
+ )
201
+ )
202
+
203
+ def reject_cancel(
204
+ self,
205
+ cancel_id: str,
206
+ *,
207
+ reject_reason: str,
208
+ reject_message: Optional[str] = None,
209
+ ):
210
+ """
211
+ Reject a cancel.
212
+ """
213
+ self._put_orderflow_event(
214
+ TaggedCancelReject(cancel_id, reject_reason, reject_message)
215
+ )
216
+
217
+ def _put_orderflow_event(self, event):
218
+ for sub_id, sub in self.orderflow_subscriptions.items():
219
+ try:
220
+ sub.queue.put_nowait(event)
221
+ except asyncio.QueueFull:
222
+ logging.warn(f"orderflow subscription queue full #{sub_id}")
223
+
224
+ def update_account_summary(
225
+ self,
226
+ account: AccountIdOrName,
227
+ *,
228
+ is_snapshot: bool,
229
+ timestamp: datetime,
230
+ balances: Optional[Dict[str, Decimal]] = None,
231
+ positions: Optional[Dict[str, AccountPosition]] = None,
232
+ cash_excess: Optional[Decimal] = None,
233
+ equity: Optional[Decimal] = None,
234
+ yesterday_equity: Optional[Decimal] = None,
235
+ position_margin: Optional[Decimal] = None,
236
+ purchasing_power: Optional[Decimal] = None,
237
+ realized_pnl: Optional[Decimal] = None,
238
+ unrealized_pnl: Optional[Decimal] = None,
239
+ ):
240
+ """
241
+ Update account summary, as reported by the exchange.
242
+
243
+ Not all fields are required--fill only the fields that are relevant.
244
+ """
245
+ positions_dict = None
246
+ if positions is not None:
247
+ positions_dict = {}
248
+ for symbol, position in positions.items():
249
+ positions_dict[symbol] = [position]
250
+ self._put_cpty_event(
251
+ UpdateAccountSummary(
252
+ account,
253
+ is_snapshot,
254
+ int(timestamp.timestamp()),
255
+ timestamp.microsecond * 1000,
256
+ balances,
257
+ positions_dict,
258
+ AccountStatistics(
259
+ cash_excess=cash_excess,
260
+ equity=equity,
261
+ yesterday_equity=yesterday_equity,
262
+ position_margin=position_margin,
263
+ purchasing_power=purchasing_power,
264
+ realized_pnl=realized_pnl,
265
+ unrealized_pnl=unrealized_pnl,
266
+ ),
267
+ )
268
+ )
269
+
270
+ def _put_cpty_event(self, event):
271
+ for sub_id, sub in self.cpty_notifications.items():
272
+ try:
273
+ sub.queue.put_nowait(event)
274
+ except asyncio.QueueFull:
275
+ logging.warn(f"cpty notification queue full #{sub_id}")
276
+
277
+ async def Cpty(
278
+ self,
279
+ request_iterator: AsyncIterable[UnannotatedCptyRequest],
280
+ context: grpc.aio.ServicerContext,
281
+ ):
282
+ context.set_code(grpc.StatusCode.OK)
283
+ await context.send_initial_metadata([])
284
+ logged_in: Optional[Login] = None
285
+ subscription_id = self.next_subscription_id
286
+ self.next_subscription_id += 1
287
+
288
+ def cleanup_subscription(_context):
289
+ if subscription_id is not None:
290
+ try:
291
+ del self.cpty_notifications[subscription_id]
292
+ logging.debug(f"cleaned up cpty notification #{subscription_id}")
293
+ except KeyError:
294
+ pass
295
+
296
+ context.add_done_callback(cleanup_subscription)
297
+ async for request in request_iterator:
298
+ logging.debug(f"Cpty: {request}")
299
+ if not logged_in and not isinstance(request, Login):
300
+ logging.error("not logged in, skipping request")
301
+ continue
302
+ if isinstance(request, Login):
303
+ try:
304
+ await self.on_login(request)
305
+ logged_in = request
306
+ logging.debug(f"registered cpty notification #{subscription_id}")
307
+ self.cpty_notifications[subscription_id] = CptyNotifications(
308
+ account=request.account,
309
+ trader=request.trader,
310
+ )
311
+ except NotImplementedError:
312
+ logging.error("on_login not implemented")
313
+ if logged_in:
314
+ # send symbology info to client
315
+ yield Symbology(self.execution_info)
316
+ # send open orders to client
317
+ open_orders = await self.get_open_orders()
318
+ yield ReconcileOpenOrders(list(open_orders))
319
+ elif isinstance(request, Logout):
320
+ try:
321
+ del self.cpty_notifications[subscription_id]
322
+ logged_in = None
323
+ await self.on_logout(request)
324
+ except NotImplementedError:
325
+ logging.error("on_logout not implemented")
326
+ elif isinstance(request, PlaceOrder):
327
+ try:
328
+ await self.on_place_order(request)
329
+ except NotImplementedError:
330
+ logging.error("on_place_order not implemented")
331
+ elif isinstance(request, CancelOrder):
332
+ try:
333
+ await self.on_cancel_order(request.cancel, request.original_order)
334
+ except NotImplementedError:
335
+ logging.error("on_cancel_order not implemented")
336
+ else:
337
+ logging.error(f"unhandled cpty request: {request}")
338
+
339
+ async def SubscribeOrderflow(
340
+ self, request: SubscribeOrderflowRequest, context: grpc.aio.ServicerContext
341
+ ):
342
+ context.set_code(grpc.StatusCode.OK)
343
+ await context.send_initial_metadata([])
344
+ logging.debug(f"Orderflow: {request}")
345
+ subscription_id = self.next_subscription_id
346
+ self.next_subscription_id += 1
347
+ logging.debug(f"registered orderflow subscription #{subscription_id}")
348
+
349
+ def cleanup_subscription(_context):
350
+ del self.orderflow_subscriptions[subscription_id]
351
+ logging.debug(f"cleaned up orderflow subscription #{subscription_id}")
352
+
353
+ context.add_done_callback(cleanup_subscription)
354
+ subscription = OrderflowSubscription(request)
355
+ self.orderflow_subscriptions[subscription_id] = subscription
356
+ while True:
357
+ next_item = await subscription.queue.get()
358
+ yield next_item
359
+
360
+ def _add_cpty_method_handlers(self, server: grpc.aio.Server):
361
+ decoder = msgspec.json.Decoder(type=UnannotatedCptyRequest, dec_hook=dec_hook)
362
+ rpc_method_handlers = {
363
+ "Cpty": grpc.stream_stream_rpc_method_handler(
364
+ self.Cpty,
365
+ request_deserializer=decoder.decode,
366
+ response_serializer=encoder.encode,
367
+ ),
368
+ }
369
+ generic_handler = grpc.method_handlers_generic_handler(
370
+ "json.architect.Cpty", rpc_method_handlers
371
+ )
372
+ server.add_generic_rpc_handlers((generic_handler,))
373
+
374
+ def _add_orderflow_method_handlers(self, server: grpc.aio.Server):
375
+ decoder = msgspec.json.Decoder(
376
+ type=SubscribeOrderflowRequest, dec_hook=dec_hook
377
+ )
378
+ rpc_method_handlers = {
379
+ "SubscribeOrderflow": grpc.unary_stream_rpc_method_handler(
380
+ self.SubscribeOrderflow,
381
+ request_deserializer=decoder.decode,
382
+ response_serializer=encoder.encode,
383
+ ),
384
+ }
385
+ generic_handler = grpc.method_handlers_generic_handler(
386
+ "json.architect.Orderflow", rpc_method_handlers
387
+ )
388
+ server.add_generic_rpc_handlers((generic_handler,))
389
+
390
+ def _add_method_handlers(self, server: grpc.aio.Server):
391
+ self._add_cpty_method_handlers(server)
392
+ self._add_orderflow_method_handlers(server)
393
+
394
+ async def serve(self, bind: str):
395
+ server = grpc.aio.server()
396
+ self._add_method_handlers(server)
397
+ server.add_insecure_port(bind)
398
+ await server.start()
399
+ logging.info(f"grpc server started on {bind}")
400
+ await server.wait_for_termination()
401
+
402
+
403
+ class CptyNotifications:
404
+ account: Optional[AccountIdOrName] = None
405
+ trader: Optional[str] = None
406
+ queue: asyncio.Queue[Union[Symbology, ReconcileOpenOrders, UpdateAccountSummary]]
407
+
408
+ def __init__(
409
+ self, account: Optional[AccountIdOrName] = None, trader: Optional[str] = None
410
+ ):
411
+ self.account = account
412
+ self.trader = trader
413
+ self.queue = asyncio.Queue()
414
+
415
+
416
+ class OrderflowSubscription:
417
+ request: SubscribeOrderflowRequest
418
+ queue: asyncio.Queue[OrderflowRequestUnannotatedResponseType]
419
+
420
+ def __init__(self, request: SubscribeOrderflowRequest):
421
+ self.request = request
422
+ self.queue = asyncio.Queue()
architect_py/client.pyi CHANGED
@@ -75,45 +75,14 @@ class Client:
75
75
 
76
76
  Query methods on Client that require auth will call this method internally.
77
77
  """
78
- def set_jwt(self, jwt: str | None, jwt_expiration: datetime | None = None):
79
- """
80
- Manually set the JWT for gRPC authentication.
81
-
82
- Args:
83
- jwt: the JWT to set;
84
- None to clear the JWT
85
- jwt_expiration: when to expire the JWT
86
- """
87
- def discover_marketdata(self) -> None:
88
- """
89
- Load marketdata endpoints from the server config.
90
-
91
- The Architect core is responsible for telling you where to find marketdata as per
92
- its configuration. You can also manually set marketdata endpoints by calling
93
- set_marketdata directly.
94
-
95
- This method is called on Client.connect.
96
- """
97
78
  def set_marketdata(self, venue: Venue, endpoint: str):
98
79
  """
99
80
  Manually set the marketdata endpoint for a venue.
100
81
  """
101
- def marketdata(self, venue: Venue) -> GrpcClient:
102
- """
103
- Get the marketdata client for a venue.
104
- """
105
82
  def set_hmart(self, endpoint: str):
106
83
  """
107
84
  Manually set the hmart (historical marketdata service) endpoint.
108
85
  """
109
- def hmart(self) -> GrpcClient:
110
- """
111
- Get the hmart (historical marketdata service) client.
112
- """
113
- def core(self) -> GrpcClient:
114
- """
115
- Get the core client.
116
- """
117
86
  def who_am_i(self) -> tuple[str, str]:
118
87
  """
119
88
  Gets the user_id and user_email for the user that the API key belongs to.
@@ -121,7 +90,6 @@ class Client:
121
90
  Returns:
122
91
  (user_id, user_email)
123
92
  """
124
- def auth_info(self) -> AuthInfoResponse: ...
125
93
  def cpty_status(self, kind: str, instance: str | None = None) -> CptyStatus:
126
94
  """
127
95
  Get cpty status.
@@ -509,7 +477,7 @@ class Client:
509
477
  symbol: the symbol to send the order for
510
478
  execution_venue: the execution venue to send the order to,
511
479
  if execution_venue is set to None, the OMS will send the order to the primary_exchange
512
- the primary_exchange can be deduced from `get_product_info`
480
+ the primary_exchange can be deduced from `get_product_info` (generally will be "CME" or "US-EQUITIES")
513
481
  dir: the direction of the order, BUY or SELL
514
482
  quantity: the quantity of the order
515
483
  limit_price: the limit price of the order
@@ -569,7 +537,7 @@ class Client:
569
537
  True if all orders were cancelled successfully
570
538
  False if there was an error
571
539
  """
572
- def create_algo_order(self, *, params: SpreaderParams, id: str | None = None, trader: str | None = None):
540
+ def place_algo_order(self, *, params: SpreaderParams, id: str | None = None, trader: str | None = None):
573
541
  """
574
542
  Sends an advanced algo order such as the spreader.
575
543
  """
@@ -0,0 +1,59 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: Accounts/ResetPaperAccountRequest.json
3
+
4
+ from __future__ import annotations
5
+ from architect_py.grpc.models.Accounts.ResetPaperAccountResponse import (
6
+ ResetPaperAccountResponse,
7
+ )
8
+
9
+ from typing import Annotated, Optional
10
+
11
+ from msgspec import Meta, Struct
12
+
13
+ from .. import definitions
14
+
15
+
16
+ class ResetPaperAccountRequest(Struct, omit_defaults=True):
17
+ account: Annotated[
18
+ definitions.AccountIdOrName,
19
+ Meta(
20
+ description="The trader for whom to reset paper accounts. If not specified, defaults to the caller user."
21
+ ),
22
+ ]
23
+ """
24
+ The trader for whom to reset paper accounts. If not specified, defaults to the caller user.
25
+ """
26
+ balance: Optional[int] = None
27
+
28
+ # Constructor that takes all field titles as arguments for convenience
29
+ @classmethod
30
+ def new(
31
+ cls,
32
+ account: definitions.AccountIdOrName,
33
+ balance: Optional[int] = None,
34
+ ):
35
+ return cls(
36
+ account,
37
+ balance,
38
+ )
39
+
40
+ def __str__(self) -> str:
41
+ return (
42
+ f"ResetPaperAccountRequest(account={self.account},balance={self.balance})"
43
+ )
44
+
45
+ @staticmethod
46
+ def get_response_type():
47
+ return ResetPaperAccountResponse
48
+
49
+ @staticmethod
50
+ def get_unannotated_response_type():
51
+ return ResetPaperAccountResponse
52
+
53
+ @staticmethod
54
+ def get_route() -> str:
55
+ return "/json.architect.Accounts/ResetPaperAccount"
56
+
57
+ @staticmethod
58
+ def get_rpc_method():
59
+ return "unary"
@@ -0,0 +1,20 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: Accounts/ResetPaperAccountResponse.json
3
+
4
+ from __future__ import annotations
5
+
6
+ from msgspec import Struct
7
+
8
+
9
+ class ResetPaperAccountResponse(Struct, omit_defaults=True):
10
+ pass
11
+
12
+ # Constructor that takes all field titles as arguments for convenience
13
+ @classmethod
14
+ def new(
15
+ cls,
16
+ ):
17
+ return cls()
18
+
19
+ def __str__(self) -> str:
20
+ return f"ResetPaperAccountResponse()"
@@ -0,0 +1,42 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: Boss/OptionsTransactionsRequest.json
3
+
4
+ from __future__ import annotations
5
+ from architect_py.grpc.models.Boss.OptionsTransactionsResponse import (
6
+ OptionsTransactionsResponse,
7
+ )
8
+
9
+ from msgspec import Struct
10
+
11
+
12
+ class OptionsTransactionsRequest(Struct, omit_defaults=True):
13
+ account_id: str
14
+
15
+ # Constructor that takes all field titles as arguments for convenience
16
+ @classmethod
17
+ def new(
18
+ cls,
19
+ account_id: str,
20
+ ):
21
+ return cls(
22
+ account_id,
23
+ )
24
+
25
+ def __str__(self) -> str:
26
+ return f"OptionsTransactionsRequest(account_id={self.account_id})"
27
+
28
+ @staticmethod
29
+ def get_response_type():
30
+ return OptionsTransactionsResponse
31
+
32
+ @staticmethod
33
+ def get_unannotated_response_type():
34
+ return OptionsTransactionsResponse
35
+
36
+ @staticmethod
37
+ def get_route() -> str:
38
+ return "/json.architect.Boss/OptionsTransactions"
39
+
40
+ @staticmethod
41
+ def get_rpc_method():
42
+ return "unary"
@@ -0,0 +1,27 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: Boss/OptionsTransactionsResponse.json
3
+
4
+ from __future__ import annotations
5
+
6
+ from typing import List
7
+
8
+ from msgspec import Struct
9
+
10
+ from .. import definitions
11
+
12
+
13
+ class OptionsTransactionsResponse(Struct, omit_defaults=True):
14
+ options_transactions: List[definitions.OptionsTransaction]
15
+
16
+ # Constructor that takes all field titles as arguments for convenience
17
+ @classmethod
18
+ def new(
19
+ cls,
20
+ options_transactions: List[definitions.OptionsTransaction],
21
+ ):
22
+ return cls(
23
+ options_transactions,
24
+ )
25
+
26
+ def __str__(self) -> str:
27
+ return f"OptionsTransactionsResponse(options_transactions={self.options_transactions})"
@@ -7,19 +7,19 @@ from typing import List
7
7
 
8
8
  from msgspec import Struct
9
9
 
10
- from .. import definitions
10
+ from .OptionsContract import OptionsContract
11
11
 
12
12
 
13
13
  class OptionsChain(Struct, omit_defaults=True):
14
- calls: List[definitions.OptionsContract]
15
- puts: List[definitions.OptionsContract]
14
+ calls: List[OptionsContract]
15
+ puts: List[OptionsContract]
16
16
 
17
17
  # Constructor that takes all field titles as arguments for convenience
18
18
  @classmethod
19
19
  def new(
20
20
  cls,
21
- calls: List[definitions.OptionsContract],
22
- puts: List[definitions.OptionsContract],
21
+ calls: List[OptionsContract],
22
+ puts: List[OptionsContract],
23
23
  ):
24
24
  return cls(
25
25
  calls,
@@ -7,19 +7,19 @@ from typing import List
7
7
 
8
8
  from msgspec import Struct
9
9
 
10
- from .. import definitions
10
+ from .OptionsGreeks import OptionsGreeks
11
11
 
12
12
 
13
13
  class OptionsChainGreeks(Struct, omit_defaults=True):
14
- calls: List[definitions.OptionsGreeks]
15
- puts: List[definitions.OptionsGreeks]
14
+ calls: List[OptionsGreeks]
15
+ puts: List[OptionsGreeks]
16
16
 
17
17
  # Constructor that takes all field titles as arguments for convenience
18
18
  @classmethod
19
19
  def new(
20
20
  cls,
21
- calls: List[definitions.OptionsGreeks],
22
- puts: List[definitions.OptionsGreeks],
21
+ calls: List[OptionsGreeks],
22
+ puts: List[OptionsGreeks],
23
23
  ):
24
24
  return cls(
25
25
  calls,