| CAPITAL | AVG WEEKLY | AVG MONTHLY | AVG YEARLY | P(PROFIT) 1Y | P(DOWN) 1Y | P(LOSE HALF) | P(NEAR ZERO) |
|---|---|---|---|---|---|---|---|
| Loading… | |||||||
Stored in this browser only and sent with each scan — never written to the server, never logged, and not shared with the other accounts. Clearing your browser data removes them. The session token is the part that expires daily; the application key is not.
Two values, two different places, and only one of them expires. Betfair calls them both “keys” in places, which is most of the confusion.
A · Application key — once, never expires
Create the app, once
You need a funded Betfair account. Log in, then run thecreateDeveloperAppKeys
call once with any name you like. If you have done this before, skip to the next step —
running it twice fails with APP_KEY_CREATION_FAILED, which is not a real problem.
Read your keys back
getDeveloperAppKeys returns two versions
of the same app.
curl -s https://api.betfair.com/exchange/account/json-rpc/v1 \
-H "X-Authentication: <SESSION TOKEN>" \
-H "Content-Type: application/json" \
-d '[{"jsonrpc":"2.0","method":"AccountAPING/v1.0/getDeveloperAppKeys","params":{},"id":1}]'
Take the DELAYED one
The response has twoapplicationKey values. Take the one whose
delayData is true. That is the free
key and the one this page wants. The delayData:false key is the live-price
key and needs a paid subscription — using it here returns
ACCESS_DENIED, which reads like a broken key but is a billing state.
B · Session token — expires about every 24 hours
Log in for a token
The interactive endpoint takes your normal username and password and hands back a token. Run this from a terminal, not from this page — the page never sees your password. curl -s https://identitysso.betfair.com/api/login \ -H "X-Application: <APPLICATION KEY>" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=<USER>&password=<PASS>"Copy the token field
A success looks like{"token":"...","status":"SUCCESS"}. Paste the
token value, not the whole response. If status is
LIMITED_ACCESS the login worked but the account needs certification
completed on the Betfair site first.
Expect to redo this daily
The token dies after roughly a day, and the symptom is anINVALID_SESSION_INFORMATION error carried on an HTTP
200, not a 403.
Fix the token before the key. Betfair validates the session first: with a definitely-invalid application key and a bad token it still answers
INVALID_SESSION_INFORMATION, never INVALID_APP_KEY.
So a key simply cannot be verified until a valid token is in hand, and a key
error only becomes visible once the token is good.
A non-expiring certificate login is the proper answer for unattended scanning
and is not set up yet.
api.betfair.com normally, while some networks are refused outright by
Cloudflare with a 403.
A 403 is never a credential problem. The blocked response is byte-identical whether a wrong application key is sent or none at all, so it carries no information about your credentials. Betfair reports every credential failure as an HTTP 200 with a JSON error. A 403 means the request did not reach the API, and no key or token will change it.
The two endpoints refuse opposite traffic:
api.betfair.com.au rejects the server (non-AU), and
api.betfair.com rejects some AU networks. This page uses
api.betfair.com from the server, which is the combination that works.
Kept in memory for this page load only, and truncated to the last 200 lines. Credentials are never written here — keys appear as their last four characters and tokens only as a length.
CHECK A WHOLE CARD AT ONCE
One bet per line: odds, or odds, stake, or
odds, stake, label. Everything is scored against the same rule.
The promo is the scarce resource, not money and not candidates — without one every band is negative. Record what you hold and the allocator spends them on the races worth the most.
This is not arbitrage, and it is not a betting edge. The raw bets LOSE 8.2% of turnover — odds taken sit about 9% below Betfair SP and only 13% of bets beat market price. Every dollar of profit comes from bonus-back promotions, which add 21.6%. Net +12.8%.
Anything above 6.0 loses even with the promo attached. An odds ceiling of 6.0 is better in 4 of 5 years and keeps 91% of bets: ROI +13.4% → +14.8%, losing weeks 30% → 25%.
Profit is capped by promo limits, not bankroll — roughly $50 a bet, ~40 bets a week. $10,000 earns the same as $5,000 because the extra capital cannot be deployed. The measurable risk is not variance, it is restriction: bets beating Betfair SP fell from 22.5% in 2020 to 9–13% by 2023, while the promo return itself held at ~21.5% every single year.
Every backtest figure in this project inherits whatever yfinance got wrong, and until now that has been an assumption rather than a measurement. This pulls the same window from both sources and differences them. If they agree, the coverage matrix stands and IBKR buys us only bid/ask and realistic fills. If they diverge, the matrix needs rebuilding on better bars.
Nineteen rounds, one verified edge.
Approaches tested and rejected. They are here so they do not get proposed again: a negative result costs the same to earn as a positive one, and most of the work behind this page produced negatives. Anything listed was measured, not dismissed.
Older exclusions, still excluded. These predate the cost-corrected engine, and none were re-opened by it.
The same pattern generators feed both the backtester and the live paper engine — which is what makes the live-vs-backtest comparison above meaningful rather than a comparison of two different systems. The broker layer is a stub: nothing places a real order.
Every pattern against every market, 5 years of daily bars, 8 concurrent positions, $25,000, run twice — once gross and once with the real fee schedule. The gap between the two is the whole story. Cells are coloured by net profit factor against a break-even midpoint; each prints its own number, so the colour only reinforces.
Live results sit above the backtest in every comparison. Not one is statistically distinguishable from noise — confirming the VWAP gap needs about 264 closed trades and there are 22; the EMA_PB gap needs 96 and there are 3.
| # | Ticker | Sector | Best Pattern | Win Rate ↓ | Frac W/L | Profit Factor | Pseudo-Sharpe ⓘ | Total PnL | Trades | Max DD |
|---|---|---|---|---|---|---|---|---|---|---|
Run Scanner Select your universe and click SCAN ALL STOCKS | ||||||||||
H12 (R16/R21), US H8 (R17), JACOB 96 bars.
| STARTED | DURATION | STRATEGIES | TRADES | W-L | WR | PF | FEES | MAX DD | NET P&L | |
|---|---|---|---|---|---|---|---|---|---|---|
| Loading… | ||||||||||
| STRATEGY | PATTERN | UNIVERSE | EVIDENCE |
|---|---|---|---|
| US_BROAD | EMA_PB | 190 liquid US equities + ETFs | PF 1.16 · 5yr n=1,229 |