How Can One Arbitrage in Football Betting? (Part 5)
The previous articles have covered the full process from market rules, payout matrix, linear solving, to real-time filtering. This article covers the final step: how strategy results are output, what each field means, and what still needs to be checked before a theoretical arbitrage result can be executed.
Q: What does one internal strategy result look like?
After linear solving, the strategy forms an internal tip. It can be understood as a group of betting suggestions:
[
EV,
special_win,
event,
hedge_match,
amount_rate
]
The most important parts are:
| Field | Meaning |
|---|---|
| EV | Effective return multiplier after rebate |
| event | Match identifier |
| hedge_match | Which legs this arbitrage group contains |
| amount_rate | Stake ratio for each leg |
For example, an over/under arbitrage result can be:
EV = 1.007
event = "World Cup|ArgentinaVS Cape Verde"
hedge_match = [
["over", "2.5", "m88", "2.05"],
["under", "2.5", "ps888", "1.98"]
]
amount_rate = [0.4913, 0.5087]
This means 49.13% of the total bankroll goes to M88 Over 2.5, and 50.87% goes to PS888 Under 2.5. If the total stake is 1000, the actual stake amounts are:
| Leg | Stake ratio | Amount under 1000 bankroll |
|---|---|---|
| Over 2.5 | 0.4913 | 491.30 |
| Under 2.5 | 0.5087 | 508.70 |
EV=1.007 does not mean "profit is 1.007 yuan." It means every 1 yuan staked theoretically returns 1.007 yuan. The net return rate is:
\[ EV-1=0.007=0.7\% \]
So under a 1000 bankroll, theoretical net profit is about:
\[ 1000\times(1.007-1)=7 \]
Q: Why does one strategy output multiple rows?
One arbitrage group usually contains multiple betting legs. A database or CSV result table outputs by leg, so the same strategy_id corresponds to multiple rows.
Example:
| strategy_id | event_id | EV | dealer | bettype | handicap | odd | amount |
|---|---|---|---|---|---|---|---|
| arbitrage_fast_20260706_120001_001 | World Cup|ArgentinaVS Cape Verde | 1.007 | m88 | over | 2.5 | 2.050 | 0.4913 |
| arbitrage_fast_20260706_120001_001 | World Cup|ArgentinaVS Cape Verde | 1.007 | ps888 | under | 2.5 | 1.980 | 0.5087 |
These two rows are not two independent strategies. They are two legs of the same strategy. They must be executed together. Executing only one row has no arbitrage meaning.
Q: What do the output fields mean?
The core output fields are:
| Field | Meaning |
|---|---|
| strategy_id | Unique id of one arbitrage strategy group |
| event_time | Match time |
| event_key | Standardized match key |
| event_id | Display match identifier, usually including time and event key |
| EV | Effective return multiplier |
| profit | Same as EV, kept as a compatibility field |
| dealer | Betting platform or data source |
| bettype | Standardized market type |
| handicap | Market line |
| odd | Output odds, kept to three decimals |
| amount | Stake ratio |
The most easily misunderstood field is amount. It is not an absolute amount. It is a capital ratio. If the total bankroll you plan to use is \(M\), the real stake is:
\[ \text{stake}_i=M\times\text{amount}_i \]
Example:
| amount | Total bankroll 1000 | Total bankroll 5000 |
|---|---|---|
| 0.4913 | 491.30 | 2456.50 |
| 0.5087 | 508.70 | 2543.50 |
Another easily misunderstood field is profit. In the current output, it uses the same value as EV. More accurately, it is not absolute profit and not net profit amount. It is the effective return multiplier. Net return rate should be:
\[ EV-1 \]
Absolute net profit should be:
\[ M\times(EV-1) \]
Q: Why does the result include traceability fields?
Arbitrage results are very sensitive to data quality. A wrong source game id, an expired timestamp, or an invalid market can turn a strategy result into a false signal.
So the output also carries traceability fields:
| Field | Purpose |
|---|---|
| source_event_id | Match id in the original source |
| source_game_id | Game id in the original source |
| quote_timestamp | Quote time |
| quote_age_seconds | Quote age |
| snapshot_run_id | Crawl batch |
| market_selection_key | Market selection key |
| freshness_status | Freshness status |
| validation_status | Validation status |
| validation_message | Validation message |
These fields are not for manual arbitrage calculation. They are for execution and review. If one group looks very good but quote_age_seconds is already large, it should be treated carefully. If validation_status is not valid, the result should not be treated as executable.
Q: Why keep only the best group per match?
One match may have several arbitrage combinations at the same time, such as moneyline combinations, over/under combinations, or handicap plus over/under combinations. But these combinations usually occupy the same match capital and can interfere with one another at execution.
The current strategy uses a conservative output method: for each match, only the group with the highest EV is kept.
The benefits are:
- The result table is clearer.
- The same match does not repeatedly occupy capital.
- Exposure risk from executing multiple combinations at once is lower.
If portfolio-level capital optimization is needed, it can be added after this layer. The single-match strategy itself only finds the best current group for that match.
Q: How are results written to the latest table?
Each run generates current result rows and replaces the latest results for this arbitrage_fast strategy type. This means the result table represents "currently visible opportunities," not the full historical opportunity set.
There are two reasons:
- Arbitrage opportunities are highly time-sensitive. Keeping old results visible will mislead execution.
- The execution side needs the current markets that can still be checked and placed, not expired historical signals.
If historical review is needed, it should use archive tables or log tables. The latest table only serves current decision-making.
Q: What must be checked before execution?
The theoretical model only proves that under current odds and rules, the stake ratios can form positive return. Real trading still needs several checks.
First, whether the odds still exist. Arbitrage often disappears quickly, especially after cross-bookmaker price differences appear.
Second, whether each company allows the required stake amount. Current amount is a ratio, not a platform limit. If one leg can only accept a small amount, the total bankroll of the whole group must shrink.
Third, whether order sequence is controllable. Multi-leg arbitrage is most afraid of placing the first leg, then seeing the second leg move or fail. The more legs there are, the worse this problem becomes.
Fourth, whether rebate is actually obtainable. If EV is greater than 1 only because of rebate, the rebate rules, cycle, and conditions must be confirmed.
Fifth, whether rules are fully consistent. Different companies may handle extra time, penalties, match interruption, and market cancellation differently. The strategy is modeled under standard football 90-minute rules, but platform terms must still be checked before execution.
Q: What is the core of this strategy?
From Part 1 to Part 5, the whole idea can be compressed into one sentence:
Do not guess arbitrage by market name. Write each market as a payout vector over all score states, then find a nonnegative linear combination of those vectors so that total return covers stake under every score.
In formula form:
\[ x_i\ge0,\quad \sum_i x_i=1 \]
\[ R_j=p_j\cdot x,\quad \forall j \]
\[ \min_j R_j>1 \]
If rebate is considered:
\[ EV=\min_j R_j+\sum_i b_i x_i \]
Each row in the output table is only one betting leg of this linear combination. Only all rows under the same strategy_id executed together form the complete strategy.
This is the biggest difference between football betting arbitrage and ordinary odds comparison. The real calculation object is not a single price, but the structure formed by rules, score states, return matrix, and stake ratios.