Using VB2008 to acccess the Betfair API: A tutorial

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

  • JayBee
    replied
    Colouring cells dependent on value...

    Having started programming in 1981 on a Tandy TRS-80, I have yet to evolve the ability to perform object-oriented programming.

    I have a working program now and am certain it would give a younger programmer a heart attack.

    What I would like to do now is use the existing code in this excellent thread but colour code individual cells dependent on value range.

    Any ideas?

    I would prefer not to do a complete rewrite of all the excellent work already done in this thread.

    Thanks.

    Leave a comment:


  • Tachikoma
    replied
    cant find Async version of getM

    Hi Mumbles0, thanks for your great work.

    Referring to your Step 9. Making Async API Calls.

    BetFairUK.getMarketPricesAsync(MpricesReq)

    Why I can't find the Async version of getMarketPrices method?

    Leave a comment:


  • JayBee
    replied
    Thank you Mumbles0, works perfectly.

    Originally posted by Mumbles0 View Post
    JayBee,

    The TreeView example of Step 15 uses data obtained from the getAllMarkets call made in Step 5. Here the properties .fromDate and .toDate define the time window for the returned markets. In other words, getAllMarkets only returns markets whose start times lie between these limits.

    So to get tomorrow’s UK racing markets try this...

    Leave a comment:


  • Mumbles0
    replied
    Tomorrow‘s markets

    JayBee,

    The TreeView example of Step 15 uses data obtained from the getAllMarkets call made in Step 5. Here the properties .fromDate and .toDate define the time window for the returned markets. In other words, getAllMarkets only returns markets whose start times lie between these limits.

    So to get tomorrow’s UK racing markets try this:

    Code:
    [COLOR="Gray"]  Dim oMarketsReq As New BFUK.GetAllMarketsReq
      Dim oMarketsResp As BFUK.GetAllMarketsResp
      With oMarketsReq
        .header = oHeaderUK()
        ReDim .eventTypeIds(0) : .eventTypeIds(0) = 7
        ReDim .countries(0) : .countries(0) = "GBR"
    [COLOR="Black"]    .fromDate = Today.AddDays(1)    'Midnight tonight
        .toDate = Today.AddDays(2)      'Midnight tomorrow night[/COLOR]
      End With
      oMarketsResp = BetFairUK.getAllMarkets(oMarketsReq)
      .........[/COLOR]
    Note that the Today method returns your local time.

    Leave a comment:


  • JayBee
    replied
    Viewing horse races the night before...

    Mumbles0,

    On the Betfair website you can view tomorrow's races and any early betting.

    I would like to do this with the application you have been building in this thread.

    Currently, the night before, if I click the markets button then nothing is returned.

    How do I get a list of tomorrow's races in my Tree View?

    Thank you.

    Leave a comment:


  • Monairda
    replied
    Mumbles, It's works fine!!

    Thanks for your help!!

    Leave a comment:


  • Mumbles0
    replied
    Step 33. Selecting a runner

    If you’ve succeeded with Steps 31 and 32 you should now be able to display the list of runners for a selected market in a DataGridView on a TabPage within a TabControl. You may now want to select a particular runner, perhaps to display additional data or set up a bet.

    It’s convenient to select a runner simply by clicking on it’s grid row. For this we need a handler for the grid’s CellMouseClick event:

    Code:
    Private WithEvents SelectedGrid As RunnerGrid  'A variable to hold a reference to the currently-selected grid
    
    'This event fires when you click on a cell in the selected RunnerGrid:
    
    Private Sub SelectedGrid_CellMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles SelectedGrid.CellMouseClick
        Dim MarketId, SelId As Integer, SelName As String
        Dim j As Integer = e.RowIndex  'The clicked row no.
    
        Beep()  'Get values for the clicked runner:
        SelId = SelectedGrid(RunnerGrid.colSelId, j).Value   'The selectionId
        SelName = SelectedGrid(RunnerGrid.colRunner, j).Value  'The name
        MarketId = tabMarkets.SelectedTab.Name 'The marketId
    
        Print(MarketId & " " & SelId & " " & SelName)  'To demonstrate
    
      End Sub
    This Sub demonstrates how to extract parameters associated with the selected runner from the grid (and tab). Your app will typically have more code than this.

    If you test this you will notice that nothing happens when you click on a runner. This is because the SelectedGrid object variable contains Nothing. To make it work we must assign a reference to the currently-selected DataGridView. We can do this by handling the Selected event for the TabControl. This fires whenever a different TabPage is selected:

    Code:
    'Event fires when a Tab is selected:
    
    Private Sub tabMarkets_Selected(ByVal sender As Object, ByVal e As System.Windows.Forms.TabControlEventArgs) Handles tabMarkets.Selected
      TabSelect(e.TabPage)
    End Sub
    
    Private Sub TabSelect(ByVal Tab As TabPage)
      If Tab IsNot Nothing Then
        SelectedGrid = Tab.Controls(0)   'A reference to the RunnerGrid on this Tab
      Else
        SelectedGrid = Nothing  'Clear the variable if no tabs exist
      End If
    End Sub
    Also uncomment the line in Sub DisplayMarketTab that was added in step 31:

    If .TabPages.Count = 1 Then TabSelect(Tab)
    I have included this line because, for some strange reason, the Selected event for the TabControl does not fire when the first TabPage is added. (Events often don’t do quite what you expect - this can drive you nuts.)

    Run the project to test. Select a market then click on a runner’s row in the grid. Sub SelectedGrid_CellMouseClick should now execute, taking the course of action you‘ve programmed.

    Leave a comment:


  • Mumbles0
    replied
    Sports API + VB .Net,

    The two recent steps in the tutorial (Step 31 & Step 32) do what you are asking - show the best back and lay prices for a market in a DataGridView. It is easy to extend this to show amounts available for each price.

    The Steps in the tutorial are to help you understand VB programming, and to give you ideas for design. You must write your own application. I won’t do this for you.

    Perhaps you are having trouble reading my English. It may be tedious but I think some other readers are using a translator to help.
    Last edited by Mumbles0; 07-11-2010, 12:14 AM.

    Leave a comment:


  • Sports API + VB .Net
    replied
    How To Display Odds

    My question is how can we display runners and their odds and amout available to back and lay after selecting perticular market navigating treeview as same as happens over betfair webiste i am stick to this and cant solve myself Please MUMBLE help me out you are geneous in your previous post i am sure you have solved these probs which is very easy for others but not for me kindly help me out in this regards............. Ignore poor english,,,,,,,,,i will be waiting.............

    Leave a comment:


  • Monairda
    replied
    Mumbles0, It works perfectly!
    Looking forward to the next step.

    Thank you very much

    Leave a comment:


  • Mumbles0
    replied
    Step 32. Displaying Prices in the Runner Grid

    In this step we add more code to display price info for the runners shown on the Tabs we made in Step 31.
    For this we require more columns in the DataGridView, so add extra code (shown bold) to Class RunnerGrid:

    Code:
    [COLOR="Gray"]Public Class RunnerGrid   'A customised DataGridView
    
      Inherits DataGridView
    
      Public Const colRunner = "Runner"  'Runner names column
      Public Const colSelId = "SelId"    'SelectionId column
      [COLOR="Black"]Public Const colBack = "Back"      'Back price column
      Public Const colLay = "Lay"        'Lay price column[/COLOR]
    
      Sub New(ByVal Runners As BFUK.Runner())
    
        RowHeadersVisible = False  'Turn off row headers
        Dock = DockStyle.Fill       'The grid fills the Tab
        If Runners.Length > 0 Then   'Runner data exists
    
          Dim NameColumn As New DataGridViewTextBoxColumn  'Add column for runner names 
          With NameColumn
            .Name = colRunner
            .ReadOnly = True
            .AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells  'Column width is automatic
          End With
          Columns.Add(NameColumn)  'Add to columns collection
    
          Dim SelIdColumn As New DataGridViewTextBoxColumn  'Add column for selectionId
          With SelIdColumn
            .Name = colSelId
            .Width = 70       'Column width is fixed
            .ReadOnly = True
          End With
          Columns.Add(SelIdColumn)  'Add to columns collection
    
          RowCount = Runners.Length  'A row for each runner 
          For i = 0 To RowCount - 1
            With Runners(i)
              Item(colRunner, i).Value = .name  'Add the runner name
              Item(colSelId, i).Value = .selectionId  'Add the selectionId
            End With
          Next
    
    [COLOR="Black"]      Dim BackColumn As New DataGridViewTextBoxColumn  'Add column for Back prices
          With BackColumn
            .Name = colBack
            .Width = 50
            .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            .DefaultCellStyle.Format = "f2"
            .ReadOnly = True
          End With
          Columns.Add(BackColumn)
    
          Dim LayColumn As New DataGridViewTextBoxColumn  'Add column for Lay prices
          With LayColumn
            .Name = colLay
            .Width = 50
            .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            .DefaultCellStyle.Format = "f2"
            .ReadOnly = True
          End With
          Columns.Add(LayColumn)[/COLOR]
    
        End If
      End Sub
    
    [COLOR="Black"]  Sub UpdatePrices(ByVal RunnerPrices As BFUK.RunnerPrices())  'Method to update the Prices
        Dim i, j, SelectionId As Integer
    
        For i = 0 To RowCount - 1  'For each row in grid
          SelectionId = Item(colSelId, i).Value
          j = Array.FindIndex(RunnerPrices, Function(x As BFUK.RunnerPrices) x.selectionId = SelectionId) 'Array index for this runner
          If j >= 0 Then 'Prices exist for this runner
            With RunnerPrices(j)
              Item(colBack, i).Value = If(.bestPricesToBack.Length > 0, .bestPricesToBack(0).price, "")   'Update best Back price
              Item(colLay, i).Value = If(.bestPricesToLay.Length > 0, .bestPricesToLay(0).price, "")      'Update best Lay price
            End With
          End If
        Next
    
      End Sub[/COLOR]
    
    End Class[/COLOR]
    To add a new column you simply create a new instance of DataGridViewTextBoxColumn and assign its properties as required. These properties control the behaviour of the column (width, readonly, visible, etc). The DefaultCellStyle property controls the appearance of the data in the column (alignment, font, colour, format, etc). You add this column to the grid by calling the Columns.Add method.

    For this exercise we only add two columns to show the best back and lay prices. A typical app would probably have more (for amounts, other prices, bets, etc). I’ll leave this up to you.

    The method UpdatePrices updates the price columns. The calling parameter is the RunnerPrices array which will be returned by getMarketPricesCompressed.

    To get regular price updates we will call getMarketPricesCompressedAsync from a timer. We already have a PriceTimer from Step 8 which we can re-use. Select the PriceTimer and ensure that these properties are set: Enabled = True, Interval = 2000 (for 2 sec period). Change the Tick event handler to this:

    Code:
    Private Sub PriceTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles PriceTimer.Tick
      With tabMarkets
        If .SelectedTab IsNot Nothing Then  'A Tab is selected
          Dim Req As New BFUK.GetMarketPricesCompressedReq
          Req.header = oHeaderUK()
          Req.marketId = .SelectedTab.Name  'Get prices for this market
          BetFairUK.getMarketPricesCompressedAsync(Req, New UserState(.SelectedTab)) 'Call the API to get prices
        End If
      End With
    End Sub
    For the async call we also require Class UserState (which was given in Step 28):

    Code:
    Class UserState
      Property Param As Object
      Sub New(ByVal Value As Object)
        Param = Value
      End Sub
    End Class
    Note the use of the SelectedTab property which holds a reference to the currently-selected Tab. We call getMarketPricesCompressedAsync with the marketId for this Tab (which is in the Tab‘s Name property).

    We also put the SelectedTab reference into the UserState object of the async call. This lets us know, when the API returns the price data, which Tab was selected when the call was made.

    From step 14 you may already have an event handler for getMarketPricesCompressedCompleted. This has probably served its purpose so I suggest you comment it out and replace it with this new one:

    Code:
    Private Sub BetFairUK_getMarketPricesCompressedCompleted(ByVal sender As Object, ByVal e As BFUK.getMarketPricesCompressedCompletedEventArgs) Handles BetFairUK.getMarketPricesCompressedCompleted
      Try
        If Not e.Cancelled Then
          With e.Result
            CheckHeader(.header)
            If .errorCode = BFUK.GetMarketPricesErrorEnum.OK Then 'OK
    
              Dim Tab As TabPage = e.UserState.Param  'The selected Tab when the request was made
              Dim Rgrid As RunnerGrid = Tab.Controls(0)  'A reference to the selected RunnerGrid
              Dim oMarketPrices As New UnpackMarketPricesCompressed(.marketPrices)  'Unpack the prices
              Rgrid.UpdatePrices(oMarketPrices.runnerPrices) 'Update the prices in the grid
    
            Else
              Print("GetMarketPricesCompressed error:" & .errorCode.ToString) 'If problem
            End If
          End With
        End If
      Catch ex As ApplicationException
        Print(e.Error.Message)
      End Try
    End Sub
    This Sub is invoked by the system when a response is returned from getMarketPricesCompressed. If the reponse is OK, the object variable Tab is assigned a reference to the Tab that was selected when the API request was made. To ensures that we update the correct RunnerGrid , we use Tab rather than the current SelectedTab. These object references will usually be the same, but they could differ if another Tab has just been selected. From Tab we obtain a reference to its RunnerGrid, which we update by calling the UpdatePrices method after first unpacking the price data.

    For at the UpdatePrices method (in Class RunnerGrid above): We obtain the selectionId for each grid row in turn. We then use the Array.FindIndex method to lookup the index (j) for the corresponding selectionId in the RunnerPrices array. We do this because the order of the runners in the grid rows (derived from getMarket) is not necessarily the same as the order of the price data returned in the RunnerPrices array. This approach ensures that the array element RunnerPrices(j) contains the corresponding price data, and also caters for the possibility of a removed runner (for which j = -1).

    That gives us the prices.

    There is a bit more to this topic. The next step we look at how to select a runner when a grid row is clicked.

    Leave a comment:


  • Sports API + VB .Net
    replied
    Help Learning Betfair

    I forgot to mention my email address if someone is interested to help me out

    My id is = wilsum786@hotmail.com

    Leave a comment:


  • Sports API + VB .Net
    replied
    Using DataGridView To Display Market Odds

    Sorry for using Poor English...............................
    Hi i am a new for betfair api program, this article is quite amazing for new babies like me, my question is very often:
    Q: how can we display the market odds in a datagridview does any one knows the coding for that in vb.net.
    and another question is :
    Q: if anyone can post jpeg file displaying how can we use all the api calls step by step for example 1st call for login then keepalive then display all markets in treeview as betfair does then if user double click on perticular market -------> the markets odds and available amounts display in datagridview then bet on a perticular selection .......... i have read the first 10 steps posted by mumble that was helpfull for me but i still dont understand what to do first if i call all the markets in treeview just after login as happened on betfair then if in runtime i select perticular market what else should i do....................................... I am just a vb application designer and i had never worked on any project in which api are called......
    What i want to design is just a simple application as betfair itself all the functions will remain same and it is just for practise after getting complete knowleadge about the simple betfair interface i will further decide what special features should be there in my prog.............
    IT WILL BE VERY THANKFULL IF SOME ONE SEND ME A COMPLETE VB PROJECTS FOR LEARNING PURPOSE......................... SO I GO FURTHER.... SORRY IN ADVANCE IF I MAKE SOMEONE ANGRY..... BUT NO ONE IS MASTER FROM SCRATCHE..................

    Leave a comment:


  • Monairda
    replied
    To Mumbles0:

    Simply fantastic!

    As always thank you very much :-))

    Leave a comment:


  • Mumbles0
    replied
    Step 31. Using the TabControl for multi-markets.

    A control worth considering for your user interface is the TabControl. In this step we will investigate using a TabControl to view the data for several markets at once.

    Drag a TabControl from the Toolbox onto your form and rename it tabMarkets. Initially two TabPages are shown, but we don’t want these. Select the TabControl (itself, not the TabPages) and in the properties window select the TabPages property, then click on (...) to show the "TabPage Collection Editor". Click on the Remove button to remove TabPage1 and TabPage2. OK.

    Now add a Sub which displays a TabPage for a given market:

    Code:
    'Display the Tab for the given MarketId
    
    Private Sub DisplayMarketTab(ByVal MarketId As Integer)
    
      With tabMarkets
        If .TabPages.ContainsKey(MarketId) Then  'A Tab exists for this market
          .SelectedTab = .TabPages(MarketId.ToString)  'Show the existing Tab
        Else  'A new market, call getMarket
          Dim Req As New BFUK.GetMarketReq With {.header = oHeaderUK(), .marketId = MarketId}
          Dim Resp As BFUK.GetMarketResp = BetFairUK.getMarket(Req)  'Call API (getMarket)
          CheckHeader(Resp.header)
          If Resp.errorCode = BFUK.GetMarketErrorEnum.OK Then
    
            Dim Tab As New TabPage  'Create a new Tab
            Tab.Name = MarketId   'The name is the marketId
            Tab.Text = Resp.market.name  'The Tab's caption is the market name
            'Tab.Controls.Add(New RunnerGrid(Resp.market.runners)) 'Put a DataGridView on the Tab
            .TabPages.Add(Tab)   'Add this tab to the TabPages collection
            .SelectedTab = Tab   'Show this Tab
            'If .TabPages.Count = 1 Then TabSelect(Tab) 'Because first tab does not raise 'Selected' event
    
          Else
            Print("GetMarket error: " & Resp.errorCode.ToString)
          End If
        End If
      End With
    End Sub
    Note that 2 lines have been commented out. We will include these later on.

    We can call this Sub when we click on a market node of the TreeView control we added in Step 15 if we add a line to the existing AfterSelect event handler:

    Code:
    [COLOR="Gray"]Private Sub tvMarkets_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tvMarkets.AfterSelect
      If e.Node.Nodes.Count = 0 Then
        Beep()
        Dim marketId As Integer = Val(e.Node.Name)  'This is the selected marketId
        [COLOR="Black"]DisplayMarketTab(marketId)   'Display a Tab for this market[/COLOR]
      End If
    End Sub[/COLOR]
    Alternatively you could call it from a "Today’s Card" list (Step 18) if you extract the marketId.

    When Sub DisplayMarketTab is called it first tests the TabPages property to see if a Tab already exists for the given marketId. If so, it simply displays the existing Tab, otherwise an API call is made to getMarket and a new Tab is added. Run the project to test this. Click on a few market nodes in the TreeView and you will, I hope, see it working.

    It’s handy to have the means to remove a tab when it is no longer required. We can do this with a KeyDown event handler:

    Code:
    Private Sub tabMarkets_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles tabMarkets.KeyDown
        If e.KeyCode = Keys.Delete Then  'Delete key down
          With tabMarkets
            If .SelectedTab IsNot Nothing Then
              .TabPages.RemoveByKey(.SelectedTab.Name)  'Remove the Tab
            End If
          End With
        End If
      End Sub
    This removes the currently-selected Tab when the Delete key is pressed while tabMarkets is selected.

    For each market we will use a DataGridView to show the list of runners. Because the market Tabs are added while the program runs we cannot simply drag a DataGridView from the Toolbox. Instead, we add these at runtime.

    Add a class module from the Project menu (Project > Add Class). Name it RunnerGrid and add this code:

    Code:
    Public Class RunnerGrid   'A customised DataGridView
    
      Inherits DataGridView
    
      Public Const colRunner = "Runner"  'Runner names column
      Public Const colSelId = "SelId"    'SelectionId column
    
      Sub New(ByVal Runners As BFUK.Runner())
    
        RowHeadersVisible = False  'Turn off row headers
        Dock = DockStyle.Fill       'The grid fills the Tab
        If Runners.Length > 0 Then   'Runner data exists
    
          Dim NameColumn As New DataGridViewTextBoxColumn  'Add column for runner names 
          With NameColumn
            .Name = colRunner
            .ReadOnly = True
            .AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells  'Column width is automatic
          End With
          Columns.Add(NameColumn)  'Add to columns collection
    
          Dim SelIdColumn As New DataGridViewTextBoxColumn  'Add column for selectionId
          With SelIdColumn
            .Name = colSelId
            .Width = 70       'Column width is fixed
            .ReadOnly = True
          End With
          Columns.Add(SelIdColumn)  'Add to columns collection
    
          RowCount = Runners.Length  'A row for each runner 
          For i = 0 To RowCount - 1
            With Runners(i)
              Item(colRunner, i).Value = .name  'Add the runner name
              Item(colSelId, i).Value = .selectionId  'Add the selectionId
            End With
          Next
    
        End If
      End Sub
    
    End Class
    This class is based on the DataGridView. The Inherits statement gives the RunnerGrid all members of the DataGridView class as well as any we care to add. We call the constructor (Sub New) with the .Runners array returned in a getMarket response object to create columns for the runner names and selectionIds. The grid is then loaded with the runner names and selectionIds.

    The line in Sub DisplayMarketTab:

    Tab.Controls.Add(New RunnerGrid(Resp.market.runners))
    invokes this constructor and places a RunnerGrid, complete with runner names and selectionIds, onto a Tab. Uncomment this line and run the project to test it.

    This step demonstrates the basic operation of a TabControl with DataGridView controls placed on the Tabs at runtime. In the next step we will add some prices returned by getMarketPricesCompressed.

    Leave a comment:

Working...
X