architect-py 5.1.4b1__py3-none-any.whl → 5.1.5__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 +19 -1
  2. architect_py/async_client.py +158 -45
  3. architect_py/client.py +4 -0
  4. architect_py/client.pyi +33 -9
  5. architect_py/grpc/client.py +24 -9
  6. architect_py/grpc/models/AlgoHelper/AlgoParamTypes.py +31 -0
  7. architect_py/grpc/models/AlgoHelper/__init__.py +2 -0
  8. architect_py/grpc/models/Auth/AuthInfoRequest.py +37 -0
  9. architect_py/grpc/models/Auth/AuthInfoResponse.py +30 -0
  10. architect_py/grpc/models/Core/ConfigResponse.py +7 -2
  11. architect_py/grpc/models/Folio/AccountHistoryRequest.py +35 -4
  12. architect_py/grpc/models/Folio/AccountSummary.py +7 -1
  13. architect_py/grpc/models/Marketdata/Candle.py +6 -0
  14. architect_py/grpc/models/Marketdata/L1BookSnapshot.py +17 -3
  15. architect_py/grpc/models/Marketdata/L2BookSnapshot.py +6 -0
  16. architect_py/grpc/models/Marketdata/Liquidation.py +6 -0
  17. architect_py/grpc/models/Marketdata/Ticker.py +6 -0
  18. architect_py/grpc/models/Marketdata/Trade.py +6 -0
  19. architect_py/grpc/models/Oms/Order.py +38 -14
  20. architect_py/grpc/models/Oms/PlaceOrderRequest.py +38 -14
  21. architect_py/grpc/models/__init__.py +4 -1
  22. architect_py/grpc/models/definitions.py +173 -0
  23. architect_py/grpc/orderflow.py +138 -0
  24. architect_py/tests/test_order_entry.py +9 -6
  25. architect_py/tests/test_orderflow.py +116 -27
  26. architect_py/tests/test_positions.py +173 -0
  27. architect_py/tests/test_rounding.py +28 -28
  28. architect_py/utils/pandas.py +50 -1
  29. {architect_py-5.1.4b1.dist-info → architect_py-5.1.5.dist-info}/METADATA +1 -1
  30. {architect_py-5.1.4b1.dist-info → architect_py-5.1.5.dist-info}/RECORD +35 -29
  31. examples/funding_rate_mean_reversion_algo.py +23 -47
  32. scripts/postprocess_grpc.py +17 -2
  33. {architect_py-5.1.4b1.dist-info → architect_py-5.1.5.dist-info}/WHEEL +0 -0
  34. {architect_py-5.1.4b1.dist-info → architect_py-5.1.5.dist-info}/licenses/LICENSE +0 -0
  35. {architect_py-5.1.4b1.dist-info → architect_py-5.1.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,173 @@
1
+ import asyncio
2
+ from decimal import Decimal
3
+
4
+ import pytest
5
+
6
+ from architect_py.async_client import AsyncClient, OrderDir, OrderType
7
+
8
+
9
+ @pytest.mark.asyncio
10
+ @pytest.mark.timeout(10)
11
+ async def test_positions(async_client: AsyncClient):
12
+ if not async_client.paper_trading:
13
+ return
14
+
15
+ accounts = await async_client.list_accounts()
16
+
17
+ assert len(accounts) == 1, (
18
+ f"Expected exactly one account in paper trading mode, got {len(accounts)}"
19
+ )
20
+ account_id = accounts[0].account.id
21
+ front_ES_future = await async_client.get_front_future("ES CME Futures", "CME")
22
+ positions = await async_client.get_positions(accounts=[account_id])
23
+ ES_position = positions.get(front_ES_future)
24
+
25
+ # flatten position
26
+ if ES_position is not None:
27
+ flatten_direction = OrderDir.SELL if ES_position > Decimal(0) else OrderDir.BUY
28
+
29
+ order = await async_client.place_order(
30
+ symbol=front_ES_future,
31
+ venue="CME",
32
+ dir=flatten_direction,
33
+ quantity=Decimal(value="1"),
34
+ account=account_id,
35
+ order_type=OrderType.MARKET,
36
+ )
37
+ while True:
38
+ open_orders = await async_client.get_open_orders(order_ids=[order.id])
39
+ if not open_orders:
40
+ break
41
+ await asyncio.sleep(0.2)
42
+
43
+ fills = await async_client.get_fills(order_id=order.id)
44
+ assert len(fills.fills) == 1, "Expected exactly one fill for the order"
45
+ assert fills.fills[0].dir == flatten_direction, (
46
+ "Fill direction does not match order direction"
47
+ )
48
+
49
+ # go long
50
+ order = await async_client.place_order(
51
+ symbol=front_ES_future,
52
+ venue="CME",
53
+ dir=OrderDir.BUY,
54
+ quantity=Decimal(value="5"),
55
+ account=account_id,
56
+ order_type=OrderType.MARKET,
57
+ )
58
+ positions = await async_client.get_positions(accounts=[account_id])
59
+ assert positions.get(front_ES_future) == Decimal(5), (
60
+ f"Expected position in {front_ES_future} to be 5, got {positions.get(front_ES_future)}"
61
+ )
62
+
63
+ # go long to flat
64
+ order = await async_client.place_order(
65
+ symbol=front_ES_future,
66
+ venue="CME",
67
+ dir=OrderDir.SELL,
68
+ quantity=Decimal(value="5"),
69
+ account=account_id,
70
+ order_type=OrderType.MARKET,
71
+ )
72
+ positions = await async_client.get_positions(accounts=[account_id])
73
+ assert positions.get(front_ES_future) is None, (
74
+ f"Expected position in {front_ES_future} to be 0, got {positions.get(front_ES_future)}"
75
+ )
76
+
77
+ # go long
78
+ order = await async_client.place_order(
79
+ symbol=front_ES_future,
80
+ venue="CME",
81
+ dir=OrderDir.BUY,
82
+ quantity=Decimal(value="8"),
83
+ account=account_id,
84
+ order_type=OrderType.MARKET,
85
+ )
86
+ positions = await async_client.get_positions(accounts=[account_id])
87
+ assert positions.get(front_ES_future) == Decimal(8), (
88
+ f"Expected position in {front_ES_future} to be 8, got {positions.get(front_ES_future)}"
89
+ )
90
+
91
+ # go long to short
92
+ order = await async_client.place_order(
93
+ symbol=front_ES_future,
94
+ venue="CME",
95
+ dir=OrderDir.SELL,
96
+ quantity=Decimal(value="10"),
97
+ account=account_id,
98
+ order_type=OrderType.MARKET,
99
+ )
100
+ positions = await async_client.get_positions(accounts=[account_id])
101
+ assert positions.get(front_ES_future) == Decimal(-2), (
102
+ f"Expected position in {front_ES_future} to be -2, got {positions.get(front_ES_future)}"
103
+ )
104
+
105
+ # go flat
106
+ order = await async_client.place_order(
107
+ symbol=front_ES_future,
108
+ venue="CME",
109
+ dir=OrderDir.BUY,
110
+ quantity=Decimal(value="2"),
111
+ account=account_id,
112
+ order_type=OrderType.MARKET,
113
+ )
114
+ positions = await async_client.get_positions(accounts=[account_id])
115
+ assert positions.get(front_ES_future) is None, (
116
+ f"Expected position in {front_ES_future} to be 0, got {positions.get(front_ES_future)}"
117
+ )
118
+
119
+ # go short
120
+ order = await async_client.place_order(
121
+ symbol=front_ES_future,
122
+ venue="CME",
123
+ dir=OrderDir.SELL,
124
+ quantity=Decimal(value="5"),
125
+ account=account_id,
126
+ order_type=OrderType.MARKET,
127
+ )
128
+ positions = await async_client.get_positions(accounts=[account_id])
129
+ assert positions.get(front_ES_future) == Decimal(-5), (
130
+ f"Expected position in {front_ES_future} to be -5, got {positions.get(front_ES_future)}"
131
+ )
132
+
133
+ # go short to flat
134
+ order = await async_client.place_order(
135
+ symbol=front_ES_future,
136
+ venue="CME",
137
+ dir=OrderDir.BUY,
138
+ quantity=Decimal(value="5"),
139
+ account=account_id,
140
+ order_type=OrderType.MARKET,
141
+ )
142
+ positions = await async_client.get_positions(accounts=[account_id])
143
+ assert positions.get(front_ES_future) is None, (
144
+ f"Expected position in {front_ES_future} to be 0, got {positions.get(front_ES_future)}"
145
+ )
146
+
147
+ # go short
148
+ order = await async_client.place_order(
149
+ symbol=front_ES_future,
150
+ venue="CME",
151
+ dir=OrderDir.SELL,
152
+ quantity=Decimal(value="5"),
153
+ account=account_id,
154
+ order_type=OrderType.MARKET,
155
+ )
156
+ positions = await async_client.get_positions(accounts=[account_id])
157
+ assert positions.get(front_ES_future) == Decimal(-5), (
158
+ f"Expected position in {front_ES_future} to be -5, got {positions.get(front_ES_future)}"
159
+ )
160
+
161
+ # go short to long
162
+ order = await async_client.place_order(
163
+ symbol=front_ES_future,
164
+ venue="CME",
165
+ dir=OrderDir.BUY,
166
+ quantity=Decimal(value="10"),
167
+ account=account_id,
168
+ order_type=OrderType.MARKET,
169
+ )
170
+ positions = await async_client.get_positions(accounts=[account_id])
171
+ assert positions.get(front_ES_future) == Decimal(5), (
172
+ f"Expected position in {front_ES_future} to be 5, got {positions.get(front_ES_future)}"
173
+ )
@@ -1,41 +1,41 @@
1
- # from decimal import Decimal
1
+ from decimal import Decimal
2
2
 
3
- # from architect_py.utils.nearest_tick import TickRoundMethod
3
+ from architect_py.utils.nearest_tick import TickRoundMethod
4
4
 
5
5
 
6
- # def test_rounding():
7
- # # Example usage
8
- # value = Decimal("123.454")
9
- # tick_size = Decimal("0.01")
6
+ def _test_rounding():
7
+ # Example usage
8
+ value = Decimal("123.454")
9
+ tick_size = Decimal("0.01")
10
10
 
11
- # rounded_value = TickRoundMethod.ROUND(value, tick_size=tick_size)
12
- # assert rounded_value == Decimal("123.45")
11
+ rounded_value = TickRoundMethod.ROUND(value, tick_size=tick_size)
12
+ assert rounded_value == Decimal("123.45")
13
13
 
14
- # rounded_ceil = TickRoundMethod.CEIL(value, tick_size)
15
- # assert rounded_ceil == Decimal("123.46")
14
+ rounded_ceil = TickRoundMethod.CEIL(value, tick_size)
15
+ assert rounded_ceil == Decimal("123.46")
16
16
 
17
- # rounded_floor = TickRoundMethod.FLOOR(value, tick_size)
18
- # assert rounded_floor == Decimal("123.45")
17
+ rounded_floor = TickRoundMethod.FLOOR(value, tick_size)
18
+ assert rounded_floor == Decimal("123.45")
19
19
 
20
- # rounded_floor = TickRoundMethod.FLOOR(Decimal("123.459"), tick_size)
21
- # assert rounded_floor == Decimal("123.45")
20
+ rounded_floor = TickRoundMethod.FLOOR(Decimal("123.459"), tick_size)
21
+ assert rounded_floor == Decimal("123.45")
22
22
 
23
- # rounded_toward_zero_pos = TickRoundMethod.TOWARD_ZERO(value, tick_size)
24
- # assert rounded_toward_zero_pos == Decimal("123.45")
23
+ rounded_toward_zero_pos = TickRoundMethod.TOWARD_ZERO(value, tick_size)
24
+ assert rounded_toward_zero_pos == Decimal("123.45")
25
25
 
26
- # value_negative = Decimal("-123.456")
27
- # rounded_toward_zero_neg = TickRoundMethod.TOWARD_ZERO(value_negative, tick_size)
28
- # assert rounded_toward_zero_neg == Decimal("-123.45")
26
+ value_negative = Decimal("-123.456")
27
+ rounded_toward_zero_neg = TickRoundMethod.TOWARD_ZERO(value_negative, tick_size)
28
+ assert rounded_toward_zero_neg == Decimal("-123.45")
29
29
 
30
- # rounded_away_from_zero_pos = TickRoundMethod.AWAY_FROM_ZERO(value, tick_size)
31
- # assert rounded_away_from_zero_pos == Decimal("123.46")
30
+ rounded_away_from_zero_pos = TickRoundMethod.AWAY_FROM_ZERO(value, tick_size)
31
+ assert rounded_away_from_zero_pos == Decimal("123.46")
32
32
 
33
- # rounded_away_from_zero_neg = TickRoundMethod.AWAY_FROM_ZERO(
34
- # value_negative, tick_size
35
- # )
36
- # assert rounded_away_from_zero_neg == Decimal("-123.46")
33
+ rounded_away_from_zero_neg = TickRoundMethod.AWAY_FROM_ZERO(
34
+ value_negative, tick_size
35
+ )
36
+ assert rounded_away_from_zero_neg == Decimal("-123.46")
37
37
 
38
38
 
39
- # if __name__ == "__main__":
40
- # test_rounding()
41
- # print("rounding.py: All tests passed!")
39
+ if __name__ == "__main__":
40
+ _test_rounding()
41
+ print("rounding.py: All tests passed!")
@@ -4,7 +4,7 @@ import msgspec
4
4
  import pandas as pd
5
5
 
6
6
  if TYPE_CHECKING:
7
- from .. import Candle
7
+ from .. import Candle, Ticker
8
8
 
9
9
  CANDLES_FIELD_MAP = {
10
10
  "av": "sell_volume",
@@ -43,3 +43,52 @@ def candles_to_dataframe(candles: List["Candle"]) -> pd.DataFrame:
43
43
  df.style.hide(["tn", "ts"], axis=1)
44
44
  df.set_index("timestamp", inplace=True)
45
45
  return df
46
+
47
+
48
+ def tickers_to_dataframe(tickers: List["Ticker"]) -> pd.DataFrame:
49
+ records = msgspec.to_builtins(tickers)
50
+ df = pd.DataFrame.from_records(records)
51
+ df.rename(
52
+ columns={
53
+ "s": "symbol",
54
+ "ve": "venue",
55
+ "ap": "ask_price",
56
+ "as": "ask_size",
57
+ "bp": "bid_price",
58
+ "bs": "bid_size",
59
+ "dividend": "dividend",
60
+ "dividend_yield": "dividend_yield",
61
+ "eps_adj": "eps_adj",
62
+ "fr": "funding_rate",
63
+ "ft": "next_funding_time",
64
+ "h": "high_24h",
65
+ "ip": "index_price",
66
+ "isp": "indicative_settlement_price",
67
+ "l": "low_24h",
68
+ "market_cap": "market_cap",
69
+ "mp": "mark_price",
70
+ "o": "open_24h",
71
+ "oi": "open_interest",
72
+ "p": "last_price",
73
+ "price_to_earnings": "price_to_earnings",
74
+ "q": "last_size",
75
+ "sd": "last_settlement_date",
76
+ "shares_outstanding_weighted_adj": "shares_outstanding_weighted_adj",
77
+ "sp": "last_settlement_price",
78
+ "v": "volume_24h",
79
+ "vm": "volume_30d",
80
+ "xh": "session_high",
81
+ "xl": "session_low",
82
+ "xo": "session_open",
83
+ "xv": "session_volume",
84
+ },
85
+ inplace=True,
86
+ )
87
+ df["timestamp"] = pd.to_datetime(
88
+ df["ts"] * 1_000_000_000 + df["tn"],
89
+ unit="ns",
90
+ utc=True,
91
+ )
92
+ df.style.hide(["tn", "ts"], axis=1)
93
+ df.set_index("symbol", inplace=True)
94
+ return df
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: architect-py
3
- Version: 5.1.4b1
3
+ Version: 5.1.5
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
@@ -1,7 +1,7 @@
1
- architect_py/__init__.py,sha256=8CrccOPnPzBy9EjbeXrvHImwdFvNofKqInTPsDz-9Fw,16123
2
- architect_py/async_client.py,sha256=k6bGfqkan0sdlKI2LOYTRwwT-UZLPDgKagxo_IUqhxU,62227
3
- architect_py/client.py,sha256=S9FsNoRJGB2xiE6H1nPPIg_-oAPZ5qPOBWy_4Hw0UuI,5056
4
- architect_py/client.pyi,sha256=bXd7pjtc1lDCB0l6tRkHr8tydz7n65TUpsyUeYaqV_4,24801
1
+ architect_py/__init__.py,sha256=jrffx1fAChnV8djCoFdEmsTwyHTCkw0_P3RvSimjcx8,16666
2
+ architect_py/async_client.py,sha256=jU_P4McMXGsKhUIov0CEXG27qi4SdfIVZkU3uFc-md8,65827
3
+ architect_py/client.py,sha256=y8w17ZLo_Y2-knH-46qqVGlSJyQHB9qwOPodI9pzN-Q,5192
4
+ architect_py/client.pyi,sha256=w8yM9u2TQvm12DHoEunq0CKTQ0EVOqrkh_iuNMf1Dk8,26113
5
5
  architect_py/common_types/__init__.py,sha256=fzOdIlKGWVN9V2Onc5z1v2bpvtZ4H9RSFA9ymJcBi3k,197
6
6
  architect_py/common_types/order_dir.py,sha256=ebyWTcXzJWrotkc2D9wNGc6JXbE5I3NLLuAz3I7FTZ8,2191
7
7
  architect_py/common_types/time_in_force.py,sha256=gEDYcNp014Eeb98zJDytiV0hGxHu_QsQndeM6Hk0Wa8,3132
@@ -23,12 +23,13 @@ architect_py/graphql_client/juniper_base_client.py,sha256=0kbAihyRgEP3n28zRumoST
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=qApYInm_eEhSFKYZRQ_EJyrV-PMA1AOhJ1PoArzGGvM,3597
26
+ architect_py/grpc/client.py,sha256=qoH-bb-sDjoDlYYmByQVbzYBbCimFY_AmoOLEBDxEtA,4096
27
+ architect_py/grpc/orderflow.py,sha256=XKysE11lK7yKXMctLvNTqq4g5F_DoKJT_8Jx37bgTLE,4836
27
28
  architect_py/grpc/resolve_endpoint.py,sha256=r_PBWANIJJ47N5uyPcnefZ21ZE1-mzgACfCBfQpekg8,2621
28
29
  architect_py/grpc/server.py,sha256=Abmdfe1eYbctVgzoJYBBBLpd7UD70FbYQLtJImSyRzs,1934
29
30
  architect_py/grpc/utils.py,sha256=5sykLExUNZbcQHcxLCCM9DdOOiJJZcpputGrDtaMifY,667
30
- architect_py/grpc/models/__init__.py,sha256=RrTLZvU7mNykDNp1oOm4-dekzab9ugIXd_my7Sm0Vx4,9153
31
- architect_py/grpc/models/definitions.py,sha256=UB2-xXjoAM6ZTkNrsa1Q2-W_t6XUWHykP_R5tqzDcbc,77048
31
+ architect_py/grpc/models/__init__.py,sha256=DVsP-OURNPSlFKWxQGShF7ytvOUJc2_fQ-ng5kOh1X8,9366
32
+ architect_py/grpc/models/definitions.py,sha256=fWVidMJ4pEzP7Z6bLhyYlSYxGttfH40Vgki1P9b47ow,82836
32
33
  architect_py/grpc/models/Accounts/AccountsRequest.py,sha256=1a88cltSebOb53EdJ0hKEGR7FlmBiibrCtGzLTKqDBY,1524
33
34
  architect_py/grpc/models/Accounts/AccountsResponse.py,sha256=DlXbkd3UbRybblBAfokw-K6nRvLNZgqz7cc0EKiW1zI,636
34
35
  architect_py/grpc/models/Accounts/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
@@ -44,6 +45,10 @@ architect_py/grpc/models/Algo/StartAlgoResponse.py,sha256=mS5kF5NEreJo6cNu4HFoDk
44
45
  architect_py/grpc/models/Algo/StopAlgoRequest.py,sha256=pKmj0L9cNTfuA682QnM87PjRBcJ_IsWPvKJdulK8Nwo,997
45
46
  architect_py/grpc/models/Algo/StopAlgoResponse.py,sha256=_HTDziNPpcVHTABHP-bdHGgro-lQRC44zf8J0Hv5dbA,418
46
47
  architect_py/grpc/models/Algo/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
48
+ architect_py/grpc/models/AlgoHelper/AlgoParamTypes.py,sha256=U-zgHxcPlND283rqjvWkFPWlYORTKNQDRAAmbr3SepE,779
49
+ architect_py/grpc/models/AlgoHelper/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
50
+ architect_py/grpc/models/Auth/AuthInfoRequest.py,sha256=9MfFQzf2O4SZ156Bb-bJrTIT1uMpbMiv7XlD0E0MHzk,825
51
+ architect_py/grpc/models/Auth/AuthInfoResponse.py,sha256=mok-7QUahZUlzBAosuQ5ng0ESSdcWLfXIywt3rgvYn4,813
47
52
  architect_py/grpc/models/Auth/CreateJwtRequest.py,sha256=3ezxlv3LbqZhM00kUrdn5OtYBGVMCZtw05m8NNOYMTI,1110
48
53
  architect_py/grpc/models/Auth/CreateJwtResponse.py,sha256=G1rsG7f4gMiWK4WVxTZMzFSy08z80nQCnZHJWWfXDNQ,483
49
54
  architect_py/grpc/models/Auth/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
@@ -59,7 +64,7 @@ architect_py/grpc/models/Boss/WithdrawalsRequest.py,sha256=876d2gsGbSTPZ74wCoe0n
59
64
  architect_py/grpc/models/Boss/WithdrawalsResponse.py,sha256=th6r28rjNBUuMBs95lwf9pxaxFtrwKJ_VAq7egwMVM8,632
60
65
  architect_py/grpc/models/Boss/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
61
66
  architect_py/grpc/models/Core/ConfigRequest.py,sha256=9taH97J4b-_Co7d-o_zHOPg_vckc_InvnADXYpd_MlM,809
62
- architect_py/grpc/models/Core/ConfigResponse.py,sha256=pQimTNwdE-FL2Z1Pq6_YRPmagt-ZgJoub9P1lpj0gVk,556
67
+ architect_py/grpc/models/Core/ConfigResponse.py,sha256=fjOEuwTyawepSaVGfLXqhmo_1ssDsDbyYkxje_SwBlU,717
63
68
  architect_py/grpc/models/Core/RestartCptyRequest.py,sha256=Hl_uSGkMFE9yPonClcNE24neeib8LP3fHH6UwpI_WSQ,916
64
69
  architect_py/grpc/models/Core/RestartCptyResponse.py,sha256=aCyJfucfFGHieGURjEejeT9HPoaKJ2xCGPVqw5pcCJs,427
65
70
  architect_py/grpc/models/Core/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
@@ -70,11 +75,11 @@ architect_py/grpc/models/Cpty/CptyStatusRequest.py,sha256=5eYYL2L5TmFKgoUuAInvFS
70
75
  architect_py/grpc/models/Cpty/CptysRequest.py,sha256=th1vto4vclExgZD4HwXaNy87amRP2oM1ix4WLetnIW8,801
71
76
  architect_py/grpc/models/Cpty/CptysResponse.py,sha256=cQiRp3VEewfcCKRxqdXpMT2EEZujO3h9LZtHATBDPtk,568
72
77
  architect_py/grpc/models/Cpty/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
73
- architect_py/grpc/models/Folio/AccountHistoryRequest.py,sha256=dAPd5pFHCcw1CauCbbTx_foKnPB2PTtbv6BZUh5H0dI,1407
78
+ architect_py/grpc/models/Folio/AccountHistoryRequest.py,sha256=62zM93rALjckq8y5sA-6OvtB6zwpUOIXRtUik_tehQA,2837
74
79
  architect_py/grpc/models/Folio/AccountHistoryResponse.py,sha256=3CUKPrqbUpH1MRYFZi2Q4dfN-nzcM6OxM_FA5pA_OyQ,622
75
80
  architect_py/grpc/models/Folio/AccountSummariesRequest.py,sha256=epYjLFc1cMblp04li_WSCIcl4bFJEjDedJNO9D2x1bg,1595
76
81
  architect_py/grpc/models/Folio/AccountSummariesResponse.py,sha256=YoJddUl0TB1pkoI7C_avt94RSL9ZCf2u8_kOYpewRGI,678
77
- architect_py/grpc/models/Folio/AccountSummary.py,sha256=MtIzJ4v78gD1jZPoa4ooV6H3sctfOf1FV2vgiUiXDp4,3633
82
+ architect_py/grpc/models/Folio/AccountSummary.py,sha256=2upTyjDCpkxIXZ40DjUmZFaBBnmIbhF1htijOoCc2D4,3816
78
83
  architect_py/grpc/models/Folio/AccountSummaryRequest.py,sha256=qu9f-liMEOqxq8LM2h9EosCj2vtTJwduUKjiwYO8GTo,1002
79
84
  architect_py/grpc/models/Folio/HistoricalFillsRequest.py,sha256=ybd6vIO1xkiovUW9Q-Pl4K21kfmFX8uMOoE7LZqsOLU,2241
80
85
  architect_py/grpc/models/Folio/HistoricalFillsResponse.py,sha256=MmHFvt-FuLgw93fHN8lfcyMsG2qHys1gUD0gq0QZGyM,775
@@ -85,16 +90,16 @@ architect_py/grpc/models/Health/HealthCheckRequest.py,sha256=uKxA8HbItw-MF-LfHk7
85
90
  architect_py/grpc/models/Health/HealthCheckResponse.py,sha256=0yh75XgiyrJdNet4xx5_u7gyW6Qx8fwTPO9h6E_HVWU,755
86
91
  architect_py/grpc/models/Health/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
87
92
  architect_py/grpc/models/Marketdata/ArrayOfL1BookSnapshot.py,sha256=Os13kKncZgwoCqrorTspvcj8EO7u4Xr3fNQV8mWONFM,329
88
- architect_py/grpc/models/Marketdata/Candle.py,sha256=VDGh7cDiDhu91dAxARLMJkE2CqJvOLL4m1Z8u-cK9KE,8259
93
+ architect_py/grpc/models/Marketdata/Candle.py,sha256=GIidzpVm9CwxbkIS3cJiRB_WaWQ3vwoGr_g6dSaDl9I,8472
89
94
  architect_py/grpc/models/Marketdata/HistoricalCandlesRequest.py,sha256=uJvsHOn2gXD9w4ybk1iXu4Z1LJ4g5g89y_DIwAMUChY,1587
90
95
  architect_py/grpc/models/Marketdata/HistoricalCandlesResponse.py,sha256=_LGtTw6dVMtF0U6N7l68IbxDDMcooOEW7YsJaoLtniY,604
91
- architect_py/grpc/models/Marketdata/L1BookSnapshot.py,sha256=X7Jm7vpBuyDJx1XI5-1XvjH5gw8h-7pap_1RTv9PHw8,3541
96
+ architect_py/grpc/models/Marketdata/L1BookSnapshot.py,sha256=tM-2KEhy3M8hxwfDpPLDmNYIh_cfblWZkRVk_A1k6Ww,3874
92
97
  architect_py/grpc/models/Marketdata/L1BookSnapshotRequest.py,sha256=9TxfqAivsmZgmIuIemmX6A9bTvMvVU6rWYDGi86gZZg,1072
93
98
  architect_py/grpc/models/Marketdata/L1BookSnapshotsRequest.py,sha256=TFGnuPfTcHMSO849WnEPj1a52RsVReAEWqQ9Fb3La1g,1189
94
- architect_py/grpc/models/Marketdata/L2BookSnapshot.py,sha256=MEyDSZ6LfAtyujGLRZ6pts5o7UNIp8A9_kqV6K7Y-k8,2572
99
+ architect_py/grpc/models/Marketdata/L2BookSnapshot.py,sha256=bvJJPfXMhS68J8M2U6Yb-yvLJuCLy_dUF_viG0udBWM,2785
95
100
  architect_py/grpc/models/Marketdata/L2BookSnapshotRequest.py,sha256=9qRKbwY2KLtW2F-40XOvRfT73kVPTymL0Q3JCR2EbtU,1072
96
101
  architect_py/grpc/models/Marketdata/L2BookUpdate.py,sha256=i-kWdJZvAoYEI280TfC3sTH46VIpMoj8N2UxWAkTDLs,2602
97
- architect_py/grpc/models/Marketdata/Liquidation.py,sha256=cLKfosZl0gdVuL3qoFuJ32UB7Xjk9vVhOxsoc_QNLEw,2420
102
+ architect_py/grpc/models/Marketdata/Liquidation.py,sha256=QFco-zA3xUKstAbFkJ4qn_uluQ8XK6yDApvQULsSl3Y,2633
98
103
  architect_py/grpc/models/Marketdata/MarketStatus.py,sha256=4Kt2z16t7dpjpiELWshJyyH1b-D07YdQchjGMvZkSRM,977
99
104
  architect_py/grpc/models/Marketdata/MarketStatusRequest.py,sha256=ajyI4UlvFusyM0743dukT4KFZTlp9iUh0lTGWl6n7nw,1056
100
105
  architect_py/grpc/models/Marketdata/SubscribeCandlesRequest.py,sha256=ck5pQx54uymlpR-jxFpxcW0LPDLU7R8GvqLqF-7GmoU,1508
@@ -105,12 +110,12 @@ architect_py/grpc/models/Marketdata/SubscribeLiquidationsRequest.py,sha256=6BhC4
105
110
  architect_py/grpc/models/Marketdata/SubscribeManyCandlesRequest.py,sha256=pel2GGysDsJXjPY7rkyqqyGS3MPl13YezJS7apihiFc,1512
106
111
  architect_py/grpc/models/Marketdata/SubscribeTickersRequest.py,sha256=7g2LBAYd97OJ9FrxpUvZKO7hSMng-K4KfnsN08O4XSM,1437
107
112
  architect_py/grpc/models/Marketdata/SubscribeTradesRequest.py,sha256=7P8FyNx6wijNUBGry0vaMhaEKuG1ik8kTibJBvdol2k,1299
108
- architect_py/grpc/models/Marketdata/Ticker.py,sha256=O4kJK1RyThYgfpvIr9mgRWAAkYgwwAKgOhEhbfDo9b4,11592
113
+ architect_py/grpc/models/Marketdata/Ticker.py,sha256=ti8Z3HEePBGk66DUwgZjKMpBhHrimT_Rv4VYaC7f3rs,11805
109
114
  architect_py/grpc/models/Marketdata/TickerRequest.py,sha256=Ay--5JKgCfdvlVWD2H6YSa_66NC3Dt6c-XK8JkbWhus,1008
110
115
  architect_py/grpc/models/Marketdata/TickerUpdate.py,sha256=sJ4wvCeGckMV30HwAcAsEMQbCzjN31OxF19q70jdxok,437
111
116
  architect_py/grpc/models/Marketdata/TickersRequest.py,sha256=x6UlQdAisnXgs3vbghQY3nuiFccSU3ueU0YJVAKaKUs,2359
112
117
  architect_py/grpc/models/Marketdata/TickersResponse.py,sha256=CLzKx-ItwH9-Qq8YruFhXh7TmtHwzNRMEOPJ9LQD9co,574
113
- architect_py/grpc/models/Marketdata/Trade.py,sha256=RKZq_HUDLxIE41caDrwf99V0c48kH2pm3XRCn5RLcEQ,2476
118
+ architect_py/grpc/models/Marketdata/Trade.py,sha256=NZ-pM4MUNzQvq5RwYOS0_xgmDI17AxdM4t8NKdPnGu8,2689
114
119
  architect_py/grpc/models/Marketdata/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
115
120
  architect_py/grpc/models/Oms/Cancel.py,sha256=P550abgbBqVbC3UE7YaOaEytF__DsTYWsepNvkHaAQE,2357
116
121
  architect_py/grpc/models/Oms/CancelAllOrdersRequest.py,sha256=oCRbluj6nyoDCHQszPDRIBt4ygFyO7QHZhCf8T8-fYM,1474
@@ -118,10 +123,10 @@ architect_py/grpc/models/Oms/CancelAllOrdersResponse.py,sha256=YM1H_nrV4RhpLMEwS
118
123
  architect_py/grpc/models/Oms/CancelOrderRequest.py,sha256=0yJysCf0IcwUevEqVnAkIm-OkOAbp_vOwh1p1ljSsp8,1939
119
124
  architect_py/grpc/models/Oms/OpenOrdersRequest.py,sha256=5Uv9ndI2WqRJgOWNLeKcIV8czb0ff6wHUW0gokeBktg,1804
120
125
  architect_py/grpc/models/Oms/OpenOrdersResponse.py,sha256=HT4YXjbbwdp2rLLXxoetF33DGe2j403soMLme2p18ts,592
121
- architect_py/grpc/models/Oms/Order.py,sha256=jjNSxHO8kdc67xhUdiRmsOdvISQPgtYeQ_pm4H3E5dg,10680
126
+ architect_py/grpc/models/Oms/Order.py,sha256=slEem8b898Hh1Uckc_mhvN2bthVgB-JfDjAlN5uxs94,11683
122
127
  architect_py/grpc/models/Oms/PendingCancelsRequest.py,sha256=jdbBOpCHBlZFAZfF6urJZXXa5Dr5cTRR3AJ9ss4rY6E,1620
123
128
  architect_py/grpc/models/Oms/PendingCancelsResponse.py,sha256=mWRNRDa489Vdg-r7dJMOmfOO8l57yg8lBMynBDcY60A,628
124
- architect_py/grpc/models/Oms/PlaceOrderRequest.py,sha256=se2iSEC_TrL5y-m_CRJkk9jsYLFOGnE57QFwz4Dqtck,8317
129
+ architect_py/grpc/models/Oms/PlaceOrderRequest.py,sha256=DDMkKgsqWVlMhUeidxTlVDHyNdeuPLu29PUwOTd0ijo,9320
125
130
  architect_py/grpc/models/Oms/__init__.py,sha256=sIyaEvJdP-VmGTGPPqZuRjKn4bc7NUClJ76Gd5uq-5s,57
126
131
  architect_py/grpc/models/OptionsMarketdata/OptionsChain.py,sha256=8Sdp57aUXlW13X1POlBKxxaEZofwRZ7VGDLzq1l9GoU,732
127
132
  architect_py/grpc/models/OptionsMarketdata/OptionsChainGreeks.py,sha256=Jhb5CM4t84EdETDO3SOakHkuaWG30Dm4lREpKgBFzFM,742
@@ -158,25 +163,26 @@ architect_py/tests/conftest.py,sha256=XCeq44muZi6i9CxOe9lH7rCmt5pQViWJ_25gSowrLP
158
163
  architect_py/tests/test_book_building.py,sha256=biqs8X9bw1YSb6mrCDS-ELesdD-P5F6bE3MYXP0BeQ4,1236
159
164
  architect_py/tests/test_encoding.py,sha256=J61Lk2CDIqgdcsj0-KYBZweYh5EQ4XAXsRyM0fdMqfU,1085
160
165
  architect_py/tests/test_marketdata.py,sha256=W26OrL51ONAclBjBcm7trS1QPXtLLjdgnsbDR2kqtIw,4963
161
- architect_py/tests/test_order_entry.py,sha256=eD3YrRKTpsJqAI5ahzk4J8uPKXby_XLYIcv_ZaqDKRA,1179
162
- architect_py/tests/test_orderflow.py,sha256=PRCr4Yzaif9OG0Eq1zxCUpTfFsHA3WEWSBiETRDvnIE,1038
166
+ architect_py/tests/test_order_entry.py,sha256=5HDjzNJOC7lSx4driP4mDJr9HuR2cFTwO8s1haGXl9E,1284
167
+ architect_py/tests/test_orderflow.py,sha256=b4iohhs7YUoJMevlUfLQyIoVqjam7pl0BPs0dSfZhqM,3951
163
168
  architect_py/tests/test_portfolio_management.py,sha256=Q4pburTDJ53hrq2_aRbNAOG3nwbCEsgZQGbI_AMHLxE,709
164
- architect_py/tests/test_rounding.py,sha256=cAQ1-tWOVgxENt0Fzs9YcFDdDDYmCtOHvAA_w76wy9g,1417
169
+ architect_py/tests/test_positions.py,sha256=zVO6qmYVn7heQt2C17deYUUCAmJ-u6cnekTmqKm8Vh0,5925
170
+ architect_py/tests/test_rounding.py,sha256=qjuPIdX6TbfPtfrzotZx6-Aodf4et7j3AswgQ7DQtm4,1363
165
171
  architect_py/tests/test_symbology.py,sha256=74fbUgoycuViMHHnurE2Dnfao75wWu_cmQMyU5XQcdY,3436
166
172
  architect_py/tests/test_sync_client.py,sha256=teaHrp-CMpKIDsGPdnyxvmuW_a3hgFftnsnPsFHz9Tw,946
167
173
  architect_py/utils/nearest_tick.py,sha256=i1cCGMSi-sP4Grbp0RCwEsoLzMWN9iC6gPMBm2daDWM,4810
168
174
  architect_py/utils/nearest_tick_2.py,sha256=f-o6b73Mo8epCIaOYBS9F0k_6UHUDSVG1N_VWg7iFBU,3641
169
175
  architect_py/utils/orderbook.py,sha256=JM02NhHbmK3sNaS2Ara8FBY4TvKvtMIzJW1oVd8KC3s,1004
170
- architect_py/utils/pandas.py,sha256=QHz2ynj4T92FobuzRaNoH3ypArHoSDCiGtZ3PVXJ2vo,1017
176
+ architect_py/utils/pandas.py,sha256=Jyiimf6Y5FbTLotUhSIgOnRHMGz7ZvAqNSCHEwZ9eQU,2599
171
177
  architect_py/utils/price_bands.py,sha256=j7ioSA3dx025CD5E2Vg7XQvmjPvxQb-gzQBfQTovpTw,21874
172
178
  architect_py/utils/symbol_parsing.py,sha256=OjJzk2c6QU2s0aJMSyVEzlWD5Vy-RlakJVW7jNHVDJk,845
173
- architect_py-5.1.4b1.dist-info/licenses/LICENSE,sha256=6P0_5gYN8iPWPZeqA9nxiO3tRQmcSA1ijAVR7C8j1SI,11362
179
+ architect_py-5.1.5.dist-info/licenses/LICENSE,sha256=6P0_5gYN8iPWPZeqA9nxiO3tRQmcSA1ijAVR7C8j1SI,11362
174
180
  examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
175
181
  examples/book_subscription.py,sha256=1WFQN_QCE8cRS_CIv2k0NxqpK37fA9-Ja2Kfxs8vsb8,1461
176
182
  examples/candles.py,sha256=T71TsxbfXCT6mrJZmTgdTKesJFdQhYP_4AsiNK-8KyQ,756
177
183
  examples/config.py,sha256=rv6x7QYJO6ckvpRcwghyJbkL_lTBPnK0u6nKgkYTvxQ,1858
178
184
  examples/external_cpty.py,sha256=xxGXONXwoWIS8ys0SgxHLSmntAi1BlwV2NR9WD1kvpc,2527
179
- examples/funding_rate_mean_reversion_algo.py,sha256=Y9zJ7N4TEm36TH3jIHMbDxucKOOlD2VHe5oNcLai11o,6502
185
+ examples/funding_rate_mean_reversion_algo.py,sha256=gv35eKiJeyU7-A6hPtFLsXxmgUxFQSMPYKV-gh2afo0,5650
180
186
  examples/order_sending.py,sha256=0M5eK20nDO5KXJZV-yidC7HR_RHP3uJL9f-q9FF0BIs,3313
181
187
  examples/orderflow_channel.py,sha256=L6W9aZS95Xmjl1IvrKA1Cp06r9-QOERsBETLOg3EImk,1891
182
188
  examples/orderflow_streaming.py,sha256=BtVwCYWBCpytaAFN9u2WPgGCugyNMsGa6nA1dPWuVLs,1300
@@ -189,12 +195,12 @@ examples/tutorial_sync.py,sha256=w5Sqa0YFh0XnpoXuhD3WsKRKpR5cuTTNb7pCp-Aqnz0,284
189
195
  scripts/add_imports_to_inits.py,sha256=bryhz6RpKAJsSieVMnXnRyLp8evNkpOsNUkBUPkk1WQ,4518
190
196
  scripts/correct_sync_interface.py,sha256=gTSJLDAT8s-ayN_JqgKbeM6c3DYZOapduS_GIqrvD-A,4134
191
197
  scripts/generate_functions_md.py,sha256=-rVRhbHlDodGH2a32UCsMLIpgXtDvOhBmkHa0RqDpCA,6232
192
- scripts/postprocess_grpc.py,sha256=QqFZdOLH6hLPRCLUkf7qvuGooLsXulcpMghCpleHc-A,23198
198
+ scripts/postprocess_grpc.py,sha256=1A8HCMG3aBAJaORlBTaYyADow8LOcm2EVeRm0xlF0Gc,23606
193
199
  scripts/preprocess_grpc_schema.py,sha256=p9LdoMZzixBSsVx7Dy3_8uJzOy_QwCoVMkAABQKUsBA,22894
194
200
  scripts/prune_graphql_schema.py,sha256=hmfw5FD_iKGKMFkq6H1neZiXXtljFFrOwi2fiusTWE4,6210
195
201
  templates/exceptions.py,sha256=tIHbiO5Q114h9nPwJXsgHvW_bERLwxuNp9Oj41p6t3A,2379
196
202
  templates/juniper_base_client.py,sha256=B8QF4IFSwqBK5UY2aFPbSdYnX9bcwnlxLK4ojPRaW0E,12705
197
- architect_py-5.1.4b1.dist-info/METADATA,sha256=T9t4zgT065VEpW9f1WGsCXkUNK_O1UQimeeqfrem1uY,2640
198
- architect_py-5.1.4b1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
199
- architect_py-5.1.4b1.dist-info/top_level.txt,sha256=UjtO97OACFQ9z5MzS-X2wBlt5Ovk1vxakQPKfokI454,40
200
- architect_py-5.1.4b1.dist-info/RECORD,,
203
+ architect_py-5.1.5.dist-info/METADATA,sha256=mUUxF_AZbqF0dHqRcn1mivlye9rkUi1KMogf-Qqw9jQ,2638
204
+ architect_py-5.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
205
+ architect_py-5.1.5.dist-info/top_level.txt,sha256=UjtO97OACFQ9z5MzS-X2wBlt5Ovk1vxakQPKfokI454,40
206
+ architect_py-5.1.5.dist-info/RECORD,,
@@ -4,7 +4,7 @@ Do *NOT* run this script in production. This script is for educational purposes
4
4
 
5
5
  import asyncio
6
6
  from decimal import Decimal
7
- from typing import AsyncIterator, Optional
7
+ from typing import Optional
8
8
 
9
9
  from architect_py import (
10
10
  AsyncClient,
@@ -13,16 +13,15 @@ from architect_py import (
13
13
  TimeInForce,
14
14
  TradableProduct,
15
15
  )
16
- from architect_py.graphql_client.exceptions import GraphQLClientHttpError
17
16
  from architect_py.grpc.models.Orderflow.Orderflow import (
18
17
  TaggedOrderAck,
19
18
  TaggedOrderOut,
20
19
  TaggedOrderReject,
21
20
  )
22
21
  from architect_py.grpc.models.Orderflow.OrderflowRequest import (
23
- OrderflowRequest,
24
22
  PlaceOrder,
25
23
  )
24
+ from architect_py.grpc.orderflow import OrderflowChannel
26
25
 
27
26
  from .config import connect_async_client
28
27
 
@@ -36,23 +35,6 @@ target_position = 0
36
35
  current_position = 0
37
36
 
38
37
 
39
- class OrderflowRequester:
40
- def __init__(self):
41
- self.queue: asyncio.Queue[OrderflowRequest] = asyncio.Queue()
42
-
43
- async def __aiter__(self) -> AsyncIterator[OrderflowRequest]:
44
- while True:
45
- value = await self.queue.get() # Wait for a value
46
- yield value # Yield it when available
47
-
48
- async def __anext__(self) -> OrderflowRequest:
49
- return await self.queue.get()
50
-
51
- async def put(self, value: OrderflowRequest) -> None:
52
- # OrderflowRequest contains: PlaceOrder, CancelOrder, CancelAllOrders
53
- await self.queue.put(value) # Put value into the queue
54
-
55
-
56
38
  async def update_marketdata(c: AsyncClient):
57
39
  while True:
58
40
  ticker = await c.get_ticker(tradable_product, venue)
@@ -81,30 +63,23 @@ async def update_marketdata(c: AsyncClient):
81
63
 
82
64
 
83
65
  async def subscribe_and_print_orderflow(
84
- c: AsyncClient, orderflow_requester: OrderflowRequester
85
- ):
86
- try:
87
- stream = c.orderflow(orderflow_requester)
88
- """
89
- subscribe_orderflow_stream is a duplex_stream meaning that it is a stream that can be read from and written to.
90
- This is a stream that will be used to send orders to the Architect and receive order updates from the Architect.
91
- """
92
- async for orderflow in stream:
93
- if isinstance(orderflow, TaggedOrderAck):
94
- print(f"<!> ACK {orderflow.order_id}")
95
- if isinstance(orderflow, TaggedOrderReject):
96
- print(f"<!> REJECT {orderflow.id} {orderflow.r}: {orderflow.rm}")
97
- # reject reason, reject message
98
- elif isinstance(orderflow, TaggedOrderOut):
99
- print(f"<!> OUT {orderflow.id}")
100
- except GraphQLClientHttpError as e:
101
- print(e.status_code)
102
- print(e.response.json())
103
-
104
-
105
- async def step_to_target_position(
106
- c: AsyncClient, orderflow_requester: OrderflowRequester
66
+ c: AsyncClient, orderflow_manager: OrderflowChannel
107
67
  ):
68
+ """
69
+ subscribe_orderflow_stream is a duplex_stream meaning that it is a stream that can be read from and written to.
70
+ This is a stream that will be used to send orders to the Architect and receive order updates from the Architect.
71
+ """
72
+ async for orderflow in orderflow_manager:
73
+ if isinstance(orderflow, TaggedOrderAck):
74
+ print(f"<!> ACK {orderflow.order_id}")
75
+ if isinstance(orderflow, TaggedOrderReject):
76
+ print(f"<!> REJECT {orderflow.id} {orderflow.r}: {orderflow.rm}")
77
+ # reject reason, reject message
78
+ elif isinstance(orderflow, TaggedOrderOut):
79
+ print(f"<!> OUT {orderflow.id}")
80
+
81
+
82
+ async def step_to_target_position(c: AsyncClient, orderflow_manager: OrderflowChannel):
108
83
  while True:
109
84
  await asyncio.sleep(10)
110
85
  # check open orders
@@ -147,7 +122,7 @@ async def step_to_target_position(
147
122
  )
148
123
 
149
124
  if order is not None:
150
- await orderflow_requester.put(
125
+ await orderflow_manager.send(
151
126
  order
152
127
  ) # this will add the order to the queue to send over
153
128
 
@@ -176,13 +151,14 @@ async def print_info(c: AsyncClient):
176
151
  async def main():
177
152
  c = await connect_async_client()
178
153
 
179
- orderflow_requester = OrderflowRequester()
154
+ orderflow_manager = await c.orderflow()
155
+ await orderflow_manager.start()
180
156
 
181
157
  await asyncio.gather(
182
158
  update_marketdata(c),
183
- step_to_target_position(c, orderflow_requester),
159
+ step_to_target_position(c, orderflow_manager),
184
160
  print_info(c),
185
- subscribe_and_print_orderflow(c, orderflow_requester),
161
+ subscribe_and_print_orderflow(c, orderflow_manager),
186
162
  )
187
163
  await c.close()
188
164
 
@@ -358,12 +358,25 @@ def add_post_processing_to_unflattened_types(content: str, json_data: dict) -> s
358
358
  )
359
359
  union_keys = set.union(*map(set, enum_variant_to_other_required_keys.values()))
360
360
 
361
+ if_statement_used = False
361
362
  for i, (enum_value, required_keys) in enumerate(
362
363
  enum_variant_to_other_required_keys.items()
363
364
  ):
364
- conditional = "if" if i == 0 else "elif"
365
+ conditional = "elif" if if_statement_used else "if"
365
366
  title = properties[enum_tag]["title"]
366
367
  req_keys_subset = [key for key in required_keys if key not in common_keys]
368
+
369
+ if not req_keys_subset:
370
+ continue
371
+
372
+ req_keys_titles = []
373
+ for key in req_keys_subset:
374
+ key_title = properties[key].get("title")
375
+ if key_title is None:
376
+ req_keys_titles.append(key)
377
+ else:
378
+ req_keys_titles.append(f"{key_title} ({key})")
379
+
367
380
  should_be_empty_keys: list[str] = list(union_keys - set(required_keys))
368
381
 
369
382
  req_keys_subset.sort()
@@ -373,12 +386,14 @@ def add_post_processing_to_unflattened_types(content: str, json_data: dict) -> s
373
386
  f' {conditional} self.{enum_tag} == "{enum_value}":\n'
374
387
  f" if not all(getattr(self, key) is not None for key in {req_keys_subset}):\n"
375
388
  f' raise ValueError(f"When field {enum_tag} ({title}) is of value {enum_value}, '
376
- f'class {class_title} requires fields {req_keys_subset}")\n'
389
+ f'class {class_title} requires fields {req_keys_titles}")\n'
377
390
  f" elif any(getattr(self, key) is not None for key in {should_be_empty_keys}):\n"
378
391
  f' raise ValueError(f"When field {enum_tag} ({title}) is of value {enum_value}, '
379
392
  f'class {class_title} should not have fields {should_be_empty_keys}")\n'
380
393
  )
381
394
 
395
+ if_statement_used = True
396
+
382
397
  return "".join(lines)
383
398
 
384
399