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.
- architect_py/__init__.py +19 -1
- architect_py/async_client.py +158 -45
- architect_py/client.py +4 -0
- architect_py/client.pyi +33 -9
- architect_py/grpc/client.py +24 -9
- architect_py/grpc/models/AlgoHelper/AlgoParamTypes.py +31 -0
- architect_py/grpc/models/AlgoHelper/__init__.py +2 -0
- architect_py/grpc/models/Auth/AuthInfoRequest.py +37 -0
- architect_py/grpc/models/Auth/AuthInfoResponse.py +30 -0
- architect_py/grpc/models/Core/ConfigResponse.py +7 -2
- architect_py/grpc/models/Folio/AccountHistoryRequest.py +35 -4
- architect_py/grpc/models/Folio/AccountSummary.py +7 -1
- architect_py/grpc/models/Marketdata/Candle.py +6 -0
- architect_py/grpc/models/Marketdata/L1BookSnapshot.py +17 -3
- architect_py/grpc/models/Marketdata/L2BookSnapshot.py +6 -0
- architect_py/grpc/models/Marketdata/Liquidation.py +6 -0
- architect_py/grpc/models/Marketdata/Ticker.py +6 -0
- architect_py/grpc/models/Marketdata/Trade.py +6 -0
- architect_py/grpc/models/Oms/Order.py +38 -14
- architect_py/grpc/models/Oms/PlaceOrderRequest.py +38 -14
- architect_py/grpc/models/__init__.py +4 -1
- architect_py/grpc/models/definitions.py +173 -0
- architect_py/grpc/orderflow.py +138 -0
- architect_py/tests/test_order_entry.py +9 -6
- architect_py/tests/test_orderflow.py +116 -27
- architect_py/tests/test_positions.py +173 -0
- architect_py/tests/test_rounding.py +28 -28
- architect_py/utils/pandas.py +50 -1
- {architect_py-5.1.4b1.dist-info → architect_py-5.1.5.dist-info}/METADATA +1 -1
- {architect_py-5.1.4b1.dist-info → architect_py-5.1.5.dist-info}/RECORD +35 -29
- examples/funding_rate_mean_reversion_algo.py +23 -47
- scripts/postprocess_grpc.py +17 -2
- {architect_py-5.1.4b1.dist-info → architect_py-5.1.5.dist-info}/WHEEL +0 -0
- {architect_py-5.1.4b1.dist-info → architect_py-5.1.5.dist-info}/licenses/LICENSE +0 -0
- {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
|
-
|
1
|
+
from decimal import Decimal
|
2
2
|
|
3
|
-
|
3
|
+
from architect_py.utils.nearest_tick import TickRoundMethod
|
4
4
|
|
5
5
|
|
6
|
-
|
7
|
-
#
|
8
|
-
|
9
|
-
|
6
|
+
def _test_rounding():
|
7
|
+
# Example usage
|
8
|
+
value = Decimal("123.454")
|
9
|
+
tick_size = Decimal("0.01")
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
rounded_value = TickRoundMethod.ROUND(value, tick_size=tick_size)
|
12
|
+
assert rounded_value == Decimal("123.45")
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
rounded_ceil = TickRoundMethod.CEIL(value, tick_size)
|
15
|
+
assert rounded_ceil == Decimal("123.46")
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
rounded_floor = TickRoundMethod.FLOOR(value, tick_size)
|
18
|
+
assert rounded_floor == Decimal("123.45")
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
rounded_floor = TickRoundMethod.FLOOR(Decimal("123.459"), tick_size)
|
21
|
+
assert rounded_floor == Decimal("123.45")
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
rounded_toward_zero_pos = TickRoundMethod.TOWARD_ZERO(value, tick_size)
|
24
|
+
assert rounded_toward_zero_pos == Decimal("123.45")
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
31
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
40
|
-
|
41
|
-
|
39
|
+
if __name__ == "__main__":
|
40
|
+
_test_rounding()
|
41
|
+
print("rounding.py: All tests passed!")
|
architect_py/utils/pandas.py
CHANGED
@@ -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,7 +1,7 @@
|
|
1
|
-
architect_py/__init__.py,sha256=
|
2
|
-
architect_py/async_client.py,sha256=
|
3
|
-
architect_py/client.py,sha256=
|
4
|
-
architect_py/client.pyi,sha256=
|
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=
|
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=
|
31
|
-
architect_py/grpc/models/definitions.py,sha256=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
162
|
-
architect_py/tests/test_orderflow.py,sha256=
|
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/
|
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=
|
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.
|
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=
|
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=
|
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.
|
198
|
-
architect_py-5.1.
|
199
|
-
architect_py-5.1.
|
200
|
-
architect_py-5.1.
|
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
|
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,
|
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
|
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
|
-
|
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,
|
159
|
+
step_to_target_position(c, orderflow_manager),
|
184
160
|
print_info(c),
|
185
|
-
subscribe_and_print_orderflow(c,
|
161
|
+
subscribe_and_print_orderflow(c, orderflow_manager),
|
186
162
|
)
|
187
163
|
await c.close()
|
188
164
|
|
scripts/postprocess_grpc.py
CHANGED
@@ -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 = "
|
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 {
|
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
|
|
File without changes
|
File without changes
|
File without changes
|