def test_Market_handling(self): mod = Model() ext = ExternalSector(mod) ca = Country(mod, 'CA', 'Canada', currency='CAD') us = Country(mod, 'US', 'United States', currency='USD') # gov_us.AddVariable('T', 'Government Taxes', '0.') gov_ca = Sector(ca, 'GOV', 'Gummint') gov_ca.AddVariable('DEM_GOOD', 'desc', '20.') market = Market(ca, 'GOOD', 'Market') supplier_ca = Sector(ca, 'BUS', 'Canada supplier') supplier_us = Sector(us, 'BUS', 'US Supplier') # Set supply so that CAD$10 is paid to each supplier. market.AddSupplier(supplier_ca) market.AddSupplier(supplier_us, '10.') # Set CAD = 2, so 2 USD = 1 CAD (USD is weaker.) mod.AddExogenous('EXT_XR', 'CAD', '[2.0,]*3') mod.EquationSolver.MaxTime = 1 mod.main() mod.TimeSeriesSupressTimeZero = True # The business sector nets USD$20 self.assertEqual([20.], mod.GetTimeSeries('US_BUS__F')) # The USD market is unbalanced; shortage of 20 USD self.assertEqual([-20.], mod.GetTimeSeries('EXT_FX__NET_USD')) # The CAD market is unbalanced; excess of 10 CAD self.assertEqual([10.], mod.GetTimeSeries('EXT_FX__NET_CAD')) # The supply in the US sector is USD $20 self.assertEqual([20.], mod.GetTimeSeries('US_BUS__SUP_CA_GOOD')) # THe supply on the Canadian side is CAD $10 self.assertEqual([10.], mod.GetTimeSeries('CA_GOOD__SUP_US_BUS'))
def test_GenerateEquations_no_supply(self): mod = Model() can = Country(mod, 'Eh', 'Canada') mar = Market(can, 'LAB', 'Market') bus = Sector(can, 'BUS', 'Business') bus.AddVariable('DEM_LAB', 'desc', '') mod._GenerateFullSectorCodes() with self.assertRaises(ValueError): mar._GenerateEquations()
def test_GenerateTermsLowLevel(self): mod = Model() can = Country(mod, 'Eh', 'Canada') mar = Market(can, 'LAB', 'Market') bus = Sector(can, 'BUS', 'Business') bus.AddVariable('DEM_LAB', 'desc', '') mod._GenerateFullSectorCodes() mar._GenerateTermsLowLevel('DEM', 'Demand') self.assertIn('-DEM_LAB', bus.EquationBlock['F'].RHS()) self.assertEqual('0.0', bus.EquationBlock['DEM_LAB'].RHS())
def test_GenerateEquations_2_supply_fail(self): mod = Model() can = Country(mod, 'Eh', 'Canada') mar = Market(can, 'LAB', 'Market') bus = Sector(can, 'BUS', 'Business') hh = Sector(can, 'HH', 'Household') hh2 = Sector(can, 'HH2', 'Household') bus.AddVariable('DEM_LAB', 'desc', 'x') hh.AddVariable('SUP_LAB', 'desc 2', '') hh2.AddVariable('SUP_LAB', 'desc 2', '') mod._GenerateFullSectorCodes() with self.assertRaises(LogicError): mar._GenerateEquations()
def build_model(self): country = self.Country gov = ConsolidatedGovernment(country, 'GOV', 'Government') hh = Household(country, 'HH', 'Household', alpha_income=.6, alpha_fin=.4) # A literally non-profit business sector bus = FixedMarginBusiness(country, 'BUS', 'Business Sector') # Create the linkages between sectors - tax flow, markets - labour ('LAB'), goods ('GOOD') tax = TaxFlow(country, 'TF', 'TaxFlow', taxrate=.2) labour = Market(country, 'LAB', 'Labour market') goods = Market(country, 'GOOD', 'Goods market') if self.UseBookExogenous: # Need to set the exogenous variable - Government demand for Goods ("G" in economist symbology) gov.SetExogenous('DEM_GOOD', '[0.,] + [20.,] * 105') return self.Model
def CreateCountry(mod, name, code): # Create the country. cntry = Country(mod, code, name) # Create sectors ConsolidatedGovernment(cntry, 'GOV', 'Government') hou = Household(cntry, 'HH', 'Household') hou.AddVariable('TaxRate', 'Tax rate for workers', '.2') cap = Capitalists(cntry, 'CAP', 'Capitalists') cap.AddVariable('TaxRate', 'Tax rate for capitalists', '0.3') FixedMarginBusiness(cntry, 'BUS', 'Business Sector') # Create the linkages between sectors - tax flow, markets - labour ('LAB'), goods ('GOOD') TaxFlow(cntry, 'TF', 'TaxFlow', .2) Market(cntry, 'LAB', 'Labour market') Market(cntry, 'GOOD', 'Goods market') return cntry
def main(): # Create model, which holds all entities mod = Model() # Create first country - Canada. (This model only has one country.) can = Country(mod, 'CA', 'Canada') # Create sectors tre = Treasury(can, 'TRE', 'Treasury') cb = CentralBank(can, 'CB', 'Central Bank') hh = Household(can, 'HH', 'Household') # A literally non-profit business sector bus = FixedMarginBusiness(can, 'BUS', 'Business Sector') # Create the linkages between sectors - tax flow, markets - labour ('LAB'), goods ('GOOD') tax = TaxFlow(can, 'TF', 'TaxFlow', .2) labour = Market(can, 'LAB', 'Labour market') goods = Market(can, 'GOOD', 'Goods market') # Add the financial markets # GOV -> issuing sector mm = MoneyMarket(can) dep = DepositMarket(can) # -------------------------------------------- # Financial asset demand equations # Need to call this before we set the demand functions for mod._GenerateFullSectorCodes() # Need the full variable name for 'F' in household hh_F = hh.GetVariableName('F') hh.AddVariable('DEM_MON', 'Demand for Money', '0.5 * ' + hh_F) hh.AddVariable('DEM_DEP', 'Demand for deposits', '0.5 * ' + hh_F) # ----------------------------------------------------------------- # Need to set the exogenous variables # Government demand for Goods ("G" in economist symbology) mod.AddExogenous('TRE', 'DEM_GOOD', '[20.,] * 105') mod.AddExogenous('DEP', 'r', '[0.0,] * 5 + [0.04]*100') mod.AddInitialCondition('HH', 'F', 80.) # Build the model # Output is put into two files, based on the file name passed into main() ['out_SIM_Machine_Model'] # (1) [out_YYY]_log.txt: Log file # (2) [out_YYY].py: File that solves the system of equations mod.MaxTime = 100 eqns = mod._main_deprecated('out_ex20170108_model_PC') # Only import after the file is created (which is unusual). import out_ex20170108_model_PC as SFCmod obj = SFCmod.SFCModel() obj.main() obj.WriteCSV('out_ex20170103_model_PC.csv') Quick2DPlot(obj.t[1:], obj.GOOD_SUP_GOOD[1:], 'Goods supplied (national production Y)') Quick2DPlot(obj.t[1:], obj.HH_F[1:], 'Household Financial Assets (F)')
def test_GenerateEquations(self): mod = Model() can = Country(mod, 'Eh', 'Canada') mar = Market(can, 'LAB', 'Market') bus = Sector(can, 'BUS', 'Business') hh = Sector(can, 'HH', 'Household') bus.AddVariable('DEM_LAB', 'desc', 'x') hh.AddVariable('SUP_LAB', 'desc 2', '') mod._GenerateFullSectorCodes() mar._GenerateEquations() self.assertIn('-DEM_LAB', bus.EquationBlock['F'].RHS()) self.assertEqual('x', bus.EquationBlock['DEM_LAB'].RHS()) self.assertEqual('LAG_F+SUP_LAB', hh.EquationBlock['F'].RHS()) # self.assertEqual('BUS_DEM_LAB', hh.Equations['SUP_LAB'].strip()) self.assertEqual('SUP_LAB', mar.EquationBlock['SUP_HH'].RHS()) self.assertEqual('LAB__SUP_HH', hh.EquationBlock['SUP_LAB'].RHS().strip())
def build_model(self): country = self.Country gov = ConsolidatedGovernment(country, 'GOV', 'Government') hh = HouseholdWithExpectations(country, 'HH', 'Household', alpha_income=.6, alpha_fin=.4) # A literally non-profit business sector bus = FixedMarginBusiness(country, 'BUS', 'Business Sector') # Create the linkages between sectors - tax flow, markets - labour ('LAB'), goods ('GOOD') tax = TaxFlow(country, 'TF', 'TaxFlow', .2) labour = Market(country, 'LAB', 'Labour market') goods = Market(country, 'GOOD', 'Goods market') if self.UseBookExogenous: # Need to set the exogenous variable - Government demand for Goods ("G" in economist symbology) gov.SetExogenous('DEM_GOOD', '[0.,] + [20.,] * 105') # In order to replicate the book results, we need to patch in this initial condition so that the # expected income in period 1 is 16. self.Model.AddInitialCondition('HH', 'AfterTax', 16.) return self.Model
def test_GenerateEquations_2_supply_multicountry_3(self): mod = Model() # Need to stay in the same currency zone can = Country(mod, 'CA', 'Canada, Eh?', currency='LOC') US = Country(mod, 'US', 'USA! USA!', currency='LOC') mar = Market(can, 'LAB', 'Market') bus = Sector(can, 'BUS', 'Business') hh = Sector(can, 'HH', 'Household') # Somehow, Americans are supplying labour in Canada... hh2 = Sector(US, 'HH2', 'Household') hh3 = Sector(US, 'HH3', 'Household#3') bus.AddVariable('DEM_LAB', 'desc', 'x') hh.AddVariable('SUP_LAB', 'desc 2', '') hh2.AddVariable('SUP_CA_LAB', 'desc 2', '') hh3.AddVariable('SUP_CA_LAB', 'desc 2', '') mod._GenerateFullSectorCodes() #mar.SupplyAllocation = [[(hh, 'SUP_LAB/2'), (hh3, '0.')], hh2] mar.AddSupplier(hh2) mar.AddSupplier(hh, 'SUP_LAB/2') mar.AddSupplier(hh3, '0.') mar._GenerateEquations() self.assertEqual('SUP_LAB/2', mar.EquationBlock['SUP_CA_HH'].RHS()) self.assertEqual('SUP_LAB-SUP_CA_HH-SUP_US_HH3', kill_spaces(mar.EquationBlock['SUP_US_HH2'].RHS())) self.assertEqual('CA_LAB__SUP_CA_HH', hh.EquationBlock['SUP_LAB'].RHS()) self.assertIn('SUP_LAB', hh.EquationBlock['F'].RHS()) self.assertEqual('CA_LAB__SUP_US_HH2', hh2.EquationBlock['SUP_CA_LAB'].RHS()) self.assertIn('SUP_CA_LAB', hh2.EquationBlock['F'].RHS()) self.assertIn('SUP_CA_LAB', hh3.EquationBlock['F'].RHS())
def test_GoldSectors(self): # Relatively big test, but it takes a lot of work to get a model # where we can create a GoldStandardCentralBank, and to set up the # equations so that they need to intervene. # Consider this an end-to-end test. mod = Model() ext = ExternalSector(mod) ca = Country(mod, 'CA', 'Canada', currency='CAD') us = Country(mod, 'US', 'United States', currency='USD') gov_us = GoldStandardGovernment(us, 'GOV') # gov_ca = GoldStandardGovernment(ca, 'CA Gov', 'GOV', 200.) tre_ca = Treasury(ca, 'TRE', 'Ministry of Finance') cb_ca = GoldStandardCentralBank(ca, 'CB', treasury=tre_ca) mon = MoneyMarket(ca, issuer_short_code='CB') dep = DepositMarket(ca, issuer_short_code='TRE') gov_us.AddVariable('T', 'Government Taxes', '0.') tre_ca.AddVariable('T', 'Government Taxes', '0.') tre_ca.SetEquationRightHandSide('DEM_GOOD', '20.') market = Market(ca, 'GOOD', 'Market') supplier_ca = Sector(ca, 'BUS', 'Canada supplier') supplier_us = Sector(us, 'BUS', 'US Supplier') market.AddSupplier(supplier_ca) market.AddSupplier(supplier_us, '10.') mod.EquationSolver.MaxTime = 1 mod.EquationSolver.MaxIterations = 90 mod.EquationSolver.ParameterErrorTolerance = 1e-1 mod.main() mod.TimeSeriesSupressTimeZero = True # markets should be balanced self.assertAlmostEqual(0., mod.GetTimeSeries('EXT_FX__NET_CAD')[0], places=2) self.assertAlmostEqual(0., mod.GetTimeSeries('EXT_FX__NET_USD')[0], places=2) # U.S. buys 10 units of GOLD self.assertAlmostEqual(10., mod.GetTimeSeries('US_GOV__GOLDPURCHASES')[0], places=2) # Canada sells 10 units self.assertAlmostEqual(-10., mod.GetTimeSeries('CA_CB__GOLDPURCHASES')[0], places=2)
def main(): # The next line of code sets the name of the output files based on the code file's name. # This means that if you paste this code into a new file, get a new log name. sfc_models.register_standard_logs('output', __file__) # Create model, which holds all entities mod = Model() # Create first country - Canada. (This model only has one country.) can = Country(mod, 'CA', 'Canada') # Create sectors gov = ConsolidatedGovernment(can, 'GOV', 'Government') hh = Household(can, 'HH', 'Household') # A literally non-profit business sector bus = FixedMarginBusiness(can, 'BUS', 'Business Sector') # Create the linkages between sectors - tax flow, markets - labour ('LAB'), goods ('GOOD') tax = TaxFlow(can, 'TF', 'TaxFlow', .2) labour = Market(can, 'LAB', 'Labour market') goods = Market(can, 'GOOD', 'Goods market') # Add the financial markets # GOV -> issuing sector mm = MoneyMarket(can, issuer_short_code='GOV') dep = DepositMarket(can, issuer_short_code='GOV') # -------------------------------------------- # Financial asset demand equations # Need the full variable name for 'F' in household hh_F = hh.GetVariableName('F') hh.AddVariable('DEM_MON', 'Demand for Money', '0.5 * ' + hh_F) hh.AddVariable('DEM_DEP', 'Demand for deposits', '0.5 * ' + hh_F) # ----------------------------------------------------------------- # Need to set the exogenous variables # Government demand for Goods ("G" in economist symbology) mod.AddExogenous('GOV', 'DEM_GOOD', '[20.,] * 105') mod.AddExogenous('DEP', 'r', '[0.0,] * 5 + [0.04]*100') mod.AddInitialCondition('HH', 'F', 80.) mod.main() mod.TimeSeriesSupressTimeZero = True mod.TimeSeriesCutoff = 20 Quick2DPlot(mod.GetTimeSeries('t'), mod.GetTimeSeries('GOOD__SUP_GOOD'), 'Goods supplied (national production Y)') Quick2DPlot(mod.GetTimeSeries('t'), mod.GetTimeSeries('HH__F'), 'Household Financial Assets (F)')
def test_Market_fail_no_external(self): mod = Model() ca = Country(mod, 'CA', 'Canada', currency='CAD') us = Country(mod, 'US', 'United States', currency='USD') # gov_us.AddVariable('T', 'Government Taxes', '0.') gov_ca = Sector(ca, 'GOV', 'Gummint') gov_ca.AddVariable('DEM_GOOD', 'desc', '20.') market = Market(ca, 'GOOD', 'Market') supplier_ca = Sector(ca, 'BUS', 'Canada supplier') supplier_us = Sector(us, 'BUS', 'US Supplier') # Set supply so that CAD$10 is paid to each supplier. market.AddSupplier(supplier_ca) market.AddSupplier(supplier_us, '10.') # Set CAD = 2, so 2 USD = 1 CAD (USD is weaker.) with self.assertRaises(LogicError): mod._GenerateFullSectorCodes() market._GenerateEquations()
def test_GenerateEquations_insert_supply(self): mod = Model() can = Country(mod, 'Eh', 'Canada') mar = Market(can, 'LAB', 'Market') bus = Sector(can, 'BUS', 'Business') hh = Sector(can, 'HH', 'Household') hh2 = Sector(can, 'HH2', 'Household') bus.AddVariable('DEM_LAB', 'desc', 'x') hh.AddVariable('SUP_LAB_WRONG_CODE', 'desc 2', '') hh2.AddVariable('SUP_LAB_WRONG_CODE', 'desc 2', '') mod._GenerateFullSectorCodes() mar.AddSupplier(hh2) mar.AddSupplier(hh, 'SUP_LAB/2') # mar.SupplyAllocation = [[(hh, 'SUP_LAB/2')], hh2] mar._GenerateEquations() self.assertEqual('SUP_LAB/2', mar.EquationBlock['SUP_HH'].RHS()) self.assertEqual('SUP_LAB-SUP_HH', kill_spaces(mar.EquationBlock['SUP_HH2'].RHS())) self.assertEqual('LAB__SUP_HH', hh.EquationBlock['SUP_LAB'].RHS()) self.assertEqual('LAB__SUP_HH2', hh2.EquationBlock['SUP_LAB'].RHS())
def test_GenerateEquations_2_supply_multicountry_2(self): mod = Model() can = Country(mod, 'CA', 'Canada, Eh?') US = Country(mod, 'US', 'USA! USA!') mar = Market(can, 'LAB', 'Market') bus = Sector(can, 'BUS', 'Business') hh = Sector(can, 'HH', 'Household') hh2 = Sector(can, 'HH2', 'Household') bus.AddVariable('DEM_LAB', 'desc', 'x') hh.AddVariable('SUP_LAB', 'desc 2', '') hh2.AddVariable('SUP_LAB', 'desc 2', '') mod._GenerateFullSectorCodes() mar.AddSupplier(hh2) mar.AddSupplier(hh, 'SUP_LAB/2') #nmar.SupplyAllocation = [[(hh, 'SUP_LAB/2')], hh2] mar._GenerateEquations() self.assertEqual('SUP_LAB/2', mar.EquationBlock['SUP_CA_HH'].RHS()) self.assertEqual('SUP_LAB-SUP_CA_HH', mar.EquationBlock['SUP_CA_HH2'].RHS()) self.assertEqual('CA_LAB__SUP_CA_HH', hh.EquationBlock['SUP_LAB'].RHS()) self.assertIn('SUP_LAB', hh.EquationBlock['F'].RHS()) self.assertEqual('CA_LAB__SUP_CA_HH2', hh2.EquationBlock['SUP_LAB'].RHS()) self.assertIn('SUP_LAB', hh2.EquationBlock['F'].RHS())
def test_GenerateTermsLowLevel_3(self): mod = Model() can = Country(mod, 'Eh', 'Canada') mar = Market(can, 'LAB', 'Market') with self.assertRaises(LogicError): mar._GenerateTermsLowLevel('Blam!', 'desc')
def main(): # The next line of code sets the name of the output files based on the code file's name. # This means that if you paste this code into a new file, get a new log name. sfc_models.register_standard_logs('output', __file__) # Create model, which holds all entities mod = Model() # Create first country - Canada. can = Country(mod, 'CA', 'Canada') # Create sectors gov = ConsolidatedGovernment(can, 'GOV', 'Government') hh = Household(can, 'HH', 'Household') # A literally non-profit business sector bus = FixedMarginBusiness(can, 'BUS', 'Business Sector') # Create the linkages between sectors - tax flow, markets - labour ('LAB'), goods ('GOOD') tax = TaxFlow(can, 'TF', 'TaxFlow', .2) labour = Market(can, 'LAB', 'Labour market') goods = Market(can, 'GOOD', 'Goods market') # Create a second country, with non-zero profits # This is a very error-prone way of building the model; if we repeat code blocks, they should be in # a function. # Create United States - Almost identical to Canada. us = Country(mod, 'US', 'United States') # Create sectors gov2 = ConsolidatedGovernment(us, 'GOV', 'Government') hh2 = Household(us, 'HH', 'Household') # ********** Profit margin of 10% ***************** bus2 = FixedMarginBusiness(us, 'BUS', 'Business Sector', profit_margin=.1) # Create the linkages between sectors - tax flow, markets - labour ('LAB'), goods ('GOOD') tax2 = TaxFlow(us, 'TF', 'TaxFlow', .2) labor2 = Market(us, 'LAB', 'Labor market') goods2 = Market(us, 'GOOD', 'Goods market') # ***************************************************************** # Need to set the exogenous variable - Government demand for Goods ("G" in economist symbology) # Since we have a two country model, we need to specify the full sector code, which includes the country code. mod.AddExogenous('CA_GOV', 'DEM_GOOD', '[20.,] * 105') mod.AddExogenous('US_GOV', 'DEM_GOOD', '[20.,] * 105') # Do the main work of building and solving the model mod.main() CUT = 25 t = mod.GetTimeSeries('t', cutoff=CUT) Y_CA = mod.GetTimeSeries('CA_GOOD__SUP_GOOD', cutoff=CUT) Y_US = mod.GetTimeSeries('US_GOOD__SUP_GOOD', cutoff=CUT) p = Quick2DPlot([t, t], [Y_CA, Y_US], 'Output - Y', run_now=False) p.Legend = ['Canada (0% profit)', 'U.S. (10% Profit)'] p.DoPlot() F_CA = mod.GetTimeSeries('CA_BUS__F', cutoff=CUT) F_US = mod.GetTimeSeries('US_BUS__F', cutoff=CUT) p = Quick2DPlot([t, t], [F_CA, F_US], 'Business Sector Financial Assets (F)', run_now=False) p.Legend = ['Canada (0% profit)', 'U.S. (10% Profit)'] p.DoPlot() BAL_CA = mod.GetTimeSeries('CA_GOV__FISC_BAL', cutoff=CUT) BAL_US = mod.GetTimeSeries('US_GOV__FISC_BAL', cutoff=CUT) p = Quick2DPlot([t, t], [BAL_CA, BAL_US], 'Government Financial Balance', run_now=False) p.Legend = ['Canada (0% profit)', 'U.S. (10% Profit)'] p.DoPlot()