Macroeconomy
Model was written in NetLogo 6.1.1
•
Viewed 247 times
•
Downloaded 26 times
•
Run 0 times
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
Info tab cannot be displayed because of an encoding error
Comments and Questions
Click to Run Model
;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; MACROECONOMY ; ;Copyright © 2020 Ander Genua Trullos ; ;This work is licensed under the Creative Commons Attribution 4.0 International License. ; To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/ or ; send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. ; ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; globals [ ; World parameters world::ticksPerMonth ; Number of ticks in a month world::interactionRadius ; Maximum distance at which agents can interact in the goods and jobs markets world::governInteractionRadius ; Maximum distance at which people can get a job in the govern world::initialPeopleCount ; Initial number of people world::initialCompanyCount ; Initial number of companies world::initialBankCount ; Initial number of banks world::initialMoneyForPeople ; Initial amount of money assigned to the people world::initialMoneyForGovern ; Initial amount of money assigned to the government world::initialMoneyForLoans ; Initial amount of money that the central bank will use to loan world::salary ; Amount of money paid by the companies to their employees each tick world::salaryIncrease ; Amount that offered salaries will be increased each tick until the position has been filled world::unemploymentBenefit ; Amount of money paid by the govern to each unemployed person. world::stockPrice ; Amount of money that each stock costs world::technology ; Companies' efficiency to produce goods world::technologyImprovementPerGovernmentWorker ; Efficiency increase per tick and per government worker due to the positive externalities of government jobs world::minCapital ; Minimum amount of capital companies must have to run. world::capitalToWorkRatio ; Most efficent amount of capital for each worker world::bondsPerWorker ; Number of bonds a bank worker can handle world::baseConsumption ; Minimum amount of goods that the people will try to consume each tick world::peopleReservesTargetTicks ; Amount of ticks that the people's reserves are designed to last world::companyReservesTargetTicks ; Amount of ticks that the companies' reserves are designed to last world::governReservesTargetTicks ; Amount of ticks that the govern's reserves are designed to last world::bankReservesTargetTicks ; Amount of ticks that the bank's reserves are designed to last world::corporationTax ; Corporation tax rate world::incomeTax ; Income tax rate world::consumptionTax ; Consumption tax rate world::bondTerm ; Time elapsed from the adquisition of a bond and its maturity in ticks world::bondFaceValue ; Face value of each bond. All bond purchases and sales are done at this price. world::defaultCoupon ; Initial value for bond coupons (per tick) world::couponIncrease ; Amount that bond coupons will increase per tick when they cannot be sold world::loanTerm ; Time elapsed from the adquisition of a loan and its maturity in ticks world::loanFaceValue ; Face value of each loan. All loan purchases and sales are done at this price. world::centralBankPolicyMaturity ; Amount of ticks that are required for the amount of money to reach is target value world::monthlyInflationTarget ; Monthly inflation rate that the central bank tries to mantain world::centralBankPolicyFactor ; Indicates how much will vary the amount of money each time the central bank takes action world::floatMax ; A big number to calculate minimum values world::governId ; Turtle id of the govern world::centralBankId ; Turgle id of the central bank ; World styles: element colors and shapes style::personColor ; Color of the person breed turtles style::personShape ; Shape of the person breed turtles style::companyColor ; Color of the company breed turtles style::companyShape ; Shape of the company breed turtles style::governColor ; Color of the govern breed turtles style::governShape ; Shape of the govern breed turtles style::bankColor ; Color of the bank breed turtles style::bankShape ; Shape of the bank breed turtles style::centralbankColor ; Color of the central bank breed turtles style::centralbankShape ; Shape of the central bank breed turtles style::consumptionColor ; Color of the consumption relationship lines style::jobColor ; Color of the job relationship lines style::investmentColor ; Color of the investment relationship lines style::bondColor ; Color of the bond relationship lines style::loanColor ; Color of the loan relationship lines ; World variables world::goodsPriceAvg ; Average price paid for the goods in the last full month world::goodsPriceMinCurrent ; Minimum price paid for the goods in the current month world::goodsPriceMaxCurrent ; Maximum price paid for the goods in the current month world::bankCountValues ; List containing all the historic values for the variables. world::coeRealValues ; " world::coeNominalValues ; " world::companyCountValues ; " world::consumptionNominalValues ; " world::consumptionRealValues ; " world::gdpNominalValues ; " world::gdpRealValues ; " world::goodsPriceAvgValues ; " world::goodsPriceMinValues ; " world::goodsPriceMaxValues ; " world::goodsProducedValues ; " world::goodsSoldValues ; " world::gosNominalValues ; " world::gosRealValues ; " world::governConsumptionTaxIncomeNominalValues ; " world::governCorporationTaxIncomeNominalValues ; " world::governFinancialExpenseValues ; " world::governIncomeNominalValues ; " world::governIncomeTaxIncomeNominalValues ; " world::governSalariesNominalValues ; " world::governUnemploymentBenefitExpensesNominalValues ; " world::investmentNominalValues ; " world::investmentRealValues ; " world::m1Values ; " world::m1TargetValues ; " world::priceIndexValues ; " world::publicExpenditureNominalValues ; " world::salaryAvgValues ; " world::salaryMaxValues ; " world::salaryMinValues ; " world::technologyValues ; " world::unemploymentValues ; " world::bankCountBase ; Base value used to make the index used to plot the variable. world::companyCountBase ; " world::gdpBase ; " world::goodsPriceBase ; " world::goodsProducedBase ; " world::m1Base ; " world::priceIndexBase ; " world::salaryBase ; " world::technologyBase ; " ; Classify management people::currentClassifyBy ; Current classify attribute for people companies::currentClassifyBy ; Current classify attribute for companies banks::currentClassifyBy ; Current classify attribute for banks ; Plot Management plot1::bluePen::variableCurrent ; Variable currently being displayed with the blue pen in the plot 1. plot1::greenPen::variableCurrent ; Variable currently being displayed with the green pen in the plot 1. plot1::pinkPen::variableCurrent ; Variable currently being displayed with the pink pen in the plot 1. plot2::bluePen::variableCurrent ; Variable currently being displayed with the blue pen in the plot 2. plot2::greenPen::variableCurrent ; Variable currently being displayed with the green pen in the plot 2. plot2::pinkPen::variableCurrent ; Variable currently being displayed with the pink pen in the plot 2. plot3::bluePen::variableCurrent ; Variable currently being displayed with the blue pen in the plot 3. plot3::greenPen::variableCurrent ; Variable currently being displayed with the green pen in the plot 3. plot3::pinkPen::variableCurrent ; Variable currently being displayed with the pink pen in the plot 3. plot4::bluePen::variableCurrent ; Variable currently being displayed with the blue pen in the plot 4. plot4::greenPen::variableCurrent ; Variable currently being displayed with the green pen in the plot 4. plot4::pinkPen::variableCurrent ; Variable currently being displayed with the pink pen in the plot 4. peoplePlot::name ; Name of the plot used to show people classification companyPlot::name ; Name of the plot used to show company classification bankPlot::name ; Name of the plot used to show bank classification plot1::name ; Name of plot 1 plot2::name ; Name of plot 1 plot3::name ; Name of plot 1 plot4::name ; Name of plot 1 ; Selection management selection::selectedPatch ; Currently selected patch selection::selectedAgent ; Currently selected agent selection::currentPatch ; Patch where the mouse is over selection::interactionRadius ; Interaction radius of the current selected agent selection::currentShowConsumptions ; Indicates if currently the consumption relationships are shown for the selected agent. selection::currentShowJobs ; Indicates if currently the employment relationships are shown for the selected agent. selection::currentShowInvestments ; Indicates if currently the investment relationships are shown for the selected agent. selection::currentShowBonds ; Indicates if currently the money loan relationships between companies and banks are shown for the selected agent. selection::currentShowLoans ; Indicates if currently the money loan relationships between banks and the central bank are shown for the selected agent. selection::colors::selected ; Color for selected patches selection::colors::mouseOver ; Color for patches where the mouse is over selection::colors::selectedRadious ; Color for patches that can interact with the selected agent selection::colors::notSelected ; Default patch color ] breed [people person] people-own [ person::actionTick ; Tick of the month when the agent will make an strategic action. person::color ; Variable used to calculate the affinity between a person and a company. person::cash ; Amount of cash that the person has. person::targetCash ; Amount of money in reserves desired by the person. person::employed ; Indicates if the person is employed (1) or not (0). person::propensityToConsume ; Indicates how much of the income will be dedicated to consumption instead of savings person::stocks ; Number of stocks the person has. person::targetStocks ; Number of stocks the person wants to have. person::last::consumedGoods ; Amount of goods consumed in the previous full month. person::last::consumedGoodsValue ; Value of the goods consumed in the previous full month. person::last::workIncome ; Income received as salary in the previous full month. person::last::investmentIncome ; Income received as dividend in the previous full month. person::last::transferIncome ; Income received as government transfer in the previous full month. person::consumedGoods ; Amount of goods already consumed in the current month. person::consumedGoodsValue ; Value of the goods already consumed in the current month. person::workIncome ; Income received as salary in the current month. person::investmentIncome ; Income received as dividend in the current month. person::transferIncome ; Income received as government transfer in the current month. ] breed [companies company] companies-own [ company::actionTick ; Tick of the month when the agent will make an strategic action. company::age ; Age in months of the company. company::color ; Variable used to calculate the affinity between a person and a company. company::workers ; Number of workers on the company. company::vacancies ; Number of empty workplaces. company::salary ; Salary offered to the new workers company::lastSalary ; Salary paid to the last hired worker company::maxSalary ; Maximun salary that the company can afford company::stocks ; Number of stocks the company has sucessfully sold. company::stocksOnSale ; Number of stocks the company wants to sell. company::cash ; Amount of money that the company has company::targetCash ; The amount of cash the company wants to have company::nonCurrentAssets ; Amount of capital that he company uses to produce company::inventory ; Amount of goods in the company's warehouse. company::inventoryValue ; Value of the goods in the company's warehouse. company::inventoryUnitaryValue ; Value of each good in the company's warehouse. company::salePrice ; Price at which the company sells goods (including taxes). company::stockProfitability ; Expected profitability of the company's stocks company::bonds ; Number of bonds currently active company::targetBonds ; Number of bonds the company wants to have company::coupon ; Value of the coupon per tick offered for the bonds on sale company::lastCoupon ; Coupon paid in the last sold bond company::maxCoupon ; Maximun coupon value that the company can afford company::risk ; Risk value of the company company::targetDebtRatio ; Debt ratio that the company wants to have company::last::production ; Amount of goods produced by the company in the last full month. company::last::productionValue ; Value of the goods produced by the company in the last full month (value includes taxes). company::last::demand ; Amount of goods demanded to the company in the last full month. company::last::sales ; Amount of goods sold by the company in the last full month. company::last::salesValue ; Value of the goods sold by the company in the last full month. company::last::laborCosts ; Cost of labor in the last full month. company::last::operatingProfit ; Operating result in the last full month. company::last::financialExpense ; Cost of debt in the last full month company::last::profitBeforeTax ; Earnings before taxes in the last full month company::last::result ; Result of the company in the last full month company::last::nonCurrentAssets ; Value of the capital used to produce in the previous month company::last::inventory ; Amount of the stored goods in the previous month company::last::inventoryValue ; Cost value of the stored goods in the previous month company::last::investment ; Amount of money that has been invested in the previous month on non-current assets and inventory (with market value including taxes) company::production ; Amount of goods already produced by the company in the current month. company::productionValue ; Value of goods already produced by the company in the current month. company::demand ; Amount of goods already demanded to the company in the current month. company::sales ; Amount of goods already sold by the company in the current month. company::salesValue ; Value of the goods already sold by the company in the current month. company::laborCosts ; Cost of labor in the current month. company::financialExpense ; Cost of debt in the current month. ] breed [governs govern] governs-own [ govern::workers ; Number of workers on the govern. govern::vacancies ; Number of empty workplaces. govern::cash ; Amount of money that the govern has govern::targetCash ; The amount of cash the govern wants to have govern::salary ; Nominal amount of money that the govern pays its workers. govern::unemploymentBenefit ; Nominal amount of money that the govern pays unemployed people. govern::bonds ; Number of bonds the govern has. govern::bondsOnSale ; Number of bonds the govern wants to sale. govern::coupon ; Currently offered coupon for the bonds. govern::lastCoupon ; Coupon of the last sold bond. govern::loans ; Numer of rescue loans received from the central bank govern::risk ; Risk of the govern. It's always 1 (none) because the central bank guarantees the bond holder its money govern::incomeFromCorporationTax ; Income received from the corporation tax in the current month. govern::incomeFromIncomeTax ; Income received from the people income tax in the current month. govern::incomeFromConsumptionTax ; Income received from the consumption tax in the current month. govern::laborCosts ; Cost of labor in the current month. govern::transferCosts ; Cost of transfers to unemployed people in the current month. govern::financialExpense ; Cost of bonds in the current month. govern::last::incomeFromCorporationTax ; Income received from the corporation tax in the last full month govern::last::incomeFromIncomeTax ; Income received from the people income tax in the last full month. govern::last::incomeFromConsumptionTax ; Income received from the consumption tax in the last full month. govern::last::laborCosts ; Cost of labor in the last full month. govern::last::transferCosts ; Cost of transfers to unemployed people in the last full month. govern::last::financialExpense ; Cost of bonds in the last full month. ] breed [banks bank] banks-own [ bank::actionTick ; Tick of the month when the agent will make an strategic action. bank::age ; Age in months of the bank. bank::workers ; Number of workers on the bank. bank::vacancies ; Number of empty workplaces. bank::salary ; Salary offered to the new workers bank::lastSalary ; Salary paid to the last hired worker bank::maxSalary ; Maximun salary that the company can afford bank::stocks ; Number of stocks the bank has sucessfully sold. bank::stocksOnSale ; Number of stocks the bank wants to sell. bank::loans ; Amount of loans the bank has bank::targetLoans ; Amount of loans the bank wants to have bank::cash ; Amount of money that the bank has bank::targetCash ; Amount of cash the bank wants to have bank::bonds ; Amount of bonds the bank has bank::targetBonds ; Amount of bonds the bank wants to have bank::minBondCoupon ; Minimum coupon value for bonds bank::nonCurrentAssets ; Value of the current bonds bank::risk ; Risk level of the bonds the bank has bank::targetRisk ; Risk level that the bank wants to operate with bank::targetDebtRatio ; Debt ratio that the bank wants to have bank::stockProfitability ; Expected profitability of the bank's stocks bank::last::laborCosts ; Cost of labor in the last full month. bank::last::operatingProfit ; Operating result in the last full month. bank::last::financialIncome ; Coupons received in the last full month bank::last::financialExpense ; Unpaid bonds in the last full month bank::last::profitBeforeTax ; Earnings before taxes in the last full month bank::last::result ; Result of the bank in the last full month bank::laborCosts ; Cost of labor in the current month. bank::financialIncome ; Coupons received in the last full month bank::financialExpense ; Unpaid bonds in the last full month ] breed [centralbanks centralbank] centralbanks-own [ centralBank::loanOffer centralBank::M1 centralBank::targetM1 ] ; Relationship between a person and the companies from which it has consumed goods in the last full month undirected-link-breed [consumptions consumption] consumptions-own [ consumption::amount ; Amount of goods consumed consumption::value ; Value of the consumed goods ] ; Relationship between a person and the companies from which it has consumed goods in the last full month undirected-link-breed [currentConsumptions currentConsumption] currentConsumptions-own [ currentConsumption::amount ; Amount of goods consumed currentConsumption::value ; Value of the consumed goods ] ; Employment relationship between a person and the agent (company, government, bank) where it works (the end1 and end2 may vary) undirected-link-breed [jobs job] jobs-own [ job::salary ; Money paid by the employer to the employee ] ; Investor relationship between a company (end2) and its stockholders (end1) undirected-link-breed [investments investment] investments-own [ investment::stocks ] ; Bond relationships between companies and banks undirected-link-breed [bonds bond] bonds-own [ bond::bondCount ; Number of bonds of a company that a bank has bond::maturities ; Queue of maurity dates of all bonds in the relationship bond::coupons ; Queue of coupon values for all bonds in the relationship. ] ; Loan relationships between banks and the central bank undirected-link-breed [loans loan] loans-own [ loan::loanCount ; Number of loans the bank has loan::maturities ; Queue of maurity dates of all loans in the relationship ] ; Initialize the world to Setup clear-all random-seed 137 ; If uncommented the same execution can be repeated over and over ; Initialize world parameters set world::ticksPerMonth 30 ; Number of ticks in a month set world::interactionRadius 10 ; Maximum distance at which agents can interact in the goods and jobs markets set world::governInteractionRadius 25 ; Maximum distance at which people can get a job in the govern set world::initialPeopleCount 2150 ; Initial number of people set world::initialCompanyCount 100 ; Initial number of companies set world::initialBankCount 15 ; Initial number of banks set world::initialMoneyForPeople 16501250 ; Initial amount of money assigned to the people set world::initialMoneyForGovern 2750000 ; Initial amount of money assigned to the government set world::initialMoneyForLoans 4000000 ; Initial amount of money that the central bank will use to loan set world::salary 50 ; Amount of money paid by the companies to their employees each tick set world::salaryIncrease 0.5 ; Amount that offered salaries will be increased each tick until the position has been filled set world::unemploymentBenefit 35 ; Amount of money paid by the govern to each unemployed person. set world::stockPrice 500 ; Amount of money that each stock costs set world::technology 60 ; Companies' efficiency to produce goods set world::technologyImprovementPerGovernmentWorker 0.0000001 ; Efficiency increase per tick and per government worker due to the positive externalities of government jobs set world::minCapital 500 ; Minimum amount of capital companies must have to run. set world::CapitalToWorkRatio 5000 ; Most efficent amount of capital for each worker set world::bondsPerWorker 75 ; Number of bonds a bank worker can handle set world::baseConsumption 35 ; Minimum amount of goods that the people will try to consume each tick set world::peopleReservesTargetTicks 90 ; Amount of ticks that the people's reserves are designed to last set world::companyReservesTargetTicks 45 ; Amount of ticks that the companies' reserves are designed to last set world::governReservesTargetTicks 30 ; Amount of ticks that the govern's reserves are designed to last set world::bankReservesTargetTicks 45 ; Amount of ticks that the bank's reserves are designed to last set world::corporationTax 0.20 ; Corporation tax rate set world::incomeTax 0.10 ; Income tax rate set world::consumptionTax 0.12 ; Consumption tax rate set world::bondTerm 180 ; Time elapsed from the adquisition of a bond and its maturity in ticks set world::bondFaceValue 500 ; Face value of each bond. All bond purchases and sales are done at this price. set world::defaultCoupon 1.2 ; Initial value for bond coupons (per tick) set world::couponIncrease 0.02 ; Amount that bond coupons will increase per tick when they cannot be sold set world::loanTerm 180 ; Time elapsed from the adquisition of a loan and its maturity in ticks set world::loanFaceValue 500 ; Face value of each loan. All loan purchases and sales are done at this price. set world::centralBankPolicyMaturity 90 ; Amount of ticks that are required for the amount of money to reach is target value set world::monthlyInflationTarget 0.02 ; Monthly inflation rate that the central bank tries to mantain set world::centralBankPolicyFactor 0.05 ; Indicates how much will vary the amount of money each time the central bank takes action set world::floatMax 1E32 charts::Initialize selection::Initialize ; World styles: element colors and shapes set style::personColor sky set style::personShape "person" set style::companyColor sky set style::companyShape "plant" set style::governColor pink set style::governShape "govern" set style::bankColor sky set style::bankShape "bank" set style::centralbankColor pink set style::centralbankShape "central bank" set style::consumptionColor yellow set style::jobColor magenta set style::investmentColor orange set style::bondColor brown set style::loanColor violet ; Event initialization set event "" ; Create agents create-governs 1 [ set world::governId self govern::Create world::initialMoneyForGovern ] ; Create agents create-centralBanks 1 [ set world::centralBankId self centralBank::Create ( world::initialMoneyForPeople + world::initialMoneyForGovern ) ( world::initialMoneyForPeople + world::initialMoneyForGovern + world::initialMoneyForLoans ) ] let personCash world::Round2 ( world::initialMoneyForPeople / world::initialPeopleCount ) create-people world::initialPeopleCount [ person::Create personCash ] create-companies world::initialCompanyCount [ company::Create ] create-banks world::initialBankCount [ bank::Create ] reset-ticks ; Initial assignment of loans, bonds, investors and workers banks::Initialize ask people [ person::BuyStocks person::GetJob ] ask companies [ ; Update the corrent assests historical value to the current one set company::last::nonCurrentAssets company::nonCurrentAssets ] ask world::governId [ ; Update the govern target cash govern::CalculateTargetCash ] end ; Execute the simulation to Go let tickOfMonth ticks mod world::ticksPerMonth let month floor( ticks / world::ticksPerMonth) ; Event management Event::HandleEvents month ; Make operational actions ask people [ person::OperationalAction ] ask companies [ company::OperationalAction ] ask world::governId [ govern::OperationalAction ] ask banks [ bank::OperationalAction ] ask world::centralBankId [ centralBank::OperationalAction ] ; Make strategic actions (not in the first month, wait to see some results) if month > 0 [ ask people with [ person::actionTick = tickOfMonth ] [ person::StrategicAction ] ask companies with [ company::actionTick = tickOfMonth ] [ company::StrategicAction ] ask banks with [ bank::actionTick = tickOfMonth ] [ bank::StrategicAction ] if tickOfMonth = 29 [ ask world::governId [ govern::StrategicAction ] ask world::centralBankId [ centralBank::StrategicAction ] ] ] ; Redraw plots if the user has changed the selection plots::Redraw ; A month has gone by, update monthly stats if tickOfMonth = 29 [ ask people [ person::MonthlyAction ] ask companies [ company::MonthlyAction ] ask world::governId [ govern::MonthlyAction ] ask banks [ bank::MonthlyAction ] ask world::centralBankId [ centralBank::MonthlyAction ] world::UpdateVariables plots::Update ] ; Redraw histograms if the user has changed the selection people::Classify companies::Classify banks::Classify ; Check if the user has mouseclicked selection::MouseSelect true tick if ticks > 0 and ticks mod ( 50 * world::ticksPerMonth) = 0 ; Auto-stop the simulation every 50 months [ stop ] end ; Interact with the model without running the simulation to ShowInfo ; Redraw plots if the user has changed the selection plots::Redraw ; Redraw histograms if the user has changed the selection people::Classify companies::Classify banks::Classify ; Check if the user has mouseclicked selection::MouseSelect false ; Force the screen to be updated whithout a tick display end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; CONSUMPTION RELATIONSHIP MANAGEMENT ; ; Create a consumption relationship that represents the consumptions done in the last full month. to consumption::Create [ amount value ] set hidden? not( selection::currentShowConsumptions and ( end1 = selection::selectedAgent or end2 = selection::selectedAgent ) ) set color style::consumptionColor set consumption::amount amount set consumption::value value end ; Create a current consumption relationship that represents the consumptions being done in the current month. to currentConsumption::Create set hidden? true set color style::consumptionColor set currentConsumption::amount 0 set currentConsumption::value 0 end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; JOB RELATIONSHIP MANAGEMENT ; ; Create a job relationship to job::Create [ salary ] set hidden? not ( selection::currentShowJobs and ( end1 = selection::selectedAgent or end2 = selection::selectedAgent ) ) set color style::jobColor set job::salary salary end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; INVESTMENT RELATIONSHIP MANAGEMENT ; ; Create an investment relationship to investment::Create set hidden? not ( selection::currentShowInvestments and ( end1 = selection::selectedAgent or end2 = selection::selectedAgent ) ) set color style::investmentColor set investment::stocks 0 end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; BOND RELATIONSHIP MANAGEMENT ; to bond::Create set hidden? not ( selection::currentShowBonds and ( end1 = selection::selectedAgent or end2 = selection::selectedAgent ) ) set color style::bondColor set bond::bondCount 0 set bond::maturities [] set bond::coupons [] end to bond::AddBond[ coupon ] set bond::bondCount bond::bondCount + 1 set bond::maturities lput (ticks + world::bondTerm) bond::maturities set bond::coupons lput coupon bond::coupons end to bond::AddInitialBond[ nBonds coupon ] set bond::bondCount bond::bondCount + nBonds while [nBonds > 0] [ let maturity 30 + random world::bondTerm set bond::maturities lput maturity bond::maturities set bond::coupons lput coupon bond::coupons set nBonds nBonds - 1 ] end to bond::RemoveBond set bond::bondCount bond::bondCount - 1 set bond::maturities but-first bond::maturities set bond::coupons but-first bond::coupons end to-report bond::GetDebtCost [ reservesTargetTicks ] let term ticks + reservesTargetTicks let totalCoupon 0 let totalPrincipal 0 (foreach bond::maturities bond::coupons [ [mat coup] -> if-else mat < term [ set totalPrincipal totalPrincipal + world::bondFaceValue set totalCoupon totalCoupon + coup * (term - mat ) ] [ set totalCoupon totalCoupon + coup * world::companyReservesTargetTicks ] ]) report totalCoupon + totalPrincipal end to-report bond::GetFinancialCost [ reservesTargetTicks ] let term ticks + reservesTargetTicks let totalCoupon 0 (foreach bond::maturities bond::coupons [ [mat coup] -> if-else mat < term [ set totalCoupon totalCoupon + coup * (term - mat ) ] [ set totalCoupon totalCoupon + coup * reservesTargetTicks ] ] ) report totalCoupon end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; LOAN RELATIONSHIP MANAGEMENT ; to loan::Create set hidden? not ( selection::currentShowLoans and ( end1 = selection::selectedAgent or end2 = selection::selectedAgent ) ) set color style::loanColor set loan::loanCount 0 set loan::maturities [] end to loan::AddLoan [ nLoans ] set loan::loanCount loan::loanCount + nLoans while [nLoans > 0] [ set loan::maturities lput (ticks + world::loanTerm) loan::maturities set nLoans nLoans - 1 ] end to loan::AddInitialLoan [ nLoans ] set loan::loanCount loan::loanCount + nLoans while [nLoans > 0] [ let maturity 30 + random world::loanTerm set loan::maturities lput maturity loan::maturities set nLoans nLoans - 1 ] end to loan::RemoveLoan set loan::loanCount loan::loanCount - 1 set loan::maturities but-first loan::maturities end to-report loan::GetDebtCost [ reservesTargetTicks ] let term ticks + reservesTargetTicks let totalPrincipal 0 (foreach loan::maturities [ [mat] -> if mat < term [ set totalPrincipal totalPrincipal + world::loanFaceValue] ]) report totalPrincipal end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; WORLD MANAGEMENT ; ; Updates the macroeconomic variables to world::UpdateVariables let isFirstUpdate floor ( ticks / world::ticksPerMonth ) = 0 ; Calculate first the price index which is needed for other variables too ; Price Index let priceIndex sum [ company::salePrice * company::last::production ] of companies / sum [company::last::production] of companies if isFirstUpdate [ set world::PriceIndexBase priceIndex ] let nominalToRealPrices world::PriceIndexBase / priceIndex ;;; Calculate the values of the rest of the macroeconomic variables ; Company Count let bankCount count banks ; Compensation of employees Nominal let coeNominal sum [person::last::workIncome] of people ; Compensation of employees Real let coeReal coeNominal * nominalToRealPrices ; Company Count let companyCount count companies ; Consumption Nominal let consumptionNominal sum [person::last::consumedGoodsValue] of people ; Consumption Real let consumptionReal consumptionNominal * nominalToRealPrices ; GDP Nominal let gdpNominal sum [ company::last::production * company::salePrice ] of companies ; GDP Real let gdpReal gdpNominal * nominalToRealPrices ; Govern Consumption Tax Income let governConsumptionTaxIncomeNominal [ govern::last::incomeFromConsumptionTax ] of world::governId ; Govern Corporation Tax Income let governCorporationTaxIncomeNominal [ govern::last::incomeFromCorporationTax ] of world::governId ; Govern Financial Expense let governFinancialExpenseNominal [ govern::last::financialExpense ] of world::governId ; Govern Income let governIncomeNominal [ govern::last::IncomeFromConsumptionTax + govern::last::IncomeFromIncomeTax + govern::last::IncomeFromCorporationTax ] of world::governId ; Govern Income Tax Income let governIncomeTaxIncomeNominal [ govern::last::IncomeFromIncomeTax ] of world::governId ; Govern Salaries let governSalariesNominal [ govern::last::laborCosts ] of world::governId ; Govern Unemployment Benefit Expenses let governUnemploymentBenefitExpensesNominal [ govern::last::transferCosts ] of world::governId ; Goods average consumption price set world::goodsPriceAvg sum [person::last::consumedGoodsValue] of people / sum [person::last::consumedGoods] of people ; Goods Minimum price let goodsPriceMin world::goodsPriceMinCurrent set world::goodsPriceMinCurrent world::floatMax ; Goods Maximum price let goodsPriceMax world::goodsPriceMaxCurrent set world::goodsPriceMaxCurrent 0 ; Goods Produced let goodsProduced sum [ company::last::production ] of companies ; Goods Sold let goodsSold sum [ company::last::sales ] of companies ; Gross Operating surplus Nominal let gosNominal sum [person::last::investmentIncome] of people ; Gross Operating surplus Real let gosReal gosNominal * nominalToRealPrices ; Investment Nominal let investmentNominal sum [ company::last::investment ] of companies ; Investment Real let investmentReal investmentNominal * nominalToRealPrices ; M1 let m1 [ centralBank::M1 ] of world::centralBankId ; Public Expenditure let publicExpenditureNominal [ govern::last::laborCosts + govern::last::transferCosts + govern::last::financialExpense ] of world::governId ; Salary Average let salaryAvg sum [ job::salary ] of jobs / count jobs ; Salary Maximum let salaryMax max [ job::salary ] of jobs ; Salary Minimum let salaryMin min[ job::salary ] of jobs ; Unemployment let unemployment count people with [ person::employed = 0 ] / count people ;;; Set base values if isFirstUpdate [ set world::bankCountBase bankCount set world::companyCountBase companyCount set world::gdpBase gdpNominal set world::goodsPriceBase world::goodsPriceAvg set world::goodsProducedBase goodsProduced set world::m1Base m1 set world::salaryBase salaryAvg set world::technologyBase world::technology ] ;;; Normalize values and add them to the list ; Bank Count let bankCountValue bankCount * 100 / world::bankCountBase set world::bankCountValues lput bankCountValue world::bankCountValues ; Compensation of employees Nominal let normalizedCOENominal coeNominal * 100 / world::gdpBase set world::coeNominalValues lput normalizedCOENominal world::coeNominalValues ; Compensation of employees Real let normalizedCOEReal coeReal * 100 / world::gdpBase set world::coeRealValues lput normalizedCOEReal world::coeRealValues ; Consumption Nominal let normalizedConsumptionNominal consumptionNominal * 100 / world::gdpBase set world::consumptionNominalValues lput normalizedConsumptionNominal world::consumptionNominalValues ; Consumption Real let normalizedConsumptionReal consumptionReal * 100 / world::gdpBase set world::consumptionRealValues lput normalizedConsumptionReal world::consumptionRealValues ; Company Count ; GDP Nominal let normalizedGDPNominal gdpNominal * 100 / world::gdpBase let companyCountValue companyCount * 100 / world::CompanyCountBase set world::companyCountValues lput companyCountValue world::companyCountValues set world::gdpNominalValues lput normalizedGDPNominal world::gdpNominalValues ; GDP Real let normalizedGdpReal gdpReal * 100 / world::gdpBase set world::gdpRealValues lput normalizedGdpReal world::gdpRealValues ; Goods Average price let normalizedGoodsPriceAvg world::goodsPriceAvg * 100 / world::goodsPriceBase set world::goodsPriceAvgValues lput normalizedGoodsPriceAvg world::goodsPriceAvgValues ; Goods Minimum price let normalizedGoodsPriceMin goodsPriceMin * 100 / world::goodsPriceBase set world::goodsPriceMinValues lput normalizedGoodsPriceMin world::goodsPriceMinValues ; Goods Maximum price let normalizedGoodsPriceMax goodsPriceMax * 100 / world::goodsPriceBase set world::goodsPriceMaxValues lput normalizedGoodsPriceMax world::goodsPriceMaxValues ; Goods Produced let normalizedGoodsProducedValues goodsProduced * 100 / world::goodsProducedBase set world::goodsProducedValues lput normalizedGoodsProducedValues world::goodsProducedValues ; Goods Sold let normalizedGoodsSoldValues goodsSold * 100 / world::goodsProducedBase set world::goodsSoldValues lput normalizedGoodsSoldValues world::goodsSoldValues ; Govern Consumption Tax Income let normalizedGovernConsumptionTaxIncomeNominal governConsumptionTaxIncomeNominal * 100 / world::gdpBase set world::governConsumptionTaxIncomeNominalValues lput normalizedGovernConsumptionTaxIncomeNominal world::governConsumptionTaxIncomeNominalValues ; Govern Corporation Tax Income let normalizedGovernCorporationTaxIncomeNominal governCorporationTaxIncomeNominal * 100 / world::gdpBase set world::governCorporationTaxIncomeNominalValues lput normalizedGovernCorporationTaxIncomeNominal world::governCorporationTaxIncomeNominalValues ; Govern Financial Expense let normalizedFinancialExpenseNominal governFinancialExpenseNominal * 100 / world::gdpBase set world::governFinancialExpenseValues lput normalizedFinancialExpenseNominal world::governFinancialExpenseValues ; Govern Income let normalizedGovernIncomeNominal governIncomeNominal * 100 / world::gdpBase set world::governIncomeNominalValues lput normalizedGovernIncomeNominal world::governIncomeNominalValues ; Govern Income Tax Income let normalizedGovernIncomeTaxIncomeNominal governIncomeTaxIncomeNominal * 100 / world::gdpBase set world::governIncomeTaxIncomeNominalValues lput normalizedGovernIncomeTaxIncomeNominal world::governIncomeTaxIncomeNominalValues ; Govern Salaries let normalizedGovernSalariesNominal governSalariesNominal * 100 / world::gdpBase set world::governSalariesNominalValues lput normalizedGovernSalariesNominal world::governSalariesNominalValues ; Govern Unemployment Benefit Expenses let normalizedGovernUnemploymentBenefitExpensesNominal governUnemploymentBenefitExpensesNominal * 100 / world::gdpBase set world::governUnemploymentBenefitExpensesNominalValues lput normalizedGovernUnemploymentBenefitExpensesNominal world::governUnemploymentBenefitExpensesNominalValues ; Gross Operating surplus Nominal let normalizedGOSNominal gosNominal * 100 / world::gdpBase set world::gosNominalValues lput normalizedGOSNominal world::gosNominalValues ; Gross Operating surplus Real let normalizedGOSReal gosReal * 100 / world::gdpBase set world::gosRealValues lput normalizedGOSReal world::gosRealValues ; Investment Nominal let normalizedInvestmentNominal investmentNominal * 100 / world::gdpBase set world::investmentNominalValues lput normalizedInvestmentNominal world::investmentNominalValues ; Investment Real let normalizedInvestmentReal investmentReal * 100 / world::gdpBase set world::investmentRealValues lput normalizedInvestmentReal world::investmentRealValues ; M1 let normalizedM1 m1 * 100 / world::m1Base set world::m1Values lput normalizedM1 world::m1Values ; M1 Target let normalizedTargetM1 ([ centralBank::targetM1 ] of world::centralBankId ) * 100 / world::m1Base set world::m1TargetValues lput normalizedTargetM1 world::m1Values ; Price Index let normalizedPriceIndex priceIndex * 100 / world::PriceIndexBase set world::priceIndexValues lput normalizedPriceIndex world::priceIndexValues ; Public Expenditure let normalizedPublicExpenditureNominal publicExpenditureNominal * 100 / world::gdpBase set world::publicExpenditureNominalValues lput normalizedPublicExpenditureNominal world::publicExpenditureNominalValues ; Salary Average let normalizedSalaryAvg salaryAvg * 100 / world::salaryBase set world::salaryAvgValues lput normalizedSalaryAvg world::salaryAvgValues ; Salary Maximum let normalizedSalaryMax salaryMax * 100 / world::salaryBase set world::salaryMaxValues lput normalizedSalaryMax world::salaryMaxValues ; Salary Minimum let normalizedSalaryMin salaryMin * 100 / world::salaryBase set world::salaryMinValues lput normalizedsalaryMin world::salaryMinValues ; Technology let normalizedTechnology world::technology * 100 / world::technologyBase set world::technologyValues lput normalizedTechnology world::technologyValues ; Unemployment let normalizedUnemployment unemployment * 100 set world::unemploymentValues lput normalizedUnemployment world::unemploymentValues end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; EVENT MANAGEMENT ; to event::HandleEvents [ month ] if event != " " [ if event = "Technology improvement" [ ; Improve technology by 5% set world::technology world::technology * 1.05 ] if event = "Technology deterioration" [ ; Deteriorate technology by 5% set world::technology world::technology * 0.95 ] if event = "Govern salary increase" [ ; Increase govern salaries 5% set world::salary world::Round2( world::salary * 1.05 ) ] if event = "Govern salary decrease" [ ; Decrease govern salaries 5% set world::salary world::Round2( world::salary * 0.95 ) ] if event = "Unemployment benefit increase" [ ; Increase the unemployment benefit 5% set world::salary world::Round2( world::unemploymentBenefit * 1.05 ) ] if event = "Unemployment benefit decrease" [ ; Decrease the unemployment benefit 5% set world::salary world::Round2( world::unemploymentBenefit * 0.95 ) ] if event = "Consumption tax increase" [ ; Increase the consumption tax 2 points set world::consumptionTax world::consumptionTax + 0.02 ] if event = "Consumption tax decrease" [ ; Decrease the consumption tax 2 points set world::consumptionTax world::consumptionTax - 0.02 ] if event = "Income tax increase" [ ; Increase the consumption tax 2 points set world::incomeTax world::incomeTax + 0.02 ] if event = "Income tax decrease" [ ; Decrease the consumption tax 2 points set world::incomeTax world::incomeTax - 0.02 ] if event = "Corporation tax increase" [ ; Increase the consumption tax 2 points set world::corporationTax world::corporationTax + 0.02 ] if event = "Corporation tax decrease" [ ; Decrease the consumption tax 2 points set world::corporationTax world::corporationTax - 0.02 ] if event = "Bank risk target increase" [ ; Increase bank's target risk 10% ask banks [ set bank::targetRisk world::Round2( bank::targetRisk * 1.1 ) ] ] if event = "Bank risk target decrease" [ ; Decrease bank's target risk 10% ask banks [ set bank::targetRisk world::Round2( bank::targetRisk * 0.9 ) ] ] plots::DrawEvent month set event " " ] end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; UTILITY FUNCTIONS ; ; Rounds to the nearest number with two decimal values to-report world::Round2 [ value ] report precision value 2 end ; Rounds to the next number with two decimal values to-report world::Round2up [ value ] report precision (value + 0.005) 2 end ; Rounds to the next number with two decimal values to-report world::Round2down [ value ] report precision (value - 0.005) 2 end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; PERSON MANAGEMENT ; ; Assign the default properties to a newly created person to person::Create [ cash ] set shape style::personShape set color style::personColor move-to one-of patches with [ count turtles-here = 0 ] set person::actionTick random world::ticksPerMonth set person::color random-float 1 set person::cash cash ; person::targetCash Assigned later set person::employed 0 set person::propensityToConsume 0.6 + random-float 0.2 set person::last::consumedGoods 0 set person::last::consumedGoodsValue 0 set person::consumedGoods 0 set person::consumedGoodsValue 0 set person::stocks 0 set person::targetStocks 15 + random 8 person::CalculateTargetCash end ; Calculates the amount of reserves desired by the person to person::CalculateTargetCash set person::targetCash world::baseConsumption * world::goodsPriceAvg * world::peopleReservesTargetTicks end ; Operational action of the person to person::OperationalAction ; Buy goods person::BuyGoods ; Invest if person::stocks > person::targetStocks [ ; Sell stocks person::SellStocks ] if person::stocks < person::targetStocks [ person::BuyStocks ] ; Get a job if person::employed = 0 [ person::GetJob ] end ; Strategic action of the person to person::StrategicAction ; Sell the less profitable stocks on the portfolio (10% chance) if there are more profitable options on the market if random-float 1 < 0.1 and person::stocks > 0 [ let companiesWithStocksOnSale companies with [ company::stocksOnSale > 0 ] if any? companiesWithStocksOnSale [ let maxMarketProfit max [ company::stockProfitability ] of companiesWithStocksOnSale let lessProfitableInvestment one-of my-investments with-min [ [ifelse-value (is-company? self ) [company::stockProfitability][bank::stockProfitability]] of end2 ] if maxMarketProfit > [ifelse-value (is-company? self ) [company::stockProfitability][bank::stockProfitability]] of ([end2] of lessProfitableInvestment) [ ; Sell max 20% of my stocks or the full investment let stocksToSell ceiling( person::stocks * 0.2) if stocksToSell > [investment::stocks] of lessProfitableInvestment [ set stocksToSell [investment::stocks] of lessProfitableInvestment ] person::SellStocksFromCompany lessProfitableInvestment stocksToSell ] ] ] ; Calculate the caution reserves an the number of stocks wanted person::CalculateTargetCash ;; Buy stocks if the person has excess cash and is not already trying to buy stocks unsuccessfully if person::cash > person::targetCash + world::stockPrice and person::targetStocks <= person::stocks [ let stocksToBuy floor( ( person::cash - person::targetCash ) / world::stockPrice) set stocksToBuy ( random stocksToBuy ) + 1 set person::targetStocks person::stocks + stocksToBuy ] ;; Sell stocks (or at least don't buy new stocks) if the reserves are not enough if person::cash < person::targetCash [ let stocksToSell ceiling( ( person::targetCash - person::cash ) / world::stockPrice ) if stocksToSell > person::stocks [ set stocksToSell person::stocks] set person::targetStocks person::stocks - stocksToSell ] ; Move to another patch (20% chance) or create a company (10 % chance) if the person doesn't have a job or if the previous month hasn't been able to consume if ( ( person::employed = 0 ) or ( ticks > 30 and person::last::consumedGoods = 0 ) ) [ let probability random-float 1 ifelse person::targetStocks > person::Stocks and probability < 0.10 [ ; If the person is employed leave the previous job if person::employed = 1 [ person::LeaveJob ] ; Create a company or bank let companyId nobody if-else random-float 1 < world::initialCompanyCount / (world::initialCompanyCount + world::initialBankCount) [ ; Create company hatch-companies 1 [ company::Create set companyId self ] ] [ ;Create bank hatch-banks 1 [ bank::Create set companyId self ] ] ; Become an investor of the new company let stocksBought person::BuyStocksFromCompany companyId (person::targetStocks - person::Stocks) ] [ if probability < 0.20 [ move-to one-of patches with [ count turtles-here = 0 ] ] ] ] ; If the neighbours earn more than me, quit the job to find something better if ( person::employed = 1 and count people-on neighbors > 0 ) [ let avgNeigborSalary sum [person::last::workIncome] of people-on neighbors / count people-on neighbors let mySalary sum[ job::salary ] of my-jobs let probability ( avgNeigborSalary - mySalary ) / mySalary if ( probability > random-float 1 ) [ person::LeaveJob ] ] end ; Executes the action of buying goods to person::BuyGoods ; Calculate the amount of goods to buy let excessCash person::cash - person::targetCash - world::stockPrice * (person::targetStocks - person::stocks + 1) if excessCash < 0 [ set excessCash 0 ] let income ( person::last::workIncome + person::last::investmentIncome + person::last::transferIncome ) / world::ticksPerMonth let personDemandUnits 0 ifelse floor ( ticks / world::ticksPerMonth ) = 0 [ ; In the first month do not take into account the previous month consumption set personDemandUnits floor ( ( person::propensityToConsume * income + 0.1 * excessCash ) / world::goodsPriceAvg ) ] [ set personDemandUnits floor ( 0.5 * ( person::propensityToConsume * income + 0.1 * excessCash ) / world::goodsPriceAvg + 0.5 * person::last::consumedGoods / world::ticksPerMonth ) ] if personDemandUnits < world::baseConsumption [ set personDemandUnits world::baseConsumption] ; Get the company list from cheapest to most expensive based on their apparent price let myColor person::Color let companyList sort-on [company::salePrice + 0.2 * company::salePrice * abs( myColor - company::color) ] companies with [ distance myself < world::interactionRadius ] let fullfilled false ; Try to buy all the goods we want let n 0 while [ not empty? companyList and not fullfilled ] [ let companyId first companyList let goodsToBuy 0 set n n + 1 ; Calculate the amount of goods the person wants to buy from this company ifelse personDemandUnits > [company::inventory] of companyId [ set goodsToBuy [company::inventory] of companyId ] [ set goodsToBuy personDemandUnits set fullfilled true ] ; Can we pay them? let grossPurchaseValue goodsToBuy * [company::salePrice] of companyId if grossPurchaseValue > person::cash [ set goodsToBuy floor( person::cash / [company::salePrice] of companyId ) set grossPurchaseValue goodsToBuy * [company::salePrice] of companyId set fullfilled true ] ; Calculate how much would the user demand if they wasn't restricted by companies inventory let goodsToDemand personDemandUnits let demandValue goodsToDemand * [company::salePrice] of companyId if demandValue > person::cash [ set goodsToDemand floor( person::cash / [company::salePrice] of companyId ) ] ask companyId [ set company::demand company::demand + round( goodsToDemand / n ) ; Divide between n not to over-generate demand ] ; Buy the goods if goodsToBuy > 0 [ let tax world::Round2( grossPurchaseValue * world::consumptionTax ) let netPurchaseValue grossPurchaseValue - tax ask companyId [ set company::cash company::cash + netPurchaseValue set company::inventory company::inventory - goodsToBuy set company::inventoryValue company::inventory * company::inventoryUnitaryValue set company::sales company::sales + goodsToBuy set company::salesValue company::salesValue + netPurchaseValue ] set person::cash person::cash - grossPurchaseValue set person::consumedGoods person::consumedGoods + goodsToBuy set person::consumedGoodsValue person::consumedGoodsValue + grossPurchaseValue ask world::governId [ set govern::cash govern::cash + tax set govern::incomeFromConsumptionTax govern::incomeFromConsumptionTax + tax ] create-currentConsumption-with companyId [ currentConsumption::Create ] ask currentConsumption-with companyId [ set currentConsumption::amount currentConsumption::amount + goodsToBuy set currentConsumption::value currentConsumption::value + grossPurchaseValue ] if [company::salePrice] of companyId < world::goodsPriceMinCurrent [ set world::goodsPriceMinCurrent [company::salePrice] of companyId] if [company::salePrice] of companyId > world::goodsPriceMaxCurrent [ set world::goodsPriceMaxCurrent [company::salePrice] of companyId] ] set personDemandUnits personDemandUnits - goodsToBuy set companyList butFirst companyList ] end ; Executes the action of selling stocks to person::SellStocks let stocksToSell person::stocks - person::targetStocks while[ stocksToSell > 0 ] [ let investmentId min-one-of my-investments [ (ifelse-value (is-company? end2) [[company::stockProfitability] of end2] [[bank::stockProfitability] of end2]) ] person::SellStocksFromCompany investmentId stocksToSell set stocksToSell person::stocks - person::targetStocks ] end ; Given an investment relationship tries to sell the specified number of stocks from that investment to person::SellStocksFromCompany[ investmentId stocksToSell ] ; Number of stocks to sell if [investment::stocks] of investmentId < stocksToSell [ set stocksToSell [investment::stocks] of investmentId ] let agentId [end2] of investmentId ( ifelse ( is-company? agentId and stocksToSell = [ company::stocks ] of agentId ) [ ; No stockholders for this company ask agentId [ company::closeBussiness false ] ] (is-bank? agentId and stocksToSell = [ bank::stocks ] of agentId) [ ; No stockholders for this company ask agentId [ bank::closeBussiness false ] ] [ ; Update investment relationship ifelse [investment::stocks] of investmentId > stocksToSell [ ask investmentId [ set investment::stocks investment::stocks - stocksToSell ] ] [ ask investmentId [die] ] ; Price of the stocks to sell let stockPrice 0 ifelse (is-company? agentId) [ set stockPrice [world::Round2Down( (company::nonCurrentAssets + company::cash - company::bonds * world::bondFaceValue) / company::stocks )] of agentId ] [; its a bank set stockPrice [world::Round2Down( (bank::nonCurrentAssets + bank::cash - bank::loans * world::loanFaceValue) / bank::stocks )] of agentId ] if ( stockPrice > world::stockPrice ) [ set stockPrice world::stockPrice ] let stocksPrice world::Round2Down( stocksToSell * stockPrice ) ; Get the money from the agent let paid true ask agentId [ ifelse (is-company? agentId) [ set company::stocks company::stocks - stocksToSell if not company::PayCapital stocksPrice [ set paid false company::closeBussiness false ] ] [ set bank::stocks bank::stocks - stocksToSell if not bank::PayCapital stocksPrice [ set paid false bank::closeBussiness false ] ] ] ; Receive the money set person::stocks person::stocks - stocksToSell if paid [ set person::cash person::cash + stocksPrice ] ] ) end ; Executes the action of buying stocks from the market to person::BuyStocks let stocksToBuy person::targetStocks - person::stocks let investmentCash person::cash - person::targetCash if stocksToBuy * world::stockPrice > investmentCash [ set stocksToBuy floor( investmentCash / world::stockPrice ) ] if stocksToBuy > 0 [ let companyList sort-on [ ifelse-value( is-company? self ) [( - company::stockProfitability )][ ( - bank::stockProfitability )] ] turtles with [ (is-company? self and company::stocksOnSale > 0 ) or (is-bank? self and bank::stocksOnSale > 0 ) ] while [stocksToBuy > 0 and not empty? companyList ] [ let stocksToBuyFromCompany person::BuyStocksFromCompany first companyList stocksToBuy ; Continue with the buying process set stocksToBuy stocksToBuy - stocksToBuyFromCompany set companyList butFirst companyList ] ] end ; Executes the action of buying stocks from a company, returns the number of stocks bought to-report person::BuyStocksFromCompany[ agentId stocksToBuy ] let personId self let affordableStocks floor( (person::cash - person::targetCash ) / world::stockPrice ) if affordableStocks < 0 [ set affordableStocks 0] if affordableStocks < stocksToBuy [ set stocksToBuy affordableStocks] let offeredStocks ifelse-value (is-company? agentId) [[company::stocksOnSale] of agentId][[bank::stocksOnSale] of agentId] let stocksToBuyFromCompany stocksToBuy if offeredStocks < stocksToBuyFromCompany [ set stocksToBuyFromCompany offeredStocks ] if stocksToBuyFromCompany > 0 [ let stocksPrice stocksToBuyFromCompany * world::stockPrice ; Create or update the investment relationship create-investment-with agentId [ investment::Create ] ask investment-with agentId [ set investment::Stocks investment::Stocks + stocksToBuyFromCompany ] ; update the person set person::stocks person::stocks + stocksToBuyFromCompany set person::cash person::cash - stocksPrice ; update the company ask agentId [ ifelse (is-company? agentId) [ set company::stocks company::stocks + stocksToBuyFromCompany set company::stocksOnSale company::stocksOnSale - stocksToBuyFromCompany set company::cash company::cash + stocksPrice company::DistributeAssets ] [ set bank::stocks bank::stocks + stocksToBuyFromCompany set bank::stocksOnSale bank::stocksOnSale - stocksToBuyFromCompany set bank::cash bank::cash + stocksPrice ] ] ] report stocksToBuyFromCompany end ; Executes the action of getting a job for an unemployed person to person::GetJob let turtleId max-one-of turtles with [ (is-company? self and distance myself < world::interactionRadius and company::vacancies > 0 and company::nonCurrentAssets > 0 ) or (is-govern? self and distance myself < world::governInteractionRadius and govern::vacancies > 0 ) or (is-bank? self and distance myself < world::interactionRadius and bank::vacancies > 0 and bank::nonCurrentAssets > 0 ) ] [ ( ifelse-value (is-company? self) [ company::salary ] (is-govern? self ) [ govern::salary ] [ bank::salary ] ) ] if turtleId != nobody [ let salary 0 if is-company? turtleId [ ask turtleId [ set company::workers company::workers + 1 set company::vacancies company::vacancies - 1 set company::lastSalary company::salary set salary company::salary ] ] if is-govern? turtleId [ ask turtleId [ set govern::workers govern::workers + 1 set govern::vacancies govern::vacancies - 1 set salary govern::salary ] ] if is-bank? turtleId [ ask turtleId [ set bank::workers bank::workers + 1 set bank::vacancies bank::vacancies - 1 set bank::lastSalary bank::salary set salary bank::salary ] ] set person::employed 1 create-job-with turtleId [ job::Create salary ] ] end ; Executes the action of leaving a job for an employed person to person::LeaveJob ask my-jobs [ ask end1 ; Govern / Person [ if is-person? self [ set person::employed 0 ] if is-company? self [ set company::workers company::workers - 1 set company::vacancies company::vacancies + 1 ] if is-govern? self [ set govern::workers govern::workers - 1 set govern::vacancies govern::vacancies + 1 ] if is-bank? self [ set bank::workers bank::workers - 1 set bank::vacancies bank::vacancies + 1 ] ] ask end2 ; Person / Company / Bank [ if is-person? self [ set person::employed 0 ] if is-company? self [ set company::workers company::workers - 1 set company::vacancies company::vacancies + 1 ] if is-govern? self [ set govern::workers govern::workers - 1 set govern::vacancies govern::vacancies + 1 ] if is-bank? self [ set bank::workers bank::workers - 1 set bank::vacancies bank::vacancies + 1 ] ] die ] end ; Updates the monthly statistical variables of the person to person::MonthlyAction set person::last::consumedGoods person::consumedGoods set person::last::consumedGoodsValue person::consumedGoodsValue set person::last::workIncome person::workIncome set person::last::investmentIncome person::investmentIncome set person::last::transferIncome person::transferIncome set person::consumedGoods 0 set person::consumedGoodsValue 0 set person::workIncome 0 set person::investmentIncome 0 set person::transferIncome 0 ; Update consumption relationships ask my-Consumptions [ die ] ask my-currentConsumptions [ let companyId end2 let amount currentConsumption::amount let value currentConsumption::value ask end1 [ create-Consumption-with companyId [ consumption::Create amount value ] ] die ] end ; Shows information about the currently selected person on the output to person::ShowInfo output-print ( word "Person (id:" who ")" ) output-print ( word " Color: " world::Round2 person::color ) output-print ( word " Cash: " world::Round2 person::cash ) output-print ( word " Target cash: " world::Round2 person::targetCash ) output-print ( word " Stocks: " round person::stocks ) output-print ( word " Target stocks: " round person::targetStocks ) output-print ( word " Consumed goods: " round person::last::consumedGoods ) output-print ( word " Consumed goods value:" world::Round2 person::last::consumedGoodsValue ) output-print ( word " Work income: " world::Round2 person::last::workIncome ) output-print ( word " Investment income: " world::Round2 person::last::investmentIncome ) output-print ( word " Transfer income: " world::Round2 person::last::transferIncome ) if person::employed = 1 [ ask my-jobs [ output-print ( word " Works at:" end2 ) ] ] output-print ( word " Consumes (company, amount, value):" ) ask my-consumptions [ output-print ( word " " end2 ", " round consumption::amount ", " world::Round2 consumption::value ) ] end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; COMPANY MANAGEMENT ; ; Initializes a newly created company to company::Create set shape style::companyShape set color style::companyColor move-to one-of patches with [ count turtles-here = 0 ] set company::actionTick random world::ticksPerMonth set company::age 0 set company::color random-float 1 set company::workers 0 set company::vacancies 10 + random 10 set company::salary world::salary set company::lastSalary world::salary set company::maxSalary world::salary ;set company::stocks 0 ;set company::stocksOnSale company::vacancies * 19 + random 20 - 10 set company::cash 0 ; company::targetCash company::CalculateTargetCash ; Update the value set company::nonCurrentAssets 0 set company::inventory 0 set company::inventoryValue 0 set company::inventoryUnitaryValue 0 ;company::salePrice calculated below ;company::stockProfitability calculated below set company::bonds 0 ;company::bondsOnSale set company::coupon world::defaultCoupon set company::lastCoupon world::defaultCoupon set company::maxCoupon world::defaultCoupon set company::risk 1 ; Set the initial risk to 1, otherwise companies won't be able to get any initial funds set company::targetDebtRatio 1 / ( 1 / ( 0.2 + random-float 0.4 ) - 1) company::CalculateNetWorthComposition ; Update stocksOnSale and bondsOnSale set company::salePrice world::Round2( (company::CostPerUnit company::vacancies (company::stocksOnSale * world::stockPrice + company::targetBonds * world::bondFaceValue - company::targetCash) (company::vacancies * company::salary) (company::coupon * company::targetBonds) ) * (1 + random-float 0.10 + world::consumptionTax ) ); unitary cost + up-to 10% + tax set company::last::production 0 set company::last::productionValue 0 set company::last::demand world::baseConsumption * world::ticksPerMonth * world::initialPeopleCount / world::initialCompanyCount ; Educated guess for the first month's demand set company::last::sales 0 set company::last::salesValue 0 set company::last::laborCosts 0 set company::last::operatingProfit 0 set company::last::financialExpense 0 set company::last::profitBeforeTax 0 set company::last::result 0 set company::last::nonCurrentAssets 0 set company::last::inventory 0 set company::production 0 set company::productionValue 0 set company::demand 0 set company::sales 0 set company::salesValue 0 set company::laborCosts 0 set company::financialExpense 0 company::CalculateProfitPerStock end ; Operational action of the company to company::OperationalAction let stillAlive true ; Produce let producedGoods company::ProduceGoods company::workers company::nonCurrentAssets if producedGoods > 0 [ let producedGoodsCost producedGoods * (company::CostPerUnit company::workers company::nonCurrentAssets (sum [job::salary] of my-jobs) (sum [bond::GetFinancialCost 1] of my-bonds) ) set company::production company::production + producedGoods set company::productionValue company::productionValue + producedGoodsCost set company::inventory company::inventory + producedGoods set company::inventoryUnitaryValue world::Round2up( (company::inventoryValue + producedGoodsCost) / company::inventory ) set company::inventoryValue company::inventoryUnitaryValue * company::inventory ; Refresh the inventory value ] ; Pay salaries ifelse sum [job::salary] of my-jobs <= company::cash [ ask my-jobs [ let grossSalary job::salary let tax world::Round2( grossSalary * world::incomeTax ) let netSalary grossSalary - tax ask end1 ; Person [ set person::cash person::cash + netSalary set person::workIncome person::workIncome + netSalary ] ask end2 ; Company [ set company::cash company::cash - grossSalary set company::laborCosts company::laborCosts + grossSalary ] ask world::governId [ set govern::cash govern::cash + tax set govern::incomeFromIncomeTax govern::incomeFromIncomeTax + tax ] ] ] [ ; Cannot pay salaries -> pay what it's possible and close the company company::CloseBussiness true set stillAlive false ] if stillAlive [ ; Increase the offered salary if there are vacancies if company::vacancies > 0 [ set company::salary company::salary + world::salaryIncrease if company::salary > company::maxSalary [ let minSalary [govern::unemploymentBenefit] of world::GovernId + 1 set company::salary ifelse-value ( minSalary > company::maxSalary) [minSalary][ company::maxSalary] ] ] ; Increase the offered coupon if there are unsold bonds if company::targetBonds > company::bonds [ set company::coupon company::coupon + world::couponIncrease if company::coupon > company::maxCoupon [ set company::coupon company::maxCoupon ] ] ] ; Pay bonds let totalAmount sum [ sum bond::coupons ] of my-bonds if totalAmount > company::cash [ set stillAlive false company::CloseBussiness false ] if stillAlive [ ask my-bonds [ let companyId nobody let bankId nobody ifelse (is-company? end1) [ set companyId end1 set bankId end2 ] [ set companyId end2 set bankId end1 ] ; Pay coupons foreach bond::coupons [ [ c ] -> ask companyId ; Company [ set company::cash company::cash - c set company::financialExpense company::financialExpense + c ] ask bankId ; Bank [ set bank::cash bank::cash + c set bank::financialIncome bank::financialIncome + c ] ] ; Pay face values while [ first bond::maturities <= ticks and stillAlive] [ bond::RemoveBond ask companyID [ set company::bonds company::bonds - 1 ifelse not company::PayCapital world::bondFaceValue [ ask bankId [ set bank::bonds bank::bonds - 1 set bank::financialExpense bank::financialExpense + world::bondFaceValue set bank::nonCurrentAssets bank::nonCurrentAssets - world::bondFaceValue ] set stillAlive false company::closeBussiness false ] [ ask bankId [ set bank::bonds bank::bonds - 1 set bank::cash bank::cash + world::bondFaceValue set bank::nonCurrentAssets bank::nonCurrentAssets - world::bondFaceValue ] ] ] if bond::bondCount = 0 [ die ] ] ] ] end ; Strategic action of the company to company::StrategicAction let vacanciesPercent company::vacancies / (company::workers + company::vacancies) if company::nonCurrentAssets > 0 ; Do not alter workforce or stocks until the company is running [ ; Calculate variables to work with let factors company::OptimalFactors company::last::demand let neededWorkers first factors let neededCapital last factors let workforceExcess company::workers - neededWorkers ; if demand is higher than expected production increase the workforce if workforceExcess < 0 [ ; Set the salary for the new employees (only if there are no vacancies)(push the salary down) if company::vacancies = 0 [ set company::salary world::Round2( company::lastSalary * (0.5 + random-float 0.5) ) let minSalary [govern::unemploymentBenefit] of world::GovernId + 1 if company::salary > company::maxSalary [ set company::salary company::maxSalary ] if company::salary < minSalary [ set company::salary minSalary ] ] ; Workforce increase probability: ; 1) + More likely if there's extra capital for the current workers ( capital / world::CapitalToWorkRatio > workers ) ; 2) - Less likely if there's not enough capital for the current workers ( capital / world::CapitalToWorkRatio < workers ) ; 3) - Less likely if the company is not able to hire people let workforceIncreaseProbability 0.0 ; If there are no workers do not create new vacancies if company::workers > 0 [ ; [ 1 & 2 ] [ 3 ] set workforceIncreaseProbability ( company::nonCurrentAssets / ( world::CapitalToWorkRatio * company::workers) ) - ( vacanciesPercent * 0.1 ) if workforceIncreaseProbability < 0.1 [ set workforceIncreaseProbability 0.1] ; At least 10% chance ] if ( random-float 1 < workforceIncreaseProbability ) [ let jobOffers (- workforceExcess) let workers10perc ceiling company::workers * 0.1 if jobOffers >= 3 and jobOffers > workers10perc ; Limit the growth of the company to ensure we don't break the reserves [ set jobOffers max (list 3 workers10perc) ] set company::vacancies random ( jobOffers + 1) ] ] ; If the demand is not enough clear vacancies and fire some workers if workforceExcess >= 0 and company::workers > 0 [ set company::vacancies 0 ] if workforceExcess > 0 [ let workforceDecreaseProbability workforceExcess / company::workers ; The greater the excess the greater the probability if ( random-float 1 < workforceDecreaseProbability ) [ let workersToBeFired random (workforceExcess + 1) if workersToBeFired > 0 [ set company::workers company::workers - workersToBeFired ask n-of workersToBeFired my-jobs [ ask end1 [ set person::employed 0 ] die ] ] ] ] ; Calculate the target cash with the expected employees company::CalculateTargetCash ; if demand is higher than expected production increase the capital let capitalShortage neededCapital - ( company::stocks * world::stockPrice + company::bonds * world::bondFaceValue - company::targetCash ) if capitalShortage > 0 [ ; Divide the capital between stocks and bonds let stockCount round ( neededCapital / (1 + company::targetDebtRatio) / world::stockPrice ) let bondCount round ( ( neededCapital - stockCount * world::stockPrice ) / world::bondFaceValue ) ; Offer stocks if company::stocks < stockCount [ ; More stocks are needed ifelse company::stocks + company::stocksOnSale > stockCount [ ; Adjust the current stock offer set company::stocksOnSale stockCount - company::stocks ] [ ; Send more stocks to the market let unsoldStocksPercent ifelse-value (company::stocks = 0) [1] [company::stocksOnSale / company::stocks] ; Capital increase probability: ; 1) + More likely if there's not enough capital ; 2) - Less likely if the company is not able to sell stocks ; [ 1 ] [ 3 ] let capitalIncreaseProbability ( capitalShortage / neededCapital ) - ( unsoldStocksPercent ) if capitalIncreaseProbability < 0.1 [ set capitalIncreaseProbability 0.1] ; At least 10% chance if ( random-float 1 < capitalIncreaseProbability ) [ let stockOffer stockCount - company::stocks - company::stocksOnSale let stocks10perc ceiling company::stocks * 0.1 if stockOffer >= 10 and stockOffer > stocks10perc ; Limit the growth of the company no to get too big too quickly [ set stockOffer max (list 10 stocks10perc) ] set company::stocksOnSale random ( stockOffer + 1) ] ] ] ; Offer bonds ifelse company::targetBonds > bondCount [ ; Adjust the current bond offer set company::targetBonds bondCount ] [ if company::targetBonds < bondCount [ ; More bonds are needed ; Set the price for the new bonds (only if there are not bonds on sale)(push the price down) if company::targetBonds = company::bonds [ set company::coupon company::lastCoupon * (0.5 + random-float 0.5) ] ; Send more bonds to the market let unsoldBondsPercent ifelse-value (company::bonds = 0) [1] [company::targetBonds / company::bonds - 1] ; Capital increase probability: ; 1) + More likely if there's not enough capital ; 2) - Less likely if the company is not able to sell bonds ; [ 1 ] [ 3 ] let capitalIncreaseProbability ( capitalShortage / neededCapital ) - ( unsoldBondsPercent ) if capitalIncreaseProbability < 0.1 [ set capitalIncreaseProbability 0.1] ; At least 10% chance if ( random-float 1 < capitalIncreaseProbability ) [ let bondOffer bondCount - company::targetBonds let bonds10perc ceiling company::bonds * 0.1 if bondOffer >= 10 and bondOffer > bonds10perc ; Limit the growth of the company no to get too big too quickly [ set bondOffer max (list 10 bonds10perc) ] set company::targetBonds company::targetBonds + random ( bondOffer + 1) ] ] ; Update the max value for salaries ifelse company::last::result > 0 [ let vacancies ifelse-value (company::vacancies > 0)[company::vacancies][1] set company::maxSalary world::Round2Up( company::last::result / ( vacancies * world::ticksPerMonth ) ) ] [ set company::maxSalary 0 ] if company::salary > company::maxSalary [ set company::salary company::maxSalary ] let minSalary [govern::unemploymentBenefit] of world::GovernId + 1 if company::salary < minSalary [ set company::salary minSalary ] ; Update the max value for coupons ifelse company::last::result > 0 [ let bondsOnSale ifelse-value (company::targetBonds - company::bonds > 0)[company::targetBonds - company::bonds][1] set company::maxCoupon world::Round2Up( company::last::result / ( bondsOnSale * world::ticksPerMonth ) ) ] [ set company::maxCoupon 0 ] if company::coupon > company::maxCoupon [ set company::coupon company::maxCoupon ] ] ] ] ; If the demand is higher than real production or costs are greater than sale price increase the price let netSalePrice world::Round2( company::salePrice * (1 - world::consumptionTax) ) if company::last::demand > company::last::production or netSalePrice < company::inventoryUnitaryValue [ ; It will increase the price if there are a lot of vacancies, if the cost is lower than the price and at least with a 20% chance let salePriceIncreaseProbability max (list 0.2 vacanciesPercent (ifelse-value(netSalePrice < company::inventoryUnitaryValue)[1][0]) ) if ( random-float 1 < salePriceIncreaseProbability ) [ set netSalePrice world::Round2up( netSalePrice * 1.02 ) if netSalePrice < company::inventoryUnitaryValue [ set netSalePrice company::inventoryUnitaryValue ] set company::salePrice world::Round2( netSalePrice * ( 1 + world::consumptionTax ) ) ] ] ; Demand is too low, try to increase it lowering prices if ( company::last::demand = 0 or company::last::demand < company::last::production ) and company::last::production > 0 [ let salePriceDecreaseProbability 1 ; If demand is 0, decrease price! if company::last::demand != 0 [ set salePriceDecreaseProbability ( company::last::production - company::last::demand ) / company::last::production ; The bigger the gap the more likely to reduce price ] if ( random-float 1 < salePriceDecreaseProbability ) [ set netSalePrice world::Round2( company::salePrice * (1 - world::consumptionTax) ) ; Reduce the price by a 2% or reduce the gap between price and costs by a 20% set netSalePrice world::Round2down ( min ( list (netSalePrice * 0.98) (netSalePrice - (netSalePrice - company::inventoryUnitaryValue) * 0.2 ) ) ) if netSalePrice < company::inventoryUnitaryValue [ set netSalePrice company::inventoryUnitaryValue ] set company::salePrice world::Round2( netSalePrice * ( 1 + world::consumptionTax ) ) ] ] ; Calculate the expected profits company::CalculateProfitPerStock ; Adjust assets to the new target cash company::DistributeAssets ; The company has 3 months since birth to rise enough capital, if it's not successfull close it if company::nonCurrentAssets = 0 and company::age > 3 [ company::closeBussiness false ] end ; Monthly action of the company to company::MonthlyAction let changeInInventory company::inventoryValue - company::last::inventoryValue ; Update the monthly statistical variables of the company set company::age company::age + 1 set company::last::production company::production set company::last::productionValue company::last::production * company::salePrice set company::last::demand company::demand set company::last::sales company::sales set company::last::salesValue company::salesValue set company::last::laborCosts company::laborCosts set company::last::operatingProfit world::Round2( company::salesValue - company::laborCosts + (company::inventoryValue - company::last::inventoryValue) ) set company::last::financialExpense company::financialExpense set company::last::profitBeforeTax company::last::operatingProfit - company::last::financialExpense set company::last::investment ( company::nonCurrentAssets - company::last::nonCurrentAssets ) + ( company::inventory - company::last::inventory ) * company::salePrice set company::last::nonCurrentAssets company::nonCurrentAssets set company::last::inventory company::inventory set company::last::inventoryValue company::inventoryValue set company::production 0 set company::productionValue 0 set company::demand 0 set company::sales 0 set company::salesValue 0 set company::laborCosts 0 set company::financialExpense 0 ; Pay taxes let tax 0 if ( company::last::profitBeforeTax > 0 ) [ set tax world::Round2( company::last::profitBeforeTax * world::corporationTax ) if company::cash < tax [ ; If not enough cash, pay what it is possible set tax company::cash ] set company::cash company::cash - tax ask world::governId [ set govern::cash govern::cash + tax set govern::incomeFromCorporationTax govern::incomeFromCorporationTax + tax ] ] set company::last::result company::last::profitBeforeTax - tax ; Update the max value for coupons ifelse company::last::result > 0 [ let pervMaxCoupon company::maxCoupon let bondsOnSale ifelse-value (company::targetBonds - company::bonds > 0)[company::targetBonds - company::bonds][1] set company::maxCoupon world::Round2Up( company::last::result / ( bondsOnSale * world::ticksPerMonth ) ) if company::coupon = pervMaxCoupon [ ;Update the coupon value set company::coupon company::lastCoupon * (0.5 + random-float 0.5) if company::coupon > company::maxCoupon [ set company::coupon company::maxCoupon ] ] ] [ set company::maxCoupon 0 ] ; Update the company's risk company::CalculateRisk ; Distribute dividend let totalAssets company::cash + company::inventoryValue + company::nonCurrentAssets let dividend totalAssets - company::targetCash - company::stocks * world::stockPrice - company::bonds * world::bondFaceValue if dividend > 0 [ if dividend > company::cash [ set dividend company::cash ] if dividend / 10 > company::stocks ; Distribute at least 10 cents to each stock [ let cashLeft dividend let stocksLeft company::stocks ask my-investments [ let grossInvestorCash world::Round2down( cashLeft / stocksLeft ) * investment::stocks set tax world::Round2( grossInvestorCash * world::incomeTax ) let netInvestorCash grossInvestorCash - tax ask world::governId [ set govern::cash govern::cash + tax set govern::incomeFromIncomeTax govern::incomeFromIncomeTax + tax ] ask end1 [ set person::cash person::cash + netInvestorCash set person::investmentIncome person::investmentIncome + netInvestorCash ] ask end2 [ set company::cash company::cash - grossInvestorCash ] set cashLeft cashLeft - grossInvestorCash set stocksLeft stocksLeft - investment::stocks ] ] ] end ; Calculate the amount of cash the company needs to have to company::CalculateTargetCash set company::targetCash ( sum [job::salary] of my-jobs + ( company::vacancies * company::salary ) ) * world::companyReservesTargetTicks + sum [bond::GetFinancialCost world::companyReservesTargetTicks] of my-bonds end ; Distributes the amount of money between the cash and nonCurrentAssets. It's used when the company's stock number increases or then the target cash is changed. to company::DistributeAssets ; If the company needs cash, convert some non current assets (but don't convert all of them) if company::cash < company::targetCash and company::nonCurrentAssets > world::minCapital [ let amount company::targetCash - company::cash if company::nonCurrentAssets - amount < world::minCapital [ set amount company::nonCurrentAssets - world::minCapital] set company::nonCurrentAssets company::nonCurrentAssets - amount set company::cash company::cash + amount ] ; If the company has excess cash, add some non current assets if they are below the expected level. if company::cash > company::targetCash [ let amount company::cash - company::targetCash set company::nonCurrentAssets company::nonCurrentAssets + amount set company::cash company::cash - amount ] end ; Pay an amount of money reducing the amount of non-current assegs if needed. It's used when selling stocks or distributing dividend, not for ordinary payments to-report company::PayCapital [ amount ] ; Pay in cash if we have enough if company::cash - amount >= company::targetCash [ set company::cash company::cash - amount report true ] ; There's not enough cash, convert some nonCurrentActives if company::cash + company::nonCurrentAssets - amount >= company::targetCash + world::minCapital [ let total company::cash + company::nonCurrentAssets - amount set company::cash company::targetCash set company::nonCurrentAssets total - company::cash report true ] ; There's enough cash but not enough to keep target reserves full if company::cash + company::nonCurrentAssets - amount >= world::minCapital [ set company::cash company::cash + company::nonCurrentAssets - amount - world::minCapital set company::nonCurrentAssets world::minCapital report true ] ; There's not enough money report false end ; Given the production factor's values calculates how much te company will produce to-report company::ProduceGoods[ workers capital ] let producedGoods 0 if workers >= 1 [ set producedGoods round ( world::technology * (workers - 0.1) ^ 0.5 * (capital / world::CapitalToWorkRatio) ^ 0.5 ) ] report producedGoods end ; Given the production factor's values calculates the cost per unit produced to-report company::CostPerUnit[ workers capital workersCost debtCost] let producedGoods company::ProduceGoods workers capital let totalCost workersCost + debtCost report world::Round2Up (totalCost / producedGoods ) end ; Given the units demanded by consumers, calculates the production factors to meet that demand to-report company::OptimalFactors[ demand ] let goodsToProduce demand - company::inventory let goodsToProducePerTick ceiling (goodsToProduce / world::ticksPerMonth) let workers 1 let capital world::minCapital if goodsToProducePerTick > 0 [ ; P = A * (N - 0.1)^0.5 * (K/5000)^0.5 ; For optimal purposes: N - 0.1 = K / 5000 -> P = A * (N - 0.1) set workers ceiling( goodsToProducePerTick / world::technology + 0.1 ) set capital workers * world::CapitalToWorkRatio ] report (list workers capital ) end ; Calculate the expected profit per stock of the company for the next month to company::CalculateProfitPerStock let workers company::workers + company::vacancies let stocks company::stocks + company::stocksOnSale let nBonds company::targetBonds let capital stocks * world::stockPrice + nBonds * world::bondFaceValue - company::targetCash if capital < world::minCapital [set capital world::minCapital] let totalIncome company::salePrice * (1 - world::consumptionTax) * company::ProduceGoods workers capital let totalCost sum [job::salary] of my-jobs + sum[bond::getFinancialCost world::ticksPerMonth ] of my-bonds / world::ticksPerMonth + ifelse-value (company::targetBonds > company::bonds) [ (company::targetBonds - company::bonds) * company::coupon ][0] set company::stockProfitability ( totalIncome - totalCost ) * world::ticksPerMonth / stocks end ; Close the company to company::CloseBussiness [ payWorkers ] ; Fire the workers and pay them what the company owes them set company::cash company::cash + company::nonCurrentAssets set company::nonCurrentAssets 0 ask my-jobs [ let lastSalary ifelse-value ( payWorkers ) [ world::Round2down( [company::cash / company::workers] of end2 )][0] ask end1 ; Person [ set person::cash person::cash + lastSalary set person::employed 0 ] ask end2 ; Company [ set company::cash company::cash - lastSalary set company::workers company::workers - 1 ] ] ; Pay bonds ask my-bonds [ let companyId nobody let bankId nobody ifelse is-company? end1 [ set companyId end1 set bankId end2 ] [ set companyId end2 set bankId end1 ] while [ bond::bondCount > 0 ] [ bond::RemoveBond if-else [company::cash] of myself >= world::bondFaceValue [ ask companyId [ set company::cash company::cash - world::bondFaceValue set company::bonds company::bonds - 1 ] ask bankId [ set bank::bonds bank::bonds - 1 set bank::cash bank::cash + world::bondFaceValue set bank::nonCurrentAssets bank::nonCurrentAssets - world::bondFaceValue ] ] [ ; Can't pay ask companyId [ set company::bonds company::bonds - 1 ] ask bankId [ set bank::bonds bank::bonds - 1 set bank::financialExpense bank::financialExpense + world::bondFaceValue set bank::nonCurrentAssets bank::nonCurrentAssets - world::bondFaceValue ] ] if bond::bondCount = 0 [ die ] ] ] ; End all investment relationships and return the remainings of their investment ask my-investments [ let stocks investment::stocks let lastDividend ifelse-value (stocks < [company::stocks] of end2 ) [ world::Round2down( stocks * [company::cash / company::stocks] of end2 ) ][ [company::cash] of end2 ] ask end1 ; Person [ set person::cash person::cash + lastDividend set person::stocks person::stocks - stocks set person::targetStocks person::targetStocks - stocks if person::targetStocks < 0 [ set person::targetStocks 0 ] ] ask end2 ; Company [ set company::cash company::cash - lastDividend set company::stocks company::stocks - stocks ] ] ; if it still has some cash give it to the govern (it may occur if the company loses all its investors) ask world::governId [ set govern::cash govern::cash + [company::cash] of myself ] set company::cash 0 ; If the company was selected, deselect it if selection::selectedAgent = self [ let patchId selection::selectedPatch set selection::selectedPatch nobody set selection::selectedAgent nobody selection::selectPatch patchId ] ; Kill the company die end ; Calculate the initial stocks and bonds on sale to company::CalculateNetWorthComposition let capital company::vacancies * world::CapitalToWorkRatio + company::targetCash set company::stocksOnSale round ( capital / (1 + company::targetDebtRatio) / world::stockPrice ) set company::targetBonds round ( ( capital - company::stocksOnSale * world::stockPrice ) / world::bondFaceValue ) end ; Calculates the risk level the company has to company::CalculateRisk let times 0 ifelse company::lastCoupon > company::Coupon [ set times company::last::result / ( company::lastCoupon * world::ticksPerMonth ) ] [ set times company::last::result / ( company::Coupon * world::ticksPerMonth ) ] if times < -2 [set times -2 ] ; Avoid number overflow when making e^-times & risk value being too high set company::risk (exp (-1 * times) ) + 1 end ; Shows information about the selected company in the output control to company::ShowInfo output-print ( word "Company (id:" who ")" ) output-print ( word " Color: " world::Round2 company::color ) output-print ( word " Age : " world::Round2 company::age ) output-print ( word " Cash: " world::Round2 company::cash ) output-print ( word " Target Cash: " world::Round2 company::targetCash ) output-print ( word " Non-current Assets: " world::Round2 company::nonCurrentAssets ) output-print ( word " No. of Workers: " round company::workers ) output-print ( word " No. of Vacancies: " round company::vacancies ) output-print ( word " Salary: " world::Round2 company::salary ) output-print ( word " Target Debt Ratio: " world::Round2 company::targetDebtRatio ) output-print ( word " Stocks: " round company::stocks ) output-print ( word " Stocks on sale: " round company::stocksOnSale ) output-print ( word " Bonds: " round company::bonds ) output-print ( word " Bonds target : " round company::targetBonds ) output-print ( word " Bonds coupon: " world::Round2 company::coupon ) output-print ( word " Production Units: " round company::last::production ) output-print ( word " Demanded Units: " round company::last::demand ) output-print ( word " Stored Goods: " round company::inventory ) output-print ( word " Unitary Cost: " world::Round2 company::inventoryUnitaryValue ) output-print ( word " Sale Price: " world::Round2 company::salePrice ) output-print ( word " Net Sale Price: " world::Round2 ( company::salePrice * ( 1 - world::consumptionTax ) ) ) output-print ( word " Sold Units: " world::Round2 company::last::sales ) output-print ( word " Value of Sales: " world::Round2 company::last::salesValue ) output-print ( word " Labor Costs: " world::Round2 company::last::laborCosts ) output-print ( word " Operating Profit: " world::Round2 company::last::operatingProfit ) output-print ( word " Financial Expense: " world::Round2 company::last::financialExpense ) output-print ( word " Profit Before Tax: " world::Round2 company::last::profitBeforeTax ) output-print ( word " Result: " world::Round2 company::last::result ) output-print ( word " Risk: " world::Round2 company::risk ) output-print ( word " Stock profitability: " world::Round2 company::stockProfitability ) end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; GOVERN MANAGEMENT ; ; Initializes a newly created govern to govern::Create[ cash ] set shape style::governShape set color style::governColor move-to patch -1 0 set govern::workers 0 set govern::vacancies 350 set govern::cash cash set govern::targetCash 0 set govern::salary world::salary set govern::unemploymentBenefit world::unemploymentBenefit set govern::bonds 0 set govern::bondsOnSale 0 set govern::coupon world::defaultCoupon set govern::lastCoupon world::defaultCoupon set govern::loans 0 set govern::risk 0 set govern::incomeFromCorporationTax 0 set govern::incomeFromIncomeTax 0 set govern::incomeFromConsumptionTax 0 set govern::laborCosts 0 set govern::transferCosts 0 set govern::financialExpense 0 set govern::last::incomeFromCorporationTax 0 set govern::last::incomeFromIncomeTax 0 set govern::last::incomeFromConsumptionTax 0 set govern::last::laborCosts 0 set govern::last::transferCosts 0 set govern::last::financialExpense 0 end ; Operational action of the govern to govern::OperationalAction ; Pay salaries let laborCosts sum [job::salary] of my-jobs if govern::cash < laborCosts [ govern::CentralBankRescue ] ask my-jobs [ let grossSalary job::salary let tax world::Round2( grossSalary * world::incomeTax ) let netSalary grossSalary - tax ask end2 ; Person [ set person::cash person::cash + netSalary set person::workIncome person::workIncome + netSalary ] ask end1 ; Govern [ set govern::cash govern::cash - grossSalary set govern::laborCosts govern::laborCosts + grossSalary set govern::cash govern::cash + tax set govern::incomeFromIncomeTax govern::incomeFromIncomeTax + tax ] ] ; Pay unemployment benefits let unemployed count people with [ person::employed = 0 ] if govern::cash < unemployed * govern::unemploymentBenefit [ govern::CentralBankRescue ] let grossUnemplymentBenefit govern::unemploymentBenefit let tax world::Round2( grossUnemplymentBenefit * world::incomeTax ) let netUnemplymentBenefit grossUnemplymentBenefit - tax ask people with [ person::employed = 0 ] [ set person::cash person::cash + netUnemplymentBenefit set person::transferIncome person::transferIncome + netUnemplymentBenefit ] set govern::cash govern::cash - world::Round2 ( netUnemplymentBenefit * unemployed ) set govern::transferCosts govern::transferCosts + world::Round2 ( grossUnemplymentBenefit * unemployed ) set govern::incomeFromIncomeTax govern::incomeFromIncomeTax + world::Round2 ( tax * unemployed ) ; Increase the offered coupon if there are unsold bonds if govern::bondsOnSale > 0 [ set govern::coupon govern::coupon + world::couponIncrease ] ; Pay debt ask my-bonds [ ; Pay coupons foreach bond::coupons [ [ c ] -> ask end1 ; Govern [ if govern::cash < c [ govern::CentralBankRescue ] set govern::cash govern::cash - c set govern::financialExpense govern::financialExpense + c ] ask end2 ; Bank [ set bank::cash bank::cash + c set bank::financialIncome bank::financialIncome + c ] ] ; Pay face values while [ first bond::maturities <= ticks ] [ bond::RemoveBond ask end1 [ if govern::cash < world::bondFaceValue [ govern::CentralBankRescue ] set govern::bonds govern::bonds - 1 set govern::cash govern::cash - world::bondFaceValue ] ask end2 ; Bank [ set bank::bonds bank::bonds - 1 set bank::cash bank::cash + world::bondFaceValue set bank::nonCurrentAssets bank::nonCurrentAssets - world::bondFaceValue ] if bond::bondCount = 0 [die] ] ] ; Return rescue loans to the central bank ask my-loans [ ; Pay face values while [ first loan::maturities <= ticks ] [ loan::RemoveLoan ask end1 [ if govern::cash < world::loanFaceValue [ govern::CentralBankRescue ] set govern::cash govern::cash - world::loanFaceValue set govern::loans govern::loans - 1 ] ask end2 [ set centralBank::M1 centralBank::M1 - world::loanFaceValue ] if loan::loanCount = 0 [ die ] ] ] ; Govern workers improve technology set world::technology world::technology * (1 + govern::workers * world::technologyImprovementPerGovernmentWorker) end ; Strategic action of the govern to govern::StrategicAction govern::CalculateTargetCash ; Hire workers if cash superavit if govern::targetCash < govern::cash [ ; The greater the cash reserves the greater the possibility of a workforce increase let workforceIncreaseProbability govern::cash / govern::targetCash if ( random-float 1 < workforceIncreaseProbability ) [ let workers10perc ceiling govern::workers * 0.1 let jobOffers max (list 3 workers10perc) let maxJobOffers floor( govern::targetCash - govern::cash / ( govern::salary * world::ticksPerMonth ) ) if jobOffers > maxJobOffers [ set jobOffers maxJobOffers ] set govern::vacancies govern::vacancies + random ( jobOffers + 1) ] ] ; Create bonds and lay off workers if cash deficit (or rescue) if govern::targetCash > govern::cash [ ; Lay off workers let workforceExcess floor ( ( govern::targetCash - govern::cash ) / govern::salary ) if workforceExcess >= govern::workers [ set workforceExcess govern::workers - 1 ] let workforceDecreaseProbability ifelse-value (govern::workers = 0)[0][workforceExcess / govern::workers] if random-float 1 < workforceDecreaseProbability [ let workersToBeFired random workforceExcess + 1 set govern::workers govern::workers - workersToBeFired ask n-of workersToBeFired my-jobs [ ask end2 [ set person::employed 0 ] die ] ] ifelse ( govern::last::financialExpense < govern::last::incomeFromCorporationTax + govern::last::incomeFromIncomeTax + govern::last::incomeFromConsumptionTax ) [ ; Emit bonds for the difference between the target cash and the current cash let pervBondsOnSale govern::bondsOnSale set govern::bondsOnSale ceiling ( ( govern::targetCash - govern::cash ) / world::bondFaceValue ) if pervBondsOnSale = 0 and govern::bondsOnSale > 0 and govern::coupon = govern::lastCoupon [ set govern::coupon govern::lastCoupon * (0.5 + random-float 0.5) ] ] [ ; The financial expenses are already more than the govern can handle govern::CentralBankRescue ] ] end ; Monthly action of the govern to govern::MonthlyAction set govern::last::incomeFromCorporationTax govern::incomeFromCorporationTax set govern::last::incomeFromIncomeTax govern::incomeFromIncomeTax set govern::last::incomeFromConsumptionTax govern::incomeFromConsumptionTax set govern::last::laborCosts govern::laborCosts set govern::last::transferCosts govern::transferCosts set govern::last::financialExpense govern::financialExpense set govern::incomeFromCorporationTax 0 set govern::incomeFromIncomeTax 0 set govern::incomeFromConsumptionTax 0 set govern::laborCosts 0 set govern::transferCosts 0 set govern::financialExpense 0 if length world::priceIndexValues > 0 [ let updateFactor last world::priceIndexValues / 100 set govern::salary world::Round2( world::salary * updateFactor ) set govern::unemploymentBenefit world::Round2( world::unemploymentBenefit * updateFactor ) ] end ; Calculates the amount of cash the government wants to have to govern::CalculateTargetCash let unemployedPeople count people with [ person::employed = 0 ] let expectedTransferCost unemployedPeople * govern::unemploymentBenefit let expectedWageCost ( govern::workers + govern::vacancies ) * govern::salary ;Increase rapidly, decrease slowly let newTargetCash (expectedTransferCost + expectedWageCost) * world::governReservesTargetTicks + sum [bond::GetDebtCost world::governReservesTargetTicks] of my-bonds + sum [loan::GetDebtCost world::governReservesTargetTicks] of my-loans if-else newTargetCash >= govern::targetCash [ set govern::targetCash newTargetCash ] [ set govern::targetCash newTargetCash * 0.25 + govern::targetCash * 0.75 ] end ; The govern has run out of money, ask for help to the central bank to govern::CentralBankRescue govern::CalculateTargetCash let neededLoans ceiling( (govern::targetCash - govern::cash) / world::loanFaceValue ) ; Create or update the bond relationship create-loan-with world::centralBankId [ loan::Create ] ask loan-with world::centralBankId [ loan::AddLoan neededLoans ] ask world::centralBankId [ set centralBank::M1 centralBank::M1 + neededLoans * world::loanFaceValue set centralBank::loanOffer ifelse-value (centralBank::loanOffer <= neededLoans) [0] [centralBank::loanOffer - neededLoans] ] set govern::cash govern::cash + neededLoans * world::loanFaceValue set govern::loans govern::loans + neededLoans end ; Shows information about the govern in the output control to govern::ShowInfo output-print ( word "Govern (id:" who ")" ) output-print ( word " Cash: " world::Round2 govern::cash ) output-print ( word " Target Cash: " world::Round2 govern::targetCash ) output-print ( word " No. of Workers: " round govern::workers ) output-print ( word " No. of Vacancies: " round govern::vacancies ) output-print ( word " Salary: " world::Round2 govern::salary ) output-print ( word " Bonds: " round govern::bonds ) output-print ( word " Bonds on sale: " round govern::bondsOnSale ) output-print ( word " Bonds coupon: " world::Round2 govern::lastCoupon ) output-print ( word " Loans: " round govern::loans ) output-print ( word " Total Income: " world::Round2 ( govern::last::incomeFromCorporationTax + govern::last::incomeFromIncomeTax + govern::last::incomeFromConsumptionTax ) ) output-print ( word " Corp. Tax Income: " world::Round2 govern::last::incomeFromCorporationTax ) output-print ( word " Income Tax Income: " world::Round2 govern::last::incomeFromIncomeTax ) output-print ( word " Consumption Tax Inc.:" world::Round2 govern::last::incomeFromConsumptionTax ) output-print ( word " Total Expenses: " world::Round2 ( govern::last::laborCosts + govern::last::transferCosts + govern::last::financialExpense) ) output-print ( word " Labor Costs: " world::Round2 govern::last::laborCosts ) output-print ( word " Unemployment Benefit:" world::Round2 govern::last::transferCosts ) output-print ( word " Financial Expense: " world::Round2 govern::last::financialExpense ) end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; BANK MANAGEMENT ; ; Initializes a newly created bank to bank::Create set shape style::bankShape set color style::bankColor move-to one-of patches with [ count turtles-here = 0 ] set bank::actionTick random world::ticksPerMonth set bank::age 0 set bank::workers 0 set bank::vacancies 5 + random 5 set bank::salary world::salary set bank::lastSalary world::salary set bank::maxSalary world::salary set bank::stocks 0 ;set bank::stocksOnSale ;set on bank::CalculateNetWorthComposition set bank::loans 0 ;set bank::targetLoans ;set on bank::CalculateNetWorthComposition set bank::cash 0 ; bank::targetCash ;set on bank::CalculateTargetCash bank::CalculateTargetCash ; Update the value set bank::bonds 0 set bank::targetBonds bank::vacancies * world::bondsPerWorker set bank::minBondCoupon world::Round2Up( bank::vacancies * bank::salary / bank::targetBonds) set bank::nonCurrentAssets 0 set bank::risk 1 set bank::targetRisk 1.37 - random-float 0.36 ; result/coupon at least 1 to aprox 4,5 set bank::targetDebtRatio 1 / (0.1 + random-float 0.3) - 1; Debt ratio that the bank wants to have ;bank::stockProfitability bank::CalculateNetWorthComposition ; Update stocksOnSale and targetLoans set bank::last::laborCosts 0 set bank::last::operatingProfit 0 set bank::last::financialIncome 0 set bank::last::financialExpense 0 set bank::last::profitBeforeTax 0 set bank::last::result 0 set bank::laborCosts 0 set bank::financialIncome 0 set bank::financialExpense 0 bank::CalculateProfitPerStock end ; Operational action of the bank to bank::OperationalAction let stillAlive true ; Get Loans from the central bank let loanDemand bank::targetLoans - bank::loans if loanDemand > 0 [ if loanDemand > [centralBank::loanOffer] of world::centralBankId [ set loanDemand [centralBank::loanOffer] of world::centralBankId ] if ( loanDemand > 0 ) [ ; Create or update the bond relationship create-loan-with world::centralBankId [ loan::Create ] ask loan-with world::centralBankId [ loan::AddLoan loanDemand ] set bank::cash bank::cash + world::loanFaceValue * loanDemand set bank::loans bank::loans + loanDemand ask world::centralBankId [ set centralBank::loanOffer centralBank::loanOffer - loanDemand set centralBank::M1 centralBank::M1 + world::loanFaceValue * loanDemand ] ] ] ; Return loans to the central bank ask my-loans [ ; Pay face values while [ first loan::maturities <= ticks and stillAlive ] [ loan::RemoveLoan ask end2 [ if-else bank::cash > world::loanFaceValue [ set bank::cash bank::cash - world::loanFaceValue set bank::loans bank::loans - 1 ] [; Cannot return loans -> pay what it's possible and close the company bank::closeBussiness false set stillAlive false ] ] if stillAlive [ ask end1 [ set centralBank::M1 centralBank::M1 - world::loanFaceValue ] ] if loan::loanCount = 0 [ die ] ] ] if stillAlive [ ; Pay salaries ifelse sum [job::salary] of my-jobs <= bank::cash [ ask my-jobs [ let grossSalary job::salary let tax world::Round2( grossSalary * world::incomeTax ) let netSalary grossSalary - tax ask end1 ; Person [ set person::cash person::cash + netSalary set person::workIncome person::workIncome + netSalary ] ask end2 ; Bank [ set bank::cash bank::cash - grossSalary set bank::laborCosts bank::laborCosts + grossSalary ] ask world::governId [ set govern::cash govern::cash + tax set govern::incomeFromIncomeTax govern::incomeFromIncomeTax + tax ] ] ] [ ; Cannot pay salaries -> pay what it's possible and close the company bank::CloseBussiness true set stillAlive false ] ] ; Buy bonds if stillAlive [ let bondsOnMarket true while [ bank::cash - bank::targetCash > world::bondFaceValue and bank::targetBonds > bank::bonds and bondsOnMarket] [ let maxRisk (bank::targetRisk - bank::risk) * bank::bonds + bank::targetRisk let agent nobody ifelse ( maxRisk < 1 ) [ let targetRisk bank::targetRisk set agent min-one-of turtles with [ (is-company? self and company::targetBonds > company::bonds and company::risk < targetRisk and company::coupon >= [bank::minBondCoupon] of myself ) or (is-govern? self and govern::bondsOnSale > 0 and govern::risk < targetRisk and govern::coupon >= [bank::minBondCoupon] of myself ) ] [ ifelse-value (is-company? self ) [company::risk][govern::risk] ] ] [ set agent max-one-of turtles with [ (is-company? self and company::targetBonds > company::bonds and company::risk <= maxRisk and company::coupon >= [bank::minBondCoupon] of myself ) or (is-govern? self and govern::bondsOnSale > 0 and govern::risk <= maxRisk and govern::coupon >= [bank::minBondCoupon] of myself ) ] [ ifelse-value (is-company? self ) [company::coupon][govern::coupon] ] ] set bondsOnMarket (agent != nobody) if (agent != nobody ) [ ; Create or update the bond relationship create-bond-with agent [ bond::Create ] ask bond-with agent [ bond::AddBond ifelse-value (is-company? agent) [[company::coupon] of agent ] [[govern::coupon] of agent] ] let agentRisk 1 ask agent [ if-else(is-company? self) [ set company::bonds company::bonds + 1 set company::cash company::cash + world::bondFaceValue set company::lastCoupon company::coupon company::DistributeAssets set agentRisk company::risk ] [ set govern::bonds govern::bonds + 1 set govern::bondsOnSale govern::bondsOnSale - 1 set govern::cash govern::cash + world::bondFaceValue set govern::lastCoupon govern::coupon set agentRisk govern::risk ] ] set bank::cash bank::cash - world::bondFaceValue set bank::nonCurrentAssets bank::nonCurrentAssets + world::bondFaceValue set bank::bonds bank::bonds + 1 set bank::risk (bank::risk * (bank::bonds - 1) + agentRisk ) / bank::bonds ; Update the bank's risk ] ] ] if stillAlive [ ; Increase the offered salary if there are vacancies if bank::vacancies > 0 [ set bank::salary bank::salary + world::salaryIncrease if bank::salary > bank::maxSalary [ let minSalary [govern::unemploymentBenefit] of world::GovernId + 1 set bank::salary ifelse-value ( minSalary > bank::maxSalary) [minSalary][ bank::maxSalary] ] ] ] end ; Strategic action of the bank to bank::StrategicAction let bondGap (bank::workers * world::bondsPerWorker) - bank::bonds ; Clear vacancies to recalculate them let prevVacancies bank::vacancies set bank::vacancies 0 ; Fire workers if the current amount of bonds can be managed with fewer people if bank::workers > 1 and bondGap > world::bondsPerWorker [ let workersToFire random ( floor (bondGap / world::bondsPerWorker )) + 1 if workersToFire > 0 [ if workersToFire >= bank::workers [ set workersToFire bank::workers - 1] set bank::workers bank::workers - workersToFire ask n-of workersToFire my-jobs [ ask end1 ; Person [ set person::employed 0 ] die ] ] ] ( ifelse ; If the bank needs more employees , increase workforce ( bondGap < 0 ) [ set bank::vacancies ceiling ( -1 * bondGap / world::bondsPerWorker ) ] ; if the bank is almost full capacity, increase workforce ( bondGap < world::bondsPerWorker * 0.2 ) [ let workersToHire random 4 ; Hire 0, 1, 2, or 3 workers each time set bank::vacancies workersToHire if (bank::workers = 0) [set bank::vacancies bank::vacancies + 1 ] ] ) ; Set the salary for the new employees (only if there are no vacancies)(push the salary down) if prevVacancies = 0 and bank::vacancies > 0 [ set bank::salary world::Round2 ( bank::lastSalary * (0.5 + random-float 0.5) ) let minSalary [govern::unemploymentBenefit] of world::GovernId + 1 if bank::salary > bank::maxSalary [ set bank::salary bank::maxSalary ] if bank::salary < minSalary [ set bank::salary minSalary ] ] ; Calculate the new amount of bonds we want to have set bank::targetBonds (bank::workers + bank::vacancies) * world::bondsPerWorker set bank::minBondCoupon world::Round2Up( ( sum[job::salary] of my-jobs + (bank::vacancies * bank::salary) ) / bank::targetBonds) ; Get capital based on the amount of bonds we want to have bank::CalculateTargetCash let neededCapital bank::targetCash + bank::targetBonds * world::bondFaceValue ; Divide the capital between stocks and loans let stockCount round ( neededCapital / (1 + bank::targetDebtRatio) / world::stockPrice ) let loanCount round ( ( neededCapital - stockCount * world::stockPrice ) / world::loanFaceValue ) if stockCount > bank::stocks [ set bank::stocksOnSale random ( stockCount - bank::stocks + 1) ] if stockCount < bank::stocks [ ; Excess stocks, reduce the loan demand let extraStockValue ( bank::stocks - stockCount ) * world::stockPrice set loanCount loanCount - floor( extraStockValue / world::loanFaceValue ) ] set bank::targetLoans loanCount end ; Monthly action of the bank to bank::MonthlyAction set bank::age bank::age + 1 set bank::last::laborCosts bank::laborCosts set bank::last::operatingProfit (- bank::last::laborCosts) set bank::last::financialIncome bank::financialIncome set bank::last::financialExpense bank::financialExpense set bank::last::profitBeforeTax bank::last::operatingProfit + bank::last::financialIncome - bank::last::financialExpense set bank::laborCosts 0 set bank::financialIncome 0 set bank::financialExpense 0 ; Pay taxes and calculate result let tax 0 if ( bank::last::profitBeforeTax > 0 ) [ set tax world::Round2( bank::last::profitBeforeTax * world::corporationTax ) if bank::cash < tax [ ; If not enough cash, pay what it is possible set tax bank::cash ] set bank::cash bank::cash - tax ask world::governId [ set govern::cash govern::cash + tax set govern::incomeFromCorporationTax govern::incomeFromCorporationTax + tax ] ] set bank::last::result bank::last::profitBeforeTax - tax ; Update the max value for salaries ifelse bank::last::result > 0 [ let vacancies ifelse-value (bank::vacancies > 0)[bank::vacancies][1] set bank::maxSalary world::Round2Up( bank::last::result / ( vacancies * world::ticksPerMonth ) ) ] [ set bank::maxSalary 0 ] if bank::salary > bank::maxSalary [ set bank::salary bank::maxSalary ] let minSalary [govern::unemploymentBenefit] of world::GovernId + 1 if bank::salary < minSalary [ set bank::salary minSalary ] ; Update the bank's risk bank::CalculateRisk ; Distribute dividend let totalAssets bank::cash + bank::nonCurrentAssets let dividend totalAssets - bank::targetCash - bank::stocks * world::stockPrice - bank::loans * world::loanFaceValue if dividend > 0 [ if dividend > bank::cash [ set dividend bank::cash ] if dividend / 10 > bank::stocks ; Distribute at least 10 cents to each stock [ let cashLeft dividend let stocksLeft bank::stocks ask my-investments [ let grossInvestorCash world::Round2down( cashLeft / stocksLeft ) * investment::stocks set tax world::Round2( grossInvestorCash * world::incomeTax ) let netInvestorCash grossInvestorCash - tax ask world::governId [ set govern::cash govern::cash + tax set govern::incomeFromIncomeTax govern::incomeFromIncomeTax + tax ] ask end1 [ set person::cash person::cash + netInvestorCash set person::investmentIncome person::investmentIncome + netInvestorCash ] ask end2 [ set bank::cash bank::cash - grossInvestorCash ] set cashLeft cashLeft - grossInvestorCash set stocksLeft stocksLeft - investment::stocks ] ] ] end ; Calculate the initial stocks on sale and loans target to bank::CalculateNetWorthComposition let netWorth bank::vacancies * world::bondsPerWorker * world::bondFaceValue + bank::targetCash set bank::stocksOnSale round ( netWorth / (1 + bank::targetDebtRatio) / world::stockPrice ) set bank::targetLoans round ( ( netWorth - bank::stocksOnSale * world::stockPrice ) / world::loanFaceValue ) end ; Calculate the expected profit per stock of the company for the next month to bank::CalculateProfitPerStock let stocks bank::stocks + bank::stocksOnSale let totalIncome sum[bond::getFinancialCost world::ticksPerMonth ] of my-bonds + (bank::targetBonds - bank::bonds) * world::defaultCoupon * world::ticksPerMonth let totalCost ( sum [job::salary] of my-jobs + bank::vacancies * bank::salary ) * world::ticksPerMonth set bank::stockProfitability ( totalIncome - totalCost ) / stocks end ; Calculate the amount of cash the bank needs to have to bank::CalculateTargetCash set bank::targetCash ( sum [job::salary] of my-jobs + bank::vacancies * bank::salary ) * world::bankReservesTargetTicks + sum [loan::GetDebtCost world::bankReservesTargetTicks ] of my-loans end to-report bank::PayCapital [ amount ] ; Pay in cash if we have enough if bank::cash >= amount [ set bank::cash bank::cash - amount report true ] ; There's not enough money report false end to bank::CloseBussiness [ payWorkers ] ; Recover all bond money ask my-bonds [ let agentId nobody let bankId nobody ifelse is-company? end1 or is-govern? end1 [ set agentId end1 set bankId end2 ] [ set agentId end2 set bankId end1 ] while [ bond::bondCount > 0 ] [ bond::RemoveBond let paid true ask agentId [ ifelse is-company? self [ set company::bonds company::bonds - 1 if not company::PayCapital world::bondFaceValue [ set paid false company::closeBussiness false ] ] [ if govern::cash < world::bondFaceValue [ govern::CentralBankRescue ] set govern::bonds govern::bonds - 1 set govern::cash govern::cash - world::bondFaceValue ] ] ask bankId ; Bank [ set bank::bonds bank::bonds - 1 if (paid) [ set bank::cash bank::cash + world::bondFaceValue ] set bank::nonCurrentAssets bank::nonCurrentAssets - world::bondFaceValue ] if bond::bondCount = 0 [die] ] ] ; Return loans ask my-loans [ ; Pay face values while [ loan::loanCount > 0 ] [ loan::RemoveLoan let paid false ask end2 [ if bank::cash > world::loanFaceValue [ set bank::cash bank::cash - world::loanFaceValue set bank::loans bank::loans - 1 set paid true ] ] if paid [ ask end1 [ set centralBank::M1 centralBank::M1 - world::loanFaceValue ] ] if loan::loanCount = 0 [die] ] ] ; Fire the workers and pay them what the company owes them ask my-jobs [ let lastSalary ifelse-value ( payWorkers ) [ world::Round2down( [bank::cash / bank::workers] of end2 )][0] ask end1 ; Person [ set person::cash person::cash + lastSalary set person::employed 0 ] ask end2 ; Company [ set bank::cash bank::cash - lastSalary set bank::workers bank::workers - 1 ] ] ; End all investment relationships and return the remainings of their investment ask my-investments [ let stocks investment::stocks let lastDividend ifelse-value (stocks < [bank::stocks] of end2 ) [ world::Round2down( stocks * [bank::cash / bank::stocks] of end2 ) ][ [bank::cash] of end2 ] ask end1 ; Person [ set person::cash person::cash + lastDividend set person::stocks person::stocks - stocks set person::targetStocks person::targetStocks - stocks if person::targetStocks < 0 [ set person::targetStocks 0 ] ] ask end2 ; Bank [ set bank::cash bank::cash - lastDividend set bank::stocks bank::stocks - stocks ] ] ; If the company was selected, deselect it if selection::selectedAgent = self [ let patchId selection::selectedPatch set selection::selectedPatch nobody set selection::selectedAgent nobody selection::selectPatch patchId ] ; Kill the company die end ; Calculate the bank's risk as the weighted average of the risk of its bonds to bank::CalculateRisk let riskAggregate 0 ifelse (bank::bonds > 0) [ ask my-bonds [ let risk 1 (ifelse (is-company? end1) [ set risk [company::risk] of end1 ] (is-company? end2) [ set risk [company::risk] of end2 ] (is-govern? end1) [ set risk [govern::risk] of end1 ] (is-govern? end2) [ set risk [govern::risk] of end2 ] ) set riskAggregate riskAggregate + bond::bondCount * risk ] set bank::risk riskAggregate / bank::bonds ] [ set bank::risk 1 ; If the bank has no bonds it has no risk ] end ; Shows information about the selected bank in the output control to bank::ShowInfo output-print ( word "Bank (id:" who ")" ) output-print ( word " Age : " world::Round2 bank::age ) output-print ( word " Cash: " world::Round2 bank::cash ) output-print ( word " Target Cash: " world::Round2 bank::targetCash ) output-print ( word " Non-current Assets: " world::Round2 bank::nonCurrentAssets ) output-print ( word " No. of Workers: " round bank::workers ) output-print ( word " No. of Vacancies: " round bank::vacancies ) output-print ( word " Salary: " world::Round2 bank::salary ) output-print ( word " Target Debt Ratio: " world::Round2 bank::targetDebtRatio ) output-print ( word " Stocks: " round bank::stocks ) output-print ( word " Stocks on sale: " round bank::stocksOnSale ) output-print ( word " Loans: " round bank::loans ) output-print ( word " Target Loans: " round bank::targetLoans ) output-print ( word " Bonds: " round bank::bonds ) output-print ( word " Target Bonds: " round bank::targetBonds ) output-print ( word " Labor Costs: " world::Round2 bank::last::laborCosts ) output-print ( word " Operating Profit: " world::Round2 bank::last::operatingProfit ) output-print ( word " Financial Income: " world::Round2 bank::last::financialIncome ) output-print ( word " Financial Expense: " world::Round2 bank::last::financialExpense ) output-print ( word " Profit Before Tax: " world::Round2 bank::last::profitBeforeTax ) output-print ( word " Result: " world::Round2 bank::last::result ) output-print ( word " Risk: " world::Round2 bank::risk ) output-print ( word " Target Risk: " world::Round2 bank::targetRisk ) output-print ( word " Stock profitability: " world::Round2 bank::stockProfitability ) end ; Make an initial distribution of loans and bonds to banks::Initialize let initialLoanOffer floor ( [centralBank::TargetM1 - centralBank::M1] of world::centralBankId / world::loanFaceValue ) ask companies with [ company::targetBonds > company::bonds] [ let bankId max-one-of banks with [bank::targetBonds > bank::bonds ] [bank::targetBonds - bank::bonds] let nBonds ifelse-value ( (company::targetBonds - company::bonds) <= [bank::targetBonds - bank::bonds] of bankId)[company::targetBonds - company::bonds][[bank::targetBonds - bank::bonds] of bankId] let nLoans ceiling ( nBonds * world::bondFaceValue / world::loanFaceValue ) if nLoans > initialLoanOffer [ set nLoans initialLoanOffer set nBonds floor( nLoans * world::loanFaceValue / world::bondFaceValue ) ] if nLoans > [bank::targetLoans - bank::loans] of bankId [ set nLoans [bank::targetLoans - bank::loans] of bankId set nBonds floor( nLoans * world::loanFaceValue / world::bondFaceValue ) ] if bankId != nobody and nBonds > 0 and nLoans > 0 [ set company::bonds company::bonds + nBonds set company::cash company::cash + nBonds * world::bondFaceValue company::DistributeAssets let agentRisk company::risk let companyCoupon company::coupon create-bond-with bankId [ bond::Create ] ask bond-with bankId [ bond::AddInitialBond nBonds companyCoupon ] ask bankId [ set bank::cash bank::cash - world::bondFaceValue * nBonds set bank::nonCurrentAssets bank::nonCurrentAssets + world::bondFaceValue * nBonds set bank::bonds bank::bonds + nBonds set bank::risk (bank::risk * (bank::bonds - nBonds) + agentRisk ) / bank::bonds ; Update the bank's risk set bank::loans bank::loans + nLoans set bank::cash bank::cash + nLoans * world::loanFaceValue create-loan-with world::centralBankId [ loan::Create ] ask loan-with world::centralBankId [ loan::AddInitialLoan nLoans ] ] ask world::centralBankId [ set centralBank::M1 centralBank::M1 + world::loanFaceValue * nLoans ] set initialLoanOffer initialLoanOffer - nLoans ] ] ask banks [ ; Update the target cash value bank::CalculateTargetCash ] ; Sort maturity by date because the program expects them to be sorted ask bonds [ set bond::maturities sort bond::maturities ] ask loans [ set loan::maturities sort loan::maturities ] end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; CENTRAL BANK MANAGEMENT ; ; Initializes a newly created central bank to centralbank::Create [ distributedCash initialTargetM1 ] set shape style::centralBankShape set color style::centralBankColor move-to patch 1 0 ;centralBank::loanOffer set centralBank::M1 distributedCash set centralBank::targetM1 initialTargetM1 centralBank::UpdateLoanOffer end ; Operational action of the centralbank to centralbank::OperationalAction centralBank::UpdateLoanOffer end ; Strategic action of the centralbank to centralbank::StrategicAction if ticks >= 60 ; Do not make strategic action until it can calculate the inflation rate [ let priceIndexT0 last but-last world::priceIndexValues let priceIndexT1 last world::priceIndexValues let priceIndexChange (priceIndexT1 - priceIndexT0) / priceIndexT0 let deviation priceIndexChange - world::monthlyInflationTarget ; The central bank is more likely to act the greater the deviation is let actionTreshhold ( ( random-float deviation ) - 0.005 ) * centralBank::M1 ( ifelse (abs deviation) < 0.005 [ ; The amount of money seems right, don't change it set centralBank::targetM1 centralBank::M1 ] ( deviation > 0 and centralBank::targetM1 >= centralBank::M1 - actionTreshhold) [ ;; Too much inflation, reduce the amount of money let newLoans ceiling( ( centralBank::M1 * world::centralBankPolicyFactor ) / world::loanFaceValue ) set centralBank::targetM1 centralBank::M1 - newLoans * world::loanFaceValue ] ( deviation < 0 and centralBank::targetM1 <= centralBank::M1 - actionTreshhold ) [ ;; Too few inflation, increase the amount of money let newLoans ceiling( ( centralBank::M1 * world::centralBankPolicyFactor ) / world::loanFaceValue ) set centralBank::targetM1 centralBank::M1 + newLoans * world::loanFaceValue ] ) ] end ; Monthly action of the centralbank to centralbank::MonthlyAction ; none end ; Update the loan offer for this tick considering the current M1 target and the loan maturities to centralBank::UpdateLoanOffer let nextTickM1 centralBank::M1 - ( sum [loan::GetDebtCost 1] of my-loans) let difference centralBank::targetM1 - nextTickM1 if-else difference > 0 [ set centralBank::loanOffer ceiling( difference / (world::loanFaceValue * world::centralBankPolicyMaturity ) ) ] [ set centralBank::loanOffer 0 ] end ; Shows information about the selected centralbank in the output control to centralbank::ShowInfo output-print ( word "Central Bank (id:" who ")" ) output-print ( word " M1 : " centralBank::M1 ) output-print ( word " Target M1 : " centralBank::targetM1 ) end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; PLOT & HISTOGRAM MANAGEMENT ; to charts::Initialize ; Classify management initialization set people::currentClassifyBy "" set companies::currentClassifyBy "" set banks::currentClassifyBy "" ; World variables initialization set world::goodsPriceAvg 1.20 ; Educated guess for the first month based on expected production costs, is needed for people to calculate their target reserves set world::goodsPriceMinCurrent world::floatMax set world::goodsPriceMaxCurrent 0 ; Variables containing the list of values for each economic variable set world::bankCountValues [] set world::coeRealValues [] set world::coeNominalValues [] set world::companyCountValues [] set world::consumptionNominalValues [] set world::consumptionRealValues [] set world::gdpNominalValues [] set world::gdpRealValues [] set world::goodsPriceAvgValues [] set world::goodsPriceMinValues [] set world::goodsPriceMaxValues [] set world::goodsProducedValues [] set world::goodsSoldValues [] set world::gosRealValues [] set world::gosNominalValues [] set world::governConsumptionTaxIncomeNominalValues [] set world::governCorporationTaxIncomeNominalValues [] set world::governFinancialExpenseValues [] set world::governIncomeNominalValues [] set world::governIncomeTaxIncomeNominalValues [] set world::governSalariesNominalValues [] set world::governUnemploymentBenefitExpensesNominalValues [] set world::investmentNominalValues [] set world::investmentRealValues [] set world::m1Values [] set world::m1TargetValues [] set world::priceIndexValues [] set world::publicExpenditureNominalValues [] set world::salaryAvgValues [] set world::salaryMaxValues [] set world::salaryMinValues [] set world::technologyValues [] set world::unemploymentValues [] ; Plot management initialization set plot1::bluePen::variableCurrent "" set plot1::greenPen::variableCurrent "" set plot1::pinkPen::variableCurrent "" set plot2::bluePen::variableCurrent "" set plot2::greenPen::variableCurrent "" set plot2::pinkPen::variableCurrent "" set plot3::bluePen::variableCurrent "" set plot3::greenPen::variableCurrent "" set plot3::pinkPen::variableCurrent "" set plot4::bluePen::variableCurrent "" set plot4::greenPen::variableCurrent "" set plot4::pinkPen::variableCurrent "" ; Set plot names set peoplePlot::name "People" set companyPlot::name "Companies" set bankPlot::name "Banks" set plot1::name "Plot 1" set plot2::name "Plot 2" set plot3::name "Plot 3" set plot4::name "Plot 4" end ; Updates the plot values to plots::Update let x floor( ticks / world::ticksPerMonth ) if plot1::bluePen::variableCurrent != " " [ set-current-plot plot1::name set-current-plot-pen "bluePen" plots::UpdatePlotLine x plot1::bluePen::variable ] if plot1::greenPen::variableCurrent != " " [ set-current-plot plot1::name set-current-plot-pen "greenPen" plots::UpdatePlotLine x plot1::greenPen::variable ] if plot1::pinkPen::variableCurrent != " " [ set-current-plot plot1::name set-current-plot-pen "pinkPen" plots::UpdatePlotLine x plot1::pinkPen::variable ] if plot2::bluePen::variableCurrent != " " [ set-current-plot plot2::name set-current-plot-pen "bluePen" plots::UpdatePlotLine x plot2::bluePen::variable ] if plot2::greenPen::variableCurrent != " " [ set-current-plot plot2::name set-current-plot-pen "greenPen" plots::UpdatePlotLine x plot2::greenPen::variable ] if plot2::pinkPen::variableCurrent != " " [ set-current-plot plot2::name set-current-plot-pen "pinkPen" plots::UpdatePlotLine x plot2::pinkPen::variable ] if plot3::bluePen::variableCurrent != " " [ set-current-plot plot3::name set-current-plot-pen "bluePen" plots::UpdatePlotLine x plot3::bluePen::variable ] if plot3::greenPen::variableCurrent != " " [ set-current-plot plot3::name set-current-plot-pen "greenPen" plots::UpdatePlotLine x plot3::greenPen::variable ] if plot3::pinkPen::variableCurrent != " " [ set-current-plot plot3::name set-current-plot-pen "pinkPen" plots::UpdatePlotLine x plot3::pinkPen::variable ] if plot4::bluePen::variableCurrent != " " [ set-current-plot plot4::name set-current-plot-pen "bluePen" plots::UpdatePlotLine x plot4::bluePen::variable ] if plot4::greenPen::variableCurrent != " " [ set-current-plot plot4::name set-current-plot-pen "greenPen" plots::UpdatePlotLine x plot4::greenPen::variable ] if plot4::pinkPen::variableCurrent != " " [ set-current-plot plot4::name set-current-plot-pen "pinkPen" plots::UpdatePlotLine x plot4::pinkPen::variable ] end ; Draws the last specified varaible value on the current plot with the current pen to plots::UpdatePlotLine [ x variable ] let valueList plots::GetValuesList variable plotxy x last valueList end ; Checks if any of the plots must be redrawn because the data to plot has changed to plots::Redraw if plot1::bluePen::variable != plot1::bluePen::variableCurrent [ set-current-plot plot1::name set-current-plot-pen "bluePen" set plot1::bluePen::variableCurrent plot1::bluePen::variable plots::DrawPlotLine plot1::bluePen::variable ] if plot1::greenPen::variable != plot1::greenPen::variableCurrent [ set-current-plot plot1::name set-current-plot-pen "greenPen" set plot1::greenPen::variableCurrent plot1::greenPen::variable plots::DrawPlotLine plot1::greenPen::variable ] if plot1::pinkPen::variable != plot1::pinkPen::variableCurrent [ set-current-plot plot1::name set-current-plot-pen "pinkPen" set plot1::pinkPen::variableCurrent plot1::pinkPen::variable plots::DrawPlotLine plot1::pinkPen::variable ] if plot2::bluePen::variable != plot2::bluePen::variableCurrent [ set-current-plot plot2::name set-current-plot-pen "bluePen" set plot2::bluePen::variableCurrent plot2::bluePen::variable plots::DrawPlotLine plot2::bluePen::variable ] if plot2::greenPen::variable != plot2::greenPen::variableCurrent [ set-current-plot plot2::name set-current-plot-pen "greenPen" set plot2::greenPen::variableCurrent plot2::greenPen::variable plots::DrawPlotLine plot2::greenPen::variable ] if plot2::pinkPen::variable != plot2::pinkPen::variableCurrent [ set-current-plot plot2::name set-current-plot-pen "pinkPen" set plot2::pinkPen::variableCurrent plot2::pinkPen::variable plots::DrawPlotLine plot2::pinkPen::variable ] if plot3::bluePen::variable != plot3::bluePen::variableCurrent [ set-current-plot plot3::name set-current-plot-pen "bluePen" set plot3::bluePen::variableCurrent plot3::bluePen::variable plots::DrawPlotLine plot3::bluePen::variable ] if plot3::greenPen::variable != plot3::greenPen::variableCurrent [ set-current-plot plot3::name set-current-plot-pen "greenPen" set plot3::greenPen::variableCurrent plot3::greenPen::variable plots::DrawPlotLine plot3::greenPen::variable ] if plot3::pinkPen::variable != plot3::pinkPen::variableCurrent [ set-current-plot plot3::name set-current-plot-pen "pinkPen" set plot3::pinkPen::variableCurrent plot3::pinkPen::variable plots::DrawPlotLine plot3::pinkPen::variable ] if plot4::bluePen::variable != plot4::bluePen::variableCurrent [ set-current-plot plot4::name set-current-plot-pen "bluePen" set plot4::bluePen::variableCurrent plot4::bluePen::variable plots::DrawPlotLine plot4::bluePen::variable ] if plot4::greenPen::variable != plot4::greenPen::variableCurrent [ set-current-plot plot4::name set-current-plot-pen "greenPen" set plot4::greenPen::variableCurrent plot4::greenPen::variable plots::DrawPlotLine plot4::greenPen::variable ] if plot4::pinkPen::variable != plot4::pinkPen::variableCurrent [ set-current-plot plot4::name set-current-plot-pen "pinkPen" set plot4::pinkPen::variableCurrent plot4::pinkPen::variable plots::DrawPlotLine plot4::pinkPen::variable ] end ; Draws the specified varaible values on the current plot with the current pen to plots::DrawPlotLine [ variable ] plot-pen-reset if variable != " " [ let valueList plots::GetValuesList variable let x 0 foreach valueList [ y -> plotxy x y set x x + 1 ] ] end ; Given a variable name returns the list that contains the value series of that variable to-report plots::GetValuesList [ variable ] if variable = "Bank Count" [ report world::bankCountValues ] if variable = "Compensation of employees - nominal" [ report world::coeRealValues ] if variable = "Compensation of employees - real" [ report world::coeNominalValues ] if variable = "Company Count" [ report world::companyCountValues ] if variable = "Consumption - nominal" [ report world::consumptionNominalValues ] if variable = "Consumption - real" [ report world::consumptionRealValues ] if variable = "GDP - nominal" [ report world::gdpNominalValues ] if variable = "GDP - real" [ report world::gdpRealValues ] if variable = "Goods Average price" [ report world::goodsPriceAvgValues ] if variable = "Goods Minimum price" [ report world::goodsPriceMinValues ] if variable = "Goods Maximum price" [ report world::goodsPriceMaxValues ] if variable = "Goods Produced" [ report world::goodsProducedValues ] if variable = "Goods Sold" [ report world::goodsSoldValues ] if variable = "Govern Consumption Tax Income" [ report world::governConsumptionTaxIncomeNominalValues ] if variable = "Govern Corporation Tax Income" [ report world::governCorporationTaxIncomeNominalValues ] if variable = "Govern Financial Expense" [ report world::governFinancialExpenseValues ] if variable = "Govern Income" [ report world::governIncomeNominalValues ] if variable = "Govern Income Tax Income" [ report world::governIncomeTaxIncomeNominalValues ] if variable = "Govern Salaries" [ report world::governSalariesNominalValues ] if variable = "Govern Unemployment Benefit Expenses"[ report world::governUnemploymentBenefitExpensesNominalValues ] if variable = "M1" [ report world::m1Values ] if variable = "M1 Target" [ report world::m1TargetValues ] if variable = "Gross Operating surplus - nominal" [ report world::gosNominalValues ] if variable = "Gross Operating surplus - real" [ report world::gosRealValues ] if variable = "Investment - nominal" [ report world::investmentNominalValues ] if variable = "Investment - real" [ report world::investmentRealValues ] if variable = "Price Index" [ report world::priceIndexValues ] if variable = "Public Expenditure" [ report world::publicExpenditureNominalValues ] if variable = "Salary Average" [ report world::salaryAvgValues ] if variable = "Salary Maximum" [ report world::salaryMaxValues ] if variable = "Salary Minimum" [ report world::salaryMinValues ] if variable = "Technology" [ report world::technologyValues ] if variable = "Unemployment" [ report world::unemploymentValues ] end ; Draws a line to mark an event on all the plots to plots::DrawEvent [ month ] set-current-plot plot1::name plots::DrawEventLine month set-current-plot plot2::name plots::DrawEventLine month set-current-plot plot3::name plots::DrawEventLine month set-current-plot plot4::name plots::DrawEventLine month end ; Draws a line to mark an event on the current plot to plots::DrawEventLine[ month ] create-temporary-plot-pen "eventPen" set-plot-pen-color red plot-pen-up plotxy month plot-y-min plot-pen-down plotxy month plot-y-max end ; Set the people histogram and agent color according to the selected attribute to people::Classify if ticks mod world::ticksPerMonth = world::ticksPerMonth - 1 or people::currentClassifyBy != people::classifyBy [ set-current-plot peoplePlot::name ifelse people::classifyBy = " " [ ask people [ set color style::personColor ] clear-plot ] [ let valueList [] if people::classifyBy = "Cash" [ set valueList [ person::cash ] of people ] if people::classifyBy = "Cash target" [ set valueList [ person::targetCash ] of people ] if people::classifyBy = "Color" [ set valueList [ person::color ] of people ] if people::classifyBy = "Consumed goods" [ set valueList [ person::last::consumedGoods ] of people ] if people::classifyBy = "Consumed goods value" [ set valueList [ person::last::consumedGoodsValue ] of people ] if people::classifyBy = "Employed" [ set valueList [ person::employed ] of people ] if people::classifyBy = "Investment income" [ set valueList [ person::last::investmentIncome ] of people ] if people::classifyBy = "Propensity to consume"[ set valueList [ person::propensityToConsume ] of people ] if people::classifyBy = "Stocks" [ set valueList [ person::stocks ] of people ] if people::classifyBy = "Stocks wanted" [ set valueList [ person::targetStocks ] of people ] if people::classifyBy = "Total income" [ set valueList [ person::last::workIncome + person::last::investmentIncome + person::last::transferIncome] of people ] if people::classifyBy = "Transfer income" [ set valueList [ person::last::transferIncome ] of people ] if people::classifyBy = "Work income" [ set valueList [ person::last::workIncome ] of people ] let minValue min valueList let maxValue max valueList let valueRange maxValue - minValue set maxValue maxValue + 0.1 ; Ensure top values appear in the histogram ask people [ let value 0 if people::classifyBy = "Cash" [ set value person::cash ] if people::classifyBy = "Cash target" [ set value person::targetCash ] if people::classifyBy = "Color" [ set value person::color ] if people::classifyBy = "Consumed goods" [ set value person::last::consumedGoods ] if people::classifyBy = "Consumed goods value" [ set value person::last::consumedGoodsValue ] if people::classifyBy = "Employed" [ set value person::employed ] if people::classifyBy = "Investment income" [ set value person::last::investmentIncome ] if people::classifyBy = "Propensity to consume"[ set value person::propensityToConsume ] if people::classifyBy = "Stocks" [ set value person::stocks] if people::classifyBy = "Stocks wanted" [ set value person::targetStocks] if people::classifyBy = "Total income" [ set value person::last::workIncome + person::last::investmentIncome + person::last::transferIncome] if people::classifyBy = "Transfer income" [ set value person::last::transferIncome] if people::classifyBy = "Work income" [ set value person::last::workIncome] ; Normalize the value and set it in the 0..255 range to color the agent if valueRange != 0 [ set value ( ( value - minValue ) / valueRange ) ] let iValue floor( value * 255 ) set color rgb ( 255 - iValue) iValue 0 ] set-plot-x-range world::round2(minValue) world::round2(maxValue) set-plot-y-range 0 count people set-histogram-num-bars 10 histogram valueList ] ] end ; Set the companies histogram and agent color according to the selected attribute to companies::Classify if ticks mod world::ticksPerMonth = world::ticksPerMonth - 1 or companies::currentClassifyBy != companies::classifyBy [ set-current-plot companyPlot::name ifelse companies::classifyBy = " " or count companies = 0 [ ask companies [ set color style::companyColor ] clear-plot ] [ let valueList [] if companies::classifyBy = "Age" [ set valueList [ company::age ] of companies ] if companies::classifyBy = "Bonds" [ set valueList [ company::bonds ] of companies ] if companies::classifyBy = "Bonds Target" [ set valueList [ company::targetBonds ] of companies ] if companies::classifyBy = "Cash" [ set valueList [ company::cash ] of companies ] if companies::classifyBy = "Cash Target" [ set valueList [ company::targetCash ] of companies ] if companies::classifyBy = "Color" [ set valueList [ company::color ] of companies ] if companies::classifyBy = "Coupon" [ set valueList [ company::lastCoupon ] of companies ] if companies::classifyBy = "Demand" [ set valueList [ company::last::demand ] of companies ] if companies::classifyBy = "Financial Expense" [ set valueList [ company::last::financialExpense ] of companies ] if companies::classifyBy = "Inventory" [ set valueList [ company::inventory ] of companies ] if companies::classifyBy = "Inventory Cost Per Unit"[ set valueList [ company::inventoryUnitaryValue ] of companies ] if companies::classifyBy = "Labor Costs" [ set valueList [ company::last::laborCosts ] of companies ] if companies::classifyBy = "Non-current Assets" [ set valueList [ company::nonCurrentAssets ] of companies ] if companies::classifyBy = "Operating Profit" [ set valueList [ company::last::operatingProfit ] of companies ] if companies::classifyBy = "Production" [ set valueList [ company::last::production ] of companies ] if companies::classifyBy = "Production Value" [ set valueList [ company::last::productionValue ] of companies ] if companies::classifyBy = "Profit Before Tax" [ set valueList [ company::last::profitBeforeTax ] of companies ] if companies::classifyBy = "Result" [ set valueList [ company::last::result ] of companies ] if companies::classifyBy = "Risk" [ set valueList [ company::risk ] of companies ] if companies::classifyBy = "Salary" [ set valueList [ company::salary ] of companies ] if companies::classifyBy = "Sale Price" [ set valueList [ company::salePrice ] of companies ] if companies::classifyBy = "Sales" [ set valueList [ company::last::sales ] of companies ] if companies::classifyBy = "Sales Value" [ set valueList [ company::last::salesValue ] of companies ] if companies::classifyBy = "Stock Profitability" [ set valueList [ company::stockProfitability ] of companies ] if companies::classifyBy = "Stocks" [ set valueList [ company::stocks ] of companies ] if companies::classifyBy = "Stocks On Sale" [ set valueList [ company::stocksOnSale ] of companies ] if companies::classifyBy = "Target Debt Ratio" [ set valueList [ company::targetDebtRatio ] of companies ] if companies::classifyBy = "Vacancies" [ set valueList [ company::vacancies ] of companies ] if companies::classifyBy = "Workers" [ set valueList [ company::workers ] of companies ] let minValue min valueList let maxValue max valueList let valueRange maxValue - minValue set maxValue maxValue + 0.1 ; Ensure top values appear in the histogram ask companies [ let value 0 if companies::classifyBy = "Age" [ set value company::age ] if companies::classifyBy = "Bonds" [ set value company::bonds ] if companies::classifyBy = "Bonds Target" [ set value company::targetBonds ] if companies::classifyBy = "Cash" [ set value company::cash ] if companies::classifyBy = "Cash Target" [ set value company::targetCash ] if companies::classifyBy = "Color" [ set value company::color ] if companies::classifyBy = "Coupon" [ set value company::lastCoupon ] if companies::classifyBy = "Demand" [ set value company::last::demand ] if companies::classifyBy = "Financial Expense" [ set value company::last::financialExpense ] if companies::classifyBy = "Inventory" [ set value company::inventory ] if companies::classifyBy = "Inventory Cost Per Unit"[ set value company::inventoryUnitaryValue ] if companies::classifyBy = "Labor Costs" [ set value company::last::laborCosts ] if companies::classifyBy = "Non-current Assets" [ set value company::nonCurrentAssets ] if companies::classifyBy = "Operating Profit" [ set value company::last::operatingProfit ] if companies::classifyBy = "Production" [ set value company::last::production ] if companies::classifyBy = "Production Value" [ set value company::last::productionValue ] if companies::classifyBy = "Profit Before Tax" [ set value company::last::profitBeforeTax ] if companies::classifyBy = "Result" [ set value company::last::result ] if companies::classifyBy = "Risk" [ set value company::risk ] if companies::classifyBy = "Salary" [ set value company::salary ] if companies::classifyBy = "Sale Price" [ set value company::salePrice ] if companies::classifyBy = "Sales" [ set value company::last::sales ] if companies::classifyBy = "Sales Value" [ set value company::last::salesValue ] if companies::classifyBy = "Stock Profitability" [ set value company::stockProfitability ] if companies::classifyBy = "Stocks" [ set value company::stocks ] if companies::classifyBy = "Stocks On Sale" [ set value company::stocksOnSale ] if companies::classifyBy = "Target Debt Ratio" [ set value company::targetDebtRatio ] if companies::classifyBy = "Vacancies" [ set value company::vacancies ] if companies::classifyBy = "Workers" [ set value company::workers ] ; Normalize the value and set it in the 0..255 range to color the agent ifelse valueRange != 0 [ set value ( ( value - minValue ) / valueRange ) ] [ set value value - minValue ] let iValue floor( value * 255 ) set color rgb ( 255 - iValue) iValue 0 ] set-plot-x-range world::round2(minValue) world::round2(maxValue) set-plot-y-range 0 count companies set-histogram-num-bars 10 histogram valueList ] ] end ; Set the banks histogram and agent color according to the selected attribute to banks::Classify if ticks mod world::ticksPerMonth = world::ticksPerMonth - 1 or banks::currentClassifyBy != banks::classifyBy [ set-current-plot bankPlot::name ifelse banks::classifyBy = " " or count banks = 0 [ ask banks [ set color style::bankColor ] clear-plot ] [ let valueList [] if banks::classifyBy = "Age" [ set valueList [ bank::age ] of banks ] if banks::classifyBy = "Bonds" [ set valueList [ bank::bonds ] of banks ] if banks::classifyBy = "Bonds Target" [ set valueList [ bank::targetBonds ] of banks ] if banks::classifyBy = "Cash" [ set valueList [ bank::cash ] of banks ] if banks::classifyBy = "Cash Target" [ set valueList [ bank::targetCash ] of banks ] if banks::classifyBy = "Financial Expense" [ set valueList [ bank::last::financialExpense ] of banks ] if banks::classifyBy = "Financial Income" [ set valueList [ bank::last::financialIncome ] of banks ] if banks::classifyBy = "Labor Costs" [ set valueList [ bank::last::laborCosts ] of banks ] if banks::classifyBy = "Loans" [ set valueList [ bank::loans ] of banks ] if banks::classifyBy = "Loans Target" [ set valueList [ bank::targetLoans ] of banks ] if banks::classifyBy = "Non-current Assets" [ set valueList [ bank::nonCurrentAssets ] of banks ] if banks::classifyBy = "Operating Profit" [ set valueList [ bank::last::operatingProfit ] of banks ] if banks::classifyBy = "Profit Before Tax" [ set valueList [ bank::last::profitBeforeTax ] of banks ] if banks::classifyBy = "Result" [ set valueList [ bank::last::result ] of banks ] if banks::classifyBy = "Risk" [ set valueList [ bank::risk ] of banks ] if banks::classifyBy = "Risk Target" [ set valueList [ bank::targetRisk ] of banks ] if banks::classifyBy = "Salary" [ set valueList [ bank::salary ] of banks ] if banks::classifyBy = "Stocks" [ set valueList [ bank::stocks ] of banks ] if banks::classifyBy = "Stock Profitability" [ set valueList [ bank::stockProfitability ] of banks ] if banks::classifyBy = "Stocks On Sale" [ set valueList [ bank::stocksOnSale ] of banks ] if banks::classifyBy = "Target Debt Ratio" [ set valueList [ bank::targetDebtRatio ] of banks ] if banks::classifyBy = "Vacancies" [ set valueList [ bank::vacancies ] of banks ] if banks::classifyBy = "Workers" [ set valueList [ bank::workers ] of banks ] let minValue min valueList let maxValue max valueList let valueRange maxValue - minValue set maxValue maxValue + 0.1 ; Ensure top values appear in the histogram ask banks [ let value 0 if banks::classifyBy = "Age" [ set value bank::age ] if banks::classifyBy = "Bonds" [ set value bank::bonds ] if banks::classifyBy = "Bonds Target" [ set value bank::targetBonds ] if banks::classifyBy = "Cash" [ set value bank::cash ] if banks::classifyBy = "Cash Target" [ set value bank::targetCash ] if banks::classifyBy = "Financial Expense" [ set value bank::last::financialExpense ] if banks::classifyBy = "Financial Income" [ set value bank::last::financialIncome ] if banks::classifyBy = "Labor Costs" [ set value bank::last::laborCosts ] if banks::classifyBy = "Loans" [ set value bank::loans ] if banks::classifyBy = "Loans Target" [ set value bank::targetLoans ] if banks::classifyBy = "Non-current Assets" [ set value bank::nonCurrentAssets ] if banks::classifyBy = "Operating Profit" [ set value bank::last::operatingProfit ] if banks::classifyBy = "Profit Before Tax" [ set value bank::last::profitBeforeTax ] if banks::classifyBy = "Result" [ set value bank::last::result ] if banks::classifyBy = "Risk" [ set value bank::risk ] if banks::classifyBy = "Risk Target" [ set value bank::targetRisk ] if banks::classifyBy = "Salary" [ set value bank::salary ] if banks::classifyBy = "Stocks" [ set value bank::stocks ] if banks::classifyBy = "Stock Profitability" [ set value bank::stockProfitability ] if banks::classifyBy = "Stocks On Sale" [ set value bank::stocksOnSale ] if banks::classifyBy = "Target Debt Ratio" [ set value bank::targetDebtRatio ] if banks::classifyBy = "Vacancies" [ set value bank::vacancies ] if banks::classifyBy = "Workers" [ set value bank::workers ] ; Normalize the value and set it in the 0..255 range to color the agent ifelse valueRange != 0 [ set value ( ( value - minValue ) / valueRange ) ] [ set value value - minValue ] let iValue floor( value * 255 ) set color rgb ( 255 - iValue) iValue 0 ] set-plot-x-range world::round2(minValue) world::round2(maxValue) set-plot-y-range 0 count banks set-histogram-num-bars 10 histogram valueList ] ] end ;;;;;;;;;;;;;;;;;:;;;;;:;:;;;:::;:;:;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; SELECTION MANAGEMENT ; to selection::Initialize ; Selection management initialization set selection::selectedPatch nobody set selection::selectedAgent nobody set selection::currentPatch nobody set selection::interactionRadius 0 set selection::currentShowConsumptions selection::showConsumptions set selection::currentShowJobs selection::showJobs set selection::currentShowInvestments selection::showInvestments set selection::currentShowBonds selection::showBonds set selection::currentShowLoans selection::showLoans set selection::colors::selected white set selection::colors::mouseOver gray set selection::colors::selectedRadious rgb 97 103 116 ; dark gray set selection::colors::notSelected black end ; Handles when the user clicks on a patch to select or deselect it. It also highlights the patch where the mouse is over. to selection::MouseSelect [ updateOnTicks ] ; Display where the mouse is selection::MouseOver ; Shows or hides the agent relationships when the user clicks on the switch selection::UpdateRelationshipsView ; Select a patch if the user clicks on it ifelse mouse-down? [ let previousSelectedPatch selection::selectedPatch while [mouse-down?] [ selection::MouseOver ] if selection::currentPatch != nobody [ ifelse selection::currentPatch != selection::selectedPatch [ ; select the current patch set selection::selectedPatch selection::currentPatch set selection::selectedAgent one-of turtles-on selection::selectedPatch ] [ ; Selecting the currently selected patch -> deselect set selection::selectedPatch nobody set selection::selectedAgent nobody ] ] selection::SelectPatch previousSelectedPatch ] [ ; Update the selection at least every month if updateOnTicks and ticks mod world::ticksPerMonth = world::ticksPerMonth - 1 [ selection::SelectPatch nobody ] ] end ; Shows the patch where the mouse is currently over in gray and updates selection::currentPatch global variable to selection::MouseOver let previousCurrentPatch selection::currentPatch ifelse mouse-inside? [ set selection::currentPatch patch mouse-xcor mouse-ycor ] [ set selection::currentPatch nobody ] ; check if the previousCurrentPatch is in the interaction area of the currently selected patch let isInRadious false if selection::interactionRadius > 0 and previousCurrentPatch != nobody and selection::selectedPatch != nobody [ ask previousCurrentPatch [ set isInRadious distance selection::selectedPatch <= selection::interactionRadius ] ] if previousCurrentPatch != nobody and previousCurrentPatch != selection::currentPatch and previousCurrentPatch != selection::selectedPatch [ ask previousCurrentPatch [ set pcolor ifelse-value (isInRadious) [selection::colors::selectedRadious] [ selection::colors::notSelected ] ] ] if selection::currentPatch != nobody and selection::currentPatch != selection::selectedPatch [ ask selection::currentPatch [ set pcolor selection::colors::mouseOver ] ] end ; Given a patch shows information about itself and the agents inside to the output control to selection::SelectPatch [ previousSelectedPatch ] clear-output ask Consumptions with [ not hidden? ] [ set hidden? true ] ask Jobs with [ not hidden? ] [ set hidden? true ] ask Investments with [ not hidden? ] [ set hidden? true ] ask Bonds with [ not hidden? ] [ set hidden? true ] ask Loans with [ not hidden? ] [ set hidden? true ] ; Paint the previously selected patch back to its original value and erase its interaction area if previousSelectedPatch != nobody and previousSelectedPatch != selection::selectedPatch [ ask previousSelectedPatch [ set pcolor ifelse-value (previousSelectedPatch != selection::currentPatch) [ selection::colors::notSelected ] [ selection::colors::mouseOver ] ] if selection::interactionRadius > 0 [ ask patches with [ distance previousSelectedPatch <= selection::interactionRadius and self != previousSelectedPatch ] [ set pcolor ifelse-value (self != selection::currentPatch) [ selection::colors::notSelected ] [ selection::colors::mouseOver ] ] ] ] ; Paint the selected patch as selected if selection::selectedPatch != nobody [ ask selection::selectedPatch [ set pcolor selection::colors::selected ] ] if selection::selectedPatch != nobody [ output-print ( word "Patch " ( [pxcor] of selection::selectedPatch ) " " [pycor] of selection::selectedPatch ) set selection::interactionRadius 0 if selection::selectedAgent != nobody [ ; Show information about the person in this patch if is-person? selection::selectedAgent [ ask selection::selectedAgent [ person::ShowInfo ] set selection::interactionRadius world::interactionRadius ] ; Show information about the company in this patch if is-company? selection::selectedAgent [ ask selection::selectedAgent [ company::ShowInfo ] set selection::interactionRadius world::interactionRadius ] ; Show information about the company in this patch if is-govern? selection::selectedAgent [ ask selection::selectedAgent [ govern::ShowInfo ] set selection::interactionRadius world::governInteractionRadius ] ; Show information about the company in this patch if is-bank? selection::selectedAgent [ ask selection::selectedAgent [ bank::ShowInfo ] set selection::interactionRadius world::interactionRadius ] ; Show information about the company in this patch if is-centralBank? selection::selectedAgent [ ask selection::selectedAgent [ centralBank::ShowInfo ] set selection::interactionRadius 0 ] ; Paint the distance at which the agent can interact if selection::interactionRadius > 0 [ ask patches with [ distance selection::selectedPatch <= selection::interactionRadius and self != selection::selectedPatch ] [ set pcolor selection::colors::selectedRadious ] ] ; Show its relationships ask selection::selectedAgent [ if selection::currentShowConsumptions [ ask my-Consumptions [ set hidden? false ] ] if selection::currentShowJobs [ ask my-Jobs [ set hidden? false ] ] if selection::currentShowInvestments [ ask my-Investments [ set hidden? false ] ] if selection::currentShowBonds [ ask my-Bonds [ set hidden? false ] ] if selection::currentShowLoans [ ask my-Loans [ set hidden? false ] ] ] ] ] end ; Checks if a switch has changed and displays the relationships accordingly to selection::UpdateRelationshipsView if selection::currentShowConsumptions != selection::ShowConsumptions [ ifelse selection::ShowConsumptions [ ; show consumptions for the selected patch (if any) if selection::selectedAgent != nobody [ ask selection::selectedAgent [ ask my-Consumptions [ set hidden? false ] ] ] ] [ ; Hide all the consumptions ask Consumptions with [ not hidden? ] [ set hidden? true ] ] set selection::currentShowConsumptions selection::ShowConsumptions ] if selection::currentShowJobs != selection::ShowJobs [ ifelse selection::ShowJobs [ ; show jobs for the selected patch (if any) if selection::selectedAgent != nobody [ ask selection::selectedAgent [ ask my-Jobs [ set hidden? false ] ] ] ] [ ; Hide all the jobs ask Jobs with [ not hidden? ] [ set hidden? true ] ] set selection::currentShowJobs selection::ShowJobs ] if selection::currentShowInvestments != selection::ShowInvestments [ ifelse selection::ShowInvestments [ ; show investements for the selected patch (if any) if selection::selectedAgent != nobody [ ask selection::selectedAgent [ ask my-Investments [ set hidden? false ] ] ] ] [ ; Hide all the investements ask Investments with [ not hidden? ] [ set hidden? true ] ] set selection::currentShowInvestments selection::ShowInvestments ] if selection::currentShowBonds != selection::showBonds [ ifelse selection::showBonds [ ; show investements for the selected patch (if any) if selection::selectedAgent != nobody [ ask selection::selectedAgent [ ask my-Bonds [ set hidden? false ] ] ] ] [ ; Hide all the bonds ask Bonds with [ not hidden? ] [ set hidden? true ] ] set selection::currentShowBonds selection::showBonds ] if selection::currentShowLoans != selection::showLoans [ ifelse selection::showLoans [ ; show investements for the selected patch (if any) if selection::selectedAgent != nobody [ ask selection::selectedAgent [ ask my-Loans [ set hidden? false ] ] ] ] [ ; Hide all the loans ask Loans with [ not hidden? ] [ set hidden? true ] ] set selection::currentShowLoans selection::showLoans ] end
There is only one version of this model, created over 3 years ago by Ander G.
This model does not have any ancestors.
This model does not have any descendants.
Per Hung Yap
Unable to extract file
Hi, I'm having some issues with the file extraction. Anyone else have this problem?
Posted about 1 month ago