Streaming and NSW

Mike left a comment on the previous post –

Always good to follow your progress. I’ve been trialing the new Gruss at home but have yet to let it loose with my Bots on my VPS. You say; “To note, the charts on the VPS are showing lower times than those at home” I’m reading that to mean “faster” times not “slower” times. What’s the bandwidth usage like with multiple sheets running?

As for the NSW markets, if you lay first it is theoretically possible to close out/green/red up your trade by laying out the other runners across the field, thereby not placing any back bets and avoiding the turnover charge. Albeit more complicated mathematics and process and it may not suit your trading style, but it is an option.

Thanks for the comment.

You are right, I meant faster times. Below is an image showing the charts whilst streaming from the VPS and from home, both monitoring same event at same time. Although the scales are different, I’ve added 100, 200 and 300 increments to highlight the difference. The VPS is generally lower times, faster, but more importantly, the consistency is better. For example, the VPS chart has 1 refresh greater than 300ms for this period, whereas at home I see 12 occasions of greater than 300ms.

gruss_stream11

In this next image I’ve tried to match the timings. Interestingly it looks like the home refresh is sometimes faster but this is just a consequence of refreshes coming in close after the refreshes that are notably slower (otherwise, if every refresh was slower, the market would drift away behind real time as the delay is compounded – mind boggling).

gruss_stream12

I’m not too sure how best to measure bandwidth in real-time but this is from the resource monitor in Windows Task Manager. This was taken with two sheets open. The first was a UK evening greyhounds with about 40s to off. The other was a US horse race from about 2 mins out (approx £5K matched). 2600 Bit per second is equal to 325 Byte per second (according to Google). Hope this helps, or let me know if there’s a better measure.

vps_bandwidth

Your possible solution to the NSW issue is very much outside the box and an excellent reminder of what we’re doing in the market. If you back one selection, you’re not only backing it, you’re effectively laying every other selection. Using this logic, as you say, it’s possible in theory to trade through the market without having to place a back bet. It does require a market with tight spreads. And also a large enough stake to be able to lay all other selections with as close to calculated values as possible. But it could work. Not likely for me though, off the top of my head, my initial stakes would be too low. I like the thinking though.

June ’17

The big event of June was the release of a beta streaming version of Gruss. As it is in development, the Gruss guys requested feedback and there were a number of bugs highlighted by users. We are now on the sixth release, which is good to know the program is being worked on and improved. The bug that I found related to moving on from suspended markets but after I fed back via the forum, a fix was quickly released. It took a little time for me to grasp the full effects of streaming. At first I thought the refresh was poor as updates were very random. The stream only updates when there is something to update, ie market activity, and doesn’t waste bandwidth by refreshing the same data repeatedly, as before streaming. This gives a refresh chart that can have quite large gaps between updates, especially on markets with some time to go before off. Now, with only a few minutes to off, the refreshes come in more than every 200ms. As there are no requests for price data, there’s no added delay. To note, the charts on the VPS are showing lower times than those at home. The request delay will still be relevant when placing orders in the market but no data is available on what it is.

Another major event, for me, was the changes to the Aus turnover eligibility. I posted about this here. I’m on with the coding around this. I have a section of code that only runs once when a market is selected and then isn’t run every refresh. I’m adding the NSW code there, which was straight forward for checking against the list of courses but tracking the traded back bets over a week is a little more complicated.

The UK dogs have done good this month. I’m considering adjusting the stake range to allow higher bets. I want to trial it on specific markets first. I’m thinking of those that are televised and tend to have much higher activity.

chart_ukdogs170630

An improved chart from the Aus horses compared to recent months. It’s nice to see a good return as I was beginning to lose patience with it and was considering stopping this bot. It’s been a long time since I ran Oscar on the UK horses as there was no value in it for me and I was thinking the Aus horses were going the same way. They still might, to be fair. But for now, with this, it will continue.

chart_aus_horse170630

US horses – better result than not trading them at all. There are some really well funded races that I’m missing, purely down to start times been well off. I’ll continue moaning about this point until I finally get a solution in place (I’ve had some good suggestions from you but the code don’t write itself, I should get on with it).

chart_ushorse170630

Definitely lower activity on the dish-lickers. An unfortunate loss keeping the return in the negative. Not much harm in continuing for now, I consider this my experimental contribution (why not?)

chart_aus_dogs170630

Aus Turnover Charge, Again

