architect-py 5.1.0b1__py3-none-any.whl → 5.1.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.
Files changed (35) hide show
  1. architect_py/__init__.py +3 -1
  2. architect_py/async_client.py +116 -28
  3. architect_py/client.py +56 -70
  4. architect_py/client.pyi +54 -12
  5. architect_py/common_types/time_in_force.py +1 -0
  6. architect_py/common_types/tradable_product.py +1 -1
  7. architect_py/graphql_client/juniper_base_client.py +4 -0
  8. architect_py/grpc/client.py +3 -0
  9. architect_py/grpc/models/Cpty/CptyStatus.py +17 -18
  10. architect_py/grpc/models/Marketdata/Ticker.py +14 -1
  11. architect_py/grpc/models/Oms/Order.py +12 -1
  12. architect_py/grpc/models/definitions.py +41 -0
  13. architect_py/grpc/resolve_endpoint.py +11 -2
  14. architect_py/tests/conftest.py +2 -5
  15. architect_py/tests/test_encoding.py +37 -0
  16. architect_py/tests/test_marketdata.py +9 -0
  17. architect_py/tests/test_order_entry.py +3 -1
  18. architect_py/tests/test_portfolio_management.py +2 -0
  19. architect_py/tests/test_symbology.py +20 -0
  20. architect_py/tests/test_sync_client.py +40 -0
  21. {architect_py-5.1.0b1.dist-info → architect_py-5.1.2.dist-info}/METADATA +4 -1
  22. {architect_py-5.1.0b1.dist-info → architect_py-5.1.2.dist-info}/RECORD +35 -33
  23. {architect_py-5.1.0b1.dist-info → architect_py-5.1.2.dist-info}/WHEEL +1 -1
  24. examples/book_subscription.py +2 -0
  25. examples/candles.py +2 -0
  26. examples/funding_rate_mean_reversion_algo.py +1 -0
  27. examples/order_sending.py +5 -3
  28. examples/stream_l1_marketdata.py +2 -0
  29. examples/stream_l2_marketdata.py +2 -0
  30. examples/trades.py +2 -0
  31. examples/tutorial_async.py +3 -1
  32. examples/tutorial_sync.py +4 -1
  33. templates/juniper_base_client.py +4 -0
  34. {architect_py-5.1.0b1.dist-info → architect_py-5.1.2.dist-info}/licenses/LICENSE +0 -0
  35. {architect_py-5.1.0b1.dist-info → architect_py-5.1.2.dist-info}/top_level.txt +0 -0
@@ -3,46 +3,45 @@
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
- from typing import Annotated, Optional
6
+ from typing import Annotated, Dict, Optional
7
7
 
8
8
  from msgspec import Meta, Struct
9
9
 
10
+ from .. import definitions
11
+
10
12
 
11
13
  class CptyStatus(Struct, omit_defaults=True):
12
14
  connected: bool
15
+ connections: Dict[str, definitions.ConnectionStatus]
13
16
  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
- ]
17
+ stale: bool
18
+ instance: Optional[str] = None
19
+ logged_in: Optional[
20
+ Annotated[Optional[bool], Meta(description="Not applicable to cpty if None")]
21
+ ] = None
21
22
  """
22
- Stale threshold in seconds, or -1 for never stale
23
+ Not applicable to cpty if None
23
24
  """
24
- logged_in: bool
25
- instance: Optional[str] = None
26
25
 
27
26
  # Constructor that takes all field titles as arguments for convenience
28
27
  @classmethod
29
28
  def new(
30
29
  cls,
31
30
  connected: bool,
31
+ connections: Dict[str, definitions.ConnectionStatus],
32
32
  kind: str,
33
- last_heartbeat: int,
34
- last_heartbeat_stale_threshold: int,
35
- logged_in: bool,
33
+ stale: bool,
36
34
  instance: Optional[str] = None,
35
+ logged_in: Optional[bool] = None,
37
36
  ):
38
37
  return cls(
39
38
  connected,
39
+ connections,
40
40
  kind,
41
- last_heartbeat,
42
- last_heartbeat_stale_threshold,
43
- logged_in,
41
+ stale,
44
42
  instance,
43
+ logged_in,
45
44
  )
46
45
 
47
46
  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})"
47
+ return f"CptyStatus(connected={self.connected},connections={self.connections},kind={self.kind},stale={self.stale},instance={self.instance},logged_in={self.logged_in})"
@@ -29,6 +29,9 @@ class Ticker(Struct, omit_defaults=True):
29
29
  ft: Optional[Annotated[Optional[datetime], Meta(title="next_funding_time")]] = None
30
30
  h: Optional[Annotated[Optional[Decimal], Meta(title="high_24h")]] = None
31
31
  ip: Optional[Annotated[Optional[Decimal], Meta(title="index_price")]] = None
32
+ isp: Optional[
33
+ Annotated[Optional[Decimal], Meta(title="indicative_settlement_price")]
34
+ ] = None
32
35
  l: Optional[Annotated[Optional[Decimal], Meta(title="low_24h")]] = None
33
36
  market_cap: Optional[Decimal] = None
34
37
  mp: Optional[Annotated[Optional[Decimal], Meta(title="mark_price")]] = None
@@ -68,6 +71,7 @@ class Ticker(Struct, omit_defaults=True):
68
71
  next_funding_time: Optional[datetime] = None,
69
72
  high_24h: Optional[Decimal] = None,
70
73
  index_price: Optional[Decimal] = None,
74
+ indicative_settlement_price: Optional[Decimal] = None,
71
75
  low_24h: Optional[Decimal] = None,
