architect-py 5.1.4rc1__py3-none-any.whl → 5.1.6__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 (49) hide show
  1. architect_py/__init__.py +24 -4
  2. architect_py/async_client.py +121 -67
  3. architect_py/client.pyi +16 -37
  4. architect_py/grpc/models/Accounts/ResetPaperAccountRequest.py +59 -0
  5. architect_py/grpc/models/Accounts/ResetPaperAccountResponse.py +20 -0
  6. architect_py/grpc/models/Boss/OptionsTransactionsRequest.py +42 -0
  7. architect_py/grpc/models/Boss/OptionsTransactionsResponse.py +27 -0
  8. architect_py/grpc/models/Core/ConfigResponse.py +7 -2
  9. architect_py/grpc/models/Folio/AccountSummary.py +7 -1
  10. architect_py/grpc/models/Marketdata/Candle.py +6 -0
  11. architect_py/grpc/models/Marketdata/L1BookSnapshot.py +6 -0
  12. architect_py/grpc/models/Marketdata/L2BookSnapshot.py +6 -0
  13. architect_py/grpc/models/Marketdata/Liquidation.py +6 -0
  14. architect_py/grpc/models/Marketdata/Ticker.py +6 -0
  15. architect_py/grpc/models/Marketdata/Trade.py +6 -0
  16. architect_py/grpc/models/OptionsMarketdata/OptionsChain.py +5 -5
  17. architect_py/grpc/models/OptionsMarketdata/OptionsChainGreeks.py +5 -5
  18. architect_py/grpc/models/OptionsMarketdata/OptionsChainGreeksRequest.py +5 -1
  19. architect_py/grpc/models/OptionsMarketdata/OptionsChainRequest.py +5 -1
  20. architect_py/grpc/models/OptionsMarketdata/OptionsContract.py +45 -0
  21. architect_py/grpc/models/OptionsMarketdata/OptionsContractGreeksRequest.py +40 -0
  22. architect_py/grpc/models/OptionsMarketdata/OptionsContractRequest.py +40 -0
  23. architect_py/grpc/models/OptionsMarketdata/OptionsExpirations.py +4 -1
  24. architect_py/grpc/models/OptionsMarketdata/OptionsExpirationsRequest.py +8 -1
  25. architect_py/grpc/models/OptionsMarketdata/OptionsGreeks.py +58 -0
  26. architect_py/grpc/models/OptionsMarketdata/OptionsWraps.py +28 -0
  27. architect_py/grpc/models/OptionsMarketdata/OptionsWrapsRequest.py +40 -0
  28. architect_py/grpc/models/__init__.py +11 -1
  29. architect_py/grpc/models/definitions.py +57 -86
  30. architect_py/grpc/orderflow.py +3 -7
  31. architect_py/grpc/server.py +1 -3
  32. architect_py/tests/test_order_entry.py +120 -1
  33. architect_py/tests/test_positions.py +364 -0
  34. architect_py/tests/test_rounding.py +28 -28
  35. architect_py/utils/pandas.py +50 -1
  36. {architect_py-5.1.4rc1.dist-info → architect_py-5.1.6.dist-info}/METADATA +1 -1
  37. {architect_py-5.1.4rc1.dist-info → architect_py-5.1.6.dist-info}/RECORD +49 -38
  38. examples/external_cpty.py +2 -1
  39. examples/funding_rate_mean_reversion_algo.py +4 -4
  40. examples/order_sending.py +3 -3
  41. examples/orderflow_channel.py +75 -56
  42. examples/stream_l1_marketdata.py +3 -1
  43. examples/stream_l2_marketdata.py +3 -1
  44. examples/tutorial_async.py +3 -2
  45. examples/tutorial_sync.py +4 -3
  46. scripts/generate_functions_md.py +2 -1
  47. {architect_py-5.1.4rc1.dist-info → architect_py-5.1.6.dist-info}/WHEEL +0 -0
  48. {architect_py-5.1.4rc1.dist-info → architect_py-5.1.6.dist-info}/licenses/LICENSE +0 -0
  49. {architect_py-5.1.4rc1.dist-info → architect_py-5.1.6.dist-info}/top_level.txt +0 -0
@@ -12,6 +12,7 @@ from msgspec import Struct
12
12
  class OptionsExpirations(Struct, omit_defaults=True):
13
13
  expirations: List[date]
14
14
  underlying: str
15
+ wrap: str
15
16
 
