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.
- architect_py/__init__.py +3 -1
- architect_py/async_client.py +116 -28
- architect_py/client.py +56 -70
- architect_py/client.pyi +54 -12
- architect_py/common_types/time_in_force.py +1 -0
- architect_py/common_types/tradable_product.py +1 -1
- architect_py/graphql_client/juniper_base_client.py +4 -0
- architect_py/grpc/client.py +3 -0
- architect_py/grpc/models/Cpty/CptyStatus.py +17 -18
- architect_py/grpc/models/Marketdata/Ticker.py +14 -1
- architect_py/grpc/models/Oms/Order.py +12 -1
- architect_py/grpc/models/definitions.py +41 -0
- architect_py/grpc/resolve_endpoint.py +11 -2
- architect_py/tests/conftest.py +2 -5
- architect_py/tests/test_encoding.py +37 -0
- architect_py/tests/test_marketdata.py +9 -0
- architect_py/tests/test_order_entry.py +3 -1
- architect_py/tests/test_portfolio_management.py +2 -0
- architect_py/tests/test_symbology.py +20 -0
- architect_py/tests/test_sync_client.py +40 -0
- {architect_py-5.1.0b1.dist-info → architect_py-5.1.2.dist-info}/METADATA +4 -1
- {architect_py-5.1.0b1.dist-info → architect_py-5.1.2.dist-info}/RECORD +35 -33
- {architect_py-5.1.0b1.dist-info → architect_py-5.1.2.dist-info}/WHEEL +1 -1
- examples/book_subscription.py +2 -0
- examples/candles.py +2 -0
- examples/funding_rate_mean_reversion_algo.py +1 -0
- examples/order_sending.py +5 -3
- examples/stream_l1_marketdata.py +2 -0
- examples/stream_l2_marketdata.py +2 -0
- examples/trades.py +2 -0
- examples/tutorial_async.py +3 -1
- examples/tutorial_sync.py +4 -1
- templates/juniper_base_client.py +4 -0
- {architect_py-5.1.0b1.dist-info → architect_py-5.1.2.dist-info}/licenses/LICENSE +0 -0
- {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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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},
|
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[
|
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
|
-
|
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
|
-
|
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
|
architect_py/tests/conftest.py
CHANGED
@@ -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
|
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 =
|
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
|
-
|
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()
|
@@ -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.
|
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=
|
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=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=
|
8
|
-
architect_py/common_types/tradable_product.py,sha256=
|
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=
|
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=
|
27
|
-
architect_py/grpc/resolve_endpoint.py,sha256=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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/
|
160
|
-
architect_py/tests/
|
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=
|
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=
|
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.
|
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=
|
174
|
-
examples/candles.py,sha256=
|
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=
|
178
|
-
examples/order_sending.py,sha256=
|
179
|
-
examples/stream_l1_marketdata.py,sha256=
|
180
|
-
examples/stream_l2_marketdata.py,sha256=
|
181
|
-
examples/trades.py,sha256=
|
182
|
-
examples/tutorial_async.py,sha256=
|
183
|
-
examples/tutorial_sync.py,sha256=
|
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=
|
192
|
-
architect_py-5.1.
|
193
|
-
architect_py-5.1.
|
194
|
-
architect_py-5.1.
|
195
|
-
architect_py-5.1.
|
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,,
|
examples/book_subscription.py
CHANGED
examples/candles.py
CHANGED
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
|
-
|
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
|
-
|
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
|
-
|
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()
|