
Montecarlo
- 43 installs
- 316 repo stars
- Updated August 1, 2026
- aojdevstudio/finance-guru
MonteCarlo is a skill that runs Monte Carlo simulations for a Finance Guru portfolio strategy, projecting income probabilities, margin safety, and outcomes over 28 months.
About
A skill that runs Monte Carlo simulations for a Finance Guru dividend-income and margin-living portfolio strategy. It runs 10,000 market scenarios over 28 months across a 4-layer portfolio to project income probabilities, margin-call rates, drawdowns, and break-even timing. A developer uses it to stress-test a portfolio, estimate probability of income targets, and incorporate buy tickets into projections.
- Runs 10,000-scenario Monte Carlo simulations over a 4-layer portfolio
- Projects income probabilities, margin-call rates, and drawdowns over 28 months
- Auto-detects portfolio values and can incorporate buy tickets
Montecarlo by the numbers
- 43 all-time installs (skills.sh)
- Ranked #622 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
montecarlo capabilities & compatibility
- Capabilities
- data analysis
- Works with
- excel
- Use cases
- data analysis · trading · research
- Pricing
- Free
What montecarlo says it does
Monte Carlo simulation engine for Finance Guru's 4-layer dividend income + margin living strategy. Runs 10,000 market scenarios to project income probabilities, margin safety, and portfolio outcomes o
Margin call rate** - % of scenarios triggering margin call (<3:1 ratio)
npx skills add https://github.com/aojdevstudio/finance-guru --skill montecarloAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 43 |
|---|---|
| repo stars | ★ 316 |
| Last updated | August 1, 2026 |
| Repository | aojdevstudio/finance-guru ↗ |
What it does
Run 10,000-scenario Monte Carlo simulations to project income probability, margin safety, and drawdowns for a portfolio.
Who is it for?
Stress-testing a dividend-income and margin portfolio and estimating probability of income targets.
Skip if: Single-point deterministic projections or non-portfolio simulations.
When should I use this skill?
When you want to run a Monte Carlo simulation, stress test a portfolio, or analyze margin-call probability.
What you get
Probability distributions for income targets, margin-call rate, drawdown, and break-even timing across 10,000 scenarios.
- JSON summary statistics
- full-results CSV
- Excel analysis workbook
By the numbers
- 10,000 scenarios
- 28-month horizon
- 4-layer portfolio model
Files
MonteCarlo
Monte Carlo simulation engine for Finance Guru's 4-layer dividend income + margin living strategy. Runs 10,000 market scenarios to project income probabilities, margin safety, and portfolio outcomes over 28 months.
Workflow Routing
| Workflow | Trigger | File |
|---|---|---|
| RunSimulation | "run monte carlo", "simulate portfolio", "stress test" | workflows/RunSimulation.md |
| IncorporateBuyTicket | "include buy ticket", "add ticket to simulation" | workflows/IncorporateBuyTicket.md |
Examples
Example 1: Run standard Monte Carlo simulation
User: "Run the monte carlo simulation with current portfolio"
-> Invokes RunSimulation workflow
-> Auto-detects portfolio values from notebooks/updates/Portfolio_Positions_*.csv
-> Runs 10,000 scenarios with v3.0 4-layer model
-> Outputs JSON summary + full CSV + Excel to fin-guru-private/fin-guru/analysis/Example 2: Incorporate a buy ticket into simulation
User: "Run monte carlo with my new buy ticket from 12-31"
-> Invokes IncorporateBuyTicket workflow
-> Reads buy ticket from fin-guru-private/fin-guru/tickets/buy-ticket-2025-12-31-*.md
-> Parses YAML frontmatter + Execution Summary table from the canonical ticket format
-> Adjusts starting portfolio values based on ticket allocations
-> Runs simulation with updated positionsExample 3: Stress test margin safety
User: "What's my margin call probability?"
-> Invokes RunSimulation workflow
-> Focuses on margin_call_rate and margin_ratio metrics
-> Reports 5th percentile (worst case) margin ratioKey Metrics Produced
Success Metrics
- P($100k income) - Probability of reaching $100k annual dividend income
- P($75k income) - Probability of reaching $75k annual dividend income
- P($50k income) - Probability of reaching $50k annual dividend income
- Margin call rate - % of scenarios triggering margin call (<3:1 ratio)
- Backstop usage rate - % of scenarios requiring business income injection
Portfolio Metrics
- Total portfolio value - Median, P5, P95 at month 28
- Layer 1 (Growth) - PLTR, TSLA, VOO, etc. (no new deployment)
- Layer 2 (Income) - Dividend funds ($11,517/month deployment)
- Layer 3 (Hedge) - SQQQ ($800/month deployment)
- GOOGL position - Scale-in ($1,000/month deployment)
Risk Metrics
- Margin ratio - Portfolio / Margin debt (must stay >3:1)
- Max drawdown - Worst peak-to-trough decline
- Break-even timing - When dividends cover margin draws
Output Files
All outputs saved to fin-guru-private/fin-guru/analysis/:
monte-carlo-v3-{date}.json- Summary statisticsmonte-carlo-v3-full-results-{date}.csv- All 10,000 scenariosmonte-carlo-v3-analysis-{date}.xlsx- Excel workbook with charts
Configuration
Simulation parameters are set in fin-guru-private/strategies/dividend_margin_monte_carlo.py:
- Starting portfolio values (auto-detected or manual)
- Monthly deployment amounts
- Bucket allocations and yields
- Margin schedule
- Market regime probabilities
Model Version
v3.0 (Jan 2026) - Full 4-layer portfolio:
- Layer 1: Growth portfolio (market returns only, no new deployment)
- Layer 2: Income portfolio (5-bucket dividend allocation)
- Layer 3: Hedge (SQQQ for crisis protection)
- GOOGL: Scale-in position (diverted from Layer 2)
Fixes applied:
- Floor at $0 for all positions (stocks can't go negative)
- Full portfolio margin ratio (all layers count toward Fidelity margin)
- Correct starting values from Fidelity CSV
PortfolioParser Reference
How to parse Fidelity CSV files for Monte Carlo simulation starting values.
Fidelity CSV Format
The Fidelity positions CSV (Portfolio_Positions_*.csv) has this structure:
Account Number,Account Name,Investment Type,Symbol,Description,Quantity,Last Price,Last Price Change,Current Value,...Important Columns
| Index | Column Name | Contains |
|---|---|---|
| 3 | Symbol | Ticker symbol (e.g., PLTR, JEPI) |
| 8 | Current Value | Dollar value of position |
| 2 | Investment Type | Stocks, ETFs, Mutual Funds |
CSV Quirks
1. BOM Character: File may start with UTF-8 BOM (\ufeff) 2. Duplicate Holdings: Same ticker can appear twice (margin + cash positions) 3. Pending Activity: Last row shows pending transactions, not a holding 4. Footer Rows: Disclaimer text appears after holdings
Layer Classification
Layer 1: Growth (Keep 100%)
LAYER1_TICKERS = {
'PLTR', 'TSLA', 'NVDA', 'AAPL', 'VOO', 'FNILX', 'SPMO',
'VXUS', 'FZILX', 'SOFI', 'COIN', 'MSTR', 'PARR'
}Layer 2: Income (Build with W2)
LAYER2_TICKERS = {
# JPMorgan Income
'JEPI', 'JEPQ',
# CEF Stable
'CLM', 'CRF', 'ECAT',
# Covered Call ETFs
'QQQI', 'SPYI', 'QQQY',
# YieldMax
'YMAX', 'AMZY', 'MSTY',
# DRIP v2 CEFs
'BDJ', 'ETY', 'ETV', 'BST', 'UTG'
}Layer 3: Hedge
LAYER3_TICKERS = {'SQQQ'}Special Positions
GOOGL_TICKERS = {'GOOGL'}Parsing Algorithm
import pandas as pd
def parse_portfolio(csv_path: str) -> dict:
"""Parse Fidelity CSV and return layer values."""
# Read CSV, handling BOM
df = pd.read_csv(csv_path, encoding='utf-8-sig')
# Filter to valid holdings (has Symbol and Current Value)
df = df[df['Symbol'].notna() & df['Current Value'].notna()]
# Remove "Pending activity" row
df = df[df['Symbol'] != 'Pending activity']
# Parse Current Value (remove $ and ,)
df['Value'] = df['Current Value'].str.replace('[$,]', '', regex=True).astype(float)
# Sum by layer
layer1 = df[df['Symbol'].isin(LAYER1_TICKERS)]['Value'].sum()
layer2 = df[df['Symbol'].isin(LAYER2_TICKERS)]['Value'].sum()
layer3 = df[df['Symbol'].isin(LAYER3_TICKERS)]['Value'].sum()
googl = df[df['Symbol'].isin(GOOGL_TICKERS)]['Value'].sum()
return {
'layer1': layer1,
'layer2': layer2,
'layer3': layer3,
'googl': googl,
'total': layer1 + layer2 + layer3 + googl
}Extracting Margin Balance
The margin balance is found in the Balances CSV (Balances_for_Account_*.csv):
def parse_margin(balance_csv: str) -> float:
"""Extract current margin debt from Fidelity balance CSV."""
df = pd.read_csv(balance_csv, encoding='utf-8-sig', header=None)
# Find "Pending activity" or negative cash
for idx, row in df.iterrows():
if 'Net debit' in str(row[0]):
# Net debit is negative margin balance
value = str(row[1]).replace('$', '').replace(',', '').replace('-', '')
return float(value)
return 0.0Alternatively, check the "Pending activity" row in positions CSV which shows the margin debt as a negative value.
Example Output
>>> parse_portfolio('notebooks/updates/Portfolio_Positions_Jan-02-2026.csv')
{
'layer1': 170073.42,
'layer2': 61725.18,
'layer3': 13198.87,
'googl': 1875.52,
'total': 246872.99
}Handling Edge Cases
Duplicate Positions
Same ticker in margin AND cash accounts:
JEPI (Margin): $4,212.85
JEPI (Cash): $2,059.83
Total JEPI: $6,272.68The parsing algorithm sums both positions automatically.
New Tickers
If user adds a new ticker not in classification: 1. Check the ticker's characteristics 2. Assign to appropriate layer 3. Update the ticker sets in this reference
Missing CSV
If positions CSV not found: 1. Check notebooks/updates/ for latest file 2. Ask user to download fresh export from Fidelity 3. Use last known values as fallback
# Placeholder for future CLI tools
# e.g., PortfolioParser.ts, SimulationRunner.ts
IncorporateBuyTicket Workflow
Incorporate a specific buy ticket into the Monte Carlo simulation by adjusting starting portfolio values.
When to Use
Use this workflow when the user wants to:
- Include a recent buy ticket in the simulation
- See how a specific purchase affects projections
- Model a deployment that hasn't yet been reflected in Fidelity CSV
Workflow Steps
Step 1: Find the Buy Ticket
Search for buy tickets in fin-guru-private/fin-guru/tickets/:
ls -la fin-guru-private/fin-guru/tickets/buy-ticket-*.mdIf user specifies a date (e.g., "12-31"), find the matching ticket:
ls fin-guru-private/fin-guru/tickets/buy-ticket-*12-31*.md 2>/dev/null || ls fin-guru-private/fin-guru/tickets/buy-ticket-2025-12-31*.md 2>/dev/nullStep 2: Parse the Buy Ticket
Read the buy ticket and extract:
- Frontmatter metadata:
deployment_amountcash_availableprice_snapshot_as_ofgenerated_on- Execution Summary allocations: Which tickers and how much to each
Example buy ticket format:
---
document_type: buy-ticket
deployment_amount: "$5,054.09"
cash_available: "$6,000.00"
price_snapshot_as_of: "2026-01-31T09:45:00-05:00"
---
## Execution Summary
| Ticker | Category | Weight | $ Amount | Price | Shares |
|--------|----------|--------|----------|-------|--------|
| JEPI | JPMorgan Income | 10.0% | $500 | $55.00 | 9.09 |
| JEPQ | JPMorgan Income | 10.0% | $500 | $52.00 | 9.61 |
| CLM | CEF Stable | 20.0% | $1,000 | $7.50 | 133.33 |
...Step 3: Categorize Allocations by Layer
Layer 2 allocations (most buy tickets):
- Any income fund: JEPI, JEPQ, QQQI, SPYI, QQQY, CLM, CRF, ECAT, BDJ, ETY, ETV, BST, UTG, YMAX, AMZY, MSTY
Layer 3 allocations:
- SQQQ
GOOGL allocations:
- GOOGL
Layer 1 allocations (rare in buy tickets):
- PLTR, TSLA, NVDA, AAPL, VOO, etc.
Step 4: Calculate Adjusted Starting Values
Get current portfolio values from RunSimulation workflow, then add:
adjusted_layer2 = current_layer2 + sum(layer2_allocations)
adjusted_layer3 = current_layer3 + sum(layer3_allocations)
adjusted_googl = current_googl + sum(googl_allocations)
adjusted_layer1 = current_layer1 + sum(layer1_allocations)Step 5: Update Simulation
Update fin-guru-private/strategies/dividend_margin_monte_carlo.py with adjusted values:
# Initialize with ADJUSTED values (includes buy ticket from {ticket_date})
layer1_portfolio = {adjusted_layer1} # Layer 1: Growth + ticket
income_portfolio = {adjusted_layer2} # Layer 2: Income + ticket
googl_position = {adjusted_googl} # GOOGL + ticket
hedge_position = {adjusted_layer3} # Layer 3: Hedge + ticket
margin_balance = {current_margin} # Margin unchanged by buy ticketStep 6: Run Simulation
Follow RunSimulation workflow steps 4-6.
Step 7: Document Changes
Note in the output that this simulation includes the buy ticket:
## Simulation Notes
- Includes buy ticket: {ticket_filename}
- Total additional deployment: ${ticket_total}
- Layer 2 adjustment: +${layer2_adjustment}
- Layer 3 adjustment: +${layer3_adjustment}
- GOOGL adjustment: +${googl_adjustment}Example
User Request: "Run monte carlo with my 12-31 payroll ticket"
Workflow Execution:
1. Find ticket: fin-guru-private/fin-guru/tickets/buy-ticket-2025-12-31-w2-payroll.md
2. Parse allocations:
- JEPI: $500
- JEPQ: $500
- CLM: $500
- SQQQ: $800
- etc.
3. Categorize:
- Layer 2: $4,254.09
- Layer 3: $800
- Total: $5,054.09
4. Adjust starting values:
- Layer 2: $61,725 + $4,254 = $65,979
- Layer 3: $13,199 + $800 = $13,999
5. Run simulation with adjusted values
6. Report results with note about included ticket
Important Notes
- Buy tickets typically deploy on payday (15th or last day of month)
- The Fidelity CSV may take 1-2 days to reflect new purchases
- If the ticket is already in the CSV, don't double-count!
- Check the ticket date vs. CSV date to avoid duplication
RunSimulation Workflow
Execute the Monte Carlo v3.0 simulation with auto-detected portfolio values.
Prerequisites
- Latest Fidelity positions CSV in
notebooks/updates/Portfolio_Positions_*.csv - Python environment configured with
uv
Workflow Steps
Step 1: Get Current Date
date +"%Y-%m-%d"Store as {simulation_date} for output file naming.
Step 2: Auto-Detect Portfolio Values
Read the latest Fidelity positions CSV from notebooks/updates/:
ls -t notebooks/updates/Portfolio_Positions_*.csv | head -1Parse the CSV to extract current values for each layer:
Layer 1 (Growth) - Sum of:
- PLTR, TSLA, NVDA, AAPL, VOO, FNILX, SPMO, VXUS, FZILX, SOFI, COIN, MSTR
Layer 2 (Income) - Sum of:
- JEPI, JEPQ, QQQI, SPYI, QQQY, CLM, CRF, ECAT, BDJ, ETY, ETV, BST, UTG, YMAX, AMZY, MSTY
Layer 3 (Hedge) - Sum of:
- SQQQ
GOOGL Position:
- GOOGL
Starting Margin:
- Look for "Pending activity" row or calculate from margin market value
Step 3: Update Simulation Starting Values
Edit fin-guru-private/strategies/dividend_margin_monte_carlo.py to update the starting values in run_single_scenario():
# Initialize portfolio components with ACTUAL {simulation_date} values
layer1_portfolio = {layer1_value} # Layer 1: Growth portfolio
income_portfolio = {layer2_value} # Layer 2: Current dividend portfolio value
googl_position = {googl_value} # Starting GOOGL value
hedge_position = {hedge_value} # Layer 3: Current SQQQ hedge value
margin_balance = {margin_value} # Starting margin debtStep 4: Run Simulation
uv run python fin-guru-private/strategies/dividend_margin_monte_carlo.pyThis produces:
- Console output with summary statistics
fin-guru-private/fin-guru/analysis/monte-carlo-v3-{date}.jsonfin-guru-private/fin-guru/analysis/monte-carlo-v3-full-results-{date}.csv
Step 5: Generate Excel Workbook
Update the paths in scripts/simulations/monte_carlo_excel_export.py if needed, then run:
uv run python scripts/simulations/monte_carlo_excel_export.pyThis produces:
fin-guru-private/fin-guru/analysis/monte-carlo-v3-analysis-{date}.xlsx
Step 6: Report Results
Present key metrics to the user:
Success Metrics:
- P($100k income): {probability_100k}
- P($75k income): {probability_75k}
- P($50k income): {probability_50k}
- Margin call rate: {margin_call_rate}
Portfolio at Month 28 (Median):
- Total value: ${median_total}
- Layer 1: ${median_layer1}
- Layer 2: ${median_layer2}
- Layer 3: ${median_hedge}
- GOOGL: ${median_googl}
Income at Month 28:
- Annual dividend: ${median_dividend}
- Range (P5-P95): ${p5_dividend} - ${p95_dividend}
Margin Safety:
- Median ratio: {median_ratio}:1
- Minimum ratio: {min_ratio}:1
- Backstop usage: {backstop_rate}%
Output Files
- JSON summary:
fin-guru-private/fin-guru/analysis/monte-carlo-v3-{simulation_date}.json - Full scenarios:
fin-guru-private/fin-guru/analysis/monte-carlo-v3-full-results-{simulation_date}.csv - Excel analysis:
fin-guru-private/fin-guru/analysis/monte-carlo-v3-analysis-{simulation_date}.xlsx
Layer Classification Reference
Layer 1 (Growth) - Keep 100%, NO new deployment
| Ticker | Description |
|---|---|
| PLTR | Palantir - Core growth |
| TSLA | Tesla - Core growth |
| NVDA | Nvidia - Core growth |
| AAPL | Apple - Core growth |
| VOO | S&P 500 ETF |
| FNILX | Zero-cost S&P 500 |
| SPMO | Momentum factor |
| VXUS | International |
| FZILX | Zero-cost international |
| SOFI | Fintech growth |
| COIN | Crypto proxy |
| MSTR | Bitcoin proxy |
| PARR | New growth position |
Layer 2 (Income) - Build with W2, $11,517/month
| Bucket | Tickers | Allocation |
|---|---|---|
| JPMorgan Income | JEPI, JEPQ | 27% |
| CEF Stable | CLM, CRF, ECAT | 20% |
| Covered Call ETFs | QQQI, SPYI, QQQY | 35% |
| YieldMax | YMAX, AMZY | 10% |
| DRIP v2 CEFs | BDJ, ETY, ETV, BST, UTG | 8% |
Layer 3 (Hedge) - Build with W2, $800/month
| Ticker | Description |
|---|---|
| SQQQ | 3x Inverse Nasdaq |
GOOGL Scale-In - Diverted from Layer 2, $1,000/month
| Ticker | Description |
|---|---|
| GOOGL | Alphabet - Top AI stock 2026 |
Related skills
FAQ
How many scenarios does it run?
10,000 market scenarios over 28 months using the v3.0 4-layer model.
What metrics does it produce?
Probability of income targets, margin-call rate, backstop usage rate, portfolio value percentiles, drawdown, and break-even timing.