16
17
  # Constructor that takes all field titles as arguments for convenience
17
18
  @classmethod
@@ -19,11 +20,13 @@ class OptionsExpirations(Struct, omit_defaults=True):
19
20
  cls,
20
21
  expirations: List[date],
21
22
  underlying: str,
23
+ wrap: str,
22
24
  ):
23
25
  return cls(
24
26
  expirations,
25
27
  underlying,
28
+ wrap,
26
29
  )
27
30
 
28
31
  def __str__(self) -> str:
29
- return f"OptionsExpirations(expirations={self.expirations},underlying={self.underlying})"
32
+ return f"OptionsExpirations(expirations={self.expirations},underlying={self.underlying},wrap={self.wrap})"
@@ -6,24 +6,31 @@ from architect_py.grpc.models.OptionsMarketdata.OptionsExpirations import (
6
6
  OptionsExpirations,
7
7
  )
8
8
 
9
+ from typing import Optional
10
+
9
11
  from msgspec import Struct
10
12
 
11
13
 
12
14
  class OptionsExpirationsRequest(Struct, omit_defaults=True):
13
15
  underlying: str
16
+ wrap: Optional[str] = None
14
17
 
15
18
  # Constructor that takes all field titles as arguments for convenience
16
19
  @classmethod
17
20
  def new(
18
21
  cls,
19
22
  underlying: str,
23
+ wrap: Optional[str] = None,
20
24
  ):
21
25
  return cls(
22
26
  underlying,
27
+ wrap,
23
28
  )
24
29
 
25
30
  def __str__(self) -> str:
26
- return f"OptionsExpirationsRequest(underlying={self.underlying})"
31
+ return (
32
+ f"OptionsExpirationsRequest(underlying={self.underlying},wrap={self.wrap})"
33
+ )
27
34
 
28
35
  @staticmethod
29
36
  def get_response_type():
@@ -0,0 +1,58 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: OptionsMarketdata/OptionsGreeks.json
3
+
4
+ from __future__ import annotations
5
+
6
+ from datetime import date
7
+ from decimal import Decimal
8
+
9
+ from msgspec import Struct
10
+
11
+ from .. import definitions
12
+
13
+
14
+ class OptionsGreeks(Struct, omit_defaults=True):
15
+ delta: Decimal
16
+ expiration: date
17
+ gamma: Decimal
18
+ implied_volatility: Decimal
19
+ put_or_call: definitions.PutOrCall
20
+ rho: Decimal
21
+ strike: Decimal
22
+ symbol: str
23
+ theta: Decimal
24
+ underlying: str
25
+ vega: Decimal
26
+
27
+ # Constructor that takes all field titles as arguments for convenience
28
+ @classmethod
29
+ def new(
30
+ cls,
31
+ delta: Decimal,
32
+ expiration: date,
33
+ gamma: Decimal,
34
+ implied_volatility: Decimal,
35
+ put_or_call: definitions.PutOrCall,
36
+ rho: Decimal,
37
+ strike: Decimal,
38
+ symbol: str,
39
+ theta: Decimal,
40
+ underlying: str,
41
+ vega: Decimal,
42
+ ):
43
+ return cls(
44
+ delta,
45
+ expiration,
46
+ gamma,
47
+ implied_volatility,
48
+ put_or_call,
49
+ rho,
50
+ strike,
51
+ symbol,
52
+ theta,
53
+ underlying,
54
+ vega,
55
+ )
56
+
57
+ def __str__(self) -> str:
58
+ return f"OptionsGreeks(delta={self.delta},expiration={self.expiration},gamma={self.gamma},implied_volatility={self.implied_volatility},put_or_call={self.put_or_call},rho={self.rho},strike={self.strike},symbol={self.symbol},theta={self.theta},underlying={self.underlying},vega={self.vega})"
@@ -0,0 +1,28 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: OptionsMarketdata/OptionsWraps.json
3
+
4
+ from __future__ import annotations
5
+
6
+ from typing import List
7
+
8
+ from msgspec import Struct
9
+
10
+
11
+ class OptionsWraps(Struct, omit_defaults=True):
12
+ underlying: str
13
+ wraps: List[str]
14
+
15
+ # Constructor that takes all field titles as arguments for convenience
16
+ @classmethod
17
+ def new(
18
+ cls,
19
+ underlying: str,
20
+ wraps: List[str],
21
+ ):
22
+ return cls(
23
+ underlying,
24
+ wraps,
25
+ )
26
+
27
+ def __str__(self) -> str:
28
+ return f"OptionsWraps(underlying={self.underlying},wraps={self.wraps})"
@@ -0,0 +1,40 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: OptionsMarketdata/OptionsWrapsRequest.json
3
+
4
+ from __future__ import annotations
5
+ from architect_py.grpc.models.OptionsMarketdata.OptionsWraps import OptionsWraps
6
+
7
+ from msgspec import Struct
8
+
9
+
10
+ class OptionsWrapsRequest(Struct, omit_defaults=True):
11
+ underlying: str
12
+
13
+ # Constructor that takes all field titles as arguments for convenience
14
+ @classmethod
15
+ def new(
16
+ cls,
17
+ underlying: str,
18
+ ):
19
+ return cls(
20
+ underlying,
21
+ )
22
+
23
+ def __str__(self) -> str:
24
+ return f"OptionsWrapsRequest(underlying={self.underlying})"
25
+
26
+ @staticmethod
27
+ def get_response_type():
28
+ return OptionsWraps
29
+
30
+ @staticmethod
31
+ def get_unannotated_response_type():
32
+ return OptionsWraps
33
+
34
+ @staticmethod
35
+ def get_route() -> str:
36
+ return "/json.architect.OptionsMarketdata/OptionsWraps"
37
+
38
+ @staticmethod
39
+ def get_rpc_method():
40
+ return "unary"
@@ -1,5 +1,7 @@
1
1
  from .Accounts.AccountsRequest import AccountsRequest
