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
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()
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()
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