Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/salesforce/ai-economist/llms.txt

Use this file to discover all available pages before exploring further.

The ContinuousDoubleAuction component (registry name "ContinuousDoubleAuction", component type "Trade") implements a commodity-exchange-style market. Agents post bids (maximum willingness to pay) and asks (minimum acceptable payment) for any collectible resource in the world. When a bid price is at least as high as an ask price, orders are matched and the trade is executed automatically.
This component applies only to BasicMobileAgent instances. The planner agent also receives market observations but does not take trading actions.

Constructor parameters

max_bid_ask
int
default:"10"
Maximum coin amount an agent can bid or ask for one unit of a resource. Sets the price ceiling; the price floor is always 0. Must be >= 1.
order_labor
float
default:"0.25"
Labor charged to an agent each time it submits a bid or ask order. Must be >= 0.
order_duration
int
default:"50"
Number of environment timesteps an unfilled order remains active before it expires and escrowed funds/resources are returned. Must be >= 1.
max_num_orders
int
Maximum number of simultaneous open orders (bids + asks combined) an agent may hold per resource. Defaults to order_duration when not set. Must be >= 1.
Required world entities: Coin, Labor.

Action space

For every collectible resource C in the world this component adds two sub-action spaces to each BasicMobileAgent:
Sub-action nameSizeMeaning
Buy_{C}1 + max_bid_askIndex 0 = no-op; index k = bid k-1 coin for one unit of C
Sell_{C}1 + max_bid_askIndex 0 = no-op; index k = ask k-1 coin to sell one unit of C
Price level 0 corresponds to a bid/ask of 0 coin, and price level max_bid_ask corresponds to the price ceiling. The actual number of price levels per sub-action is max_bid_ask + 1.

Order book mechanics

Submitting orders

When an agent bids on resource C at price p:
  1. p coin is moved from the agent’s inventory to escrow.
  2. The bid is recorded in self.bids[C].
  3. order_labor is charged to the agent’s labor endogenous state.
When an agent posts an ask for resource C at price p:
  1. One unit of C is moved from the agent’s inventory to escrow.
  2. The ask is recorded in self.asks[C].
  3. order_labor is charged.

Matching orders

After all agents act, match_orders() runs the continuous double auction:
  • Bids are sorted descending by price, then ascending by age.
  • Asks are sorted ascending by price, then descending by age.
  • For each valid bid/ask pair where bid >= ask, a trade is executed:
    • Price rule: trade price equals the bid price if the bid was placed first; otherwise equals the ask price.
    • The resource moves from the seller’s escrow to the buyer’s inventory.
    • The buyer’s escrowed coin is consumed; any excess above the trade price is returned to the buyer.
    • The seller receives the trade price in their inventory.

Order expiration

remove_expired_orders() runs after matching. Orders that have been open for more than order_duration timesteps are removed and all escrowed funds/resources are returned to their owners.

Observations

Both agents and the planner observe market state. Agents only see bids/asks that they did not themselves submit (i.e., orders they could respond to), plus their own outstanding orders.

Agent observations (per resource C)

market_rate-{C}
float
Exponentially weighted average trade price for resource C across all agents.
price_history-{C}
ndarray
Scaled histogram of recent trade prices (length max_bid_ask + 1). Decays by a factor of 0.995 each timestep.
available_asks-{C}
ndarray
Histogram of open asks from other agents that this agent could bid against.
available_bids-{C}
ndarray
Histogram of open bids from other agents that this agent could ask against.
my_asks-{C}
ndarray
Histogram of this agent’s own outstanding asks.
my_bids-{C}
ndarray
Histogram of this agent’s own outstanding bids.

Planner observations (per resource C)

market_rate-{C}
float
Same weighted average trade price visible to agents.
price_history-{C}
ndarray
Aggregate price history across all agents.
full_asks-{C}
ndarray
Complete ask histogram across all agents.
full_bids-{C}
ndarray
Complete bid histogram across all agents.

Action masks

  • Sell actions are fully masked if the agent has no inventory of that resource or is at the order limit.
  • Buy actions are masked at price levels the agent cannot afford (price > current coin balance) or if the agent is at the order limit.

Metrics

get_metrics() returns per-agent, per-resource trade statistics averaged over the episode:
{agent_idx}/Buy{C}/n_sales
int
Number of successful purchases of resource C by this agent.
{agent_idx}/Buy{C}/price
float
Average price paid per unit of C (NaN if no purchases).
{agent_idx}/Buy{C}/cost
float
Average total cost per purchase transaction.
{agent_idx}/Sell{C}/n_sales
int
Number of successful sales of resource C by this agent.
{agent_idx}/Sell{C}/income
float
Average income per unit of C sold (NaN if no sales).
n_trades
int
Total number of trades executed across all resources and agents over the episode.

Dense log

get_dense_log() returns a list — one entry per timestep — of trade lists. Each executed trade is a dict:
commodity
string
Name of the traded resource.
buyer
int
Agent index of the buyer.
seller
int
Agent index of the seller.
price
int
Executed trade price in coin.
bid
int
Original bid price submitted by the buyer.
ask
int
Original ask price submitted by the seller.

Example usage

env_config = {
    "components": [
        {
            "ContinuousDoubleAuction": {
                "max_bid_ask": 10,
                "order_labor": 0.25,
                "order_duration": 50,
                "max_num_orders": 5,
            }
        }
    ]
}

Build docs developers (and LLMs) love