2
2
  from .Accounts.AccountsResponse import AccountsResponse
3
+ from .Accounts.ResetPaperAccountRequest import ResetPaperAccountRequest
4
+ from .Accounts.ResetPaperAccountResponse import ResetPaperAccountResponse
3
5
  from .Algo.AlgoOrder import AlgoOrder
4
6
  from .Algo.AlgoOrderRequest import AlgoOrderRequest
5
7
  from .Algo.AlgoOrdersRequest import AlgoOrdersRequest
@@ -18,6 +20,8 @@ from .Auth.CreateJwtRequest import CreateJwtRequest
18
20
  from .Auth.CreateJwtResponse import CreateJwtResponse
19
21
  from .Boss.DepositsRequest import DepositsRequest
20
22
  from .Boss.DepositsResponse import DepositsResponse
23
+ from .Boss.OptionsTransactionsRequest import OptionsTransactionsRequest
24
+ from .Boss.OptionsTransactionsResponse import OptionsTransactionsResponse
21
25
  from .Boss.RqdAccountStatisticsRequest import RqdAccountStatisticsRequest
22
26
  from .Boss.RqdAccountStatisticsResponse import RqdAccountStatisticsResponse
23
27
  from .Boss.StatementUrlRequest import StatementUrlRequest
@@ -89,8 +93,14 @@ from .OptionsMarketdata.OptionsChain import OptionsChain
89
93
  from .OptionsMarketdata.OptionsChainGreeks import OptionsChainGreeks
90
94
  from .OptionsMarketdata.OptionsChainGreeksRequest import OptionsChainGreeksRequest
91
95
  from .OptionsMarketdata.OptionsChainRequest import OptionsChainRequest
96
+ from .OptionsMarketdata.OptionsContract import OptionsContract
97
+ from .OptionsMarketdata.OptionsContractGreeksRequest import OptionsContractGreeksRequest
98
+ from .OptionsMarketdata.OptionsContractRequest import OptionsContractRequest
92
99
  from .OptionsMarketdata.OptionsExpirations import OptionsExpirations
93
100
  from .OptionsMarketdata.OptionsExpirationsRequest import OptionsExpirationsRequest
101
+ from .OptionsMarketdata.OptionsGreeks import OptionsGreeks
102
+ from .OptionsMarketdata.OptionsWraps import OptionsWraps
103
+ from .OptionsMarketdata.OptionsWrapsRequest import OptionsWrapsRequest
94
104
  from .Orderflow.Dropcopy import Dropcopy
95
105
  from .Orderflow.DropcopyRequest import DropcopyRequest
96
106
  from .Orderflow.Orderflow import Orderflow
@@ -113,4 +123,4 @@ from .Symbology.UploadProductCatalogResponse import UploadProductCatalogResponse
113
123
  from .Symbology.UploadSymbologyRequest import UploadSymbologyRequest
