Ejemplo n.º 1
0
    def cancel(self, session):
        users_and_holdings = Holding.users_that_hold_asset(
            session, self.contract_asset)
        if any(user for user, volume_sum in users_and_holdings
               if user is not self.issuer):
            logger.info(
                'Cannot cancel futures contract {} if other people hold it'.
                format(self.id))
            return False

        valid_states = (OrderStateType.cancelled.value,
                        OrderStateType.executed.value)
        if session.query(exists().where(
                and_(Order.contract == self,
                     Order.state.notin_(valid_states)))).scalar():
            logger.info(
                'There are orders not in state (cancelled, executed) for contract {}'
                .format(self.id))
            return False

        if self.expired or self.expires_at < datetime.now():
            logger.info(
                'The expire() method has been run or exp. date has passed for contract {}'
                .format(self.id))
            return False

        if self.cancelled:
            logger.info('The contract {} has already been cancelled'.format(
                self.id))
            return False

        # Return funds that was taken for deposit
        funds = self.issuer.increase_volume_of_asset(session, self.asset,
                                                     self.volume)
        if funds is None:
            logger.warning(
                'Could not return funds when cancelling futures contract {}'.
                format(self.id))
            return None

        # Remove entire volume held in the future (should always work)
        self.issuer.decrease_volume_of_asset(
            session, self.contract_asset,
            self.issuer.volume_of_asset(session, self.contract_asset))

        # We cannot delete the asset from database since we know that at least one `Holding` refers to it
        self.contract_asset.remove(session)

        if not session.query(Order).count():
            session.delete(self)
        else:
            self.cancelled = True
            session.add(self)

        session.commit()
        logger.info('Cancelled contract {}'.format(self.id))
        return True
Ejemplo n.º 2
0
    def expire(self, session):
        if self.expired:
            return

        users_and_holdings = Holding.users_that_hold_asset(session, self.contract_asset)

        # We may assume that all holdings are strictly positive
        total_volume = sum(volume_sum for _, volume_sum in users_and_holdings)
        for user, volume_sum in users_and_holdings:
            user.increase_volume_of_asset(session, self.asset, volume_sum / total_volume * self.volume)
            logger.info('Distributed {} of asset {} to user {}'.format(volume_sum, self.asset_id, user.id))

        self.expired = True
        session.add(self)
        session.commit()
Ejemplo n.º 3
0
    def expire(self, session):
        if self.expired:
            return

        users_and_holdings = Holding.users_that_hold_asset(
            session, self.contract_asset)

        # We may assume that all holdings are strictly positive
        total_volume = sum(volume_sum for _, volume_sum in users_and_holdings)
        for user, volume_sum in users_and_holdings:
            user.increase_volume_of_asset(
                session, self.asset, volume_sum / total_volume * self.volume)
            logger.info('Distributed {} of asset {} to user {}'.format(
                volume_sum, self.asset_id, user.id))

        self.expired = True
        session.add(self)
        session.commit()
Ejemplo n.º 4
0
    def cancel(self, session):
        users_and_holdings = Holding.users_that_hold_asset(session, self.contract_asset)
        if any(user for user, volume_sum in users_and_holdings if user is not self.issuer):
            logger.info('Cannot cancel futures contract {} if other people hold it'.format(self.id))
            return False

        valid_states = (OrderStateType.cancelled.value, OrderStateType.executed.value)
        if session.query(exists().where(and_(Order.contract == self, Order.state.notin_(valid_states)))).scalar():
            logger.info('There are orders not in state (cancelled, executed) for contract {}'.format(self.id))
            return False

        if self.expired or self.expires_at < datetime.now():
            logger.info('The expire() method has been run or exp. date has passed for contract {}'.format(self.id))
            return False

        if self.cancelled:
            logger.info('The contract {} has already been cancelled'.format(self.id))
            return False

        # Return funds that was taken for deposit
        funds = self.issuer.increase_volume_of_asset(session, self.asset, self.volume)
        if funds is None:
            logger.warning('Could not return funds when cancelling futures contract {}'.format(self.id))
            return None

        # Remove entire volume held in the future (should always work)
        self.issuer.decrease_volume_of_asset(session, self.contract_asset,
                                             self.issuer.volume_of_asset(session, self.contract_asset))

        # We cannot delete the asset from database since we know that at least one `Holding` refers to it
        self.contract_asset.remove(session)

        if not session.query(Order).count():
            session.delete(self)
        else:
            self.cancelled = True
            session.add(self)

        session.commit()
        logger.info('Cancelled contract {}'.format(self.id))
        return True