afp-sdk 0.1.1__py3-none-any.whl → 0.2.0__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/builder.py CHANGED
@@ -41,7 +41,7 @@ class Builder(ClearingSystemAPI):
41
41
  oracle_address: str,
42
42
  fsv_decimals: int,
43
43
  fsp_alpha: Decimal,
44
- fsp_beta: int,
44
+ fsp_beta: Decimal,
45
45
  fsv_calldata: str,
46
46
  start_time: datetime,
47
47
  earliest_fsp_submission_time: datetime,
@@ -177,7 +177,7 @@ class Builder(ClearingSystemAPI):
177
177
  oracle_address=cast(ChecksumAddress, product.oracle_address),
178
178
  fsv_decimals=product.fsv_decimals,
179
179
  fsp_alpha=int(product.fsp_alpha * config.FULL_PRECISION_MULTIPLIER),
180
- fsp_beta=product.fsp_beta,
180
+ fsp_beta=int(product.fsp_beta * 10**product.fsv_decimals),
181
181
  fsv_calldata=HexBytes(product.fsv_calldata),
182
182
  ),
183
183
  price_quotation=product.price_quotation,
afp/api/trading.py CHANGED
@@ -54,6 +54,7 @@ class Trading(ExchangeAPI):
54
54
  max_trading_fee_rate: Decimal,
55
55
  good_until_time: datetime,
56
56
  margin_account_id: str | None = None,
57
+ rounding: str | None = None,
57
58
  ) -> Intent:
58
59
  """Creates an intent with the given intent data, generates its hash and signs it
59
60
  with the configured account's private key.
@@ -62,6 +63,13 @@ class Trading(ExchangeAPI):
62
63
  is assumed to be the same as the margin account if the margin account ID is not
63
64
  specified.
64
65
 
66
+ The limit price must have at most as many fractional digits as the product's
67
+ tick size, or if `rounding` is specified then the limit price is rounded to the
68
+ appropriate number of fractional digits. `rounding` may be one of
69
+ `ROUND_CEILING`, `ROUND_FLOOR`, `ROUND_UP`, `ROUND_DOWN`, `ROUND_HALF_UP`,
70
+ `ROUND_HALF_DOWN`, `ROUND_HALF_EVEN` and `ROUND_05UP`; see the rounding modes of
71
+ the `decimal` module of the Python Standard Library.
72
+
65
73
  Parameters
66
74
  ----------
67
75
  product : afp.schemas.ExchangeProduct
@@ -71,6 +79,8 @@ class Trading(ExchangeAPI):
71
79
  max_trading_fee_rate : decimal.Decimal
72
80
  good_until_time : datetime.datetime
73
81
  margin_account_id : str, optional
82
+ rounding : str, optional
83
+ A rounding mode of the `decimal` module or `None` for no rounding.
74
84
 
75
85
  Returns
76
86
  -------
@@ -85,7 +95,9 @@ class Trading(ExchangeAPI):
85
95
  intent_data = IntentData(
86
96
  trading_protocol_id=self._trading_protocol_id,
87
97
  product_id=product.id,
88
- limit_price=limit_price,
98
+ limit_price=validators.validate_limit_price(
99
+ Decimal(limit_price), product.tick_size, rounding
100
+ ),
89
101
  quantity=quantity,
90
102
  max_trading_fee_rate=max_trading_fee_rate,
91
103
  side=getattr(OrderSide, side.upper()),
@@ -59,6 +59,24 @@ class Trade:
59
59
  intents: typing.List[Intent]
60
60
 
61
61
 
62
+ @dataclass
63
+ class Settlement:
64
+ """Port of `struct Settlement` on the IMarginAccount contract."""
65
+
66
+ position_id: hexbytes.HexBytes
67
+ quantity: int
68
+ price: int
69
+
70
+
71
+ @dataclass
72
+ class Order:
73
+ """Port of `struct Order` on the ITradingProtocol contract."""
74
+
75
+ margin_account_id: eth_typing.ChecksumAddress
76
+ margin_account_contract: eth_typing.ChecksumAddress
77
+ settlement: Settlement
78
+
79
+
62
80
  class TradingProtocol:
63
81
  """TradingProtocol contract binding.
