> ## Documentation Index
> Fetch the complete documentation index at: https://village-docs.villagelabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Basic Simulation Example

> Complete walkthrough of a simple ESOP simulation

## Scenario Overview

Let's model **Acme Corporation**, a 100-person manufacturing company that established an ESOP in 2020 with a \$3M loan. We'll project 10 years to forecast repurchase obligations.

<Info>
  **Company Profile:**

  * 100 employees
  * Single ESOP loan from 2020
  * \$500K annual contribution budget
  * Current share price: \$100/share
</Info>

## Step 1: Define Plan Rules

The legal framework that rarely changes:

```python theme={null}
from villagelabs import PlanRules, VestingSchedule, DistributionPolicy

plan_rules = PlanRules(
    plan_name="Acme Corporation ESOP",
    plan_year_end="12/31",
    
    # 6-year graded vesting
    vesting_schedule=VestingSchedule(
        type="graded",
        schedule=[0, 0, 20, 40, 60, 80, 100]  # Years 0-6
    ),
    
    # Distribute 1 year after termination
    distribution_policy=DistributionPolicy(
        timing="termination_plus_1_year",
        form="lump_sum",
        in_service_distributions=False
    ),
    
    # Cash usage hierarchy for repurchases
    cash_usage_policy=[
        "unallocated_company_contributions",
        "unallocated_forfeiture_cash",
        "participant_cash_accounts"
    ],
    
    # Diversification per ERISA standards
    diversification_rules={
        "enabled": True,
        "age_requirement": 55,
        "service_requirement": 10,
        "first_election_percentage": 0.25,
        "final_election_percentage": 0.50,
        "final_election_age": 60
    }
)
```

## Step 2: Set Operating Assumptions

The annual business strategy:

```python theme={null}
from villagelabs import OperatingAssumptions

operating_assumptions = OperatingAssumptions(
    # Fixed $500K contribution
    contribution_policy={
        "type": "fixed_amount",
        "annual_amount": 500_000
    },
    
    # Share valuation assumptions
    share_valuation={
        "current_price": 100.00,
        "annual_growth_rate": 0.05  # 5% growth
    },
    
    # Repurchase timing and funding
    repurchase_strategy={
        "timing": "immediate",  # Buy shares right away
        "funding_source": "trust_cash"  # Use available cash
    },
    
    # Company financial projections
    financial_projections={
        "revenue_growth": 0.06,
        "ebitda_margin": 0.22,
        "payroll_growth": 0.03
    },
    
    # Turnover assumptions
    turnover_assumptions={
        "use_predictive_model": True,
        "base_turnover_rate": 0.08  # 8% annual turnover
    }
)
```

## Step 3: Provide Initial State

Current ESOP status (simplified for example):

```python theme={null}
from villagelabs import InitialState, Participant, ESOPLoan

initial_state = InitialState(
    census_year=2024,
    
    # Employee census (showing 3 of 100 for brevity)
    participants=[
        Participant(
            id="EMP001",
            age=45,
            hire_date="2016-01-15",
            service_years=8,
            annual_compensation=75_000,
            allocated_shares=950,
            vested_percentage=0.80
        ),
        Participant(
            id="EMP002",
            age=38,
            hire_date="2019-03-20",
            service_years=5,
            annual_compensation=65_000,
            allocated_shares=600,
            vested_percentage=0.60
        ),
        Participant(
            id="EMP003",
            age=55,
            hire_date="2014-08-10",
            service_years=10,
            annual_compensation=95_000,
            allocated_shares=1_200,
            vested_percentage=1.00
        ),
        # ... 97 more employees
    ],
    
    # Trust cash balances
    trust_cash={
        "participant_cash_accounts": 75_000,
        "unallocated_company_contributions": 100_000,
        "unallocated_forfeiture_cash": 25_000
    },
    
    # ESOP loan details
    esop_loans=[
        ESOPLoan(
            loan_id="LOAN_2020_INITIAL",
            origination_date="2020-01-01",
            original_principal=3_000_000,
            principal_balance=2_100_000,  # 4 years paid
            interest_rate=0.065,
            term_years=10,
            payment_schedule="amortizing",
            suspense_shares=21_000,  # 9,000 already released
            original_suspense_shares=30_000
        )
    ],
    
    # Share counts
    total_shares_outstanding=80_000,
    allocated_shares=59_000,  # To 100 participants
    unallocated_shares=0
)
```

## Step 4: Configure Simulation

Runtime settings:

```python theme={null}
from villagelabs import SystemConfiguration

system_config = SystemConfiguration(
    projection_years=10,  # 2025-2034
    include_turnover_projection=True,
    run_sensitivity_analysis=False,
    output_format="detailed"
)
```

## Step 5: Run Simulation

Execute the forecast:

```python theme={null}
from villagelabs import RepurchaseEngine

# Initialize engine
engine = RepurchaseEngine(api_key="your_api_key")

# Run simulation
results = engine.simulate(
    plan_rules=plan_rules,
    operating_assumptions=operating_assumptions,
    initial_state=initial_state,
    system_config=system_config
)

print(f"Simulation completed in {results.execution_time_ms}ms")
```

## Step 6: Analyze Results

### Summary Metrics

```python theme={null}
# High-level insights
print(f"10-Year Repurchase Obligation: ${results.total_repurchase_obligation:,.0f}")
# Output: 10-Year Repurchase Obligation: $8,450,000

print(f"Peak Cash Year: {results.peak_cash_year}")
# Output: Peak Cash Year: 2029

print(f"Peak Cash Amount: ${results.peak_cash_amount:,.0f}")
# Output: Peak Cash Amount: $1,250,000

print(f"Average Annual Contribution: ${results.average_annual_contribution:,.0f}")
# Output: Average Annual Contribution: $500,000

print(f"Final Trust Cash (2034): ${results.final_trust_cash:,.0f}")
# Output: Final Trust Cash (2034): $425,000
```

### Year-by-Year Breakdown

```python theme={null}
# Detailed annual projections
for year in results.annual_projections:
    print(f"\n=== Year {year.year} ===")
    print(f"  Contribution: ${year.company_contribution:,.0f}")
    print(f"  Shares Released: {year.shares_released:,.0f}")
    print(f"  Repurchases: ${year.repurchase_amount:,.0f}")
    print(f"  Ending Cash: ${year.ending_trust_cash:,.0f}")

# Output:
# === Year 2025 ===
#   Contribution: $500,000
#   Shares Released: 3,000
#   Repurchases: $425,000
#   Ending Cash: $275,000
#
# === Year 2026 ===
#   Contribution: $500,000
#   Shares Released: 3,000
#   Repurchases: $680,000
#   Ending Cash: $195,000
# ...
```

### Repurchase Obligation Trend

```python theme={null}
import matplotlib.pyplot as plt

years = [proj.year for proj in results.annual_projections]
repurchases = [proj.repurchase_amount for proj in results.annual_projections]

plt.figure(figsize=(10, 6))
plt.plot(years, repurchases, marker='o', linewidth=2)
plt.title('Projected Repurchase Obligations')
plt.xlabel('Year')
plt.ylabel('Repurchase Amount ($)')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
```

### Participant Analysis

```python theme={null}
# Focus on a specific participant
emp_003_timeline = results.get_participant_timeline("EMP003")

for snapshot in emp_003_timeline:
    print(f"Year {snapshot.year}: {snapshot.allocated_shares} shares, "
          f"${snapshot.account_value:,.0f} value")

# Output:
# Year 2025: 1,230 shares, $136,290 value
# Year 2026: 1,260 shares, $150,570 value
# Year 2027: 1,295 shares, $166,805 value
# ...
```

## Step 7: Create Scenarios

Compare different contribution strategies:

```python theme={null}
# Scenario A: Current plan ($500K/year)
results_a = engine.simulate(..., contribution=500_000)

# Scenario B: Reduced contribution ($400K/year)
operating_assumptions_b = operating_assumptions.copy()
operating_assumptions_b.contribution_policy["annual_amount"] = 400_000
results_b = engine.simulate(..., operating_assumptions=operating_assumptions_b)

# Compare
comparison = engine.compare_scenarios(results_a, results_b)

print(f"Contribution difference: ${comparison.contribution_delta:,.0f}")
print(f"Repurchase obligation impact: ${comparison.repurchase_delta:,.0f}")
print(f"Recommendation: {comparison.recommendation}")

# Output:
# Contribution difference: $1,000,000 over 10 years
# Repurchase obligation impact: +$450,000 (Scenario B higher)
# Recommendation: Maintain $500K contribution for better cash management
```

## Key Insights from Example

<AccordionGroup>
  <Accordion title="Repurchase obligations peak in 2029" icon="chart-line">
    This is when early participants (hired 2014-2016) begin retiring with significant vested balances. Plan sponsors should begin accumulating cash reserves now.
  </Accordion>

  <Accordion title="Loan payoff reduces future flexibility" icon="file-invoice-dollar">
    Once the 2020 loan is fully paid (2030), no more suspense shares remain for allocation. Future contributions must be cash, not share releases.
  </Accordion>

  <Accordion title="Diversification creates cash demand" icon="chart-pie">
    Participants over 55 with 10+ years can diversify starting in 2025. This creates additional cash needs beyond repurchases.
  </Accordion>

  <Accordion title="Share price growth drives obligations" icon="arrow-trend-up">
    5% annual growth means account values grow faster than contributions, increasing future repurchase costs.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Multi-Loan Example" icon="layer-group" href="/examples/multi-loan">
    Model a complex leveraged ESOP with multiple loans
  </Card>

  <Card title="Diversification Planning" icon="chart-pie" href="/examples/diversification">
    Focus on diversification impact
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/simulate">
    Full API documentation
  </Card>

  <Card title="Data Models" icon="database" href="/models/overview">
    Deep dive into object structures
  </Card>
</CardGroup>
