architect-py 3.2.1__py3-none-any.whl → 3.2.2__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.
- architect_py/__init__.py +1 -1
- architect_py/async_client.py +14 -5
- architect_py/client.py +16 -12
- architect_py/client_protocol.py +3 -2
- architect_py/grpc_client/Cpty/CptyRequest.py +3 -2
- architect_py/grpc_client/Cpty/CptyResponse.py +3 -3
- architect_py/grpc_client/Cpty/CptyStatus.py +48 -0
- architect_py/grpc_client/Cpty/CptyStatusRequest.py +45 -0
- architect_py/grpc_client/Cpty/CptysRequest.py +37 -0
- architect_py/grpc_client/Cpty/CptysResponse.py +27 -0
- architect_py/grpc_client/Marketdata/Ticker.py +13 -2
- architect_py/grpc_client/Orderflow/OrderflowRequest.py +1 -0
- architect_py/grpc_client/definitions.py +45 -157
- architect_py/grpc_client/grpc_client.py +8 -0
- architect_py/grpc_client/grpc_server.py +7 -6
- architect_py/tests/conftest.py +4 -2
- architect_py/tests/test_order_sending.py +7 -3
- architect_py/tests/test_subscriptions.py +2 -5
- architect_py-3.2.2.dist-info/METADATA +191 -0
- {architect_py-3.2.1.dist-info → architect_py-3.2.2.dist-info}/RECORD +22 -20
- {architect_py-3.2.1.dist-info → architect_py-3.2.2.dist-info}/WHEEL +1 -1
- architect_py/grpc_client/Folio/AggregatedAccountSummariesRequest.py +0 -59
- architect_py/grpc_client/Folio/AggregatedAccountSummariesResponse.py +0 -27
- architect_py-3.2.1.dist-info/METADATA +0 -212
- {architect_py-3.2.1.dist-info → architect_py-3.2.2.dist-info}/LICENSE +0 -0
architect_py/__init__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
__version__ = "3.2.
|
1
|
+
__version__ = "3.2.2"
|
2
2
|
# this is automatically updated by poetry-dynamic-versioning, see README.md
|
architect_py/async_client.py
CHANGED
@@ -161,9 +161,9 @@ class AsyncClient:
|
|
161
161
|
**kwargs: Any,
|
162
162
|
):
|
163
163
|
"""
|
164
|
-
Users should
|
164
|
+
Users should essentially never be using this constructor directly.
|
165
165
|
|
166
|
-
Use the
|
166
|
+
Use the connect method instead.
|
167
167
|
See self.connect for arg explanations
|
168
168
|
"""
|
169
169
|
|
@@ -199,6 +199,14 @@ class AsyncClient:
|
|
199
199
|
api_key=api_key, api_secret=api_secret, host=host, port=_port, **kwargs
|
200
200
|
)
|
201
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
|
+
|
202
210
|
# ------------------------------------------------------------
|
203
211
|
# Symbology
|
204
212
|
# ------------------------------------------------------------
|
@@ -244,7 +252,6 @@ class AsyncClient:
|
|
244
252
|
info = await self.graphql_client.get_product_info_query(symbol)
|
245
253
|
return info.product_info
|
246
254
|
|
247
|
-
@functools.lru_cache
|
248
255
|
async def get_product_infos(
|
249
256
|
self, symbols: Optional[list[str]]
|
250
257
|
) -> Sequence[ProductInfoFields]:
|
@@ -264,7 +271,6 @@ class AsyncClient:
|
|
264
271
|
infos = await self.graphql_client.get_product_infos_query(symbols)
|
265
272
|
return infos.product_infos
|
266
273
|
|
267
|
-
@functools.lru_cache
|
268
274
|
async def get_execution_info(
|
269
275
|
self, symbol: TradableProduct, execution_venue: str
|
270
276
|
) -> Optional[ExecutionInfoFields]:
|
@@ -949,6 +955,7 @@ class AsyncClient:
|
|
949
955
|
async def send_limit_order(
|
950
956
|
self,
|
951
957
|
*,
|
958
|
+
id: Optional[str] = None,
|
952
959
|
symbol: TradableProduct,
|
953
960
|
execution_venue: Optional[str],
|
954
961
|
odir: OrderDir,
|
@@ -1027,7 +1034,7 @@ class AsyncClient:
|
|
1027
1034
|
quantity,
|
1028
1035
|
order_type,
|
1029
1036
|
time_in_force,
|
1030
|
-
|
1037
|
+
id,
|
1031
1038
|
trader,
|
1032
1039
|
account,
|
1033
1040
|
limit_price,
|
@@ -1042,6 +1049,7 @@ class AsyncClient:
|
|
1042
1049
|
async def send_market_pro_order(
|
1043
1050
|
self,
|
1044
1051
|
*,
|
1052
|
+
id: Optional[str] = None,
|
1045
1053
|
symbol: TradableProduct,
|
1046
1054
|
execution_venue: str,
|
1047
1055
|
odir: OrderDir,
|
@@ -1118,6 +1126,7 @@ class AsyncClient:
|
|
1118
1126
|
limit_price = tick_round_method(limit_price, tick_size)
|
1119
1127
|
|
1120
1128
|
return await self.send_limit_order(
|
1129
|
+
id=id,
|
1121
1130
|
symbol=symbol,
|
1122
1131
|
execution_venue=execution_venue,
|
1123
1132
|
odir=odir,
|
architect_py/client.py
CHANGED
@@ -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
|
architect_py/client_protocol.py
CHANGED
@@ -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]: ...
|
@@ -6,7 +6,7 @@ from architect_py.grpc_client.Cpty.CptyResponse import (
|
|
6
6
|
CptyResponse,
|
7
7
|
Symbology,
|
8
8
|
ReconcileOrder,
|
9
|
-
|
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
|
-
Symbology | ReconcileOrder |
|
66
|
+
Symbology | ReconcileOrder | ReconcileOpenOrders | UpdateAccountSummary
|
66
67
|
)
|
67
68
|
CptyRequest_route = "/json.architect.Cpty/Cpty"
|
@@ -63,7 +63,7 @@ class Symbology(Struct, omit_defaults=True, tag_field="t", tag="xs"):
|
|
63
63
|
return f"Symbology(execution_info={self.execution_info})"
|
64
64
|
|
65
65
|
|
66
|
-
class
|
66
|
+
class ReconcileOpenOrders(Struct, omit_defaults=True, tag_field="t", tag="oo"):
|
67
67
|
orders: List[Order]
|
68
68
|
snapshot_for_account: Optional[definitions.AccountIdOrName] = None
|
69
69
|
|
@@ -80,7 +80,7 @@ class ReconcileOpenOrder(Struct, omit_defaults=True, tag_field="t", tag="oo"):
|
|
80
80
|
)
|
81
81
|
|
82
82
|
def __str__(self) -> str:
|
83
|
-
return f"
|
83
|
+
return f"ReconcileOpenOrders(orders={self.orders},snapshot_for_account={self.snapshot_for_account})"
|
84
84
|
|
85
85
|
|
86
86
|
class ReconcileOrder(Order, omit_defaults=True, tag_field="t", tag="ro"):
|
@@ -88,6 +88,6 @@ class ReconcileOrder(Order, omit_defaults=True, tag_field="t", tag="ro"):
|
|
88
88
|
|
89
89
|
|
90
90
|
CptyResponse = Annotated[
|
91
|
-
Union[Symbology, ReconcileOrder,
|
91
|
+
Union[Symbology, ReconcileOrder, ReconcileOpenOrders, UpdateAccountSummary],
|
92
92
|
Meta(title="CptyResponse"),
|
93
93
|
]
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# generated by datamodel-codegen:
|
2
|
+
# filename: Cpty/CptyStatus.json
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
from typing import Annotated, Optional
|
7
|
+
|
8
|
+
from msgspec import Meta, Struct
|
9
|
+
|
10
|
+
|
11
|
+
class CptyStatus(Struct, omit_defaults=True):
|
12
|
+
connected: bool
|
13
|
+
kind: str
|
14
|
+
last_heartbeat: Annotated[int, Meta(description="UNIX epoch time or -1 for never")]
|
15
|
+
"""
|
16
|
+
UNIX epoch time or -1 for never
|
17
|
+
"""
|
18
|
+
last_heartbeat_stale_threshold: Annotated[
|
19
|
+
int, Meta(description="Stale threshold in seconds, or -1 for never stale")
|
20
|
+
]
|
21
|
+
"""
|
22
|
+
Stale threshold in seconds, or -1 for never stale
|
23
|
+
"""
|
24
|
+
logged_in: bool
|
25
|
+
instance: Optional[str] = None
|
26
|
+
|
27
|
+
# below is a constructor that takes all field titles as arguments for convenience
|
28
|
+
@classmethod
|
29
|
+
def new(
|
30
|
+
cls,
|
31
|
+
connected: bool,
|
32
|
+
kind: str,
|
33
|
+
last_heartbeat: int,
|
34
|
+
last_heartbeat_stale_threshold: int,
|
35
|
+
logged_in: bool,
|
36
|
+
instance: Optional[str] = None,
|
37
|
+
):
|
38
|
+
return cls(
|
39
|
+
connected,
|
40
|
+
kind,
|
41
|
+
last_heartbeat,
|
42
|
+
last_heartbeat_stale_threshold,
|
43
|
+
logged_in,
|
44
|
+
instance,
|
45
|
+
)
|
46
|
+
|
47
|
+
def __str__(self) -> str:
|
48
|
+
return f"CptyStatus(connected={self.connected},kind={self.kind},last_heartbeat={self.last_heartbeat},last_heartbeat_stale_threshold={self.last_heartbeat_stale_threshold},logged_in={self.logged_in},instance={self.instance})"
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# generated by datamodel-codegen:
|
2
|
+
# filename: Cpty/CptyStatusRequest.json
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
from architect_py.grpc_client.Cpty.CptyStatus import CptyStatus
|
6
|
+
|
7
|
+
from typing import Optional
|
8
|
+
|
9
|
+
from msgspec import Struct
|
10
|
+
|
11
|
+
|
12
|
+
class CptyStatusRequest(Struct, omit_defaults=True):
|
13
|
+
kind: str
|
14
|
+
instance: Optional[str] = None
|
15
|
+
|
16
|
+
# below is a constructor that takes all field titles as arguments for convenience
|
17
|
+
@classmethod
|
18
|
+
def new(
|
19
|
+
cls,
|
20
|
+
kind: str,
|
21
|
+
instance: Optional[str] = None,
|
22
|
+
):
|
23
|
+
return cls(
|
24
|
+
kind,
|
25
|
+
instance,
|
26
|
+
)
|
27
|
+
|
28
|
+
def __str__(self) -> str:
|
29
|
+
return f"CptyStatusRequest(kind={self.kind},instance={self.instance})"
|
30
|
+
|
31
|
+
@staticmethod
|
32
|
+
def get_response_type():
|
33
|
+
return CptyStatus
|
34
|
+
|
35
|
+
@staticmethod
|
36
|
+
def get_unannotated_response_type():
|
37
|
+
return CptyStatus
|
38
|
+
|
39
|
+
@staticmethod
|
40
|
+
def get_route() -> str:
|
41
|
+
return "/json.architect.Cpty/CptyStatus"
|
42
|
+
|
43
|
+
@staticmethod
|
44
|
+
def get_rpc_method():
|
45
|
+
return "unary"
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# generated by datamodel-codegen:
|
2
|
+
# filename: Cpty/CptysRequest.json
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
from architect_py.grpc_client.Cpty.CptysResponse import CptysResponse
|
6
|
+
|
7
|
+
from msgspec import Struct
|
8
|
+
|
9
|
+
|
10
|
+
class CptysRequest(Struct, omit_defaults=True):
|
11
|
+
pass
|
12
|
+
|
13
|
+
# below is a constructor that takes all field titles as arguments for convenience
|
14
|
+
@classmethod
|
15
|
+
def new(
|
16
|
+
cls,
|
17
|
+
):
|
18
|
+
return cls()
|
19
|
+
|
20
|
+
def __str__(self) -> str:
|
21
|
+
return f"CptysRequest()"
|
22
|
+
|
23
|
+
@staticmethod
|
24
|
+
def get_response_type():
|
25
|
+
return CptysResponse
|
26
|
+
|
27
|
+
@staticmethod
|
28
|
+
def get_unannotated_response_type():
|
29
|
+
return CptysResponse
|
30
|
+
|
31
|
+
@staticmethod
|
32
|
+
def get_route() -> str:
|
33
|
+
return "/json.architect.Cpty/Cptys"
|
34
|
+
|
35
|
+
@staticmethod
|
36
|
+
def get_rpc_method():
|
37
|
+
return "unary"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# generated by datamodel-codegen:
|
2
|
+
# filename: Cpty/CptysResponse.json
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
from typing import List
|
7
|
+
|
8
|
+
from msgspec import Struct
|
9
|
+
|
10
|
+
from .CptyStatus import CptyStatus
|
11
|
+
|
12
|
+
|
13
|
+
class CptysResponse(Struct, omit_defaults=True):
|
14
|
+
cptys: List[CptyStatus]
|
15
|
+
|
16
|
+
# below is a constructor that takes all field titles as arguments for convenience
|
17
|
+
@classmethod
|
18
|
+
def new(
|
19
|
+
cls,
|
20
|
+
cptys: List[CptyStatus],
|
21
|
+
):
|
22
|
+
return cls(
|
23
|
+
cptys,
|
24
|
+
)
|
25
|
+
|
26
|
+
def __str__(self) -> str:
|
27
|
+
return f"CptysResponse(cptys={self.cptys})"
|
@@ -4,7 +4,7 @@
|
|
4
4
|
from __future__ import annotations
|
5
5
|
from datetime import datetime, timezone
|
6
6
|
|
7
|
-
from datetime import datetime
|
7
|
+
from datetime import date, datetime
|
8
8
|
from decimal import Decimal
|
9
9
|
from typing import Annotated, Optional
|
10
10
|
|
@@ -37,6 +37,7 @@ class Ticker(Struct, omit_defaults=True):
|
|
37
37
|
p: Optional[Annotated[Optional[Decimal], Meta(title="last_price")]] = None
|
38
38
|
price_to_earnings: Optional[Decimal] = None
|
39
39
|
q: Optional[Annotated[Optional[Decimal], Meta(title="last_size")]] = None
|
40
|
+
sd: Optional[Annotated[Optional[date], Meta(title="last_settlement_date")]] = None
|
40
41
|
shares_outstanding_weighted_adj: Optional[Decimal] = None
|
41
42
|
sp: Optional[Annotated[Optional[Decimal], Meta(title="last_settlement_price")]] = (
|
42
43
|
None
|
@@ -75,6 +76,7 @@ class Ticker(Struct, omit_defaults=True):
|
|
75
76
|
last_price: Optional[Decimal] = None,
|
76
77
|
price_to_earnings: Optional[Decimal] = None,
|
77
78
|
last_size: Optional[Decimal] = None,
|
79
|
+
last_settlement_date: Optional[date] = None,
|
78
80
|
shares_outstanding_weighted_adj: Optional[Decimal] = None,
|
79
81
|
last_settlement_price: Optional[Decimal] = None,
|
80
82
|
volume_24h: Optional[Decimal] = None,
|
@@ -108,6 +110,7 @@ class Ticker(Struct, omit_defaults=True):
|
|
108
110
|
last_price,
|
109
111
|
price_to_earnings,
|
110
112
|
last_size,
|
113
|
+
last_settlement_date,
|
111
114
|
shares_outstanding_weighted_adj,
|
112
115
|
last_settlement_price,
|
113
116
|
volume_24h,
|
@@ -119,7 +122,7 @@ class Ticker(Struct, omit_defaults=True):
|
|
119
122
|
)
|
120
123
|
|
121
124
|
def __str__(self) -> str:
|
122
|
-
return f"Ticker(symbol={self.s},timestamp_ns={self.tn},timestamp={self.ts},venue={self.ve},ask_price={self.ap},ask_size={self.as_},bid_price={self.bp},bid_size={self.bs},dividend={self.dividend},dividend_yield={self.dividend_yield},eps_adj={self.eps_adj},funding_rate={self.fr},next_funding_time={self.ft},high_24h={self.h},index_price={self.ip},low_24h={self.l},market_cap={self.market_cap},mark_price={self.mp},open_24h={self.o},open_interest={self.oi},last_price={self.p},price_to_earnings={self.price_to_earnings},last_size={self.q},shares_outstanding_weighted_adj={self.shares_outstanding_weighted_adj},last_settlement_price={self.sp},volume_24h={self.v},volume_30d={self.vm},session_high={self.xh},session_low={self.xl},session_open={self.xo},session_volume={self.xv})"
|
125
|
+
return f"Ticker(symbol={self.s},timestamp_ns={self.tn},timestamp={self.ts},venue={self.ve},ask_price={self.ap},ask_size={self.as_},bid_price={self.bp},bid_size={self.bs},dividend={self.dividend},dividend_yield={self.dividend_yield},eps_adj={self.eps_adj},funding_rate={self.fr},next_funding_time={self.ft},high_24h={self.h},index_price={self.ip},low_24h={self.l},market_cap={self.market_cap},mark_price={self.mp},open_24h={self.o},open_interest={self.oi},last_price={self.p},price_to_earnings={self.price_to_earnings},last_size={self.q},last_settlement_date={self.sd},shares_outstanding_weighted_adj={self.shares_outstanding_weighted_adj},last_settlement_price={self.sp},volume_24h={self.v},volume_30d={self.vm},session_high={self.xh},session_low={self.xl},session_open={self.xo},session_volume={self.xv})"
|
123
126
|
|
124
127
|
@property
|
125
128
|
def symbol(self) -> str:
|
@@ -273,6 +276,14 @@ class Ticker(Struct, omit_defaults=True):
|
|
273
276
|
def last_size(self, value: Optional[Decimal]) -> None:
|
274
277
|
self.q = value
|
275
278
|
|
279
|
+
@property
|
280
|
+
def last_settlement_date(self) -> Optional[date]:
|
281
|
+
return self.sd
|
282
|
+
|
283
|
+
@last_settlement_date.setter
|
284
|
+
def last_settlement_date(self, value: Optional[date]) -> None:
|
285
|
+
self.sd = value
|
286
|
+
|
276
287
|
@property
|
277
288
|
def last_settlement_price(self) -> Optional[Decimal]:
|
278
289
|
return self.sp
|
@@ -46,6 +46,7 @@ OrderflowRequest = Annotated[
|
|
46
46
|
]
|
47
47
|
|
48
48
|
OrderflowRequest_rpc_method = "duplex_stream"
|
49
|
+
UnannotatedOrderflowRequest = PlaceOrder | CancelOrder | CancelAllOrders
|
49
50
|
OrderflowRequestResponseType = Orderflow
|
50
51
|
OrderflowRequestUnannotatedResponseType = (
|
51
52
|
OrderPending
|