Ejemplo n.º 1
0
    def validate(left, right) -> Tuple['Quantity', 'Quantity']:

        if isinstance(left, Quantity) and isinstance(right, Quantity):
            if left.instrument != right.instrument:
                raise IncompatibleInstrumentOperation(left, right)

            if (left.path_id
                    and right.path_id) and (left.path_id != right.path_id):
                raise QuantityOpPathMismatch(left.path_id, right.path_id)

            elif left.path_id and not right.path_id:
                right.path_id = left.path_id

            elif not left.path_id and right.path_id:
                left.path_id = right.path_id

            return left, right

        elif isinstance(left, Number) and isinstance(right, Quantity):
            left = Quantity(right.instrument, float(left), right.path_id)
            return left, right

        elif isinstance(left, Quantity) and isinstance(right, Number):
            right = Quantity(left.instrument, float(right), left.path_id)
            return left, right

        elif isinstance(left, Quantity):
            raise InvalidNonNumericQuantity(right)

        elif isinstance(right, Quantity):
            raise InvalidNonNumericQuantity(left)

        return left, right
Ejemplo n.º 2
0
    def __rtruediv__(self, other: Union['Price', float, int]):
        """Divides two PriceType objects together.

        Arguments:
            other: Union[Price, float, int]
                The object that is the left argument of the
                addition operation.

        Raises:
            IncompatibleTradingPairException:
                If (other : Price) and the pairs do not equal each other.
            InvalidNonNumericQuantity:
                If not (other : Union[Price, Number]).
        """
        price = None

        if isinstance(other, float) or isinstance(other, int):
            price = Price(other / self.rate, self.pair.quote / self.pair.base)

        elif isinstance(other, Quantity):
            raise IncompatiblePriceQuantityOperation(self, other)

        elif not isinstance(other, Number):
            raise InvalidNonNumericQuantity(other)

        return price
Ejemplo n.º 3
0
    def __rsub__(self, other: Union['Price', float, int]):
        """Subtracts two PriceType objects together.

        Arguments:
            other: Union[Price, float, int]
                The object that is the left argument of the
                operation.

        Raises:
            IncompatibleTradingPairException:
                If (other : Price) and the pairs do not equal each other.
            InvalidNonNumericQuantity:
                If not (other : Union[Price, Number]).
        """
        price = None

        if isinstance(other, Price):
            rate = other.rate - self.rate
            pair = self.pair or other.pair

            if self.pair != other.pair:
                raise IncompatibleTradingPairOperation(self.pair, other.pair)

            price = Price(rate, pair)

        elif isinstance(other, float) or isinstance(other, int):
            price = Price(other - self.rate, self.pair)

        elif not isinstance(other, Number):
            raise InvalidNonNumericQuantity(other)

        return price
Ejemplo n.º 4
0
    def __iadd__(self, other: Union['Price', float, int]):
        """Iteratively add to a Price object.

        Arguments:
            other: Union[Price, float, int]
                The object that is the left argument of the
                operation.

        Raises:
            IncompatibleTradingPairException:
                If (other : Price) and the pairs do not equal each other.
            InvalidNonNumericQuantity:
                If not (other : Union[Price, Number]).
        """

        if isinstance(other, Price):
            if self.pair != other.pair:
                raise IncompatibleTradingPairOperation(self.pair, other.pair)

            self.rate += other.rate

        elif isinstance(other, float) or isinstance(other, int):
            self.rate += other

        elif not isinstance(other, Number):
            raise InvalidNonNumericQuantity(other)

        return self
Ejemplo n.º 5
0
    def __mul__(self, other: Union['Price', 'Quantity', float, int]):
        """Multiplies two PriceType objects together.

        Arguments:
            other: Union[Price, float, int]
                The object that is the right argument of the
                operation.

        Raises:
            IncompatibleTradingPairException:
                If (other : Price) and the pairs do not equal each other.
            InvalidNonNumericQuantity:
                If not (other : Union[Price, Number]).
        """
        price = None

        if isinstance(other, Price):
            rate = self.rate * other.rate
            pair = self.pair or other.pair

            if self.pair != other.pair:
                raise IncompatibleTradingPairOperation(self.pair, other.pair)

            price = Price(rate, pair)

        elif isinstance(other, float) or isinstance(other, int):
            price = Price(self.rate * other, self.pair)

        elif isinstance(other, Quantity):

            if other.instrument != self.pair.quote:
                raise IncompatiblePriceQuantityOperation(
                    self.pair.quote, other.instrument)

            return Quantity(self.pair.base, self.rate * other.size,
                            other.path_id)

        elif not isinstance(other, Number):
            raise InvalidNonNumericQuantity(other)

        return price
Ejemplo n.º 6
0
    def _bool_operation(left: Union['Quantity', float,
                                    int], right: Union['Quantity', float, int],
                        bool_op: operator) -> bool:
        right_size = right

        if isinstance(right, Quantity):
            if left.instrument != right.instrument:
                raise IncompatibleInstrumentOperation(left, right)

            right_size = right.size

        if not isinstance(right_size, Number):
            raise InvalidNonNumericQuantity(right_size)

        boolean = bool_op(left.size, right_size)

        if not isinstance(boolean, bool):
            raise Exception(
                "`bool_op` cannot return a non-bool type ({}).".format(
                    boolean))

        return boolean
Ejemplo n.º 7
0
    def _math_operation(left: Union['Quantity', float,
                                    int], right: Union['Quantity', float, int],
                        op: operator) -> 'Quantity':
        right_size = right

        if isinstance(right, Quantity):
            if left.instrument != right.instrument:
                raise IncompatibleInstrumentOperation(left, right)

            if left.path_id and right.path_id:
                if left._path_id != right._path_id:
                    raise QuantityOpPathMismatch(left.path_id, right.path_id)

            right_size = right.size

        if not isinstance(right_size, Number):
            raise InvalidNonNumericQuantity(right_size)

        size = op(left.size, right_size)

        return Quantity(instrument=left.instrument,
                        size=size,
                        path_id=left.path_id)