DEFAULT_THRESHOLD = 4 class Person ( object ): def __init__ ( self , bank , endowment , productivities , preferences , investment_pref , savings_pref ): ''' :param bank: which Bank does this Person banks with? :param endowment: how much savings does a person initially start with? rich families = high endowment :param productivities: a list of numbers the size of `basket`. This represents how many goods Person can produce per period. :param preferences: a list of floats the size of `basket` :param investment_pref: a float between [0,1). 0 = person doesn't care about his/her future earnings ''' self . bank = bank self . savings = endowment self . bank . holding += self . savings self . productivities = productivities self . preferences = preferences self . investment_pref = investment_pref self . savings_pref = savings_pref self . loans = [] self . investments = [] self . last_income = endowment self . nonpayment = 0 self . defaulted = False self . consumerism = np . random . beta ( 3 , 5 ) def utility ( self , q , investment ): ''' utility represents a utility a Person has when presented with an allocation of goods and investment. :param q: a list of quantities :param investment: a number ''' u = 1 for g , p in zip ( q , self . preferences ): u *= math . pow ( g , p ) u *= math . pow ( investment , self . investment_pref ) return u def normalized_preferences ( self ): return [ pref / ( sum ( self . preferences ) + self . investment_pref + self . savings_pref ) for pref in self . preferences ] def normalized_productivities ( self ): return [ prod / sum ( self . productivities ) for prod in self . productivities ] def produce ( self , priceMatrix , current ): ''' produce simulates the production capactity of a Person. ''' normal_prod = np . array ( self . normalized_productivities ()) budget = self . budget ( current ) quantities = normal_prod * priceMatrix return quantities def consume ( self , priceMatrix , current ): ''' Returns the demand given the prices. Demand is inelastick, because these Persons are turdballs. ''' normal_pref = np . array ( self . normalized_preferences ()) budget = self . budget ( current ) quantities = normal_pref * budget / priceMatrix return quantities def budget ( self , current ): ''' The budget forms the constraint for a Person in his/her consumption ''' repayments = 0.0 for loan in self . loans : if current == loan . repay_at : repayments += loan . repay_amount () return self . creditworthiness () * self . consumerism + self . savings - ( 1 - self . consumerism ) * repayments def creditworthiness ( self ): ''' creditworthiness determines how much a Person can borrow from the bank ''' if self . savings > 0 : return self . last_income + ( self . last_income * interest_rate ) + self . savings elif self . last_income > 0 : return self . last_income + ( self . last_income * interest_rate ) return 0 # NO CREDIT FOR YOU! def debt ( self ): ''' How much debt does a Person have? ''' amount = 0.0 for loan in self . loans : amount += loan . repay_amount () return amount def spend ( self , amount , current ): if amount < self . savings : self . savings -= amount return elif amount > self . savings : if self . bank . can_lend ( amount ): loan = Loan ( self . bank , self , self . creditworthiness (), current + 5 , interest_rate ) self . loans . append ( loan ) self . bank . lend ( loan ) else : self . savings = 0 def earn ( self , income ): self . savings += income self . last_income = income def invest ( self , amount , current ): investment = Investment ( amount , interest_rate , current + 7 ) self . investments . append ( investment ) def step ( self , prices , current ): production = self . produce ( prices , current ) income = sum ([ p * q for p , q in zip ( prices , production )]) consumption = self . consume ( prices , current ) inv_pref = self . investment_pref / ( sum ( self . preferences ) + self . investment_pref ) inv_amt = inv_pref * self . budget ( current ) norm_prod = self . normalized_productivities () prod_cost = [ p * q for p , q in zip ( prices , production )] prod_cost = sum ( n * c for n , c in zip ( norm_prod , prod_cost )) cost = sum ([ p * q for p , q in zip ( prices , consumption )]) + inv_amt + prod_cost self . earn ( income ) self . spend ( cost , current ) if self . savings > inv_amt : self . invest ( inv_amt , current ) # remove loans that are up remove = [] cantpay = False for loan in self . loans : if loan . repay_at <= current : if self . savings >= loan . repay_amount (): self . savings -= loan . repay_amount () self . bank . repay ( loan ) remove . append ( loan ) else : cantpay = True for loan in remove : self . loans . remove ( loan ) if cantpay : self . nonpayment += 1 # realize investments remove = [] for investment in self . investments : if investment . return_at == current : self . savings += investment . principle * ( 1 + investment . return_rate ) self . productivities = [ prod * ( 1 + investment . p ) for prod in self . productivities ] remove . append ( investment ) for investment in remove : self . investments . remove ( investment ) # check for defaults if self . nonpayment >= DEFAULT_THRESHOLD : self . defaulted = True default_amt = 0.0 for loan in self . loans : default_amt += loan . amount self . bank . unrecovered -= default_amt