Using VB2008 to acccess the Betfair API: A tutorial

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts

  • BigSprout
    replied
    Mumbles, thank you for a wonderful and informative thread. I read through it a number of times so that I understood it and made a pledge to myself to refrain from asking questions that were already covered or could easily be found by a small effort on my part

    I succeeded

    I now have my own program working through the API to my satisfaction - it did have its moments tho

    Incident 1
    Reading through the literature and trying to work out the sequence of events in the case of a non-runner (got that sorted now)

    Incident 2
    Testing the Place multiple bets - Field Lay of $5 @ 1.01
    I was checking to see all bets were showing on my datagridview - all good
    Just before market close, one of the lays turned to "M"...somebody had placed a back bet (probably incorrectly) on the fav at odds of 100/1 ON


    ....it WON

    5 cents was deducted from my account (fav was showing around 2.90 on BF before the jump)

    Anyway it has been an enjoyable journey and I appreciate the time and effort you have put in to help all of us - well done

    cheers Les
    Last edited by BigSprout; 15-02-2011, 03:31 AM.

    Leave a comment:


  • Mumbles0
    replied
    Thanks Grantay. I will just add a bit more...

    I presume calypsored is calling getMarketPricesCompressed (or getMarketPrices) to get the odds. For each runner these calls return the “3 best” prices and amounts available in the arrays .bestPricesToBack and .bestPricesToLay, providing 3 best prices exist.

    Sometimes this may not be the case. This can occur if, for example, a market is new, or a runner is not fancied, or for some other reason such as the football case when the score line becomes impossible.

    Looking at the .bestPricesToBack array:

    If there are less than 3 back prices on offer, the array length will contract to accommodate only what’s available. To illustrate this:

    Usual case: 3 or more back prices available, .bestPricesToBack.Length is 3
    .bestPricesToBack(0) contains best price and amount
    .bestPricesToBack(1) contains 2nd best
    .bestPricesToBack(2) contains 3rd best

    Only 2 back prices available, .bestPricesToBack.Length is 2
    .bestPricesToBack(0) contains best price and amount
    .bestPricesToBack(1) contains the other price and amount

    Only 1 back price available, .bestPricesToBack.Length is 1
    .bestPricesToBack(0) contains the only price and amount

    No back prices available, .bestPricesToBack.Length is 0
    In this case the array exists, but its length is zero. This may sound a bit strange, but it is an empty array.

    If you attempt to access an non-existent array element you will get the “Index was outside to bounds of the array” exception, which is what will happen if you try something like:

    Print(.bestPricesToBack(0).price)
    when there are no back prices.

    So the rule is to always test .bestPricesToBack.Length to ensure that an element exists before you access it. So you should always do something like this:

    Code:
     If .bestPricesToBack.Length > 0 Then  'Array contains at least one price
       Print(.bestPricesToBack(0).price)
     Else
       Print("No price available")  'Take alternative action
     End If
    This, of course, applies to .bestPricesToLay as well.

    Leave a comment:


  • Grantay.
    replied
    Empty back or lay prices

    Calupsored,

    Some where in this thread Mumbles(0) has descibed this issue, and the solution; I cant find it exactly, but you need to have a test to ensure the back or lay side is not empty.

    Here is the code I use in market prices (from the tutorial):

    Code:
                    With .marketPrices
                        Print("MarketID = " & .marketId)
                        For i = 0 To .runnerPrices.Length - 1
                            With .runnerPrices(i)
                                Print("Runner " & i + 1 & "  LPM = " & .lastPriceMatched)
                                Back = ""
                                For j = 0 To .bestPricesToBack.Length - 1 '[COLOR="Red"]TEST here[/COLOR]
                                    With .bestPricesToBack(j)
                                        Back = Back & "  " & .price & "/" & Int(.amountAvailable)
                                    End With
                                Next
                                Lay = ""
                                For j = 0 To .bestPricesToLay.Length - 1 [COLOR="red"]'TEST here[/COLOR]
                                    With .bestPricesToLay(j)
                                        Lay = Lay & "  " & .price & "/" & Int(.amountAvailable)
                                    End With
                                Next
                                Print("Back = " & Back & "   Lay = " & Lay)
                            End With
                        Next
                    End With
    If the lay of back side is empty the code skips over it.

    grantay

    Leave a comment:


  • calypsored
    replied
    Thanks for the reply BigSprout, I appreciate your effort to help... but...

    All unmatched bets are cancelled when a goal is scored, but that scoreline does not become a non-runner! Let's take 0-0 as an example - obviously if a team scores that result can't now happen (unless the game is abandoned and the result voided I suppose!). However lots of people might have laid it at highish odds and have a lot of money tied up in a dead rubber.

    Some layers, with more cash in their accounts than Yours Truly, offer a lay at odds of 1000 - the reason being so that those people who laid 0-0 previously can back 0-0 at odds of 1000 to free their liability....and free money to those later layers (if that all makes sense!)

    Also, some of the late night matches (Latin America etc) have scorelines where no money is being offered on one or both sides of the market for some scores!

    I have in fact tried exactly the trap you suggest (amongst many others) to no avail. I'm unsure how to test if a given element in an array is empty, null, non-numeric - that's the nub of my problem!

    Leave a comment:


  • BigSprout
    replied
    Dave, not sure if this is correct - but I am not going to learn if I just sit back.

    I believe that when a goal is scored (non-runner in a race), the market is suspended and unmatched bets are cancelled.

    So check 1 would be if marketstatus is "SUSPENDED" and then not try to load prices

    or check 2
    Code:
    if  .bestpricestoback.length=0 then
        Print("an error Message")
        Exit Sub
    endif
    eventually all "Back" prices would be filled and betting can commence
    Last edited by BigSprout; 14-02-2011, 02:20 AM.

    Leave a comment:


  • calypsored
    replied
    Another little brick wall....

    Hi guys, I've finally sorted out my little application to pull current odds in the Correct Score football market across the API, but once again find myself stumped....

    When a goal is scored some scorelines obviously become impossible and usually you find there is money available on the lay side but not on the back side. My program is falling over when it encounters what is presumably a null entry in the 'marketprices' routine...(index out of range is the exception message)

    I've tried trapping this with various if .. then's but can't get a workaround - can anyone help me please?

    Thanks, Dave
    Last edited by calypsored; 14-02-2011, 12:06 AM.

    Leave a comment:


  • Mumbles0
    replied
    Also, another good reason to use getMarketPricesCompressed is because it can be called 60 times/min on the free API (only 10/min for getMarketPrices).

    Any computer not more than 10 years old should have no problem unpacking the compressed data. Tutorial Step 14 gives a fairly efficient algorithm for this.

    Leave a comment:


  • MarkL
    replied
    Well, it's the internet, so if you're placing bets very close to the off and you to see a betDelay of zero in the marketPrices response and send a bet request, network delays might mean that your bet request actually arrives after the market has turned in-play.

    If you're not trying to be right up to the last second before the market turns in-play though, you shouldn't have a problem.

    Yes, the advantage of getMarketPricesCompressed is that it takes a lot less bandwidth than the non-compressed version. Also, it's slightly let load on our end to generate the response.

    Leave a comment:


  • monkeymagix
    replied
    getMarketPrices or getMarketPricesCompressed

    Cheers Mark

    I had read somewhere (I think on this forum) that some people had experienced issues with the delay value and had placed bets thinking the market had not turned in play yet only to find out that it was actually in play. Currently I do not want to be placing bets in markets that have started so I am looking for a 100% guaranteed way of knowing when the market has turned in play.

    Also I am currently using getMarketPrices as apposed to getMarketPricesCompressed.

    Is there any specific reason why people tend to use the compressed version over the uncompressed version?

    Obviously the size of the data passed back and forth is smaller with the compressed version but then the downside is the time spent processing the data to make it usable.

    Do you have any thoughts on this?

    Leave a comment:


  • MarkL
    replied
    Originally posted by monkeymagix View Post
    On the topice of determining whether a market has turned in play

    What do you suggest is the best way for determining from the API alone whether or not a race has actually started.

    I don't want to place any inplay bets at all but I need to be 100% sure that a race has started or not.

    From reading up it seems that using the BetDelay property in the compressed market data is not very accurate due to the fact that they cache the data. Therefore I could get a bet delay of 0 and presume the market hadn't started yet but in fact it had and the data was out of date.
    Checking the BetDelay in the getMarketPricesCompressed response is the best way. The data won't be out of data. The API does cache, but changes in the exchange are pushed to the API servers when they occur.

    http://bdp.betfair.com/index.php?opt...180&Itemid=108

    Leave a comment:


  • monkeymagix
    replied
    In Play

    LOL Cheers for the stroke? I take it your a Brit and you mean what I think you mean

    I am looking into some results API's and I already use another BOT that gets results from certain betting sites but they are only running once every 20 mins at the moment due to the overhead of scraping and de-constructing their poorly and often changing HTML. So I will look into that a bit more to see if I can get results a bit quicker.

    My bot is basically using data from lots of disparate systems at the moment and it's going to involve a major consolidation process to get it all tied up. I have found myself a nice little profitable system but it relies on being able to place accumulators so until I can make enough money to give up the day job the shoe string will remain at the core of the system.

    On the topice of determining whether a market has turned in play

    What do you suggest is the best way for determining from the API alone whether or not a race has actually started.

    I don't want to place any inplay bets at all but I need to be 100% sure that a race has started or not.

    From reading up it seems that using the BetDelay property in the compressed market data is not very accurate due to the fact that they cache the data. Therefore I could get a bet delay of 0 and presume the market hadn't started yet but in fact it had and the data was out of date.

    Do you have any suggestion?

    Leave a comment:


  • Mumbles0
    replied
    Monkeymagix,

    Thanks for the stroke, but I’m afraid that my knowledge, as far as this forum is concerned, extends mainly to VB programming. I’m sure there are many readers and contributors who know a lot more about unexpected/undesirable behaviours of the Exchange than I do.

    I don’t know how to make Betfair settle bets any faster than they do.

    What you need is a prompt results service. Betfair offer a results service, but I have not evaluated it.

    I don’t know why your bet lapsed before the event started.

    Also, I don't know the probability of a wiiner being subsequently disqualified.

    Leave a comment:


  • monkeymagix
    replied
    Accumulator Bets and LAPSED Status Codes

    Hi Mumbles

    As you seem to be the most knowledgeable person I have met on this board so far and I didn't want to cross post I was wondering if you check out this thread I started on handling races where the time between two legs in an accumulator are only 10 minutes apart and Betfair only settles the first leg once the 2nd one has started.

    The thread is located here >> http://forum.bdp.betfair.com/showthr...=4526#post4526

    I would be interested to hear your thoughts on the matter.

    Also I don't suppose anyone has had any ideas to why one of my bets was marked as L = LAPSED before the race had occurred (see previous post)

    I thought you could only get a LAPSED bet if the bet wasn't matched by the time of the race but I got this code hours before.

    The selection wasn't VOIDED (still ran in the race) so I am confused to why I got a LAPSED status code.

    Anyway keep up the good work

    Thanks

    Leave a comment:


  • calypsored
    replied
    Thanks Mumbles, a 'bit confused' is probably a massive understatement!

    What I don't understand is why you felt the the need to separate the request and the response into separate procedures in that particular step? In all previous procedures you call them in the same routine... I think that's what threw me..

    Leave a comment:


  • beans
    replied
    Re: Step 10. Calling getCompleteMarketPricesCompressed.

    In Step 10. Calling getCompleteMarketPricesCompressed, has the API changed since you wrote this or am I miss understanding something?

    You have the following in the upack class:
    .asianLineId = Field(7)
    .farBSP = Val(Field(8))
    .nearBSP = Val(Field(9))
    .actualBSP = Val(Field(10))

    However I kept finding the BSP was 0. After looking at the API documentation there is (or no longer) appears to be a feild for asianLineID. Is this correct?
    If so, is the reason my BSP is always zero because I nead to drop the feild numbers down one, ie .actualBSP = val(Field(9)).

    Or could I have made a mistake somewhere else that would cause BSP = 0 all the time (I am working with BSP markets)?

    EDIT: DOH! I had these fields mixed up between COMPLETEpricesCompressed and the normal PricesCompressed. As per your Step 14. Calling getMarketPricesCompressed, there is no .asianLineID in the normal pricesCompressed. I had somehow pasted the same field numbers in both unpack procedures.

    Silly mistake and sorry for the bother!
    Last edited by beans; 03-02-2011, 04:02 PM.

    Leave a comment:

Working...
X