afp-sdk 0.5.2__py3-none-any.whl → 0.5.3__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.
afp/api/trading.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import secrets
2
2
  import warnings
3
- from datetime import datetime
3
+ from datetime import datetime, timedelta
4
4
  from decimal import Decimal
5
5
  from typing import Generator, Iterable
6
6
 
@@ -16,6 +16,7 @@ from ..schemas import (
16
16
  Intent,
17
17
  IntentData,
18
18
  MarketDepthData,
19
+ OHLCVItem,
19
20
  Order,
20
21
  OrderFilter,
21
22
  OrderCancellationData,
@@ -238,6 +239,7 @@ class Trading(ExchangeAPI):
238
239
  self,
239
240
  *,
240
241
  product_id: str | None = None,
242
+ intent_account_id: str | None = None,
241
243
  type_: str | None = None,
242
244
  states: Iterable[str] = (),
243
245
  side: str | None = None,
@@ -255,6 +257,8 @@ class Trading(ExchangeAPI):
255
257
  Parameters
256
258
  ----------
257
259
  product_id : str, optional
260
+ intent_account_id : str, optional
261
+ Defaults to the address of the authenticated account.
258
262
  type_ : str, optional
259
263
  One of `LIMIT_ORDER` and `CANCEL_ORDER`.
260
264
  states : iterable of str
@@ -274,8 +278,11 @@ class Trading(ExchangeAPI):
274
278
  -------
275
279
  list of afp.schemas.OrderFill
276
280
  """
281
+ if intent_account_id is None:
282
+ intent_account_id = self._authenticator.address
283
+
277
284
  filter = OrderFilter(
278
- intent_account_id=self._authenticator.address,
285
+ intent_account_id=intent_account_id,
279
286
  product_id=product_id,
280
287
  type=None if type_ is None else OrderType(type_.upper()),
281
288
  states=[OrderState(state.upper()) for state in states],
@@ -306,6 +313,7 @@ class Trading(ExchangeAPI):
306
313
  self,
307
314
  *,
308
315
  product_id: str | None = None,
316
+ intent_account_id: str | None = None,
309
317
  intent_hash: str | None = None,
310
318
  start: datetime | None = None,
311
319
  end: datetime | None = None,
@@ -323,6 +331,8 @@ class Trading(ExchangeAPI):
323
331
  Parameters
324
332
  ----------
325
333
  product_id : str, optional
334
+ intent_account_id : str, optional
335
+ Defaults to the address of the authenticated account.
326
336
  intent_hash : str, optional
327
337
  start : datetime.datetime, optional
328
338
  end : datetime.datetime, optional
@@ -339,8 +349,11 @@ class Trading(ExchangeAPI):
339
349
  -------
340
350
  list of afp.schemas.OrderFill
341
351
  """
352
+ if intent_account_id is None:
353
+ intent_account_id = self._authenticator.address
354
+
342
355
  filter = OrderFillFilter(
343
- intent_account_id=self._authenticator.address,
356
+ intent_account_id=intent_account_id,
344
357
  product_id=product_id,
345
358
  intent_hash=intent_hash,
346
359
  start=start,
@@ -357,6 +370,7 @@ class Trading(ExchangeAPI):
357
370
  self,
358
371
  *,
359
372
  product_id: str | None = None,
373
+ intent_account_id: str | None = None,
360
374
  intent_hash: str | None = None,
361
375
  trade_states: Iterable[str] = ("PENDING",),
362
376
  ) -> Generator[OrderFill, None, None]:
@@ -376,6 +390,8 @@ class Trading(ExchangeAPI):
376
390
  Parameters
377
391
  ----------
378
392
  product_id : str, optional
393
+ intent_account_id : str, optional
394
+ Defaults to the address of the authenticated account.
379
395
  intent_hash : str, optional
380
396
  trade_states: iterable of str
381
397
  Any of `PENDING`, `CLEARED` and `REJECTED`.
@@ -384,8 +400,11 @@ class Trading(ExchangeAPI):
384
400
  -------
385
401
  afp.schemas.OrderFill
386
402
  """
403
+ if intent_account_id is None:
404
+ intent_account_id = self._authenticator.address
405
+
387
406
  filter = OrderFillFilter(
388
- intent_account_id=self._authenticator.address,
407
+ intent_account_id=intent_account_id,
389
408
  product_id=product_id,
390
409
  intent_hash=intent_hash,
391
410
  start=None,
@@ -439,3 +458,71 @@ class Trading(ExchangeAPI):
439
458
  """
440
459
  value = validators.validate_hexstr32(product_id)
441
460
  yield from self._exchange.iter_market_depth_data(value)
461
+
462
+ def ohlcv(
463
+ self,
464
+ product_id: str,
465
+ start: datetime | None = None,
466
+ interval: timedelta = timedelta(minutes=5),
467
+ ) -> list[OHLCVItem]:
468
+ """Retrieves Open-High-Low-Close-Volume time series data for the given product.
469
+
470
+ Parameters
471
+ ----------
472
+ product_id : str
473
+ start : datetime
474
+ Defaults to 1 day ago.
475
+ interval : timedelta
476
+ The distance between 2 data points. Gets rounded to a multiple of 5 seconds.
477
+ Defaults to 5 minutes.
478
+
479
+ Returns
480
+ -------
481
+ list of afp.schemas.OHLCVItem
482
+
483
+ Raises
484
+ ------
485
+ afp.exceptions.NotFoundError
486
+ If no such product exists.
487
+ """
488
+ if start is None:
489
+ start = datetime.now() - timedelta(days=1)
490
+
491
+ product_id = validators.validate_hexstr32(product_id)
492
+ start_timestamp = int(start.timestamp())
493
+ interval_secs = int(validators.validate_timedelta(interval).total_seconds())
494
+ return self._exchange.get_time_series_data(
495
+ product_id, start_timestamp, interval_secs
496
+ )
497
+
498
+ def iter_ohlcv(
499
+ self, product_id: str, interval: timedelta = timedelta(seconds=5)
500
+ ) -> Generator[OHLCVItem, None, None]:
501
+ """Subscribes to Open-High-Low-Close-Volume time series data updates for the
502
+ given product.
503
+
504
+ Returns a generator that yields OHLCV data points as they are published
505
+ by the exhange.
506
+
507
+ Parameters
508
+ ----------
509
+ product_id : str
510
+ interval : timedelta
511
+ The distance between 2 data points. Gets rounded to a multiple of 5 seconds.
512
+ Defaults to 5 seconds.
513
+
514
+ Yields
515
+ -------
516
+ afp.schemas.OHLCVItem
517
+
518
+ Raises
519
+ ------
520
+ afp.exceptions.NotFoundError
521
+ If no such product exists.
522
+ """
523
+ product_id = validators.validate_hexstr32(product_id)
524
+ start_timestamp = int(datetime.now().timestamp())
525
+ interval_secs = int(validators.validate_timedelta(interval).total_seconds())
526
+ yield from self._exchange.iter_time_series_data(
527
+ product_id, start_timestamp, interval_secs
528
+ )
afp/enums.py CHANGED
@@ -11,6 +11,7 @@ class ListingState(StrEnum):
11
11
  class OrderType(StrEnum):
12
12
  LIMIT_ORDER = "LIMIT_ORDER"
13
13
  CANCEL_ORDER = "CANCEL_ORDER"
14
+ EXCHANGE_INITIATED_CANCELLATION = "EXCHANGE_INITIATED_CANCELLATION"
14
15
 
15
16
 
16
17
  class OrderState(StrEnum):
afp/exchange.py CHANGED
@@ -21,6 +21,7 @@ from .schemas import (
21
21
  ExchangeProductUpdateSubmission,
22
22
  LoginSubmission,
23
23
  MarketDepthData,
24
+ OHLCVItem,
24
25
  Order,
25
26
  OrderFilter,
26
27
  OrderFill,
@@ -138,6 +139,30 @@ class ExchangeClient:
138
139
  for line in response.iter_lines():
139
140
  yield MarketDepthData.model_validate_json(line)
140
141
 
142
+ # GET /time-series/{product_id}
143
+ def get_time_series_data(
144
+ self, product_id: str, start: int, interval: int
145
+ ) -> list[OHLCVItem]:
146
+ response = self._send_request(
147
+ "GET",
148
+ f"/time-series/{product_id}",
149
+ params=dict(start=start, interval=interval),
150
+ )
151
+ return [OHLCVItem(**item) for item in response.json()["data"]]
152
+
153
+ # GET /stream/time-series/{product_id}
154
+ def iter_time_series_data(
155
+ self, product_id: str, start: int, interval: int
156
+ ) -> Generator[OHLCVItem, None, None]:
157
+ response = self._send_request(
158
+ "GET",
159
+ f"/stream/time-series/{product_id}",
160
+ params=dict(start=start, interval=interval),
161
+ stream=True,
162
+ )
163
+ for line in response.iter_lines():
164
+ yield OHLCVItem.model_validate_json(line)
165
+
141
166
  def _send_request(
142
167
  self,
143
168
  method: str,
afp/schemas.py CHANGED
@@ -209,6 +209,15 @@ class MarketDepthData(Model):
209
209
  asks: list[MarketDepthItem]
210
210
 
211
211
 
212
+ class OHLCVItem(Model):
213
+ timestamp: Timestamp
214
+ open: Decimal
215
+ high: Decimal
216
+ low: Decimal
217
+ close: Decimal
218
+ volume: int
219
+
220
+
212
221
  # Clearing API
213
222
 
214
223
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: afp-sdk
3
- Version: 0.5.2
3
+ Version: 0.5.3
4
4
  Summary: Autonomous Futures Protocol Python SDK
5
5
  Keywords: autonity,web3,trading,crypto,prediction,forecast,markets
6
6
  License-Expression: MIT
@@ -5,7 +5,7 @@ afp/api/admin.py,sha256=6TiWCo0SB41CtXYTkTYYGQY7MrdB6OMTyU3-0J0V_7o,2170
5
5
  afp/api/base.py,sha256=5X1joEwFX4gxYUDCSTvp_hSFCfLZCktnW-UtZFxDquk,4471
6
6
  afp/api/margin_account.py,sha256=sC1DF7J3QTHR7cXcRjTG33oZswVy6qr9xnevQbrQ-ew,15256
7
7
  afp/api/product.py,sha256=2N4bPBahuw19GcBbBL20oQ5RFRuUxa5LOZzmN7hs39U,10156
8
- afp/api/trading.py,sha256=RdBFcY4U6A1T24vZUqR1J8MwdhaouMYZfFqBrdbMcA0,14309
8
+ afp/api/trading.py,sha256=y5Q2KApEpUau9R8G9KUqOdm4ymhw9Hbu9d2dkG80AsQ,17262
9
9
  afp/auth.py,sha256=sV_9E6CgRWV1xYoppc4IdrnqNo5ZNDBIp6QF3fQbMWE,2055
10
10
  afp/bindings/__init__.py,sha256=_n9xoogYi8AAlSx_PE-wjnwP1ujVyDUwoRM0BSm243U,1271
11
11
  afp/bindings/auctioneer_facet.py,sha256=4p906zdU2lUsqpWlsiLE3dlxTPrlNpqk8DtjiQUWJ8M,23919
@@ -24,14 +24,14 @@ afp/bindings/trading_protocol.py,sha256=ZloF3REbjFq9v0UGVsM0_Lk0EhfWJKdeJ0PzVEny
24
24
  afp/config.py,sha256=_WKywiuty8poE1A0v46uBe1JGpfCzRlxCPamKennfpE,699
25
25
  afp/constants.py,sha256=EvDhLpKBOsc8OHGm1paiUAdAetPGD4nyi13coB8rd14,1930
26
26
  afp/decorators.py,sha256=SEUQtbgPGc4iVPtBQV2eiCejcDAVImmXcI0uPXFhtJA,2774
27
- afp/enums.py,sha256=HQ9EqLEvg9EHBA_UDSyn0Lma72fYoefjHfzOcIVKyh0,616
27
+ afp/enums.py,sha256=9JhwdLcTNhyKabKdrALAlCeL3C5XfeXYSSSXSCsuTzE,688
28
28
  afp/exceptions.py,sha256=frdS-EH84K0fOf92RgRgNkTe3VII2m36XNCS8eyXLLM,390
29
- afp/exchange.py,sha256=-QE44UZ-3Q0gsyWip4o19V4BYy283JpaKuQh7_-uS5g,6624
29
+ afp/exchange.py,sha256=QQAfglOzsxo_T0BUOFAkxI2wUbda1sKStMXUO9IcDbw,7498
30
30
  afp/hashing.py,sha256=gBCWN93-ydRPlgnnorSvDQlylcnglrAypRDb-1K-20I,1949
31
31
  afp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
- afp/schemas.py,sha256=PCHoEpaU-O-C50UTrru3eRNalCLccWsTRE1AWITiIP0,6607
32
+ afp/schemas.py,sha256=zyZOPvAdDnXp60kqYqX-OoWnKvRLPZT7at0A0MHlurc,6746
33
33
  afp/validators.py,sha256=zQvPu3HDu6ADnEE72EJlS5hc1-xfru78Mzd74s1u_EM,1841
34
- afp_sdk-0.5.2.dist-info/licenses/LICENSE,sha256=ZdaKItgc2ppfqta2OJV0oHpSJiK87PUxmUkUo-_0SB8,1065
35
- afp_sdk-0.5.2.dist-info/WHEEL,sha256=n2u5OFBbdZvCiUKAmfnY1Po2j3FB_NWfuUlt5WiAjrk,79
36
- afp_sdk-0.5.2.dist-info/METADATA,sha256=SBHaznfY-kCneVxC6gFXrqL0YE28Wxk1LlxWsQ1-hrg,6354
37
- afp_sdk-0.5.2.dist-info/RECORD,,
34
+ afp_sdk-0.5.3.dist-info/licenses/LICENSE,sha256=ZdaKItgc2ppfqta2OJV0oHpSJiK87PUxmUkUo-_0SB8,1065
35
+ afp_sdk-0.5.3.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
36
+ afp_sdk-0.5.3.dist-info/METADATA,sha256=__Jo9oroNSkI1O9-vAOSA2HrSEONWX95AB4nLKkrjg0,6354
37
+ afp_sdk-0.5.3.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.8.23
2
+ Generator: uv 0.8.24
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any