G-Factor,
Thanks for your post.
Settings
You suggestion to use the in-built Settings facility is good. I might post a step taking a closer look at this.
Response time variations
I too have noticed this. The first API call made after a project starts running take a lot longer than subsequent calls. I timed some calls made to getMarket with a VB program. The first call took 1.7 sec, while subsequent calls made every 30 sec thereafter took only 0.4 sec. If I ceased calling for a few minutes, the next call took longer (1.1 sec). I’m calling the UK exchange from Australia with a fairly modest line speed, using Windows XP.
I also called getMarket using SoapUI (which a Java app). The Same effect was noticed (although the times were a bit different).
I'm fairly sure this phenomenon is caused by the secure (SSL) behavior of the transmission. Using Wireshark I observed the packet sequence. On the initial call there was a lot of handshaking going on (exchanging certificates, etc.), whereas the subsequent transmissions were a lot briefer. This accounted for the time difference.
Your times of “5 - 10 seconds” seem a bit excessive. Is this for all API calls? What does it reduce to? Have you enabled gzip? There are other tweaks that can be done. I suggest you take a closer look at your interactions using a network analyser such as Wireshark.
Text styles in DataGridView
Unlike Excel and HTML, you cannot have different text styles within a single cell of a DataGridView, although the cells can have individual text styles.
But .... having said this I think there is a way it can be done using graphics. I will investigate this.
Using VB2008 to acccess the Betfair API: A tutorial
Collapse
This topic is closed.
X
X
-
Inspired!
Over the last few days I've worked my way through the whole thread.
Firstly, all credit to you Mumbles0 for sparing your time and knowledge.
I've made some crude apps with self-taught vb.net, but nothing very complicated.
My progs normally manage to do what I want them to, but after reading this thread I realise (already suspected) that my code is very untidy! I plan to re-look at them and try to make them more efficient, and easier to read, if I can.
You've said before that there can be many ways to do things in vb.net and I'd just like to suggest an alternative that I use to saving settings in a separate file.
I use the settings built in to each project.
For those that don't know, if you double-click "My Project" in the solution explorer a new 'tab' will open with lots of complicated settings that I wouldn't go near, but one of the options on the left hand side is Settings.
If you click on that it will give you a list of settings currently being used. There should be your web references there as application settings, but you can add your own.
Just choose a name, a type, and a value if required.
These settings can then be accessed in your program using My.Settings. and will be available to you each time you run it.
***********************
I was hoping to find answers to a couple of things that have been bugging (no pun intended) me for a while now, and haven't, so I hope you won't mind me asking them.
Whenever I start my app, the first call to the API always takes way longer than any subsequent calls, typically 5-10 seconds! I know it's not just the Login call, as I've started my prog already logged in and a GetEvents call took just as long.
It's only the first call though, weird!
Has anyone got any ideas as to why this might be?
Secondly, I've been trying to get my display to look a little easier to read.
I display runners and prices in a datagridview, and would like to show price & amount available but with the price in bold text (as the website does).
I've managed to concatenate the price and amount together and to display one above the other, but can't change from bold to not in the middle of it. I've tried tags and ascii characters but that's the limit of my ideas and I can't find anything by Googling.
Any ideas? Is it even possible? It seems daft that I can do it in Excel and not .NET
Thanks in advance for anyone who might be able to help.
Leave a comment:
-
Reply to gvigliani (re: getCompleteMarketPricesCompressed)
The two API “Prices” calls return runner prices differently. getMarketPricesCompressed returns two arrays for each runner in the unpacked response object:
oMarketPrices.runnerPrices(i).bestPricesToBack()containing the best (up to) 3 prices available to back for runner i, and:
oMarketPrices.runnerPrices(i).bestPricesToLay()containing the best (up to) 3 prices available to lay for the same runner. I see that you have succeeded in “digging out” these arrays.
But getCompleteMarketPricesCompressed returns all prices (both back and lay) in a single array for each runner:
oMarketPrices.runnerInfo(i).prices()If I modify the code of Step 10 a bit so that it now “prints” the .prices array:
we can see what's in the .prices array for a typical runner:Code:[COLOR="Gray"] ...... Dim oMarketPrices As New UnpackCompleteMarketPricesCompressed(.completeMarketPrices) With oMarketPrices Print(.marketId & " " & .runnerInfo.Length & " runners") 'Process returned market prices here. For i = 0 To .runnerInfo.Length - 1 With .runnerInfo(i) [COLOR="Black"] Print("Selection = " & .selectionId & vbCrLf & "price backAmount layAmount") For j = 0 To .prices.Length - 1 With .prices(j) Print(.price & " " & .backAmount & " " & .layAmount) End With Next[/COLOR] End With Next End With .....[/COLOR]
From this you can see that the 3 best back prices are 2.28, 2.26 & 2.16. Also the 3 best lay prices are 2.4, 2.54 & 2.6.Code:Selection = 201255 price backAmount layAmount 1.01 64.14 0 1.74 47.03 0 1.99 4.88 0 2.02 0.14 0 2.06 30.16 0 2.08 66.12 0 2.1 15.26 0 2.16 112.52 0 2.26 113.64 0 2.28 90.59 0 2.4 0 144.3 2.54 0 125.72 2.6 0 0.11 2.72 0 17.4 1000 0 4.17
There are usually many prices for each runner. You may have a problem trying to fit them all on your UI form. You may need to write additional code to extract only the prices and amounts that interest you.
Leave a comment:
-
Arrays in request objects
granted,
First read my tutorial post regarding arrays here. This, I hope, will give you a better understanding of arrays.
If you look at the Sports API Guide for any API call you will see, under the heading Input, details of the request parameters that must be assigned. With VB2008/2010 these parameters are the properties of the request object. For each parameter a type is given. You must use either a value of the given type, or a value that VB can convert to the given type.
For example, for getSilksV2 the markets request parameter has type ArrayOfInt (i.e. array of type integer). Using an array lets you request data for several markets in one call. If you only want one market then you must use an integer array with a length of one, with its’ single element containing the (integer) marketId. You can do it like this:
Because the .markets property of oGetSilksV2Req is, in fact, an array of integer we can create a suitable array by ReDiming this to 0 (0 being the upper bound of the array). Because array elements are numbered from 0, this creates an array with one element. This single element is referred to as .markets(0), to which we assign the marketId.Code:Dim oGetSilksV2Req As New BFAU.GetSilksV2Req With oGetSilksV2Req .header = oHeaderAU() ReDim .markets(0) .markets(0) = marketidt.Text End With
(Note that getSilksV2 is not available on the free API.)
Your query about buttons and labels is a more advanced topic. I will look at this in a separate post.
Leave a comment:
-
Get Silks V2 (exchange) - GetSilksV2Req is of type ArrayOfInt
the GetSilksV2Req 'markets' parameter is of type ArrayOfInt.
But i just want to put in one market id...the one im currently looking at
i tried
With oGetSilksV2Req
.header = oHeaderAU()
.markets = marketid.text
but it says: value of type integer cannot be converted to a 1-dimensional array of integer
what does it want me to put there?
------------------------------------------------
also, when we print the runners, they appear as follows for example:
4290762 1. Sharufa
3286065 2. Spend The Money
4914968 3. Amberman
4914969 4. Ieramugadu
4183913 5. Last To Leave
2127783 6. Intercode
4914970 7. Charming Manners
3661066 8. Enhanced Design
2016704 9. Circus Pony
4914971 10. Gangway
how can i put each runners name into a vb 'label' and assign the runner id to a 'button'
i know how to do it for the event name...because there's only one name...but here, there is an array
can you help please...as even more confusing is on the GetMarketResp, the parameter runners is of type ArrayOfRunners
thanksLast edited by granted; 14-08-2010, 05:34 AM.
Leave a comment:
-
Reply to granted (getMarket code)
granted,
You learn by your mistakes.
Code:Private Sub bLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bLoad.Click Print("*** MarketRunners ***") '[COLOR="Red"]<<< Note 1[/COLOR] Dim oGetMarketReq As New BFAU.GetMarketReq 'Create the request object Dim oGetMarketResp As BFAU.GetMarketResp '[COLOR="Red"]<<< Note 2[/COLOR] With oGetMarketReq .header = oHeaderAU() 'Load request parameters .marketId = marketidt '[COLOR="Red"]<<< Note 3[/COLOR] End With With BetFairAU.getMarket(oGetMarketReq) 'Call the API CheckHeader(.header) Print("ErrorCode = " & .errorCode.ToString) If .errorCode = BFAU.GetMarketErrorEnum.OK Then Dim Markets As New UnpackAllMarkets(.market) '[COLOR="Red"]<<< Note 4[/COLOR] With Markets For i = 0 To .market.Length - 1 '[COLOR="Red"]<<< Note 5[/COLOR] Next Print(.runners) End With End If End With End Sub- If you are having a problem with this my guess that the Print sub of Step 1 is missing. Ensure that this sub (and its associated textbox tLog) is included somewhere in your project.
- The compiler is telling you that oGetMarketResp is unused because you’re not using it.
- The .marketId property of the request object can only hold an integer. marketidt is the textbox object, not what’s in it. You cannot assign this object to an integer, hence the error. What’s in the textbox is given by the .Text property. So try:
.marketId = marketidt.Text - You will be getting an error here. UnpackAllMarkets is a class to convert the data string returned by the API call getAllMarkets. It won’t work here because you are calling getMarket which returns an object which does not require unpacking. This statement is not right, so removed it. But when you do you will get more errors ...

