Building Your First Model on Shoal
The model builder is where intuition meets evidence. You probably have some idea — a theory about when certain bets have value. Maybe it's about home underdogs in certain conditions. Maybe it's about teams in certain form windows. The model builder helps you turn that idea into a defined ruleset and test it against historical data.
This walkthrough explains the basics. We'll build a simple model: bet on home teams when they're underdogs (odds > 2.0) in a mid-table league position clash.
How the Builder Works
The canvas shows nodes connected by edges. Data flows left to right:
Data nodes define the universe of events you're considering.
Filter nodes narrow that universe based on conditions.
Logic nodes combine multiple conditions with AND, OR, NOT.
The output node defines what bet to place when conditions are met, and how to size it.
Step 1: Add a Sport Node
Drag a Sport node from the left panel onto the canvas. Click it and select "Soccer" (or whatever sport you're modelling).
This node represents every match in the historical dataset for that sport.
Step 2: Add a Competition Filter
Drag a Competition node and connect it after the Sport node. Select specific leagues, or leave it broad. For this example, leave it at all leagues.
Step 3: Add an Odds Range Filter
Drag a Filter → Odds Range node. Set:
- Selection: Home team
- Minimum odds: 2.00 (this filters for home underdogs)
Connect this to the Competition node.
Step 4: Add a Home/Away Filter
Drag a Filter → Team Position node. Set:
- Select: Home team within top 40–60% of table (mid-table, not elite)
Connect in series with the Odds Range filter. Your graph now reads: "Soccer matches where the home team is an underdog (2.00+) and in mid-table position."
Step 5: Set the Output
The Output node defines the bet:
- Selection: Home Win
- Staking: Flat $10
Connect the last filter to the Output node.
Step 6: Run the Backtest
Hit the backtest button. Set a date range (e.g., 2022–2024) and run.
The results panel shows:
- Total bets placed
- Win rate
- ROI
- P&L chart over time
- Individual bet breakdown
Interpreting Results
A few things to check:
Is the sample size large enough? Under 200 bets makes it hard to draw conclusions. A 55% win rate over 50 bets is almost certainly variance.
Is the ROI positive? Even if it is, check if it exceeds the typical vig margin. A 2% ROI on bets with a 5% vig isn't profitable.
Is the P&L chart smooth or jagged? A very jagged chart with huge swings suggests the model is high-variance. Even if profitable, it requires significant bankroll depth.
Does it make sense? A model that shows 30% ROI on 500 bets should be treated with extreme skepticism. It's more likely a bug, look-ahead bias, or a statistical coincidence than a genuine edge.
Look-Ahead Bias
A word of caution: be careful about any filter that uses information that wouldn't have been available at bet time. League position today isn't the same as league position before the match. Player injury data changes.
The mock data in Shoal is designed to minimize this, but as you build more complex models, think carefully about what information was actually available when the bet would have been placed.
What Next?
A model that shows promise in backtesting needs to be tested forward in time (paper trading) before real money is involved. Backtesting is a tool for eliminating bad ideas efficiently. A good backtest means your idea is worth watching — not that you've found guaranteed money.
From here, try:
- Adding more filter conditions (form, goals conceded, days since last match)
- Testing different staking strategies (Kelly vs. flat)
- Comparing results across different leagues or sports