from __future__ import annotations from decimal import Decimal import pytest from app.domain.backtesting_math import AssetQuantity, PricePerAsset from app.domain.instruments import ( asset_quantity_from_weight, price_per_weight_from_asset_price, weight_from_asset_quantity, ) from app.domain.units import BaseCurrency, Weight, WeightUnit def test_gld_share_quantity_converts_to_troy_ounce_weight() -> None: quantity = AssetQuantity(amount=Decimal("10"), symbol="GLD") weight = weight_from_asset_quantity(quantity) assert weight == Weight(amount=Decimal("1.0"), unit=WeightUnit.OUNCE_TROY) def test_gld_troy_ounce_weight_converts_to_share_quantity() -> None: weight = Weight(amount=Decimal("1"), unit=WeightUnit.OUNCE_TROY) quantity = asset_quantity_from_weight("GLD", weight) assert quantity == AssetQuantity(amount=Decimal("10"), symbol="GLD") def test_gld_share_quote_converts_to_ounce_equivalent_spot() -> None: quote = PricePerAsset(amount=Decimal("404.19"), currency=BaseCurrency.USD, symbol="GLD") spot = price_per_weight_from_asset_price(quote, per_unit=WeightUnit.OUNCE_TROY) assert spot.amount == Decimal("4041.9") assert spot.currency is BaseCurrency.USD assert spot.per_unit is WeightUnit.OUNCE_TROY def test_instrument_conversions_fail_closed_for_unsupported_symbols() -> None: quote = PricePerAsset(amount=Decimal("28.50"), currency=BaseCurrency.USD, symbol="SLV") with pytest.raises(ValueError, match="Unsupported instrument metadata"): price_per_weight_from_asset_price(quote, per_unit=WeightUnit.OUNCE_TROY) with pytest.raises(ValueError, match="Unsupported instrument metadata"): weight_from_asset_quantity(AssetQuantity(amount=Decimal("10"), symbol="SLV")) with pytest.raises(ValueError, match="Unsupported instrument metadata"): asset_quantity_from_weight("SLV", Weight(amount=Decimal("1"), unit=WeightUnit.OUNCE_TROY))