Using VB2008 to acccess the Betfair API: A tutorial

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

  • Mumbles0
    replied
    Wpf

    Peter,

    Obviously I don't know much about WPF.

    Leave a comment:


  • Mumbles0
    replied
    ribogio7,

    These numbers are the "Book %" or "overround" values for the market.

    ribogio7-1.bmp

    I don't think you can get them directly from the API but they are quite easy to calculate. Their value is the sum of the reciprocals of the best prices, expressed as a percentage:
    For the Back = (1/2.08 + 1/4.4 + 1/3.35) * 100 = 100.7
    For the Lay = (1/2.1 + 1/4.5 + 1/3.45) * 100 = 98.8

    Leave a comment:


  • ribogio7
    replied
    Hi Mumbles0,

    I have upload an image.And i would like to ask a simple question.How can i take these numbers (100.7% and 99.3%) with betfair api...? (Which method must be use and which property must be use in this method)

    Thank you.
    Attached Files

    Leave a comment:


  • Peter Simple
    replied
    I know the DataGridView and have used it many times. But the DataGridView is part of Windows Form and not WPF (Windows Presentations Foundation). WPF shall be the successor of Windows Forms. Earlier versions (before VS 2010) WPF had nothing like a DataGridView and only WPF 3.5 introduced a similar tool and it was called "DataGrid" but is not so handy like the DataGridView (perhaps it is only a matter of convenience).

    I have now decided that i use WPF for all my new applications because soon or later you have to learn it.

    The basic way to display datas in WPF is so:

    1. You need a class

    Public Class Example

    Private _Item01 As String
    Private _ Item02 As String

    Public Property Item01/Item02 As String

    Get ... / Set ...

    ...

    End Class

    2. WPF XAML

    We have a DataGrid called "DataGrid1) in the Window

    <DataGrid AutoGenerateColumns="False" Height="271" HorizontalAlignment="Left" Margin="12,28,0,0" Name="DataGrid1" VerticalAlignment="Top" ItemsSource="{Binding}" Width="261" >
    <DataGrid.Columns>
    <DataGridTextColumn Header="Item" Width="90" Binding="{Binding Path=Item01}"></DataGridTextColumn>
    <DataGridTextColumn Header="Next Item" Width="90" Binding="{Binding Path=Item02}"></DataGridTextColumn>
    </DataGrid.Columns>
    </DataGrid>
    3. MainWindow.xaml.vb

    Class MainWindow

    Dim table As New List(Of Exampel)

    ...

    Private Sub X_Response_Process ( ...)

    Dim response As New Exampel

    ...
    response.Item01 = "x"
    response.Item02 = "y"

    table.Add(response)

    ...
    End Sub

    Private Sub ShowAllInDataGrid ()

    DataGrid1.ItemsSource = table
    DataGrid1.IsReadOnly = True

    End Sub

    When you modify items of the table and try to update the DataGrid you have to add:

    DataGrid1.Items.Refresh()

    This is the basic structure and should help for a start but things can become very quickly complex.

    Leave a comment:


  • Mumbles0
    replied
    Peter,

    I’m surprised you haven’t got DataGridView. It’s been included as a replacement for DataGrid since VB2005. Try this:

    Right-click on the Toolbox and select "Choose Items..." to show the "Choose Toolbox Items" form. You should find DataGridView on the list (on the ".NET Framework Components" tab) Ensure this is checked this and click OK. The DataGridView control should now appear in the Toolbox.

    Leave a comment:


  • Peter Simple
    replied
    I am using VB 10 and WPF 4.0 and i am missing really the DataGridView because you could load datas directly.

    In WPF 4.0 you have only a DataGrid and here is a direct loading not possible. You can not simply add a row. A DataGrid requires an item source like a class or datatable.

    Leave a comment:


  • Mumbles0
    replied
    Using DataGridView

    John10,

    A few thoughts on using DataGridView.

    I see that you are first loading the data into a DataTable object, then assigning this to the DataGridView. This is a perfectly valid approach, but did you know that you can load the DataGridView directly?

    You can set up column properties (header, width, alignment, format, etc.) with the columns editor. To launch the columns editor select the Columns property (in the properties window for dgvMarkets) and click on (...).

    Although there are many different ways to do this, the code to load the data can be similar to what you already have:

    Code:
      ......
      With AllMarkets
        For i = 0 To .marketData.Length - 1
          With .marketData(i)
            dgvMarkets.Rows.Add()  'Add a new row to dgvMarkets
            Dim row As DataGridViewRow = dgvMarkets.Rows(i)   'A reference to the new row
            row.Cells("colId").Value = .marketId  'Add the MarketIds
            row.Cells("colJump").Value = .eventDate.ToLocalTime   'and Start Time
            row.Cells("colNo").Value = ""        'and Race No (to do)
            row.Cells("colTrack").Value = ""        'and Track names (to do)
            row.Cells("colName").Value = .marketName         'and Race names
            row.Cells("ColExtra").Value = i
          End With
        Next
      End With
      ......
    This gives the result:

    [ATTACH]119[/ATTACH]


    Notice that the time value has been formatted with the columns editor (by setting the DefaultCellStyle.Format property for colJump).

    It’ easy to access a particular cell using row and column numbers, for example:

    x = dgvMarkets(4, 2).Value
    gets the value of the cell at column 4, row 2.
    Alternatively you can use the column name:

    x = dgvMarkets("colName", 2).Value
    You can get the corresponding marketId when you click on a row with a handler for the CellContentClick event:

    Code:
    Private Sub dgvMarkets_CellContentClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvMarkets.CellContentClick
      Dim marketId As Integer
      marketId = dgvMarkets("colId", e.RowIndex).Value  'get the marketId
      Print(marketId)  'To test
    End Sub
    Even though DataGridView looks complicated, it’s fairly easy to use as an output UI device.

    Leave a comment:


  • John10
    replied
    Mumbles0 just found the problem, I set columns in the DataGridVeiw first, what happened the data table columns also got added to the right (out of veiw) Removed columns from DataGridView and works properly. ps thanks for the quick response.

    Leave a comment:


  • Mumbles0
    replied
    John10,

    Your code works for me. Data is appearing in the rows of the grid.

    John10-1.png

    You've obviously got more work to do getting the column data right, but the basic structure seems OK. What problems are you having?

    Also - when you say you are using a DataGrid, do you mean a DataGridView? (A DataGrid is something else.)

    Leave a comment:


  • John10
    replied
    Mumbles0 Great tutorial, however i have a problem getting the UnpackAllMarkets data into a DataGrid, could you help.
    The DataGrid gets the rows with no data

    Code:
    Private TableMarkets As New DataTable  'The Markets data table
    
    Sub GetAllMarkets()
    
            Dim row As DataRow
    
            With TableMarkets.Columns    'Set up all columns
                .Add("colId")
                .Add("colJump")
                .Add("colNo")
                .Add("colTrack")
                .Add("colName")
                .Add("ColExtra")
            End With
    
            Dim oMarketsReq As New BFAU.GetAllMarketsReq
            Dim oMarketsResp As BFAU.GetAllMarketsResp
    
            With oMarketsReq
                .header = oHeaderAU()
                'Set request parameters here
                ReDim .eventTypeIds(0) : .eventTypeIds(0) = 7  'For horse racing
                ReDim .countries(1) : .countries(0) = "AUS" : .countries(1) = "NZL"
                .fromDate = Today
                .toDate = Today.AddDays(1)
            End With
    
            oMarketsResp = BetFairAU.getAllMarkets(oMarketsReq) 'Call AU exchange
            With oMarketsResp
                CheckHeader(.header)
                If .errorCode = BFAU.GetAllMarketsErrorEnum.OK Then
                    Print("**Markets**")
                    'Print(.marketData)
                    Dim AllMarkets As New UnpackAllMarkets(.marketData)  'Create an object and unpack the string
    
                    With AllMarkets
                        For i = 0 To .marketData.Length - 1
                            With .marketData(i)
                                Print(.marketId & " " & .marketStatus & "  " & .marketName & "  " & .menuPath)
                                row = TableMarkets.NewRow
                                row("colId") = .marketId  'Add the Markets Ids
                                row("colJump") = FormatDateTime(.eventDate, DateFormat.ShortTime) 'and Start Time
                                row("colNo") = 1             'and Race No
                                row("colTrack") = .eventDate                'and Track names
                                row("colName") = .eventDate                'and Race names
                                row("ColExtra") = ""
                                TableMarkets.Rows.Add(row)
                            End With
                        Next
                    End With
                Else
                    Print("ErrorCode = " & .errorCode.ToString)
                End If
            End With
            dgvMarkets.DataSource = TableMarkets  'Show the data
            dgvMarkets.Refresh()
    
        End Sub
    Last edited by John10; 14-09-2010, 03:41 AM. Reason: adding more info

    Leave a comment:


  • Peter Simple
    replied
    Some interesting observations.

    1. It was my fault to use a service reference. But i could do all calls (login, logout, gunds, event etc) using the global and the UK_Exchange service. Every call was repsonded with correct .Resp which i could transform in usefull datas (using the common techniques which here are also shown).

    2. After adding the web reference and changing the code the "MaxReceivedMessageSize" exception was gone ! That is a dramatic difference because i can now receive much, much larger message files. So it was no problem to get all saturday football matches.

    3. It seems that the "MaxReceivedMessageSize" is a common problem. Here is an interesting link

    http://craigrandall.net/archives/200...size/#more-995

    I have also found various articles by MSDN but i have no real clue about the matter. It seems to me that there is a default size which depends on the RAM in your system but you can change it manually when you understand the technique.

    Leave a comment:


  • Oldb
    replied
    Mumbles0...

    Yes i was calling "getCompleteMarketPricesCompressed" in error

    Your original instructions were 100% accurate.. sorry.

    Appreciate your patience

    Regards Oldb

    Leave a comment:


  • Mumbles0
    replied
    Reply to granted (Re: accessing the selectionId)

    If you want to access the SelectionId for a clicked runner button then you can call a sub from the event handler. For example:

    Code:
    [COLOR="Gray"]'The 'Click' event handler
    
    Private Sub RunnerButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
      Dim RunnerButton As Button = sender  'A reference to the button that was clicked
      With RunnerButton
        [COLOR="Black"]ProcessYourSelection(.Tag)  'Call your sub with the selectionId for the clicked button[/COLOR]
      End With
    End Sub[/COLOR]
    
    [COLOR="Black"]Sub ProcessYourSelection(ByVal SelectionId As Integer)
      [I]'Code to do something with the clicked selection[/I]
    End Sub[/COLOR]
    The selectionId for each runner is in the button's Tag property. When you call the sub the SelectionId is passed in as the parameter.

    Leave a comment:


  • Mumbles0
    replied
    Reply to Oldb (re: compressed prices)

    There are 2 API calls which return compressed prices: getMarketPricesCompressed and getCompleteMarketPricesCompressed.

    If you want the data to be the same as getMarketPrices, then call getMarketPricesCompressed (as shown in my post).

    I think you are calling getCompleteMarketPricesCompressed instead.

    Leave a comment:


  • Mumbles0
    replied
    Reply to Peter Simple

    Peter,

    BFGlobalServiceClient

    Looks like you've added a service reference instead of a web reference in Step 2. See this post. It's interesting to see that you're getting somewhere with the service reference, but the tutorial exercises use the web reference.

    System.ServiceModel.CommunicationException

    Sometimes users have got this exception when requesting a large amount of data from getAllMarkets. See this conversation. You may have to increase the value of the maxStringContentLength (and possibly other values) in your app.config file.

    Leave a comment:

Working...
X