CAFBotV2 with wider spreads
The algorithm would be:. I wanted to reuse the idea of polling a strategy for the orders that it wished to offer and the core being stateless, since that would mean that if the bot crashed, I could restart it and it would proceed where it left off. That did mean simple actions like "buy this" became more difficult to encode: Finally, yet another Daedric prince got added to my collection: Sheogorath , "The infamous Prince of Madness, whose motives are unknowable" I had given up on my naming scheme making sense by this point , would schedule instances of Azura to be run during the trading day by using the Betfair API to fetch a list of greyhound races and executing Azura several minutes before that.
I obviously wasn't ready to get Sheogorath to execute multiple instances of Azura and start losing money at computer speed quite yet, so for now I ran the new strategy manually on some races, first without placing any bets just printing them out and then actually doing so.
Hence it took some of that exposure into the race, which wasn't good. In addition, when testing Sheogorath's scheduling by getting it to kick off instances of Azura that didn't place bets , I noticed a weird thing: Sheogorath would start Azura one minute later than intended. For example, for a race that kicked off at 3pm, Azura was supposed to be started 5 minutes before that 2: While investigating this, I realised that there was another issue with my data: I had relied on the stream recorder using the market suspend times that were fetched from Betfair to stop recording, but that might not have been the case: Any backtest that counted backwards from the final point in the stream would kind of have access to forward-looking information: Hence I had to recover the suspend times that the recorder saw and use those instead.
I still had all of the logs that it used, so I could scrape the times from them. But here was another fun thing: That meant the forward-looking information issue was a bigger one, since the recorder would have run for longer and have a bigger chance of being interrupted by a race start.
It would also be a problem in horse markets: But more importantly, why were the suspend times different? Was it an issue on Betfair's side? Was something wrong with my code? It was probably the latter. After meditating on more logfiles, I realised that the suspend times seen by Azura were correct whereas the suspend times for Sheogorath for the same markets were 1 minute off. They were making the same request, albeit at different times Sheogorath would do it when building up a trading schedule, Azura would do it when one of its instances would get started.
The only difference was that the former was written in Python and the latter was written in Scala. After some time of going through my code with a debugger and perusing documentation, I learned a fun fact about timezones. Was the timezone offset back then something reasonable, like an hour? Nope, it was 1 minute. And here's an answer from the django-users mailing group on the right way to use timezones:.
The right way to attach a pytz timezone to a naive Python datetime is to call tzobj. Finally, here's some background on how this offset was calculated. Luckily, I knew which exact days in my data were affected by this bug and was able to recover the right suspend times. In fact, I've been lying to you this whole time and all of the plots in this blog series were produced after I had finished the project, with the full and the correct dataset. So the results, actually, weren't affected that much and now I have some more confidence in them.
As usual, posts in this series will be available at https: Alternatively, follow me on twitter. Interested in this blogging platform? It's called Kimonote , it focuses on minimalism, ease of navigation and control over what content a user follows. Kimonote help demo sign up log in. A fun fact about timezones Recovery Conclusion In ' mildbyte': Shameless plug over, back to the world of automated trading goodness.
CAFBotV2 with wider spreads Remember how in the real-world greyhound market the bot managed to have some of its bets matched despite that they were several ticks away from the best back and lay? So while that was a cute idea, it didn't seem to work.
What if we didn't have to cross the spread? Implementation in Scala With that reasoning, I went to work changing the internals of Azura to write another core for it and slightly alter the way it ran. The algorithm would be: At entry end time: Live trading I obviously wasn't ready to get Sheogorath to execute multiple instances of Azura and start losing money at computer speed quite yet, so for now I ran the new strategy manually on some races, first without placing any bets just printing them out and then actually doing so.
A fun fact about timezones I used this bit of code to make sure all times the bot was handing were in UTC: Here's a fun snippet of code so you can try this at home: Recovery Luckily, I knew which exact days in my data were affected by this bug and was able to recover the right suspend times. Watford U23 v Ipswich U Celtic Res v Aberdeen Res.
South Africa W v Malawi W. Highlights English Premier League. Other markets Today Southampton v Brighton Matched: More English Premier League.
Confirm bets before placing. Please log in below Username: Opening an account is quick and easy to do. Sports All Sports Football Time. Please Gamble Responsibly More details. Careers Betfair Corporate Resolve a Dispute. Triq il-Kappillan Mifsud, St. Underage gambling is an offence. Ok, I get it. You can now search over 10, sports betting opportunities Find teams, competitions, races, and more Southampton v Brighton Matched: Saturday, 22 September Fulham v Watford Matched: Burnley v Bournemouth Matched: C Palace v Newcastle Matched: Cardiff v Man City Matched: Leicester v Huddersfield Matched: Liverpool v Southampton Matched: Man Utd v Wolves Matched: Brighton v Tottenham Matched: