def test_deposit_shock(self): for b, d, c, f in zip(range(5), [10, 20, 30, 40, 50], [50, 20, 15, 10, 5], [.1, .2, .3, .4, .5]): bank = self.banks[b] bank.parameters.set('depositShockFactor', f) assert approx_equal(d, bank.deposits, 0.0000001), "expected bank %s to have %r deposits but got %r" % (b, d, bank.deposits) assert approx_equal(c, bank.cash, 0.0000001), "expected bank %s to have %r cash but got %r" % (b, c, bank.cash) for b, d, c in zip(range(5), [9, 16, 21, 24, 25], [49, 16, 6, -6, -20]): bank = self.banks[b] bank.do_deposit_shock() assert approx_equal(d, bank.deposits, 0.0000001), "expected bank %s to have %r deposits but got %r" % (b, d, bank.deposits) assert approx_equal(c, bank.cash, 0.0000001), "expected bank %s to have %r cash but got %r" % (b, c, bank.cash)
def test_banks_assets(self): simulator.do_economy_parameters(self.simInfo, self.pList, self.parameterDefs) simulator.do_bank_parameters(self.simInfo, self.pList, self.parameterDefs) eq_(len(self.simInfo.bankDirectory), 3, "Expected 3 banks but got %r" % len(self.simInfo.bankDirectory)) b1 = self.simInfo.bankDirectory["bank1"] b2 = self.simInfo.bankDirectory["bank2"] e1 = self.simInfo.economyDirectory["econ1"] e2 = self.simInfo.economyDirectory["econ2"] eq_(b1.economy, e1, "expected bank1's economy to be econ1 but is %r" % b1.economy) eq_(b2.economy, e2, "expected bank2's economy to be econ2 but is %r" % b2.economy) assert simulator.check_bank_nodes(self.simInfo) simulator.reset_economies(self.simInfo) simulator.reset_banks(self.simInfo) # expect the following bank loans to be in place: # bank1 -> bank2, mean size 10 # bank2 -> bank1, mean size 20 # bank2 -> bank3, mean size 20 # bank3 -> bank1, mean size 30 b3 = self.simInfo.bankDirectory["bank3"] for bFrom, bTo, bl in zip([b1, b2, b2, b3], [b2, b1, b3, b1], [10, 20, 20, 30]): lending = network.bank_lending(self.simInfo, bFrom, bTo) assert abs(bl - lending) < 10, ("expected lending from %s to %s to be roughly %r but is %r" % (bFrom.id_, bTo.id_, bl, lending)) borrowing = network.bank_borrowing(self.simInfo, bTo, bFrom) assert abs(bl - borrowing) < 10, ("expected borrowing to %s from %s to be roughly %r but is %r" % (bTo.id_, bFrom.id_, bl, borrowing)) for b, far, cr, capR in zip([b1, b2, b3], [0.30, 0.40, 0.25], [0.1, 0.15, 0.15], [0.15, .2, .125]): assert approx_equal(b.total_assets(), b.total_liabilities() + b.equity_value(), .0000001), \ "Expected %s balance sheet to balance: assets %f, liabilities %f, capital %f" % ( b.id_, b.total_assets(), b.total_liabilities(), b.equity_value()) thisFar = b.financial_asset_ratio() thisCr = b.cash / b.total_assets() thisCapR = b.equity_value() / b.total_assets() if b.deposits > 0: # there was no hanky panky assert approx_equal(far, thisFar, .0000001), ("Expected %s financial asset ratio to be %f but is %f" % (b.id_, far, thisFar)) assert approx_equal(cr, thisCr, .0000001), ("Expected %s cash ratio to be %f but is %f" % (b.id_, cr, thisCr)) assert approx_equal(capR, thisCapR, .0000001), ("Expected %s capital ratio to be %f but is %f" % (b.id_, capR, thisCapR)) else: assert thisFar < far, ("Expected %s financial asset ratio to be less than %f but is %f" % (b.id_, far, thisFar)) assert thisCr > cr, ("Expected %s cash ratio to be greater than %f but is %f" % (b.id_, cr, thisCr)) assert thisCapR < capR, ("Expected %s capital ratio to be less than %f but is %f" % (b.id_, capR, thisCapR))
def test_firesale(self): parameterDefs = simulator.define_parameters() eParams = Parameters(parameterDefs) simInfo = SimulationInfo() econ = Economy(simInfo, "Economy1", eParams) inv = [] holders = [] for i in range(5): inv.append(econ.create_investment()) holders.append("holder%s" % i) econ.params.set('fireSaleFactor', 1.0) # price is affected by sales simInfo.updateCount = 1 for i in range(5): inv[0].buy(5, holders[i]) inv[1].buy(5, holders[i]) # one holder sells a bit of the investment simInfo.updateCount = 2 q, v = inv[0].sell(1, holders[0]) assert v < 1, "expected consideration < 1 but is %f" % v eq_(v, inv[0].currentPrice, "expected consideration equal to price but they are %f, %f" % (v, inv[0].currentPrice)) check_asset_holding(inv[0], holders[0], quantity=4, value=4 * v, tag="fs1") check_asset_holding(inv[0], holders[1], quantity=5, value=5 * v, tag="fs1") price1 = inv[0].currentPrice simInfo.updateCount = 3 q, v = inv[0].sell(3, holders[2]) # a total of 4 has now been sold price2 = inv[0].currentPrice assert price2 < price1, "expected price < %f but is %f (fs2)" % (price1, price2) assert approx_equal(v, price2 * q, 0.00001), "expected consideration %f but is %f (fs2)" % (price2 * q, v) simInfo.updateCount = 4 inv[1].sell(4, holders[3]) # sell 4, so price should be same as inv0 price3 = inv[1].currentPrice assert approx_equal(price2, price3, 0.00001), "expected price to be %f but is %f (fs3)" % (price2, price3) pHistory = inv[1].priceHistory when, price = pHistory[-1] eq_(4, when, "expected last item in price history to be at time 4 but got %r" % when) eq_(price3, price, "expected last item in price history to be price %f but got %f" % (price3, price))
def test_reduce_inv(self): self.econ.params.set('fireSaleFactor', 0.0) investments = self.banks[0].get_investments() eq_(1, len(investments), "expected bank 0 to have one investment but has %r" % investments) self.simInfo.updateCount = 1 self.banks[0].reduce_investments(0.5) # no other banks have investments in common with bank 0 affected = self.banks[0].get_sharing_banks() eq_(0, len(affected), "Expected no banks to be affected but found %r (1)" % len(affected)) iVal = self.banks[0].investment_value() assert approx_equal(25, iVal, 0.00001), "expected bank 0 to have investments of 25 but has %r (2)" % iVal investments = self.banks[1].get_investments() eq_(2, len(investments), "expected bank 1 to have 2 investments but has %r" % investments) self.simInfo.updateCount = 2 self.banks[1].reduce_investments(0.5) affected = self.banks[1].get_sharing_banks() eq_(3, len(affected), "expected bank 1 to affect 3 banks but affects %r" % len(affected)) iVal = self.banks[1].investment_value() assert approx_equal(10, iVal, 0.00001), "expected bank 1 to have investments of 10 but has %r (2)" % iVal
def test_banks_liabilities(self): simulator.do_economy_parameters(self.simInfo, self.pList, self.parameterDefs) simulator.do_bank_parameters(self.simInfo, self.pList, self.parameterDefs) self.simInfo.theParameters.set('balanceSheetMethod', 'liabilities') b1 = self.simInfo.bankDirectory["bank1"] b2 = self.simInfo.bankDirectory["bank2"] simulator.reset_economies(self.simInfo) simulator.reset_banks(self.simInfo) # expect the following bank loans to be in place: # bank1 -> bank2, mean size 10 # bank2 -> bank1, mean size 20 # bank2 -> bank3, mean size 20 # bank3 -> bank1, mean size 30 b3 = self.simInfo.bankDirectory["bank3"] for b, capR, flr, cr in zip([b1, b2, b3], [0.15, .2, .125], [0.7, 0.2, 0.7], [0.1, 0.15, 0.15]): assert approx_equal(b.total_assets(), b.total_liabilities() + b.equity_value(), .0000001), \ "Expected %s balance sheet to balance: assets %f, liabilities %f, capital %f" % ( b.id_, b.total_assets(), b.total_liabilities(), b.equity_value()) thisCapR = b.equity_value() / b.total_assets() thisFlr = b.financial_liability_ratio() thisCr = b.cash / b.total_assets() thisInv = b.investment_value() if thisInv > 0: # no hanky panky assert approx_equal(capR, thisCapR, .0000001), ("Expected %s capital ratio to be %f but is %f" % (b.id_, capR, thisCapR)) assert approx_equal(flr, thisFlr, .0000001), ("Expected %s financial liability ratio to be %f but is %f" % (b.id_, flr, thisFlr)) assert approx_equal(cr, thisCr, .0000001), ("Expected %s cash ratio to be %f but is %f" % (b.id_, cr, thisCr)) else: assert thisCapR < capR, ("Expected %s capital ratio to be less than %f but is %f" % (b.id_, capR, thisCapR)) assert thisFlr < flr, ("Expected %s financial liability ratio to be less than %f but is %f" % (b.id_, flr, thisFlr)) assert thisCr < cr, ("Expected %s cash ratio to be less than %f but is %f" % (b.id_, cr, thisCr))
def test_default_bank(self): self.banks[1].cash = -10 # this sends it insolvent # with assets 20 and liabilities 21 self.banks[1].check_solvency() prop = 20.0 / 21.0 self.simInfo.updateCount = 2 affected = network.do_default_loans(self.simInfo, self.banks[1], prop) eq_(1, len(affected), "1 bank should be affected, but %r are" % len(affected)) assert self.banks[0] in affected, "Bank 0 should be affected but isn't" # 0 had lent 1 1, and borrowed 10 # orig bank lending and borrowing: # lending: 0 10, 1 10, 2 20, 3 30, 4 40 # borrowing: 0 100, 1 1, 2 2, 3 3, 4 4 bl = network.bank_lending(self.simInfo, self.banks[1]) assert approx_equal(10, bl, 0.0000001), "Bank %r lending should be %r but is %r (def1)" % (0, 10, bl) # the lending has been netted off... bl = network.bank_borrowing(self.simInfo, (self.banks[1])) assert approx_equal(prop, bl, 0.0000001), "Bank %r lending should be %r but is %r (def2)" % (0, prop, bl) eq_(1, len(affected), "1 banks should be affected, but %r are" % len(affected))
def test_update1(self): self.econ.params.set('targetCashProportion', 0.0) self.econ.params.set('assetSalesFactor', 1.0) self.banks[0].cash = -10 self.banks[0].check_solvency() assert not self.banks[0].solvent, "expected bank to be insolvent!! (up1)" self.simInfo.updateCount = 1 affected, ratio = self.banks[0].update() # assets = 50 (with -10 cash), liabilities 110 # so liabilities reduced to 5/11 of original prop = 5.0 / 11.0 # it has borrowed from 4 other banks... eq_(4, len(affected), "Expected 4 banks to be affected but found %r (up1)" % len(affected)) for b, bl in zip([1, 2, 3, 4], [10, 20, 30, 40]): lHistory = self.banks[0].borrowingHistory[self.banks[b]] thisB = self.banks[b].id_ # expect 2 entries in each history, one from when the loan was set up and one from the update eq_(2, len(lHistory), "expected 2 entries in the loan history for %s but got %r" % (thisB, len(lHistory))) when, amount = lHistory[1] # last entry eq_(1, when, "expected last entry in loan history for %s to be 1, but was %r" % (thisB, when)) assert approx_equal(amount, prop * bl, 0.0000001), "expected last loan history amount for %s to be %f, but got %f" % ( thisB, prop * bl, amount) when, amount = lHistory[0] # first entry eq_(0, when, "expected first entry in loan history for %s to be 0, but was %r" % (thisB, when)) assert approx_equal(amount, bl, 0.00000001), "expected first loan history amount for %s to be %f, but got %f" % ( thisB, bl, amount) # Insolvent, so nothing is done about its liquidity iVal = self.banks[0].investment_value() assert approx_equal(50, iVal, 0.00001), "expected bank 0 to have investments of 50 but has %r (up1)" % iVal assert approx_equal(-10, self.banks[0].cash, "expected bank 0 to have -10 cash but has %f (up1)" % self.banks[0].cash) # but it should have defaulted on its liabilities dHistory = self.banks[0].defaultHistory eq_(len(dHistory), 1, "expected an entry in the default history but got %r" % len(dHistory)) liabilities = self.banks[0].total_liabilities() assert approx_equal(50, liabilities, .0000001), "Expected total liabilities to be 50 but got %f" % liabilities deposits = self.banks[0].deposits assert approx_equal(prop * 10, deposits, .00000001), "Expected deposits to be %f but got %f" % (prop * 10, deposits) capital = self.banks[0].equity_value() assert approx_equal(0, capital, 0.00000001), "Expected zero capital but got %f" % capital # it has been updated, so should have a history entry hLen = len(self.banks[0].stateHistory) eq_(hLen, 1, "expected 1 entry in state history but got %r" % hLen)
def train(self): # saver self.logger.info('Initialize saver ...') train_saver = Saver(self.sess, tf.global_variables(), self.cfg.model_dir) merged = tf.summary.merge_all() writer = tf.summary.FileWriter(self.cfg.log_dir, self.sess.graph) # initialize weights self.logger.info('Initialize all variables ...') self.sess.run( tf.variables_initializer(tf.global_variables(), name='init')) self.load_weights(self.cfg.init_model) self.logger.info('Start training ...') start_itr = self.cur_epoch * self.itr_per_epoch + 1 end_itr = self.itr_per_epoch * self.cfg.end_epoch + 1 for itr in range(start_itr, end_itr): self.tot_timer.tic() self.cur_epoch = itr // self.itr_per_epoch setproctitle.setproctitle('train epoch:' + str(self.cur_epoch)) cur_lr = get_lr(self.cur_epoch) if not approx_equal(cur_lr, self.lr_eval): print(self.lr_eval, cur_lr) self.sess.run(tf.assign(self.lr, cur_lr)) # input data self.read_timer.tic() feed_dict = self.next_feed() self.read_timer.toc() # train one step self.gpu_timer.tic() _, self.lr_eval, *summary_res = self.sess.run( [self.graph_ops[0], self.lr, *self.summary_dict.values()], feed_dict=feed_dict) self.gpu_timer.toc() if (itr % 1 == 0): result = self.sess.run(merged, feed_dict=feed_dict) writer.add_summary(result, itr) itr_summary = dict() for i, k in enumerate(self.summary_dict.keys()): itr_summary[k] = summary_res[i] screen = [ 'Epoch %d itr %d/%d:' % (self.cur_epoch, itr, self.itr_per_epoch), 'lr: %g' % (self.lr_eval), 'speed: %.2f(%.2fs r%.2f)s/itr' % (self.tot_timer.average_time, self.gpu_timer.average_time, self.read_timer.average_time), '%.2fh/epoch' % (self.tot_timer.average_time / 3600. * self.itr_per_epoch), ' '.join( map(lambda x: '%s: %.4f' % (x[0], x[1]), itr_summary.items())), ] if itr % self.cfg.display == 0: self.logger.info(' '.join(screen)) if itr % self.itr_per_epoch == 0: train_saver.save_model(self.cur_epoch) self.tot_timer.toc()
def test_lending(self): # check individual loans between the banks in both directions for b, l, factor in zip(range(5), [10, 10, 20, 30, 40], [.5, 0, .1, .6, .8]): thisBank = self.banks[b] thisBank.parameters.set('loanShockFactor', factor) # used later... bl = network.bank_lending(self.simInfo, self.banks[b]) eq_(l, bl, "Bank %r lending should be %r but is %r (mat1)" % (b, l, bl)) if b != 0: lHistory0 = self.banks[0].borrowingHistory[thisBank] # should have only initial setup in eq_(len(lHistory0), 1, "expected loan history from %r to 0 to have 1 entry but got %r" % (b, len(lHistory0))) when, amount = lHistory0[0] eq_(when, 0, "expected last loan history item from %r to 0 to be at time 0 but got %r" % (b, when)) eq_(amount, l, "expected last loan history item from %r to 0 to be amount %r but got %r" % (b, l, amount)) for b, l in zip(range(5), [100, 1, 2, 3, 4]): thisBank = self.banks[b] bl = network.bank_borrowing(self.simInfo, self.banks[b]) eq_(l, bl, "Bank %r borrowing should be %r but is %r (mat2)" % (b, l, bl)) lHistory = thisBank.borrowingHistory if b == 0: eq_(len(lHistory), 4, "expected loan history for %r to have length 4 but got %r" % (b, len(lHistory))) else: eq_(len(lHistory), 1, "expected loan history for %r to have length 1 but got %r" % (b, len(lHistory))) lHistory0 = lHistory[self.banks[0]] eq_(len(lHistory0), 1, "expected loan history from 0 to %r to have 1 entry but got %r" % (b, len(lHistory0))) when, amount = lHistory0[0] eq_(when, 0, "expected last loan history item from 0 to %r to be at time 0 but got %r" % (b, when)) eq_(amount, l, "expected last loan history item from 0 to %r to be amount %r but got %r" % (b, l, amount)) self.simInfo.updateCount = 2 for bank in self.banks: bank.do_loan_shock() for b, l in zip(range(5), [4.8, 5, 10, 15, 20]): thisBank = self.banks[b] bl = network.bank_lending(self.simInfo, self.banks[b]) assert approx_equal(l, bl, 0.000001), "Bank %r lending should be %r but is %r (mat3)" % (b, l, bl) if b != 0: lHistory0 = self.banks[0].borrowingHistory[thisBank] # should have initial setup plus loan maturities eq_(len(lHistory0), 2, "expected loan history from %r to 0 to have 2 entries but got %r" % (b, len(lHistory0))) when, amount = lHistory0[1] eq_(when, 2, "expected last loan history item from %r to 0 to be at time 2 but got %r" % (b, when)) eq_(amount, l, "expected last loan history item from %r to 0 to be amount %r but got %r" % (b, l, amount)) for b, l in zip(range(5), [50, 1, 1.8, 1.2, .8]): thisBank = self.banks[b] bl = network.bank_borrowing(self.simInfo, self.banks[b]) assert approx_equal(l, bl, 0.0000001), "Bank %r borrowing should be %r but is %r (mat4)" % (b, l, bl) lHistory = thisBank.borrowingHistory if b == 0: eq_(len(lHistory), 4, "expected loan history for %r to have length 4 but got %r" % (b, len(lHistory))) else: eq_(len(lHistory), 1, "expected loan history for %r to have length 1 but got %r" % (b, len(lHistory))) lHistory0 = lHistory[self.banks[0]] # history of borrowing from bank0 if b == 1: # factor for bank 1 is 0, so nothing happens lhLen = 1 lhWhen = 0 else: lhLen = 2 lhWhen = 2 eq_(len(lHistory0), lhLen, "expected loan history from 0 to %r to have %r entries but got %r" % (b, lhLen, len(lHistory0))) when, amount = lHistory0[lhLen - 1] eq_(when, lhWhen, "expected last loan history item from 0 to %r to be at time %s but got %r" % (b, lhWhen, when)) assert approx_equal(amount, l, 0.0000001), ( "expected last loan history item from 0 to %r to be amount %r but got %r" % ( b, l, amount)) # orig cash: 50 20 15 10 5 for b, l in zip(range(5), [5.2, 25, 24.8, 23.2, 21.8]): bank = self.banks[b] bl = bank.cash assert approx_equal(l, bl, 0.0000001), "Bank %r cash should be %r but is %r (mat5)" % (b, l, bl) # orig liabilities: 110, 21, 32, 43, 54 for b, l in zip(range(5), [60, 21, 31.8, 41.2, 50.8]): bank = self.banks[b] bl = bank.total_liabilities() eq_(l, bl, "Bank %r liabilities should be %r but is %r (mat6)" % (b, l, bl)) # orig assets: 110, 50, 75, 70, 125 for b, l in zip(range(5), [60, 50, 74.8, 68.2, 121.8]): bank = self.banks[b] bl = bank.total_assets() eq_(l, bl, "Bank %r assets should be %r but is %r (mat7)" % (b, l, bl)) # equity value hasn't changed, as loans have just been swapped for cash for b, l in zip(range(5), [0, 29, 43, 27, 71]): bank = self.banks[b] bl = bank.equity_value() eq_(l, bl, "Bank %r equity should be %r but is %r (mat8)" % (b, l, bl))
def test_liquidise(self): self.econ.params.set('fireSaleFactor', 0.0) self.banks[0].cash = -10 self.simInfo.updateCount = 3 affected = self.banks[0].liquidise(0.0, 1.0) # Should have needed to sell off 10 in investments eq_(0, len(affected), "Expected no banks to be affected but found %r (liq1)" % len(affected)) iVal = self.banks[0].investment_value() bCash = self.banks[0].cash assert approx_equal(40, iVal, 0.00001), "expected bank 0 to have investments of 40 but has %r (liq1)" % iVal assert approx_equal(0, bCash, 0.000001), "expected bank 0 to have zero cash but has %f (liq1)" % bCash self.simInfo.updateCount = 5 affected = self.banks[4].liquidise(.1, 1.0) # should take investments down to 72.5 eq_(3, len(affected), "Expected 3 banks to be affected but found %r (liq2)" % len(affected)) iVal = self.banks[4].investment_value() bCash = self.banks[4].cash assert approx_equal(72.5, iVal, 0.00001), "expected bank 4 to have investments of 72.5 but has %r (liq2)" % iVal assert approx_equal(12.5, bCash, 0.000001), "expected bank 4 to have 12.5 cash but has %f (liq2)" % bCash self.simInfo.updateCount = 6 affected = self.banks[2].liquidise(0, 1.0) # should have no effect eq_(0, len(affected), "Expected no banks to be affected but found %r (liq3)" % len(affected)) iVal = self.banks[2].investment_value() bCash = self.banks[2].cash assert approx_equal(40, iVal, 0.00001), "expected bank 2 to have investments of 40 but has %r (liq3)" % iVal assert approx_equal(15, bCash, 0.000001), "expected bank 2 to have 15 cash but has %f (liq3)" % bCash self.banks[2].cash = -10 # takes actual assets to 60, net assets to 50 self.simInfo.updateCount = 7 affected = self.banks[2].liquidise(0.1, 1.0) # should end up with 6 cash, having sold 16 investments eq_(3, len(affected), "Expected 3 banks to be affected but found %r (liq4)" % len(affected)) iVal = self.banks[2].investment_value() bCash = self.banks[2].cash assert approx_equal(24, iVal, 0.00001), "expected bank 2 to have investments of 24 but has %r (liq4)" % iVal assert approx_equal(6, bCash, 0.0000001), "expected bank 2 to have 6 cash but has %f (liq4)" % bCash # we expect to run out of investments on this one self.simInfo.updateCount = 8 affected = self.banks[1].liquidise(0.9, 1.0) ta = self.banks[1].total_assets() iv = self.banks[1].investment_value() bCash = self.banks[1].cash assert bCash < 0.9 * ta, "expected less than %f cash, but got %f" % (0.9 * ta, bCash) assert approx_equal(0, iv, 0.00001), "expected zero investments but got %f" % iv eq_(3, len(affected), "expected 3 banks to be affected but got %r (liq4.5)" % len(affected)) affected = self.banks[1].get_sharing_banks() eq_(0, len(affected), "expected 0 sharing banks but got %r (liq4.5)" % len(affected)) self.econ.params.set('fireSaleFactor', 1.0) # price falls on sales self.simInfo.updateCount = 9 self.banks[3].liquidise(0.2, 1.1) # total assets will fall, because of sales ta = self.banks[3].total_assets() bCash = self.banks[3].cash assert ta < 70, "expected total assets < 70 but is %f (liq5)" % ta assert bCash >= 0.2 * ta, "expected cash >= %f but is %f (liq5)" % (0.2 * ta, bCash)