Back in Feb 2016 I wrote about Aus turnover charge. Since then the rules changed, meaning qualification for the charge was more difficult. However, I got an email last week from the friendly Betfair staff, warning me in advance of another rule change that happened today – 1st July (see Betfair Law). In brief, the charges apply to NSW races and now only 25 markets per week before charge eligibility. But which venues are in NSW? To avoid wearing out the map book, I tweeted @BetfairCS, who initially pointed me to the rules and regs. I persisted and a very helpful chap (or chapette) emailed over a list of venues in an Excel spreadsheet – result. For now I’ve set the bot to jump past the NSW markets, in future I’d like to code to allow trading up to the limits allowed. Here’s a link to the file. I also list below –

NSW Metropolitan  Abbreviation State Class
Canterbury Cant (AUS) NSW Metro
Randwick Rand (AUS) NSW Metro
Rosehill Rose (AUS) NSW Metro
Warwick Farm WFrm (AUS) NSW Metro
NSW Country Tracks Abbreviation State Class
Albury Alby (AUS) NSW Country
Armidale Armi (AUS) NSW Country
Ballina Bali (AUS) NSW Country
Bathurst Bath (AUS) NSW Country
Bowraville Bowr (AUS) NSW Country
Casino Casi (AUS) NSW Country
Cessnock Cess (AUS) NSW Country
Coffs Harbour Coff (AUS) NSW Country
Coonabarabran Cona (AUS) NSW Country
Coonamble Cnbl (AUS) NSW Country
Corowa Coro (AUS) NSW Country
Cootamundra Coot (AUS) NSW Country
Cowra Cowr (AUS) NSW Country
Dubbo Dubb (AUS) NSW Country
Forbes Forb (AUS) NSW Country
Gilgandra Gilg (AUS) NSW Country
Glen Innes GInn (AUS) NSW Country
Gosford Gosf (AUS) NSW Provincial
Goulburn Goul (AUS) NSW Country
Grafton Graf (AUS) NSW Country
Griffith Grif (AUS) NSW Country
Gundagai Gund (AUS) NSW Country
Gunnedah Gunn (AUS) NSW Country
Hawkesbury Hawk (AUS) NSW Provincial
Inverell Inve (AUS) NSW Country
Junee Jnee (AUS) NSW Country
Kembla Grange KemG (AUS) NSW Provincial
Kempsey Kemp (AUS) NSW Country
Leeton Leet (AUS) NSW Country
Lismore Lism (AUS) NSW Country
Moree Mree (AUS) NSW Country
Moruya Moru (AUS) NSW Country
Mudgee Mudg (AUS) NSW Country
Murwillumbah Murw (AUS) NSW Country
Muswellbrook Musw (AUS) NSW Country
Narrabri Nbri (AUS) NSW Country
Narrandera Ndra (AUS) NSW Country
Narromine Narr (AUS) NSW Country
Newcastle Newc (AUS) NSW Provincial
Nowra Nowr (AUS) NSW Country
Orange Orng (AUS) NSW Country
Parkes Park (AUS) NSW Country
Port Macquarie PMaq (AUS) NSW Country
Queanbeyan Quea (AUS) NSW Country
Quirindi Quir (AUS) NSW Country
Sapphire Coast Sapp (AUS) NSW Country
Scone Scne (AUS) NSW Country
Tamworth Tamw (AUS) NSW Country
Taree Tare (AUS) NSW Country
Temora Temo (AUS) NSW Country
Tuncurry Tunc (AUS) NSW Country
Wagga Wagg (AUS) NSW Country
Walcha Walc (AUS) NSW Country
Warren Warn (AUS) NSW Country
Wellington Well (AUS) NSW Country
Wyong Wyng (AUS) NSW Provincial

 

A comment, an icon, rounding and an offer.

US Horse Racing Off Times have been a problem for bot developers since the year dot. The US off times are just a guide and are not religiously adhered to like the rest of the world. Initially I got around this by polling the Time to Post stat that gives a guide of when the off time is due. This value can be scraped from a number of different sites. Even this was a little hit and miss. What I eventually landed on was waiting till the overround was less than 105% to indicate that the race was about to go off. Works quite well in sparse US markets where all the money comes in at the end before the off.

Thanks for this comment. I’ve looked into scraping times and have found a few sites. Not made any attempts to integrate yet. The idea of watching the overround is very good and something I hadn’t thought of. This goes on the to-do list, thanks.

 

 

I’ve been coding an app in Visual Studio to replicate a spreadsheet I’d made when I was doing the matched betting thing. I added an icon and thought I’d add it to this site, so if you haven’t noticed, it should be at the top of the address bar and look like this –

favicon3

I like the simple look, which is fortunate. And it should show up as different to WordPress in any bookmarks, or in the blog roll on green-all-over (It’s been quiet over there recently).

 

