Markets
Markets: prices, competition, retail, inventories, queues, and barter of Cobb-Douglas traders on trade networks.
AdaptiveAuctionInteraction(label, *, rule=None, phase=None, buyers, sellers, step=1.0, unlimited=False)
Bases: FeedbackInteraction[SystemView]
Double auction in which every buyer meets a random seller every iteration and both adapt their quotes.
Every iteration the buyers that still want units, in random order, meet a random seller that still holds units.
When the bid reaches the ask, one unit trades at the ask, and afterwards the buyer lowers its bid and the seller
raises its ask, to push the price their way. When it does not, the buyer raises its bid and the seller lowers its
ask, to create trade, each change a uniform draw between 0 and step. Bids never exceed the values and asks never
fall below the costs. With unlimited units, traders are resupplied and keep consuming, so trade goes on forever.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the auction. |
required |
rule
|
None
|
Unused, since the auction overrides |
None
|
phase
|
str | None
|
The phase the auction acts in, or |
None
|
buyers
|
Annotated[str, RoleSpec()]
|
The path of the group of buyers. |
required |
sellers
|
Annotated[str, RoleSpec()]
|
The path of the group of sellers. |
required |
step
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The change of a quote after a meeting. |
1.0
|
unlimited
|
bool
|
Whether the units of the traders never run out. |
False
|
Examples:
>>> from skcomplex.systems.economics.markets import AdaptiveAuctionInteraction
>>> AdaptiveAuctionInteraction('auction', buyers='buyers', sellers='sellers').reports
('price', 'volume', 'mean_bid', 'mean_ask')
Source code in src/skcomplex/systems/economics/markets/_adaptive_auction.py
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | |
act(system)
Run the meetings of one iteration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
SystemView
|
The system view of the auction. |
required |
Source code in src/skcomplex/systems/economics/markets/_adaptive_auction.py
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
AdaptiveTraderElement(label, visual=VisualSpec('agents', {'color_by': 'quote'}), *, value=0.0, quote=0.0, units=5.0)
Bases: Element
Buyer or seller of a double auction, with its value or cost, its current bid or ask, and its units left.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
VisualSpec('agents', {'color_by': 'quote'})
|
value
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The value of a unit to a buyer, or its cost to a seller. |
0.0
|
quote
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The current bid of a buyer or ask of a seller. |
0.0
|
units
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The units a buyer still wants or a seller still holds. |
5.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import AdaptiveTraderElement
>>> GroupElement('buyers', element=AdaptiveTraderElement, size=3, values={'value': 120.0}).size
3
Source code in src/skcomplex/systems/economics/markets/_adaptive_auction.py
56 57 58 59 60 61 62 63 64 65 66 67 68 | |
AuctionLedgerInteraction(label, *, rule=None, phase=None)
Bases: FeedbackInteraction[SystemView]
Ledger that closes every trading period: it measures its surplus and gives every trader a new unit.
The realised surplus is the value of the units bought minus the cost of the units sold, and the allocative efficiency is its ratio to the maximum surplus of the supply and demand schedules.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the ledger. |
required |
phase
|
str | None
|
The phase the ledger acts in. |
None
|
Examples:
>>> from skcomplex.systems.economics.markets import AuctionLedgerInteraction
>>> AuctionLedgerInteraction('ledger', phase='close').reports
('surplus', 'efficiency')
Source code in src/skcomplex/core/components/interactions/_feedback.py
44 45 46 47 48 49 50 51 52 53 | |
act(system)
Report the surplus and the efficiency of the trading period and open the next one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
SystemView
|
The system view scoped to the ledger. |
required |
Source code in src/skcomplex/systems/economics/markets/_double_auction.py
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | |
BarterTraderElement(label, visual=None, *, good1=10.0, good2=10.0, mrs=1.0, links=0.0, partners=math.inf)
Bases: Element
Trader with a bundle of two goods and the Cobb-Douglas utility good1 good2, who records its rate.
Its marginal rate of substitution good2 / good1 is the price of the first good, in units of the second, at
which it is indifferent to trade. Every step it records the rate of its current bundle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
good1
|
Annotated[float, StateSpec(domain=open(0, oo))]
|
The holding of the first good. |
10.0
|
good2
|
Annotated[float, StateSpec(domain=open(0, oo))]
|
The holding of the second good. |
10.0
|
mrs
|
Annotated[float, StateSpec(domain=open(0, oo))]
|
The marginal rate of substitution of the bundle. |
1.0
|
links
|
Annotated[float, StateSpec(domain=NN)]
|
The number of trading partners the trader can search. |
0.0
|
partners
|
Annotated[float, StateSpec()]
|
The number of partners that can match with the trader in a step, without limit. |
inf
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import BarterTraderElement
>>> GroupElement('traders', element=BarterTraderElement, size=4).size
4
Source code in src/skcomplex/systems/economics/markets/_barter_networks.py
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | |
get_rate(agent, system)
staticmethod
Return the marginal rate of substitution of the bundle, good2 / good1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
BarterTraderView
|
The trader. |
required |
system
|
SystemView
|
The system view of the appraisal. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
mrs |
float
|
The marginal rate of substitution. |
Source code in src/skcomplex/systems/economics/markets/_barter_networks.py
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | |
get_rate_gap(trader, other)
staticmethod
Return the gap between the logarithms of the rates of substitution of a trader and a trading partner.
The gap is minus infinity for a trader that is not a partner, so a trader takes a partner whenever it has one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trader
|
object
|
The trader that searches. |
required |
other
|
object
|
Another trader. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
gap |
float
|
The absolute difference of the logarithms of the two rates. |
Source code in src/skcomplex/systems/economics/markets/_barter_networks.py
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | |
is_partner(trader, other)
staticmethod
Return whether another trader is a trading partner of a trader, a neighbour on the trade network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trader
|
object
|
The trader that searches. |
required |
other
|
object
|
Another trader. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
partner |
bool
|
Whether the other trader is in a node next to the trader's node. |
Source code in src/skcomplex/systems/economics/markets/_barter_networks.py
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
BartererElement(label, visual=VisualSpec('agents', {'color_by': 'chocolate_weight', 'color_range': (0.0, 1.0)}), *, chocolate=5.0, cigarettes=5.0, chocolate_weight=0.5, cigarettes_weight=0.5)
Bases: Element
Barterer who holds chocolate and cigarettes and values them with Cobb-Douglas weights.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
VisualSpec('agents', {'color_by': 'chocolate_weight', 'color_range': (0.0, 1.0)})
|
chocolate
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The holding of chocolate. |
5.0
|
cigarettes
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The holding of cigarettes. |
5.0
|
chocolate_weight
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The Cobb-Douglas weight of chocolate. |
0.5
|
cigarettes_weight
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The Cobb-Douglas weight of cigarettes. |
0.5
|
Examples:
>>> from skcomplex.systems.economics.markets import BartererElement
>>> GroupElement('barterers', element=BartererElement, size=2, values={'chocolate': [8.0, 2.0]}).size
2
Source code in src/skcomplex/systems/economics/markets/_barter.py
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | |
BilateralBarterInteraction(label, *, requesters, providers, rule=RandomSearchSpec(), limit='limit', quantity='quantity', allowance='allowance', transfers=(), phase=None, on_match=None, units=100)
Bases: MatchingInteraction[SystemView]
Barter in which every trader trades with the neighbour it matched, the one whose rate differs the most.
A greedy matching pairs every trader, in random order, with the neighbour whose marginal rate of substitution
differs the most in logarithm, and a neighbour takes any number of partners. The score of a trader that is not a
neighbour is minus infinity, and a trader without neighbours trades with no one. Each pair trades single units of
the first good at the price (g2 + g2') / (g1 + g1') of their pooled bundles, which lies between their rates, while
the trade raises the utility of both. Besides the reporters of a matching, the reporters trades and searches
count the units traded and the neighbours searched in a step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
requesters
|
Annotated[str, RoleSpec()]
|
The path of the group of traders that search for a partner. |
required |
providers
|
Annotated[str, RoleSpec()]
|
The path of the group of traders that can be found, the same group. |
required |
rule
|
MatchingRule
|
The spec of the algorithm that pairs the traders, such as |
RandomSearchSpec()
|
limit
|
str | tuple[str, str]
|
The state with the limit of both sides, missing for traders, which then accept any partner. |
'limit'
|
quantity
|
str | tuple[str, str]
|
The states of the partners a requester wants and a provider takes, one and without limit for traders. |
'quantity'
|
allowance
|
str
|
The state of a requester with the most value it can give, missing for traders. |
'allowance'
|
transfers
|
Sequence[tuple[str, int]]
|
The states every match moves, none for traders, whose trades move the goods. |
()
|
phase
|
str | None
|
The phase the barter runs in, or |
None
|
on_match
|
Callable[[MatchSpec, SystemView], None] | None
|
A function of every match and the system view, run after the trade, or |
None
|
units
|
Annotated[int, ParameterSpec(domain=NN)]
|
The most units one pair trades in a step. |
100
|
Examples:
>>> from skcomplex.systems.economics.markets import BilateralBarterInteraction
>>> BilateralBarterInteraction('barter', requesters='traders', providers='traders').units
100
Source code in src/skcomplex/systems/economics/markets/_barter_networks.py
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | |
match(system)
Pair and trade, and report the units traded and the neighbours searched besides the matching reporters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
SystemView
|
The system view of the interaction. |
required |
Source code in src/skcomplex/systems/economics/markets/_barter_networks.py
277 278 279 280 281 282 283 284 285 286 287 288 | |
BreweryInteraction(label, *, factory)
Bases: TransferInteraction
Brewery of a supply chain, which brews the orders of the factory over its production delay.
The brewing is a transfer from the brewery into the beer in production at the factory and on to its inventory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the brewery. |
required |
factory
|
Annotated[str, RoleSpec()]
|
The path of the factory. |
required |
Examples:
>>> from skcomplex.systems.economics.markets import BreweryInteraction
>>> BreweryInteraction('brewery', factory='factory').factory
'factory'
Source code in src/skcomplex/systems/economics/markets/_supply_chains.py
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | |
BudgetHouseholdElement(label, visual=None, *, demand=0.0, expenditure=0.0, utility=0.0, price=1.0, budget=100.0, alpha=0.1, elasticity=-1.0, change=0.1, initial_price=1.0, kind='cobb-douglas')
Bases: Element
Household with a budget that buys a good at a price that rises by a share every step.
With the demand 'cobb-douglas' the household maximizes A^alpha B^(1 - alpha) against a composite good B of
price 1, so it buys A = alpha m / p and spends the share alpha of its budget m on the good. With the demand
'elasticity' it spends the budget share alpha at the initial price p0 and its demand changes with its
own-price elasticity, A = (alpha m / p0) (p / p0)^elasticity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
demand
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The demand for the good. |
0.0
|
expenditure
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The expenditure on the good. |
0.0
|
utility
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The Cobb-Douglas utility of the good and the composite good bought. |
0.0
|
price
|
Annotated[float, StateSpec(domain=open(0, oo))]
|
The price of the good. |
1.0
|
budget
|
Annotated[float, StateSpec(domain=open(0, oo))]
|
The budget of the household. |
100.0
|
alpha
|
Annotated[float, StateSpec(domain=closed(0, 1))]
|
The budget share of the good, the exponent of the Cobb-Douglas utility. |
0.1
|
elasticity
|
Annotated[float, StateSpec()]
|
The own-price elasticity of the demand. |
-1.0
|
change
|
Annotated[float, ParameterSpec(domain=open(-1, oo))]
|
The relative rise of the price every step. |
0.1
|
initial_price
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The price at the start. |
1.0
|
kind
|
str
|
The demand, |
'cobb-douglas'
|
Raises:
| Type | Description |
|---|---|
ValidationError
|
The demand is unknown, raised by |
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import BudgetHouseholdElement
>>> GroupElement('households', element=BudgetHouseholdElement, size=2, values={'budget': [50.0, 150.0]}).size
2
Source code in src/skcomplex/systems/economics/markets/_household_demand.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | |
get_demand(s, price)
Return the demand of the household at a price.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s
|
SimpleNamespace
|
The namespace of the household. |
required |
price
|
Expression
|
The price. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
demand |
Expression
|
The demand for the good. |
Source code in src/skcomplex/systems/economics/markets/_household_demand.py
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | |
CarDealershipElement(label, visual=None, *, inventory=200.0, demand=20.0, demand_step=2.0, step_time=25.0, coverage=10.0, perception_delay=5.0, response_delay=3.0, delivery_delay=5.0)
Bases: Element
Car dealership whose inventory deliveries fill and sales drain, ordered to close the gap to a desired coverage.
Sales are the demand, stepping up at step_time, limited by the inventory. The dealer perceives sales through a
first-order smoothing, desires coverage days of perceived sales, and orders the perceived sales plus the gap to
the desired inventory over the response delay, never negative. Orders arrive through a third-order delay. The
dealership holds the inventory and the parameters, and a transfer within it of the system moves the cars.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the dealership. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
inventory
|
Annotated[float, StateSpec(domain=closed_open(0, oo), quantity=cars)]
|
The initial number of cars on the lot. |
200.0
|
demand
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The customer demand in cars per day. |
20.0
|
demand_step
|
Annotated[float, ParameterSpec()]
|
The permanent change of the demand. |
2.0
|
step_time
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The day of the change of the demand. |
25.0
|
coverage
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The days of perceived sales the dealer wants on the lot. |
10.0
|
perception_delay
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The time over which the dealer averages sales. |
5.0
|
response_delay
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The time over which the dealer closes the inventory gap. |
3.0
|
delivery_delay
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The average time between an order and its delivery. |
5.0
|
Examples:
>>> from skcomplex.systems.economics.markets import CarDealershipElement
>>> CarDealershipElement('dealer', inventory=150.0).inventory
150.0
Source code in src/skcomplex/systems/economics/markets/_inventory.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | |
CarElement(label, visual=None, *, stage=WASH, work=525.0, crew=0)
Bases: Element
Car at the wash, waiting for or receiving a wash or a valet.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
stage
|
Annotated[float, StateSpec(domain=NN)]
|
0 for the wash and 1 for the valet. |
WASH
|
work
|
Annotated[float, StateSpec()]
|
The person-seconds of work left at the current stage. |
525.0
|
crew
|
Annotated[float, StateSpec(domain=NN)]
|
The number of workers on the car in the current second. |
0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import CarElement
>>> GroupElement('cars', element=CarElement, size=1).size
1
Source code in src/skcomplex/systems/economics/markets/_queues.py
58 59 60 61 62 63 64 65 66 67 68 69 70 | |
CarWashOperationInteraction(label, *, cars, till, p_pass=0.33, p_enter=0.005, p_valet=0.5, wash_work=525.0, valet_work=1750.0, wash_price=4.0, valet_price=10.0, balk=3.0)
Bases: Interaction
Arrival of passing cars, completion of washes and valets, and payment, once every second.
A passing car turns in with a probability, unless the wash queue holds balk cars or more. A washed car stays for
a valet with a probability, and pays the wash price or the valet price when it leaves.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
cars
|
Annotated[str, RoleSpec()]
|
The path of the group of cars. |
required |
till
|
Annotated[str, RoleSpec()]
|
The path of the group that holds the till. |
required |
p_pass
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability that a car passes in a second. |
0.33
|
p_enter
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability that a passing car turns in. |
0.005
|
p_valet
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability that a washed car stays for a valet. |
0.5
|
wash_work
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The person-seconds of a wash. |
525.0
|
valet_work
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The person-seconds of a valet. |
1750.0
|
wash_price
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The price of a wash. |
4.0
|
valet_price
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The price of a wash with a valet. |
10.0
|
balk
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The length of the wash queue at which drivers no longer turn in. |
3.0
|
Examples:
>>> from skcomplex.systems.economics.markets import CarWashOperationInteraction
>>> CarWashOperationInteraction('wash', cars='cars', till='till', p_enter=0.01).p_enter
0.01
Source code in src/skcomplex/systems/economics/markets/_queues.py
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | |
operate(system)
Finish the cars whose work is done, reset the crews, and let a passing car turn in or drive on.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
SystemView
|
The system. |
required |
Source code in src/skcomplex/systems/economics/markets/_queues.py
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | |
CobwebInteraction(label, *, target, a=10.0, b=2.0, c=1.0, d=1.0)
Bases: MapInteraction
Cobweb system, where supply reacts to the previous price and demand clears the market.
Demand is a - b * price and supply is c + d * previous price, so the next price is
(a - c - d * price) / b, a map of the state price of the market.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the market. |
required |
a
|
Annotated[float, ParameterSpec()]
|
The demand intercept. |
10.0
|
b
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The demand slope. |
2.0
|
c
|
Annotated[float, ParameterSpec()]
|
The supply intercept. |
1.0
|
d
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The supply slope. |
1.0
|
Examples:
>>> from skcomplex.systems.economics.markets import CobwebInteraction
>>> CobwebInteraction('cobweb', target='wheat', a=10, b=2, c=1, d=1).b
2
Source code in src/skcomplex/systems/economics/markets/_cobweb.py
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | |
CommodityMarketElement(label, visual=None, *, inventory=25.0, capacity=100.0, demand=100.0, demand_step=10.0, step_time=2.0, desired_coverage=0.25, reference_price=1.0, supply_elasticity=0.1, demand_elasticity=0.25, expectation_time=1.0, construction_delay=3.0, lifetime=15.0)
Bases: Element
Commodity market whose inventory production fills and consumption drains, with capacity built after a delay.
The price is a falling table function of the coverage of the demand by the inventory relative to the desired coverage. Production is the capacity times the relative price to the supply elasticity, consumption the demand times the relative price to minus the demand elasticity. Capacity is ordered at the rate of retirements times a rising table function of the smoothed price, completed through a third-order delay, and retired over its lifetime. The market holds the stocks and the parameters, and transfers within it of the system move the commodity and the capacity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the market. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
inventory
|
Annotated[float, StateSpec(domain=closed_open(0, oo), quantity=commodity)]
|
The initial inventory of the commodity. |
25.0
|
capacity
|
Annotated[float, StateSpec(domain=closed_open(0, oo), quantity=capacity)]
|
The initial production capacity per year. |
100.0
|
demand
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The demand per year at the reference price. |
100.0
|
demand_step
|
Annotated[float, ParameterSpec()]
|
The permanent change of the demand. |
10.0
|
step_time
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The year of the change of the demand. |
2.0
|
desired_coverage
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The years of demand producers want the inventory to hold. |
0.25
|
reference_price
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The price at the desired coverage. |
1.0
|
supply_elasticity
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The elasticity of the utilization of capacity with respect to the price. |
0.1
|
demand_elasticity
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The elasticity of consumption with respect to the price, as a positive number. |
0.25
|
expectation_time
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The time over which producers smooth the price into their expected price. |
1.0
|
construction_delay
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The average time between an order of capacity and its completion. |
3.0
|
lifetime
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The average lifetime of capacity. |
15.0
|
Examples:
>>> from skcomplex.systems.economics.markets import CommodityMarketElement
>>> CommodityMarketElement('market', lifetime=20.0).lifetime
20.0
Source code in src/skcomplex/systems/economics/markets/_commodities.py
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
ConsumerElement(label, visual=VisualSpec('agents', {'color_by': 'fair', 'color_range': (0.0, 1.0)}), *, fair=0.0, ethics=0.5, budget=2.0, premium=0.3, ethics_weight=2.0, price_weight=5.0, social_weight=2.0)
Bases: Element
Consumer who buys fair-trade or regular food, with an ethical concern, a budget, and the weights of its utility.
The utility of fair food is ethics_weight * ethics - price_weight * premium / budget + social_weight * share,
where share is the share of neighbours who bought fair food in the last step, and the utility of regular food is
zero. A consumer whose budget does not cover the price 1 + premium of fair food buys regular food.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
VisualSpec('agents', {'color_by': 'fair', 'color_range': (0.0, 1.0)})
|
fair
|
Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))]
|
One when the consumer bought fair food in the last step, zero otherwise. |
0.0
|
ethics
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The ethical concern of the consumer, between zero and one. |
0.5
|
budget
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The money the consumer can spend on one unit of food, regular food costing one. |
2.0
|
premium
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The extra price of fair food over regular food. |
0.3
|
ethics_weight
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The weight of ethical concern in the utility of fair food. |
2.0
|
price_weight
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The weight of the premium relative to the budget. |
5.0
|
social_weight
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The weight of the share of neighbours who buy fair food. |
2.0
|
Examples:
>>> from skcomplex.systems.economics.markets import ConsumerElement
>>> GroupElement('consumers', element=ConsumerElement, size=4, values={'ethics': 0.5}).size
4
Source code in src/skcomplex/systems/economics/markets/_fair_food.py
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | |
CournotAdjustmentInteraction(label, *, target, a=1500.0, b=10.0, error=0.0)
Bases: MapInteraction
Simultaneous best responses of two firms to their beliefs about the rival's last output.
Under the inverse demand P = a - b Q, each firm sets q_i = (a - c_i) / (2 b) - belief_j / 2, where the
belief is the rival's last output scaled by a factor drawn uniformly from [1 - error, 1 + error]. It is a
synchronous map of the agent form of the outputs, so both firms respond to the outputs of the step before.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the group of the two firms. |
required |
a
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The intercept of the inverse demand. |
1500.0
|
b
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The slope of the inverse demand. |
10.0
|
error
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The largest relative error of a firm's belief about the rival's output. |
0.0
|
Examples:
>>> from skcomplex.systems.economics.markets import CournotAdjustmentInteraction
>>> CournotAdjustmentInteraction('market', target='firms', error=0.1).error
0.1
Source code in src/skcomplex/systems/economics/markets/_duopoly.py
99 100 101 102 103 104 105 106 107 108 109 110 111 | |
CournotBestResponseElement(label, *, q_i=0.0, q_j=0.0, demand=10.0, c_i=1.0, c_j=2.0, lambda_i=0.0, lambda_j=0.0)
Bases: Element
Quantities of two firms at the best responses of a Cournot game, where each firm holds a share of the other.
The conditions are alpha - 2 q_i - q_j = c_i / (1 + lambda_i) and its mirror (Forrest 2018 Eq. 21.5), whose
solution is q_i = (alpha - 2 c_i / (1 + lambda_i) + c_j / (1 + lambda_j)) / 3 (Eq. 21.6).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the element. |
required |
q_i
|
Annotated[float, StateSpec()]
|
The initial guess of the quantity of the first firm, which the equations replace. |
0.0
|
q_j
|
Annotated[float, StateSpec()]
|
The initial guess of the quantity of the second firm, which the equations replace. |
0.0
|
demand
|
Annotated[float, ParameterSpec()]
|
The intercept |
10.0
|
c_i
|
Annotated[float, ParameterSpec()]
|
The unit cost of the first firm. |
1.0
|
c_j
|
Annotated[float, ParameterSpec()]
|
The unit cost of the second firm. |
2.0
|
lambda_i
|
Annotated[float, ParameterSpec()]
|
The cross holding of the first firm. |
0.0
|
lambda_j
|
Annotated[float, ParameterSpec()]
|
The cross holding of the second firm. |
0.0
|
Examples:
>>> from skcomplex.systems.economics.markets import CournotBestResponseElement
>>> CournotBestResponseElement('duopoly', demand=8.0).demand
8.0
Source code in src/skcomplex/systems/economics/markets/_oligopoly.py
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | |
CustomerElement(label, visual=None, *, s1=0.5, s2=0.5, shop=0.0, freshness=1.0, T=0.1)
Bases: Element
Customer who remembers how satisfied it was with the products of each of two shops.
The customer visits the shop k of larger satisfaction S_k more often, with the logit utility S_k / T, and
holds the freshness of the product it bought last.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
s1
|
Annotated[float, StateSpec()]
|
The satisfaction with the first shop. |
0.5
|
s2
|
Annotated[float, StateSpec()]
|
The satisfaction with the second shop. |
0.5
|
shop
|
Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))]
|
The index of the shop the customer visits, 0 or 1. |
0.0
|
freshness
|
Annotated[float, StateSpec(domain=closed(0, 1))]
|
The freshness of the product the customer bought last. |
1.0
|
T
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The temperature of the choice, the randomness of the customer. |
0.1
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import CustomerElement
>>> GroupElement('customers', element=CustomerElement, size=10, values={'s1': 0.5, 's2': 0.5}).size
10
Source code in src/skcomplex/systems/economics/markets/_perishables.py
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | |
destination(agent, system)
staticmethod
Return the node of the shop the customer chose.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
AgentViewProtocol
|
The customer. |
required |
system
|
SystemViewProtocol
|
The system view of the movement. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
node |
int | None
|
The node of the shop, or |
Source code in src/skcomplex/systems/economics/markets/_perishables.py
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
payoff(agent, system, option)
staticmethod
Return the freshness of the product the customer bought last, the payoff of the shop it visited.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
CustomerView
|
The customer. |
required |
system
|
SystemView
|
The system view of the reinforcement. |
required |
option
|
int
|
The index of the shop the customer visited. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
freshness |
float
|
The freshness of the product. |
Source code in src/skcomplex/systems/economics/markets/_perishables.py
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | |
preference(agent)
staticmethod
Return p_1 - p_2 = tanh((S_1 - S_2) / 2T), how much more likely the customer visits the first shop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
CustomerView
|
The customer. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
preference |
float
|
The difference of the probabilities of visiting the first and the second shop. |
Source code in src/skcomplex/systems/economics/markets/_perishables.py
155 156 157 158 159 160 161 162 163 164 165 166 167 | |
utility(agent, system, option)
staticmethod
Return the utility S_k / T of visiting shop k.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
CustomerView
|
The customer. |
required |
system
|
SystemView
|
The system view of the choice. |
required |
option
|
float
|
The index of the shop. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
utility |
float
|
The satisfaction with the shop divided by the temperature. |
Source code in src/skcomplex/systems/economics/markets/_perishables.py
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | |
DuopolistElement(label, visual=None, *, output=50.0, cost=0.0)
Bases: Element
Firm of a Cournot duopoly, described by its output and its constant marginal cost.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
output
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The initial output. |
50.0
|
cost
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The marginal cost. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import DuopolistElement
>>> GroupElement('firms', element=DuopolistElement, size=2, values={'output': [100.0, 100.0]}).size
2
Source code in src/skcomplex/systems/economics/markets/_duopoly.py
52 53 54 55 56 57 58 59 60 61 62 | |
EchelonElement(label, visual=None, *, inventory=12.0, in_transit=8.0, backlog=4.0, expected=4.0, supply_line=16.0, desired=13.44, theta=0.36, alpha=0.26, beta=0.34, dispatch_time=1.0, mail_delay=2.0, shipping_delay=2.0)
Bases: Element
Echelon of a supply chain, which ships its backlog from its inventory and orders by anchoring and adjustment.
It ships its backlog over the dispatch time, limited by its inventory. Its expected demand adapts to incoming
orders at the rate theta, and it orders its expected demand plus alpha times the gap between its desired stock
and its effective inventory, the inventory less the backlog, less beta times its supply line, never negative.
Its orders reach its supplier after the mail delay, and the beer its supplier ships arrives after the shipping
delay.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the echelon. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
inventory
|
Annotated[float, StateSpec(domain=closed_open(0, oo), quantity=beer)]
|
The initial inventory, in cases. |
12.0
|
in_transit
|
Annotated[float, StateSpec(domain=closed_open(0, oo), quantity=beer)]
|
The initial beer on its way to the echelon. |
8.0
|
backlog
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The initial orders waiting to ship. |
4.0
|
expected
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The initial expected demand. |
4.0
|
supply_line
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The initial beer ordered and not received. |
16.0
|
desired
|
Annotated[float, ParameterSpec()]
|
The desired stock |
13.44
|
theta
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The rate at which the expected demand adapts to incoming orders. |
0.36
|
alpha
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The fraction of the stock gap ordered per week. |
0.26
|
beta
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The weight of the supply line in the stock gap. |
0.34
|
dispatch_time
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The time over which the echelon ships its backlog. |
1.0
|
mail_delay
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The average time an order of the echelon takes to reach its supplier. |
2.0
|
shipping_delay
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The average time a shipment takes to reach the echelon from its supplier. |
2.0
|
Examples:
>>> from skcomplex.systems.economics.markets import EchelonElement
>>> EchelonElement('retailer', inventory=10.0).inventory
10.0
Source code in src/skcomplex/systems/economics/markets/_supply_chains.py
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | |
EmployerElement(label, visual=None, *, bid=0.0, demand=0.0, posted=-1.0, vacancy_rate=0.5, low_wage=0.5, high_wage=1.0)
Bases: Element
Firm that posts a vacancy with a random wage offer in some steps, filled by at most one worker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
bid
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The wage offered for the vacancy. |
0.0
|
demand
|
Annotated[float, StateSpec(domain=NN)]
|
The number of open vacancies, one or zero. |
0.0
|
posted
|
Annotated[float, StateSpec()]
|
The step in which the vacancy was posted. |
-1.0
|
vacancy_rate
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability of posting a vacancy in a step. |
0.5
|
low_wage
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The lowest wage offer. |
0.5
|
high_wage
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The highest wage offer. |
1.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import EmployerElement
>>> GroupElement('firms', element=EmployerElement, size=5).size
5
Source code in src/skcomplex/systems/economics/markets/_labour.py
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | |
get_posting()
staticmethod
Return the states a firm sets in the phase of offers, in their order.
The firm withdraws its last vacancy and posts a new one at the vacancy rate, with a uniform wage offer and the step of posting.
Returns:
| Name | Type | Description |
|---|---|---|
posting |
tuple[tuple[str, Callable[[EmployerView, SystemView], float]], ...]
|
The name of every state and the function of its value, of the firm and the system view. |
Source code in src/skcomplex/systems/economics/markets/_labour.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | |
ExchangeInteraction(label, *, source, target, goods=GOODS, pairing='pairs', quantity=0.1, phase='trade')
Bases: TransferInteraction
Bilateral barter between paired traders, a transfer whose trades repeat while both traders gain.
Every step the transfer pairs the traders, and every pair barters small quantities of every pair of goods at the
geometric mean of their marginal rates of substitution while both gain. A trader holds every good in the state of
its name and its Cobb-Douglas weight in the state <good>_weight. Every trade moves goods between the two traders,
so the total of every good stays the same, which the default run checks as invariants. The exchange reports the
mean price of the second good in units of the first, the standard deviation dispersion of its logarithm over
the trades of the step, and the number of trades volume.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the exchange. |
required |
source
|
str
|
The path of the group of traders. |
required |
target
|
str
|
The path of the group of traders, the source again. |
required |
goods
|
tuple[str, ...]
|
The names of the traded goods. |
GOODS
|
pairing
|
str
|
How the transfer pairs the traders, such as |
'pairs'
|
quantity
|
float
|
The quantity of the bought good in every trade. |
0.1
|
phase
|
str
|
The phase the trades run in. |
'trade'
|
Examples:
>>> from skcomplex.systems.economics.markets import ExchangeInteraction
>>> ExchangeInteraction('exchange', source='traders', target='traders').reports
('price', 'dispersion', 'volume')
Source code in src/skcomplex/systems/economics/common/_exchange_interaction.py
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | |
report_trades(system)
Report the mean price of the second good in the first, its dispersion, and the trades of the step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
SystemViewProtocol
|
The system view of the exchange. |
required |
Source code in src/skcomplex/systems/economics/common/_exchange_interaction.py
122 123 124 125 126 127 128 129 130 131 132 133 134 | |
transfer(source, target, system)
Barter between two traders while both gain, and keep the trades of the step for its report.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
AgentViewProtocol
|
The first trader. |
required |
target
|
AgentViewProtocol
|
The second trader. |
required |
system
|
SystemViewProtocol
|
The system view of the exchange. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
traded |
bool
|
Whether the traders made a trade. |
Source code in src/skcomplex/systems/economics/common/_exchange_interaction.py
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
FactoryElement(label, visual=None, *, inventory=12.0, in_transit=8.0, backlog=4.0, expected=4.0, supply_line=16.0, desired=13.44, theta=0.36, alpha=0.26, beta=0.34, dispatch_time=1.0, mail_delay=2.0, shipping_delay=2.0, production_delay=3.0)
Bases: EchelonElement
Factory of a supply chain, an echelon whose orders a brewery brews over the production delay.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the factory. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
inventory
|
Annotated[float, StateSpec(domain=closed_open(0, oo), quantity=beer)]
|
The initial inventory, in cases. |
12.0
|
in_transit
|
Annotated[float, StateSpec(domain=closed_open(0, oo), quantity=beer)]
|
The initial beer on its way to the echelon. |
8.0
|
backlog
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The initial orders waiting to ship. |
4.0
|
expected
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The initial expected demand. |
4.0
|
supply_line
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The initial beer ordered and not received. |
16.0
|
desired
|
Annotated[float, ParameterSpec()]
|
The desired stock |
13.44
|
theta
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The rate at which the expected demand adapts to incoming orders. |
0.36
|
alpha
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The fraction of the stock gap ordered per week. |
0.26
|
beta
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The weight of the supply line in the stock gap. |
0.34
|
dispatch_time
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The time over which the echelon ships its backlog. |
1.0
|
mail_delay
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The average time an order of the echelon takes to reach its supplier. |
2.0
|
shipping_delay
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The average time a shipment takes to reach the echelon from its supplier. |
2.0
|
production_delay
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The average time the brewery takes to brew an order, through a third-order delay. |
3.0
|
Examples:
>>> from skcomplex.systems.economics.markets import FactoryElement
>>> FactoryElement('factory').production_delay
3.0
Source code in src/skcomplex/systems/economics/markets/_supply_chains.py
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | |
FairFoodMarketInteraction(label, *, rule=None, phase=None, shops, farms, pressure=0.001)
Bases: FeedbackInteraction[SystemView]
Tomato market and the Fair Food Program, which buyers and farms join by the four rules of Chesney.
Every period, in the order of the code of Chesney (2021, Section 7.6), every buyer outside the programme joins it at
level 1 with the probability pressure (Rule 1). Every buyer at level 1, in random order, moves to level 2 when
the member farms grow at least what the buyers at level 2 need plus its own need (Rule 2). The buyers then fill
their needs in random order from the farms in random order, any farm at level 0, member farms first at level 1, and
only member farms at level 2 (Rule 3). Finally every farm outside the programme joins it when it grows more than
the buyers outside the programme need (Rule 4). Levels only rise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the market. |
required |
rule
|
None
|
Unused, since the market overrides |
None
|
phase
|
str | None
|
The phase the market acts in, or |
None
|
shops
|
Annotated[str, RoleSpec()]
|
The path of the group of buyers. |
required |
farms
|
Annotated[str, RoleSpec()]
|
The path of the group of farms. |
required |
pressure
|
Annotated[float, ParameterSpec(domain=closed(0, 1))]
|
The probability per period that a buyer outside the programme joins it at level 1. |
0.001
|
Examples:
>>> from skcomplex.systems.economics.markets import FairFoodMarketInteraction
>>> FairFoodMarketInteraction('market', shops='shops', farms='farms').reports[:2]
('committed_shops', 'member_shops')
Source code in src/skcomplex/systems/economics/markets/_fair_food_program.py
134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
act(system)
Run the four rules of one period.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
SystemView
|
The system view of the market. |
required |
Source code in src/skcomplex/systems/economics/markets/_fair_food_program.py
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | |
ForagerElement(label, visual=VisualSpec('agents', {'color_by': 'sugar'}), *, sugar=10.0, vision=1.0, metabolism=1.0)
Bases: Element
Agent that moves to the richest free cell in sight, harvests its sugar, burns its metabolism, and may starve.
In its own activation, a forager sees vision cells along each of the four lattice directions and moves to the
free cell with the most sugar, the nearest among equals, or stays when no cell in sight beats its own, by a
MovementInteraction of the best step with a vision. Transfers then harvest the sugar of its cell and burn its
metabolism, and a LifeCycleInteraction removes it when its wealth falls below zero.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
VisualSpec('agents', {'color_by': 'sugar'})
|
sugar
|
Annotated[float, StateSpec()]
|
The wealth of the forager. |
10.0
|
vision
|
Annotated[float, StateSpec(domain=NN)]
|
The number of cells the forager sees in every direction. |
1.0
|
metabolism
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The sugar the forager burns in a step. |
1.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import ForagerElement
>>> GroupElement('foragers', element=ForagerElement, size=3, values={'vision': 2.0}).size
3
Source code in src/skcomplex/systems/economics/markets/_sugarscape.py
67 68 69 70 71 72 73 74 75 76 77 78 79 | |
GoodsTraderElement(label, visual=VisualSpec('agents', {'color_by': 'sugar_weight', 'color_range': (0.0, 1.0)}), *, sugar=10.0, spice=10.0, salt=0.0, sugar_weight=0.5, spice_weight=0.5, salt_weight=0.0)
Bases: Element
Trader who holds goods and values them with Cobb-Douglas weights.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
VisualSpec('agents', {'color_by': 'sugar_weight', 'color_range': (0.0, 1.0)})
|
sugar
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The holding of sugar. |
10.0
|
spice
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The holding of spice. |
10.0
|
salt
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The holding of salt. |
0.0
|
sugar_weight
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The Cobb-Douglas weight of sugar. |
0.5
|
spice_weight
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The Cobb-Douglas weight of spice. |
0.5
|
salt_weight
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The Cobb-Douglas weight of salt, zero when salt is not traded. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import GoodsTraderElement
>>> GroupElement('traders', element=GoodsTraderElement, size=4, values={'sugar': 5.0}).size
4
Source code in src/skcomplex/systems/economics/markets/_goods_traders.py
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | |
HeuristicPricingInteraction(label, *, rule=None, phase=None, traders, rate=1.1, strength=1.2, cost=1.0, risk=1.0, noise=0.01, initial=0.1)
Bases: FeedbackInteraction[SystemView]
Market maker that clears the risky asset at the price where the mean forecast of the traders is met.
The deviation x of the price from its fundamental value clears at R x_t = sum_h n_h f_h + eps_t, where n_h
is the share of traders using heuristic h. The fundamentalists forecast the fundamental, f = 0, and the trend
chasers extrapolate the last deviation, f = g x_{t-1}, both as heuristics.fundamental with a reversion of 0
and g. The realised fitness of a heuristic is the profit of its last forecast,
(x_t - R x_{t-1}) (f_h(t - 1) - R x_{t-1}) / (a sigma^2), minus its cost.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the institution. |
required |
rule
|
Callable[[SystemView], None] | None
|
Unused, since the institution overrides |
None
|
phase
|
str | None
|
The phase the institution clears in. |
None
|
traders
|
Annotated[str, RoleSpec()]
|
The path of the group of traders. |
required |
rate
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The gross return |
1.1
|
strength
|
Annotated[float, ParameterSpec()]
|
The extrapolation |
1.2
|
cost
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The cost of the fundamentalist heuristic. |
1.0
|
risk
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The risk aversion times the variance of returns, |
1.0
|
noise
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The standard deviation of the noise of the price. |
0.01
|
initial
|
Annotated[float, ParameterSpec()]
|
The initial deviation of the price from its fundamental value. |
0.1
|
Examples:
>>> from skcomplex.systems.economics.markets import HeuristicPricingInteraction
>>> HeuristicPricingInteraction('pricing', traders='traders').reports
('deviation', 'trend_share', 'fitness_fundamentalist', 'fitness_trend')
Source code in src/skcomplex/systems/economics/markets/_brock_hommes.py
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | |
act(system)
Clear the price from the forecasts of the traders' heuristics and report the fitnesses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
SystemView
|
The system view of the institution. |
required |
Source code in src/skcomplex/systems/economics/markets/_brock_hommes.py
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | |
HeuristicTraderElement(label, visual=None, *, predictor=0.0, fundamentalist_fitness=0.0, trend_fitness=0.0)
Bases: Element
Trader who holds the index of the forecasting heuristic in use, 0 for the fundamentalist and 1 for the trend.
The trader scores every heuristic by its last realised fitness, fundamentalist_fitness and trend_fitness, which
a reinforcement of rate 1 sets every step and a logit choice reads.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
predictor
|
Annotated[float, StateSpec(domain=NN)]
|
The index of the heuristic in use. |
0.0
|
fundamentalist_fitness
|
Annotated[float, StateSpec()]
|
The last realised fitness of the fundamentalist heuristic. |
0.0
|
trend_fitness
|
Annotated[float, StateSpec()]
|
The last realised fitness of the trend heuristic. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import HeuristicTraderElement
>>> GroupElement('traders', element=HeuristicTraderElement, size=10, values={'predictor': 1.0}).size
10
Source code in src/skcomplex/systems/economics/markets/_brock_hommes.py
84 85 86 87 88 89 90 91 92 93 94 95 96 | |
get_fitness(agent, system, option)
staticmethod
Return the score of a heuristic of a trader, its last realised fitness.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
HeuristicTraderView
|
The trader. |
required |
system
|
SystemView
|
The system view of the choice. |
required |
option
|
float
|
The index of the heuristic. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
fitness |
float
|
The last realised fitness of the heuristic. |
Source code in src/skcomplex/systems/economics/markets/_brock_hommes.py
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | |
get_realised_fitness(agent, system, index)
staticmethod
Return the fitness of a heuristic that the market maker reported last, zero before the first report.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
HeuristicTraderView
|
The trader. |
required |
system
|
SystemView
|
The system view of the reinforcement. |
required |
index
|
int
|
The index of the heuristic. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
fitness |
float
|
The last reported fitness of the heuristic. |
Source code in src/skcomplex/systems/economics/markets/_brock_hommes.py
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | |
JobseekerElement(label, visual=None, *, ask=1.0, supply=1.0, employer=-1.0, wage=0.0, duration=0.0, hired=-1.0, offer=-1.0, separation=0.05, reservation=1.0, decline=0.1)
Bases: Element
Worker who loses its job at the separation rate and, while unemployed, lowers its reservation wage.
A worker who loses its job searches from the next step. An unemployed worker asks the reservation wage
w_0 (1 - decline)^d, where d is the number of steps of search, and is hired by the matching market.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
ask
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The reservation wage. |
1.0
|
supply
|
Annotated[float, StateSpec(domain=NN)]
|
One while the worker searches in the current step, zero otherwise. |
1.0
|
employer
|
Annotated[float, StateSpec(reference=firms)]
|
The id of the employer, or -1 for an unemployed worker. |
-1.0
|
wage
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The wage of the current job. |
0.0
|
duration
|
Annotated[float, StateSpec(domain=NN)]
|
The number of steps of the current spell of search. |
0.0
|
hired
|
Annotated[float, StateSpec()]
|
The step of the last hire. |
-1.0
|
offer
|
Annotated[float, StateSpec()]
|
The step in which the offer of the last hire was posted. |
-1.0
|
separation
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability that a job is destroyed in a step. |
0.05
|
reservation
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The reservation wage at the start of a search. |
1.0
|
decline
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The relative fall of the reservation wage per step of search. |
0.1
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import JobseekerElement
>>> GroupElement('workers', element=JobseekerElement, size=5).size
5
Source code in src/skcomplex/systems/economics/markets/_labour.py
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | |
get_search()
staticmethod
Return the states a worker sets in the phase of offers before the separations, in their order.
A worker unemployed at the start of the step searches, with a reservation wage that falls with the duration of its search.
Returns:
| Name | Type | Description |
|---|---|---|
search |
tuple[tuple[str, Callable[[JobseekerView, SystemView], float]], ...]
|
The name of every state and the function of its value, of the worker and the system view. |
Source code in src/skcomplex/systems/economics/markets/_labour.py
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | |
get_spell()
staticmethod
Return the states a worker sets in the phase of offers after the separations, in their order.
A worker who lost its job earns no wage, and the duration of a search grows while the worker searches.
Returns:
| Name | Type | Description |
|---|---|---|
spell |
tuple[tuple[str, Callable[[JobseekerView, SystemView], float]], ...]
|
The name of every state and the function of its value, of the worker and the system view. |
Source code in src/skcomplex/systems/economics/markets/_labour.py
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | |
MarketElement(label, visual=None, *, price=1.0)
Bases: Element
Market of one good described by its price.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the market. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
price
|
Annotated[float, StateSpec()]
|
The initial price. |
1.0
|
Examples:
>>> from skcomplex.systems.economics.markets import MarketElement
>>> MarketElement('wheat', price=2.0).price
2.0
Source code in src/skcomplex/systems/economics/markets/_cobweb.py
38 39 40 41 42 43 44 45 46 | |
PricePointElement(label, *, distribution=0.5, price=1.0, alpha=0.25, beta=0.5, n_firms=2.0)
Bases: Element
Equilibrium distribution of prices at one price, which makes a firm indifferent among its prices.
A firm that charges P sells to its loyal share alpha, and to the switchers beta when it undercuts all its
m - 1 rivals, each with the probability 1 - F(P), for the expected profit P (alpha + beta (1 - F)^(m - 1)).
In equilibrium every price gives the profit alpha of selling to the loyal share at the highest price 1, which
F(P) = 1 - (alpha (1 - P) / (beta P))^(1 / (m - 1)) solves (Forrest 2018 Lemma 20.1).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the point or the group. |
required |
distribution
|
Annotated[float, StateSpec()]
|
The initial guess of |
0.5
|
price
|
Annotated[float, StateSpec(domain=open_closed(0, 1))]
|
The price |
1.0
|
alpha
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The loyal share of every firm. |
0.25
|
beta
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The share of switchers. |
0.5
|
n_firms
|
Annotated[float, ParameterSpec(domain=closed_open(2, oo))]
|
The number of firms |
2.0
|
Examples:
>>> from skcomplex.systems.economics.markets import PricePointElement
>>> PricePointElement('point', price=0.5).price
0.5
Source code in src/skcomplex/systems/economics/markets/_oligopoly.py
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | |
get_profit(member)
staticmethod
Return the expected profit of a firm at the price of a member, for the observables of a run.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
member
|
SimpleNamespace
|
The namespace of the states and parameters of the member. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
profit |
Expression
|
The expected profit |
Source code in src/skcomplex/systems/economics/markets/_oligopoly.py
154 155 156 157 158 159 160 161 162 163 164 165 166 | |
PricingFirmElement(label, price=1.0, scores=0.0)
Bases: Element
Firm that charges one price of a grid and counts what every price would have earned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the firm or the group. |
required |
price
|
Annotated[float, StateSpec()]
|
The price the firm charges. |
1.0
|
scores
|
Annotated[ArrayLike, StateSpec(vector=True)]
|
The sum of the payoffs of every price of the grid against the prices of the rival so far. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import PricingFirmElement
>>> GroupElement('firms', element=PricingFirmElement, size=2).size
2
Source code in src/skcomplex/systems/economics/markets/_oligopoly.py
277 278 279 280 281 282 283 284 285 | |
PricingGameSpec(prices, alpha, beta)
dataclass
Bases: BaseSpec
Grid of prices of two firms, each with a loyal share, that share the switchers who pay the lower price.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prices
|
Array
|
The prices the firms choose among, increasing. |
required |
alpha
|
float
|
The loyal share of every firm. |
required |
beta
|
float
|
The share of switchers. |
required |
Examples:
>>> import numpy as np
>>> from skcomplex.systems.economics.markets import PricingGameSpec
>>> PricingGameSpec(np.array([0.5, 1.0]), 0.25, 0.5).beta
0.5
payoff(agent, system, k)
Return what the price of index k earns against the price the rival charged in this step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
PricingFirmView
|
The firm. |
required |
system
|
SystemView
|
The system view, which holds the rival. |
required |
k
|
int
|
The index of the price. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
payoff |
float
|
The profit of the price. |
Source code in src/skcomplex/systems/economics/markets/_oligopoly.py
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | |
utility(agent, system, option)
Return what a price has earned so far against the prices of the rival, its score.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
PricingFirmView
|
The firm. |
required |
system
|
SystemView
|
The system view, which the score does not read. |
required |
option
|
float
|
The price. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
utility |
float
|
The score of the price. |
Source code in src/skcomplex/systems/economics/markets/_oligopoly.py
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | |
ProductElement(label, visual=None, *, shelved=0.0, tau_a=1.0)
Bases: Element
Product on the shelf of a shop, which ages from the time it was shelved, its freshness exp(-age / tau_a).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
shelved
|
Annotated[float, StateSpec()]
|
The time at which the product was put on the shelf. |
0.0
|
tau_a
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The time over which the product ages. |
1.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import ProductElement
>>> GroupElement('products', element=ProductElement, size=4, location=[0, 0, 1, 1]).size
4
Source code in src/skcomplex/systems/economics/markets/_perishables.py
200 201 202 203 204 205 206 207 208 209 210 | |
restock(product, customer, system)
staticmethod
Return the amount shelved - t that resets the shelving time of a sold product to the time of the sale.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product
|
ProductView
|
The product sold. |
required |
customer
|
CustomerView
|
The customer who buys it. |
required |
system
|
SystemView
|
The system view of the purchase. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
amount |
float
|
The amount taken from the shelving time. |
Source code in src/skcomplex/systems/economics/markets/_perishables.py
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | |
sell(product, customer, system)
staticmethod
Return the amount that sets the freshness the customer holds to exp(-(t - shelved) / tau_a).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product
|
ProductView
|
The product sold. |
required |
customer
|
CustomerView
|
The customer who buys it. |
required |
system
|
SystemView
|
The system view of the purchase. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
amount |
float
|
The change of the freshness the customer holds. |
Source code in src/skcomplex/systems/economics/markets/_perishables.py
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | |
ProgramMemberElement(label, visual=VisualSpec('agents', {'color_by': 'level'}), *, acres=0.0, level=0, traded=0.0)
Bases: Element
Tomato buyer or farm with its acres of tomatoes, its level in the Fair Food Program, and what it traded.
A buyer needs acres of tomatoes every period and has the level 0 outside the programme, 1 when it buys from
member farms first, and 2 when it buys only from member farms. A farm grows acres of tomatoes and has the level 0
outside the programme and 1 inside. traded is what a buyer bought or a farm sold in the period.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
VisualSpec('agents', {'color_by': 'level'})
|
acres
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The tomatoes a buyer needs or a farm grows every period, in acres. |
0.0
|
level
|
Annotated[float, StateSpec(domain=NN)]
|
The level of involvement in the programme. |
0
|
traded
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The tomatoes bought or sold in the period. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import ProgramMemberElement
>>> GroupElement('farms', element=ProgramMemberElement, size=3, values={'acres': 10.0}).size
3
Source code in src/skcomplex/systems/economics/markets/_fair_food_program.py
64 65 66 67 68 69 70 71 72 73 74 75 76 | |
QuadraticSupplyMarketElement(label, visual=None, *, P=1.0, k=1.0, beta=10.0, lam=1.0, delta=1.0, alpha=2.0, gamma=-0.1)
Bases: Element
Market of one good whose price adjusts to the excess of a linear demand over a quadratic supply.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the market. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
P
|
Annotated[float, StateSpec()]
|
The initial price. |
1.0
|
k
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The speed of the price adjustment. |
1.0
|
beta
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The demand at price zero. |
10.0
|
lam
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The slope of the demand. |
1.0
|
delta
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The supply at price zero. |
1.0
|
alpha
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The linear intensity of the supply. |
2.0
|
gamma
|
Annotated[float, ParameterSpec()]
|
The quadratic intensity of the supply, negative for saturation. |
-0.1
|
Examples:
>>> from skcomplex.systems.economics.markets import QuadraticSupplyMarketElement
>>> QuadraticSupplyMarketElement('market', P=2.0).P
2.0
Source code in src/skcomplex/systems/economics/markets/_prices.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | |
ResidentElement(label, visual=VisualSpec('agents', {'color_by': 'travel', 'color_range': (0.0, 1.0)}), *, bid=20.0, demand=1.0, money=1000.0, travel=1.0, distance_cost=1.0, online=0.0)
Bases: Element
Shopper who wants one unit a step and shops in person, paying for travel, or online, where distance is free.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
VisualSpec('agents', {'color_by': 'travel', 'color_range': (0.0, 1.0)})
|
bid
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The highest price the shopper pays. |
20.0
|
demand
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The units still wanted in the step. |
1.0
|
money
|
Annotated[float, StateSpec()]
|
The money of the shopper. |
1000.0
|
travel
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The travel cost per cell of the current step, zero online. |
1.0
|
distance_cost
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The travel cost per cell of shopping in person. |
1.0
|
online
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The probability of shopping online in a step. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import ResidentElement
>>> GroupElement('shoppers', element=ResidentElement, size=3, values={'online': 1.0}).size
3
Source code in src/skcomplex/systems/economics/markets/_shops.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | |
get_preference(shopper, shop)
staticmethod
Return the preference of a shopper for a shop, the opposite of the delivered price.
The delivered price is the shop's ask plus the shopper's travel cost per cell times the distance to the shop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shopper
|
object
|
The shopper. |
required |
shop
|
object
|
The shop. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
preference |
float
|
The opposite of the delivered price, higher for a preferred shop. |
Source code in src/skcomplex/systems/economics/markets/_shops.py
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | |
get_travel(agent, system)
staticmethod
Return the travel cost per cell of the step, zero when the shopper shops online with its probability.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
ResidentView
|
The shopper. |
required |
system
|
SystemView
|
The system view of the plan. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
travel |
float
|
The travel cost per cell. |
Source code in src/skcomplex/systems/economics/markets/_shops.py
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
RetailDemandInteraction(label, *, retailer)
Bases: TransferInteraction
Customers of a supply chain, who take the shipments of the retailer.
The sales are a transfer from the inventory of the retailer to the customers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the customers. |
required |
retailer
|
Annotated[str, RoleSpec()]
|
The path of the retailer. |
required |
Examples:
>>> from skcomplex.systems.economics.markets import RetailDemandInteraction
>>> RetailDemandInteraction('customers', retailer='retailer').retailer
'retailer'
Source code in src/skcomplex/systems/economics/markets/_supply_chains.py
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 | |
RetailerElement(label, visual=None, *, inventory=12.0, in_transit=8.0, backlog=4.0, expected=4.0, supply_line=16.0, desired=13.44, theta=0.36, alpha=0.26, beta=0.34, dispatch_time=1.0, mail_delay=2.0, shipping_delay=2.0, demand=4.0, demand_step=4.0, step_time=5.0)
Bases: EchelonElement
Retailer of a supply chain, an echelon whose customers order their demand, which steps once.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the retailer. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
inventory
|
Annotated[float, StateSpec(domain=closed_open(0, oo), quantity=beer)]
|
The initial inventory, in cases. |
12.0
|
in_transit
|
Annotated[float, StateSpec(domain=closed_open(0, oo), quantity=beer)]
|
The initial beer on its way to the echelon. |
8.0
|
backlog
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The initial orders waiting to ship. |
4.0
|
expected
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The initial expected demand. |
4.0
|
supply_line
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The initial beer ordered and not received. |
16.0
|
desired
|
Annotated[float, ParameterSpec()]
|
The desired stock |
13.44
|
theta
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The rate at which the expected demand adapts to incoming orders. |
0.36
|
alpha
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The fraction of the stock gap ordered per week. |
0.26
|
beta
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The weight of the supply line in the stock gap. |
0.34
|
dispatch_time
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The time over which the echelon ships its backlog. |
1.0
|
mail_delay
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The average time an order of the echelon takes to reach its supplier. |
2.0
|
shipping_delay
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The average time a shipment takes to reach the echelon from its supplier. |
2.0
|
demand
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The customer demand, in cases a week. |
4.0
|
demand_step
|
Annotated[float, ParameterSpec()]
|
The permanent change of the demand. |
4.0
|
step_time
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The week of the change of the demand. |
5.0
|
Examples:
>>> from skcomplex.systems.economics.markets import RetailerElement
>>> RetailerElement('retailer').demand
4.0
Source code in src/skcomplex/systems/economics/markets/_supply_chains.py
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | |
ShopperElement(label, visual=None, *, wanted=0, visited=0, missed=0, spent=0.0)
Bases: Element
Shopper who visits one stall a step that it has not visited yet and buys what it wants there.
A shopper gives up the items that it has not found once it has visited every stall.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
wanted
|
Annotated[float, StateSpec(domain=NN)]
|
The bit mask of the items on the shopping list. |
0
|
visited
|
Annotated[float, StateSpec(domain=NN)]
|
The bit mask of the stalls already visited. |
0
|
missed
|
Annotated[float, StateSpec(domain=NN)]
|
The bit mask of the items given up. |
0
|
spent
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The money spent. |
0.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import ShopperElement
>>> GroupElement('shoppers', element=ShopperElement, size=5, values={'wanted': 3}).size
5
Source code in src/skcomplex/systems/economics/markets/_produce.py
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | |
shop(agent, system)
Visit a random stall not visited yet and buy every wanted item that it sells.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
ShopperView
|
The shopper. |
required |
system
|
SystemView
|
The system. |
required |
Source code in src/skcomplex/systems/economics/markets/_produce.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | |
StallElement(label, visual=None, *, stall=0, stock=0, markup=0.1)
Bases: Element
Market stall that sells some kinds of produce at the wholesale price plus its markup.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
stall
|
Annotated[float, StateSpec(domain=NN)]
|
The index of the stall. |
0
|
stock
|
Annotated[float, StateSpec(domain=NN)]
|
The bit mask of the kinds of produce that the stall sells. |
0
|
markup
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The relative markup on the wholesale prices. |
0.1
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import StallElement
>>> GroupElement('stalls', element=StallElement, size=3, values={'stall': [0, 1, 2]}).size
3
Source code in src/skcomplex/systems/economics/markets/_produce.py
165 166 167 168 169 170 171 172 173 174 175 176 177 | |
StoreElement(label, visual=VisualSpec('agents', {'color_by': 'price'}), *, price=10.0, ask=10.0, supply=0.0, sales=0.0, money=100.0, profit=0.0, direction=1.0, capacity=1000.0, unit_cost=1.0, fixed_cost=20.0, adjustment=0.05)
Bases: Element
Shop that offers its capacity at its price, searches for the price of the largest profit, and may close.
The shop searches for its price by trial and error: it moves the price by adjustment in the same direction as
long as its profit grows, and turns back when the profit falls, never below the unit cost. It pays the unit cost
of every unit sold and the fixed cost every step, and closes when its money runs out.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
VisualSpec('agents', {'color_by': 'price'})
|
price
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The price of a unit. |
10.0
|
ask
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The price offered in the current step. |
10.0
|
supply
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The units still offered in the step. |
0.0
|
sales
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The units sold in the last step. |
0.0
|
money
|
Annotated[float, StateSpec()]
|
The money of the shop. |
100.0
|
profit
|
Annotated[float, StateSpec()]
|
The profit of the last step. |
0.0
|
direction
|
Annotated[float, StateSpec()]
|
The direction of the last change of the price, 1 up or -1 down. |
1.0
|
capacity
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The units the shop can sell in a step. |
1000.0
|
unit_cost
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The cost of a unit sold. |
1.0
|
fixed_cost
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The cost of running the shop for a step. |
20.0
|
adjustment
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The relative change of the price in a step. |
0.05
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import StoreElement
>>> GroupElement('shops', element=StoreElement, size=4, values={'price': 10.0}).size
4
Source code in src/skcomplex/systems/economics/markets/_shops.py
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | |
get_opening()
staticmethod
Return the states a shop sets when it opens for the market, its capacity offered at its price.
Returns:
| Name | Type | Description |
|---|---|---|
opening |
tuple[tuple[str, Callable[[StoreView, SystemView], float]], ...]
|
The name of every state and the function of its value, of the shop and the system view. |
Source code in src/skcomplex/systems/economics/markets/_shops.py
274 275 276 277 278 279 280 281 282 283 284 285 286 | |
get_profit(agent)
staticmethod
Return the profit of the step, the margin on the units sold less the fixed cost.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
StoreView
|
The shop. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
profit |
float
|
The profit of the step. |
Source code in src/skcomplex/systems/economics/markets/_shops.py
260 261 262 263 264 265 266 267 268 269 270 271 272 | |
get_settlement()
staticmethod
Return the states a shop sets when it settles its accounts, in their order.
The shop turns its price back when its profit falls, records the profit, and pays its costs. The pricing of the system then steps the price by the sign of the direction.
Returns:
| Name | Type | Description |
|---|---|---|
settlement |
tuple[tuple[str, Callable[[StoreView, SystemView], float]], ...]
|
The name of every state and the function of its value, of the shop and the system view. |
Source code in src/skcomplex/systems/economics/markets/_shops.py
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | |
record_sale(match, system)
staticmethod
Count the units of a purchase in the sales of the shop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
match
|
MatchSpec
|
The purchase of a shopper, the requester, from a shop, the provider. |
required |
system
|
SystemView
|
The system view of the market. |
required |
Source code in src/skcomplex/systems/economics/markets/_shops.py
306 307 308 309 310 311 312 313 314 315 316 317 318 319 | |
SugarPatchElement(label, visual=VisualSpec('agents', {'color_by': 'sugar', 'color_range': (0.0, 4.0)}), *, sugar=0.0, capacity=0.0, growback=1.0)
Bases: Element
Cell of the landscape whose sugar grows back by a fixed amount a step up to its capacity.
The growback is a RegrowthInteraction of the group of patches.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
VisualSpec('agents', {'color_by': 'sugar', 'color_range': (0.0, 4.0)})
|
sugar
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The sugar on the patch. |
0.0
|
capacity
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The most sugar the patch holds. |
0.0
|
growback
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The sugar that grows back in a step. |
1.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import SugarPatchElement
>>> GroupElement('patches', element=SugarPatchElement, size=4, values={'capacity': 2.0}).size
4
Source code in src/skcomplex/systems/economics/markets/_sugarscape.py
135 136 137 138 139 140 141 142 143 144 145 146 147 | |
SupplyLinkInteraction(label, *, downstream, upstream)
Bases: TransferInteraction
Link of a supply chain, which ships beer from the upstream echelon to the downstream echelon.
The shipments and their arrivals, after a third-order delay of the shipping delay of the downstream echelon, are the legs of one transfer, from the inventory of the upstream echelon to the beer in transit to the downstream echelon and on to its inventory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the link. |
required |
downstream
|
Annotated[str, RoleSpec()]
|
The path of the echelon that orders. |
required |
upstream
|
Annotated[str, RoleSpec()]
|
The path of the echelon that ships. |
required |
Examples:
>>> from skcomplex.systems.economics.markets import SupplyLinkInteraction
>>> SupplyLinkInteraction('link', downstream='retailer', upstream='wholesaler').upstream
'wholesaler'
Source code in src/skcomplex/systems/economics/markets/_supply_chains.py
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | |
TillElement(label, visual=None, *, revenue=0.0, washes=0, valets=0, turned_away=0)
Bases: Element
Till of the car wash, which counts the revenue and the cars served and turned away.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
revenue
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The money taken. |
0.0
|
washes
|
Annotated[float, StateSpec(domain=NN)]
|
The number of cars that left after a wash only. |
0
|
valets
|
Annotated[float, StateSpec(domain=NN)]
|
The number of cars that left after a valet. |
0
|
turned_away
|
Annotated[float, StateSpec(domain=NN)]
|
The number of drivers who did not turn in because of the queue. |
0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import TillElement
>>> GroupElement('till', element=TillElement, size=1).size
1
Source code in src/skcomplex/systems/economics/markets/_queues.py
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | |
ToyMarketInteraction(label, *, rule=None, phase=None, traders, sight=1.0, mutation=0.0, imitation=0.1, elite=0.05, size=51.0, n_goods=1, fitness='none')
Bases: FeedbackInteraction[SystemView]
Market of the Toy Trader: every trader buys the cheapest good it can see, sellers price by inventory, all move.
Every iteration the traders, in random order, try to buy one unit of every good from the trader with the lowest
price within the radius sight, picking at random among equal prices, and buy it when they can pay. After a sale
the seller lowers its price by its factor price_down when its stock is above the target and raises it by
price_up when it is below, never below 0.5. Then every trader moves one unit in a random direction on the torus.
Toys are priced by the trader's own factors, which mutate with the probability mutation by the difference of two
uniform draws on [0, 0.01), and crayons and blackboards by the factors 1.0101 and 0.99. With a fitness test, a
trader of the poorest half copies with the probability imitation the toy price of a random trader of the richest
elite share and, each with probability one half, its factors plus a uniform mutation on [-0.01, 0.01].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the market. |
required |
rule
|
None
|
Unused, since the market overrides |
None
|
phase
|
str | None
|
The phase the market acts in, or |
None
|
traders
|
Annotated[str, RoleSpec()]
|
The path of the group of traders. |
required |
sight
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The radius within which a trader sees prices, its market sight. |
1.0
|
mutation
|
Annotated[float, ParameterSpec(domain=closed(0, 1))]
|
The probability per iteration that a factor of the toy price mutates. |
0.0
|
imitation
|
Annotated[float, ParameterSpec(domain=closed(0, 1))]
|
The probability per iteration that a poor trader imitates a rich one. |
0.1
|
elite
|
Annotated[float, ParameterSpec(domain=open(0, 1))]
|
The share of the richest traders that poor traders imitate. |
0.05
|
size
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The side of the torus. |
51.0
|
n_goods
|
int
|
The goods traded, 1 for toys only or 3 for toys, crayons, and blackboards. |
1
|
fitness
|
str
|
The fitness test of imitation, |
'none'
|
Raises:
| Type | Description |
|---|---|
ValidationError
|
The fitness test or the number of goods is unknown, raised by |
Examples:
>>> from skcomplex.systems.economics.markets import ToyMarketInteraction
>>> ToyMarketInteraction('market', traders='traders').reports[:2]
('average_price', 'trades')
Source code in src/skcomplex/systems/economics/markets/_toy_trader.py
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | |
act(system)
Run one iteration: trade, evolve the pricing rules, and move.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
SystemView
|
The system view of the market. |
required |
Source code in src/skcomplex/systems/economics/markets/_toy_trader.py
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | |
ToyTraderElement(label, visual=VisualSpec('agents', {'color_by': 'money'}), *, x=0.0, y=0.0, money=100.0, toys=5.0, crayons=0.0, blackboards=0.0, toy_price=10.0, crayon_price=10.0, blackboard_price=10.0, price_up=PRICE_UP, price_down=PRICE_DOWN)
Bases: Element
Trader on a torus with money, toys, crayons, and blackboards, its selling prices, and its pricing rule.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
VisualSpec('agents', {'color_by': 'money'})
|
x
|
Annotated[float, StateSpec()]
|
The horizontal place of the trader. |
0.0
|
y
|
Annotated[float, StateSpec()]
|
The vertical place of the trader. |
0.0
|
money
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The money of the trader. |
100.0
|
toys
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The toys of the trader. |
5.0
|
crayons
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The crayons of the trader. |
0.0
|
blackboards
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The blackboards of the trader. |
0.0
|
toy_price
|
Annotated[float, StateSpec(domain=open(0, oo))]
|
The price the trader sells a toy at. |
10.0
|
crayon_price
|
Annotated[float, StateSpec(domain=open(0, oo))]
|
The price the trader sells a crayon at. |
10.0
|
blackboard_price
|
Annotated[float, StateSpec(domain=open(0, oo))]
|
The price the trader sells a blackboard at. |
10.0
|
price_up
|
Annotated[float, StateSpec(domain=closed_open(1, oo))]
|
The factor that raises the toy price when the toys run short. |
PRICE_UP
|
price_down
|
Annotated[float, StateSpec(domain=closed(0, 1))]
|
The factor that lowers the toy price when the toys pile up. |
PRICE_DOWN
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import ToyTraderElement
>>> GroupElement('traders', element=ToyTraderElement, size=3).size
3
Source code in src/skcomplex/systems/economics/markets/_toy_trader.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
WasherElement(label, visual=None)
Bases: Element
Worker who joins the front car of the wash or of the valet while it has fewer than two workers.
A worker who finds both areas staffed helps at a random one of them. One second of work removes one person-second from the car.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import WasherElement
>>> GroupElement('workers', element=WasherElement, size=4).size
4
Source code in src/skcomplex/core/components/elements/_base.py
70 71 72 | |
work(agent, system)
Work one second on the front car of an area.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
AgentView
|
The worker. |
required |
system
|
SystemView
|
The system. |
required |
Source code in src/skcomplex/systems/economics/markets/_queues.py
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | |
ZeroIntelligenceBuyerElement(label, visual=None, *, value=100.0, bid=0.0, demand=1.0, profit=0.0, ceiling=200.0, constrained=1.0)
Bases: Element
Buyer of one unit per trading period who bids a random price, below its value under the budget constraint.
In every round of a trading period, a buyer that has not bought yet bids a price drawn uniformly from 0 to its value, or to the price ceiling without the constraint, the zero-intelligence traders of Gode and Sunder (1993).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
value
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The value of the unit to the buyer, its redemption value. |
100.0
|
bid
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The current bid. |
0.0
|
demand
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The number of units still wanted in the trading period. |
1.0
|
profit
|
Annotated[float, StateSpec()]
|
The accumulated surplus of the buyer's trades. |
0.0
|
ceiling
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The highest price of the market. |
200.0
|
constrained
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
One when the buyer never bids above its value, zero otherwise. |
1.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import ZeroIntelligenceBuyerElement
>>> GroupElement('buyers', element=ZeroIntelligenceBuyerElement, size=5, values={'value': 100.0}).size
5
Source code in src/skcomplex/systems/economics/markets/_double_auction.py
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | |
get_bid(agent, system)
staticmethod
Return a bid drawn uniformly from 0 to the value, or to the price ceiling without the constraint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
ZeroIntelligenceBuyerView
|
The buyer. |
required |
system
|
SystemView
|
The system view of the quotes. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bid |
float
|
The bid of the round. |
Source code in src/skcomplex/systems/economics/markets/_double_auction.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | |
ZeroIntelligenceSellerElement(label, visual=None, *, value=100.0, ask=200.0, supply=1.0, profit=0.0, ceiling=200.0, constrained=1.0)
Bases: Element
Seller of one unit per trading period who asks a random price, above its cost under the budget constraint.
In every round of a trading period, a seller that has not sold yet asks a price drawn uniformly from its cost, or from 0 without the constraint, to the price ceiling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the agent or group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
None
|
value
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The cost of the unit to the seller. |
100.0
|
ask
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The current ask. |
200.0
|
supply
|
Annotated[float, StateSpec(domain=closed_open(0, oo))]
|
The number of units still offered in the trading period. |
1.0
|
profit
|
Annotated[float, StateSpec()]
|
The accumulated surplus of the seller's trades. |
0.0
|
ceiling
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The highest price of the market. |
200.0
|
constrained
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
One when the seller never asks below its cost, zero otherwise. |
1.0
|
Examples:
>>> from skcomplex.core.components.elements import GroupElement
>>> from skcomplex.systems.economics.markets import ZeroIntelligenceSellerElement
>>> GroupElement('sellers', element=ZeroIntelligenceSellerElement, size=5, values={'value': 50.0}).size
5
Source code in src/skcomplex/systems/economics/markets/_double_auction.py
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | |
get_ask(agent, system)
staticmethod
Return an ask drawn uniformly from the cost, or from 0 without the constraint, to the price ceiling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
ZeroIntelligenceSellerView
|
The seller. |
required |
system
|
SystemView
|
The system view of the quotes. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ask |
float
|
The ask of the round. |
Source code in src/skcomplex/systems/economics/markets/_double_auction.py
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | |
barter(n_barterers=2, *, chocolate=(9.0, 1.0), cigarettes=(2.0, 8.0), weights=(0.6, 0.3), quantity=0.02, random_state=0)
Return barter of chocolate and cigarettes, in an Edgeworth box of two barterers or among many prisoners.
Every step the barterers are paired at random, and every pair trades small quantities of one good for the other at the geometric mean of their marginal rates of substitution while both gain, so the totals of both goods are unchanged. Two barterers with the given endowments and weights of chocolate trade within the Edgeworth box until no trade improves both, which is a point of the contract curve, where their marginal rates of substitution are equal. More barterers are prisoners of war who receive random Red Cross parcels and random tastes, and their trades settle on a common price, as Radford (1945) observed (Hamill and Gilbert 2016 ch. 5).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_barterers
|
int
|
The number of barterers, 2 for the Edgeworth box. |
2
|
chocolate
|
tuple[float, float]
|
The chocolate of the two barterers of the Edgeworth box, and the range of the parcels of more barterers. |
(9.0, 1.0)
|
cigarettes
|
tuple[float, float]
|
The cigarettes of the two barterers of the Edgeworth box, and the range of the parcels of more barterers. |
(2.0, 8.0)
|
weights
|
tuple[float, float]
|
The weights of chocolate of the two barterers of the Edgeworth box, and the range of the weights of more barterers. |
(0.6, 0.3)
|
quantity
|
float
|
The quantity of the bought good in every trade. |
0.02
|
random_state
|
int | Generator | None
|
The seed or generator of the parcels and the weights of more than two barterers. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Raises:
| Type | Description |
|---|---|
ValueError
|
There are fewer than two barterers. |
Examples:
>>> from skcomplex.systems.economics.markets import barter
>>> barter().elements[0].prepare().size_
2
Source code in src/skcomplex/systems/economics/markets/_barter.py
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | |
beer_game(inventory=12.0, *, demand=4.0, demand_step=4.0, step_time=5.0, theta=0.36, alpha=0.26, beta=0.34, dispatch_time=1.0, mail_delay=2.0, shipping_delay=2.0, production_delay=3.0)
Return Sterman's beer distribution game, a supply chain whose orders swing wider at every echelon upstream.
A retailer, a wholesaler, a distributor, and a factory each hold an inventory of beer and a backlog of orders
waiting to ship. Each ships its backlog over the dispatch time, limited by its inventory, and the beer reaches the
next echelon downstream after the shipping delay. Orders reach the next echelon upstream after the mail delay, and
the factory brews its orders over the production delay. Customer demand steps from 4 to 8 cases a week in week 5.
Every echelon orders by Sterman's anchoring and adjustment rule, its expected demand plus alpha times the gap
between its desired stock S' and its effective inventory, the inventory less the backlog, plus beta times its
supply line, the beer it ordered and has not received. The expected demand adapts to incoming orders at the rate
theta. The defaults of theta, alpha, and beta are the median estimates of Sterman 1989, and S' is set so
the chain starts in equilibrium at 4 cases a week. The game is weekly and its delays are fixed, while this system is
a continuous approximation in which third-order delays stand in for the fixed ones. The amplitude of the orders
grows from the retailer to the factory, the bullwhip effect.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inventory
|
float
|
The initial inventory of every echelon, in cases. |
12.0
|
demand
|
float
|
The customer demand, in cases a week. |
4.0
|
demand_step
|
float
|
The permanent change of the customer demand. |
4.0
|
step_time
|
float
|
The week of the change of the customer demand. |
5.0
|
theta
|
float
|
The rate at which the expected demand adapts to incoming orders. |
0.36
|
alpha
|
float
|
The fraction of the stock gap ordered per week. |
0.26
|
beta
|
float
|
The weight of the supply line in the stock gap. |
0.34
|
dispatch_time
|
float
|
The time over which an echelon ships its backlog. |
1.0
|
mail_delay
|
float
|
The average time an order takes to reach the next echelon upstream. |
2.0
|
shipping_delay
|
float
|
The average time a shipment takes to reach the next echelon downstream. |
2.0
|
production_delay
|
float
|
The average time the factory takes to brew its orders. |
3.0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the stocks |
Examples:
>>> from skcomplex.systems.economics.markets import beer_game
>>> [element.label for element in beer_game().elements]
['retailer', 'wholesaler', 'distributor', 'factory']
Source code in src/skcomplex/systems/economics/markets/_supply_chains.py
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 | |
brock_hommes(n_traders=1000, *, intensity=1.0, rate=1.1, strength=1.2, cost=1.0, risk=1.0, noise=0.01, initial=0.1)
Return Brock and Hommes' asset market with traders switching between fundamentalists and trend chasers.
Every step the traders score every heuristic by its last realised fitness and choose a heuristic by a logit choice
of intensity beta on its last realised fitness, and the market maker clears the deviation of the price from the
fundamental at R x_t = sum_h n_h f_h. The fundamental steady state is stable while the share of trend chasers
there, 1 / (1 + exp(-beta C)), is below R / g, and beyond the critical intensity beta* = ln(R / (g - R)) / C
the price fluctuates persistently around the fundamental.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_traders
|
int
|
The number of traders. |
1000
|
intensity
|
float
|
The intensity of choice |
1.0
|
rate
|
float
|
The gross return |
1.1
|
strength
|
float
|
The extrapolation |
1.2
|
cost
|
float
|
The cost |
1.0
|
risk
|
float
|
The risk aversion times the variance of returns, |
1.0
|
noise
|
float
|
The standard deviation of the noise of the price. |
0.01
|
initial
|
float
|
The initial deviation of the price from its fundamental value. |
0.1
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.economics.markets import brock_hommes
>>> brock_hommes(100).elements[0].prepare().size_
100
Source code in src/skcomplex/systems/economics/markets/_brock_hommes.py
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | |
car_dealer(inventory=200.0, *, demand=20.0, demand_step=2.0, step_time=25.0, coverage=10.0, perception_delay=5.0, response_delay=3.0, delivery_delay=5.0)
Return Meadows' car dealership, whose inventory oscillates after a step in demand because of its delays.
The inventory is a stock of cars that deliveries from the factory fill and sales to customers drain. Sales are the
customer demand, limited by the cars on the lot. The dealer smooths sales over the perception delay, wants an
inventory of coverage days of perceived sales, and orders the perceived sales plus the gap to that inventory
divided by the response delay. Orders arrive through a third-order material delay, a continuous stand-in for
Meadows' fixed delivery delay. Lengthening the response delay damps the oscillation, while shortening the
perception delay makes the dealer react faster to the new demand and slightly enlarges it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inventory
|
float
|
The initial number of cars on the lot. |
200.0
|
demand
|
float
|
The customer demand in cars per day. |
20.0
|
demand_step
|
float
|
The permanent change of the demand. |
2.0
|
step_time
|
float
|
The day of the change of the demand. |
25.0
|
coverage
|
float
|
The days of perceived sales the dealer wants on the lot. |
10.0
|
perception_delay
|
float
|
The time over which the dealer averages sales. |
5.0
|
response_delay
|
float
|
The time over which the dealer closes the inventory gap. |
3.0
|
delivery_delay
|
float
|
The average time between an order and its delivery. |
5.0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the cars on the lot |
Examples:
>>> from skcomplex.systems.economics.markets import car_dealer
>>> car_dealer(response_delay=6.0).elements[0].response_delay
6.0
Source code in src/skcomplex/systems/economics/markets/_inventory.py
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | |
car_wash(n_workers=4, n_cars=1, *, p_pass=0.33, p_enter=0.005, p_valet=0.5, wash_work=525.0, valet_work=1750.0, wash_price=4.0, valet_price=10.0, balk=3)
Return Chesney's Clean and Wax hand car wash, a shadow account of the revenue of its workers' labour.
Every step is one second. Passing cars turn in with a probability and queue for the wash, washed cars may queue for a valet, and the workers serve the front car of each area, two at a time if they can. The wash opens with cars already queuing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_workers
|
int
|
The number of workers. |
4
|
n_cars
|
int
|
The number of cars queuing for the wash at the start, at least one. |
1
|
p_pass
|
float
|
The probability that a car passes in a second. |
0.33
|
p_enter
|
float
|
The probability that a passing car turns in. |
0.005
|
p_valet
|
float
|
The probability that a washed car stays for a valet. |
0.5
|
wash_work
|
float
|
The person-seconds of a wash. |
525.0
|
valet_work
|
float
|
The person-seconds of a valet. |
1750.0
|
wash_price
|
float
|
The price of a wash. |
4.0
|
valet_price
|
float
|
The price of a wash with a valet. |
10.0
|
balk
|
int
|
The length of the wash queue at which drivers no longer turn in. |
3
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the groups |
Examples:
>>> from skcomplex.systems.economics.markets import car_wash
>>> car_wash(5).elements[0].prepare().size_
5
Source code in src/skcomplex/systems/economics/markets/_queues.py
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | |
cobb_douglas(agent, goods, weights)
Return the logarithm of the Cobb-Douglas utility of an agent, sum_i a_i log x_i.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
object
|
The agent, with a state for the holding of every good and for the weight of every good. |
required |
goods
|
Sequence[str]
|
The names of the states that hold the goods. |
required |
weights
|
Sequence[str]
|
The names of the states that hold the weights of the goods, in the order of |
required |
Returns:
| Name | Type | Description |
|---|---|---|
utility |
float
|
The logarithm of the utility, minus infinity when a weighted good runs out. |
Examples:
>>> from types import SimpleNamespace
>>> from skcomplex.systems.economics.markets import cobb_douglas
>>> agent = SimpleNamespace(x=4.0, y=1.0, a=0.5, b=0.5)
>>> round(cobb_douglas(agent, ('x', 'y'), ('a', 'b')), 6)
0.693147
Source code in src/skcomplex/systems/economics/common/_exchange.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
cobweb(price=1.0, *, a=10.0, b=2.0, c=1.0, d=1.0)
Return a market whose price converges to or oscillates around equilibrium as supply lags the price.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
price
|
float
|
The initial price. |
1.0
|
a
|
float
|
The demand intercept. |
10.0
|
b
|
float
|
The demand slope. |
2.0
|
c
|
float
|
The supply intercept. |
1.0
|
d
|
float
|
The supply slope. |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the market |
Examples:
>>> from skcomplex.systems.economics.markets import cobweb
>>> cobweb(price=2.0).elements[0].price
2.0
Source code in src/skcomplex/systems/economics/markets/_cobweb.py
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | |
commodity_cycle(inventory=25.0, capacity=100.0, *, demand=100.0, demand_step=10.0, step_time=2.0, desired_coverage=0.25, reference_price=1.0, supply_elasticity=0.1, demand_elasticity=0.25, expectation_time=1.0, construction_delay=3.0, lifetime=15.0)
Return a commodity market whose price and capacity cycle because new capacity arrives after a delay.
The inventory is a stock of the commodity that production fills and consumption drains. The price is a falling table function of the inventory coverage, the years of demand the inventory holds, relative to the desired coverage. A high price raises the utilization of capacity and lowers consumption with constant elasticities. Producers form an expected price by smoothing the price, and order new capacity at the rate of retirements multiplied by a rising table function of the expected price. Orders become capacity through a third-order delay. After a step in demand the market overshoots, so the price and the capacity oscillate, the commodity cycle of Bala et al. Section 4.11.4. The book was not at hand, so the tables and the parameters are a documented reconstruction of that structure, in years and in units of the reference demand and price. The market starts in equilibrium.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inventory
|
float
|
The initial inventory of the commodity. |
25.0
|
capacity
|
float
|
The initial production capacity per year. |
100.0
|
demand
|
float
|
The demand per year at the reference price. |
100.0
|
demand_step
|
float
|
The permanent change of the demand. |
10.0
|
step_time
|
float
|
The year of the change of the demand. |
2.0
|
desired_coverage
|
float
|
The years of demand producers want the inventory to hold. |
0.25
|
reference_price
|
float
|
The price at the desired coverage. |
1.0
|
supply_elasticity
|
float
|
The elasticity of the utilization of capacity with respect to the price. |
0.1
|
demand_elasticity
|
float
|
The elasticity of consumption with respect to the price, as a positive number. |
0.25
|
expectation_time
|
float
|
The time over which producers smooth the price into their expected price. |
1.0
|
construction_delay
|
float
|
The average time between an order of capacity and its completion. |
3.0
|
lifetime
|
float
|
The average lifetime of capacity. |
15.0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the inventory |
Examples:
>>> from skcomplex.systems.economics.markets import commodity_cycle
>>> commodity_cycle(construction_delay=5.0).elements[0].construction_delay
5.0
Source code in src/skcomplex/systems/economics/markets/_commodities.py
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | |
contract_curve(chocolate, first_weight, second_weight, total_chocolate, total_cigarettes)
Return the cigarettes of the first of two barterers on the contract curve, given its chocolate.
On the contract curve of two Cobb-Douglas barterers the marginal rates of substitution are equal,
a y / ((1 - a) x) = b (Y - y) / ((1 - b) (X - x)), where a and b are the weights of chocolate, x and y
the chocolate and cigarettes of the first barterer, and X and Y the totals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chocolate
|
ArrayLike
|
The chocolate of the first barterer. |
required |
first_weight
|
float
|
The weight of chocolate of the first barterer. |
required |
second_weight
|
float
|
The weight of chocolate of the second barterer. |
required |
total_chocolate
|
float
|
The total chocolate of both. |
required |
total_cigarettes
|
float
|
The total cigarettes of both. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
cigarettes |
NDArray[float64]
|
The cigarettes of the first barterer on the contract curve. |
Examples:
>>> from skcomplex.systems.economics.markets import contract_curve
>>> float(contract_curve(5.0, 0.5, 0.5, 10.0, 10.0))
5.0
Source code in src/skcomplex/systems/economics/markets/_barter.py
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | |
cournot_duopoly(outputs=(100.0, 100.0), costs=(0.0, 0.0), *, a=1500.0, b=10.0, error=0.0)
Return two Cournot duopolists that adjust their output to their beliefs about each other.
Without errors the outputs converge to the Nash equilibrium, q_i = (a - 2 c_i + c_j) / (3 b), which is 50 units
each for the defaults. Errors in the beliefs keep the total output fluctuating around it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
outputs
|
Sequence[float]
|
The initial outputs of the two firms. |
(100.0, 100.0)
|
costs
|
Sequence[float]
|
The marginal costs of the two firms. |
(0.0, 0.0)
|
a
|
float
|
The intercept of the inverse demand. |
1500.0
|
b
|
float
|
The slope of the inverse demand. |
10.0
|
error
|
float
|
The largest relative error of a firm's belief about the rival's output. |
0.0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.economics.markets import cournot_duopoly
>>> cournot_duopoly(error=0.01).interactions[0].error
0.01
Source code in src/skcomplex/systems/economics/markets/_duopoly.py
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | |
double_auction(n_buyers=50, n_sellers=50, *, protocol='order_book', rounds=20, constrained=True, ceiling=200.0, random_state=0)
Return Gode and Sunder's double auction of zero-intelligence traders, a step per trading period.
Every buyer values one unit and every seller can produce one unit at a cost, both drawn uniformly below the price ceiling. During a trading period of several rounds, every trader that has not traded yet quotes a random price and the market matches the quotes, continuously in a limit order book or at one uniform price in a call auction. With the budget constraint (ZI-C) no trader accepts a loss, and the market alone reaches nearly the whole competitive surplus. Without it (ZI-U), traders make losing trades and the efficiency drops.
The traders are the zero-intelligence traders of Gode and Sunder (1993). The double auction of Gooding (2019), whose traders adapt their bids and asks, is a different model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_buyers
|
int
|
The number of buyers. |
50
|
n_sellers
|
int
|
The number of sellers. |
50
|
protocol
|
str
|
The protocol of the market, |
'order_book'
|
rounds
|
int
|
The number of quoting rounds of a trading period. |
20
|
constrained
|
bool
|
Whether traders never quote at a loss. |
True
|
ceiling
|
float
|
The highest price of the market. |
200.0
|
random_state
|
int | Generator | None
|
The seed or generator of the values and the costs. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the groups |
Raises:
| Type | Description |
|---|---|
ValueError
|
The protocol is unknown. |
Examples:
>>> from skcomplex.systems.economics.markets import double_auction
>>> [group.size for group in double_auction(10, 8).elements]
[10, 8]
Source code in src/skcomplex/systems/economics/markets/_double_auction.py
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | |
fair_food(width=20, height=20, *, premium=0.3, ethics_weight=2.0, price_weight=5.0, social_weight=2.0, intensity=1.0, low_budget=1.0, high_budget=3.0, random_state=0)
Return the choice between fair-trade and regular food of consumers who influence their neighbours.
Every consumer, of uniform ethical concern and budget, sits on a cell of a grid and every step buys fair or regular food, all at once from the choices of their neighbours in the last step. The share of fair food rises with the weight of ethics and falls with the premium, and social influence raises it.
The choice is the binary logit choice with social interactions of Brock and Durlauf (2001), with a private utility of ethics and price and a social utility of the share of neighbours who buy fair food. Neither Ajani's Choice nor the Fair Food Program of Chesney (2021) is this model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
int
|
The number of columns of the grid. |
20
|
height
|
int
|
The number of rows of the grid. |
20
|
premium
|
float
|
The extra price of fair food over regular food, which costs one. |
0.3
|
ethics_weight
|
float
|
The weight of ethical concern in the utility of fair food. |
2.0
|
price_weight
|
float
|
The weight of the premium relative to the budget. |
5.0
|
social_weight
|
float
|
The weight of the share of neighbours who buy fair food. |
2.0
|
intensity
|
float
|
The intensity of the logit choice. |
1.0
|
low_budget
|
float
|
The lowest budget. |
1.0
|
high_budget
|
float
|
The highest budget. |
3.0
|
random_state
|
int | Generator | None
|
The seed or generator of the ethics and the budgets. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.economics.markets import fair_food
>>> fair_food(5, 4).elements[0].prepare().size_
20
Source code in src/skcomplex/systems/economics/markets/_fair_food.py
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | |
fair_food_program(n_shops=30, n_farms=20, *, acres=1000.0, pressure=0.001, random_state=0)
Return Chesney's Fair Food Program, in which pressure on tomato buyers draws farms into fair wages.
The Coalition of Immokalee Workers presses tomato buyers to join the Fair Food Program, whose member farms pay
pickers a penny more per pound. Buyers join at level 1, buying from member farms first, then move to level 2,
buying only from member farms, once the member farms grow enough, and farms join when the buyers outside the
programme need less than they grow. Buyers and farms have random sizes that share the acres of farmland, and the
buyers need as much as the farms grow. This is the model of Chesney (2021, Sections 7.2 to 7.6), with the floor
and ceiling of its NetLogo code, whose sell_me subtracts the last tomatoes of a farm from the buyer instead of
adding them, which this system corrects. Farms hold out until most buyers have joined, then join in a cascade, a
tipping point that comes later the more unequal the agents.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_shops
|
int
|
The number of buyers. |
30
|
n_farms
|
int
|
The number of farms. |
20
|
acres
|
float
|
The acres of farmland, which the buyers need and the farms grow. |
1000.0
|
pressure
|
float
|
The probability per period that a buyer outside the programme joins it at level 1. |
0.001
|
random_state
|
int | Generator | None
|
The seed or generator of the sizes of the buyers and farms. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the groups |
Examples:
>>> from skcomplex.systems.economics.markets import fair_food_program
>>> [group.prepare().size_ for group in fair_food_program(5, 3).elements]
[5, 3]
Source code in src/skcomplex/systems/economics/markets/_fair_food_program.py
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | |
gooding_double_auction(n_buyers=100, n_sellers=100, *, value=120.0, cost=20.0, spread=0.1, units=5.0, step=1.0, unlimited=False, random_state=0)
Return Gooding's double auction, whose buyers and sellers move their quotes towards trade and then apart.
Buyers value a unit near value and sellers can supply it near cost, each differing by up to spread of it. As
in the experiments the model replicates, buyers start bidding near the sellers' cost and sellers start asking near
the buyers' value, and both move their quotes towards one another until they trade, after which each tries to push
the price its way (Gooding 2019, Section 11.3 and the appendix). In the short run, with sellers of a few units and
buyers that are satiated after a few, the price settles near the competitive price halfway between value and cost,
70 at the defaults. With unlimited supply and demand, the long-run price wanders between the cost and the value and
the equilibrium disappears. The source describes the rules in prose, so the meetings and the fixed steps of the
quotes are a reconstruction of them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_buyers
|
int
|
The number of buyers. |
100
|
n_sellers
|
int
|
The number of sellers. |
100
|
value
|
float
|
The mean value of a unit to the buyers. |
120.0
|
cost
|
float
|
The mean cost of a unit to the sellers. |
20.0
|
spread
|
float
|
The largest relative difference of a trader's value or cost from the mean. |
0.1
|
units
|
float
|
The units every seller holds and every buyer wants. |
5.0
|
step
|
float
|
The change of a quote after a meeting. |
1.0
|
unlimited
|
bool
|
Whether the units of the traders never run out. |
False
|
random_state
|
int | Generator | None
|
The seed or generator of the values and costs. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the groups |
Examples:
>>> from skcomplex.systems.economics.markets import gooding_double_auction
>>> [group.prepare().size_ for group in gooding_double_auction(4, 3).elements]
[4, 3]
Source code in src/skcomplex/systems/economics/markets/_adaptive_auction.py
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | |
goods_traders(n_traders=200, *, goods=3, width=20, height=20, quantity=0.1, mobility=0.5, low=1.0, high=20.0, random_state=0)
Return traders who wander a grid and barter two or three goods with their neighbours.
Every trader holds random amounts of the goods and values them with random Cobb-Douglas weights. Every step the traders wander to a random neighbouring cell, then every trader is paired with a neighbour, and the pairs barter while both gain, at the geometric mean of their marginal rates of substitution. Trades only move goods between the traders, so the total of every good is unchanged, while the mean utility rises and the prices of different trades converge, so the dispersion of the logarithm of the price falls.
The trade rule is the bilateral barter of sugar and spice of Epstein and Axtell (1996), and salt extends it to a third good. The Toy Trader of Gooding (2019), with money, posted prices, and imitation of price rules, is a different model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_traders
|
int
|
The number of traders. |
200
|
goods
|
int
|
The number of goods, 2 for sugar and spice or 3 with salt. |
3
|
width
|
int
|
The number of columns of the grid. |
20
|
height
|
int
|
The number of rows of the grid. |
20
|
quantity
|
float
|
The quantity of the bought good in every trade. |
0.1
|
mobility
|
float
|
The probability that a trader moves in a step. |
0.5
|
low
|
float
|
The smallest initial holding of a good. |
1.0
|
high
|
float
|
The largest initial holding of a good. |
20.0
|
random_state
|
int | Generator | None
|
The seed or generator of the cells, holdings, and weights. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Raises:
| Type | Description |
|---|---|
ValueError
|
The number of goods is not 2 or 3. |
Examples:
>>> from skcomplex.systems.economics.markets import goods_traders
>>> goods_traders(20, goods=2).elements[0].prepare().size_
20
Source code in src/skcomplex/systems/economics/markets/_goods_traders.py
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | |
hire(trade, system)
Record the employer, the wage, and the steps of the hire and of its offer on the hired worker.
The hired worker keeps its search flag supply until the next step, which the market lowered when it cleared, so
the observable searching counts every worker who searched in the step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trade
|
MatchSpec
|
The match of a firm, the requester of labour, with a worker, its provider. |
required |
system
|
SystemView
|
The system view of the market. |
required |
Source code in src/skcomplex/systems/economics/markets/_labour.py
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | |
household_demand(n_households=1000, *, demand='cobb-douglas', shares=FOOD_SHARES, share_deviation=0.02, elasticities=FOOD_ELASTICITIES, elasticity_deviation=0.1, minimum=100 / 3, change=0.1, random_state=0)
Return Hamill and Gilbert's heterogeneous households, whose demand for food traces a curve as its price rises.
Every household has a budget drawn from an exponential law shifted right by a minimum and normalized to a mean of
100, which gives a Gini coefficient of about a third and a P90/P10 ratio just over 4, and a budget share of food
drawn around the mean of its budget quintile, from 15 percent for the poorest to 8 percent for the richest. Every
step the price rises by the share change, from 1. With the Cobb-Douglas utility of Section 3.2 of Hamill and
Gilbert (2016) the demand is alpha m / p, the own-price elasticity is -1, the expenditure stays the same, and the
poorest lose the most utility. With the practical model of Section 3.3 the households also have own-price
elasticities drawn around the means of their quintiles, from -0.6 to -0.3, so a price rise of 10 percent lowers
the demand by about 4.4 percent and raises the expenditure by about 5.1 percent, more for the richest.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_households
|
int
|
The number of households. |
1000
|
demand
|
str
|
|
'cobb-douglas'
|
shares
|
Sequence[float]
|
The mean budget share of the good of every budget quintile, from the poorest. |
FOOD_SHARES
|
share_deviation
|
float
|
The standard deviation of the budget shares within a quintile. |
0.02
|
elasticities
|
Sequence[float]
|
The mean own-price elasticity of every budget quintile, from the poorest. |
FOOD_ELASTICITIES
|
elasticity_deviation
|
float
|
The standard deviation of the elasticities within a quintile. |
0.1
|
minimum
|
float
|
The shift of the exponential law of the budgets before normalization. |
100 / 3
|
change
|
float
|
The relative rise of the price every step. |
0.1
|
random_state
|
int | Generator | None
|
The seed or generator of the budgets, shares, and elasticities. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.economics.markets import household_demand
>>> household_demand(10).elements[0].prepare().size_
10
Source code in src/skcomplex/systems/economics/markets/_household_demand.py
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | |
labour_market(n_workers=200, n_firms=40, *, separation=0.05, vacancy_rate=0.3, reservation=1.0, decline=0.1, low_wage=0.5, high_wage=1.0, unemployment=0.5, random_state=0)
Return Hamill and Gilbert's labour market of firms posting wage offers and unemployed workers searching.
In the phase of offers, jobs are destroyed at the separation rate s, every firm posts a vacancy with a uniform
wage offer at the vacancy rate, and unemployed workers set reservation wages that fall with the duration of their
search. In the phase of matching, a deferred-acceptance market pairs vacancies with workers whose reservation wage
they cover, every worker getting the best offer of a stable matching. The unemployment rate settles at the
flow-balance value s / (s + f), with f the share of searching workers hired in a step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_workers
|
int
|
The number of workers. |
200
|
n_firms
|
int
|
The number of firms, each with at most one vacancy per step. |
40
|
separation
|
float
|
The probability |
0.05
|
vacancy_rate
|
float
|
The probability that a firm posts a vacancy in a step. |
0.3
|
reservation
|
float
|
The reservation wage at the start of a search. |
1.0
|
decline
|
float
|
The relative fall of the reservation wage per step of search. |
0.1
|
low_wage
|
float
|
The lowest wage offer. |
0.5
|
high_wage
|
float
|
The highest wage offer. |
1.0
|
unemployment
|
float
|
The initial share of unemployed workers. |
0.5
|
random_state
|
int | Generator | None
|
The seed or generator of the initial employment. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the groups |
Examples:
>>> from skcomplex.systems.economics.markets import labour_market
>>> [group.size for group in labour_market(20, 5).elements]
[5, 20]
Source code in src/skcomplex/systems/economics/markets/_labour.py
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | |
marginal_rate(agent, good, numeraire, weights)
Return the marginal rate of substitution of a good for a numeraire, the units of numeraire one unit is worth.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
object
|
The agent. |
required |
good
|
str
|
The name of the state that holds the good. |
required |
numeraire
|
str
|
The name of the state that holds the numeraire. |
required |
weights
|
tuple[str, str]
|
The names of the states that hold the weights of the good and of the numeraire. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
rate |
float
|
The ratio of the marginal utilities, |
Examples:
>>> from types import SimpleNamespace
>>> from skcomplex.systems.economics.markets import marginal_rate
>>> agent = SimpleNamespace(x=2.0, y=6.0, a=0.5, b=0.5)
>>> marginal_rate(agent, 'x', 'y', ('a', 'b'))
3.0
Source code in src/skcomplex/systems/economics/common/_exchange.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | |
maximum_surplus(values, costs)
Return the largest total surplus of single units, the competitive surplus of the supply and demand schedules.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
ndarray
|
The value of a unit to every buyer. |
required |
costs
|
ndarray
|
The cost of a unit to every seller. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
surplus |
float
|
The sum of the positive differences between the highest values and the lowest costs. |
Examples:
>>> import numpy as np
>>> from skcomplex.systems.economics.markets import maximum_surplus
>>> maximum_surplus(np.array([10.0, 6.0, 2.0]), np.array([1.0, 4.0, 8.0]))
11.0
Source code in src/skcomplex/systems/economics/markets/_double_auction.py
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | |
oligopoly_equilibria(n_firms=2, *, alpha=0.25, n_prices=21, demand=10.0, c_i=1.0, c_j=2.0, lambda_i=0.0, lambda_j=0.0, dynamics='static')
Return the equilibria of a Cournot duopoly and of a pricing game of firms with loyal customers and switchers.
The static system solves the Cournot best responses (Forrest 2018 Eqs. 21.5-21.6) and, on a grid of prices, the
symmetric mixed equilibrium of m firms of loyal share alpha and switchers beta = 1 - m alpha, whose price
distribution makes a firm indifferent among its prices, at the profit alpha (Lemma 20.1). With
dynamics='fictitious-play', two firms learn to price on the grid instead: every round each plays a best response
to the prices of its rival so far, and the prices they charge are distributed near the mixed equilibrium.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_firms
|
int
|
The number of firms of the pricing game, two under fictitious play. |
2
|
alpha
|
float
|
The loyal share of every firm. |
0.25
|
n_prices
|
int
|
The number of prices of the grid from |
21
|
demand
|
float
|
The intercept of the inverse demand of the Cournot duopoly. |
10.0
|
c_i
|
float
|
The unit cost of the first Cournot firm. |
1.0
|
c_j
|
float
|
The unit cost of the second Cournot firm. |
2.0
|
lambda_i
|
float
|
The cross holding of the first Cournot firm. |
0.0
|
lambda_j
|
float
|
The cross holding of the second Cournot firm. |
0.0
|
dynamics
|
str
|
|
'static'
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The static system, with the states |
Raises:
| Type | Description |
|---|---|
ValidationError
|
The dynamics are unknown, or fictitious play has other than two firms. |
Examples:
>>> from skcomplex.core.engine.runtime import Simulation
>>> from skcomplex.systems.economics.markets import oligopoly_equilibria
>>> trajectory = Simulation(oligopoly_equilibria()).prepare().run(1.0).trajectory_
>>> round(float(trajectory.values('cournot.q_i')[0]), 6)
3.333333
Source code in src/skcomplex/systems/economics/markets/_oligopoly.py
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | |
perishable_goods_duopoly(customers=200, *, stock=0.5, T=0.1, alpha=0.9, tau_a=1.0, random_state=0)
Return customers who choose between two shops of perishable goods, preferring the one that sold fresher goods.
Each shop holds stock products per customer, and every sale replaces a product with a fresh one, so the shop
with more customers sells fresher goods and attracts more customers. With the control parameter
R = 2 stock / tau_a, the symmetric state m = p_1 - p_2 = 0 loses its stability below the temperature
T_c = R / (1 + R)^2, and one shop takes most customers. The transition is continuous for R > sqrt(3) - 1 and
discontinuous below. One unit of time is N visits by customers drawn with replacement. A visited customer
chooses a shop with the probability 1 / (1 + exp(-(S_1 - S_2) / T)) for the first one, moves to it, buys a random
product of age tau, of freshness h = exp(-tau / tau_a), which the shop replaces with a fresh one, and updates
its satisfaction with that shop alone to alpha S + (1 - alpha) h. The shops are the two nodes of a network on
which their products stand.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
customers
|
int
|
The number of customers |
200
|
stock
|
float
|
The number of products of each shop per customer. |
0.5
|
T
|
float
|
The temperature of the choice, the randomness of the customers. |
0.1
|
alpha
|
float
|
The memory of the satisfaction, between 0 and 1. |
0.9
|
tau_a
|
float
|
The time over which the products age. |
1.0
|
random_state
|
int | Generator | None
|
The seed or generator of the initial satisfactions, which scatter by 0.01 around 0.5. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the groups |
Examples:
>>> from skcomplex.systems.economics.markets import perishable_goods_duopoly
>>> perishable_goods_duopoly(20).elements[0].prepare().size_
20
Source code in src/skcomplex/systems/economics/markets/_perishables.py
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | |
produce_market(n_shoppers=50, n_stalls=9, *, n_items_stocked=6, random_state=0)
Return Hamill and Gilbert's produce market, where shoppers with lists of produce visit stalls at random.
There are twelve kinds of fruit and vegetables. Every stall sells a random selection of them at its own markup of 1 to 30 percent on the wholesale prices, and every shopper wants between one and eight of them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_shoppers
|
int
|
The number of shoppers. |
50
|
n_stalls
|
int
|
The number of stalls. |
9
|
n_items_stocked
|
int
|
The number of kinds of produce that every stall sells. |
6
|
random_state
|
int | Generator | None
|
The seed or generator of the stocks, the markups, and the shopping lists. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the groups |
Examples:
>>> from skcomplex.systems.economics.markets import produce_market
>>> [group.size for group in produce_market(10, 3).elements]
[3, 10]
Source code in src/skcomplex/systems/economics/markets/_produce.py
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | |
riccati_prices(price=1.0, *, k=1.0, beta=10.0, lam=1.0, delta=1.0, alpha=2.0, gamma=-0.1)
Return a price that moves with excess demand under linear demand and saturating quadratic supply.
The price follows the Riccati equation dP/dt = k (D - S) with demand D = beta - lam P and supply
S = delta + alpha P + gamma P^2. When (lam + alpha)^2 > 4 gamma (delta - beta) there are two equilibrium prices,
and prices below the larger one converge to the smaller one. Otherwise the price blows up in finite time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
price
|
float
|
The initial price. |
1.0
|
k
|
float
|
The speed of the price adjustment. |
1.0
|
beta
|
float
|
The demand at price zero. |
10.0
|
lam
|
float
|
The slope of the demand. |
1.0
|
delta
|
float
|
The supply at price zero. |
1.0
|
alpha
|
float
|
The linear intensity of the supply. |
2.0
|
gamma
|
float
|
The quadratic intensity of the supply, negative for saturation. |
-0.1
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the price |
Examples:
>>> from skcomplex.systems.economics.markets import riccati_prices
>>> riccati_prices(gamma=-0.2).elements[0].gamma
-0.2
Source code in src/skcomplex/systems/economics/markets/_prices.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | |
shops(n_shops=16, *, width=20, height=20, online=0.0, distance_cost=1.0, capacity=1000.0, fixed_cost=20.0, value=20.0, random_state=0)
Return shops on a grid that compete for the shoppers on every cell, in person or in a digital market.
Every step every shopper wants one unit and shops online with probability online, and in person otherwise, when it
pays a travel cost for the distance to the shop. The shoppers choose in random order the shops they prefer by price
plus travel cost, within the shops' capacities, a greedy matching that pays the shop's ask for a unit. Shops search
for the price of the largest profit by trial and error, pay a fixed cost every step, and close when their money runs
out. Distance gives every shop a local market, so many shops survive with high prices. In the digital market the
cheapest shop takes every shopper, the others undercut it, prices fall toward the unit cost, and most shops close
(Hamill and Gilbert 2016 sec. 6.3-6.4).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_shops
|
int
|
The initial number of shops. |
16
|
width
|
int
|
The number of columns of the grid, with one shopper per cell. |
20
|
height
|
int
|
The number of rows of the grid. |
20
|
online
|
float
|
The probability that a shopper shops online in a step. |
0.0
|
distance_cost
|
float
|
The travel cost per cell of shopping in person. |
1.0
|
capacity
|
float
|
The units every shop can sell in a step. |
1000.0
|
fixed_cost
|
float
|
The cost of running a shop for a step. |
20.0
|
value
|
float
|
The highest price a shopper pays. |
20.0
|
random_state
|
int | Generator | None
|
The seed or generator of the cells and initial prices of the shops. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the groups |
Examples:
>>> from skcomplex.systems.economics.markets import shops
>>> [group.size for group in shops(4, width=5, height=5).elements]
[25, 4]
Source code in src/skcomplex/systems/economics/markets/_shops.py
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 | |
sugarscape(width=50, height=50, *, n_foragers=400, max_vision=6, max_metabolism=4.0, low_sugar=5.0, high_sugar=25.0, growback=1.0, random_state=0)
Return the Sugarscape of Epstein and Axtell, foragers of random vision and metabolism on two sugar peaks.
Every step the foragers, in random order, move to the richest free cell in sight, harvest it, and burn their metabolism, and those whose wealth falls below zero die. Then the sugar grows back. Foragers of poor vision or high metabolism starve, so the population falls to the carrying capacity of the landscape, and the wealth of the survivors becomes skewed, with a Gini coefficient that rises from its initial value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
int
|
The number of columns. |
50
|
height
|
int
|
The number of rows. |
50
|
n_foragers
|
int
|
The initial number of foragers. |
400
|
max_vision
|
int
|
The largest vision, every forager seeing from 1 to |
6
|
max_metabolism
|
float
|
The largest metabolism, every forager burning from 1 to |
4.0
|
low_sugar
|
float
|
The lowest initial wealth. |
5.0
|
high_sugar
|
float
|
The highest initial wealth. |
25.0
|
growback
|
float
|
The sugar that grows back on every patch in a step. |
1.0
|
random_state
|
int | Generator | None
|
The seed or generator of the foragers' cells, visions, metabolisms, and wealth. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the groups |
Examples:
>>> from skcomplex.systems.economics.markets import sugarscape
>>> [group.size for group in sugarscape(10, 10, n_foragers=20).elements]
[100, 20]
Source code in src/skcomplex/systems/economics/markets/_sugarscape.py
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | |
toy_trader(n_traders=400, *, sight=1.0, mutation=0.0, imitation=0.1, fitness='none', n_goods=1, size=51.0, random_state=0)
Return Gooding's Toy Trader, traders with money and toys who buy the cheapest toy they can see.
Four hundred traders on a 51 by 51 torus start with 100 money, 5 toys, and a toy price of 10. Every iteration every
trader buys one toy from the cheapest trader within its market sight, if it can pay, and moves one unit in a random
direction. A seller keeps its stock at 3 toys by lowering its price by the factor 0.99 above it and raising it by
1.0101 below it (Gooding 2019, Section 8.2 and the appendix). Money and toys are conserved and supply exceeds the
demand for stocks, yet the price depends on the market sight: it falls when traders see only their neighbours and
rises when they see everyone, so supply and demand alone do not set it (Section 10.1). Mutating pricing factors
make the traders heterogeneous and raise prices and inequality, and the imitation of the richest 5 percent by the
poorest half under a fitness test of money or of assets evolves the price patterns of speculation and asset markets
(Sections 10.2 and 11). With n_goods=3 the traders also trade crayons and blackboards, starting with 30 and 15,
which keep the fixed factors and the target stocks of 10 to 15 and 5 to 8 of the Three-Goods Trader (Section 11.1).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_traders
|
int
|
The number of traders. |
400
|
sight
|
float
|
The radius within which a trader sees prices. |
1.0
|
mutation
|
float
|
The probability per iteration that a factor of the toy price mutates, such as 1 / 5000. |
0.0
|
imitation
|
float
|
The probability per iteration that a poor trader imitates a rich one under a fitness test. |
0.1
|
fitness
|
str
|
The fitness test of imitation, |
'none'
|
n_goods
|
int
|
The goods traded, 1 for toys only or 3 for toys, crayons, and blackboards. |
1
|
size
|
float
|
The side of the torus. |
51.0
|
random_state
|
int | Generator | None
|
The seed or generator of the places of the traders. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Examples:
>>> from skcomplex.systems.economics.markets import toy_trader
>>> toy_trader(10).elements[0].prepare().size_
10
Source code in src/skcomplex/systems/economics/markets/_toy_trader.py
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | |
trade_goods(first, second, goods, weights, *, quantity=0.1, limit=1000)
Barter small quantities of goods between two agents while both gain, and return the trades.
For every pair of goods in turn, the agent that values the first good more in units of the second buys quantity
of it from the other at the geometric mean of their marginal rates of substitution, as in the Sugarscape trade of
Epstein and Axtell (1996). A trade happens only when it raises the Cobb-Douglas utility of both agents, and every
trade is two transfers, so the total of every good is unchanged. The agents trade until a round over all pairs of
goods makes no trade, or until limit trades.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
first
|
object
|
The first agent, with a state for the holding and for the weight of every good. |
required |
second
|
object
|
The second agent. |
required |
goods
|
Sequence[str]
|
The names of the states that hold the goods. |
required |
weights
|
Sequence[str]
|
The names of the states that hold the weights of the goods, in the order of |
required |
quantity
|
float
|
The quantity of the bought good in every trade. |
0.1
|
limit
|
int
|
The largest number of trades. |
1000
|
Returns:
| Name | Type | Description |
|---|---|---|
trades |
list[tuple[int, int, float]]
|
The index of the bought good, the index of the good paid with, and the price of every trade. |
Examples:
>>> from types import SimpleNamespace
>>> from skcomplex.systems.economics.markets import trade_goods
>>> first = SimpleNamespace(x=9.0, y=1.0, a=0.5, b=0.5)
>>> second = SimpleNamespace(x=1.0, y=9.0, a=0.5, b=0.5)
>>> trades = trade_goods(first, second, ('x', 'y'), ('a', 'b'), quantity=0.5)
>>> first.x + second.x, len(trades) > 0
(10.0, True)
Source code in src/skcomplex/systems/economics/common/_exchange.py
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | |
wilhite_trade_networks(n_agents=500, *, topology='small_world', n_groups=10, shortcuts=5, endowment=100.0, units=100, random_state=0)
Return Wilhite's bilateral barter of two goods among traders on one of four trade networks.
Traders start with random bundles of two goods and the utility good1 good2. Every step, each trader searches
its neighbours and trades with the one whose marginal rate of substitution differs the most, single units at a
price between their rates, while both gain. Trade drives the rates of every connected set of traders towards one
price. On the complete network every trader searches every other, so it needs the most searches, and traders crowd
onto the most extreme partners, so prices converge slowly. Isolated groups settle on different prices. Groups
chained by shared end traders, or a small world with some long links, bring the prices together with far fewer
searches.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_agents
|
int
|
The number of traders. |
500
|
topology
|
str
|
|
'small_world'
|
n_groups
|
int
|
The number of groups of the isolated, linked, and small-world networks. |
10
|
shortcuts
|
int
|
The number of random long links between groups of the small world. |
5
|
endowment
|
float
|
The largest initial holding of each good, drawn uniformly from 1 to it. |
100.0
|
units
|
int
|
The most units one pair trades in a step. |
100
|
random_state
|
int | Generator | None
|
The seed or generator of the bundles and the long links. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the group |
Raises:
| Type | Description |
|---|---|
ValueError
|
The topology is unknown. |
Examples:
>>> from skcomplex.systems.economics.markets import wilhite_trade_networks
>>> system = wilhite_trade_networks(40, topology='isolated', n_groups=4)
>>> system.elements[0].prepare().size_
40
Source code in src/skcomplex/systems/economics/markets/_barter_networks.py
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | |