So far all is good. The error is solved as i catch it and do the relog... but... last few days I had one other problem - error I will post the screen here. Maybe someone know whats the problem.
Using VB2008 to acccess the Betfair API: A tutorial
Collapse
This topic is closed.
X
X
-
-
I red some forums and upgraded my msxml.dll to 4.0 sp3 version but i am still geting this error from time to time... anyone knows the reasons...
it seems that java parses something and dont close a tag so its text instead of xml and its not accepted by my objects as response.
cheers
Comment
-
Reply to Vreljanski (Re: Communications error)
Your error message looks like an HTML page sent by a server indicating that it cannot cope with what it has received. Your request may have become severely corrupted or even gone to the wrong server. I’ve got no idea what has caused this.
I have suggested previously that the internet is never 100% reliable. You must expect communication errors from time to time. You should catch these types of errors and have a effective retry strategy, particularly if you are running an unattended bot. I think you have something like this in place which you should develop further.
It this happens too frequently I would question the reliability of your internet service or your computer.
Comment
-
thanks Mumbles as always great help. First I wanted to be sure that it isn't caused by Betfair API. But regardless of the cause I do have to extend my internet errors catching to a full application scale layer that would do all the error handling.
I will do that and also try to find the real reason of this error so maybe we help other ppl if they expiriance it.
My internet is screwed it has some short brakes from time to time... And I am working on solving them as well.
Also I think I may have gotten a bit off topic with this problem, if so please dont hesitate to let me know.
cheers
Comment
-
OK. I must admit that I'm no expert in diagnosing internet problems. As you know, the internet is quite vast and complex. There are hosts, ISPs, Telcos, international data carriers and servers all around the world. Its a miracle it works at all! Problems often occur in areas competely beyond our control.
Comment
-
Help with bet placments
Hi this thread is great thanks for all the info!
Could someone give me an example of how I would go about placing a bet at x seconds before a race start time. I have a list of selections and I want to trigger a routine to place a bet at say 1 minute before the off. Do i use a timer and monitor the time every second compared with a race in my list? any help and sample code much appreciated!
Thanks
Comment
-
Reply to willz123 (Re: Placing bets before race start time)
Yes. Incorporate a timer with a one second interval and include a simple test in the Tick event handler something like this:
NextTimeToGo is the start time of the next race of interest. This would typically be obtained from a previous getMarket call and held in an ordered list. Note all times returned from the API are UTC (i.e. GMT).Code:Private NextTimeToGo As Date .......................... Private Sub OneSecTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles OneSecTimer.Tick .......................... If NextTimeToGo.AddSeconds(-60) = Date.UtcNow Then 'Place bet 60 sec before race start time. [I]'Code to place a bet for this race[/I] End If End Sub
Note that market times returned by the API are scheduled times only. It is not unusual for the start of an event to be delayed. This is particularly true of horse races. The given market start times are not updated to reflect these delays (at least that’s my belief - someone please correct me if I’m wrong).
This means that you cannot accurately predict when a race will actually start. This is a problem if you want to place bets in the last few seconds before the off.
Comment
-
Step 18. Horse Racing - Today’s Card.
You may have noticed that getAllMarkets does not return any data for eventTypeIds 13 (horse racing - todays card), also 15 (greyhound - todays card) and 14 (soccer - fixtures). “Todays card” is often useful because the markets are returned in chronological order.
It is fairly easy to obtain “today’s card” by filtering the markets returned by getAllMarkets using an eventTypeId that works. For this example, assume we are interested in today’s horse races in GB and IRE, win markets only.
Because we will be sorting the filtered markets in time order we need a class to facilitate this. Add this code to, say, Module Unpack:
This class is similar to the one we used in step 17. The race start time is given by the .eventDate property and the Compare method returns +1 if the time in x is after (or the same as) time in the y object, -1 otherwise. This allows the time sort to proceed as required.Code:Class CompareMarketTimes Implements IComparer(Of MarketDataType) Public Function Compare(ByVal x As MarketDataType, ByVal y As MarketDataType) As Integer Implements System.Collections.Generic.IComparer(Of MarketDataType).Compare Return If(x.eventDate >= y.eventDate, 1, -1) End Function End Class
We can now modify Sub bMarkets_Click (of step 5 and 6) which calls getAllMarkets. Here we specify eventTypeId = 7 (horse racing) and country codes for UK and Ireland. The unpacked market data will appear in the .marketData array within the AllMarkets object.
The filter (shown black) is custom-built for this requirement. It has been designed by closely examining the .menuPath parameters of the returned markets, and then some trial and error. Here we notice that markets of interest have, for example, a .menuPath like this:Code:[COLOR="Gray"]Private Sub bMarkets_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bMarkets.Click Print("*** Horse Racing - Today's Card ***") Dim oMarketsReq As New BFUK.GetAllMarketsReq Dim oMarketsResp As BFUK.GetAllMarketsResp With oMarketsReq .header = oHeaderUK() ReDim .eventTypeIds(0) : .eventTypeIds(0) = 7 'For horse racing ReDim .countries(1) : .countries(0) = "GBR" : .countries(1) = "IRL" .fromDate = Today .toDate = Today.AddDays(1) End With oMarketsResp = BetFairUK.getAllMarkets(oMarketsReq) With BetFairUK.getAllMarkets(oMarketsReq) 'Call getAllMarkets CheckHeader(.header) Print("ErrorCode = " & .errorCode.ToString) If .errorCode = BFUK.GetAllMarketsErrorEnum.OK Then Dim AllMarkets As New UnpackAllMarkets(.marketData) [COLOR="DarkSlateGray"]Dim Names As String(), TodaysCard As New List(Of MarketDataType)[/COLOR] With AllMarkets For i = 0 To .marketData.Length - 1 [COLOR="Black"]Names = .marketData(i).menuPath.Split("\") [COLOR="DarkSlateGray"]'This is the filter[/COLOR] If Names.Length = 4 AndAlso Not Names(3).StartsWith("Daily") Then If .marketData(i).noOfWinners = 1 Then[/COLOR] [COLOR="DarkSlateGray"]TodaysCard.Add(.marketData(i)) 'Add win markets only End If End If[/COLOR] Next End With [COLOR="DarkSlateGray"]TodaysCard.Sort(New CompareMarketTimes) 'Sort according to market times For Each Race In TodaysCard 'Print the card With Race Names = .menuPath.Split("\") Print(.eventDate.ToLocalTime.TimeOfDay.ToString & " " & .marketId & " " & Names(3) & " - " & .marketName) End With Next[/COLOR] End If End With End Sub[/COLOR]
\Horse Racing\GB\Sand 13th Aug
We split this into its substrings and put the result into the Names array. For the markets of interest we notice that the Names array has a length of 4 (the first element being "" ). Other market categories, such as Match Bets, Reverse Forecast, etc. have longer lengths so we can try this test:
If Names.Length = 4 then 'Accept this market
This filters all the markets of interest, but is also lets through the “Daily Win Dist Line” markets which we don’t want, so we extend the test to:
If Names.Length = 4 AndAlso Not Names(3).StartsWith("Daily") Then
This now does what we want. Because we are interested in “Win” markets only we include the additional test:
If .marketData(i).noOfWinners = 1 Then
This eliminates the “To Be Placed” markets and the filter is now complete.
We iterate through all markets and collect the filtered markets in TodaysCard. This is an array-based object of type List(Of MarketDataType) which grows automatically when we add a new market.
When we have collected all the markets of interest we sort them according to race start time (which is given in the .eventDate parameter) using the List.Sort method which uses the CompareMarketTimes class.
In the example we use a For Each ... Next loop to print the list of markets we have filtered. This is the output:
*** Horse Racing - Today's Card ***
HeaderCode = OK
ErrorCode = OK
12:55:00 100725113 Salis 13th Aug - 7f Mdn Stks
13:10:00 100725089 Bev 13th Aug - 1m4f Hcap
13:20:00 100725146 Sand 13th Aug - 5f Hcap
13:30:00 100725115 Salis 13th Aug - 7f Mdn Stks
13:40:00 100725091 Bev 13th Aug - 5f Mdn Stks
13:50:00 100725148 Sand 13th Aug - 1m Mdn Stks
14:05:00 100725117 Salis 13th Aug - 7f Mdn Stks
14:15:00 100725093 Bev 13th Aug - 5f Hcap
14:25:00 100725150 Sand 13th Aug - 7f Hcap
14:40:00 100725119 Salis 13th Aug - 1m4f Hcap
14:50:00 100725095 Bev 13th Aug - 1m2f Hcap
15:00:00 100725152 Sand 13th Aug - 1m Mdn Stks
15:15:00 100725121 Salis 13th Aug - 1m Grp3
15:25:00 100725097 Bev 13th Aug - 7f Nursery
15:35:00 100725154 Sand 13th Aug - 1m Hcap
15:50:00 100725123 Salis 13th Aug - 6f Hcap
16:00:00 100725099 Bev 13th Aug - 1m Hcap
16:10:00 100725156 Sand 13th Aug - 1m1f Hcap
16:15:00 100725410 Tram 13th Aug - 2m Mdn
16:20:00 100725125 Salis 13th Aug - 1m6f Hcap
16:25:00 100725378 Leop 13th Aug - 6f Hcap
16:40:00 100725337 Strat 13th Aug - 2m Nov Hrd
16:45:00 100725412 Tram 13th Aug - 1m4f Mdn
16:50:00 100725101 Chep 13th Aug - 6f Mdn Stks
16:55:00 100725380 Leop 13th Aug - 7f Mdn
17:00:00 100725134 Newc 13th Aug - 7f Nov Stks
17:10:00 100725339 Strat 13th Aug - 2m Nov Hrd
17:15:00 100725414 Tram 13th Aug - 1m4f Hcap
17:20:00 100725103 Chep 13th Aug - 1m4f Sell Stks
17:25:00 100725382 Leop 13th Aug - 7f Mdn
17:30:00 100725136 Newc 13th Aug - 7f Hcap
17:40:00 100725341 Strat 13th Aug - 2m5f Hcap Chs
17:45:00 100725416 Tram 13th Aug - 1m4f Hcap
17:50:00 100725105 Chep 13th Aug - 2m2f Hcap
17:55:00 100725384 Leop 13th Aug - 1m Hcap
18:00:00 100725138 Newc 13th Aug - 1m Hcap
18:10:00 100725343 Strat 13th Aug - 2m Hcap Hrd
18:15:00 100725418 Tram 13th Aug - 2m Hcap Chs
18:20:00 100725107 Chep 13th Aug - 7f Mdn Stks
18:25:00 100725386 Leop 13th Aug - 1m4f Grp3
18:30:00 100725140 Newc 13th Aug - 5f Hcap
18:40:00 100725345 Strat 13th Aug - 2m7f Hcap Chs
18:45:00 100725420 Tram 13th Aug - 2m Mdn Hrd
18:50:00 100725109 Chep 13th Aug - 6f Hcap
18:55:00 100725388 Leop 13th Aug - 1m1f Hcap
19:00:00 100725142 Newc 13th Aug - 1m2f Hcap
19:10:00 100725347 Strat 13th Aug - 2m3f Nov Hrd
19:15:00 100725422 Tram 13th Aug - 2m Hcap Hrd
19:20:00 100725111 Chep 13th Aug - 1m Hcap
19:25:00 100725390 Leop 13th Aug - 1m2f Mdn
19:30:00 100725144 Newc 13th Aug - 1m2f Hcap
For greyhound markets use .eventTypeId = 4339 and try a filter something like this:
If Names.Length = 4 AndAlso Not Names(2).StartsWith("Forecast") Then
To get soccer fixtures use .eventTypeId = 1. You could try a filter like this to get a list of “Match Odds” markets:
If Names.Length = 6 AndAlso Names(4).StartsWith("Fixtures") Then
If .marketData(i).marketName = "Match Odds" Then
The details of the actual filter you use will depend on your requirement. You design this so you only get the markets you are interested in.
Comment
-
Reply to Dodgee (Re Sorting with IComparer)
Parameters returned from the API such as eventDate, marketTime, etc. are of type Date (or DateTime*) and incorporate both date and time components (e.g. “18/08/09 5:40:00 PM”). In the “Today’s Card” example the sort is performed on the .eventDate parameter and does, in fact, sort first by date, then by time. If you set the request parameter: .toDate = Today.AddDays(2) you will print “Today and Tomorrow’s Card” with races in correct date and time order without changing the CompareMarketTimes class. In other words you can perform a date and time sort by simply sorting on a single Date (or DateTime*) value.
(*The Date and DateTime data types are synonymous.)
More generally, say you have an array of objects of type Jack, having two properties being:
You can sort the array according to valueA, then valueB (if the valueA’s are the same) using the comparer class:Code:Class Jack Public valueA As Integer Public valueB As Integer ............... End Class
Here valueA has precedence. The sort proceeds according to valueA, then according to valueB if the valueA’s are the same when comparing two objects.Code:Class CompareJack Implements IComparer(Of Jack) Public Function Compare(ByVal x As Jack, ByVal y As Jack) As Integer Implements System.Collections.Generic.IComparer(Of Jack).Compare If x.valueA = y.valueA Then 'Sort on valueB Return x.valueB - y.valueB Else 'Sort on valueA Return x.valueA - y.valueA End If End Function End Class
Comment
-
Re Sorting with iComparer
Yeah I think the date/time hypothetical example was a bad one. Basically I have an array with a number of values, 2 of which are the race time and the name of the meet that the race belongs to (a string value). I want to sort first by the meet, then by the time.
I'm assuming it is possible to sort by two different datatypes like this, as the string values would be compared to each other, then the datetime values to each other....
Will give it a go.
Comment
-
Bet status
I would like to place a back-bet and I would request the lay(0) price for my backbet...
If I check status of this bet later, how can I see if the bet was matched or partiel matched or not matched?
If the bet only was partiel matched, how do I cancel the rest?
Comment
-
Reply to runen (Re: Partial-matched bet)
After you place a bet using placeBets you can observe the status of the bet by calling getMUBets at regular time intervals (say 1 sec).
Here's an FAQ from BDP which is relevant:
This suggests that if the bet is partially matched, the .bets() array returned by getMUBets will contain 2 bets having the same betId, one with betStatus U (unmatched) and the other with betStatus M (matched). This betId will be the same as that returned originally by placeBets.If a bet is partially matched is its state U, M or MU if a getBet call is made?
There isn't a status as such for a partially matched bet.
For getMUBets the result would include all of the 'portions' of the bet depending on the request parameters - if you request 'MU' e.g. it would return both an M and a U item (with the same betId) for the bet.
For getBet however, the response attributes one 'status' to the bet, and for partially matched bets this happens to be U. This even though the bet does include a match portion, the details of which are also included in the response.
Calling cancelBets with this betId should cancel the unmatched part.
You can also change the size and the price of the unmatched part using updateBets. See this post.
Comment


Comment