- This For..Next loop contains no statements - it is useless. This suggests that you need to understand more about programming. There are many VB tutorials on the Internet, for example here.
We covered what you are trying to do here in Step 12. Try to understand how we printed the list of runners in this step.
Leave a comment:
- If you are having a problem with this my guess that the Print sub of Step 1 is missing. Ensure that this sub (and its associated textbox tLog) is included somewhere in your project.
-
Dear Mumbles0,Originally posted by Mumbles0 View Postgvigliani,
If you need more than 3 best prices (for a price ladder), call getCompleteMarketPricesCompressed. This returns all prices for each runner. See step 10.
Working with multiple markets is more complicated, particularly if you are using async calls. When you receive a response you have to determine which market it is for. This is OK if you call getMarket or getMarketPricesCompressed because the marketId is returned in the response. This lets you update the correct group of controls for each market.
I have tried in every way but I can not find a way to access different shares to be included in a Ladder:
My code is:
Can you give me a help to better understand?Code:Private Sub BetFairUK_getCompleteMarketPricesCompressedCompleted(ByVal sender As Object, ByVal e As BFUK.getCompleteMarketPricesCompressedCompletedEventArgs) Handles BetFairUK.getCompleteMarketPricesCompressedCompleted Dim RaceStart As Date = Nothing 'The time when the race turns in-play Dim RaceStarted As Boolean = Nothing 'A flag, set True when the race has started Try If Not e.Cancelled Then With e.Result CheckHeader(.header) PrintRes("ErrorCode = " & .errorCode.ToString) If .errorCode = BFUK.GetCompleteMarketPricesErrorEnum.OK Then Dim oMarketPrices As New UnpackCompleteMarketPricesCompressed(.completeMarketPrices) With oMarketPrices t_run.Text = .runnerInfo.Length If .delay > 0 Then 'Race is in-play Mark_status.BackColor = Color.Green Mark_status.Text = "Market In Play" If RaceStarted Then manca.Text = Now.Subtract(RaceStart).ToString.Substring(0, 8) 'Update the time label Else 'Initialize the variables RaceStart = Now 'Save the race start time RaceStarted = True 'Set the flag End If Else Mark_status.BackColor = System.Drawing.Color.FromArgb(CType(CType(47, Byte), Integer), CType(CType(70, Byte), Integer), CType(CType(232, Byte), Integer)) End If End With End If End With End If Catch ex As ApplicationException PrintRes(e.Error.Message) End Try End Sub
Thank you so much!
gvigliani
Leave a comment:
-
load market runner error in my code
i have a text box called marketidt and a button called Load, so i was hoping to code a load runners PRINT like we did before with events, login etc
and here is the code i tried:
Private Sub bLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bLoad.Click
Print("*** MarketRunners ***")
Dim oGetMarketReq As New BFAU.GetMarketReq 'Create the request object
Dim oGetMarketResp As BFAU.GetMarketResp 'Create a variable for the response object
With oGetMarketReq
.header = oHeaderAU() 'Load request parameters
.marketId = marketidt
End With
With BetFairAU.getMarket(oGetMarketReq) 'Call the API
CheckHeader(.header)
Print("ErrorCode = " & .errorCode.ToString)
If .errorCode = BFAU.GetMarketErrorEnum.OK Then
Dim Markets As New UnpackAllMarkets(.market) 'Unpack .market
With Markets
For i = 0 To .market.Length - 1
Next
Print(.runners)
End With
End If
End With
End Sub
the error i get is that the marketidt text box cannot be converted to an integer and the other error i get is with Print("*** MarketRunners ***")
it also told me that oGetMarketResp variable was not being used
any help would be appreciated
thanksLast edited by granted; 11-08-2010, 03:17 PM.
Leave a comment:
-
Price ladder & multi markets
gviglinani,
If you need more than 3 best prices (for a price ladder), call getCompleteMarketPricesCompressed. This returns all prices for each runner. See step 10.
Working with multiple markets is more complicated, particularly if you are using async calls. When you receive a response you have to determine which market it is for. This is OK if you call getMarket or getMarketPricesCompressed because the marketId is returned in the response. This lets you update the correct group of controls for each market.
Leave a comment:
-
Results
WStecher,
I don't think you can get results of matches via the API. You may have to resort to "scraping" web pages from sports websites.
Has anyone got any suggestions?
You could perhaps ask the question in the "General Sports Programming" section of the Forum.
Leave a comment:
-
Event time sorting
granted,
There are many ways of achieving this. WStecher has outlined a way of loading the market data into a DataGridView control, then sorting the EventDate column. A more direct way would be to use a comparer class similar to what was done in Step 17.
Then add a line to perform the sort using an instance of this class:Code:Class CompareMarketTimes Implements IComparer(Of MarketDataType) Public Function Compare(ByVal x As Unpack.MarketDataType, ByVal y As Unpack.MarketDataType) As Integer Implements System.Collections.Generic.IComparer(Of Unpack.MarketDataType).Compare Return Date.Compare(x.eventDate, y.eventDate) End Function End Class
This sorts the .marketData array according to the .eventDate property.Code:[COLOR="Gray"] ....... Dim AllMarkets As New UnpackAllMarkets(.marketData) 'Unpack .marketData With AllMarkets [COLOR="Black"]Array.Sort(.marketData, New CompareMarketTimes)[/COLOR] For i = 0 To .marketData.Length - 1 With .marketData(i) ..........[/COLOR]
Leave a comment:
-
@granted: how would i add sorting by times to this sub?
Hey granted,
I think you have to put the data in a datatable and create a dataview on it.
The dataview can be sorted. This will bring the data in a sorted tableview to you. If you don't want to have a DataGridView on your form, you can set visible = false to the datagridview.
Just one idea. I would do it like this:
First place a datagridview to your form and name it "DataGrid1"
Add the following code to your class (not the sub):
Add the following code to your "bInPlay_Click_1" SubCode:Private dtInPlay As New DataTable("InPlay") With dtInPlay.Columns .Add("EventDate", GetType(System.DateTime)) .Add("MarketID", GetType(System.String)) .Add("Match", GetType(System.String)) .Add("MarketName", GetType(System.String)) End With DataGrid1.DataSource = dtInPlay
Replace the code fromCode:Dim matchdata(4) As Object
- With AllMarkets
to
- End With
in your "bInPlay_Click_1" Sub with the following code:
Code:With AllMarkets For i = 0 To .marketData.Length - 1 With .marketData(i) If .turningInPlay Then matchdata(0) = .eventDate.ToLocalTime matchdata(1) = .marketID matchdata(2) = .menuPath matchdata(3) = .marketName dtInPlay.Rows.Add(matchdata) End If End With Next DataGrid1.Sort(DataGrid1.Columns(0), System.ComponentModel.ListSortDirection.Ascending) End With 'the data will be displayed sorted by EventDate in the DataGridView 'if you want to print it with the function "print()", add the following code: For Each DataGridRow As DataRow In DataGrid1.Rows Print(DataGridRow.Item(0).ToString & " " & DataGridRow.Item(1).ToString & " " & DataGridRow.Item(2).ToString & "\" & DataGridRow.Item(3).ToString) Next
Leave a comment:
-
how would i add sorting by times to this sub?
Private Sub bInPlay_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bInPlay.Click
Print("*** InPlay Markets ***")
Dim oMarketsReq As New BFAU.GetAllMarketsReq
With oMarketsReq
.header = oHeaderAU()
.fromDate = Now
.toDate = Now.AddDays(1) 'Specifies next 24 hour period
End With
With BetFairAU.getAllMarkets(oMarketsReq) 'Call the AU API
CheckHeader(.header)
Print("ErrorCode = " & .errorCode.ToString)
If .errorCode = BFAU.GetAllMarketsErrorEnum.OK Then
Dim AllMarkets As New UnpackAllMarkets(.marketData) 'Unpack .marketData
With AllMarkets
For i = 0 To .marketData.Length - 1
With .marketData(i)
If .turningInPlay Then 'This market will become InPlay
Print(.eventDate.ToLocalTime.TimeOfDay.ToString & " " & .marketId & " " & .menuPath & "\" & .marketName)
End If
End With
Next
End With
End If
End With
End Sub
i want the printed list to be sorted by earliest to latest...but cant figure it out
thanks
christian
Leave a comment:
-
Get results of all matches?
Hello,
first at all I want to say THANKS to this gread Thread. It helped me very much building my own Betfair software. At the end I still have one question:
Is there any possibility in the betfair API to get the results (I only want to know which team or player has won) of all matches in a market?
With getAccountStatement() I can get the results for each match I have placed a bet. But I also want to know the winning player/team for the matches I don't have placed a bet. So I can build up a history of what I could have had won if I would have placed a bet.
Thanks for your ideas.
Leave a comment:
-
Look my code.Originally posted by waldjunge View PostI have tried to write code for betting less then the minimum stake for Lay betting, according to this guideline.
'Documentation will not help you with this issue. Trick is to do it in few steps.
'If you want, for example, to place £0.1 bet then place regular £2 bet on highest quote (1000 if you want to back)
'or lowest quote (1.01 if you want to lay). The bet will not be matched.
'Change its amount to 2.1£ and as result you will have two bets: one with £2 and the other with £0.1 amount.
'Cancel first one, change £0.1 bet quote on the desired value and that's it
But I can not really update the bet to get a new betID and a new st
Best Regards
Leave a comment:


Leave a comment: