Point = float
Pip = float
Lot = float


class Units:
    LOT_SIZE = 100_000
    PIP_SIZE = 0.0001
    POINT_SIZE = PIP_SIZE / 10

    OPEN_COMMISSION = -6.0  # per lot, per side
    MAINTAIN_BUY_COMMISSION = -5.0  # per lot, per day
    MAINTAIN_SELL_COMMISSION = 1.25  # per lot, per day

    @staticmethod
    def pip_value(lots: Lot) -> float:
        """Account currency value of 1 pip move for `lots` position size."""
        return lots * Units.LOT_SIZE * Units.PIP_SIZE

    @staticmethod
    def point_value(lots: Lot) -> float:
        """Account currency value of 1 point move for `lots` position size."""
        return lots * Units.LOT_SIZE * Units.POINT_SIZE

    @staticmethod
    def pips_to_value(pips: Pip, lots: Lot) -> float:
        """Convert a pip distance to account currency."""
        return pips * Units.pip_value(lots)

    @staticmethod
    def points_to_value(points: Point, lots: Lot) -> float:
        """Convert a point distance to account currency."""
        return points * Units.point_value(lots)

    @staticmethod
    def open_commission(lots: Lot) -> float:
        """Opening commission in account currency for a given lot size."""
        return Units.OPEN_COMMISSION * lots

    @staticmethod
    def maintain_buy_commission(lots: Lot) -> float:
        """Daily swap cost for a buy position in account currency."""
        return Units.MAINTAIN_BUY_COMMISSION * lots

    @staticmethod
    def maintain_sell_commission(lots: Lot) -> float:
        """Daily swap for a sell position in account currency."""
        return Units.MAINTAIN_SELL_COMMISSION * lots