64
82
 
@@ -101,6 +119,11 @@ class TradingProtocol:
101
119
  """Binding for `event RoleRevoked` on the TradingProtocol contract."""
102
120
  return self._contract.events.RoleRevoked
103
121
 
122
+ @property
123
+ def SequenceExecuted(self) -> contract.ContractEvent:
124
+ """Binding for `event SequenceExecuted` on the TradingProtocol contract."""
125
+ return self._contract.events.SequenceExecuted
126
+
104
127
  @property
105
128
  def Upgraded(self) -> contract.ContractEvent:
106
129
  """Binding for `event Upgraded` on the TradingProtocol contract."""
@@ -450,6 +473,36 @@ class TradingProtocol:
450
473
  clearing_address,
451
474
  )
452
475
 
476
+ def order_mae_check(
477
+ self,
478
+ orders: typing.List[Order],
479
+ ) -> typing.List[bool]:
480
+ """Binding for `orderMAECheck` on the TradingProtocol contract.
481
+
482
+ Parameters
483
+ ----------
484
+ orders : typing.List[Order]
485
+
486
+ Returns
487
+ -------
488
+ typing.List[bool]
489
+ """
490
+ return_value = self._contract.functions.orderMAECheck(
491
+ [
492
+ (
493
+ item.margin_account_id,
494
+ item.margin_account_contract,
495
+ (
496
+ item.settlement.position_id,
497
+ item.settlement.quantity,
498
+ item.settlement.price,
499
+ ),
500
+ )
501
+ for item in orders
502
+ ],
503
+ ).call()
504
+ return [bool(return_value_elem) for return_value_elem in return_value]
505
+
453
506
  def proxiable_uuid(
454
507
  self,
455
508
  ) -> hexbytes.HexBytes:
@@ -718,6 +771,25 @@ ABI = typing.cast(
718
771
  "name": "RoleRevoked",
719
772
  "type": "event",
720
773
  },
