From 74670dae05d6e4f99881729f4ae8976bd12c0adf Mon Sep 17 00:00:00 2001 From: Adriano Dal Pastro Date: Thu, 4 Jun 2026 16:10:28 +0000 Subject: [PATCH] =?UTF-8?q?fix(live):=20quantizzazione=20amount=20senza=20?= =?UTF-8?q?artefatti=20float=20(Decimal)=20=E2=80=94=2072*0.001=3D0.072000?= =?UTF-8?q?00000000001=20causava=20'Invalid=20params'=20su=20Deribit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- src/live/execution.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/live/execution.py b/src/live/execution.py index c71d0b1..826cd36 100644 --- a/src/live/execution.py +++ b/src/live/execution.py @@ -17,6 +17,7 @@ from __future__ import annotations import time from dataclasses import dataclass, field +from decimal import Decimal from typing import Any from src.live.cerbero_client import CerberoClient @@ -46,6 +47,13 @@ def settlement_currency(instrument: str) -> str: return instrument.split("-")[0].split("_")[0] +def _quantize_step(value: float, step: float, mn: float) -> float: + """Arrotonda `value` al multiplo di `step` SENZA artefatti float + (es. 72*0.001 = 0.07200000000000001 → Deribit 'Invalid params').""" + n_steps = round(value / step) + return float(max(n_steps * Decimal(str(step)), Decimal(str(mn)))) + + def notional_to_amount(instrument: str, notional_usd: float, price: float | None = None) -> float: """Notional USD → `amount` Deribit, arrotondato allo step e clampato al minimo. @@ -59,10 +67,10 @@ def notional_to_amount(instrument: str, notional_usd: float, units = notional_usd / price # base-coin richiesti if units < step / 2: return 0.0 - return max(round(units / step) * step, mn) + return _quantize_step(units, step, mn) if notional_usd < step / 2: return 0.0 - return max(round(notional_usd / step) * step, mn) + return _quantize_step(notional_usd, step, mn) @dataclass