Know your real odds of passing a prop firm challenge before you pay the fee.
You know your win rate and your average R:R. The firm publishes its profit target and drawdown limits. Between those numbers sits the one you actually care about, your probability of getting funded, and almost nobody bothers to compute it. People guess, pay, fail and pay again.
prop-odds is a Monte Carlo simulator for evaluation challenges (two-step, one-step, trailing drawdown). Give it your stats and it gives you numbers:
$ prop-odds run --preset two-step-classic --win-rate 0.45 --rr 2 --risk 1 --trades-per-day 3
┌──────────────────────────────────────────────────────────────────────────┐
│ prop-odds: two-step-classic │
├──────────────────────────────────────────────────────────────────────────┤
│ trader win rate 45% | R:R 2 | risk 1%/trade | 3 trades/day │
│ edge expectancy +0.350R per trade │
└──────────────────────────────────────────────────────────────────────────┘
Phase 1
pass 96.8%
fail (daily) 0.0% fail (total) 3.2% timeout 0.0%
days to pass median 6, mean 8.0
Phase 2
pass 97.2%
➜ P(funded) : 94.1%
➜ expected attempts : 1.1
➜ expected days when funded: 14 trading days
➜ expected fees per funded : 573 (before any refund)
Simulated on the classic two-step rule set (8%/5% targets, 5% daily loss, 10% max loss), 50k paths, 1% risk, 3 trades per day:
| Trader | Expectancy | P(funded) | Expected fees per funded account |
|---|---|---|---|
| 45% WR, 2R | +0.35R | 94% | ~575 |
| 40% WR, 1.5R | 0.00R (no edge at all) | 36% | ~1,500 |
| 38% WR, 1.5R | −0.05R | 21% | ~2,600 |
Read the middle row again. A trader with zero edge passes a two-step challenge about one time in three. Passing once proves very little. It also explains why social media is full of funded traders who later blow up, and why selling challenges is such a good business. What separates an edge from luck is staying funded, and the fees column shows what the attempt grinder really pays.
Your risk per trade interacts with the daily loss limit in a way most people miss: the limit quantizes risk. At 3 trades a day with a 5% daily limit, risking 1.5% means three straight losses cost you 4.5%, so the daily limit is mathematically out of reach. At 1.75%, those same three losses cost 5.25% and the account is gone.
$ prop-odds sweep --preset two-step-classic --win-rate 0.45 --rr 2 --trades-per-day 3
risk/trade │ P(funded) │ E[days] │ fees per funded
───────────────────────────────────────────────────
0.50% │ 99.7% │ 26 │ 540
1.00% │ 93.9% │ 14 │ 574
1.50% │ 84.5% │ 11 │ 638
1.75% │ 42.5% │ 8 │ 1,269 ← the cliff
2.50% │ 31.9% │ 8 │ 1,689
Lower risk almost always raises P(funded), but it costs more days. The sweep shows what each extra day of patience buys you.
pip install prop-odds # numpy only
pip install "prop-odds[charts]" # adds PNG charts
prop-odds presets # bundled rule sets
prop-odds run --preset one-step-trailing --win-rate 0.5 --rr 1.5 --risk 0.5 --charts out/
prop-odds sweep --preset two-step-classic --win-rate 0.45 --rr 2
prop-odds run --rules my_firm.json ... # your own rules, one JSON file
Or from Python:
from prop_odds import TraderProfile, load_preset, simulate_challenge
me = TraderProfile(win_rate=0.45, rr=2.0, risk_pct=1.0, trades_per_day=3)
outcome = simulate_challenge(me, load_preset("two-step-classic"), n_paths=100_000, seed=42)
print(f"P(funded) = {outcome.funded_rate:.1%}")- Fixed risk per trade, expressed as a percentage of the initial phase balance. That is how firms compute limits and how most challenge takers size.
- Trades are i.i.d.: you win
rr × riskwith probabilitywin_rate, otherwise you loserisk. No fat tails, no autocorrelation, no tilt after a losing streak. Real trading is usually worse, so read these odds as optimistic. - Limits are checked after every trade. If you hit the target before the minimum number of trading days, the model assumes you coast at zero risk until the days are clocked.
- Not modeled yet: consistency rules, news-trading restrictions, slippage, payout mechanics.
The most useful contribution is rule sets: real firms' current rules as a preset JSON with a link to the source (there is an issue template for it). Model extensions are welcome too, custom R distributions and consistency rules in particular. pip install -e ".[dev]" && pytest.
This is a calculator. It simulates the assumptions you feed it, it does not predict your results, and it has no affiliation with any prop firm. Nothing here is financial advice.
MIT, Lucien Henriet