114
124
  from .Symbology.UploadSymbologyResponse import UploadSymbologyResponse
115
125
 
116
- __all__ = ["AccountsRequest", "AccountsResponse", "AlgoOrder", "AlgoOrderRequest", "AlgoOrdersRequest", "AlgoOrdersResponse", "CreateAlgoOrderRequest", "PauseAlgoRequest", "PauseAlgoResponse", "StartAlgoRequest", "StartAlgoResponse", "StopAlgoRequest", "StopAlgoResponse", "AlgoParamTypes", "AuthInfoRequest", "AuthInfoResponse", "CreateJwtRequest", "CreateJwtResponse", "DepositsRequest", "DepositsResponse", "RqdAccountStatisticsRequest", "RqdAccountStatisticsResponse", "StatementUrlRequest", "StatementUrlResponse", "StatementsRequest", "StatementsResponse", "WithdrawalsRequest", "WithdrawalsResponse", "ConfigRequest", "ConfigResponse", "RestartCptyRequest", "RestartCptyResponse", "CptyRequest", "CptyResponse", "CptyStatus", "CptyStatusRequest", "CptysRequest", "CptysResponse", "AccountHistoryRequest", "AccountHistoryResponse", "AccountSummariesRequest", "AccountSummariesResponse", "AccountSummary", "AccountSummaryRequest", "HistoricalFillsRequest", "HistoricalFillsResponse", "HistoricalOrdersRequest", "HistoricalOrdersResponse", "HealthCheckRequest", "HealthCheckResponse", "ArrayOfL1BookSnapshot", "Candle", "HistoricalCandlesRequest", "HistoricalCandlesResponse", "L1BookSnapshot", "L1BookSnapshotRequest", "L1BookSnapshotsRequest", "L2BookSnapshot", "L2BookSnapshotRequest", "L2BookUpdate", "Liquidation", "MarketStatus", "MarketStatusRequest", "SubscribeCandlesRequest", "SubscribeCurrentCandlesRequest", "SubscribeL1BookSnapshotsRequest", "SubscribeL2BookUpdatesRequest", "SubscribeLiquidationsRequest", "SubscribeManyCandlesRequest", "SubscribeTickersRequest", "SubscribeTradesRequest", "Ticker", "TickerRequest", "TickerUpdate", "TickersRequest", "TickersResponse", "Trade", "Cancel", "CancelAllOrdersRequest", "CancelAllOrdersResponse", "CancelOrderRequest", "OpenOrdersRequest", "OpenOrdersResponse", "Order", "PendingCancelsRequest", "PendingCancelsResponse", "PlaceOrderRequest", "OptionsChain", "OptionsChainGreeks", "OptionsChainGreeksRequest", "OptionsChainRequest", "OptionsExpirations", "OptionsExpirationsRequest", "Dropcopy", "DropcopyRequest", "Orderflow", "OrderflowRequest", "SubscribeOrderflowRequest", "DownloadProductCatalogRequest", "DownloadProductCatalogResponse", "ExecutionInfoRequest", "ExecutionInfoResponse", "PruneExpiredSymbolsRequest", "PruneExpiredSymbolsResponse", "SubscribeSymbology", "SymbologyRequest", "SymbologySnapshot", "SymbologyUpdate", "SymbolsRequest", "SymbolsResponse", "UploadProductCatalogRequest", "UploadProductCatalogResponse", "UploadSymbologyRequest", "UploadSymbologyResponse"]
126
+ __all__ = ["AccountsRequest", "AccountsResponse", "ResetPaperAccountRequest", "ResetPaperAccountResponse", "AlgoOrder", "AlgoOrderRequest", "AlgoOrdersRequest", "AlgoOrdersResponse", "CreateAlgoOrderRequest", "PauseAlgoRequest", "PauseAlgoResponse", "StartAlgoRequest", "StartAlgoResponse", "StopAlgoRequest", "StopAlgoResponse", "AlgoParamTypes", "AuthInfoRequest", "AuthInfoResponse", "CreateJwtRequest", "CreateJwtResponse", "DepositsRequest", "DepositsResponse", "OptionsTransactionsRequest", "OptionsTransactionsResponse", "RqdAccountStatisticsRequest", "RqdAccountStatisticsResponse", "StatementUrlRequest", "StatementUrlResponse", "StatementsRequest", "StatementsResponse", "WithdrawalsRequest", "WithdrawalsResponse", "ConfigRequest", "ConfigResponse", "RestartCptyRequest", "RestartCptyResponse", "CptyRequest", "CptyResponse", "CptyStatus", "CptyStatusRequest", "CptysRequest", "CptysResponse", "AccountHistoryRequest", "AccountHistoryResponse", "AccountSummariesRequest", "AccountSummariesResponse", "AccountSummary", "AccountSummaryRequest", "HistoricalFillsRequest", "HistoricalFillsResponse", "HistoricalOrdersRequest", "HistoricalOrdersResponse", "HealthCheckRequest", "HealthCheckResponse", "ArrayOfL1BookSnapshot", "Candle", "HistoricalCandlesRequest", "HistoricalCandlesResponse", "L1BookSnapshot", "L1BookSnapshotRequest", "L1BookSnapshotsRequest", "L2BookSnapshot", "L2BookSnapshotRequest", "L2BookUpdate", "Liquidation", "MarketStatus", "MarketStatusRequest", "SubscribeCandlesRequest", "SubscribeCurrentCandlesRequest", "SubscribeL1BookSnapshotsRequest", "SubscribeL2BookUpdatesRequest", "SubscribeLiquidationsRequest", "SubscribeManyCandlesRequest", "SubscribeTickersRequest", "SubscribeTradesRequest", "Ticker", "TickerRequest", "TickerUpdate", "TickersRequest", "TickersResponse", "Trade", "Cancel", "CancelAllOrdersRequest", "CancelAllOrdersResponse", "CancelOrderRequest", "OpenOrdersRequest", "OpenOrdersResponse", "Order", "PendingCancelsRequest", "PendingCancelsResponse", "PlaceOrderRequest", "OptionsChain", "OptionsChainGreeks", "OptionsChainGreeksRequest", "OptionsChainRequest", "OptionsContract", "OptionsContractGreeksRequest", "OptionsContractRequest", "OptionsExpirations", "OptionsExpirationsRequest", "OptionsGreeks", "OptionsWraps", "OptionsWrapsRequest", "Dropcopy", "DropcopyRequest", "Orderflow", "OrderflowRequest", "SubscribeOrderflowRequest", "DownloadProductCatalogRequest", "DownloadProductCatalogResponse", "ExecutionInfoRequest", "ExecutionInfoResponse", "PruneExpiredSymbolsRequest", "PruneExpiredSymbolsResponse", "SubscribeSymbology", "SymbologyRequest", "SymbologySnapshot", "SymbologyUpdate", "SymbolsRequest", "SymbolsResponse", "UploadProductCatalogRequest", "UploadProductCatalogResponse", "UploadSymbologyRequest", "UploadSymbologyResponse"]
@@ -12,8 +12,6 @@ from typing import Annotated, Dict, List, Literal, Optional, Union
12
12
 