774
+ {
775
+ "anonymous": False,
776
+ "inputs": [
777
+ {
778
+ "indexed": False,
779
+ "internalType": "bool[]",
780
+ "name": "results",
781
+ "type": "bool[]",
782
+ },
783
+ {
784
+ "indexed": False,
785
+ "internalType": "bytes[]",
786
+ "name": "errors",
787
+ "type": "bytes[]",
788
+ },
789
+ ],
790
+ "name": "SequenceExecuted",
791
+ "type": "event",
792
+ },
721
793
  {
722
794
  "anonymous": False,
723
795
  "inputs": [
@@ -1100,6 +1172,55 @@ ABI = typing.cast(
1100
1172
  "stateMutability": "nonpayable",
1101
1173
  "type": "function",
1102
1174
  },
1175
+ {
1176
+ "inputs": [
1177
+ {
1178
+ "components": [
1179
+ {
1180
+ "internalType": "address",
1181
+ "name": "marginAccountID",
1182
+ "type": "address",
1183
+ },
1184
+ {
1185
+ "internalType": "address",
1186
+ "name": "marginAccountContract",
1187
+ "type": "address",
1188
+ },
1189
+ {
1190
+ "components": [
1191
+ {
1192
+ "internalType": "bytes32",
1193
+ "name": "positionId",
1194
+ "type": "bytes32",
1195
+ },
1196
+ {
1197
+ "internalType": "int256",
1198
+ "name": "quantity",
1199
+ "type": "int256",
1200
+ },
1201
+ {
1202
+ "internalType": "uint256",
1203
+ "name": "price",
1204
+ "type": "uint256",
1205
+ },
1206
+ ],
1207
+ "internalType": "struct IMarginAccount.Settlement",
1208
+ "name": "settlement",
1209
+ "type": "tuple",
1210
+ },
1211
+ ],
1212
+ "internalType": "struct ITradingProtocol.Order[]",
1213
+ "name": "orders",
1214
+ "type": "tuple[]",
1215
+ }
1216
+ ],
1217
+ "name": "orderMAECheck",
1218
+ "outputs": [
1219
+ {"internalType": "bool[]", "name": "results", "type": "bool[]"}
1220
+ ],
1221
+ "stateMutability": "view",
1222
+ "type": "function",
1223
+ },
1103
1224
  {
1104
1225
  "inputs": [],
1105
1226
  "name": "proxiableUUID",
afp/schemas.py CHANGED
@@ -172,7 +172,7 @@ class ProductSpecification(Model):
172
172
  oracle_address: Annotated[str, AfterValidator(validators.validate_address)]
173
173
  fsv_decimals: Annotated[int, Field(ge=0, lt=256)] # uint8
174
174
  fsp_alpha: Decimal
175
- fsp_beta: int
175
+ fsp_beta: Decimal
176
176
  fsv_calldata: Annotated[str, AfterValidator(validators.validate_hexstr)]
177
177
  # Product
178
178
  start_time: Timestamp
afp/validators.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from datetime import datetime, timedelta
2
+ from decimal import Decimal
2
3
 
3
4
  from binascii import Error
4
5
  from eth_typing.evm import ChecksumAddress
@@ -41,3 +42,15 @@ def validate_address(value: str) -> ChecksumAddress:
41
42
  return Web3.to_checksum_address(value)
42
43
  except ValueError:
43
44
  raise ValueError(f"{value} is not a valid blockchain address")
45
+
46
+
47
+ def validate_limit_price(
48
+ value: Decimal, tick_size: int, rounding: str | None = None
49
+ ) -> Decimal:
50
+ if rounding is None:
51
+ num_fractional_digits = abs(int(value.normalize().as_tuple().exponent))
52
+ if num_fractional_digits > tick_size:
53
+ raise ValueError(
54
+ f"Limit price {value} can have at most {tick_size} fractional digits"
55
+ )
56
+ return value.quantize(Decimal("10") ** -tick_size, rounding=rounding)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: afp-sdk
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: Autonomous Futures Protocol Python SDK
5
5
  Keywords: autonity,web3,trading,crypto,prediction,forecast,markets
6
6
  License-Expression: MIT
@@ -2,10 +2,10 @@ afp/__init__.py,sha256=LTxZrvSFI5blSuBEsGlyZhFfmrNVV3LpPrdi7aYwiTs,325
2
2
  afp/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  afp/api/admin.py,sha256=7ymtCloff4UhyS-MAqA8_cndWlfZanjuGgPgkiV5Jhc,1526
4
4
  afp/api/base.py,sha256=iS-sjAc9mME2qOMEvnB6T6x9L_8oeJnHY6h79xrbAOE,2632
5
- afp/api/builder.py,sha256=4Kmulk2f4QAblLgmI0J6YYt-WuBoLSw3l2jY3Q6tNN8,7078
5
+ afp/api/builder.py,sha256=mde8XemEMKL76KgEd5rxg7RLBS6lyIfNOEGmE1_iK0M,7114
6
6
  afp/api/clearing.py,sha256=nMVjayFkf0XYYP3aKAdgR6NaFSG4Cl_QsEuADRuIO7M,12922
7
7
  afp/api/liquidation.py,sha256=CtME5524VVW9mXMMpORyUP205sTVqpLnHIPoTy2MGa8,5439
8
- afp/api/trading.py,sha256=0nD3JnnQwmmFeZYRws1V4rfWCuxgwnY7O5uF-NZ3Mtc,9917
8
+ afp/api/trading.py,sha256=HjskW4c13CwAB-AwyIsSBcvyXKKEJk7a9768tqcTzUE,10648
9
9
  afp/bindings/__init__.py,sha256=5PDdlk0aClsTt2NgbVqP-R-z2QQp99IfXaSB13Pmf5c,1155
10
10
  afp/bindings/auctioneer_facet.py,sha256=99FmK35trfOIJGqJqyc1NnpG0KavhH0_jNufszZ9VhA,24013
11
11
  afp/bindings/bankruptcy_facet.py,sha256=Yg8sLhDU0crsL1ISSy4eoeQEP5jrAuiWBBlco5MtgPc,11370
@@ -18,17 +18,17 @@ afp/bindings/margin_account_registry.py,sha256=mx9sAU6HuC09d-LAf9bzP57HPLa3M6qXp
18
18
  afp/bindings/mark_price_tracker_facet.py,sha256=vnVsAmpts_2Sv9Jmx3JlON8X8FJd9D2jOFhqSwXIA7A,2830
19
19
  afp/bindings/oracle_provider.py,sha256=CMpVAXdUuTP_W9ZE297B-m9MjuW90yCOhNLMVl3kCf0,15863
20
20
  afp/bindings/product_registry.py,sha256=HFWwbFKvXk0A2dZB6KBa0Ul8-vX9uvvtGj0dhRL9UUw,43701
21
- afp/bindings/trading_protocol.py,sha256=XN9UbViMhVLIzFCTTgEW65GRF0finTjq-2iHrhtL3P8,39873
21
+ afp/bindings/trading_protocol.py,sha256=a8QLCQ9bKgV26IW1y4aY8js9ykO8l2_VTM8YPCo6SqM,43895
22
22
  afp/config.py,sha256=3S7k49n4ZaRko3FX6Hw95r5L-sw2XiAjWtqYiX3Omx0,1017
23
23
  afp/decorators.py,sha256=Ustc15RbXGYIEqDb9lXnd-bdhZJ8ZrztN4h_vjkLsG0,2692
24
24
  afp/enums.py,sha256=4dglBx4Amcu0GrlJn0cIj-rp9uDHZGfDEP_vMAO02xo,485
25
25
  afp/exceptions.py,sha256=RE8IE6akDgbar2PobdpOiBdGZZCYkb4jWf1ozJmdLaI,342
26
26
  afp/exchange.py,sha256=l8Cartp0R4PPe6O_Wu10YDw-5P_PbaAkd7w-W5QrlWY,5272
27
27
  afp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- afp/schemas.py,sha256=RQ-NkDOgFnoJXHIngiqAJCX88gu5qlkMu6lxnvVyYfI,4899
28
+ afp/schemas.py,sha256=nCR8FLnq8msTFW9wsLxjTrxIzcKG85BKG-WmQ5Oazrc,4903
29
29
  afp/signing.py,sha256=7fohnAvoiDA4ems_3OcVnr16OmYLSg9NnnCSzDplg6s,2235
30
- afp/validators.py,sha256=zhOP0vYS2aXMKLsIVDwD6xwwCg0moIU5IhMlNHihWkM,1329
31
- afp_sdk-0.1.1.dist-info/licenses/LICENSE,sha256=ZdaKItgc2ppfqta2OJV0oHpSJiK87PUxmUkUo-_0SB8,1065
32
- afp_sdk-0.1.1.dist-info/WHEEL,sha256=4n27za1eEkOnA7dNjN6C5-O2rUiw6iapszm14Uj-Qmk,79
33
- afp_sdk-0.1.1.dist-info/METADATA,sha256=BZuKka2wtt3_X2jt09psAhsi0WZIlze1OEJ4Qa7QAJA,5618
34
- afp_sdk-0.1.1.dist-info/RECORD,,
30
+ afp/validators.py,sha256=m61ZpP385CxsdDGJavPkXKTXnJAHKLCzedoZ8mL6daI,1818
31
+ afp_sdk-0.2.0.dist-info/licenses/LICENSE,sha256=ZdaKItgc2ppfqta2OJV0oHpSJiK87PUxmUkUo-_0SB8,1065
32
+ afp_sdk-0.2.0.dist-info/WHEEL,sha256=NHRAbdxxzyL9K3IO2LjmlNqKSyPZnKv2BD16YYVKo18,79
33
+ afp_sdk-0.2.0.dist-info/METADATA,sha256=GXQP-Cbxe6UAMmmveYzLeG8vDgRodS0N_9jz0Bx1FlE,5618
34
+ afp_sdk-0.2.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.8.13
2
+ Generator: uv 0.8.14
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any