Using Excel VB Sample Code Sheet

Collapse
X
 
  • Time
  • Show
Clear All
new posts

  • jabe
    replied
    NewtonSoftJson and the JavaScriptSerializer both allow a JSON string to be converted to an object (or back) to save us all the problems of writing code to parse the JSON strings returned by Betfair.

    (Warning: totally inadequate definition follows!) An object is a data item. It can contain data items. It can contain methods to do things, often with data. Some of the .NET languages are not as strict about objects as other languages. The contained data items might be properties (this is where .NET gets a bit lax about things).

    Objects are defined using classes.

    This is an examples of a class used in the API:

    Code:
    [CODE]Public Class ClassCountryCodeResult
        Public countryCode As String    ' ISO-2 code for the country
        Public marketCount As Integer   ' No of related markets 
    End Class
    [/CODE]

    As you can see, it has two data items - countryCode and marketCount. The .NET languages allow you to directly read the countryCode and marketCount when they are defined as Public. (I say that; VB certainly does. C# might be more strict).

    If I do a listCountryCode API call, I'll get lots of CountryCodes back, so the object for receiving all this data might look like this:

    Code:
    Public Class ClassListCountryResult
        Public jsonrpc As String
        Public result() As ClassCountryCodeResult
    End Class
    As you can see, it contains an array called result().

    When I do a listCountryCode, I'll get a string back. It looks like this, but there's much more; I've put line breaks after the commas (etc) to aid readability:

    {"jsonrpc":"2.0",
    "result":[
    {"countryCode":"GB","marketCount":2874},
    {"countryCode":"PL","marketCount":138},
    {"countryCode":"UA","marketCount":251},
    {"countryCode":"CH","marketCount":821},
    {"countryCode":"IE","marketCount":28},
    {"countryCode":"SE","marketCount":370}
    ],
    "id":1}

    This is a relatively simple example. I have a value for "jsonrpc" and half a dozen ClassCountryCodeResult objects in an array.

    Now then, the way NewtonSoftJson works is that in a SINGLE statement it can take all the data from the string and put it into a object defined as ClassListCountryResult.

    Rather like this:

    If I call the string above inString, then

    Code:
    Dim countries = Newtonsoft.Json.JsonConvert.DeserializeObject(Of ClassListCountryResult)(inString)
    This parses the string for you and puts all the data into the countries so you can directly access data items such as

    countries.result(0).countryCode
    countries.result(0).marketCount

    and even if you want to

    countries.jsonrpc

    though I don't know why you'd want to.

    Etc.

    You might wonder what happened to the "id" parameter from the JSON string. There was nowhere for it to go, so it got ignored. Easy.

    You might need to be more specific and say
    Dim countries as ClassListCountryResult (etc)
    but VB.NET does a good job assuming you want it that way via the class mentioned in the DeserializeObject statement.


    Going from an object to a string is serializing and looks like this:

    Code:
    Dim aString = Newtonsoft.Json.JsonConvert.SerializeObject(anObject)
    The NewtonSoftJson is a third-party add-in. in Visual Studio it's installed via menu items Project / Manage NuGet Packages. I don't know how Excel would do it.

    So, basically you can convert between strings and objects without writing masses of code to do it.

    If you can't find out how to get the NewtonSoft stuff in Excel, you could investigate the JavaScriptSerializer, which does much the same (but with slightly different code). If neither work out, let me know.

    Leave a comment:


  • judgement
    replied
    thanks for the explanation and offer it sounds as if this maybe useful if betting on lots of sports and events but as i am still taking baby steps i don't think i need it now but i'll know where to go to thanks!

    my thoughts are now turning to extracting data from strings that are returned. i was thinking i would have to search for specific strings of characters in the string and use VBA to chop the relevant bits out or something like that but when i was searching around to see if i could find anything i could use i found this:

    http://www.mrexcel.com/forum/excel-q...lications.html

    which looks as if it does what is needed. is this the way to go?

    what is NewtonSoftJson? what does that do? sorry so many questions

    Leave a comment:


  • jabe
    replied
    The navigation file contains the data with all the headings that appear in the left column when you use the Exchange site.

    It starts a list of sports (etc), and allows you to select sub-categorisations. The navigation file (or menu.json as it's actually called) can be downloaded by an API call.

    I eventually got my code (which is VB and you can have it if you want) to return a string correctly, but my conversion from the string to objects hasn't worked. Initially the returned string was too big for the JavaScriptSerializer, but fixing that didn't help, nor did my attempts to use the NewtonSoftJson converter. My classes might be inadequate. You're welcome to the code I used. At some point I intend to return to it and post my findings, along with some working code, but it's not my priority.

    The menu/navigation file is described here:
    http://docs.developer.betfair.com/do...r+Applications

    The endpoint is this:
    https://api.betfair.com/exchange/bet...tion/menu.json

    Leave a comment:


  • judgement
    replied
    Originally posted by jabe View Post
    If you're interested in just Premier League games, you could potentially drill down the navigation file to find the relevant EventIds. I haven't made this work yet. The amount of data returned is around 3-6MB - not quick to download, as you might guess. My attempts so far to convert the returned string into objects have all failed. Fortunately I don't currently need it.
    out of interest what is the navigation file? i haven't come across that yet. my calls returned text strings so nowhere this amount of data or the weighting limits i'd guess.

    Leave a comment:


  • judgement
    replied
    Originally posted by jabe View Post
    After that you'd get the marketCatalogues for each game or all the games you're interested in. You'd specify all the EventIds for the games of interest, or do them one at a time. Then you'd need the relevant marketBooks.
    Originally posted by jabe View Post
    The MarketCatalogue does include competitionCode, so perhaps you could narrow things down later with that.
    Originally posted by jabe View Post
    When it comes to listMarketBook, you can pass a string of several marketIds to it.
    Originally posted by jabe View Post
    It might be possible to make listMarketCatalogue calls specifically for Premier League games without troubling the weighting limits. I guess that would depend on how far in advance such games are added to Betfair.
    just as you said

    Leave a comment:


  • judgement
    replied
    think i managed to do what i wanted more by luck than judgement.

    the code below is the GetListMarketCatalogueRequestString function of the sample spreadsheet edited to include competitionId 31 which is the Premier league and to find 30 results which returns listMarketCatalogue info for the next 30 Premier league matches.

    Code:
    "{""filter"":{""eventTypeIds"":[""" & EventTypeId & """],""competitionIds"":[""" & 31 & """],""marketCountries"":[""GB""],""marketTypeCodes"":[""MATCH_ODDS""]},""marketStartTime"":{""from"":""" & dateNow & """},""sort"":""FIRST_TO_START"",""maxResults"":""30"",""marketProjection"":[""RUNNER_DESCRIPTION""]}"
    and the code below is the GetListMarketBookRequestString function edited to find listMarketBook info for 2 of the matches returned by the listMarketCatalogue call:

    Code:
    "{""marketIds"":[""" & 1.127850691 & """,""" & 1.127850355 & """],""priceProjection"":{""priceData"":[""EX_BEST_OFFERS""]}}"

    Leave a comment:


  • judgement
    replied
    many thanks for the reply i thought it would be possible and this gives me a good idea of how to go about it thanks so i'll try and give it a go.

    Leave a comment:


  • jabe
    replied
    It is possible to do calls to get data for several games. The data is hierarchical in nature, so you might start at the Event level (perhaps specifying the Event type for football along with a date). After that you'd get the marketCatalogues for each game or all the games you're interested in. You'd specify all the EventIds for the games of interest, or do them one at a time. Then you'd need the relevant marketBooks.

    If you're interested in just Premier League games, you could potentially drill down the navigation file to find the relevant EventIds. I haven't made this work yet. The amount of data returned is around 3-6MB - not quick to download, as you might guess. My attempts so far to convert the returned string into objects have all failed. Fortunately I don't currently need it.

    For the listEvents call, countryCode can be specified to reduce the number of Events returned. The marketFilter mentions competitionCode, but competitionCode isn't in the Event class, and I don't know if you could specify it in a listEvent call. I'd guess not. The MarketCatalogue does include competitionCode, so perhaps you could narrow things down later with that.

    You might want to make a few calls, during when your program starts, such as listCountries, list Competitions, etc. Be aware that the countryCode may not always exist or be valid, so you might need to fill in gaps.

    When it comes to listMarketBook, you can pass a string of several marketIds to it.

    If you do intend to make calls for multiple matches of markets, you do need to be aware that there are weighting limits for certain calls, as listed in this link:
    http://docs.developer.betfair.com/do...Request+Limits

    It might be possible to make listMarketCatalogue calls specifically for Premier League games without troubling the weighting limits. I guess that would depend on how far in advance such games are added to Betfair.
    Last edited by jabe; 23-10-2016, 06:12 PM.

    Leave a comment:


  • judgement
    replied
    Originally posted by judgement View Post
    response to listCurrentOrders call:

    {"jsonrpc":"2.0","result":{"currentOrders":[{"betId":"77337570265","marketId":"1.127508662","s electionId":55190,"handicap":0.0,"priceSize":{"pri ce":2.26,"size":2.0},"bspLiability":0.0,"side":"BA CK","status":"EXECUTABLE","persistenceType":"LAPSE ","orderType":"LIMIT","placedDate":"2016-10-19T18:42:42.000Z","averagePriceMatched":0.0,"sizeM atched":0.0,"sizeRemaining":2.0,"sizeLapsed":0.0," sizeCancelled":0.0,"sizeVoided":0.0,"regulatorCode ":"GIBRALTAR REGULATOR"}],"moreAvailable":false},"id":1}
    the calls to and responses from Betfair i have done so far have been for 1 football match each. is it possible to get information from Betfair for more than 1 match at a time eg all Premier league matches, all GB matches or even all football matches or do you have to make separate calls for each match?

    Leave a comment:


  • judgement
    replied
    Originally posted by judgement View Post
    got my first listMarketBook call to Betfair incorporated in the Sample spreadsheet.

    added these 3 lines in the Example module:

    Request = MakeJsonRpcRequestString(ListTradedVolumeMethod, GetTradedVolumeRequestString())
    Dim ListTradedVolumeResponse As String: ListTradedVolumeResponse = SendRequest(GetJsonRpcUrl(), GetAppKey(), GetSession(), Request)
    Sheet1.Cells(OutputRow + 1, OutputColumn).value = ListTradedVolumeResponse


    declared this variable in the Util module for the ListTradedVolumeMethod input:

    Public Const ListTradedVolumeMethod As String = "listMarketBook"

    added this function in the Util module for the GetTradedVolumeRequestString() input:

    Function GetTradedVolumeRequestString() As String
    GetTradedVolumeRequestString = "{""marketIds"":[""" & MarketId & """],""priceProjection"":{""priceData"":[""EX_BEST_OFFERS"",""EX_TRADED""],""exBestOffersOverrides"":{""bestPricesDepth"":1} }}"
    End Function
    listCurrentOrders added in the same way..

    added to Example module:

    Request = MakeJsonRpcRequestString(listCurrentOrdersMethod, GetlistCurrentOrdersRequestString())
    Dim listCurrentOrdersResponse As String: listCurrentOrdersResponse = SendRequest(GetJsonRpcUrl(), GetAppKey(), GetSession(), Request)
    Sheet1.Cells(OutputRow + 1, OutputColumn).value = listCurrentOrdersResponse


    declared in the Util module:

    Public Const listCurrentOrdersMethod As String = "listCurrentOrders"

    added in Util module:

    Function GetlistCurrentOrdersRequestString() As String
    GetlistCurrentOrdersRequestString = "{""marketIds"":[""" & MarketId & """],""fromRecord"":0,""recordCount"":0}"
    End Function


    lifted from

    Originally posted by betdynamics View Post
    JSON request for listCurrentOrders:

    Code:
    {"jsonrpc":"2.0","method":"SportsAPING/v1.0/listCurrentOrders","params":{"marketIds":["1.116451712"],"fromRecord":0,"recordCount":0},"id":1}
    thanks betdynamics

    £2 unmatched bet placed on the relevant match.
    response to listCurrentOrders call:

    {"jsonrpc":"2.0","result":{"currentOrders":[{"betId":"77337570265","marketId":"1.127508662","s electionId":55190,"handicap":0.0,"priceSize":{"pri ce":2.26,"size":2.0},"bspLiability":0.0,"side":"BA CK","status":"EXECUTABLE","persistenceType":"LAPSE ","orderType":"LIMIT","placedDate":"2016-10-19T18:42:42.000Z","averagePriceMatched":0.0,"sizeM atched":0.0,"sizeRemaining":2.0,"sizeLapsed":0.0," sizeCancelled":0.0,"sizeVoided":0.0,"regulatorCode ":"GIBRALTAR REGULATOR"}],"moreAvailable":false},"id":1}

    Leave a comment:


  • jabe
    replied
    Originally posted by judgement View Post
    ok thanks at some stage i will get on to extracting relevant bits from returns.

    so much to learn and so little time!
    There is a lot to learn. No short cuts, alas. I used to be a programmer for a living and my current APING program is probably the most complicated one I've ever written. Good luck with your!

    Leave a comment:


  • betdynamics
    replied
    Originally posted by judgement View Post
    is the traded volume the same as totalMatched? i am getting a figure for totalMatched returned.
    No - my mistake. tradedVolume is not the same at totalMatched.

    Leave a comment:


  • judgement
    replied
    Originally posted by jabe View Post
    It's only data in strings, and the Betfair server has standard responses, so don't worry about unwanted data.
    ok thanks at some stage i will get on to extracting relevant bits from returns.

    Originally posted by jabe View Post
    You might find a look at the JSON tutorial on the w3c website worthwhile. It'd save you trying things like the one above.
    so much to learn and so little time!

    Leave a comment:


  • judgement
    replied
    Originally posted by betdynamics View Post
    Trying to get the traded volume is not a good idea as you are using the delayed AppKey. The delayed AppKey does not return any traded volume.
    is the traded volume the same as totalMatched? i am getting a figure for totalMatched returned.


    Originally posted by betdynamics View Post
    I would also recommend the use of the API Visualiser. This allows you to enter different parameters and see what data is returned, all from within your browser. You can access the API Visualiser at https://developer.betfair.com/exchan...ting-api-demo/
    i've started using it a little but didn't know this is the visualiser. i've seen a lot of references to the visualiser but didn't realise this is it!

    Originally posted by betdynamics View Post
    If you use the Visualiser from within Chrome, then you can hit the F12 key and you will be able to see the request that was sent to Betfair and the response received (these would be in JSON format)
    that seems a good way to find out the code to use. i just gave it a quick try but couldn't immediately see the code of the request but will have a better look later.

    Leave a comment:


  • jabe
    replied
    Originally posted by judgement View Post

    "{""marketIds"":[""" & MarketId & """totalMatched""]}"

    but that failed altogether.
    It's only data in strings, and the Betfair server has standard responses, so don't worry about unwanted data.

    You might find a look at the JSON tutorial on the w3c website worthwhile. It'd save you trying things like the one above.

    Leave a comment:

Working...
X