R/betfair.R

Defines functions bfLogin bfLogout keepAlive bfSessionToken bfSessionHandler getAllEventTypes getActiveEventTypes getEvents getAllMarkets getMarket getMarketInfo getMarketTradedVolume getMarketTradedVolumeCompressed getCompleteMarketPricesCompressed getMarketPrices getMarketPricesCompressed getBet getBetLite getBetMatchesLite getMUBets getMUBetsLite getBetHistory getMarketProfitAndLoss bfBet placeBets cancelBets cancelBetsByMarket bfBetUpdate updateBets getAccountFunds getAccountStatement getSubscriptionInfo transferFunds viewProfile

Documented in bfBet bfBetUpdate bfLogin bfLogout bfSessionHandler bfSessionToken cancelBets cancelBetsByMarket getAccountFunds getAccountStatement getActiveEventTypes getAllEventTypes getAllMarkets getBet getBetHistory getBetLite getBetMatchesLite getCompleteMarketPricesCompressed getEvents getMarket getMarketInfo getMarketPrices getMarketPricesCompressed getMarketProfitAndLoss getMarketTradedVolume getMarketTradedVolumeCompressed getMUBets getMUBetsLite getSubscriptionInfo keepAlive placeBets transferFunds updateBets viewProfile

##' The \code{betfairly} package allows to access most of the  Betfair
##' \href{https://docs.developer.betfair.com/betfair/}{API} directly from R.
##'
##' For the list of all implemented functions and the details of the current
##' development status please see
##' \href{https://code.google.com/p/betfairly/source/browse/trunk/inst/extra/todo.org}{todo}.
##'
##' If a particular functionality that you need is missing,  please contact the author.
##'
##' For examples of usage see \href{https://code.google.com/p/betfairly/source/browse/trunk/inst/extra/examples.R}{here}.
##'
##' \bold{Table of most common functions:}
##'
##' \tabular{ll}{
##' \bold{If you want to:} \tab \bold{Use:}\cr
##' Login \tab \code{\link{bfLogin}}\cr
##' Request a list of available events \tab \code{\link{getActiveEventTypes}} \cr
##' Request a list of Market for a specific eventType \tab \code{\link{getAllMarkets}} \cr
##' Request details of a Market (excluding prices) \tab \code{\link{getMarket}} \cr
##' Request prices for a Market\tab \code{\link{getMarketPricesCompressed}}\cr
##' Place a bet \tab \code{\link{placeBets}}\cr
##' Cancel a bet before it is matched\tab \code{\link{cancelBets}}\cr
##' Retrieve a list of my Matched/Unmatched bets\tab \code{\link{getMUBets}}\cr
##' Edit an Unmatched bet \tab \code{\link{updateBets}}\cr
##' Retrieve the P&L for a market \tab \code{\link{getMarketProfitAndLoss}}\cr
##' Place a Betfair SP bet \tab \code{\link{placeBets}}\cr
##' Check if a market is in-play now \tab \code{\link{getMarketPricesCompressed}}\cr
##' Check if a market is due to be turned in-play\tab \code{\link{getAllMarkets}}\cr
##' Retrieve a list of Settled bets \tab \code{\link{getBetHistory}}\cr
##' Retrieve your P&L for a market \tab \code{\link{getMarketProfitAndLoss}}
##' }
##'
##'
##'
##' For a description of payed and free access types see
##' \url{http://bdp.betfair.com/index.php?option=com_content&task=view&id=36&Itemid=64}.
##' }
##'
##' \section{Output of \code{betfairly} functions}{
##'
##' All \code{betfairly} API functions can return four types of
##' output, given by the \code{option} parameter which can be:
##'
##' \describe{
##'
##' \item{\code{simple} (the default)}{Simplified output represented by a
##' \code{\link{bfSimpleOutput}} object containing slots \code{bfType}
##' (original betfair class), \code{errorCode} ("OK" if succeed),  and
##' \code{minorErrorCode}  (usually an empty string). See
##' \code{\link{bfSimpleOutput-class}}  for more information.}
##'
##' \item{\code{xml}}{raw XML representation}
##'
##' \item{\code{list}}{recursive list mirroring the structure of the node}
##'
##' \item{\code{S4}}{S4 object as described by the service SOAP protocol. Note
##' what you will need \code{XMLSchema} package for the S4 conversion to work,
##' as it defines some  classes which are not provided with \code{betfairly}
##' package. See \code{\link{bfInitClasses}} for further instructions. }
##'
##' }
##'
##' You can change the default by setting the \code{bfOutput} option:
##'
##' \code{options(bfOutput = "XML")}
##'
##' }
##'
##'
##' \section{Betfair exchange servers}{ Functions to betfair exchange services
##' accept a \code{server} parameter, which can be either "GB" (the default)
##' or "AU". You can set a different default with  \code{options(bfServer =
##' "AU")}
##' }
##'
##' \section{Curl Options}{ Each \code{betfairly} function accepts
##' \code{curlOpts} parameter which is passed directly to
##' \code{\link{curlPerform}},  see the documentation of that function for
##' details.
##' }
##'
##' \section{Reporting Bugs}{Before reporting bugs please see the relevant
##' section in the official Betfair
##' \href{https://docs.developer.betfair.com/betfair/}{documentation} and ensure
##' it's not a betfair service issue. Known isssues are documented for each
##' Betfair API action.}
##'
##' \section{Disclaimer}{ The betfairly package is provided with
##' absolutely no warranty. The documentation of the functional API is an
##' adapted and abbreviated version of official Betfair
##' \href{https://docs.developer.betfair.com/betfair/}{documentation}. Please
##' refer to it for the complete reference.
##' @name betfairly-package
##' @docType package
##' @title Access Betfair API from R
##' @author Vitalie Spinu \email{spinuvit@@gmail.com}
##' @keywords package betfair api
##' @seealso \code{\link{bfSimpleOutput-class}}
##' @references \url{http://code.google.com/p/betfairly/}, \url{https://docs.developer.betfair.com/betfair/}\cr
##' \href{https://bdp.betfair.com/index.php?option=com_weblinks&task=view&catid=59&id=29}{Betfair API Quick Start}
NULL



#### SESSION MANAGEMENT:

