Пример #1
0
    def withdraw(self, quantity: 'Quantity', reason: str) -> 'Quantity':
        """Withdraws funds from the wallet.

        Parameters
        ----------
        quantity : `Quantity`
            The amount to withdraw from this wallet.
        reason : str
            The reason for withdrawing the amount.

        Returns
        -------
        `Quantity`
            The withdrawn amount.
        """
        if quantity.is_locked and self._locked.get(quantity.path_id, False):
            locked_quantity = self._locked[quantity.path_id]
            if quantity > locked_quantity:
                if (quantity-locked_quantity)>Decimal(10)**(-self.instrument.precision+2):
                    raise InsufficientFunds(locked_quantity, quantity)
                else:
                    quantity = locked_quantity
            self._locked[quantity.path_id] -= quantity

        elif not quantity.is_locked:
            if quantity > self.balance:
                if (quantity-self.balance)>Decimal(10)**(-self.instrument.precision+2):
                    raise InsufficientFunds(self.balance, quantity)
                else:
                    quantity = self.balance
            self.balance -= quantity

        self.balance = self.balance.quantize()

        self.ledger.commit(wallet=self,
                           quantity=quantity,
                           source="{}:{}/locked".format(self.exchange.name, self.instrument),
                           target=self.exchange.name,
                           memo="WITHDRAWAL ({})".format(reason))

        return quantity
Пример #2
0
    def lock(self, quantity, order: 'Order', reason: str) -> 'Quantity':
        """Locks funds for specified order.

        Parameters
        ----------
        quantity : `Quantity`
            The amount of funds to lock for the order.
        order : `Order`
            The order funds will be locked for.
        reason : str
            The reason for locking funds.

        Returns
        -------
        `Quantity`
            The locked quantity for `order`.

        Raises
        ------
        DoubleLockedQuantity
            Raised if the given amount is already a locked quantity.
        InsufficientFunds
            Raised if amount is greater the current balance.
        """
        if quantity.is_locked:
            raise DoubleLockedQuantity(quantity)

        if quantity > self.balance:
            raise InsufficientFunds(self.balance, quantity)

        self.balance -= quantity

        quantity = quantity.lock_for(order.path_id)

        if quantity.path_id not in self._locked:
            self._locked[quantity.path_id] = quantity
        else:
            self._locked[quantity.path_id] += quantity

        self._locked[quantity.path_id] = self._locked[
            quantity.path_id].quantize()
        self.balance = self.balance.quantize()

        self.ledger.commit(wallet=self,
                           quantity=quantity,
                           source="{}:{}/free".format(self.exchange.name,
                                                      self.instrument),
                           target="{}:{}/locked".format(
                               self.exchange.name, self.instrument),
                           memo="LOCK ({})".format(reason))

        return quantity
Пример #3
0
    def unlock(self, quantity: 'Quantity', reason: str) -> 'Quantity':
        """Unlocks a certain amount from the locked funds of the wallet that
        are associated with the given `quantity` path id.

        Parameters
        ----------
        quantity : `Quantity`
            The quantity to unlock from the funds.
        reason : str
            The reason for unlocking funds.

        Returns
        -------
        `Quantity`
            The free quantity.

        Raises
        ------
        DoubleUnlockedFunds
            Raised if `quantity` is not a locked quantity.
        QuantityNotLocked
            Raised if  `quantity` has a path id that is not currently allocated
            in this wallet.
        InsufficientFunds
            Raised if `quantity` is greater than the amount currently allocated
            for the associated path id.
        """
        if not quantity.is_locked:
            raise DoubleUnlockedQuantity(quantity)

        if quantity.path_id not in self._locked:
            raise QuantityNotLocked(quantity)

        if quantity > self._locked[quantity.path_id]:
            raise InsufficientFunds(self._locked[quantity.path_id], quantity)

        self._locked[quantity.path_id] -= quantity
        self.balance += quantity.free()

        self._locked[quantity.path_id] = self._locked[
            quantity.path_id].quantize()
        self.balance = self.balance.quantize()

        self.ledger.commit(
            wallet=self,
            quantity=quantity,
            source="{}:{}/locked".format(self.exchange.name, self.instrument),
            target="{}:{}/free".format(self.exchange.name, self.instrument),
            memo="UNLOCK {} ({})".format(self.instrument, reason))

        return quantity