Do you have a friend who likes betting and would like to sharpen his/her action? Help them on their path by sharing the BowTiedBettor Substack. Win and help win!
Welcome Degen Gambler!
It’s time to enter one of the most dangerous territories in betting markets, the Betfair Exchange.
Since
There is a decent barrier to entry [knowledge-wise],
It’s one of very few places where you won’t be thrown out for winning a bet or two,
you’ll naturally be up against the creme de la creme of gambling markets. Therefore, tread carefully or get rekt [& poor].
Betfair is peer-to-peer, i.e. every time you get matched on a trade there’s another gambler out there taking the other side of it, much like classic order book action in crypto/stock markets. Compared to the other ‘real’ betting alternative, parimutuels [where everyone places their bets & the odds are calculated at post time], this gambler-to-gambler matching is *a great feature* since it only requires you to beat *one counterparty* as opposed to a complete market [weighted average of many opinions]. Not really a relevant fact in highly liquid instruments [why?] but far from every market is perfectly liquid. Finding one degen is easier than finding a whole army of them [the latter may present a far superior opportunity though].
Now, since we’re on this side of the web we won’t just enter the exchange markets with boring, manual trading.
Instead we’ll utilize one of the great advantages of Betfair, the Betfair API, & code up a Betting Bot that will do the work for us.
For a gentle introduction to the Betfair API, see this post.
So what’s a Betting Bot?
It’s simple, really.
You have *an idea/a potential edge* which [if your plan is to make any money from it] can be converted into A Trade.
With this idea/trade setup, you’ve got two options.
Option Number One: stay at the desk 24/7, scan the markets manually to look for opportunities where you could run The Trade, & then run it if certain conditions/requirements are satisfied.
Option Number Two: map your thoughts/conditions into code & let your computer perform the tasks for you.
Needless to say, Option Number Two is the better option.
Note: We’re assuming you’re in it to *win it* [long-term] here. If you’re only going to place a trade or two on rare one-time events it of course makes no sense to do it programmatically.
But how do we *actually go through* with Option Number Two, i.e. Build & Deploy A [hopefully profitable] Betfair Bot?
Well, that’s what this post will explain.
Note: Our coding/programming material assumes that you have some familiarity with Python. If you don’t, go learn it or be left behind.
Except for Betfair’s guides [takes some time to find the good stuff, but check this site out] there really isn’t much content available on this online. Ran some quick searches & all we could find was a bunch of third-party software begging you to tell them all about your potential edges [our interpretation].
The Process
The Process of Building & Running A Betfair [or really any betting bot] Bot can be split into four phases.
Research/idea generation. This is the part where you’re supposed to come up with the potential inefficiency you want to take advantage of. If you’ve never been particularly active in the exchange markets your creativity levels will most likely be terrible at this point. That’s expected: no one invents theorems without studying math, similarly no one invents +EV models/angles without studying the markets. If this is the case for you [brain fog], use this guide solely to set up collection/storage of hard-to-find data & then start analyzing that same data. Might find something…
Design. When you’ve discovered and want to begin trading an edge, it’s more than helpful to create proper designs for both the program that will execute your instructions & the exact trading methodology that’ll underpin your strategy.
Gathering Information/Updates.
Will you subscribe to a stream of order book updates & handle them one by one, or rather perform a quick check every five seconds or so [e.g. after some background calculations have been completed]? Maybe a combination where you switch to ‘stream mode’ closer to post time?
Integration With Other Systems.
At the very least you’ll probably want to call a couple of routines on the Betfair Data you’re receiving from the feeds mentioned above to determine whether you’ll be trading that particular horse/game or not.
More advanced users may want to use new updates as input to a more sophisticated model that’ll be called & run repeatedly.
Perhaps [most likely] you want to manipulate & write/store the data to a database/in memory, will this be done sequentially within the ‘trading process’ [time between you receive an update & it being fully handled by your trading module goes up] or from a separate, parallel one?
If your trading depends on the evolution throughout the last 1 000 updates, where will you store this data? How will you access it? In a proper database? A local JSON file? Keep it in memory [what if the Bot has to be relaunched]? Questions that need to be addressed.
You either think this part through at this step [before writing a single line of code], or find yourself frustrated & wasting tons of time downstream.
Low-Level Trading Decisions.
What will your execution look like? Maker/taker orders, or a combination of them? Iceberg/hidden orders to avoid showing your intentions or visible ones [positive for queuing position & getting degen attention to your trades]?
How are you going to determine your sizing?
Trading in/out of positions repeatedly?
Checking for liquidity before sending trades? What if the liquidity disappears while your orders are on their way to the exchange?
Will you introduce caps on max exposure/number of trades in a particular market [maybe first & foremost to prevent bugs]?
Any other exception handling?
Construction. Now that you’ve created a great design for your project, it’s time to actually build it all out. Recommend you do it yourself [or at least that you’re well involved with the coding] but in case you’re uncomfortable with coding/not willing to spend time learning it, it’s of course an option to outsource this part.
The actual programming will naturally give rise to plenty of implementation details/questions you’ll want to think through properly so in practice most likely to find yourself iterating between (2) & (3).
Continuous re-evaluation. The first draft will never be the optimal version of a gambling bot. Optimization is an ongoing process & as the Bot keeps taking trades day in day out you’ll automatically find yourself asking a bunch of questions about its performance, strategy & execution. And adjust accordingly. By continually running this sort of trial & error you get closer & closer to the perfect version of your strategy, until one day you simply deem it good enough & ‘let it run’ [at least until a stupid nerd comes along & starts stealing your trades, heh]. In order to complete this evaluation/optimization stage as efficiently as possible it’ll be necessary to log & store everything that has even the slightest chance of providing answers to future, often yet unknown, questions [just log it all]. Two examples:
Bet Logging. Hard to improve a ‘betting system’ without proper logging of the bets/trades/positions it’s taking. Many ideas that ‘should work’ actually do when sufficiently constrained, but people never find out because they group them with other -EV bets & end up never seeing the difference.
‘Action’ logging. When the Bot performs any action whatsoever [e.g. sends a trade to the exchange], you log it & store it for future [error?] analysis. Simple as that. Aim to surveil the Bot like a bank would do a bettor & you’ll be good to go.
Champions adjust.
The overall concept & a clear, precise process of how to make the transition from a vague idea to a complete, proper implementation has now been defined.
With the recipe laid out in front of us, it’s time to cook up a [the best?] Betting Bot.
Code repository available here. As usual recommended to move back & forth between text and code to make sure you’re actually following while reading.
(1) Research/Idea Generation
Repeatedly been shilling the importance of staying up-to-date on the *exact* rules/features of the platforms/exchanges you’re using. Whether it’s sports, crypto or tradfi doesn’t matter. Why?
The ‘fun stuff’ is what keeps the people excited & their dopamine levels high → no one takes the time to actually read through the rules/docs *properly*. The crowd prefers pure guessing & yelling ‘SCAM’ as they’re caught by surprise when a market is settled according to the rules, but against their ‘logic’. Conclusion: If you’re one of the few who’ve studied the design of the game diligently beforehand, you’ll be taking their money when this happens.
Larger players are in many cases constrained and/or incentivized in different ways by such rules & consequently forced to adjust their action. You’re much more likely to understand how & why certain things [will] play out if you can put yourself in the perspective of a main market participant and think about his/her optimal strategies under different setups/conditions.
Example: Free sizing is an important ingredient for improved market efficiency since [in general/on average] high stakes gamblers possess higher value opinions. Now what if the max stake per ID/account in the ‘should be highly efficient’ parimutuel pool is capped at ~1/1000 of the total pool size?
Really doesn’t take much time & thinking to either create new edges and/or improve/increase confidence in existing ones by integrating ‘rule-inspired’ ideas.
To illustrate the advantage of staying up to date on new features, we’ll have today’s Betting Bot targeted at a fairly recent addition to the Betfair website/UI, the ‘Betfair Price Beacons’.
No, don’t believe this will be a money making machine [or it wouldn’t be shared here]. Hopefully slightly more interesting than your average tutorial though.
[Haven’t checked potential profitability so in case you appreciate the angle & spend some time sharpening it might earn a dollar or two ;).]
The Idea we’ll be trading is the following:
Traders trust trends & enjoy catching on to larger price moves. The new ‘Beacon Feature’ makes it easier for manual traders to do so. Therefore, if we position ourselves in front of them & have our orders meet theirs just as the thresholds of the beacons have been passed, we’re more likely than usual to get matched at a price of our choice.
(2) Design
As with business ideas, coming up with something that *potentially could be a clever trade* is easy, while the implementation & the conversion of thoughts into money is the difficult part.
Side Note: Obvious ideas will get you into crowded trades. Yes, in theory [perhaps even in backtests] they might work out well but in practice you’ll always see a quicker/smarter nerd come along & pick the profits up in front of you. Solution: either become that nerd [hard] or develop more sophisticated angles [again hard].
Before we proceed with construction we’ll have to define & clarify exactly how our thesis is supposed to be transformed into real world $’s.
Recall the idea.
Traders trust trends & enjoy catching on to larger price moves. The new ‘Beacon Feature’ makes it easier for manual traders to do so. Therefore, if we position ourselves in front of them & have our orders meet theirs just as the thresholds of the beacons have been passed, we’re more likely than usual to get matched at a price of our choice.
Trading Methodology
*Manual traders* are mentioned [find it hard to believe bots will be influenced by the emojis, but who knows]. Which markets have high manual activity & when are those manual gamblers active? Honestly don’t know → we’ll just run the strategy 24/7 on all UK races for now & see what happens.
The anchor price [from which the 7.5 % drop/drift is determined] will be crucial to get right, as everything depends upon it. It’ll be necessary to construct a get_anchor_price routine that when fed a horse/a runner book [or possibly a sequence of them] returns the correct anchor price for the selection.
A reasonable execution of this trade should be the following [we’ll handle the dropping odds/steamer case here, equivalent for drifters but in the opposite direction]:
Compute both the anchor & threshold prices [7.5 % below the anchor price].
Analyze the order book around the threshold price & add lay orders within a few ticks of the threshold price.
What’a few ticks? 1? 10? There’s a tradeoff between likelihood of being matched & profit size per successful trade to consider here.
Whenever a price trends towards the threshold price, add extra pressure with a bunch of back orders to push the price past the threshold point & have the manual traders pile in to back it.
Note that the ‘Betfair Beacon’ [the information symbol] will disappear if the price reverses & crosses the 7.5 % line again. Might make sense to move our trade one or two [or more] ticks to the left.
EXAMPLE: Jumeira Vision trades at ~4.50-4.60 with an anchor price of 4.70 [threshold price of 4.3475]. We’ll prepare for a potential trade by adding lay orders at 4.20 & 4.10 [want decent queuing positions]. As the ‘best available back price’ transitions to 4.30, we’ll back it & thus have the symbol ‘turned on’. If our thesis is correct, backers will come in & join the steam [more precisely we, on average, hope to see ‘more backers than layers’ under this setup].
Include additional order book checks to avoid taking the back side on horses with a wall of lay orders before ours [unlikely to be matched on the second leg of the trade].
Bot Design
Our Bot will be built in Flumine → won’t have to worry too much about the communication with the Betfair Engine/Servers, Flumine takes care of this for us.
We’ll connect to a Betfair data stream which pushes all order book updates. As an update comes along, we’ll run our trading logic on it & process/add/remove orders + store relevant parts of the data for analysis/logging purposes.
At the completion of a trade [back & lay orders fully matched], we’ll log it in a local file & possibly send information about it via Email/Telegram or any other notification service.
The infrastructure for the Bot will consist of three main parts/mini-modules:
Trading & Help Routines: Necessary and/or helpful functions (for instance get_anchor_price for a given horse/object, send_to_telegram for notifications… ). Called while processing order book updates and/or orders from within the Strategy discussed below.
Strategy: Defines our Strategy/Trade Idea as a Python Class. Methods such as check_market_book, process_market_book, process_orders. Uses functions from the Trading & Help Routines to beautify & readify the code.
Trading Instance/Execution Program: Responsible for defining trading parameters, launching the Flumine Instance & feeding it our Strategy.
(3) Construction
At this point our idea has been well defined & the design completed.
Thus, it’s time to dive into the code.
We’ll only comment on the most important aspects here & let you investigate the implementation for yourself over at Github.
Quick overview of Flumine specifics [bot.py file]:
At initialization, the Flumine Framework/Trading Bot is basically ‘naked’, it sits there & awaits further instructions.
Next we equip it with the most basic information: login details + which events/races to ‘listen to’ [receive updates from]. Bot completes the stream listening part by setting up subscriptions to the relevant Betfair Order Book Feeds [the markets matching your criteria/filter], essentially sends a ‘hey set me up for these races’-request to Betfair.
We then add strategies [implemented as Python Classes] to it. In our case we only run one [BetfairBeacons] but there’s nothing stopping you from running a bunch of them. When receiving new updates, the Bot will simply redirect/forward the content to each one of your strategies & run them more or less in parallel [well, we skip the ‘tism details here].
Finally we adjust the Trading Controls & [possibly] add custom Background Workers.
Trading Controls are hard stops that prevent the Bot from executing certain transactions. Example: StrategyExposure checks that orders doesn’t invalidate max caps [that you’ve determined yourself] on order size & total selection exposure [how much is risked on a given horse].
Background Workers are code routines that are being run in the background to keep everything clean & up-to-date and/or handle ‘outside tasks’.
Example I: Every 45 seconds, update numbers/parameters by fetching & manipulating data from a third-party source.
Example II: If more than 30 seconds has passed since the last race of the day went In-Play, terminate the Bot.
For more information on the inner workings of Flumine, check the docs.
The lowest level parts of the implementation were left undone, would simply take too much time for no return at all. Brief comments on what needs to be done for the Trading Bot to be 100 % ready for deployment:
Implementation of the update_anchor_prices routine [tradingroutines.py file]. Seems like it will be enough to hold the latest version of each RunnerBook [Order Book for a runner] in memory & compare the traded runner volume between version N & version (N+1). Whenever it crosses the required volume for the given odds range (i.e. traded selection volume at time N is below the Betfair threshold, volume at (N+1) above), the anchor price has been determined. Add the selectionId & the anchor price as a key-value pair & return the updated dictionary.
Exact trading logic. Probably best implemented completely within the process_market_book method [strategies.py file]. Whenever a new anchor price is determined, initialize a Trade for the selection. Then at each new stream update you may want to calibrate/adjust this Trade with new orders/removal of orders & so on. Tons of freedom here and there’s really no correct way to do this.
Note that you’ll need to consider precise Betfair Order Rules [price, order size etc.] to avoid getting a bunch of violations.
(4) Continuous Re-evaluation
This is where the trial & error begins. Now that the Bot is launched and up and running on the exchange, we’ll of course be interested in monitoring, analyzing and improving its performance. Different strategies give rise to different analysis and for our specific trading strategy it may be beneficial to put some extra emphasis on questions such as:
Given the first leg of the trade, what percentage of the time is the next leg matched on the correct/wrong side of it?
Would the performance be improved if we moved the whole trade/parts of it two ticks to the left/right? Don’t just try 1 000 angles here & go with the one that fits your data best, statistical common sense [Bayesian Thinking] still applies.
What percentage of the size of the second leg do we tend to get matched on when we get matched? If ~100 %, increase size. If less, reduce size?
Given the price crossing our threshold price, what does the price distribution look like over the next 1/5/10/15 minutes?
***ALWAYS PLOT EVERYTHING***
Then, given answers, we adjust the code and deploy GamblingBot v2.
& repeat.
Iteration yields magic.
Always Be Iterating.
Summary & general BowTiedBettor notes
Turned into one of our longer posts, we hope you enjoyed the read. More Betfair content will be shared but might take some time since most of our subscribers are US based & don’t have access.
Note I: Prophet Exchange is available in NJ & appears to offer all their customers API access. If in NJ, give it a try. Never checked it out so no clue about liquidity/spreads etc., feel free to share any findings.
Note II: With a high-gambling-volume election coming up we wouldn’t be too surprised if we could invent a post or two that could spur some American curiosity.
Feel free to use the Comments section [& the Discord] as much as you please if you found today’s content interesting & feel like getting to work.
General BowTiedBettor notes:
Currently working on a ‘The Path To $100 000 in Betting Profits’-post. Will lay out the most efficient route to make a decent chunk out of gambling markets *without* having to devote your life to it. Includes [of course] but not limited to bonus rugging. Can think of it as a one-time-robbery. When you’re done you’re *done* [won’t be any easy money left for you to collect]. Stay toon’d!
Our promise of ‘high volume streams of top quality bets’ at the launch of BowTied BetPicks has been kept very well so far.
UK Horse Racing Channel is averaging ~50 bets per day, ROI ~20 %.
US Sports Channel at ~70 bets per day with a ~8 % ROI.
Note: Real, practical figures probably slightly lower since bets arrive while you sleep and/or live life [affects volume] + a subset of them are hard to catch at the logged price but still offer value at the tick [or ticks] below [affects ROI].
Personal BetPicks bets [currently have two guys tailing as much of the action as possible ;)] has generated a 17 % ROI over ~1 300 bets for the horses & a 9 % ROI over ~750 bets for sports.
Think that’s all for today.
Until next time…
Disclaimer: None of this is to be deemed legal or financial advice of any kind. These are *opinions* written by an anonymous group of mathematicians who moved into betting.