This vignette will walk through the methods used to place a bet using the betfaiR
package. It will exhibit a number of different options, returning different data, before finally placing a bet, then replacing the bet, and ultimately cancelling the bet - it might become expensive if I let the bets ride.
The primary function in the betfaiR
package is the betfair
function, which returns an environment with the various methods to query the Betfair API.
First we need to login in, this requires a valid username, valid password, and valid API key. The appendix on the betfair
page talks about how to best store these details in a safe manner. The suggestions come from Jenny Bryan via Hadley Wickham’s httr
package (which is used by betfaiR
)
So to login, first load the library, then login, saving the returned environment to a variable, here I named it bf
. This can then be printed to see the available methods:
library(betfaiR)
bf <- betfair(usr = Sys.getenv("bf_usr"),
pwd = Sys.getenv("bf_pwd"),
key = Sys.getenv("bf_key"))
Login successful
bf
<betfaiR API>
Methods available:
$account(pwd)
$cancelOrders(..., marketId = NA)
$clearedOrders(betStatus = "SETTLED", eventTypeIds = NULL, eventIds = NULL, marketIds = NULL, runnerIds = NULL,
betIds = NULL, side = "BACK", from = NULL, to = NULL)
$competitions(filter = marketFilter())
$countries(filter = marketFilter())
$currentOrders(betId = NULL, marketId = NULL, orderProjection = "ALL", from = NULL, to = NULL, orderBy = "BY_BET",
sort = "EARLIEST_TO_LATEST", fromRecord = NULL, count = NULL)
$events(filter = marketFilter())
$eventTypes(filter = marketFilter())
$login(usr, pwd, key, jurisdiction = "default")
$marketBook(marketIds = list(), priceProjection = "EX_BEST_OFFERS", orderProjection = "EXECUTABLE", matchProjection = "NO_ROLLUP",
getRunners = NULL)
$marketCatalogue(filter = marketFilter(), marketProjection = "EVENT", sort = NULL, maxResults = 1, keepRules = FALSE)
$marketPnL(marketIds, settled = NULL, bsp = NULL, NET = NULL)
$marketTypes(filter = marketFilter())
$placeOrders(marketId, selectionId, orderType = "LIMIT", handicap = NULL, side = "BACK", order = limitOrder())
$replaceOrders(..., marketId)
$session()
$updateOrders(..., marketId)
$venues(filter = marketFilter())
It’s unlikely to be the case that you know the marketId or selectionId to go straight to placing a bet, so searching for the markets is usually required. This can be done via a number of different methods, which include, competitions
, countries
, events
, eventTypes
, venues
and perhaps most useful marketCatalogue
and the helper function marketFilter
function.
You can filter on a wide variety of parameters, but some familiarity with these parameters is useful, for example, knowing that an eventTypeId of 1 will return football markets, while eventTypeId of 7 will return horse racing markets. We will look for 5 horse racing markets, in the UK, and we will sort by the amount traded. The response (stored as markets
below) can be passed to summary
for details about the 5 markets, in an easy to read format which allows users to quickly identify the market they’re interested in:
markets <- bf$marketCatalogue(filter = marketFilter(eventTypeIds = 7,
marketCountries = "GB"),
maxResults = 5,
sort = "MAXIMUM_TRADED")
summary(markets)
Market ID: 1.123618419
Event ID: 28061489
Market Name: Gold Cup
Event Name: Chelt 17th Mar
Matched: 454549
---------------------------------------------------------------------------
Market ID: 1.123618411
Event ID: 28061486
Market Name: Champion Hrd
Event Name: Chelt 14th Mar
Matched: 178493.84
---------------------------------------------------------------------------
Market ID: 1.125287736
Event ID: 28061486
Market Name: Supreme Nov Hrd
Event Name: Chelt 14th Mar
Matched: 119524.4
---------------------------------------------------------------------------
Market ID: 1.125287766
Event ID: 28061486
Market Name: Arkle Nov Chs
Event Name: Chelt 14th Mar
Matched: 101155.62
---------------------------------------------------------------------------
Market ID: 1.124139580
Event ID: 28061506
Market Name: Grand National
Event Name: Aint 8th Apr
Matched: 93247.68
---------------------------------------------------------------------------
Let’s look at the first market, the market name is Gold Cup while the event name is Chelt 17th Mar. Below we query this market, and retrieve additional data about the runners, via the marketProjection
parameter:
marketId <- markets[[1]]$market$marketId
market <- bf$marketCatalogue(filter = marketFilter(marketIds = marketId),
marketProjection = "RUNNER_DESCRIPTION")
summary(market)
Market ID: 1.123618419
Market Name: Gold Cup
Matched: 454549
Runners: 88
selectionId runnerName handicap sortPriority
7198646 Thistlecrack 0 1
8902711 Native River 0 2
6987962 Djakadam 0 3
4360454 Cue Card 0 4
6853519 Outlander 0 5
8872379 Bristol De Mai 0 6
---------------------------------------------------------------------------
Now we know the marketId
we can use the marketBook
method to get up to date (well, with a second or so delays) market data. The response of this method can also be passed to summary
for pretty printing, before being mined further. One unfortunate thing about the marketBook
method is that it only returns selectionIds, rather than runner names, so the likes of Thistlecrack or Native River are not included.
market_data <- bf$marketBook(marketIds = marketId,
priceProjection = "EX_BEST_OFFERS")
summary(market_data)
Market ID: 1.123618419
Matched: 527219.33
Available: 25550.97
Runners: 38 (50 removed)
.id selectionId handicap status lastPriceTraded totalMatched
7198646 7198646 0 ACTIVE 2.2 289139.54
8902711 8902711 0 ACTIVE 8.6 29648.37
6987962 6987962 0 ACTIVE 12.0 24268.79
4360454 4360454 0 ACTIVE 13.5 37690.50
6853519 6853519 0 ACTIVE 17.0 11272.76
8872379 8872379 0 ACTIVE 19.0 3924.98
---------------------------------------------------------------------------
Let’s place a lay bet on the current favourite using the placeOrders
method, Thistlecrack, we don’t want this to be matched, so the lay will be at the 1.01 price, and for just ?2. To place a bet, we need the marketId
and selectionId
:
marketId <- market_data[[1]]$market$marketId
selectionId <- market_data[[1]]$runners[[1]]$basic$selectionId
bet <- bf$placeOrders(marketId = marketId,
selectionId = selectionId,
side = "LAY",
order = limitOrder(size = 2, price = 1.01))
With any luck we will get a successful response:
bet
Status: SUCCESS
MarketId: 1.123618419
summary(bet)
Status: SUCCESS
MarketId: 1.123618419
Order:
status betId placedDate averagePriceMatched
SUCCESS 84123177274 2017-01-24T19:26:47.000Z 0
sizeMatched orderStatus
0 EXECUTABLE
Instructions:
selectionId handicap size price persistenceType orderType side
7198646 0 2 1.01 LAPSE LIMIT LAY
We’ll now change that order using the replaceOrders
function, for this we need the betId (which was returned above), and we’ll change the price we wish to be matched at to 1.10.
betId <- bet$order$betId
bet1 <- bf$replaceOrders(replace_inst(betId = betId,
newPrice = 1.10),
marketId = marketId)
This update was a SUCCESS, but we don’t want to leave the bet there, so lets cancel it. We can either target this specific bet using it’s ID, returned above, or we can cancel all bets as below:
(cancel <- bf$cancelOrders())
Status: SUCCESS