72
76
  market_cap: Optional[Decimal] = None,
73
77
  mark_price: Optional[Decimal] = None,
@@ -102,6 +106,7 @@ class Ticker(Struct, omit_defaults=True):
102
106
  next_funding_time,
103
107
  high_24h,
104
108
  index_price,
109
+ indicative_settlement_price,
105
110
  low_24h,
106
111
  market_cap,
107
112
  mark_price,
@@ -122,7 +127,7 @@ class Ticker(Struct, omit_defaults=True):
122
127
  )
123
128
 
124
129
  def __str__(self) -> str:
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})"
130
+ 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},indicative_settlement_price={self.isp},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})"
126
131
 
127
132
  @property
128
133
  def symbol(self) -> str:
@@ -228,6 +233,14 @@ class Ticker(Struct, omit_defaults=True):
228
233
  def index_price(self, value: Optional[Decimal]) -> None:
229
234
  self.ip = value
230
235
 
236
+ @property
237
+ def indicative_settlement_price(self) -> Optional[Decimal]:
238
+ return self.isp
239
+
240
+ @indicative_settlement_price.setter
241
+ def indicative_settlement_price(self, value: Optional[Decimal]) -> None:
242
+ self.isp = value
243
+
231
244
  @property
232
245
  def low_24h(self) -> Optional[Decimal]:
233
246
  return self.l
@@ -22,7 +22,18 @@ class Order(Struct, omit_defaults=True):
22
22
  src: Annotated[definitions.OrderSource, Meta(title="source")]
23
23
  tif: Annotated[TimeInForce, Meta(title="time_in_force")]
24
24
  tn: Annotated[int, Meta(ge=0, title="recv_time_ns")]
25
- ts: Annotated[int, Meta(title="recv_time")]
25
+ ts: Annotated[
26
+ int,
27
+ Meta(
28
+ description="Timestamp that the Architect OMS first received the order.\n\nFor reconciled orders, this could be very far in the future relative to the exchange order timestamp.",
29
+ title="recv_time",
30
+ ),
31
+ ]
32
+ """
33
+ Timestamp that the Architect OMS first received the order.
34
+
35
+ For reconciled orders, this could be very far in the future relative to the exchange order timestamp.
36
+ """
26
37
  u: Annotated[definitions.UserId, Meta(title="trader")]
27
38
  ve: Annotated[str, Meta(title="execution_venue")]
28
39
  xq: Annotated[Decimal, Meta(title="filled_quantity")]
@@ -182,6 +182,47 @@ class CandleWidth(int, Enum):
182
182
  OneDay = 86400
183
183
 
184
184
 
185
+ class ConnectionStatus(Struct, omit_defaults=True):
186
+ connected: bool
187
+ last_heartbeat: Annotated[int, Meta(description="UNIX epoch time or -1 for never")]
188
+ """
189
+ UNIX epoch time or -1 for never
190
+ """
191
+ last_heartbeat_stale_threshold: Annotated[
192
+ int, Meta(description="Stale threshold in seconds, or -1 for never stale")
193
+ ]
194
+ """
195
+ Stale threshold in seconds, or -1 for never stale
196
+ """
197
+ logged_in: Optional[
198
+ Annotated[
199
+ Optional[bool], Meta(description="Not applicable to connection if None")
200
+ ]
201
+ ] = None
202
+ """
203
+ Not applicable to connection if None
204
+ """
205
+
206
+ # Constructor that takes all field titles as arguments for convenience
207
+ @classmethod
208
+ def new(
209
+ cls,
210
+ connected: bool,
211
+ last_heartbeat: int,
212
+ last_heartbeat_stale_threshold: int,
213
+ logged_in: Optional[bool] = None,
214
+ ):
215
+ return cls(
216
+ connected,
217
+ last_heartbeat,
218
+ last_heartbeat_stale_threshold,
219
+ logged_in,
220
+ )
221
+
222
+ def __str__(self) -> str:
223
+ return f"ConnectionStatus(connected={self.connected},last_heartbeat={self.last_heartbeat},last_heartbeat_stale_threshold={self.last_heartbeat_stale_threshold},logged_in={self.logged_in})"
224
+
225
+
185
226
  class CptyLogoutRequest(Struct, omit_defaults=True):
186
227
  pass
187
228
 
@@ -7,8 +7,12 @@ import dns.asyncresolver
7
7
  import dns.resolver
8
8
  from dns.rdtypes.IN.SRV import SRV
9
9
 
10
+ PAPER_GRPC_PORT = 10081
10
11
 
11
- async def resolve_endpoint(endpoint: str) -> Tuple[str, int, bool]:
12
+
13
+ async def resolve_endpoint(
14
+ endpoint: str, paper_trading: bool = True
15
+ ) -> Tuple[str, int, bool]:
12
16
  """
13
17
  From a gRPC endpoint, resolve the host, port and whether or not the endpoint
14
18
  should use SSL. If the port is specified explicitly, it will be used. Otherwise,
@@ -67,4 +71,9 @@ async def resolve_endpoint(endpoint: str) -> Tuple[str, int, bool]:
67
71
 
68
72
  host = str(record.target).rstrip(".") # strips the period off of FQDNs
69
73
 
70
- return host, record.port, use_ssl
74
+ port = record.port
75
+ if paper_trading:
76
+ if "app.architect.co" in host or "staging.architect.co" in host:
77
+ port = PAPER_GRPC_PORT
78
+
79
+ return host, port, use_ssl
@@ -29,7 +29,7 @@ def is_truthy(value: str | None) -> bool:
29
29
  return value is not None and value.lower() in ("1", "true", "yes")
30
30
 
31
31
 
32
- class TestEnvironment:
32
+ class GetEnvironment:
33
33
  @classmethod
34
34
  def from_env(cls):
35
35
  endpoint = os.getenv("ARCHITECT_ENDPOINT")
@@ -80,7 +80,7 @@ class TestEnvironment:
80
80
  @pytest_asyncio.fixture
81
81
  async def async_client() -> AsyncClient:
82
82
  load_dotenv()
83
- test_env = TestEnvironment.from_env()
83
+ test_env = GetEnvironment.from_env()
84
84
  async_client = await AsyncClient.connect(
85
85
  api_key=test_env.api_key,
86
86
  api_secret=test_env.api_secret,
@@ -119,6 +119,3 @@ async def front_ES_future_usd(async_client: AsyncClient) -> str:
119
119
  """
