diff --git a/examples/information_cascades/README.md b/examples/information_cascades/README.md
new file mode 100644
index 000000000..8603fdb16
--- /dev/null
+++ b/examples/information_cascades/README.md
@@ -0,0 +1,90 @@
+# Information Cascades & Trading Behavior Model
+
+This example implements a hybrid model of **Information Cascades and Trading Behavior** using **Mesa** and **Solara**.
+
+The model studies how individual opinions evolve through repeated pairwise interactions (based on bounded confidence) and how investor overconfidence leads to excessive trading and wealth destruction.
+
+---
+
+## Model Description
+
+Each investor agent holds a continuous opinion value in the range **(-1, 1)**, an overconfidence level between **(1.0, 5.0)**, and an initial wealth of **1000.0**.
+At each time step:
+
+1. A random pair of agents is selected.
+2. If the difference between their opinions is less than a confidence threshold **ε (epsilon)**, they interact.
+3. During an interaction, both agents adjust their opinions toward each other by a fraction **μ (mu)**, adjusted by their stubbornness (overconfidence).
+4. Agents then execute trades with a probability based on their confidence level. Each trade deducts a fixed transaction cost from their wealth.
+
+Depending on parameter values, the model can exhibit:
+- Herd formation (Consensus)
+- Echo chambers (Polarization and Fragmentation)
+- Systematic wealth depletion due to overtrading
+
+---
+
+## Parameters
+
+| Parameter | Description |
+|-------------------------|------------|
+| `n` | Number of investors in the market |
+| `epsilon (ε)` | Confidence threshold controlling whether agents interact |
+| `mu (μ)` | Convergence rate controlling how strongly opinions are updated |
+| `transaction_cost` | The fee deducted from an agent's wealth per executed trade |
+
+---
+
+## Collected Metrics
+
+The model tracks the following quantities over time:
+
+- **Variance** – dispersion of opinions in the population
+- **Avg Wealth** – the average remaining capital across all agents
+
+These metrics are visualized alongside individual opinion trajectories and wealth distribution.
+
+---
+
+## Visualization
+
+This example includes a Solara-based interactive visualization that shows:
+
+- Opinion trajectories of all agents (Herd Formation)
+- A scatter plot validating that "Trading is Hazardous to Your Wealth" (Confidence vs. Wealth)
+- Opinion Variance over time
+- Average Wealth over time
+- Real-time trading performance stats
+
+The market parameters can be adjusted in real-time using the sliders.
+
+---
+
+## Installation
+
+To install the dependencies, use `pip` to install the requirements:
+
+```bash
+ $ pip install -r requirements.txt
+```
+
+From this directory, run:
+```bash
+ $ solara run app.py
+```
+
+Then open your browser to local host http://localhost:8765/ and press Reset, then Step or Play.
+
+## Files
+- model.py: Defines the TradingDWModel, including market parameters, agent interactions, and data collection.
+- agents.py: Defines the InvestorAgent class, the logic for updating agent opinions, and the trading execution mechanism.
+- app.py: Contains the code for the interactive Solara visualization, including opinion trajectories, scatter plots, and custom performance metrics.
+
+
+## References
+- Barber, B. M., & Odean, T. (2000).
+Trading is hazardous to your wealth: The common stock investment performance of individual investors.
+The Journal of Finance, 55(2), 773-806.
+
+- Banerjee, A. V. (1992).
+A simple model of herd behavior.
+The Quarterly Journal of Economics, 107(3), 797-817.
diff --git a/examples/information_cascades/app.py b/examples/information_cascades/app.py
new file mode 100644
index 000000000..6f3775b12
--- /dev/null
+++ b/examples/information_cascades/app.py
@@ -0,0 +1,134 @@
+import matplotlib.pyplot as plt
+import solara
+import solara.lab
+from information_cascades.model import TradingDWModel
+from mesa.visualization import SolaraViz, make_plot_component
+
+
+def TradingPerformanceStats(model):
+ agents = list(model.agents)
+ if not agents:
+ return solara.Text("initializing...")
+
+ avg_gross = sum(a.gross_wealth for a in agents) / len(agents)
+ avg_net = sum(a.net_wealth for a in agents) / len(agents)
+
+ sorted_agents = sorted(agents, key=lambda x: x.trades)
+ n = len(sorted_agents)
+ split = max(1, n // 5)
+
+ low_traders = sorted_agents[:split]
+ high_traders = sorted_agents[-split:]
+
+ avg_net_low = sum(a.net_wealth for a in low_traders) / len(low_traders)
+ avg_net_high = sum(a.net_wealth for a in high_traders) / len(high_traders)
+
+ return solara.Card(
+ title="Barber & Odean (2000) Validation",
+ children=[
+ solara.Markdown(f"**Market Avg (Gross)**: {avg_gross:.2f}"),
+ solara.Markdown(f"**Market Avg (Net)**: {avg_net:.2f}"),
+ solara.Markdown("---"),
+ solara.Markdown(
+ f"**Low Turnover Top 20% Net Wealth**: {avg_net_low:.2f}"
+ ),
+ solara.Markdown(
+ f"**High Turnover Top 20% Net Wealth**: {avg_net_high:.2f}"
+ ),
+ ],
+ )
+
+
+def WealthVsConfidenceScatter(model):
+ fig, ax = plt.subplots(figsize=(6, 4), constrained_layout=True)
+ agents = list(model.agents)
+ confidences = [a.confidence for a in agents]
+ wealths = [a.net_wealth for a in agents]
+
+ if wealths:
+ avg_w = sum(wealths) / len(wealths)
+ ax.scatter(confidences, wealths, alpha=0.6, c=wealths, cmap="RdYlGn")
+
+ w_min, w_max = min(wealths), max(wealths)
+ padding = (w_max - w_min) * 0.2 if w_max > w_min else 10
+ ax.set_ylim(w_min - padding, w_max + padding)
+
+ ax.axhline(avg_w, color="blue", linestyle="--", alpha=0.5)
+ ax.fill_between(
+ [1, 5],
+ w_min - padding,
+ avg_w,
+ color="red",
+ alpha=0.1,
+ label="Underperforming",
+ )
+
+ ax.set_xlabel("Confidence Level")
+ ax.set_ylabel("Net Wealth")
+ ax.set_title("Trading is Hazardous to Your Wealth")
+
+ return solara.FigureMatplotlib(fig)
+
+
+def OpinionTrajectoryPlot(model):
+ fig, ax = plt.subplots(figsize=(6, 4), constrained_layout=True)
+ df = model.datacollector.get_agent_vars_dataframe()
+ if df.empty:
+ return solara.FigureMatplotlib(fig)
+
+ opinions = df["opinion"].unstack()
+ opinions.plot(ax=ax, legend=False, alpha=0.4)
+ ax.set_xlabel("Steps")
+ ax.set_ylabel("Opinion")
+ ax.set_title("Herd Formation (Banerjee, 1992)")
+ return solara.FigureMatplotlib(fig)
+
+
+model_params = {
+ "n": {
+ "type": "SliderInt",
+ "value": 100,
+ "label": "Number of Investors",
+ "min": 20,
+ "max": 300,
+ "step": 1,
+ },
+ "epsilon": {
+ "type": "SliderFloat",
+ "value": 0.6,
+ "label": "Confidence Threshold (ε)",
+ "min": 0.01,
+ "max": 1.0,
+ "step": 0.01,
+ },
+ "mu": {
+ "type": "SliderFloat",
+ "value": 0.1,
+ "label": "Convergence Rate (μ)",
+ "min": 0.01,
+ "max": 0.5,
+ "step": 0.01,
+ },
+ "transaction_cost": {
+ "type": "SliderFloat",
+ "value": 0.5,
+ "label": "Transaction Cost",
+ "min": 0,
+ "max": 10,
+ "step": 0.5,
+ },
+}
+
+initial_model = TradingDWModel()
+
+page = SolaraViz(
+ model=initial_model,
+ model_params=model_params,
+ components=[
+ TradingPerformanceStats,
+ OpinionTrajectoryPlot,
+ WealthVsConfidenceScatter,
+ make_plot_component("Variance"),
+ make_plot_component(["Avg Gross Wealth", "Avg Net Wealth"]),
+ ],
+)
diff --git a/examples/information_cascades/information_cascades/__init__.py b/examples/information_cascades/information_cascades/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/examples/information_cascades/information_cascades/agents.py b/examples/information_cascades/information_cascades/agents.py
new file mode 100644
index 000000000..cde088369
--- /dev/null
+++ b/examples/information_cascades/information_cascades/agents.py
@@ -0,0 +1,36 @@
+from mesa import Agent
+
+
+class InvestorAgent(Agent):
+ """
+ While Banerjee's Herding Effect highlights how investors blindly follow the crowd, Barber & Odean's Overconfidence
+ Theory explains their stubborn reliance on flawed personal judgment; together, they amplify irrational market
+ volatility and pricing inefficiencies.
+ """
+
+ def __init__(self, model, opinion, confidence):
+ super().__init__(model)
+ self.opinion = opinion
+ self.confidence = confidence
+ """
+ The core of the Barber and Odean theory lies in the critical distinction between gross returns
+ and net returns, demonstrating how overconfident investors' excessive trading costs erode potential gains.
+ """
+ self.gross_wealth = (
+ 1000.0 # Theoretical Market Wealth Under a Buy-and-Hold Strategy (Gross)
+ )
+ self.net_wealth = 1000.0 # Actual Wealth After Deducting Frequent Trading Commissions and Fees (Net)
+ self.trades = 0
+
+ def update_opinion(self, other_opinion, mu):
+ # The more inflated the confidence, the more stubborn the bias (resulting in a smaller effective mu
+ effective_mu = mu / self.confidence
+ self.opinion += effective_mu * (other_opinion - self.opinion)
+
+ def execute_trade(self):
+ # Barber & Odean: Overconfidence leads to excessive turnover rates.
+ trade_prob = 0.05 * self.confidence
+ if self.random.random() < trade_prob:
+ self.trades += 1
+ # Only net wealth accounts for the deduction of transaction friction costs.
+ self.net_wealth -= self.model.transaction_cost
diff --git a/examples/information_cascades/information_cascades/model.py b/examples/information_cascades/information_cascades/model.py
new file mode 100644
index 000000000..974707cb6
--- /dev/null
+++ b/examples/information_cascades/information_cascades/model.py
@@ -0,0 +1,74 @@
+import statistics
+
+from mesa import Model
+from mesa.datacollection import DataCollector
+
+from .agents import InvestorAgent
+
+
+class TradingDWModel(Model):
+ def __init__(self, n=100, epsilon=0.2, mu=0.5, transaction_cost=2.0, rng=None):
+ super().__init__(rng=rng)
+ self.n = n
+ self.epsilon = epsilon
+ self.mu = mu
+ self.transaction_cost = transaction_cost
+ self.attempted_interactions = 0
+ self.accepted_interactions = 0
+
+ self.datacollector = DataCollector(
+ model_reporters={
+ "Variance": self.compute_variance,
+ "Avg Gross Wealth": lambda m: (
+ statistics.mean([a.gross_wealth for a in m.agents])
+ if m.agents
+ else 0
+ ),
+ "Avg Net Wealth": lambda m: (
+ statistics.mean([a.net_wealth for a in m.agents]) if m.agents else 0
+ ),
+ },
+ agent_reporters={
+ "opinion": "opinion",
+ "net_wealth": "net_wealth",
+ "confidence": "confidence",
+ "trades": "trades",
+ },
+ )
+
+ for _ in range(self.n):
+ op = self.random.uniform(-1, 1)
+ conf = self.random.uniform(1.0, 5.0)
+ agent = InvestorAgent(self, op, conf)
+ self.agents.add(agent)
+
+ self.datacollector.collect(self)
+
+ def step(self):
+ agent_list = list(self.agents)
+
+ # Simulating Natural Market Volatility Returns (Random Walk with Positive Drift
+ market_return = self.random.normalvariate(0.001, 0.01)
+ for agent in agent_list:
+ agent.gross_wealth *= 1 + market_return
+ agent.net_wealth *= 1 + market_return
+
+ for _ in range(self.n):
+ agent_a, agent_b = self.random.sample(agent_list, 2)
+ self.attempted_interactions += 1
+
+ # Banerjee: Communication within cognitive thresholds leads to opinion convergence (herd formation).
+ if abs(agent_a.opinion - agent_b.opinion) < self.epsilon:
+ old_op_a = agent_a.opinion
+ agent_a.update_opinion(agent_b.opinion, self.mu)
+ agent_b.update_opinion(old_op_a, self.mu)
+
+ agent_a.execute_trade()
+ agent_b.execute_trade()
+ self.accepted_interactions += 1
+
+ self.datacollector.collect(self)
+
+ def compute_variance(self):
+ opinions = [a.opinion for a in self.agents]
+ return statistics.variance(opinions) if len(opinions) > 1 else 0
diff --git a/examples/information_cascades/requirements.txt b/examples/information_cascades/requirements.txt
new file mode 100644
index 000000000..e08682a35
--- /dev/null
+++ b/examples/information_cascades/requirements.txt
@@ -0,0 +1,7 @@
+mesa>3.0.0
+solara
+matplotlib
+pandas
+numpy
+networkx
+altair
\ No newline at end of file