##' \code{login} enables customers to log in to the API service and initiates a
##' secure session for the user. Users can have multiple sessions 'alive' at any
##' point in time.\cr\cr
##' \code{logout}  allows you to explicitly end your session.\cr\cr
##' \code{keepAlive} can be used to stop a session timing out. Every
##' call to the Betfair API returns a token, in the sessionToken field, that
##' identifies a login session. Every time your application calls the Betfair
##' API and is returned a sessionToken, the session timeout is reset to
##' approximately 20 minutes. After the timeout has passed, the session is
##' expired and you need to login again.\cr
##' If you want to keep your login session active, but your application has not
##' made any Betfair API calls that would generate a new sessionToken and reset
##' the session timeout, you can call keepAlive to obtain a new sessionToken and
##' reset the session timeout.\cr\cr
##' \code{bfSessionTocken} returns the current session token, if any,  NULL otherwise.
##'
##' \code{bfSessionHandler} (not implemented yet) creates a session handler used
##' to access multiple sessions. A betfair functions can be accessed through
##' \code{obj$foo(...)}, where \code{obj} is the session handler object returned
##' by \code{bfSessionHandler}. All the functions in the handler share common
##' parent environment where the \code{.sessionToken} is stored.
##'
##' Every betfair API request/response must contains a session token.  All
##' functions in betfairly-package store the session token in .GlobalEnv in
##' .sessionToken variable by \code{<<-} assignment. To manage a single account
##' this is appropriate. To manipulate several different sessions at the same
##' time create a handler for each session with \code{bfSessionHandler}.
##'
##' @rdname BF_Session_Management
##' @title Session Management.
##' @aliases >BF_Session_Management bfLogin bfLogout keepAlive bfSessionToken bfSessionHandler
##' @usage bfLogin(username, password, productId=82, ipAddress="0", locationId=0, vendorSoftwareId=0, curlOpts=list())
##' bfLogout(curlOpts = list())
##' keepAlive(curlOpts = list())
##' bfSessionToken()
##' bfSessionHandler()
##' @param username The username with which to login to the API for a new session.
##' @param password The password with which to login to the API for a new session.
##' @param productId The API product ID with which to login to the API for a new
##' session. If you want to use the Free Access API, use 82. If you are a paying
##' API subscriber, use the Id provided when you signed up.
##' @param ipAddress For applications that proxy the user's connection, the IP
##' address of the user's computer. Betfair may inform you in the future if you
##' need to provide this field, otherwise set this field to 0 (the default).
##' @param locationId The location ID with which to login for a new session.
##' @param vendorSoftwareId The vendor software ID with which to login to the
##' API for a new session. This is only relevant for software vendors and is
##' provided when software vendors sign up.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return invisibly a sessionToken string
##' @seealso \code{\link{betfairly-package}} \code{\link{bfSimpleOutput-class}}
##' @references \url{http://code.google.com/p/betfairly/},  \url{https://docs.developer.betfair.com/betfair/}
##' @export bfLogin bfLogout keepAlive bfSessionHandler bfSessionToken
##' @author Vitalie Spinu (\email{spinuvit@@gmail.com})
bfLogin <- function(username, password, productId = 82L, ipAddress = "0", locationId = 0L, vendorSoftwareId = 0L,
                    curlOpts = list()){
    mess <- paste("<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:bfg='http://www.betfair.com/publicapi/v3/BFGlobalService/' >
    f<soapenv:Header/>
    <soapenv:Body>
    <bfg:login>
    <bfg:request>
    <ipAddress >", ipAddress, " </ipAddress>
    <locationId>", as.integer(locationId), "</locationId>
    <password>", password, "</password>
    <productId >", as.integer(productId), "</productId>
    <username>", username, "</username>
    <vendorSoftwareId>", vendorSoftwareId, "</vendorSoftwareId>
    </bfg:request>
    </bfg:login>
    </soapenv:Body>
    </soapenv:Envelope>", sep = "")
    bfRequest(mess, "login", url= "https://api.betfair.com/global/v3/BFGlobalService", curlOpts=curlOpts)
    invisible(.sessionToken)
}
bfLogout <- function(curlOpts = list()){
    .bfRequestInternal(operation = "logout", curlOpts = curlOpts)
    invisible(.sessionToken)
}
keepAlive <- function(curlOpts = list()){
    .bfRequestInternal(operation = "keepAlive", curlOpts = curlOpts)
    invisible(.sessionToken)
}
bfSessionToken <- function(){
    if(exists(".sessionToken")) .sessionToken
    else NULL
}
bfSessionHandler <- function(){
    stop("Not implemented yet")
}

#### GET EVENTS:

##' Functions to retrieve betfair events (Games,  sports, politics etc)
##'
##' getAllEventTypes: Allows the customer to retrieve lists of all categories of
##' sports (Games, Event Types) that have at least one market associated with
##' them, regardless of whether that market is now closed for betting. This
##' means that, for example, the service would always return the event types
##' Soccer and Horse Racing and would also return Olympics 2004 or EURO 2004 for
##' a certain period after the markets for those events had closed; it would
##' also return Olympics 2004 or EURO 2004 for a certain period before the
##' markets for those events had opened. The service returns information on
##' future events to allow API programmers to see the range of events that will
##' be available to bet on in the near future.
##'
##' @rdname BF_Events
##' @aliases >BF_Events getAllEventTypes
##' @title Betfair Events
##' @param locale Specify the language for the reply if you want a different language than the account default.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return A data frame with columns id nextMarketId  and exchangeId; an  xml node or S4 object,  as specified by the \code{output} parameter
##' @seealso \code{\link{betfairly-package}} \code{\link{bfSimpleOutput-class}} \code{\link{getActiveEventTypes}}
##' @references \url{http://code.google.com/p/betfairly/},  \url{https://docs.developer.betfair.com/betfair/}
##' @export
##' @author Vitalie Spinu (\email{spinuvit@@gmail.com})
getAllEventTypes <- function(locale,
                             output = getOption("bfOutput"), curlOpts = list()){
    res <- bfGenericRequest(match.call())
    returnBFOutput(res, output, classPostfix = "DF", letMeParseFunc = function(x,...){
        x <- bfArrayToDataFrame2(x[["eventTypeItems"]])
        x <- x[!is.na(x$name), ]
        x <- x[order(x$id), ]
        rownames(x) <- x$name
        x$name <- NULL
        list(x) })
}

##'
##'
##' getActiveEventTypes: Allows the customer to retrieve lists of all categories
##' of sporting events (Games, Event Types) that are available to bet on: in
##' other words, all those that have at least one currently active or suspended
##' market associated with them. This means, therefore, that the service would,
##' for example, always return the event types Soccer and Horse Racing but would
##' not return Olympics 2004 or EURO 2004 after those events had finished.
##'
##' @rdname BF_Events
##' @param locale Specify the language for the reply if you want a different
##' language than the account default.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return A data frame with columns id, nextMarketId and exchangeId; an xml node or an S4 object,  as specified by the \code{output} parameter
##' @note The GetActiveEventTypes service is a global service, and it returns information about the events
##' available on both the UK and the Australian exchange servers.
##' @export
getActiveEventTypes <- function(locale,
                             output = getOption("bfOutput"), curlOpts = list()) NULL
getActiveEventTypes <- getAllEventTypes
## str(getAllEventTypes())
## str(getActiveEventTypes(output = "S4"))


##'
##'
##' getEvents: Allows you to navigate through the events hierarchy until you
##' reach details of the betting market for an event that you are interested in.
##'
##' From API 5.0 onwards, the GetEvents service returns details of line and
##' range markets, where these markets are available for an event.  Requests
##' for the GetEvents service take as input a parameter called
##' eventParentID. The value of this parameter is either: the (integer) Id
##' value from one item in an array of eventTypeItems that has been returned by
##' the GetAllEventTypes or GetActiveEventTypes services; or an (integer)
##' eventId value from one item in an array of eventItems that has been
##' returned by an earlier GetEvents request.  Use the GetEvents service
##' repeatedly, specifying a different value for eventParentId in each request,
##' until there are no further events to request (this means you have reached
##' the leafnode of the branch of the events tree you have been navigating).
##' To retrieve full details of a betting market whose details have been
##' returned by the GetEvents service, you need to send a GetMarket request to
##' the exchange server indicated by the market's exchangeId parameter (see
##' CROSS REFERENCE TEXT NEEDS RESOLVING). This GetMarket request must also
##' specify the marketId for the market you are requesting. Both the exchangeId
##' and the marketId are returned by GetEvents. For information about
##' GetMarket, see Chapter 24 .
##'
##' @rdname BF_Events
##' @param eventParentId integer This is either an Id value for a single item (in
##' an array of eventTypeItems returned by GetAllEventTypes or
##' GetActiveEventTypes), or it is an eventId for a single eventItem (in an array
##' of eventItems returned by an earlier GetEvents request).
##' @param locale Specify the language for the reply if you want a different language than the account default.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{GetEventsRespSimple} which inherits from
##' \code{\link[=bfSimpleOutput-class]{bfSimpleOutput}} class. With slots
##' \code{eventItems} and \code{marketItems} which are data.frames.
##' @export
##' @author Vitalie Spinu (\email{spinuvit@@gmail.com})
##'
getEvents <- function(eventParentId = 1L, locale,
                      output = getOption("bfOutput"), curlOpts = list()){
    call <- match.call()
    call["eventParentId"] <- as.integer(eventParentId)
    res <- bfGenericRequest(call)
    returnBFOutput(res, output,
                   data_slots = c("eventItems", "marketItems"),
                   info_slots = c("eventParentId", "couponLinks"),
                   converters= list(`n2:ArrayOfBFEvent`= bfArrayToDataFrame2,
                     `n2:ArrayOfMarketSummary` = bfArrayToDataFrame2))
}
## getEvents()


#### GET MARKETS
##' Functions to retrieve information about Betfair markets.
##'
##' getAllMarkets: Retrieve information about all of the markets that are
##' currently active or suspended on the given exchange. You can use this
##' service to quickly analyse the available markets on the exchange, or use the
##' response to build a local copy of the Betfair.com navigation menu. You can
##' limit the response to a particular time period, country where the event is
##' taking place, and event type. Otherwise, the service returns all active and
##' suspended markets.
##'
##' @rdname BF_Markets
##' @aliases >BF_Markets getAllMarkets
##' @title Betfair markets
##' @param eventTypeIds A vector with the events ids to return. If not
##' specified, markets from all event types are returned.
##' @param countries The countries where the event is taking place as an array
##' of ISO3 country codes. If not specified, markets from all countries (or
##' international markets) for the specified exchange are returned.
##' @param fromDate Any R date-time object or  string recognized by
##' as.POSIXlt. Use \code{asBFDateTime} to see how your time input is
##' interpreted. If this is set, the response contains only markets where the
##' market time is not before the specified date.
##' @param toDate Any R date-time object or  string recognized by
##' as.POSIXlt. If this is set, the response contains only markets where the
##' market time is not after the specified date. No limit if not specified.
##' @param locale Specify the language for the reply if you want a different language than the account default.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return A data.frame containing one market per row and a character string if \code{output = "S4"}.
##' @seealso \code{\link{betfairly-package}} \code{\link{bfSimpleOutput-class}}
##' @references \url{http://code.google.com/p/betfairly/},  \url{https://docs.developer.betfair.com/betfair/}
##' @export
getAllMarkets <- function(eventTypeIds, countries, fromDate, toDate, locale,
                          server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    call <- match.call()
    if(!missing(eventTypeIds))
        call[["eventTypeIds"]] <- asBF(eventTypeIds, "ArrayOfInt")
    if(!missing(countries))
        call[["counetries"]] <- asBF(countries, "ArrayOfCountryCode")
    if(!missing(fromDate))
        call[["fromDate"]] <- asBFDateTime(fromDate)
    if(!missing(toDate))
        call[["toDate"]] <- asBFDateTime(toDate)
    res <- bfGenericRequest(call)
    returnBFOutput(res, output, classPostfix = "DF",
                   letMeParseFunc = function(res){
                       res <- fromBFXML(res[["marketData"]], forceList = TRUE)
                       if(res=="") return(list(data.frame()))
                       res <- strsplit(strsplit(res, ":", fixed = TRUE)[[1]][-1], "~",fixed = TRUE) ## todo use "[^\\]:" instead? to avoid escapes \:
                       res <- as.data.frame(do.call(rbind, res), stringsAsFactors=FALSE)
                       types <- c(marketID="integer", marketName="character", marketType="factor", marketStatus="factor",
                                  eventDate="character", menuPath="character", eventHierarchy="character",
                                  betDelay="numeric", exchangeID= "integer", countryCode="character",
                                  lastRefresh= "character", nrRunners="integer", nrWinners="integer",
                                  totalMatched="numeric", BSP="factor", turningInPlay="factor")
                       names(res) <- names(types)
                       for(nm in names(res))
                           res[[nm]] <- as(res[[nm]], types[[nm]])
                       res[["eventDate"]] <- toBFPOSIX(res[["eventDate"]])
                       res[["lastRefresh"]] <- toBFPOSIX(res[["lastRefresh"]])
                       list(res)
                   })
}
## head(getAllMarkets(1, c("GBR")))

##'
##'
##' getMarket: The API GetMarket service allows the customer to input a Market
##' ID and retrieve all static market data for the market requested. To get a
##' Market ID for the betting market associated with an event you are interested
##' in, use the GetEvents command.
##'
##' @rdname BF_Markets
##' @param marketId Integer specifying the market ID.
##' @param includeCouponLinks If you set this parameter to true, the service
##' response contains a list of any coupons that include the market you have
##' requested. If you set the parameter to FALSE (the default), no coupon data is returned.
##' @param locale Specify the language for the reply if you want a different language than the account default.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{GetMarketRespSimple} which inherits from
##' \code{\link[=bfSimpleOutput-class]{bfSimpleOutput}} class. Additional slot
##' \code{runners} contains a data frame of event participants.
##'
##' Object of native betfair class \code{GetMarketResp} if \code{output = "S4"}.
##' @export
getMarket <- function(marketId, includeCouponLinks = FALSE, locale = "en",
                      server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    call <- match.call()
    call["marketId"] <- as.integer(marketId)
    res <- bfGenericRequest(call)
    returnBFOutput(res, output,  data_slots = "runners", simpleNode = "market",
                   converters= list(`n2:ArrayOfRunner`= bfArrayToDataFrame2))
}

##getMarket("102902130")
## getMarket(102759800L)

##'
##'
##' getMarketInfo: The API GetMarketInfo service allows you to input a Market ID
##' and retrieve market data for the market requested. To get a Market ID for
##' the betting market associated with an event you are interested in, use the
##' GetEvents command. This is a lite service to compliment the GetMarket
##' service.
##'
##' @rdname BF_Markets
##' @param marketId Integer specifying the market ID.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{GetMarketInfoRespSimple} which inherits from
##' \code{\link[=bfSimpleOutput-class]{bfSimpleOutput}} class and has no extra slots.
##'
##' If \code{output = "S4"},  object of native betfair class \code{GetMarketInfoResp}.
##' @export
getMarketInfo <- function(marketId,
                          server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    call <- match.call()
    call["marketId"] <- as.integer(marketId)
    res <- bfGenericRequest(match.call())
    returnBFOutput(res, output, simpleNode = "marketLite")
}
## getMarketInfo("102759800")


##'
##'
##' getMarketTradedVolume: Obtain all the current odds and matched amounts on a
##' single runner in a particular event.
##' @rdname BF_Markets
##' @param marketId Integer specifying the market ID.
##' @param selectionId The desired runner id.
##' @param asianLineId Mandatory if the market specified by Market ID is an
##' Asian Market, otherwise optional
##' @param currencyCode Three letter ISO 4217 code.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{GetMarketTradedVolumeRespSimple} with a slot
##' \code{priceItems} containing a data frame of  total match volumes for each odd.
##' @export
getMarketTradedVolume <- function(marketId,  selectionId, asianLineId, currencyCode,
                                  server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    call <- match.call()
    ## mandatory fields:
    call[c("marketId", "selectionId")] <- c(marketId, selectionId)
    res <- bfGenericRequest(call)
    returnBFOutput(res, output, data_slots = "priceItems", info_slots = "actualBSP",
                   converters = list(`n2:ArrayOfVolumeInfo` = bfArrayToDataFrame2))
}

##'
##'
##' getMarketTradedVolumeCompressed: Obtain the current price (odds) and matched
##' amounts at each price on all of the runners in a particular market.
##' @rdname BF_Markets
##' @param marketId Integer specifying the market ID.
##' @param currencyCode Three letter ISO 4217 code.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{GetMarketTradedVolumeCompressedRespSimple}
##' with two additional slots \code{runners} and \code{volumes}.
##' @export
getMarketTradedVolumeCompressed <- function(marketId, currencyCode,
                                            server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    call <- match.call()
    ## mandatory fields:
    call["marketId"] <- marketId
    res <- bfGenericRequest(call)
    returnBFOutput(res, output, letMeParseFunc = .simple_getMarketTradedVolumeCompressed)
}


#### GET PRICES
##' Functions to retrieve prices on Betfair markets.
##'
##' getCompleteMarketPricesCompressed: Retrieve all back and lay stakes for each
##' price on the exchange for a given Market ID in a compressed format. The
##' information returned is similar to the GetDetailAvailableMarketDepth, except
##' it returns the data for an entire market, rather than just one selection.
##'
##' @rdname BF_Prices
##' @aliases >BF_Prices getCompleteMarketPricesCompressed
##' @title Prices on betfair markets.
##' @param marketId Integer specifying the market ID.
##' @param currencyCode Three letter ISO 4217 code.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return A list of class \code{GetCompleteMarketPricesCompressedRespSimple}
##' with three additional slots containing data.frames \code{removedRunners},
##' \code{runners} and \code{prices}. Use \code{\link{merge}} for joining these
##' by the common field \code{runners}.
##' @seealso \code{\link{betfairly-package}} \code{\link{bfSimpleOutput-class}} \code{\link{getActiveEventTypes}}
##' @references \url{http://code.google.com/p/betfairly/},  \url{https://docs.developer.betfair.com/betfair/}
##' @export
##' @author Vitalie Spinu (\email{spinuvit@@gmail.com})
getCompleteMarketPricesCompressed <- function(marketId, currencyCode = "EUR",
                                              server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    res <- bfGenericRequest(match.call())
    returnBFOutput(res, output, letMeParseFunc = .simple_getCompleteMarketPricesCompresed)
}


##'
##'
##' getMarketPrices: Retrieve dynamic market data for a given Market ID.
##'
##' @rdname BF_Prices
##' @param marketId integer ID of the required market
##' @param currencyCode character  Three letter ISO 4217 code. If not supplied,
##' users currency is used
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{"GetMarketPricesRespSimple"} with a slot
##' \code{runnerPrices} containing a data frame of back and lay prices for each
##' runner. This function returns the same information as
##' \code{getMarketPricesCompressed} but in a merged, long format.
##' @export
getMarketPrices <- function(marketId, currencyCode,
                            server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    call <- match.call()
    call[["marketId"]] <- as.integer(marketId)
    res <- bfGenericRequest(call)
    returnBFOutput(res, output, data_slots="runnerPrices", simpleNode = "marketPrices",
                   converters= list(
                     `n2:ArrayOfPrice`= bfArrayToDataFrame2,
                     `n2:ArrayOfRunnerPrices`=
                     function(x,..., converters){
                         if(is.character(x)) return(if(x == "") NA else x)
                         runners <- fromBFXML(x, list(), converters = converters)
                         if(length(runners) == 0) return(NULL)
                         out <- list()
                         for(i in seq_along(runners)){
                             toBack <-
                                 if(is1NA(toBack <- runners[[i]]$bestPricesToBack)) NULL
                                 else cbind(bestPrice = "toBack", toBack)
                             toLay <-
                                 if(is1NA(toLay <- runners[[i]]$bestPricesToLay)) NULL
                                 else  cbind(bestPrice = "toLay", toLay)
                             runners[[i]]$bestPricesToLay <- runners[[i]]$bestPricesToBack <- NULL
                             out[[i]] <- do.call(cbind, c(runner=i, list( rbind(toBack, toLay)), runners[[i]]))
                         }
                         out <- do.call(rbind , out)
                         rownames(out) <- NULL
                         out
                     }))
}

## getMarket("101513259")
## getMarketPrices("101513259")

##'
##'
##' getMarketPricesCompressed: Retrieve dynamic market data for a given Market
##' ID in a compressed format. This service returns the same information as the
##' Get Market Prices service but returns it in a ~ (tilde) delimited String.
##'
##' @rdname BF_Prices
##' @param marketId Integer specifying the market ID.
##' @param currencyCode Three letter ISO 4217 code.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{GetMarketPricesCompressedRespSimple} containing slots \code{runners} and \code{prices}.
##' @export
getMarketPricesCompressed <- function(marketId, currencyCode,
                                      server = getOption("bfServer"), output= getOption("bfOutput"), curlOpts = list()){
    res <- bfGenericRequest(match.call())
    ## fromBFXML(res[["marketPrices"]])
    returnBFOutput(res, output, letMeParseFunc = .simple_getMarketPricesCompressed)
}
## getMarketPricesCompressed(mid)
## getMarketPrices(102892658)


#### BET HISTORY:
##' With \code{getBetHistory}, \code{getMUBets} and \code{getMUBetsLite} you
##' access information about all your bets.  With getBet, getBetLite and
##' getBetMatchesLite you can access detailed information about your specific
##' bets.
##'
##' getBet: Retrieve information about a particular bet. Each request will
##' retrieve all components of the desired bet.
##'
##' You can retrieve Cancelled, Lapsed, and Voided bets from only settled
##' markets and these bets are available for a maximum of 10 days from the date
##' the market was settled.
##' @title Access your bets
##' @rdname BF_Bet_History
##' @param betId The unique bet identifier
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return A list of class \code{GetBetRespSimple} containing slot
##' \code{matches} with info  about matched portions of the bet.
##' @author Vitalie Spinu (\email{spinuvit@@gmail.com})
##' @export
##' @seealso \code{\link{betfairly-package}} \code{\link{bfSimpleOutput-class}}
##' @references \url{http://code.google.com/p/betfairly/},  \url{https://docs.developer.betfair.com/betfair/}
getBet <- function(betId,
                   server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    out <- .bfRequestInternal(betId = betId, operation = "getBet", curlOpts = curlOpts, server = server)
    returnBFOutput(out, output = output, data_slots = "matches", simpleNode = "bet",
                   converters = list('n2:ArrayOfMatch' = bfArrayToDataFrame2))
}

##'
##'
##' getBetLite: This is the lite version of the GetBet service.
##' @rdname BF_Bet_History
##' @param betId The unique bet identifier
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return A list of class \code{GetBetLiteRespSimple} with no additional
##' slots.  Contains a subset of information from data part of \code{getBet}
##' response.
##' @export
getBetLite <- function(betId,
                       server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    out <- .bfRequestInternal(betId = betId, operation = "getBetLite", curlOpts = curlOpts, server = server)
    returnBFOutput(out, output = output, simpleNode = "betLite")
}


##'
##' getBetMatchesLite: This is a lite version of the GetBet service that returns
##' information on matched bets.
##' @rdname BF_Bet_History
##' @param betId The unique bet identifier
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Data frame of class \code{GetBetMatchesLiteRespSimple} containing
##' subset of information from \code{@@matches} slot in \code{getBet} response.
##' @export
##' @seealso \code{\link{betfairly-package}} \code{\link{bfSimpleOutput-class}}
getBetMatchesLite <- function(betId,
                              server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    out <- .bfRequestInternal(betId = betId, operation = "getBetMatchesLite", curlOpts = curlOpts, server = server)
    returnBFOutput(out, output = output, classPostfix = "DF",
                   letMeParseFunc = function(out) list(bfArrayToDataFrame2(out[["matchLites"]])))
}

##'
##'
##' getMUBets: Retrieve information about all your matched and unmatched bets on
##' a particular exchange server.  You should be aware that voided bets are not
##' returned by getMUBets. Your application should track the number of matched
##' and unmatched bets against the number of bets returned by getMUBets in order
##' to detect a voided bet.
##' @rdname BF_Bet_History
##' @param marketId For \strong{getMUBets} and \strong{getMUBetsLite}: If
##' marketId is present and non-zero, then bets placed on the specified market
##' are returned and any bet ids specified in betIds are ignored.\cr For
##' \strong{getBetHistory} Returns the records of your matched or unmatched bets
##' for the specified market. If you use this parameter you must not specify
##' \code{eventTypeId} array. Note that, if you specify a marketId, you must also
##' specify either M or U as the value for the \code{betTypesIncluded} parameter.
##' @param betIds Specifies the betId of each bet you want returned. The maximum
##' number of bets you can include in the array is 200. If you include marketId
##' in the request and marketId contains a non-zero value, then betIds is
##' ignored. If you specify a betId, then you must specify MU for betStatus.
##' @param betStatus M, U or MU. The status of the bets to return (matched, unmatched, or
##' both) - please see betfairly Simple Data Types . If you specify a betId, then
##' you must specify MU.
##' @param matchedSince Specifies a date and time to start from for the list of
##' returned bets. Any R date-time object or  string recognized by
##' as.POSIXlt. Use \code{asBFDateTime} to see how your time input is
##' interpreted. If you use the matchedSince parameter and you have specified a
##' betStatus of MU, the bets returned will ignore any limit you set (using
##' recordCount) for the number of records to be returned. Specifying a
##' betStatus of MU causes the API to return your unmatched bets along with the
##' matched ones.
##' @param orderBy The order of returned results. Valid orders are BET_ID,
##' PLACED_DATE, and MATCHED_DATE.
##' @param sortOrder ASC or DESC. Whether the results are in ascending or descending order
##' @param recordCount Maximum number of records to return. The maximum number allowed is 200.
##' @param startRecord The first record number to return (supports
##' paging). Record numbering starts from 0. For example, to retrieve the third
##' record and higher, set startRecord to 2.
##' @param excludeLastSecond If true, the API excludes bets placed or matched
##' that occurred less than one second before the GetMUBets call. Set this to
##' true if you want to ensure that the response does not include bets that may
##' have changed state between the time you sent the request and before the
##' response was generated. If false, all bets are returned. Therefore, you may
##' receive a response that indicates an unmatched bet that has actually been
##' matched during the time taken for the API to respond.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{xxx} containing slot
##' @export
##' @seealso \code{\link{betfairly-package}} \code{\link{bfSimpleOutput-class}}
getMUBets <- function(marketId, betIds, betStatus = "MU", matchedSince, orderBy = "BET_ID",
                      sortOrder = "ASC", recordCount = 200, startRecord = 0, excludeLastSecond = FALSE,
                      server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    call <- match.call()
    call[c("betStatus", "orderBy", "recordCount", "sortOrder", "startRecord")] <-
        c(betStatus, orderBy, recordCount, sortOrder, startRecord)
    if(!missing(betIds))
        call[["betIds"]] <- asBF(betIds, "ArrayOfBetId")
    if(!missing(matchedSince))
        call[["matchedSince"]] <- asBFDateTime(matchedSince)
    out <- bfGenericRequest(call)
    returnBFOutput(out, output, classPostfix = "DF", letMeParseFunc = function(out){
        df <- bfArrayToDataFrame2(out[["bets"]])
        if(length(df)){
            dNames <- grep("Date", names(df), fixed = TRUE)
            df <- df[, c((1:length(df))[-dNames], dNames)]
        }
        list(df)
    })
}

##'
##'
##' getMUBetsLite: This is a lite version of the getMUBets service.
##' @rdname BF_Bet_History
##' @param marketId Integer specifying the market ID.
##' @param betIds A vector specifying the betId of each bet you want
##' returned. The maximum number of bets you can include in the array is 200. If
##' you include marketId in the request and marketId contains a non-zero value,
##' then betIds is ignored. If you specify a betId, then you must specify MU for
##' betStatus.
##' @param betStatus
##' @param matchedSince
##' @param orderBy
##' @param sortOrder
##' @param recordCount
##' @param startRecord
##' @param excludeLastSecond
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @export
getMUBetsLite <- function(marketId, betIds, betStatus = "MU", matchedSince, orderBy = "BET_ID",
                          sortOrder = "ASC", recordCount = 200, startRecord = 0, excludeLastSecond = FALSE,
                          server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    call <- match.call()
    call[c("betStatus", "orderBy", "recordCount", "sortOrder", "startRecord")] <-
        c(betStatus, orderBy, recordCount, sortOrder, startRecord)
    if(!missing(betIds))
        call[["betIds"]] <- asBF(betIds, "ArrayOfBetId")
    if(!missing(matchedSince))
        call[["matchedSince"]] <- asBFDateTime(matchedSince)
    out <- bfGenericRequest(call)
    returnBFOutput(out, output, classPostfix = "DF",
                   letMeParseFunc = function(out) list(bfArrayToDataFrame2(out[["betLites"]])))
}


##'
##'
##' @rdname BF_Bet_History
##' @param marketId Integer specifying the market ID.
##' @param eventTypeIds An array of event types to return. For matched and
##' unmatched bets only, you can leave it unspecified  and specify zero (the default) as the
##' marketId to receive records of all your bets on the exchange.
##' @param detailed [logical] Whether to show details of all the matches on a single bet
##' @param sortBetsBy [ASC, DESC] How the bets are ordered.
##' @param betTypesIncluded [C Cancelled, L Lapsed, M Matched, MU Matched and
##' Unmatched, S Settled (default), U Unmatched, V Voided] Indicates the status of the
##' bets to include in the response. If your \code{betHistory} request is for a
##' specific market (in other words, if you have specified a marketId in your
##' request), then you must specify either M or U as the value for
##' betTypesIncluded. Otherwise you will receive an INVALID_BET_STATUS
##' error. Only settled markets return cancelled, void, or lapsed bets.
##' @param marketTypesIncluded [A Asian Handicap, L Line, O Odds (default), R
##' Range] Indicates the types of market that you want your betting history
##' returned for.
##' @param placedDateFrom Any R date/date-time object is accepted or any character
##' string recognized by as.POSIXlt. Default to current day at 00:00.
##' @param placedDateTo Any R date/date-time object. Default to Sys.time().
##' @param recordCount The maximum number of records to return. This number must
##' be between 1 and 100, inclusive.
##' @param startRecord The first record number to return (supports
##' paging). Record numbering starts from 0. For example, to retrieve the third
##' record and higher, set startRecord to 2.
##' @param locale Specify the language for the reply if you want a different language than the account default.
##' @param timezone Specify an alternative time-zone from the user account default.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{GetBetHistoryRespSimple} containing slots
##' \code{betHistoryItems} - a data frame with one  bet per row  and
##' \code{matches} - a data frame with all the matches if the \code{details}
##' parameter  was set to TRUE.
##' @export
getBetHistory <- function(marketId = 0, eventTypeIds = NULL, detailed = FALSE, sortBetsBy = "NONE",
                          betTypesIncluded = "S", marketTypesIncluded = "O",
                          placedDateFrom = Sys.Date(), placedDateTo = Sys.time(),
                          recordCount = 100, startRecord = 0,
                          locale, timezone,
                          server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    request <- list(eventTypeIds = asBF(eventTypeIds, "ArrayOfInt"), detailed = detailed, betTypesIncluded = betTypesIncluded,
                    marketTypesIncluded = asBF(marketTypesIncluded, "ArrayOfMarketTypeEnum"),
                    placedDateFrom = asBFDateTime(placedDateFrom), placedDateTo = asBFDateTime(placedDateTo),
                    recordCount = recordCount, startRecord = startRecord, sortBetsBy = sortBetsBy, curlOpts = curlOpts, server = server)
    if(!missing(marketId)) request[["marketId"]] <- marketId
    if(!missing(locale)) request[["locale"]] <- locale
    if(!missing(timezone)) request[["timezone"]] <- timezone
    out <- do.call(.bfRequestInternal, c(request, operation = "getBetHistory"))
    returnBFOutput(out, output, letMeParseFunc = .simple_GetBetHistory)
}

##'
##'
##' getMarketProfitAndLoss: Retrieve Profit and Loss information for the user
##' account in a given market. The limitations for the service in the initial
##' release are:
##'
##'    * Profit and loss for single and multi-winner odds markets is implemented
##' however it won't calculate worstCaseIfWin nor futureIfWin.
##'
##'    * The calculation for AH markets will include worstCaseIfWin but not futureIfWin.
##' @rdname BF_Bet_History
##' @param marketID The market ID for which the profit and loss for the user is
##' to be returned
##' @param includeSettledBets logical If TRUE then the P&L calculation for each runner
##' includes any profit and loss from any bets on runners that have already been
##' settled. The default is FALSE, which matches the default on Betfair.com.
##' @param includeBspBets If TRUE, BSP bets are returned as part of the P&L
##' @param netOfCommission If TRUE return P&L net of users current commission rate
##' for this market including any special tariffs, default is FALSE.
##' @param locale Specify the language for the reply if you want a different language than the account default.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{GetMarketProfitAndLossRespSimple} containing slot \code{annotations} which is a data frame with P&L data.
##' @export
getMarketProfitAndLoss <- function(marketID, includeSettledBets = FALSE,  includeBspBets = TRUE,   netOfCommission = FALSE, locale,
                                   server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    call <- match.call()
    call[c("marketID", "includeBspBets")] <- c(marketID, includeBspBets)
    out <- bfGenericRequest(call)
    returnBFOutput(out, output, exclude_info_slots = c("header", "errorCode", "minorErrorCode"),
                   data_slots = "annotations", converters = list('n2:ArrayOfProfitAndLoss' = bfArrayToDataFrame2))
}


### BET PLACEMENT

##' Place, update and cancel multiple bets at a time. \cr \cr For
##' \code{placeBets} and \code{updateBets}, there are two equivalent ways of
##' supplying the bet info. First, by passing a list of corresponding objects
##' (\code{bfBet} and \code{bfBetUpdate}) as \code{bets} argument. Second, a
##' vectorized (\code{mapplyish}) way,  by supplying vectors to corresponding
##' arguments. Vectorized arguments are recycled to the same length if
##' needed. These arguments are all in plural and are not documented below.
##'
##'
##' bfBet: Constructor of \code{bfBet} object. You supply a list of these objects as
##' \code{bets} argument to \code{placeBets}.
##'
##' The required fields in bets are dependent on the category of bet. The
##' following table shows the required fields for each bet category.
##'
##' Table 1. Valid Bet Category request field combinations
##' \tabular{lrrrr}{
##' Bet Category \tab Price \tab Size \tab BspLiability \tab BetPersistenceType \cr
##' Exchange \tab Yes \tab Yes \tab No \tab Yes \cr
##' Market on Close \tab No \tab No \tab Yes \tab No \cr
##' Limit on Close \tab Yes \tab No \tab Yes \tab No
##' }
##' @title Functions to place, update and cancel bets.
##' @rdname BF_Bet_Placement
##' @aliases >BF_Bet_Placement bfBet
##' @param marketId Integer specifying the market ID.
##' @param selectionId  ID of the desired runner or selection within the market
##' @param price numeric  The price (odds) you want to set for the bet. Valid
##' values are 1.01 to 1000. For a BSP Limit on Close bet, specify the desired
##' price limit. For a Back bet, the minimum price you want. If the Starting
##' Price is lower than this amount, then your bet is not matched. For a Lay
##' bet, the maximum acceptable price. If the Starting Price is higher than this
##' amount, then your bet is not matched. If the specified limit is equal to the
##' starting price, then it may be matched, partially matched, or may not be
##' matched at all, depending on how much is needed to balance all bets against
##' each other (MOC, LOC and normal exchange bets).
##' @param size numeric The stake (amount) for an exchange bet. The minimum
##' amount for a back bet is 2 (or equivalent). If the betPersistenceType is
##' set to SP, then the minimum amount for a lay bet is 10 (or equivalent),
##' otherwise, the minumum lay bet amount is 2 (or equivalent).
##' @param betType 'B' - back, 'L'- lay. See details.
##' @param bspLiability numeric  This is the maximum amount of money you want to risk for
##' a BSP bet. The minimum amount for a back bet is 2 (or equivalent). The
##' minimum amount for a lay bet is 10 (or equivalent) For a back bet, this is
##' equivalent to the stake on a normal exchange bet. For a lay bet, this is the
##' equivalent to the liability on a normal exchange bet. If after the market is
##' reconciled, the actual stake is calculated once the price is known.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param betCategoryType E, M or L. 'E' - Exchange bet, 'M' - Market on
##' Close SP bet, 'L' - Limit on Close SP bet. If you specify Limit on Close,
##' specify the desired limit using the price argument. See details.
##' @param betPersistenceType NONE, IP or SP. Specify what happens to an
##' unmatched (or partially unmatched) exchange bet when the market turns
##' in-play. If betCategoryType is an SP bet, betPersistenceType must be set to
##' NONE. See details.
##' @return String of class \code{bfBet}.
##' @author Vitalie Spinu (\email{spinuvit@@gmail.com})
##' @export
##' @seealso \code{\link{betfairly-package}} \code{\link{bfSimpleOutput-class}}
##' @references \url{http://code.google.com/p/betfairly/},  \url{https://docs.developer.betfair.com/betfair/}
bfBet <- function(marketId, selectionId, price, size, betType = "B", bspLiability = 0.0,
                  betCategoryType = "E", betPersistenceType = "NONE",
                  server = getOption("bfServer")){
    call <- match.call()
    switch(betCategoryType,
           E = call[c("betCategoryType", "price", "size", "betPersistenceType", "bspLiability")] <- c(betCategoryType, price, size, betPersistenceType, bspLiability),
           M = call[c("betCategoryType", "bspLiability", "betPersistenceType")] <- c(betPersistenceType, bspLiability, betPersistenceType),
           L = call[c("betCategoryType", "price", "bspLiability")] <- c(betCategoryType, price, bspLiability),
           stop("betCategoryType must be one of E, M, L. Supplied : ", betCategoryType))
    if(!(betPersistenceType %in% c("NONE", "IP", "SP")))
        stop("betPersistenceType must be NONE, IP, or SP. Supplied : ", betPersistenceType)
    if(!(betType %in% c("B", "L")))
        stop("betType must be B, or L. Supplied : ", betType)
    call[c("marketId", "selectionId", "betType")] <- c(marketId, selectionId, betType)
    call[[1]] <- as.name("list")
    
    structure(bfCollapseParams(eval(call, envir = parent.frame(1L))), class = "bfBet")
}



##' 
##'
##' placeBets: Place multiple (1 to 60) bets on a single Market. There is an instance of
##' PlaceBetsResp returned in the output for each instance of PlaceBets in the
##' input. The success or failure of the individual bet placement operation is
##' indicated by the Success Boolean.
##'
##' \describe{
##' 
##' \item{Bet Types}{
##' 
##' You can specify, for each bet, if you want to place a Back bet or a Lay bet.
##'
##' * B - Back bets win when the selection is settled as the winner in the market.
##' * L - Lay bets win when the selection is settled as a looser in the market.
##'
##' For more information on Bet types, see the Betfair website help.
##' }
##' \item{Bet Categories}{
##'
##' You can specify, for each bet, whether the bet is a regular exchange bet, or
##' a Betfair Market on Close (or Starting Price) bet (with or without a price
##' limit).
##'
##' * E - Exchange bets are placed on the market and are matched against bets at the
##' specified or better price. Exchange bets are matched on a first in, first
##' matched basis.
##'
##' * M - Market on Close (MOC) bets remain unmatched until the market is
##' reconciled. They are matched and settled at a price that is representative
##' of the market at the point the market is turned in-play. The market is
##' reconciled to find a starting price and MOC bets are settled at whatever
##' starting price is returned. MOC bets are always matched and settled, unless
##' a starting price is not available for the selection. Market on Close bets
##' can only be placed before the starting price is determined.
##'
##' * L - Limit on Close (LOC) bets are matched if, and only if, the returned
##' starting price is better than a specified price. In the case of back bets,
##' LOC bets are matched if the calculated starting price is greater than the
##' specified price. In the case of lay bets, LOC bets are matched if the
##' starting price is less than the specified price. If the specified limit is
##' equal to the starting price, then it may be matched, partially matched, or
##' may not be matched at all, depending on how much is needed to balance all
##' bets against each other (MOC, LOC and normal exchange bets)
##' }
##' \item{Bet Persistence}{
##'
##' You can specify what happens to an Exchange bet that is unmatched when the
##' market is reconciled and the starting price is calculated.
##'
##' * NONE - The unmatched bet is cancelled when the market is reconciled and turned in-play.
##'
##' * IP - The unmatched bet stays as an unmatched bet when the market is turn in-play.
##'
##' * SP - The unmatched bet becomes a Market on Close bet and is matched at the starting price.
##'
##' }}
##'
##' @rdname BF_Bet_Placement
##' @param bets For \emph{\code{placeBets}}  an \code{bfBet} object or a list (of max 60) such objects.\cr
##' For \emph{\code{cancelBets}}  a vector of bet ids to be canceled (max 40).\cr
##' For \emph{\code{updateBets}}  an \code{bfBetUpdate} object or a list (of max 15) such objects.
##' @param marketIds Vector of integers specifying the market IDs.
##' @param selectionIds _
##' @param prices _
##' @param sizes _
##' @param betTypes _
##' @param bspLiabilities _
##' @param betCategoryTypes _
##' @param betPersistenceTypes _
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Data frame with info on the success of placed bets, one bet per row.
##' @export
placeBets <- function(bets = list(),
                      marketIds, selectionIds, prices, sizes, betTypes = "B", bspLiabilities = 0.0,
                      betCategoryTypes = "E", betPersistenceTypes = "NONE",
                      server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    if(is(bets, "bfBet"))
        bets <- list(bets)
    if(length(bets) && !all(sapply(bets, is, "bfBet")))
        stop("All elements of 'bets' argument must be of class 'bfBet' as produced by 'bfBet' function.")
    if(!missing(marketIds))
        bets <- c(bets, mapply(bfBet, marketIds, selectionIds, prices, sizes, betTypes, bspLiabilities,
                               betCategoryTypes, betPersistenceTypes))
    out <- .bfRequestInternal(bets = asBF(bets, "ArrayOfPlaceBets"), operation = "placeBets", curlOpts = curlOpts, server = server)
    returnBFOutput(out, output = output, classPostfix = "DF",
                   letMeParseFunc = function(out) list(bfArrayToDataFrame2(out[["betResults"]])))
}

##' 
##'
##' cancelBets: Cancel multiple unmatched (1 to 40) bets placed on a single
##' Market. The success or failure of the individual bet cancellation operation
##' will be indicated by the Success Boolean. If a portion of the original bet
##' is already matched, cancelBets cancels the unmatched portion of the bet.
##' @rdname BF_Bet_Placement
##' @param bets
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Data frame with info on canceled bets, one bet per row.
##' @export
cancelBets <- function(bets,
                       server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    stopifnot(is.vector(bets))
    out <- .bfRequestInternal(bets = asBF(bets, "ArrayOfCancelBets"), operation = "cancelBets", curlOpts = curlOpts, server = server)
    returnBFOutput(out, output = output, classPostfix = "DF",
                   letMeParseFunc = function(out) list(bfArrayToDataFrame2(out[["betResults"]])))
}

##' 
##'
##' cancelBetsByMarket: [payed] Cancel all unmatched bets (or unmatched portions
##' of bets) placed on one or more Markets. You might use this service to
##' quickly close out a position on a market.
##' @rdname BF_Bet_Placement
##' @param markets Vector of market IDs.
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{xxx} containing slot
##' @export
cancelBetsByMarket <- function(markets,
                               server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    stopifnot(is.vector(markets))
    out <- .bfRequestInternal(markets = asBF(markets, "ArrayOfInt"),  operation = "cancelBetsByMarket", curlOpts = curlOpts, server = server)
    returnBFOutput(out, output = output, classPostfix = "DF",
                   letMeParseFunc = function(out) bfArrayToDataFrame2(out[["results"]]))
}

##' 
##'
##' bfBetUpdate: Constructor of \code{bfBetUpdate} object. You supply a list of
##' these objects as \code{bets} argument to \code{cancelBets}.
##' @rdname BF_Bet_Placement
##' @param betId The unique identifier for the bet.
##' @param newPrice New odds desired on the bet For BSP Limit on Close bets,
##' newPrice should be set to the new limit desired. For BSP Limit on Close back
##' bets, you can only change the limit downward. For BSP Limit on Close lay
##' bets, you can only change the limit upward.
##' @param oldPrice For an exchange bet, original odds on the bet.
##' @param newSize New stake desired on the bet
##' @param oldSize For an exchange bet, original stake on the bet
##' @param newBetPersistenceType New persistence type on an exchange bet. Only
##' valid before the market turns in-play.
##' @param oldBetPersistenceType Original persistence type on an exchange
##' bet. Only valid before the market turns in-play.
##' @return String of class \code{bfBetUpdate}.
##' @export
bfBetUpdate <- function(betId, newPrice, oldPrice, newSize, oldSize,newBetPersistenceType,  oldBetPersistenceType){
    call <- match.call()
    call[c("betId")] <- c(betId)
    call[[1]] <- as.name("list")
    structure(bfCollapseParams(eval(call, envir = parent.frame(1))), class = "bfBetUpdate")
}

##' 
##'
##' updateBets: Edit multiple (1 to 15) bets on a single Market. The success or
##' failure of the individual bet editing operation is indicated by the Success
##' Boolean. If newPrice and newSize are both specified the newSize value is
##' ignored. For example, an original bet is placed for 100 with odds of 1.5:
##' UpdateBets is called with newSize = 200, newPrice = 2. The original bet is
##' cancelled and a new bet is place for 100 with odds of 2.
##' @rdname BF_Bet_Placement
##' @param bets Can be an \code{bfBetUpdate} object or a list (of max 15) such objects.
##' @param betIds _
##' @param newPrices _
##' @param oldPrices _
##' @param newSizes _
##' @param oldSizes _
##' @param newBetPersistenceTypes _
##' @param oldBetPersistenceTypes _
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Data frame with info on the success of bet updates,  one bet per row.
##' @export
updateBets <- function(bets = list(), betIds, newPrices, oldPrices, newSizes, oldSizes,  newBetPersistenceTypes, oldBetPersistenceTypes,
                       server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    if(is(bets, "bfBetUpdate"))
        bets <- list(bets)
    if(length(bets) && !all(sapply(bets, is, "bfBetUpdate")))
        stop("All elements of 'bets' argument must be of class 'bfBet' as produced by 'bfBet' function.")
    if(!missing(betIds)){
        args <- list(betId = betIds)
        if(!missing(newPrices)) args[["newPrice"]] <- newPrices
        if(!missing(oldPrices)) args[["oldPrice"]] <- oldPrices
        if(!missing(newSizes)) args[["newSize"]] <- newSizes
        if(!missing(oldSizes)) args[["oldSize"]] <- oldSizes
        if(!missing(newBetPersistenceTypes)) args[["newBetPersistenceType"]] <- newBetPersistenceTypes
        if(!missing(oldBetPersistenceTypes)) args[["oldBetPersistenceType"]] <- oldBetPersistenceTypes
        bets <- c(bets, do.call("mapply",  c("bfBetUpdate", args)))
    }
    out <- .bfRequestInternal(bets = asBF(bets, "ArrayOfUpdateBets"), operation = "updateBets", curlOpts = curlOpts, server = server)
    returnBFOutput(out, output = output, classPostfix = "DF",
                   letMeParseFunc = function(out) list(bfArrayToDataFrame2(out[["betResults"]])))
}



#### ACCOUNT MANAGEMENT

##' Various functions to access information about your account and wallets.
##'
##' getAccountFunds: Retrieve information about your local wallet on a
##' particular exchange server. For an explanation of the concept of wallets,
##' see "Using Region-specific Wallets for Placing Bets" on page 12 in Betfair
##' API Developer Documentation.
##' @title Account management.
##' @rdname BF_Acount_Management
##' @aliases >BF_Acount_Management getAccountFunds
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{GetAccountFundsRespSimple} with no extra slots.
##' @author Vitalie Spinu (\email{spinuvit@@gmail.com})
##' @export
##' @seealso \code{\link{betfairly-package}} \code{\link{bfSimpleOutput-class}}
##' @references \url{http://code.google.com/p/betfairly/},  \url{https://docs.developer.betfair.com/betfair/}
getAccountFunds <- function(server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    out <- .bfRequestInternal(operation = "getAccountFunds", curlOpts = curlOpts, server = server)
    returnBFOutput(out, output = output,
                   exclude_info_slots = c("header", "errorCode", "minorErrorCode"))
}


##'
##'
##' getAccountStatement: Obtain information about transactions involving your
##' local wallet on an exchange server.
##' @rdname BF_Acount_Management
##' @param startDate Return records on or after this date.
##' @param endDate Return records on or before this date.
##' @param startRecord The first record number to return (supports
##' paging). Record numbering starts from 0. For example, to retrieve the third
##' record and higher, set startRecord to 2.
##' @param recordCount The maximum number of records to return.
##' @param itemsIncluded Determines what type of statements items to return.
##' @param locale Specify the language for the reply if you want a different language than the account default.
##' @param ignoreAutoTransfers _
##' @param server "GB" (default)  or "AU" - a Betfair exchange server to
##' use. You can set the default with \code{options(bfServer = "AU")}.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Data.frame of class \code{GetAccountStatementRespSimpleDF} with no extra slots.
##' @author Vitalie Spinu (\email{spinuvit@@gmail.com})
##' @export
##' @seealso \code{\link{betfairly-package}} \code{\link{bfSimpleOutput-class}}
##' @references \url{http://code.google.com/p/betfairly/},  \url{https://docs.developer.betfair.com/betfair/}
getAccountStatement <- function(startDate = Sys.Date()-1, endDate = Sys.time(),
                                startRecord = 0, recordCount  = 100, itemsIncluded ="ALL", locale, ignoreAutoTransfers = TRUE,
                                server = getOption("bfServer"), output = getOption("bfOutput"), curlOpts = list()){
    req <- list(startDate = asBFDateTime(startDate), endDate = asBFDateTime(endDate),
                startRecord = startRecord, recordCount = recordCount, itemsIncluded = itemsIncluded
                )
    if(!missing(locale)) req[["locale"]] <- locale
    out <- do.call(.bfRequestInternal, c(req, operation = "getAccountStatement", curlOpts = curlOpts, server = server))
    returnBFOutput(out, output, classPostfix = "DF",
                   letMeParseFunc = function(out) list(bfArrayToDataFrame2(out[["items"]])))
}

##'
##'
##' getSubscriptionInfo: Return information on your API subscription.
##' @rdname BF_Acount_Management
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{getSubscriptionInfo} with no extra slots.
##' @export
getSubscriptionInfo <- function( output = getOption("bfOutput"), curlOpts = list()){
    out <- .bfRequestInternal(operation = "getSubscriptionInfo", curlOpts = curlOpts)
    returnBFOutput(out, output, classPostfix = "DF",
                   letMeParseFunc = function(out) list(bfArrayToDataFrame2(out[["subscriptions"]])))
}



##'
##'
##' transferFunds: Transfer funds between your UK and Australian account
##' wallets. The concept of account wallets has been introduced in release 5.0
##' of the Betfair API. Instead of a single account holding all of a customer's
##' funds for betting on sports events, there are now two "wallets" for each
##' customer's account: one for betting on the UK exchange server and one for
##' betting on the Australian exchange server.
##' @rdname BF_Acount_Management
##' @param amount _
##' @param sourceWalletId 	The wallet that you are requesting the funds to
##' be transferred from. There are two possible wallets: 1 = UK Sports Betting
##' wallet 2 = Australian Sports Betting wallet
##' @param targetWalletId 	The wallet that you are requesting the funds to
##' be transferred from.
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{TransferFundsRespSimple} with no extra slots.
##' @export
transferFunds <- function(amount, sourceWalletId = 1,  targetWalletId = 2,
                          output = getOption("bfOutput"), curlOpts = list()){
    out <- .bfRequestInternal(amount = amount, sourceWalletId = sourceWalletId, targetWalletId = targetWalletId, operation = "transferFunds")
    returnBFOutput(out, output, info_slots = "monthlyDepositTotal")
}

##'
##'
##' viewProfile: Retrieve information about the user account, such as the
##' registered address, e-mail address, phone numbers, etc.
##' @rdname BF_Acount_Management
##' @param output Indicates the form of the returned value. Can be "simple"
##' (default), "xml", "list" or "S4". See \code{\link{betfairly-package}}.
##' @param curlOpts RCurl options passed directly to
##' \code{\link{curlPerform}}. You can also set the defaults with
##' \code{options(bfCurlOpts = list(opt1 = val1, opt2 = val2, ...))}.
##' @return Object of class \code{ViewProfileRespSimple} with not extra slots.
##' @export
viewProfile <- function(output = getOption("bfOutput"), curlOpts = list()){
    out <- .bfRequestInternal(operation = "viewProfile")
    returnBFOutput(out, output, exclude_info_slots = c("header", "errorCode", "minorErrorCode"))
}

## Local Variables:
## ess-roxy-template-alist: (
##  ("description" . "..description")
##  ("details" . "..details")
##  ("title" . "")
##  ("rdname" . "")
##  ("param" . "")
##  ("return" . "Object of class \\code{xxx} containing slot ")
##  ("author" . "Vitalie Spinu (\\email{spinuvit@@gmail.com})")
##  ("export" . "")
##  ("seealso" . "\\code{\\link{betfairly-package}} \\code{\\link{bfSimpleOutput-class}}")
##  ("references" . "\\url{https://docs.developer.betfair.com/betfair/}")
##  )
## end:
vspinu/betfairly documentation built on May 3, 2019, 7:08 p.m.