13
13
  from msgspec import Meta, Struct
14
14
 
15
- from .Marketdata.Ticker import Ticker
16
-
17
15
 
18
16
  class AccountHistoryGranularity(str, Enum):
19
17
  FiveMinutes = "FiveMinutes"
@@ -422,13 +420,51 @@ class L2BookDiff(Struct, omit_defaults=True):
422
420
 
423
421
  @property
424
422
  def datetime(self) -> datetime:
423
+ """
424
+ Convenience property to get the timestamp as a datetime object in UTC.
425
+ """
425
426
  return datetime.fromtimestamp(self.ts, tz=timezone.utc)
426
427
 
427
428
  @property
428
429
  def datetime_local(self) -> datetime:
430
+ """
431
+ Convenience property to get the timestamp as a datetime object in local time.
432
+ """
429
433
  return datetime.fromtimestamp(self.ts)
430
434
 
431
435
 
436
+ class OptionsTransaction(Struct, omit_defaults=True):
437
+ clearing_firm_account: str
438
+ quantity: Decimal
439
+ timestamp: datetime
440
+ tradable_product: str
441
+ transaction_type: str
442
+ price: Optional[Decimal] = None
443
+
444
+ # Constructor that takes all field titles as arguments for convenience
445
+ @classmethod
446
+ def new(
447
+ cls,
448
+ clearing_firm_account: str,
449
+ quantity: Decimal,
450
+ timestamp: datetime,
451
+ tradable_product: str,
452
+ transaction_type: str,
453
+ price: Optional[Decimal] = None,
454
+ ):
455
+ return cls(
456
+ clearing_firm_account,
457
+ quantity,
458
+ timestamp,
459
+ tradable_product,
460
+ transaction_type,
461
+ price,
462
+ )
463
+
464
+ def __str__(self) -> str:
465
+ return f"OptionsTransaction(clearing_firm_account={self.clearing_firm_account},quantity={self.quantity},timestamp={self.timestamp},tradable_product={self.tradable_product},transaction_type={self.transaction_type},price={self.price})"
466
+
467
+
432
468
  OrderId = Annotated[
433
469
  str, Meta(description="System-unique, persistent order identifiers")
434
470
  ]
