Using VB2008 to acccess the Betfair API: A tutorial

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

  • Mumbles0
    replied
    Calypsored,

    It look like you are still a bit confused by classes, objects, methods, etc. and passing arguments to procedures (i.e. subs and functions).

    In step 7 Sub ShowMprices simply "prints" the properties of the GetMarketPricesResp object passed to it as a parameter. You have modified this sub by making it a function method of your BFInterface class which returns a string. That’s OK but, because the parameter remains the same, it should be called similar to the Step 7 example.

    You have declared the function method like this:

    Public Function ShowMprices(ByVal MpriceResp As BFUK.GetMarketPricesResp) As String
    The argument used in the call must evaluate to an object of type BFUK.GetMarketPricesResp. You could call this as in Step 7:

    Dim sMsg As String = BFIF.ShowMprices(BetFairUK.getMarketPrices(Mprices Req))
    where MpricesReq is the function which returns the request object given in Step 7.

    To make this clearer I will expand this out:

    Code:
      Dim PricesResp As BFUK.GetMarketPricesResp          'Declare a variable to hold an object of type BFUK.GetMarketPricesResp
      PricesResp = BetFairUK.getMarketPrices(MpricesReq)  'Call the API to get the response object
      Dim sMsg As String = BFIF.ShowMprices(PricesResp)   'Call ShowMprices with the response object as the argument
    Note that PricesResp is an object of type BFUK.GetMarketPricesResp. This satisfies the calling requirement.

    You have mentioned that you are trying to make a class (presumably BFInterface) containing the various API calls. This is a good idea, but using ShowMprices isn’t the way to go. Each method of the class should contain code to call the API. ShowMprices does not do this.

    Leave a comment:


  • Grantay.
    replied
    calypsored, you have a few things going askew...

    1) your ShowMprices function is set to return a string, it acutally returns and object

    2) your call to ShowMPrices does not specify the marketid of interest

    so instead of:

    Code:
    Dim sMsg As String = bfIF.ShowMprices(bfIF.BetFairUK.getMarketPricesresp)
    
    try
    
    Dim dMsg = ShowMprices(BetFairUK.getMarketPrices(MpricesReq(1235456)))
    
    or whateveryour marketid of interest is.
    Grantay

    Leave a comment:


  • calypsored
    replied
    Mumbles and others, great thread - an enormous help someone new to api programming like me.

    I am trying to create a generic class project to hold all the various api calls so that i don't have to replicate the same code for differing front ends.

    I am stumped by one thing and have tried every which way that I can come up with and would appreciate any help you are able to give..

    Way back in Step 7, trying to call the sub (I've actually turned it into a function but don't see why that would cause a problem) from my form I can't work out a way to get the ByVal parameter passed. I've made the reference to BFUK global, which isn't ideal I know, in an attempt to work around this to no avail...

    This is my code:

    In my class project:

    Public Function ShowMprices(ByVal MpriceResp As BFUK.GetMarketPricesResp) As String

    Dim Lay, Back, sMsg As String
    With MpriceResp
    CheckHeader(.header)
    sMsg &= ("ErrorCode = " & .errorCode.ToString) & vbCrLf
    If .errorCode = BFUK.GetMarketPricesErrorEnum.OK Then
    With .marketPrices
    sMsg &= ("MarketID = " & .marketId) & vbCrLf
    For i As Integer = 0 To .runnerPrices.Length - 1
    With .runnerPrices(i)
    sMsg &= ("Runner " & i + 1 & " LPM = " & .lastPriceMatched) & vbCrLf
    Back = ""
    For j As Integer = 0 To .bestPricesToBack.Length - 1
    With .bestPricesToBack(j)
    Back = Back & " " & .price & "/" & Int(.amountAvailable)
    End With
    Next
    Lay = ""
    For j As Integer = 0 To .bestPricesToLay.Length - 1
    With .bestPricesToLay(j)
    Lay = Lay & " " & .price & "/" & Int(.amountAvailable)
    End With
    Next
    sMsg &= ("Back = " & Back & " Lay = " & Lay) & vbCrLf
    End With
    Next
    End With
    End If
    End With
    Return sMsg
    End Function

    And the calling procedure from my form (the class project is referenced as "BFIF":

    Private Sub bPrices_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bPrices.Click
    Dim sMsg As String = bfIF.ShowMprices(bfIF.BetFairUK.getMarketPricesres p)
    Print(sMsg)
    End Sub

    The message I'm getting is this: ' bfIF.BetfairUK.getMarketPricesResp is not a member of BFInterface.BFUK.ExchangeService '

    I'm sure the solution is simple but I cannot figure it out! Any help much appreciated.

    Thanks

    Leave a comment:


  • Dingo Bongo
    replied
    Well done sir!!!!

    First and foremost, a big thanks to Mumbles for this thread. It has been a godsend to a VB noob like me. I have followed all of the steps and as a result I now have the outline of a useful application.

    I am going back over the code in more detail now so that I can learn how to carry things forward on my own, in my own direction. To this end I have done a couple of things which may be of use to other users and the noobs that will no doubt follow in my footsteps.

    1) I have copypasted all the posts in this thread in to a Word document. I have two versions of this document now. One is Mumbles lessons ONLY. The other, which isnt quite finished yet, has all the posts BUT has been edited so that posts have been sorted into categories which makes it much easier to follow. I will also be putting these into a Notepad++ format when I have finished the edit.

    2) In the course of going back over the code I am adding in a more detailed set of comments which often include Mumbles posts/extracts as a precis if deemed suitable. Basically they comment on each step of the code so that noobs can see what is going on incrementally.

    I have a bit of time off work just now so Im going to be able to get this finished in the course of the next few days and I'll post up some files with the completed docs in.

    Once again, many thanks for your instruction Mumbles. Big up yourself!!!

    Leave a comment:


  • John_The_Greek
    replied
    Thanks Mumbles0,

    it seems that it will do the job i want...

    Cheers



    John

    Leave a comment:


  • Mumbles0
    replied
    Bet results

    Call getBet. This returns a lot of info about your bet.

    Leave a comment:


  • John_The_Greek
    replied
    Problem with bet result

    Hello friends,

    I have read the thread and the API guide but i can not understand how can i get the result of a settlet bet. (e.g. i have the bet id and i want the API to return the bet's profit or loss).

    Please if you have write about this in this forum tell me the page no or the topic title.


    Thanks


    John

    Leave a comment:


  • John_The_Greek
    replied
    mubles0,

    thank you so much...

    so simple and yet so effective...

    thanks again friend

    have a nice day

    Leave a comment:


  • Mumbles0
    replied
    Formatting Time column

    John_The_Greek,

    You can format the data in a column of a DataGridView by adding code to handle its CellFormatting event. This event fires whenever your program writes data to a cell of the DataGridView. Here is an example:

    Code:
    Private Sub DGView_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles DGView.CellFormatting
        Dim d As Date
    
        If e.ColumnIndex = RaceTimeColNo Then  'Race time column is being updated
          d = e.Value
          e.Value = d.ToString("H:mm")  'Convert DateTime value to 24-hour time value
        End If
    
      End Sub
    The system calls this with e being an object containing some properties of the cell currently being written to.
    RaceTimeColNo is the column number of your race time column.
    The code modifies the Value property of the cell using the ToString method with a custom format string ("H:mm").

    Leave a comment:


  • John_The_Greek
    replied
    Problem with datagrid

    Hello friends,

    i have a little problem

    i populate a datagrid view through a DB with an sql sommand. One collumn is a race time which in .net appears with full date and time (e.g. 1/15/2011 11:50 am).

    Please advice how i can achieve to show only the time (e.g 11:50)


    Thanks alot


    John

    Leave a comment:


  • monkeymagix
    replied
    LAPSED Bet status hours before Race Time

    Could someone help me explain something I have noticed today.

    My bot placed a LAY bet at 3.00 am this morning which wasn't matched and it had a status of U for a good few hours. The race time is for 14:15 this afternoon and it was part of a trade bet and the WIN part was matched immediately.

    However at 09:01:02 this morning when my bot checked the current status of the bet to see if it had been matched the betfair API returned a status code of L = LAPSED.

    I have gone into the betfair website to double check this and the bet is under the LAPSED section in the current bets part of the site.

    The WIN part of the TRADE is still active and appearing in the MATCHED section so the runner hasn't been removed from the race or the race cancelled and I would have expected a V = VOID status code if that had happened anyway.

    Does anyone know what would cause a status code of L = LAPSED to occur before the market has been settled? I was under the impression the only way to obtain a status of LAPSED was when an unmatched bet couldn't be matched before the market was settled.

    From my log file

    Checking Bet Status for a LAY bet with BetID = 13274041XXX which was for XX LAY bet for: Inside Dealer at Taunton - 10/01/2011 14:15:00; Last Bet Status: U
    This bets status has changed from U to L

    Thanks

    Leave a comment:


  • monkeymagix
    replied
    Thansk

    Thanks for that Mumbles.

    I really hadn't seen that table anywhere before and the limit on prices definitely explains a lot of issues I have had with my auto trading bot.

    I have updated my bot to handle the INVALID_INCREMENT error message.

    Can you point me to something that lists out the specific details of the errors and what would cause them to be raised. Most of them are obvious but I am interested in knowing what instances would cause CANNOT_ACCEPT_BET
    to be raised.

    Thanks for your help

    Leave a comment:


  • Mumbles0
    replied
    Price Increments

    Monkeymagix,

    The table of price increments is given here.

    If you attempt to place a bet at price 11.80 the resultCode will return INVALID_INCREMENT.

    Leave a comment:


  • monkeymagix
    replied
    Code to ensure a price is valid

    If anyone is interested the following code may be useful for ensuring that a price is valid. Betfair only allows prices that increment in certain steps (which I only found out today) therefore if you have a price of 11.80 it won't be accepted as prices between 10 and 20 must increment in steps of 0.5 so 11, 11.50 or 12 are valid.

    I am doing automatic trading where the LAY bet price is set once the WIN bet has been placed and I create a range (best price, max price) by deducting specified values from the matched WIN price. Therefore quite often these prices are actually invalid and my bets were not being placed.

    I created this User Defined Function (SQL 2005) which will round any invalid price down to the next valid value and I just wrap any potential prices in it before use. You can use it as is or take the code out and use it a pseudo code.

    Code:
    -- =============================================
    -- Author:		Rob Reid
    -- Create date: 04-JAN-2011
    -- Description: Ensure prices are valid in terms of betfairs price ranges
    /*
    
    -- examples 
    SELECT dbo.udf_BETFAIR_CHECK_PRICE(11.82) 
    11.50
    
    SELECT dbo.udf_BETFAIR_CHECK_PRICE(115.81)
    110.00
    
    SELECT dbo.udf_BETFAIR_CHECK_PRICE(2.47)
    2.46
    
    SELECT dbo.udf_BETFAIR_CHECK_PRICE(1.49)
    1.49
    
    */
    -- =============================================
    ALTER FUNCTION [dbo].[udf_BETFAIR_CHECK_PRICE]
    (
    	@Price decimal(10,2)
    )
    RETURNS decimal(10,2)
    AS
    BEGIN
    		
    	DECLARE @Remainder decimal(10,2)
    	
    	-- check whether our price is within each betfair range and check for any remainder
    	-- usinga MOD function. If there is no remainder the price is already valid and if
    	-- there is a remainder we can deduct it from our price to create a valid value
    	SELECT	@Remainder = CASE 	WHEN @Price BETWEEN  100 AND 1000 THEN @Price % 10 
    				WHEN @Price BETWEEN  50 AND 99 THEN @Price % 5  
    				WHEN @Price BETWEEN  30 AND 49 THEN @Price % 2  
    				WHEN @Price BETWEEN  20 AND 29 THEN @Price % 1  
    			        WHEN @Price BETWEEN  10 AND 19.99 THEN @Price % 0.5  
    				WHEN @Price BETWEEN  6 AND 9.99 THEN @Price % 0.2  
    				WHEN @Price BETWEEN  4 AND 5.99 THEN @Price % 0.1  
    				WHEN @Price BETWEEN  3 AND 3.99 THEN @Price % 0.05  
    				WHEN @Price BETWEEN  2 AND 2.99 THEN @Price % 0.02  
    				ELSE 0 END
    								
    	-- if there is any remainder we deduct it from our price to create a valid price
    	IF @Remainder > 0
    	  SELECT @Price = @Price - @Remainder	  
    	
    	RETURN @Price	
    	
    END

    Leave a comment:


  • monkeymagix
    replied
    Thanks Davecon I didn't even realise there was a limit on the kind of prices you could set bets to and because my bot is automatically calculating the TRADE LAY price by deducting a specified percentage from the matched WIN price on occasion this is giving me prices that are unacceptable e.g 11.80 as from between 10-20 you must increment in steps of 0.5.

    I have never seen a list of these acceptable price ranges anywhere so I have created one myself by using the betfair website and I will need to update my code to handle this.

    Strange thing is I wasn't getting any error message back from the API which would have pointed this out to me a long time ago. I get errors back if the bet amount is below £2 or I put a long floating number in as a price so I would have expected the BFUK.PlaceBetsResultEnum.INVALID_SIZE error to be raised but its not.

    Thanks for pointing this out to me

    Leave a comment:

Working...
X