Moral Markets
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
"Moral Markets" is an agent-based computational approach to The Adam Smith Problem. It combines an original simulation of norm formation, based on ideas presented in Adam Smith's "Theory of Moral Sentiments," with a simple economic process adapted from Iain Weaver's "Sugarscape" (2009 NetLogo model).
HOW TO USE IT
Buttons:
Standard “setup” and “go” buttons.
Sliders:
“sugar-reap-rate”: controls base amount of “sugar” turtles gather
“spice-reap-rate”: controls base amount of “spice” turtles gather
“specialization”: coefficient that controls “reap-rate.” When specialization is set to zero, it has no effect, and the turtles gather according to their reap rate. But when set above zero, sugar gatherers will gather more sugar when their color is below 70 and spice gatherers will gather more when their color is above 70. This creates an “incentive” for turtles to develop colors away from the mean.
“initial-self-command”: normally distributes “self command” around mean value for new turtles. The higher this is set, the more like the turtles will assimilate.
“initial-tolerance”: normally distributes “tolerance” around mean value for new turtles
“norm-radius”: This controls the radius that each patch looks to when establishing the local norm
“policing-level”: the controls how willing turtles are to enforce norms outside their own social status. If the other turtle’s status is further apart than the “policing level,” then they will still be willing to do business. So, if it’s set to 4, status 5 turtles will do business with status 1 turtles, but turtles of more proximate status will refuse to do business.
Switches:
“education?”: when turned on, newly hatched turtles will inherit (with some randomization) self-command, tolerance, and initial-color from their parents
“clustering?”: when turned on, turtles will find a “friend” and follow it. Note that this only works when “moralizing?” is also turned on
“discriminating?”: when turned on, turtles trade according to a different trading rule. They will only trade with turtles who have a color within their “tolerance” range.
“exceptions?”: when turned on, turtles will not discriminate against turtles of their own profession, or of turtles of sufficiently different status. (See the slider “policing level”)
“trading?”: when turned on, turtles will farm and trade.
“moralizing?” when turned on, turtles will evaluate each other and assimilate.
Monitors:
“% Socialized”: this shows the percent of turtles who are adopting the color of their “impartial spectator.”
“Tolerance”: the mean “tolerance” of turtles. May change as turtles evolve.
“Self-Command”: mean “self-command” of turtles. Will also often change.
“Liquidity”: total trade value divided by the sum of turtle wealth. This is a loose but very good measure of how well the marketplace is functioning.
“Trades Per Turtles”: another good measure for showing how well the market is functioning.
Plots:
“Welfare of Growers”: shows the wealth distribution of each profession
“Price”: shows relative prices of sugar and spice
“Moral Deviance”: measures the standard deviation of colors (see also the monitors on the side)
“Mean color”: measures the mean values of colors (see also the monitors on the side)
“Population”: count of turtles by profession
“Wealth Per Capita”: current wealth by profession
THINGS TO TRY
Begin by running it first with only the "moralizing?" switch turned on. Turn on: "moralizing?" but turn off "trading?" (if trading? is off, discriminating?, exceptions?, and "education?" will have no effect). Play around with the "clustering?" switch, as well as the "norm-radius," "self-command," and "tolerance" variables. Play with this until you have a sense of how the "moral" functions work.
Then, try only the economics. Turn on "trading?" and turn off "moralizing?" Now, play around with the reap rates and specialization to see how the market performs (and how the colors evolve) in the absence of social norms.
Then, combine them. Look for how different moral settings affect economic behavior, and vice versa.
SUBMODELS
Local Norm Update Rule
We understand the moral subject, as imagined by Smith, to exist as three closely related, commensurable variables. The first represents the subject’s internally held desires or emotions: their true states as they might exist in the absence of social exchange and moral surveillance. We represent this as a single variable, randomly assigned between 0 and 140. These values correspond to NetLogo’s color scheme, and so we use the color of the turtle ( C’ ) to represent the subject’s natural state. At initialization, each turtle’s color is set to this randomly assigned number, and that number is stored as a permanently held variable, designated “initial-color” in the NetLogo code.
However, as Smith makes clear, subjects’ moral self-presentation does not always represent their internally held desires. As they interact with one another, people gradually become socialized, developing a sense (also internally held) of how to act with propriety in any context. This internal watchdog, the “impartial spectator,” is continually updated based on the subjects’ experience: we represent this as a variable ( K ), also in the bounded range of 0 to 140, designated “impartial-spectator” in the NetLogo code.
At any given time, individuals either follow the dictates of their impartial spectator or they fail to do so. We thus create a third variable to represent the subject’s moral self-presentation: How do they behave? How do they comport themselves in a context of moral surveillance? We represent this moral decision-making as a toggling of the turtles’ color C, which at any given moment of the simulation will be set either to their K or C’ values. When turtles are behaving according to their understanding of how turtles should behave, they display the value of their “impartial-spectator” variable and so appear as color K. However, if the gap between their internally held desires and their local context becomes too great, the impartial spectator procedure breaks down and the turtles revert to their base state, the “initial-color” variable C.
The operation of social norms is thus represented as shifting colors in the NetLogo stage. The field of interaction, called “patches,” updates its background color to match the colors of the turtles, thus changes in shared norms and expectations can be visualized in aggregate as shifting colors in the background of the simulation. As turtles develop a commonly shared set of ideas about what the “right” color to be is -- that is, as their “impartial spectator” variables regress toward the mean -- the patches appear as increasingly uniform colors. However, that uniformity is never perfect, always shifting, and always carries a latent possibility for sudden, radical shifts. The color of patches (“pcolor”) represents the aggregate norm held by local turtles. In its simplest formation, the local norm L within any given radius is a simple average of the colors of turtles within that radius, such that:
Lr =Cr
However, in the model itself this value is subject to one additional computation. Smith makes it clear that people have a tendency to defer to the moral self-presentations of wealthy, high-status individuals, therefore we use a weighted majority rule to determine the local norm. (In the basic TMS model, the status is a value assigned randomly at initialization. When the model is combined with WN, as we shall see, it changes with turtles’ changing wealth totals.) To account for the greater impact of high-status individuals, the local norm is calculated in a slightly more complicated way, first adjusting their “display-strength” ( D ) as a simple function of their color combined with their status ( S ), such that
D= CS
The local norm that turtles encounter in any given situation can thus be given as the average display strength divided by the average status:
Lr = DrSr
What this function does is, essentially, take status into consideration when calculating the average color, then divide it out. Let me give a hypothetical example: suppose three turtles exist together within a common radius. One is a high status individual (S = 5) and the other two are low-status individuals ( S = 1). The high-status individual is red ( C = 15 ) and the low-status individuals are blue ( C = 105). If a straight average was taken of their colors, the local norm would be designated such that
L = ( 15 + 105 + 105) / 3 = 75.
Under a simple average, local norm would be assigned a value of 75, and the patch would be updated to display the color turquoise (much closer to blue than red). Adjusted for display strength, the calculation is performed as follows:
D1 = ( 15 * 5 ) = 75 D2 = (105 * 1 ) = 105 D3 = ( 105 * 1 ) = 105 Average display strength = 95 Average status = ( 5 + 1 + 1 ) / 3 = 2.333
Local norm = 95 / 2.333 = 40.714 In the second, more complicate calculation, the outcome is weighted toward the higher-status individual, and the patch is updated to display the color 40.7, which sits between yellow and red in NetLogo’s color swatch and is visually indistinguishable from black.
Putting these functions together, the local-norm update rule can be written out as follows:
Lr = {C1S1, C2S2, … CrSr} Sr
Impartial Spectator Update Rule
As stated above, each agent carries an “impartial-spectator” variable that updates at each tick. The “impartial-spectator” variable is the average of every local norm ( Lr ) each turtle encounters during its lifetime.
Kt+1=(Lr + KtA)A + 1
Because of the way this function is designed, agents begin their lives with very fluid conceptions of propriety but gradually harden over time. With each tick, the current local norm is incorporated into a rolling average calculated against the agent’s age. Thus, the “impartial-spectator” is an average of averages -- what Smith refers to as the “Golden Mean” (borrowing a term from Aristotle but using it in a sociological sense of shared norms, rather than Aristotle’s understanding of virtue as the point equidistant between complementary vices). In the NetLogo code, this functions as turtles comparing their own color to the color of their local patch. This function basically has them keep tabs on every color they’ve encountered and add it into to their experienced average.
Agent Self-Presentation Rule
Following rule for calculating the difficulty experienced by agents as they conform to local norms: Smith calls this the exercise of self-command. Because the local norms are expressed as an average of nearby agents’ color (adjusted for their status), the difficulty of exercising self-command can be expressed simply as the difference between the local norms and internally felt desire, such that
P= Lr - C'
where P is the pain the agent feels by experiencing the disjunction between local norms, Lr , and its own initial color state, C'. The level of pain is compared to what Smith calls “self-command,” the willingness to endure personal discomfort in the service of conformity. We therefore introduce the following rule:
If P > M, the impartial spectator fails.
CREDITS AND REFERENCES
Moral Markets (2014 NetLogo model) by Michael Gavin, University of South Carolina
Iain Weaver, Sugarscape (NetLogo model, 2009)
Comments and Questions
;; This version current draft as of June 12, 2014 ;; ;; breed [agents agent] undirected-link-breed [trades trade] ;; economic variables borrowed from "SugarScape" agents-own [ profession ;; 1 = sugar grower and 0 = spice grower sugar spice sugarMetabolism spiceMetabolism MRS foresight welfare display-strength status initial-color impartial-spectator self-command tolerance friend ;; "friend" controls the "clustering" variable age ] trades-own [sugarAmount spiceAmount price] patches-own [ countdown harvest-ready ] globals [ showLinks? grass-regrowth-time ;; rather than use a slider bar, I just set this to 50. If set much lower, the grass grows back quickly and the populations get so big the simulation slows down; mucher higher, all the turtles die. total-sugar-production total-spice-production total-production ] to setup ca set grass-regrowth-time 50 set showLinks? true ask patches [ set harvest-ready true set countdown random grass-regrowth-time set pcolor random 140 ] create-agents 200 [ setxy random-xcor random-ycor set profession one-of [1 0] set color random 140 set initial-color color set impartial-spectator random 140 set age random 100 set self-command random-normal initial-self-command 10 set tolerance random-normal initial-tolerance 3 set sugar 100 set spice 100 set sugarMetabolism 1 + random 2 set spiceMetabolism 1 + random 2 set foresight random 4 set MRS 1 if not trading? [ set status one-of [ 1 1 1 1 1 2 2 2 2 3 3 3 4 4 5 ] ] set friend one-of turtles ] reset-ticks end to go ask agents [ move ] if trading? [ ask agents [ set-welfareMRS eat farm ifelse discriminating? [ ifelse exceptions? [ trade-with-prejudice-with-exceptions ] [ trade-with-prejudice ] ] [ trade-without-prejudice ] reproduce ] ask patches [ grow ] ] if moralizing? [ ask agents [ update-impartial-spectator present-color make-friends ] ask patches [ display-social-norm ] ] if count agents < 2 [ stop ] ; if ticks = 3500 [ stop ] update-globals diffuse pcolor 1 tick end to move if trading? [ carefully [ set heading [heading] of turtles-here ] [] ] if clustering? [ carefully [ set heading [heading] of friend ] [] ] rt random 20 lt random 20 fd 1 set age age + 1 end ;; MORALIZING PROCEDURES ;; when a group of turtles meets, they change the color of the patch to display-social-norm let community turtles in-radius norm-radius if any? community [ set pcolor ( sum [display-strength] of community / sum [status] of community ) ] end ;; to update-impartial-spectator set impartial-spectator ( [pcolor] of patch-here + (impartial-spectator * age) ) / ( age + 1 ) set age age + 1 if trading? [ set-status ] set display-strength color * status end to present-color ifelse abs (pcolor - initial-color) > self-command [set color initial-color ] [ set color impartial-spectator ] end to make-friends let same-neighbors nobody set same-neighbors other turtles-here with [ abs (color - [color] of myself) < tolerance ] if any? same-neighbors [ set friend one-of same-neighbors ] end ;; TRADING PROCEDURES ;; ;; turtles eat. if they run out of food they die. to eat set sugar sugar - sugarMetabolism set spice spice - spiceMetabolism if sugar <= 0 [ die ] if spice <= 0 [ die ] end ;; if a patch is ready for harvest, all turtles on it will reap equally according to their profession to farm if [harvest-ready] of patch-here = true [ if [profession] of self = 1 [ set sugar sugar + sugar-reap-rate * ( 1 + ( (70 - color) / 140 * specialization ) ) set total-sugar-production total-sugar-production + sugar-reap-rate ] if [profession] of self = 0 [ set spice spice + spice-reap-rate * ( 1 + ( (color - 70) / 140 * specialization ) ) set total-spice-production total-spice-production + spice-reap-rate ] ask patch-here [ set harvest-ready false set countdown grass-regrowth-time] ] end ;; turtles split themselves in half to reproduce if random-float 100 < 2 [ set sugar ( sugar / 2 ) set spice ( spice / 2 ) hatch 1 [ set age 0 ifelse education? [ set tolerance [tolerance] of myself + random 2 - random 2 set self-command [self-command] of myself + random 2 - random 2 set initial-color [initial-color] of myself + random 20 - random 20 ] [ set profession one-of [ 0 1 ] set color random 140 set initial-color color set impartial-spectator random 140 set self-command random-normal initial-self-command 10 set tolerance random-normal initial-tolerance 3 ] rt random 360 fd 1 ] ] end ;; turtles divide themselves by caste (inheritable) to set-status if welfare > mean [ welfare ] of turtles [ set status 3 ] if welfare > mean [ welfare ] of turtles * 2 [ set status 4 ] if welfare > mean [ welfare ] of turtles * 5 [ set status 5 ] if welfare <= mean [ welfare ] of turtles [ set status 2 ] if welfare <= mean [ welfare ] of turtles / 2 [ set status 1 ] end ;; trade rule to trade-with-prejudice-with-exceptions let p 0 let a self let as [] let tSugar 0 let tSpice 0 let tsSugar 0 let tsSpice 0 let tWelfare 0 let tsWelfare 0 let x 0 let y 0 let traded? true ask neighbors4 [ ask agents-here [set as fput self as] ] if empty? as [stop] while [traded? = true] [ set traded? false set as sort-by [random 2 = 0] as foreach as [ if [MRS] of ? != [MRS] of a and ( abs ( [color] of ? - [impartial-spectator] of a ) < tolerance or abs ([status] of ? - [status] of a) >= policing-level or [profession] of ? = [profession] of a ) ; Check only agents with unequal MRS, similar color or unequal status [ set x ([MRS] of a < [MRS] of ?) ; Record which MRS is initially higher set p sqrt([MRS] of a * [MRS] of ?) ; Set a price ifelse p >= 1 [ ifelse [MRS] of a < [MRS] of ? [ set tSugar [sugar] of a - 1 set tSpice [spice] of a + p set tsSugar [sugar] of ? + 1 set tsSpice [spice] of ? - p ] [ set tSugar [sugar] of a + 1 set tSpice [spice] of a - p set tsSugar [sugar] of ? - 1 set tsSpice [spice] of ? + p ] ] [ ifelse [MRS] of a < [MRS] of ? [ set tSugar [sugar] of a - (1 / p) set tSpice [spice] of a + 1 set tsSugar [sugar] of ? + (1 / p) set tsSpice [spice] of ? - 1 ] [ set tSugar [sugar] of a + (1 / p) set tSpice [spice] of a - 1 set tsSugar [sugar] of ? - (1 / p) set tsSpice [spice] of ? + 1 ] ] if tSugar > 0 and tSpice > 0 and tsSugar > 0 and tsSpice > 0 [ set y (find-MRS tSugar [sugarMetabolism] of a tSpice [spiceMetabolism] of a [foresight] of a) < (find-MRS tsSugar [sugarMetabolism] of ? tsSpice [spiceMetabolism] of ? [foresight] of ?) ; Record which MRS is now higher set tWelfare find-welfare tSugar [sugarMetabolism] of a tSpice [spiceMetabolism] of a [foresight] of a set tsWelfare find-welfare tsSugar [sugarMetabolism] of ? tsSpice [spiceMetabolism] of ? [foresight] of ? if x = y and tWelfare > [welfare] of a and tsWelfare > [welfare] of ? ; If the trade does not corss the MRS over and benefits the welfare of both... [ ask a [ set sugar tSugar ] ask a [ set spice tSpice ] ask ? [ set sugar tsSugar ] ask ? [ set spice tsSpice ] ask a [set-welfareMRS] ask ? [set-welfareMRS] create-trade-with ? [ set price p ifelse p >= 1 [ set sugarAmount 1 set spiceAmount p ] [ set sugarAmount 1 / p set spiceAmount 1 ] ifelse showLinks? = true [set hidden? false] [set hidden? true] set color [color] of ? ] set traded? true ; Loop continutes until no viable trades can be made ] ] ] ] ] end ;; trade rule to trade-with-prejudice let p 0 let a self let as [] let tSugar 0 let tSpice 0 let tsSugar 0 let tsSpice 0 let tWelfare 0 let tsWelfare 0 let x 0 let y 0 let traded? true ask neighbors4 [ ask agents-here [set as fput self as] ] if empty? as [stop] while [traded? = true] [ set traded? false set as sort-by [random 2 = 0] as foreach as [ if [MRS] of ? != [MRS] of a and abs ( [color] of ? - [impartial-spectator] of a ) < tolerance ; or abs ([status] of ? - [status] of a) >= policing-level or [profession] of ? = [profession] of a ) ; Check only agents with unequal MRS, similar color or unequal status [ set x ([MRS] of a < [MRS] of ?) ; Record which MRS is initially higher set p sqrt([MRS] of a * [MRS] of ?) ; Set a price ifelse p >= 1 [ ifelse [MRS] of a < [MRS] of ? [ set tSugar [sugar] of a - 1 set tSpice [spice] of a + p set tsSugar [sugar] of ? + 1 set tsSpice [spice] of ? - p ] [ set tSugar [sugar] of a + 1 set tSpice [spice] of a - p set tsSugar [sugar] of ? - 1 set tsSpice [spice] of ? + p ] ] [ ifelse [MRS] of a < [MRS] of ? [ set tSugar [sugar] of a - (1 / p) set tSpice [spice] of a + 1 set tsSugar [sugar] of ? + (1 / p) set tsSpice [spice] of ? - 1 ] [ set tSugar [sugar] of a + (1 / p) set tSpice [spice] of a - 1 set tsSugar [sugar] of ? - (1 / p) set tsSpice [spice] of ? + 1 ] ] if tSugar > 0 and tSpice > 0 and tsSugar > 0 and tsSpice > 0 [ set y (find-MRS tSugar [sugarMetabolism] of a tSpice [spiceMetabolism] of a [foresight] of a) < (find-MRS tsSugar [sugarMetabolism] of ? tsSpice [spiceMetabolism] of ? [foresight] of ?) ; Record which MRS is now higher set tWelfare find-welfare tSugar [sugarMetabolism] of a tSpice [spiceMetabolism] of a [foresight] of a set tsWelfare find-welfare tsSugar [sugarMetabolism] of ? tsSpice [spiceMetabolism] of ? [foresight] of ? if x = y and tWelfare > [welfare] of a and tsWelfare > [welfare] of ? ; If the trade does not corss the MRS over and benefits the welfare of both... [ ask a [ set sugar tSugar ] ask a [ set spice tSpice ] ask ? [ set sugar tsSugar ] ask ? [ set spice tsSpice ] ask a [set-welfareMRS] ask ? [set-welfareMRS] create-trade-with ? [ set price p ifelse p >= 1 [ set sugarAmount 1 set spiceAmount p ] [ set sugarAmount 1 / p set spiceAmount 1 ] ifelse showLinks? = true [set hidden? false] [set hidden? true] set color [color] of ? ] set traded? true ; Loop continutes until no viable trades can be made ] ] ] ] ] end ;; trade without prejudice rule to trade-without-prejudice let p 0 let a self let as [] let tSugar 0 let tSpice 0 let tsSugar 0 let tsSpice 0 let tWelfare 0 let tsWelfare 0 let x 0 let y 0 let traded? true ask neighbors4 [ ask agents-here [set as fput self as] ] if empty? as [stop] while [traded? = true] [ set traded? false set as sort-by [random 2 = 0] as foreach as [ if [MRS] of ? != [MRS] of a ; Check only agents with unequal MRS [ set x ([MRS] of a < [MRS] of ?) ; Record which MRS is initially higher set p sqrt([MRS] of a * [MRS] of ?) ; Set a price ifelse p >= 1 [ ifelse [MRS] of a < [MRS] of ? [ set tSugar [sugar] of a - 1 set tSpice [spice] of a + p set tsSugar [sugar] of ? + 1 set tsSpice [spice] of ? - p ] [ set tSugar [sugar] of a + 1 set tSpice [spice] of a - p set tsSugar [sugar] of ? - 1 set tsSpice [spice] of ? + p ] ] [ ifelse [MRS] of a < [MRS] of ? [ set tSugar [sugar] of a - (1 / p) set tSpice [spice] of a + 1 set tsSugar [sugar] of ? + (1 / p) set tsSpice [spice] of ? - 1 ] [ set tSugar [sugar] of a + (1 / p) set tSpice [spice] of a - 1 set tsSugar [sugar] of ? - (1 / p) set tsSpice [spice] of ? + 1 ] ] if tSugar > 0 and tSpice > 0 and tsSugar > 0 and tsSpice > 0 [ set y (find-MRS tSugar [sugarMetabolism] of a tSpice [spiceMetabolism] of a [foresight] of a) < (find-MRS tsSugar [sugarMetabolism] of ? tsSpice [spiceMetabolism] of ? [foresight] of ?) ; Record which MRS is now higher set tWelfare find-welfare tSugar [sugarMetabolism] of a tSpice [spiceMetabolism] of a [foresight] of a set tsWelfare find-welfare tsSugar [sugarMetabolism] of ? tsSpice [spiceMetabolism] of ? [foresight] of ? if x = y and tWelfare > [welfare] of a and tsWelfare > [welfare] of ? ; If the trade does not corss the MRS over and benefits the welfare of both... [ ask a [ set sugar tSugar ] ask a [ set spice tSpice ] ask ? [ set sugar tsSugar ] ask ? [ set spice tsSpice ] ask a [set-welfareMRS] ask ? [set-welfareMRS] create-trade-with ? [ set price p ifelse p >= 1 [ set sugarAmount 1 set spiceAmount p ] [ set sugarAmount 1 / p set spiceAmount 1 ] ifelse showLinks? = true [set hidden? false] [set hidden? true] set color [color] of ? ] set traded? true ; Loop continutes until no viable trades can be made ] ] ] ] ] end to set-welfareMRS ; Utility to update agent welfare and MRS set welfare find-welfare sugar sugarMetabolism spice spiceMetabolism foresight set MRS find-MRS sugar sugarMetabolism spice spiceMetabolism foresight end to grow if harvest-ready = false [ set countdown countdown - 1 if countdown <= 0 [ set harvest-ready true ] ] end to update-globals set total-production total-production + total-sugar-production + total-spice-production end to-report agent-volatility report standard-deviation [color] of turtles end to-report ideal-volatility report standard-deviation [impartial-spectator] of turtles end to-report norm-volatility report standard-deviation [pcolor] of patches end to-report trade-norm-volatility ifelse count trades > 1 [ report standard-deviation [color] of trades ] [ report count trades ] end to-report total-wealth report sum [sugar] of turtles + sum [spice] of turtles end to-report report-total-production report total-production end to-report liquidity let available-supply 1 let quantity-traded 0 set available-supply ( sum [sugar] of turtles + sum [spice] of turtles ) - (sum [sugarMetabolism] of turtles + sum [spiceMetabolism] of turtles) set quantity-traded ( sum [sugarAmount] of trades + sum [spiceAmount] of trades ) report ( quantity-traded / available-supply ) end to-report find-welfare [sug sugm spi spim for] ; Utility to find new welfare after a potential move; let m1 sugm let m2 spim let mt (sugm + spim) let w1 max list 0 (sug - (for) * sugm) let w2 max list 0 (spi - (for) * spim) report (w1 ^ (m1 / mt)) * (w2 ^ (m2 / mt)) end to-report find-MRS [sug sugm spi spim for] ; Utility to find new MRS after a potential trade report (spi / spim) / (sug / sugm) end
There is only one version of this model, created almost 11 years ago by Michael Gavin.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Moral Markets.png | preview | Preview for 'Moral Markets' | almost 11 years ago, by Michael Gavin | Download |
This model does not have any ancestors.
This model does not have any descendants.