Using VB2008 to acccess the Betfair API: A tutorial

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

  • gvigliani
    replied
    Drag & Drop for more markets in same Panel

    Hello everyone.
    I have a little problem, as always, I hope you will help me to solve. I have a TreeView with nodes and subnodes and that a panel should receive information about the clicked node and carried.
    In this way I wish I could put more markets on the same panel. If I click on the treeview = start Added: Drag & Drop = successive engagements

    I created this sub on the treeview
    Code:
    Private Sub tvMarkets_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles tvMarkets.DragEnter
                  If e.Data.GetDataPresent(DataFormats.Text) Then
                      e.Effect = DragDropEffects.Copy
                  Else
                      e.Effect = DragDropEffects.None
                  End If
    End Sub


    While these other two relate to the Panel that receives:

    Code:
    Private Sub tbox_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles tbox.DragEnter
                  If e.Data.GetDataPresent(DataFormats.Text) Then
                      e.Effect = DragDropEffects.Copy
                  Else
                      e.Effect = DragDropEffects.None
                  End If
    End Sub
    
    Private Sub tbox_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles tbox.DragDrop
                  Dim dummy As String = "hello"
                  Dim s As String = CStr(e.Data.GetData(dummy.GetType()))
                  s = s.Substring((s.IndexOf(":") + 1)).Trim()
                  Position.X = e.X
                  Position.Y = e.Y
                  Position = tbox.PointToClient(Position)
                  MsgBox(s)
    End Sub

    The problem is that the code tells me, via the msgbox (s) as the name of the text node and not the Node.Name that interests me.

    Do you have a way to solve my problem?

    I enclose also the code that gives me 'is this information if I click on the affected node without of course the drag and drop.

    Code:
    Private Sub tvMarkets_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tvMarkets.AfterSelect
                  If e.Node.Nodes.Count = 0 Then
                      Dim marketId As Integer = Val(e.Node.Name)    'This is the selected marketId  
                  End If
    End Sub
    Thank you

    Leave a comment:


  • Monairda
    replied
    Thank you very much

    You are a great help. You're always willing to help.

    I am interested in learning. The main problem is that I can not associate the call to getMarketPricesCompressedCompleted with the call to
    getMarketTradedVolumeCompressedCompleted without using the solution you developed.

    And I wanted to find another solution without having the forms filled monitor.

    I look forward to your response. Sorry for the English translation by a translator. Thank you very much.

    Leave a comment:


  • Mumbles0
    replied
    Reply to monkeymagix (re getMUBets)

    I’m pleased to see that a C# programmer has got some benefit from the thread. After all, the two languages come from the same stable and are basically similar. With C# all you have to do is put the type before the name, add some semicolons and throw in a few curly things;

    I translated your GetMUBetStatus method:

    Code:
    Public Sub GetMUBetStatus(ByVal betId As Long)
    
      Dim Req As New BFUK.GetMUBetsReq
      With Req
        .header = oHeaderUK()
        .betStatus = BFUK.BetStatusEnum.MU
        .recordCount = 100
        '// tried with a market ID but no luck - comment out when using the betId
        .marketId = 101836370
        '/*  OR	*/
        ReDim .betIds(0) : .betIds(0) = betId
      End With
    
      Dim resp As BFUK.GetMUBetsResp = BetFairUK.getMUBets(Req)
      With resp
        CheckHeader(.header)
        Print("ErrorCode: " & .errorCode.ToString)
        If .errorCode = BFUK.GetMUBetsErrorEnum.OK Then
          For i = 0 To .bets.Length - 1
            Print("BetID: " & .bets(i).betId & " - Status: " & .bets(i).betStatus.ToString & " - Price: " & .bets(i).price)
          Next
        End If
      End With
    
    End Sub
    This worked fine for me. I could use either marketId or betIds (or both). All I can suggest is perhaps the bet was not on the market you specified. This would give errorCode = NO_RESULTS.

    As far as I know there is no test facility for the Sports API. This would be handy to have because it’s not easy to experiment with partially-matched bets (without spending a lot of money). You have asked some very good questions. I don’t know the answers. I too would like to know, when a bet is partially matched:
    • Do the two parts have the same betId ?
    • Do they have the same transactionId?
    • What is the transactionId?

    Leave a comment:


  • Mumbles0
    replied
    Reply to Monairda (using the TabControl for multi-markets)

    Monairda,

    The TabControl is a nice way to view the data for several markets, but it requires a bit of effort to get it going. I will soon post a step (or two) showing how to do this.

    Leave a comment:


  • Mumbles0
    replied
    Reply to Mr.Anderson (re: security)

    The API has an "https://...." URL. All data transferred between the API and a remote host is encrypted using SSL. It is reasonable to assume that the security of the API is similar to the website as far as sending your username and password is concerned.

    (Note: This is IMHO. You could perhaps seek further info from Betfair re security.)

    It certainly is good policy not to hard-code your username & password, particularly if other people have access to your computer. You could perhaps use a couple of TextBoxes to login and logout as required. Thewhistler devised a way to do this using a separate Login form. See here.
    Last edited by Mumbles0; 15-10-2010, 11:12 AM. Reason: A few afterthoughts.

    Leave a comment:


  • Mumbles0
    replied
    Reply to Iraklis35 (Build Bet Lists)

    Let’s take one thing at a time, the statement:
    Bets(i).Add(d)
    will cause the error because Bets is nothing. It must first be initialized with some code like this:

    Code:
        ReDim Bets(n - 1)
        For i = 0 To n - 1
          Bets(i) = New List(Of BetInfo)
        Next
    where n is the number of runners in the market.

    The profit & loss code must integrate closely with your application. For the market of interest you will have some type of data structure (perhaps a DataGridView control) which holds runner data (names, selectionIds, etc.) obtained from a getMarket call. The bet lists should be incorporated within this structure, with each runner having its own bet list.

    You must have the runner data set up properly before you look at profit & loss calculation. I don’t know what you have...

    Leave a comment:


  • monkeymagix
    replied
    Cannot get getMUBets working.

    First off I would just like to thank the author of this series for such a great explaination of the Betfair API. It has proved to be invaluable and I have used it as the guide to creating my own C# console bot.

    Now my own system requires that each bet is stored in a table in my database with any corresponding relationship to a parent bet (so that I can
    do accumulators). Once the bet is placed I store the BetID in this table so that I can update it later once I know the outcome. However along
    with many people it seems I am having problems with the concept of partially matched bets as this could theoretically lead me to have multiple
    rows in my table with the same BetID but different bet amounts and prices etc.

    I do have a unique BetPK primary key on the table so I could do a SUM on all matched parts of the bet but I am stuck on how to collect all these parts
    to store them. From what I have read I should be using getMUBets and not getBet to ensure I get all parts of a bet however I am having problems getting the code to work.

    As a test I have just placed a back bet at stupidly high odds which remains unmatched and whilst I can run the following code with the relevant
    betID to find out it's unmatched:


    Code:
    public void GetBetStatus(long betId)
    {
        
        BFUK.GetBetReq Req = new BetfairBOT.BFUK.GetBetReq();
    
        Req.header = oHeaderUK();
        Req.betId = betId;
    
        BFUK.GetBetResp Resp = BetfairUK.getBet(Req);
        
        CheckHeader(Resp.header);
        
        if (Resp.errorCode == BFUK.GetBetErrorEnum.OK)
        {
    
    	if (Resp.bet.betStatus == BetfairBOT.BFUK.BetStatusEnum.S)
    	{
    
    	    // settled - did we win
    	    if (Resp.bet.profitAndLoss > 0)
    	    {
    		Program.ShowMsg("The bet: " + betId.ToString() + " has been settled and resulted in a profit of " + Resp.bet.profitAndLoss.ToString());
    	    }
    	    else
    	    {
    		Program.ShowMsg("The bet: " + betId.ToString() + " has been settled and resulted in a loss of " + Resp.bet.profitAndLoss.ToString());
    	    }
    	}
    	else if (Resp.bet.betStatus == BetfairBOT.BFUK.BetStatusEnum.M)
    	{
    	    Program.ShowMsg("The bet: " + betId.ToString() + " has been matched at price " + Resp.bet.matchedSize.ToString());
    	}
    	else if (Resp.bet.betStatus == BetfairBOT.BFUK.BetStatusEnum.U)
    	{
    	    Program.ShowMsg("The bet: " + betId.ToString() + " has not been matched");
    	}
    	else if (Resp.bet.betStatus == BetfairBOT.BFUK.BetStatusEnum.C)
    	{
    	    Program.ShowMsg("The bet: " + betId.ToString() + " was cancelled");
    	} 
        } 
    
    }
    when I try to use getMUBets (as its suggested to do) I cannot get the same info back and I just recieve the NO_RESULTS error code which is obviously
    wrong as the bet definitely exists. I have tried this method by supplying only a market ID and just a bet ID but they both return the same error.

    Code:
    public void GetMUBetStatus(long betId)
    {
        BFUK.GetMUBetsReq Req = new BFUK.GetMUBetsReq();
        Req.header = oHeaderUK();
    
        // tried with a market ID but no luck - comment out when using the betId
        Req.marketId = 101826566;
        Req.recordCount = 10;
    
       /*  OR	*/
        Req.betIds = new long[1];
        Req.betIds[0] = betId;     
        Req.betStatus = BFUK.BetStatusEnum.MU;
    
        BFUK.GetMUBetsResp Resp = BetfairUK.getMUBets(Req);
    
        CheckHeader(Resp.header);
    
        Program.ShowMsg("ErrorCode: " + Resp.errorCode.ToString());
    
        if (Resp.errorCode == BFUK.GetMUBetsErrorEnum.OK)
        {
    	for(int i = 0; i < Resp.bets.Length - 1; i++)
    	{
    	    Program.ShowMsg("BetID: " + Resp.bets[i].betId.ToString() + " - Status: " + Resp.bets[i].betStatus + " - Price: " + Resp.bets[i].price);
    	}                
           
        }
    
    }
    Can anyone see what I am doing wrong in terms of the getMUBets function?

    Also is there a testmode within the Betfair API so that I can simulate the placing of partially matched bets as I cannot think of any other
    way to simulate this situation to test for it correctly? How have other people solved this problem?

    Also am I right in the following assumptions regarding this scenario

    -I place a £100 back bet at 20/1
    -£50 is matched at that price creating 2 bets with the same ID. One part has the status of U the other M.
    -If the remaining £50 is matched later on does this become two separate bets with different Bet IDs? Or does it remain as one bet with one Bet ID
    but two parts each with a status of M?
    -Also do I get two transaction IDs for each part of the bet or is this shared as well
    -If both parts are successful and pay off does this become one settled bet or remain as multiple parts with the same Bet ID

    The main problem is that I need to know the best way of identifying individual bets and storing them in my database so that I can check
    a) the whole bet amount I wanted to place on a selection has been matched (one way or another)
    b) I can easily check whether the bet on the selection was successful once settled.

    When I check to see if the bet has paid out once it has been settled I am guessing that my first GetBetStatus function isn't good enough unless the individual matched parts are joined back up again to hold the total profit for a bet. Otherwise I would need to loop through all the sections using another method.

    Apart from this one problem my own bot is 99% ready so it is something I really need to get my head round.

    The bot is a console application and doesn't need to make async calls as the number of transactions it will make a day will be pretty minimal as its not a high frequency trader bot. Any good example code would be much appreciated.

    Thanks

    Leave a comment:


  • Monairda
    replied
    Handling async calls for multiple markets

    Hello everyone

    Mumbles long ago gave me a solution calls for multiple async Handling Markets

    http://forum.bdp.betfair.com/showthr...?t=112&page=33

    Now I would like to find another way to handling async calls for multiples markets without using a form for each market. It could be done using a tab for each market in one form? How?


    Any help, please?

    Leave a comment:


  • Mr.Anderson
    replied
    Application security

    Thank you Mumbles0 for a very nice tutorial! Easy to follow even for a novice like myself. But since I am a novice and Visual Studio does so much coding for us I really do not understand much of what is going on behind the scenes. Specifically is there anything to be concerned about from a security standpoint?
    Is it reasonably safe (as safe as it is to use a standard web browser) to use applications based on this test application to communicate with Betfair? For example is my username and password encrypted/sent over a secure channel from my computer to Betfair? One thing I know I would change is that I would not store my username and password locally in plain text. Would appreciate input on this matter from Mumbles0 or any other experienced programmer.

    Leave a comment:


  • iraklis35
    replied
    Example from my code

    Originally posted by iraklis35 View Post
    Can you give me an example of creating 'Build the array of bet lists'
    I get this error when set Betinfo class

    'ERROR Warning
    'Bets' is used before it has been assigned a value. A null reference exception could result at runtime. My purpose is to calculate profit and loss before assign any bet. In my bet tab before assign, i can have multiple bets for a lot of runners scenario. How can i do that.

    This is my code

    Public Class BetInfo 'A class for bet details

    Private mPrice As Decimal
    Private mAmount As Decimal
    Private mId As String
    Private mType As BFUK.BetTypeEnum
    Public Property type() As BFUK.BetTypeEnum
    Get
    Return mType
    End Get
    Set(ByVal value As BFUK.BetTypeEnum)
    mType = value

    End Set
    End Property
    Public Property price() As Decimal
    Get
    Return mPrice
    End Get
    Set(ByVal value As Decimal)
    mPrice = value

    End Set
    End Property
    Public Property amount() As Decimal 'Use + for back, - for lay
    Get
    Return mAmount
    End Get
    Set(ByVal value As Decimal)
    mAmount = value

    End Set
    End Property
    Public Property Id() As String 'Use + for back, - for lay
    Get
    Return mId
    End Get
    Set(ByVal value As String)
    mId = value

    End Set
    End Property


    'Other bet properties

    End Class


    Sub calc_profitAndLossBeforePlace()

    Dim Bets() As List(Of BetInfo)

    Dim IfWin() As Decimal

    Dim i, j, k, m As Integer

    Dim d As New BetInfo
    'Build the array of bet lists


    Dim Req As New BFUK.GetMUBetsReq
    Dim Resp As New BFUK.GetMUBetsResp
    With Req
    .header = oHeaderUK() 'The standard header
    .marketId = Val(txt_marketid.Text) 'The market of interest
    .betStatus = BFUK.BetStatusEnum.MU 'Return status of matched and unmatched bets
    .recordCount = 100 'Max 100 bets
    End With

    Resp = BetFairUK.getMUBets(Req)
    k = 0

    'Fill Bets() with the Matched Bets

    Try
    With Resp
    CheckHeader(.header)
    'Print("ErrorCode = " & .errorCode.ToString)
    If .errorCode = BFUK.GetMUBetsErrorEnum.OK Then

    'ctr.lbl_selection_name.Text
    'ctr.lbl_profit.Text
    'MsgBox(.bets(k).selectionId.ToString)
    '.bets(k).selectionId
    For i = 0 To .bets.Length - 1 'For all bets on the market
    With .bets(i)
    d.Id = .selectionId.ToString
    If .betStatus = BFUK.BetStatusEnum.M Then
    If .betType = BFUK.BetTypeEnum.B Then
    d.price = .price
    d.amount = .size
    Else
    d.price = .price
    d.amount = -.size
    End If
    End If

    End With

    Next
    Bets(i).Add(d)

    'ERROR Warning
    'Bets' is used before it has been assigned a value. A null reference exception could result at runtime. C:\betfair\BetApis\BetApis\MainForm.vb 4240 21 BetApis

    End If

    End With


    Catch ex As Exception
    Print(ex.Message)
    End Try

    'FIll the BETS() from going to bet Panel
    For Each ctr As AddBet In Panel_bet_tab1.Controls

    If ctr.GroupBox1.Text = "ΥΠΕΡ" Then
    d.price = ctr.Nud_apodosi.Value
    d.amount = ctr.nud_axia.Value
    d.Id = ctr.lbl_selectioname.Tag
    Else
    d.price = ctr.Nud_apodosi.Value
    d.amount = -ctr.nud_axia.Value
    d.Id = ctr.lbl_selectioname.Tag
    End If
    Bets(i).Add(d)
    i += 1

    Next


    For i = 0 To Bets.Count - 1
    MsgBox(Bets(i).ToString)
    Next

    m = Bets.Count - 1 'The number of runners - 1
    ReDim IfWin(m) 'An array to hold the profit(or loss) values for each runner



    For i = 0 To m 'For each runner
    For j = 0 To m 'Look at all runners
    For k = 0 To Bets(j).Count - 1 'For each bet on this runner
    With Bets(j)(k)
    MsgBox("Bets(" + j.ToString + ")(" + k.ToString + ") Id:" + .Id.ToString + " Apodosi:" + .price.ToString + " Poso:" + .amount.ToString)
    If j = i Then 'Runner is winner
    IfWin(i) += .amount * (.price - 1) 'Accumulate totals
    Else 'Other runners
    IfWin(i) += -.amount
    End If
    End With
    Next
    Next
    Next
    End Sub
    Last edited by iraklis35; 07-10-2010, 10:27 AM. Reason: Purpose of my code

    Leave a comment:


  • Mumbles0
    replied
    Krandall,

    From the getAllMarkets call you obtain the marketId for the market you are interested in. With this marketId you can call getMarket to get the runners and their selectionIds, then call getMarketPricesCompressed to get back and lay prices. See Step 12 and Step 14.

    Leave a comment:


  • Krandall
    replied
    Get Lay &amp; Back Prices with Section Name

    Hi,

    I am using betfair api, I read market data with getAllMarket function which returns whole market data per sport as I select (Calico - 1) for Soccer and using UnpackMarket , Now I want to read Lay & Back Prices with Secion for each market.

    Please help me out. How to do it.

    Many Thanks

    Leave a comment:


  • Mumbles0
    replied
    Reply to iraklis35 (re: Bet Lists)

    Building an array of bet lists is very application-specific and I can’t post a simple example for the case where many bets are placed on a single market. Perhaps the profit/loss example I’ve shown oversimplifies the situation.

    You could hold runner data in a class (or some other data structure, even a DataGridView), which included the Bets list, for example:

    Code:
    Class RunnerData
      Property RunnerName As String
      Property SelectonId As Integer
      'other properties (prices, etc.)
      Property Bets() As List(Of BetInfo)  'The bet list 
    End Class
    For the market you would set up an array of RunnerData after calling getMarket.

    You call getMUBets to monitor your bets. You then consider each bet in turn, building the bet lists for each runner as you go. Do something like this:

    For each bet in the .bets array returned by getMUbets:

    1. Determine the index in the element in the array of RunnerData matching the selectionId.

    2. Add a new bet object containing the bet price and amount to the Bets list for this runner using the .add method

    This is a simple view of what is required. You might want code to select matched and/or unmatched bets. Also you may want to somehow include a proposed bet to provide a “what if you placed this new bet” scenario. This would have to link into you bet placement UI.

    Leave a comment:


  • Mumbles0
    replied
    Form1_KeyDown

    granted,

    In Step 29 we put the buttons on a new instance of the MarketForm form.

    Sounds like you need to become more familiar with the IDE. In the Solution Explorer select "Form1.vb", then click the "View Designer" icon to show the "Form1.vb [Design]" tab. Look for the "Properties" window. If it's not there, open the "View" menu and select "Properies Window". Now if you click on Form1, its properties will appear in this window. What more can I say?

    Alternatively, you can set the KeyPreview property at run time. A good place to do this in the Form1_Load event. This event fires the first time the form is shown.

    Code:
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      Me.KeyPreview = True
    End Sub
    
    Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
      If e.KeyCode = Keys.Z Then
        Me.RadioButton1.Checked = True
        Me.RadioButton2.Checked = False
      Else
        Me.RadioButton1.Checked = False
        Me.RadioButton2.Checked = True
      End If
    End Sub

    Leave a comment:


  • iraklis35
    replied
    Originally posted by Mumbles0 View Post
    The values shown near each runner name are the profit & loss values. These are the amount you would win (or lose) if that particular runner were to win the event.

    The API call getMarketProfitAndLoss returns a set of values, but it only takes into account your matched bets. The website shows the IfWin values for proposed (unsubmitted) bets. Neither of these sets are particularly useful if you want to assess your current situation if you have several bets (matched, unmatched and proposed) on a market, so it’s probably best to calculate your own values. At least that way you know what you're getting.

    For each runner:
    IfWin = Total profits from back bets on this runner - Total losses from lay bets on this runner
    - Total amount of back bets on other runners + Total amount of lay bets on other runners
    Here is an idea to calculate the IfWin values:

    Define a class (say, BetInfo) to hold details of each bet on the market:

    Code:
    Class BetInfo   'A class for bet details
      Property price As Decimal
      Property amount As Decimal  'Use + for back, - for lay
      
      'Other bet properties
      
      End Class
    Use this class for both back and lay bets, but use +ve amounts for Back, and -ve amounts for Lay. This will simplify the calculations. For example:

    Bet1.amount = 5 for a Back bet
    Bet1.amount = -5 for a Lay bet
    When you place a bet add an instance of this class to a separate bet List for each runner to model the bets on the market. Hold the Lists for all the runners in an array (say, Bets()).

    An algorithm the calculate the IfWin values for each runner is this:

    Code:
    Dim Bets() As List(Of BetInfo), IfWin() As Decimal, i, j, k, m As Integer
    
      'Build the array of bet lists
      '.....
      
      m = Bets.Count - 1   'The number of runners - 1
      ReDim IfWin(m)       'An array to hold the profit(or loss) values for each runner
      
      For i = 0 To m   'For each runner
        For j = 0 To m    'Look at all runners
          For k = 0 To Bets(j).Count - 1  'For each bet on this runner
            With Bets(j)(k)
              If j = i Then 'Runner is winner
                IfWin(i) += .amount * (.price - 1)  'Accumulate totals
              Else  'Other runners
                IfWin(i) += -.amount
              End If
            End With
          Next
        Next
      Next
    It’s up to you what bets are added to the bet lists - matched, unmatched or proposed. Bear in mind that unmatched bets may not, of course, be matched at the desired price.

    Can you give me an example of creating 'Build the array of bet lists'

    Leave a comment:

Working...
X