@@ -598,6 +634,11 @@ class ProductCatalogInfo(Struct, omit_defaults=True):
598
634
  return f"ProductCatalogInfo(exchange={self.exchange},exchange_product={self.exchange_product},category={self.category},cqg_contract_symbol={self.cqg_contract_symbol},info_url={self.info_url},long_description={self.long_description},multiplier={self.multiplier},price_display_format={self.price_display_format},quote_currency={self.quote_currency},schedule_description={self.schedule_description},settle_method={self.settle_method},short_description={self.short_description},sub_category={self.sub_category})"
599
635
 
600
636
 
637
+ class PutOrCall(str, Enum):
638
+ P = "P"
639
+ C = "C"
640
+
641
+
601
642
  class RqdAccountStatistics(Struct, omit_defaults=True):
602
643
  account_number: str
603
644
  account_type: Optional[str] = None
@@ -1114,11 +1155,6 @@ class Unknown(Struct, omit_defaults=True):
1114
1155
  return f"Unknown(product_type={self.product_type})"
1115
1156
 
1116
1157
 
1117
- class PutOrCall(str, Enum):
1118
- P = "P"
1119
- C = "C"
1120
-
1121
-
1122
1158
  class SnapshotOrUpdateForStringAndProductCatalogInfo1(Struct, omit_defaults=True):
1123
1159
  snapshot: Dict[str, ProductCatalogInfo]
1124
1160
 
@@ -1854,6 +1890,20 @@ class Fill(Struct, omit_defaults=True):
1854
1890
  def trade_time(self, value: int) -> None:
1855
1891
  self.ts = value
1856
1892
 
1893
+ @property
1894
+ def datetime(self) -> datetime:
1895
+ """
1896
+ Convenience property to get the timestamp as a datetime object in UTC.
1897
+ """
1898
+ return datetime.fromtimestamp(self.ts, tz=timezone.utc)
1899
+
1900
+ @property
1901
+ def datetime_local(self) -> datetime:
1902
+ """
1903
+ Convenience property to get the timestamp as a datetime object in local time.
1904
+ """
1905
+ return datetime.fromtimestamp(self.ts)
1906
+
1857
1907
  @property
1858
1908
  def execution_venue(self) -> str:
1859
1909
  return self.x
@@ -1935,85 +1985,6 @@ class Fill(Struct, omit_defaults=True):
1935
1985
  self.xid = value
1936
1986
 
1937
1987
 
1938
- class OptionsContract(Struct, omit_defaults=True):
1939
- expiration: date
1940
- put_or_call: PutOrCall
1941
- strike: Decimal
1942
- ticker: Ticker
1943
- underlying: str
1944
- in_the_money: Optional[bool] = None
1945
-
1946
- # Constructor that takes all field titles as arguments for convenience
1947
- @classmethod
1948
- def new(
1949
- cls,
1950
- expiration: date,
1951
- put_or_call: PutOrCall,
1952
- strike: Decimal,
1953
- ticker: Ticker,
1954
- underlying: str,
1955
- in_the_money: Optional[bool] = None,
1956
- ):
1957
- return cls(
1958
- expiration,
1959
- put_or_call,
1960
- strike,
1961
- ticker,
1962
- underlying,
1963
- in_the_money,
1964
- )
1965
-
1966
- def __str__(self) -> str:
1967
- return f"OptionsContract(expiration={self.expiration},put_or_call={self.put_or_call},strike={self.strike},ticker={self.ticker},underlying={self.underlying},in_the_money={self.in_the_money})"
1968
-
1969
-
1970
- class OptionsGreeks(Struct, omit_defaults=True):
1971
- delta: Decimal
1972
- expiration: date
1973
- gamma: Decimal
1974
- implied_volatility: Decimal
1975
- put_or_call: PutOrCall
1976
- rho: Decimal
1977
- strike: Decimal
1978
- symbol: str
1979
- theta: Decimal
1980
- underlying: str
1981
- vega: Decimal
1982
-
1983
- # Constructor that takes all field titles as arguments for convenience
1984
- @classmethod
1985
- def new(
1986
- cls,
1987
- delta: Decimal,
1988
- expiration: date,
1989
- gamma: Decimal,
1990
- implied_volatility: Decimal,
1991
- put_or_call: PutOrCall,
1992
- rho: Decimal,
1993
- strike: Decimal,
1994
- symbol: str,
1995
- theta: Decimal,
1996
- underlying: str,
1997
- vega: Decimal,
1998
- ):
1999
- return cls(
2000
- delta,
2001
- expiration,
2002
- gamma,
2003
- implied_volatility,
2004
- put_or_call,
2005
- rho,
2006
- strike,
2007
- symbol,
2008
- theta,
2009
- underlying,
2010
- vega,
2011
- )
2012
-
2013
- def __str__(self) -> str:
2014
- return f"OptionsGreeks(delta={self.delta},expiration={self.expiration},gamma={self.gamma},implied_volatility={self.implied_volatility},put_or_call={self.put_or_call},rho={self.rho},strike={self.strike},symbol={self.symbol},theta={self.theta},underlying={self.underlying},vega={self.vega})"
2015
-
2016
-
2017
1988
  class OptionsSeriesInfo(Struct, omit_defaults=True):