The app I’ve made calculates the lay stake at given odds. A problem I encountered whilst testing my little app was a difference between what I calculated and what I was seeing on the Betfair site. It’s only small but at large stakes it’s noticeable and any discrepancies are worrying, suggesting an error in the formula used. My error came down to rounding. Initially I was just rounding the result only to 2dp. Each step of the formula requires rounding to 2dp to keep it accurate. At no point can you place a lay stake of £50.083333. Attention to detail is key, my mistake.

 

Talking of attention to detail, I recieved an offer to try out a VPS in Dublin with less than 3ms delay. That’s extremely fast for sports trading and probably as good as it gets without co-location (something I’m sure goes on). I had looked at getting a Dublin based VPS when I was setting up but was not willing to pay the obvious premium rate. The offer I received came via Twitter and the first thing anyone does is look at the website of the people making the offer. I remember this company was looking for people to trial its VPS about a year ago. Their website still has some pages that haven’t been altered from the template settings – the blurb you get when you start a website from a pre-made layout offered by these site builder outfits. There’s a lot of trust when putting your bots onto a VPS and you want to know you’re in safe hands that pay attention to detail. I declined the offer.

May ’17 – and the art of separation.

Work on the VB bot was frustrating me so I decided to pause it and have a play with Oscar, my VBA bot. I’ve nearly always run one instance of Oscar, navigating between different markets and sports based on some preset criteria. I decided to split the sports, running an instance for UK dogs and one for Aus horsies. This has the benefit of not missing conflicting events across the two sports. The reason Oscar didn’t do this originally is because back in the day, Betfair charged for making excessive calls above a relatively low amount. This changed some time back but I hadn’t.

This new set-up runs well and so I added Aus dogs, also running in its own instance. And why not US horses? OK, they are now covered in another instance. (Previous attempts at US horses had not seen many trades but most races were missed in favour of the other markets.)

I’ve monitored some cross-over times on the VPS and I haven’t seen any drop in performance. At some points in the morning, three of the bots are running at 0.2s refresh rate but I’m still getting a delay of less than 20ms on each.

I did notice the other day that the US horses were buggered by some error in the stated off time. For one venue the times were in the quick pick list but when the markets were selected, the off time was around an hour and a half out. This may have been an API issue but if I see it again I’ll look at coding to handle the mismatch between the two.

Next, Chris commented on Speedy data 2  –

Very interesting articles about bot speeds. I have been looking into the same. I have looked at my algorithms and have improved them. They now return values within 3-4 ms. However the main bottle neck is the price refreshes. Without streaming they currently have a price refresh at 200ms, my prices can be 180 ms out of date. If I was able to implement streaming I could improve my robots speed by a huge amount (probably 100ms), dwarfing any gains that could be made over optimising my robots. So I would suggest that the bottleneck is in your price refreshing and you could see a large improvement with your bots if you were able to stream prices.

Thanks for the comment. 3-4ms is fast and I haven’t seen those speeds from my bots yet. How are you timing the code? And what language are you coding in? The arrival of streaming made me less eager to push on with the VB bot as I don’t want to put all the time in to get the code perfect just to see it become old-hat overnight. Gruss, the software I use for my VBA bots, are releasing a beta streaming version soon. When I’ve had a go with that, I’ll look at how to stream with VB. There’s no point at all in not streaming if it’s faster and as reliable (collective eye roll) as the API-NG.

And now, some charts.

UK dogs have done ok, nice steady performance.

chart_ukdogs170531

Aus horses continue to throw some bad results. The three sharp drops in this chart have different causes. The first is actually 3 losing markets together, so no problem there. The second was an error, a problem I haven’t seen for a while where an extra lay is submitted for some reason. I’ve previously thought this is down to timing and the bot missing signals at specific points, eg when greening occurs and a bet is taken at the same time as a CANCEL-ALL command is triggered. The third was just a bad run of multiple bets being placed within the stoploss window, all eventually losing trades. When I’ve attempted to overcome this particular event in the past, the number of trades significantly reduced. I may look at this again, specifically in the Aus horse markets, but with a more complex solution.

chart_aus_horse170531

NEW – Aus dogs, although not many markets, has a good looking chart, certainly one to watch. Stakes are still hovering around £2 for now.

chart_aus_dogs170531

NEW – US horses, only 3 days here so wait and see what happens in June. Interesting to see average bets per market at 9.9, with other sports being

UK dogs = 5.6

Aus horses = 6.1

Aus dogs = 2.9

chart_ushorse170531

You can find all of Oscar’s UK dogs charts on a single page now – see here.

 

Australian greyhounds and other activities