120
120
  future = await get_front_ES_future(async_client)
121
121
  return f"{future}/USD"
122
-
123
-
124
- # CR alee: add sync Client tests
@@ -0,0 +1,37 @@
1
+ from datetime import datetime, timezone
2
+
3
+ from architect_py.common_types.time_in_force import TimeInForce
4
+ from architect_py.common_types.tradable_product import TradableProduct
5
+ from architect_py.grpc.utils import encoder
6
+
7
+
8
+ def test_encoding():
9
+ product = TradableProduct("ES 20250321 CME Future", "USD")
10
+ encoded = encoder.encode(product)
11
+
12
+ assert encoded == b'"ES 20250321 CME Future/USD"', (
13
+ 'Encoding of TradableProduct failed, expected "ES 20250321 CME Future/USD" but got '
14
+ + str(encoded)
15
+ )
16
+
17
+ now = datetime.now(timezone.utc)
18
+
19
+ encoded = encoder.encode(TimeInForce.GTD(now))
20
+
21
+ assert encoded == b'{"GTD": "' + now.isoformat().encode() + b'"}', (
22
+ 'Encoding of TimeInForce.GTD failed, expected {"GTD": "'
23
+ + now.isoformat()
24
+ + '"} but got '
25
+ + str(encoded)
26
+ )
27
+
28
+ encoded = encoder.encode(TimeInForce.GTC)
29
+
30
+ assert encoded == b'"GTC"', (
31
+ 'Encoding of TimeInForce.GTC failed, expected "GTC" but got ' + str(encoded)
32
+ )
33
+
34
+
35
+ if __name__ == "__main__":
36
+ test_encoding()
37
+ print("All tests passed.")
@@ -18,6 +18,7 @@ async def test_get_market_status(async_client: AsyncClient, venue: str, symbol:
18
18
  assert market_status is not None
19
19
  # CR alee: this is broken upstream
20
20
  # assert market_status.is_trading
21
+ await async_client.close()
21
22
 
22
23
 
23
24
  @pytest.mark.asyncio
@@ -35,6 +36,7 @@ async def test_get_historical_candles(
35
36
  symbol, venue, CandleWidth.OneHour, start - timedelta(hours=24), start
36
37
  )
37
38
  assert len(candles) > 0
39
+ await async_client.close()
38
40
 
39
41
 
40
42
  @pytest.mark.asyncio
@@ -49,6 +51,7 @@ async def test_get_l1_book_snapshot(async_client: AsyncClient, venue: str, symbo
49
51
  assert snap is not None
50
52
  assert snap.best_bid is not None
51
53
  assert snap.best_ask is not None
54
+ await async_client.close()
52
55
 
53
56
 
54
57
  @pytest.mark.asyncio
@@ -63,6 +66,7 @@ async def test_get_l2_book_snapshot(async_client: AsyncClient, venue: str, symbo
63
66
  assert snap is not None
64
67
  assert len(snap.bids) > 0
65
68
  assert len(snap.asks) > 0
69
+ await async_client.close()
66
70
 
67
71
 
68
72
  @pytest.mark.asyncio
@@ -76,6 +80,7 @@ async def test_get_ticker(async_client: AsyncClient, venue: str, symbol: str):
76
80
  ticker = await async_client.get_ticker(symbol, venue)
77
81
  assert ticker is not None
78
82
  assert ticker.last_price is not None
83
+ await async_client.close()
79
84
 
80
85
 
81
86
  @pytest.mark.asyncio
@@ -96,6 +101,7 @@ async def test_stream_l1_book_snapshots(
96
101
  i += 1
97
102
  if i > 20:
98
103
  break
104
+ await async_client.close()
99
105
 
100
106
 
101
107
  @pytest.mark.asyncio
@@ -132,6 +138,7 @@ async def test_stream_l2_book_updates(
132
138
  i += 1
133
139
  if i > 20:
134
140
  break
141
+ await async_client.close()
135
142
 
136
143
 
137
144
  @pytest.mark.asyncio
@@ -149,6 +156,8 @@ async def test_stream_trades(async_client: AsyncClient, venue: str, symbol: str)
149
156
  if i > 20:
150
157
  break
151
158
 
159
+ await async_client.close()
160
+
152
161
 
153
162
  # @pytest.mark.asyncio
154
163
  # @pytest.mark.parametrize(
@@ -26,7 +26,7 @@ async def test_place_limit_order(async_client: AsyncClient):
26
26
  order = await async_client.place_limit_order(
27
27
  symbol=symbol,
28
28
  execution_venue=venue,
29
- odir=OrderDir.BUY,
29
+ dir=OrderDir.BUY,
30
30
  quantity=Decimal(1),
31
31
  limit_price=limit_price,
32
32
  account=str(account.account.id),
@@ -34,3 +34,5 @@ async def test_place_limit_order(async_client: AsyncClient):
34
34
  assert order is not None
35
35
  await asyncio.sleep(1)
36
36
  await async_client.cancel_order(order.id)
37
+
38
+ await async_client.close()
@@ -21,3 +21,5 @@ async def test_get_account_summary(async_client: AsyncClient):
21
21
  assert summary.balances is not None
22
22
  assert len(summary.balances) > 0
23
23
  assert summary.positions is not None
24
+
25
+ await async_client.close()
@@ -67,6 +67,26 @@ async def test_get_cme_future_from_root_month_year(async_client: AsyncClient):
67
67
  "future base name does not match regex"
68
68
  )
69
69
 
70
+ await async_client.close()
71
+
72
+
73
+ @pytest.mark.asyncio
74
+ async def test_get_front_future(async_client: AsyncClient):
75
+ """
76
+ Test that we can get the front future for a given series.
77
+ """
78
+ series_name = "ES CME Futures"
79
+ front_future = await async_client.get_front_future(series_name, "CME")
80
+ assert front_future is not None, "front future is None"
81
+ assert re.match(r"ES \d* CME Future", front_future), (
82
+ "front future base name does not match regex"
83
+ )
84
+ front_future = await async_client.get_front_future(series_name)
85
+ assert front_future is not None, "front future is None"
86
+ assert re.match(r"ES \d* CME Future", front_future), (
87
+ "front future base name does not match regex"
88
+ )
89
+
70
90
 
71
91
  def add_one_month_to_datetime(dt: datetime):
72
92
  if dt.month == 12:
@@ -0,0 +1,40 @@
1
+ from dotenv import load_dotenv
2
+
3
+ from architect_py import Client
4
+ from architect_py.tests.conftest import GetEnvironment
5
+
6
+
7
+ def test_sync_client():
8
+ load_dotenv()
9
+ test_env = GetEnvironment.from_env()
10
+ client = Client(
11
+ api_key=test_env.api_key,
12
+ api_secret=test_env.api_secret,
13
+ paper_trading=test_env.paper_trading,
14
+ endpoint=test_env.endpoint,
15
+ graphql_port=test_env.graphql_port,
16
+ )
17
+
18
+ symbols = client.list_symbols(marketdata="CME")
19
+
20
+ assert symbols is not None
21
+ assert len(symbols) > 20
22
+
23
+ client.close()
24
+
25
+
26
+ def test_creation():
27
+ load_dotenv()
28
+ test_env = GetEnvironment.from_env()
29
+ client = Client(
30
+ api_key=test_env.api_key,
31
+ api_secret=test_env.api_secret,
32
+ paper_trading=True,
33
+ endpoint="app.architect.co",
34
+ )
35
+
36
+ symbols = client.list_symbols(marketdata="CME")
37
+
38
+ assert symbols is not None
39
+ assert len(symbols) > 20
40
+ client.close()
@@ -1,9 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: architect-py
3
- Version: 5.1.0b1
3
+ Version: 5.1.2
4
4
  Summary: Python SDK for the Architect trading platform and brokerage.
5
5
  Author-email: "Architect Financial Technologies, Inc." <hello@architect.co>
6
6
  License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://www.architect.co/brokerage/overview
8
+ Project-URL: Documentation, https://docs.architect.co
9
+ Project-URL: Repository, https://github.com/architect-xyz/architect-py
7
10
  Classifier: Programming Language :: Python :: 3
8
11
  Classifier: Operating System :: OS Independent
9
12
  Classifier: Development Status :: 5 - Production/Stable
@@ -1,11 +1,11 @@
1
- architect_py/__init__.py,sha256=18bhau9o35uBVHpoQlkCgF0aT-qNHYCO3JJpWkDykjM,16077
2
- architect_py/async_client.py,sha256=Re743h6J6Qax5TAwf8Rv3A1AYTaHTYmcI5y1x5q7Eh8,58787
3
- architect_py/client.py,sha256=fpgE23nqB9GGsOyGdf0WRhVektOjso-qRm-XiQVF690,6048
4
- architect_py/client.pyi,sha256=OTlM_F_zANNHKuWV0XNGvcM9vIeENaZjBLSa8VMQXiI,23050
1
+ architect_py/__init__.py,sha256=0AUu9lue-XJfjKuCe_CgnQXdOlwhgBSwRLFc5yeU4LI,16121
2
+ architect_py/async_client.py,sha256=0cpFvY36YquphGqD7z7hdWEb59OyuJiDYgrHzfykuC4,61646
3
+ architect_py/client.py,sha256=yC0OVzz6uXUMdIIhqqR3GyVuBApYSm00AS51QM8xPak,4911
4
+ architect_py/client.pyi,sha256=VJrg85KaupKzWY4BvS86xREs67S_TFrItNirczYLrgc,24565
5
5
  architect_py/common_types/__init__.py,sha256=fzOdIlKGWVN9V2Onc5z1v2bpvtZ4H9RSFA9ymJcBi3k,197
6
6
  architect_py/common_types/order_dir.py,sha256=ebyWTcXzJWrotkc2D9wNGc6JXbE5I3NLLuAz3I7FTZ8,2191
7
- architect_py/common_types/time_in_force.py,sha256=lzGAQCm_BqJ0mlNdZfhHYcybbHhP-Uc7dlcxrrCwQRo,3051
8
- architect_py/common_types/tradable_product.py,sha256=S4sFIvG13KA4SVqUI9w2smWwomqL6Qh0xIkvKAIxKH0,2131
7
+ architect_py/common_types/time_in_force.py,sha256=gEDYcNp014Eeb98zJDytiV0hGxHu_QsQndeM6Hk0Wa8,3132
8
+ architect_py/common_types/tradable_product.py,sha256=4IIyrkPsMXjS_LrPDIgRWZY03FAsOaALdGTrPHtg6Rs,2148
9
9
  architect_py/graphql_client/__init__.py,sha256=fTZjb1MbdYM80p9dCklWwu5T0c7C3KYMLLGGsF7ZGAA,2306
10
10
  architect_py/graphql_client/base_model.py,sha256=o2d-DixASFCGztr3rTiGX0AwgFu7Awr7EgD70FI8a-I,620
11
11
  architect_py/graphql_client/client.py,sha256=qsjGZG7M9KwGLL1f6dVLV8-r27vUIYA9al0IDJw4ugo,9976
@@ -19,16 +19,16 @@ architect_py/graphql_client/get_future_series_query.py,sha256=pRfdJ31gW2bxYotmXv
19
19
  architect_py/graphql_client/get_product_info_query.py,sha256=oxDDx3J2jGSnNXQZw-lDHdzZO33XCOC0hpNSofjqKQ0,598
20
20
  architect_py/graphql_client/get_product_infos_query.py,sha256=vZImiKh19LCG0yKiw9aP9y1lnUgxgywW7whj1FeSnGk,601
21
21
  architect_py/graphql_client/input_types.py,sha256=6Obe-vvDm4TDgH3oRZUzbEvkbquaQOHYRK_62B1_0FA,57
22
- architect_py/graphql_client/juniper_base_client.py,sha256=njikUx3G2PLqYmx6PGhT_EHALUwD9EHlI2o4W1XMnMk,12609
22
+ architect_py/graphql_client/juniper_base_client.py,sha256=0kbAihyRgEP3n28zRumoSTvpOV695bd8bQPlVE3tRTY,12737
23
23
  architect_py/graphql_client/search_symbols_query.py,sha256=hbGa6gF-gMWtRYQm2vlCTPDex8RWrJ4Yn4nT0VRQnCQ,614
24
24
  architect_py/graphql_client/user_id_query.py,sha256=tWKJJLgEINzd8e7rYlGklQCnwcwHzYFpCGQvhxQGX20,334
25
25
  architect_py/grpc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- architect_py/grpc/client.py,sha256=6NolGeMdIxEcx1R0ij_wWW-o1MspS_XqYE2TtQqaxsk,3343
27
- architect_py/grpc/resolve_endpoint.py,sha256=HnOYC7n7taeSdnGY5E4TCSArCuY2LTwsGOnt_YLh9vQ,2415
26
+ architect_py/grpc/client.py,sha256=1_2JuxFoIVRtcuczkuI-uF7zy-AqSYehf5N3E9Gy4Jg,3406
27
+ architect_py/grpc/resolve_endpoint.py,sha256=r_PBWANIJJ47N5uyPcnefZ21ZE1-mzgACfCBfQpekg8,2621
28
28
  architect_py/grpc/server.py,sha256=Abmdfe1eYbctVgzoJYBBBLpd7UD70FbYQLtJImSyRzs,1934
29
29
  architect_py/grpc/utils.py,sha256=5sykLExUNZbcQHcxLCCM9DdOOiJJZcpputGrDtaMifY,667
30
30
  architect_py/grpc/models/__init__.py,sha256=RrTLZvU7mNykDNp1oOm4-dekzab9ugIXd_my7Sm0Vx4,9153
31
- architect_py/grpc/models/definitions.py,sha256=R7saySbcFH_OADDO-aWZqlJmF6hjWY-TxopDX_Mu3qk,75743
31
+ architect_py/grpc/models/definitions.py,sha256=sGc8KYz4Hki6X3Kvr-Qe6iVnTaQC47wwJP3NeEPT5cQ,77014
32
32
  architect_py/grpc/models/Accounts/AccountsRequest.py,sha256=1a88cltSebOb53EdJ0hKEGR7FlmBiibrCtGzLTKqDBY,1524
33
33
  architect_py/grpc/models/Accounts/AccountsResponse.py,sha256=DlXbkd3UbRybblBAfokw-K6nRvLNZgqz7cc0EKiW1zI,636
34
34
  architect_py/grpc/models/Accounts/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
@@ -65,7 +65,7 @@ architect_py/grpc/models/Core/RestartCptyResponse.py,sha256=aCyJfucfFGHieGURjEej
65
65
  architect_py/grpc/models/Core/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
66
66
  architect_py/grpc/models/Cpty/CptyRequest.py,sha256=eWBayFNnhAZgszneP7f6hDvzQ82JQrFLDSeOPAyiRlg,1711
67
67
  architect_py/grpc/models/Cpty/CptyResponse.py,sha256=UObbkmbtD3sWWklml4hx-Ggc1RaI1v1-J5QW9doWpe4,2865
68
- architect_py/grpc/models/Cpty/CptyStatus.py,sha256=QArnE_viYbiKLW5gctN2Pdy-R0lmKhC3bDiGPPKPjgw,1423
68
+ architect_py/grpc/models/Cpty/CptyStatus.py,sha256=UG8LkBWyQ8oJfxU22iJD5ieZRqmuyIqJxToO6Li5RTc,1281
69
69
  architect_py/grpc/models/Cpty/CptyStatusRequest.py,sha256=5eYYL2L5TmFKgoUuAInvFS0qlSh7YKw4j05Z9ftpxaA,1027
70
70
  architect_py/grpc/models/Cpty/CptysRequest.py,sha256=th1vto4vclExgZD4HwXaNy87amRP2oM1ix4WLetnIW8,801
71
71
  architect_py/grpc/models/Cpty/CptysResponse.py,sha256=cQiRp3VEewfcCKRxqdXpMT2EEZujO3h9LZtHATBDPtk,568
@@ -105,7 +105,7 @@ architect_py/grpc/models/Marketdata/SubscribeLiquidationsRequest.py,sha256=6BhC4
105
105
  architect_py/grpc/models/Marketdata/SubscribeManyCandlesRequest.py,sha256=pel2GGysDsJXjPY7rkyqqyGS3MPl13YezJS7apihiFc,1512
106
106
  architect_py/grpc/models/Marketdata/SubscribeTickersRequest.py,sha256=7g2LBAYd97OJ9FrxpUvZKO7hSMng-K4KfnsN08O4XSM,1437
107
107
  architect_py/grpc/models/Marketdata/SubscribeTradesRequest.py,sha256=7P8FyNx6wijNUBGry0vaMhaEKuG1ik8kTibJBvdol2k,1299
108
- architect_py/grpc/models/Marketdata/Ticker.py,sha256=XOZbaSwCOyE8sDQi4aKA7jc39igXay63JCFOpeQN1Fo,11091
108
+ architect_py/grpc/models/Marketdata/Ticker.py,sha256=O4kJK1RyThYgfpvIr9mgRWAAkYgwwAKgOhEhbfDo9b4,11592
109
109
  architect_py/grpc/models/Marketdata/TickerRequest.py,sha256=Ay--5JKgCfdvlVWD2H6YSa_66NC3Dt6c-XK8JkbWhus,1008
110
110
  architect_py/grpc/models/Marketdata/TickerUpdate.py,sha256=sJ4wvCeGckMV30HwAcAsEMQbCzjN31OxF19q70jdxok,437
111
111
  architect_py/grpc/models/Marketdata/TickersRequest.py,sha256=_BYkOO2pk-terLNwyxN8gtHQxIrfPA7klodDeTS5ouM,2200
@@ -118,7 +118,7 @@ architect_py/grpc/models/Oms/CancelAllOrdersResponse.py,sha256=YM1H_nrV4RhpLMEwS
118
118
  architect_py/grpc/models/Oms/CancelOrderRequest.py,sha256=0yJysCf0IcwUevEqVnAkIm-OkOAbp_vOwh1p1ljSsp8,1939
119
119
  architect_py/grpc/models/Oms/OpenOrdersRequest.py,sha256=5Uv9ndI2WqRJgOWNLeKcIV8czb0ff6wHUW0gokeBktg,1804
120
120
  architect_py/grpc/models/Oms/OpenOrdersResponse.py,sha256=HT4YXjbbwdp2rLLXxoetF33DGe2j403soMLme2p18ts,592
121
- architect_py/grpc/models/Oms/Order.py,sha256=wcLx5lK_xF3z99Ix1Q1j43Mjk4zvoyBGwgFuYmOB-5E,10257
121
+ architect_py/grpc/models/Oms/Order.py,sha256=jjNSxHO8kdc67xhUdiRmsOdvISQPgtYeQ_pm4H3E5dg,10680
122
122
  architect_py/grpc/models/Oms/PendingCancelsRequest.py,sha256=jdbBOpCHBlZFAZfF6urJZXXa5Dr5cTRR3AJ9ss4rY6E,1620
123
123
  architect_py/grpc/models/Oms/PendingCancelsResponse.py,sha256=mWRNRDa489Vdg-r7dJMOmfOO8l57yg8lBMynBDcY60A,628
124
124
  architect_py/grpc/models/Oms/PlaceOrderRequest.py,sha256=se2iSEC_TrL5y-m_CRJkk9jsYLFOGnE57QFwz4Dqtck,8317
@@ -154,33 +154,35 @@ architect_py/grpc/models/Symbology/UploadSymbologyRequest.py,sha256=XRMC6W6LLG0d
154
154
  architect_py/grpc/models/Symbology/UploadSymbologyResponse.py,sha256=LM6iHjta4yZY784qMR5etG9gKjiBsBCntZqAcmaOHac,444
155
155
  architect_py/grpc/models/Symbology/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
156
156
  architect_py/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
- architect_py/tests/conftest.py,sha256=5CcEuqakcU-ZapywYZRcLI5y1GicrTeOxiEixt--R0w,3552
157
+ architect_py/tests/conftest.py,sha256=XCeq44muZi6i9CxOe9lH7rCmt5pQViWJ_25gSowrLP0,3515
158
158
  architect_py/tests/test_book_building.py,sha256=biqs8X9bw1YSb6mrCDS-ELesdD-P5F6bE3MYXP0BeQ4,1236
159
- architect_py/tests/test_marketdata.py,sha256=mhYIiNhmsY706PQD3Nvto0l4uDl5dPHn8BcqGPgFCA8,4714
160
- architect_py/tests/test_order_entry.py,sha256=qRKWa4QvIlurZG96AK2CMF9dpRAKep9RquOuEAdAuRY,1148
159
+ architect_py/tests/test_encoding.py,sha256=J61Lk2CDIqgdcsj0-KYBZweYh5EQ4XAXsRyM0fdMqfU,1085
160
+ architect_py/tests/test_marketdata.py,sha256=W26OrL51ONAclBjBcm7trS1QPXtLLjdgnsbDR2kqtIw,4963
161
+ architect_py/tests/test_order_entry.py,sha256=eD3YrRKTpsJqAI5ahzk4J8uPKXby_XLYIcv_ZaqDKRA,1179
161
162
  architect_py/tests/test_orderflow.py,sha256=PRCr4Yzaif9OG0Eq1zxCUpTfFsHA3WEWSBiETRDvnIE,1038
162
- architect_py/tests/test_portfolio_management.py,sha256=LPlkLP2SllLPm0Un7OptfVo96uqiDI7-osTaHxH5m54,677
163
+ architect_py/tests/test_portfolio_management.py,sha256=Q4pburTDJ53hrq2_aRbNAOG3nwbCEsgZQGbI_AMHLxE,709
163
164
  architect_py/tests/test_rounding.py,sha256=cAQ1-tWOVgxENt0Fzs9YcFDdDDYmCtOHvAA_w76wy9g,1417
164
- architect_py/tests/test_symbology.py,sha256=892FN_FGwE8t4lVQtUMGKav69MGzHACeF5RAYrAEdBw,2707
165
+ architect_py/tests/test_symbology.py,sha256=74fbUgoycuViMHHnurE2Dnfao75wWu_cmQMyU5XQcdY,3436
166
+ architect_py/tests/test_sync_client.py,sha256=teaHrp-CMpKIDsGPdnyxvmuW_a3hgFftnsnPsFHz9Tw,946
165
167
  architect_py/utils/nearest_tick.py,sha256=i1cCGMSi-sP4Grbp0RCwEsoLzMWN9iC6gPMBm2daDWM,4810
166
168
  architect_py/utils/nearest_tick_2.py,sha256=f-o6b73Mo8epCIaOYBS9F0k_6UHUDSVG1N_VWg7iFBU,3641
167
169
  architect_py/utils/orderbook.py,sha256=JM02NhHbmK3sNaS2Ara8FBY4TvKvtMIzJW1oVd8KC3s,1004
168
170
  architect_py/utils/pandas.py,sha256=QHz2ynj4T92FobuzRaNoH3ypArHoSDCiGtZ3PVXJ2vo,1017
169
171
  architect_py/utils/price_bands.py,sha256=j7ioSA3dx025CD5E2Vg7XQvmjPvxQb-gzQBfQTovpTw,21874
170
172
  architect_py/utils/symbol_parsing.py,sha256=OjJzk2c6QU2s0aJMSyVEzlWD5Vy-RlakJVW7jNHVDJk,845
171
- architect_py-5.1.0b1.dist-info/licenses/LICENSE,sha256=6P0_5gYN8iPWPZeqA9nxiO3tRQmcSA1ijAVR7C8j1SI,11362
173
+ architect_py-5.1.2.dist-info/licenses/LICENSE,sha256=6P0_5gYN8iPWPZeqA9nxiO3tRQmcSA1ijAVR7C8j1SI,11362
172
174
  examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
- examples/book_subscription.py,sha256=eyXEt23dTyyArXt7N7C-XdRmLFSdZSntOYZaL0W-PBU,1440
174
- examples/candles.py,sha256=AicLj6d-yUVbZVX-mQUBJkI6KEoJeC-BErvxD9-8Z8Y,735
175
+ examples/book_subscription.py,sha256=W7pldoHIPOclhxhxFvVmsBTB1wx1aS4OgAg0EFXeAzA,1461
176
+ examples/candles.py,sha256=Vc1IgwgFPmpAtURdNXGhgdL82y_JNcryADE30r3vVY0,756
175
177
  examples/common.py,sha256=K2ppu4vdlTNsL1oX5RDrNKczljfPVOTPzDia1Abrppg,2987
176
178
  examples/external_cpty.py,sha256=xxGXONXwoWIS8ys0SgxHLSmntAi1BlwV2NR9WD1kvpc,2527
177
- examples/funding_rate_mean_reversion_algo.py,sha256=iP3bghdYMzERfaJMs_QJZ-e3SUVhLgHLNPvOf2sDkIQ,6482
178
- examples/order_sending.py,sha256=2Wple0qOe1I-9c8nTX9xtOuMjIvPydIezUfn6LQnWlE,3290
179
- examples/stream_l1_marketdata.py,sha256=Oi7ovb0i4hTdWfkhcRYUJLW5Ou64JxWzZMGhqSL8f_I,707
180
- examples/stream_l2_marketdata.py,sha256=e5d0z4Hft3X51oZsPwJbb_5VG2iDfCMlbbFv3qOkma4,1070
181
- examples/trades.py,sha256=AGKX8g7Xaf5r-KPWEeeAfL7XxoVeh8WsZvaWW5kBuMg,540
182
- examples/tutorial_async.py,sha256=HTh2iVJOlXckenWRJxYxp8awhNGBiFPDgtIe4f8mBYk,2626
183
- examples/tutorial_sync.py,sha256=egXb184Q-HuSK7G-NHcnOFM8ywmv08tlKr4GUrk75sY,2813
179
+ examples/funding_rate_mean_reversion_algo.py,sha256=3wy9SsQ5brYRRyzEAl6IV5g-MGFSfYInmHN0T50jzOg,6502
180
+ examples/order_sending.py,sha256=1OV5YSmEVXqeuzLsUWmwnjsdsLFNUdnmwdmdwnKuIYI,3313
181
+ examples/stream_l1_marketdata.py,sha256=6Hkfacbexmgj7n-zT7bIyGksghSl5asrDErtRcjAn2E,728
182
+ examples/stream_l2_marketdata.py,sha256=ZeQlap7YeLg19IdAHnSc95IFFaQ7PgCY2S0MZY4RIvY,1091
183
+ examples/trades.py,sha256=ikMvpLy_b5Y4_2URhkAgdOTzAEC-DAAKilUZenw_J_c,561
184
+ examples/tutorial_async.py,sha256=paanYeCyydHVE_srO-lxj9tpmf4r535dhYaXUV95SN8,2646
185
+ examples/tutorial_sync.py,sha256=G6jsxlpxnaewll4XCER6AYMCAK-1Z_A0Zef4D9CKGvw,2824
184
186
  scripts/add_imports_to_inits.py,sha256=bryhz6RpKAJsSieVMnXnRyLp8evNkpOsNUkBUPkk1WQ,4518
185
187
  scripts/correct_sync_interface.py,sha256=O8qxSqNSNIL8KrgZ4C8rjs_pUCdcA1WeqKAggM2DINw,4056
186
188
  scripts/generate_functions_md.py,sha256=-rVRhbHlDodGH2a32UCsMLIpgXtDvOhBmkHa0RqDpCA,6232
@@ -188,8 +190,8 @@ scripts/postprocess_grpc.py,sha256=QqFZdOLH6hLPRCLUkf7qvuGooLsXulcpMghCpleHc-A,2
188
190
  scripts/preprocess_grpc_schema.py,sha256=p9LdoMZzixBSsVx7Dy3_8uJzOy_QwCoVMkAABQKUsBA,22894
189
191
  scripts/prune_graphql_schema.py,sha256=hmfw5FD_iKGKMFkq6H1neZiXXtljFFrOwi2fiusTWE4,6210
190
192
  templates/exceptions.py,sha256=tIHbiO5Q114h9nPwJXsgHvW_bERLwxuNp9Oj41p6t3A,2379
191
- templates/juniper_base_client.py,sha256=x3W5bRmeAK-oznsjJm_4TvrRJJICW23jKHcCKUIj7Vg,12577
192
- architect_py-5.1.0b1.dist-info/METADATA,sha256=gdF0ZucoSHYWHr8320fPwGYKbfaPeFghMQmfLzFX5_I,2369
193
- architect_py-5.1.0b1.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
194
- architect_py-5.1.0b1.dist-info/top_level.txt,sha256=UjtO97OACFQ9z5MzS-X2wBlt5Ovk1vxakQPKfokI454,40
195
- architect_py-5.1.0b1.dist-info/RECORD,,
193
+ templates/juniper_base_client.py,sha256=B8QF4IFSwqBK5UY2aFPbSdYnX9bcwnlxLK4ojPRaW0E,12705
194
+ architect_py-5.1.2.dist-info/METADATA,sha256=9Kut96FHWLTstvnSxNhaf5bvSCdI1JzzY4BettvbdBk,2559
195
+ architect_py-5.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
196
+ architect_py-5.1.2.dist-info/top_level.txt,sha256=UjtO97OACFQ9z5MzS-X2wBlt5Ovk1vxakQPKfokI454,40
197
+ architect_py-5.1.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.8.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -46,6 +46,8 @@ async def main():
46
46
  except ValidationError as e:
47
47
  print(e)
48
48
 
49
+ await c.close()
50
+
49
51
 
50
52
  if __name__ == "__main__":
51
53
  asyncio.run(main())
examples/candles.py CHANGED
@@ -24,5 +24,7 @@ async def main():
24
24
  print(e.status_code)
25
25
  print(e.response.json())
26
26
 
27
+ await c.close()
28
+
27
29
 
28
30
  asyncio.run(main())
@@ -184,6 +184,7 @@ async def main():
184
184
  print_info(c),
185
185
  subscribe_and_print_orderflow(c, orderflow_requester),
186
186
  )
187
+ await c.close()
187
188
 
188
189
 
189
190
  asyncio.run(main())
examples/order_sending.py CHANGED
@@ -36,7 +36,7 @@ async def test_send_order(client: AsyncClient, account: str):
36
36
 
37
37
  order = await client.place_limit_order(
38
38
  symbol=symbol,
39
- odir=OrderDir.BUY,
39
+ dir=OrderDir.BUY,
40
40
  quantity=best_bid_quantity,
41
41
  order_type=OrderType.LIMIT,
42
42
  execution_venue="CME",
@@ -67,7 +67,7 @@ async def test_send_market_pro_order(client: AsyncClient, account: str):
67
67
  await client.send_market_pro_order(
68
68
  symbol=symbol,
69
69
  execution_venue=venue,
70
- odir=OrderDir.BUY,
70
+ dir=OrderDir.BUY,
71
71
  quantity=Decimal(1),
72
72
  account=account,
73
73
  time_in_force=TimeInForce.IOC,
@@ -84,7 +84,7 @@ async def send_NQ_buy_for_mid(client: AsyncClient, account: str):
84
84
 
85
85
  order = await client.place_limit_order(
86
86
  symbol=NQ_lead_future,
87
- odir=OrderDir.BUY,
87
+ dir=OrderDir.BUY,
88
88
  quantity=Decimal(1),
89
89
  order_type=OrderType.LIMIT,
90
90
  execution_venue=CME,
@@ -104,6 +104,8 @@ async def main():
104
104
  await test_send_order(client, account)
105
105
  await test_send_market_pro_order(client, account)
106
106
 
107
+ await client.close()
108
+
107
109
 
108
110
  if __name__ == "__main__":
109
111
  loop = asyncio.new_event_loop()