2018
1989
  derivative_kind: DerivativeKind
2019
1990
  exercise_type: OptionsExerciseType
@@ -4,12 +4,8 @@ from typing import TYPE_CHECKING, Any, AsyncGenerator, AsyncIterator, Optional,
4
4
 
5
5
  import grpc.aio
6
6
 
7
- from architect_py.grpc.models.Orderflow.Orderflow import Orderflow
8
- from architect_py.grpc.models.Orderflow.OrderflowRequest import (
9
- OrderflowRequest,
10
- OrderflowRequest_route,
11
- OrderflowRequestUnannotatedResponseType,
12
- )
7
+ from architect_py.grpc.models.Orderflow.Orderflow import *
8
+ from architect_py.grpc.models.Orderflow.OrderflowRequest import *
13
9
 
14
10
  if TYPE_CHECKING:
15
11
  from architect_py.async_client import AsyncClient
@@ -120,7 +116,7 @@ class OrderflowChannel:
120
116
  self, request_iterator: AsyncIterator[OrderflowRequest]
121
117
  ) -> AsyncGenerator[Orderflow, None]:
122
118
  """Low-level wrapper around Architect’s gRPC bidirectional stream."""
123
- grpc_client = await self._client.core()
119
+ grpc_client = await self._client._core()
124
120
  decoder = grpc_client.get_decoder(OrderflowRequestUnannotatedResponseType)
125
121
 