As mentioned in a previous post, an Oscar clone has been let out of the traps (ha ha, out of the traps – greyhounds, traps, letting out of the… yeah, yeah) and has been trading the Australian greyhounds for the past week. The liquidity is generally lower on these markets, especially for the earlier races but some of the later races are ok. With settings almost identical to those for the UK, only 27 races saw any trading with a total 115 bets settled. Profit of 27 pence (coincidentally) and £270.69 traded, giving a P&L/TV of 0.1%, which is not an unusual figure for Oscar. I’ll let it run for now to see what results come in.

aus_dogs_170521

Other activities

I know many of you will have it on your mind but for those that are new here – back in October I did a post on stakes ending with me wondering what to do with any profits. I gave four possibilities, as I saw it –

  1. Leave it where it is, doing nothing.
  2. Create a second Betfair account, for other/future bots or split activities.
  3. Remove from Betfair, put it in savings to be returned to Betfair when required.
  4. Remove from Betfair, spend it (I doubt this will happen).

Option 2 is not an option. I thought option 3 would be the one to go with but the wife suggested (after pointing out that there wasn’t vast amounts to play with ” and after all that time you spend on the computer“) that I should buy something – option 4 – which was MY LEAST favoured option. So after thinking it over and realising that she was right, because that’s how it is, I decided to part company with my faithful 20+ year old mountain bike (Claud Butler frame swapped for a scrap ’85 Ford Escort, crank and gears from a previous GT, all other parts swapped/added separately pre 2000, except tyres) and purchase a brand spanking shiny new modern lighter full suspension ally framed disk braked, mountain bike. I’ve been using it regularly for the past few months to try (really try) to improve my fitness. This is most certainly a work in progress.

img_20170114_140522068
Old
img_20170114_140422315
New (when it was new)

(p.s. I still have the old bike, just can’t bring myself to drop it at the tip after all these years)

 

Speedy data 2

My Speedy data post generated a few comments and some discussion. I really appreciate people taking the time to get involved and share their knowledge and views.

The first comments came via twitter from TraderBot (here and here) with a link to stackoverflow. This is a site I’ve found to be really useful to get help with many programming issues in multiple languages (That reminds me, I keep meaning to do a list of what I use – apps and sites). The Q&As linked to, although relating to Java, are an interesting read with an answer to the speed question, in summary, of “it depends on what exactly you want to do/measure”.

LiamPauling commented on the post asking where I’m hosted and do I stream? I’m cloud hosted and not streaming. He continues that he thinks bottlenecks are more likely elsewhere, which, after further reference in later comments, seems to be a good point.

Betfair Pro Trader asked why I wanted to use an array. It’s not that I want to use an array more than any other data structure, I was looking at getting the best solution, if such a thing exists (which is becoming less clear).

Tony, via Twitter, suggested running a test code with the different structures used. This could be useful but I was put off from this initially by the confusion I was getting from reading differing opinions based on various implementations of arrays, collections and dictionaries (and later, lists). At this point I was thinking that the optimum stucture is dependant on the specific use and there isn’t an exact answer to my speed question.

Next, a comment from Ken. He points to Lists as it’s something that he uses regularly and he talks of some of the benefits. Again, I’d previously come across articles saying lists were slow but maybe I was too quick to dismiss them. Betfair Pro Trader has also suggested using lists and dictionaries combined. Ken adds that he codes in C# (C sharp) but I think for the purpose of data structures and speed they are similar (they, C# and VB.net compile to the same language and run against the same runtime libraries).

n00bmind added a detailed comment. He makes the point that the advantages of one structure over another are not always so, as mentioned above. Also, he goes on to agree with previous comments that my speed question may be missing the main issues – those being the program/algorithm itself and network latency. Further advice is given about profiling (something, as a specific process, I haven’t come across before) and maybe using a different language, such as Python (I have only a basic understanding of Python from messing with it on my Raspberry Pi).

Finally, Jptrader commented, agreeing mostly with n00bmind, and others, about looking at “handling network latency properly and doing performance profiling”.

Although a simple answer hasn’t been found (because there isn’t one), I’m guided by these comments to focus more on my code, handling serialization and latency, making the algorithm efficient and using the data structures that work for now, whether that’s arrays, collections, dictionaries, lists or a combination of. Moving to another language just isn’t feasible for me at the moment, it’s taken me over a year to get a running bot in VB, with limited hobby time. I am happy to accept that another language may have it’s advantages, so would advise others to look at this for optimising their bots performance (for me the advantage will be seen moving from VBA to VB.net).

The testing I’ve done hasn’t shown any particular advantage of the different structures. From my searches on the web I think this could be due to the relatively small amount of data I’m handling (many articles talk of data lines in the 10s to 100s of thousands when comparing structures). An error on my part also had me making double calls for data with my bot which added to my difficulties and questions initially.

I have plenty to be getting on with for now and will continue looking to improve my bots. Thanks again for all the comments.