Using VB2008 to acccess the Betfair API: A tutorial

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Vreljanski
    Junior Member
    • May 2009
    • 16

    #166
    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.
    Attached Files

    Comment

    • Vreljanski
      Junior Member
      • May 2009
      • 16

      #167
      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

      • Mumbles0
        Junior Member
        • Jan 2009
        • 240

        #168
        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

        • Vreljanski
          Junior Member
          • May 2009
          • 16

          #169
          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

          • Mumbles0
            Junior Member
            • Jan 2009
            • 240

            #170
            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

            • willz123
              Junior Member
              • Jun 2009
              • 1

              #171
              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

              • Mumbles0
                Junior Member
                • Jan 2009
                • 240

                #172
                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:

                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
                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).

                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

                • gogcam
                  Junior Member
                  • Aug 2009
                  • 2

                  #173
                  Great Tutorial and Help, Mumbles0!

                  Thanks a lot

                  Comment

                  • Mumbles0
                    Junior Member
                    • Jan 2009
                    • 240

                    #174
                    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:

                    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
                    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.

                    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.

                    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]
                    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:
                    \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.
                    Last edited by Mumbles0; 06-04-2010, 02:37 PM. Reason: Minor code change

                    Comment

                    • Dodgee
                      Junior Member
                      • Jan 2009
                      • 17

                      #175
                      Sort by two values

                      Good stuff Mumbles. Do you know how you would modify the iComparer class to be able to sort by 2 values (e.g. maybe you have an array with separate date and time properties and you wanted to sort by date, then time)?

                      Comment

                      • Mumbles0
                        Junior Member
                        • Jan 2009
                        • 240

                        #176
                        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:

                        Code:
                        Class Jack
                          Public valueA As Integer
                          Public valueB As Integer
                        
                          ...............
                        
                        End Class
                        You can sort the array according to valueA, then valueB (if the valueA’s are the same) using the comparer class:

                        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
                        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.

                        Comment

                        • Dodgee
                          Junior Member
                          • Jan 2009
                          • 17

                          #177
                          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

                          • runen
                            Junior Member
                            • May 2009
                            • 6

                            #178
                            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

                            • Mumbles0
                              Junior Member
                              • Jan 2009
                              • 240

                              #179
                              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:

                              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.
                              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.

                              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

                              • runen
                                Junior Member
                                • May 2009
                                • 6

                                #180
                                Thanks Mumbles0

                                Comment

                                Working...
                                X