126
122
  stub: grpc.aio.StreamStreamMultiCallable = grpc_client.channel.stream_stream(
@@ -41,9 +41,7 @@ class OrderflowServicer(object):
41
41
 
42
42
 
43
43
  def add_OrderflowServicer_to_server(servicer, server):
44
- decoder = msgspec.json.Decoder(
45
- type=SubscribeOrderflowRequest.get_unannotated_response_type()
46
- )
44
+ decoder = msgspec.json.Decoder(type=SubscribeOrderflowRequest)
47
45
  rpc_method_handlers = {
48
46
  "SubscribeOrderflow": grpc.unary_stream_rpc_method_handler(
49
47
  servicer.SubscribeOrderflow,
@@ -4,7 +4,8 @@ from decimal import Decimal
4
4
  import pytest
5
5
 
6
6
  from architect_py import AsyncClient, OrderDir, TickRoundMethod
7
- from architect_py.grpc.models.definitions import OrderType
7
+ from architect_py.common_types.tradable_product import TradableProduct
8
+ from architect_py.grpc.models.definitions import OrderType, SpreaderParams
8
9
 
9
10
 
10
11
  @pytest.mark.asyncio
@@ -39,3 +40,121 @@ async def test_place_limit_order(async_client: AsyncClient):
39
40
  await async_client.cancel_order(order.id)
40
41
 
41
42
  await async_client.close()
43
+
44
+
45
+ @pytest.mark.asyncio
46
+ @pytest.mark.timeout(3)
47
+ async def test_place_market_order(async_client: AsyncClient):
48
+ venue = "CME"
49
+ front_future = await async_client.get_front_future("ES CME Futures", venue)
50
+ info = await async_client.get_execution_info(front_future, venue)
51
+ assert info is not None
52
+ assert info.tick_size is not None
53
+ snap = await async_client.get_ticker(front_future, venue)
54
+ assert snap is not None
55
+ assert snap.bid_price is not None
56
+ accounts = await async_client.list_accounts()
57
+ account = accounts[0]
58
+
59
+ # bid far below the best bid
60
+ order = await async_client.place_order(
61
+ symbol=front_future,
62
+ execution_venue=venue,
63
+ dir=OrderDir.BUY,
64
+ quantity=Decimal(1),
65
+ order_type=OrderType.MARKET,
66
+ account=str(account.account.id),
67
+ )
68
+
69
+ assert order is not None
70
+
71
+ await asyncio.sleep(1.5)
72
+ order = await async_client.get_order(order.id)
73
+ assert order is not None
74
+
75
+ await async_client.close()
76
+
77
+
78
+ @pytest.mark.asyncio
79
+ @pytest.mark.timeout(3)
80
+ async def test_equity_order(async_client: AsyncClient):
81
+ tradable_product = TradableProduct(base_or_value="AAPL US Equity/USD")
82
+
83
+ product_info = await async_client.get_product_info(tradable_product.base())
84
+ assert product_info is not None
85
+ venue = product_info.primary_venue
86
+ assert venue is not None
87
+
88
+ market_status = await async_client.get_market_status(tradable_product, venue)
89
+ if not market_status.is_trading:
90
+ pytest.skip(f"Market {venue} for {tradable_product} is not open")
91
+
92
+ info = await async_client.get_execution_info(tradable_product, venue)
93
+ assert info is not None
94
+ # assert info.tick_size is not None
95
+
96
+ tick_size = Decimal("0.01")
97
+
98
+ snap = await async_client.get_ticker(tradable_product, venue)
99
+ assert snap is not None
100
+ assert snap.bid_price is not None
101
+ accounts = await async_client.list_accounts()
102
+ account = accounts[0]
103
+
104
+ # bid far below the best bid
105
+ limit_price = TickRoundMethod.FLOOR(snap.bid_price * Decimal(0.9), tick_size)
106
+ order = await async_client.place_order(
107
+ symbol=tradable_product,
108
+ execution_venue=venue,
109
+ dir=OrderDir.BUY,
110
+ quantity=Decimal(1),
111
+ order_type=OrderType.LIMIT,
112
+ limit_price=limit_price,
113
+ post_only=False,
114
+ account=str(account.account.id),
115
+ )
116
+
117
+ assert order is not None
118
+ await asyncio.sleep(1)
119
+ await async_client.cancel_order(order.id)
120
+
121
+ await async_client.close()
122
+
123
+
124
+ @pytest.mark.asyncio
125
+ @pytest.mark.timeout(3)
126
+ async def test_spreader_algo(async_client: AsyncClient):
127
+ accounts = await async_client.list_accounts()
128
+ account = accounts[0]
129
+
130
+ venue = "CME"
131
+
132
+ front_ES_future = await async_client.get_front_future("ES CME Futures", venue)
133
+ front_NQ_future = await async_client.get_front_future("NQ CME Futures", venue)
134
+
135
+ params = SpreaderParams(
136
+ dir=OrderDir.BUY, # or OrderDir.SELL
137
+ leg1_marketdata_venue=venue,
138
+ leg1_price_offset=Decimal("0"),
139
+ leg1_price_ratio=Decimal("1"),
140
+ leg1_quantity_ratio=Decimal("1"),
141
+ leg1_symbol=front_ES_future,
142
+ leg2_marketdata_venue=venue,
143
+ leg2_price_offset=Decimal("0"),
144
+ leg2_price_ratio=Decimal("-1"),
145
+ leg2_quantity_ratio=Decimal("-1"),
146
+ leg2_symbol=front_NQ_future,
147
+ limit_price=Decimal("0.25"),
148
+ order_lockout="1s",
149
+ quantity=Decimal("10"),
150
+ leg1_account=account.account.id,
151
+ leg1_execution_venue=venue,
152
+ leg2_account=account.account.id,
153
+ leg2_execution_venue=venue,
154
+ )
155
+
156
+ order = await async_client.place_algo_order(params=params)
157
+
158
+ print(order)
159
+
160
+ await async_client.close()