Thursday, 26 February 2009

BetFair Java API with Apache CXF, Spring and Maven

In this post I present how to login and place a bet on BetFair in Java. Betfair provides a webservice API to get events, markets, place a bet and do many other things. There are several ways to use this API in Java but personally I prefer one of the easiest and quickest of them, which is based on Apache CXF technology.

Apache CXF is a professional open-source Java library to create webservice clients and servers. It generates a webservice java client automatically from a wsdl file, that works very well with BetFair API. Thus calling most of a BetFair operations such a login, getEvents, placeBet is very simple and is just a couple of lines.

The diagram below presents how BetfairService is designed and used in my betting application:

Diagram details:
  • BFGlobalService/BFExchangeService - Betfair webservices generated by Apache CXF. GlobalService contains login operation and others, which don't require logging in. Whereas ExchangeService allows to get market data, place bets, get account information and others, which require user to be logged in.
  • BettingServiceImpl - BetFair Facade, that simplifies access to the BetFair operations from a BettingEngine.
  • BettingEngine - Module of my application responsible for executing betting strategies.
How to login to a Betfair account?


The login operation is provided by a BFGlobalService. To login to a Betfair account three parameters are required: user, password and productId. For Betfair free API the productId is 82.
//Login to a BetFair account.
//
public void login(String userName, String password, int productId) {

//Creating login command which contains all login parameters.
LoginReq req = new LoginReq();
req.setUsername(userName);
req.setPassword(password);
req.setProductId(productId);
req.setLocationId(0);
req.setVendorSoftwareId(0);

//Calling BetFair webservice login operaton.
LoginResp resp = globalWebService.login(req);

//Checking login result and storing session token, which is necessary to call BFExchangeService operations, e.g. getMarkets, placeBet.
if (resp.getErrorCode().equals(LoginErrorEnum.OK))
{
state.setSessionToken(resp.getHeader(). getSessionToken());
} else {
throw new BetFairException("Login error. Error code: " + resp.getErrorCode() + ", api code: "
+ resp.getHeader().getErrorCode());
}
}

How to place a bet?


The placeBet operation is provided by a BFExchangeService. There are many different bet types available. This example show how to place a back/lay bet on a betting exchange. The code snippet below presents a placeBet method with parameters:
  • marketId/selectionId - Which market runner the bet is placed on, e.g. draw in a football match, tennis player in a tennis match or horse in a horse race.
  • betType - Back or lay , e.g. back bet means that something will happen, e.g. draw in a football match, lay means that it will not happen, e.g. tennis player will not win the match.
  • betCategory - Exchange or SP(starting price) bet.
  • price - Binary odds of a bet, e.g. 2.0
  • size - Stake of a bet, e.g. 20 dollars.
//Place a bet on a BetFair
//betting exchange.
public void placeBet(int marketId, int selectionId, BetTypeEnum betType, BetCategoryTypeEnum betCategory,
double price, double size) {

//Creating request header with a session token returned by login operation.
APIRequestHeader requestHeader = new APIRequestHeader();
requestHeader.setSessionToken(sessionToken);

//Creating placeBet command, which contains all required parameters.
PlaceBetsReq req = new PlaceBetsReq();
req.setHeader(requestHeader);

ArrayOfPlaceBets arrayOfBets = new ArrayOfPlaceBets();
PlaceBets placeBets = new PlaceBets();
placeBets.setAsianLineId(0);
placeBets.setBetCategoryType(betCategory);
placeBets.setPrice(price);
placeBets.setSize(size);
placeBets.setBspLiability(0d);
placeBets.setBetPersistenceType( BetPersistenceTypeEnum.NONE);
placeBets.setBetType(betType);
placeBets.setMarketId(marketId);
placeBets.setSelectionId(selectionId);
arrayOfBets.getPlaceBets().add(placeBets);
req.setBets(arrayOfBets);

//Calling placeBet operation on a BetFair webservice.
PlaceBetsResp resp = exchangeWebService.placeBets(req);
if (resp.getErrorCode().equals(...) {
//Checking placing bet result.
}
}

How to generate BFGlobal and BFExchange services with Maven and cxf-codegen-plugin?

Because my betting tool uses a Maven build system, I use a cxf-codegen-plugin to generate java classes for BetFair webservices. There are two plugin executions to generate java classes for BFGlobal and BFExchange services. Java classes are generated from the wsdl files. See lines 17 and 37.


org.apache.cxf
cxf-codegen-plugin
2.0.5-incubator



generate-sources_BFGlobalService
generate-sources


${basedir}/target/generated-sources/src/main/ java




${basedir}/src/main/wsdl/ BFGlobalService.wsdl





wsdl2java




generate-sources_BFExchangeService
generate-sources


${basedir}/target/generated-sources/src/main/ java




${basedir}/src/main/wsdl/ BFExchangeService.wsdl





wsdl2java





How to configure BFGlobal and BFExchange services with Spring?

The BFGlobal and BFExchange services are created by a JaxWsProxyFactory bean, which is configured using the class name of generated webservice and the url of a BetFair webservice. Afterwards BetFair services are injected into a BetFair facade, which is used by my betting application.




 




 
 






 
 





Resources

References
Bye,
Daniel

28 comments:

  1. sounds great. let us know how much have you won :D

    I put 50 euros in my Betfair account and I managed to lose them in 2 hours :D

    ReplyDelete
  2. Hi,

    I started about one year agou with a balance of 200 pounds. My current balance about 1300 pounds.I'm placing bets on a minumim stake of 2 pounds. Currently the profit per week is between 40 and 100 pounds.

    Bye.
    Jessica

    ReplyDelete
  3. Hi,

    Thanks a lot for this great blog !
    Anyway, I don't know the class LoginReq. Is it a BetFair class ?
    And what is the globalWebService variable ?

    Moreover, I'm curious, like Dracula, on your winnings.
    On what kind of market are you betting ?

    Christophe

    ReplyDelete
  4. Keep going Jessica - blogging about this stuff is hard work, but even though you only have two entries, you have gathered some attention!

    ReplyDelete
  5. Interesting... Love your first post. I'm thinking of doing the same thing - in C# though. But looking at how nice and clean your Java code looks I might just switch to Java. I am already looking forward to your next post.
    One question though, why Spring? Can you not just have a main(...) function and create objects/beans which spring is instantiating in there instead?

    ReplyDelete
  6. Hello,

    Thanks to everyone for interest. I'm currently working on the next post about: "Betting with Eclipse BIRT Business Intelligence". Should be published in 2 weeks.

    Why I use Spring?

    To create a simple Java app to place some bets we can have a main() method and manage our beans/components ourselves but when:

    The application is growing and growing then Spring is a great technology to organize all beans, manage dependencies, transactions, database access. My app currently has many modules, and beans, that's why I use Spring. The list below presents some of the modules I have, which are organized as beans in my Spring application (Now you should understand better why Spring:))

    Betapi (betfair,bwin,oddschecker), Commons(cache, domain,utils), Dao, Services(VirtualBettingExchange,marketsService, runnersService, birtReports, stateMachine), Tasks, Web console

    I will be writing about all these stuff in next weeks, months...

    Bye,
    Jessica

    ReplyDelete
  7. I didn't know that bwin and oddschecker propose an API. Do you plan articles here on them ?

    ReplyDelete
  8. Hi Guizmo,

    There is no official BWin or OddsChecker API, I created it myself. I will write about it in a future or even I will publish it on the internet.

    ReplyDelete
  9. There also cheap software for mining the web like Unit miner for example http://www.qualityunit.com/unitminer/

    ReplyDelete
  10. It sounds good what you are doing.
    I was scalping horseraces on betFair using betTrader and after 1 week i felt tired to do that for long hours. I ask my self why dont try to create a full automated scalping system which can do the job.
    I was searching over racingtraders forum and found your blog and your post abount automated betting exchange.
    I was pretty sure it is possible to generate profit using full automated scalping systems like arbitrage systems used in financial institutions.
    As a java developer in finance for 5 years I decided to try to write some code to try this idea.
    It will be very pleasure for me if we can change some ideas about that.

    ReplyDelete
  11. Hi Shark,

    Read my next two posts and you should have a better idea about my automated betting.

    If you have any questions feel free to ask.

    Bye,
    Jessica

    ReplyDelete
  12. Hi Jessica

    DO you have an api for C# developers?

    Regards
    Tom

    ReplyDelete
  13. I'm sorry but I have BetFair JAVA API only.

    ReplyDelete
  14. Jessica, are you building up data as you go along or just looking at the one-off race situation; and odds.

    ReplyDelete
  15. Hi Paul,

    I use both of them, it depends on a type of trading. Usually I use historical data for betting/trading before market start time. When market is in play then I use mostly the recent data.

    ReplyDelete
  16. Hi Jessica

    Im using the betfair API from java and would
    like to place a Market On Close Back Bet.
    but have been unable to do so.

    I have successfully placed Exchange Back Bets
    from my code but whenever I try a MOC bet I
    get an INVALID_SIZE error even though Im
    betting more than the minimum.

    Im unsure what I should be setting the price
    to for a MOC bet. Im setting the betCatgeoryType to M

    betfairBet.setBetCategoryType(BetCategoryTypeEnum.M);

    Do you know what Im doing wrong. Any advice gratefully recived. in the meantime I will keep
    looking at the manual :-)

    I found your code snippets useful.
    Thanks
    Rich

    ReplyDelete
  17. Hi,

    I had the same issue. This is what I'm using for MOC bets. As I remember the key thing is to set the size to 0. I hope it's useful for You.

    placeBets.setPrice(validatedLimit); //0 for MoC, limit for LoC.
    placeBets.setBspLiability(liability);
    placeBets.setSize(0d);
    placeBets.setBetType(betType);
    placeBets.setMarketId(marketId);
    placeBets.setSelectionId(selectionId);

    Regards,
    Jessica

    ReplyDelete
  18. Hi
    That did the trick!
    Thank you Jessica.

    ReplyDelete
  19. I recently came across your post and have been reading along. I thought I would leave my first comment. I don't know what to say except that it caught my interest and you've provided informative points. I will visit this blog often.

    Thank you,

    Business Loans

    ReplyDelete
  20. Marco Costantini7 April 2012 07:58

    Under "How to generate BFGlobal and BFExchange services with Maven and cxf-codegen-plugin?" I cannot see the code, just some words. I guess there is code because you refer to "lines 17 and 37", is it possible to fix the problem?

    ReplyDelete
  21. Marco Costantini7 April 2012 10:20

    Sorry I've just realized that you put online the java API for betfair. Many of them do imports of libraries that I don't have (apache, spring) where can I find the libraries they need? Thanks

    ReplyDelete
  22. If you use maven, then all required libraries will be downloaded automatically. At the http://code.google.com/p/betfair-api/ home page there are details on maven repository as well as an example integration test, demonstrating how to use this api.

    If you don't know maven (or you don't want to use it), you have two options:
    - download all dependencies manually from the internet, e.g. from apache cxf home page or spring home page.

    - Install maven and then in the betfair-api trunk directory call mvn clean install. This will download all required dependencies to local maven repo.

    How to use this API:
    With Spring: http://code.google.com/p/betfair-api/source/browse/trunk/src/test/java/dk/bot/betfairservice/BetFairServiceImplIntegrationTest.java

    Without spring:
    Simply create an object of this factory:
    http://code.google.com/p/betfair-api/source/browse/trunk/src/main/java/dk/bot/betfairservice/DefaultBetFairServiceFactoryBean.java

    then set user,pass and product Id, call login and finally call getObject factory method, which returns configured api object.

    ReplyDelete
  23. hi Daniel,

    i feel a little confused. i'm a java developer, but i'm not so confident with maven.

    i've eclipse indigo. what exactly i have to do to intall your package correctly?

    could you be a little more precise?

    it's 1 hour i'm trying to set up the environment and i'm not able :(

    ReplyDelete
  24. Look at my comment above yours one. It may help, if not then please ask some precise questions. Unfortunately I don't have enough time to write detailed user guide, but others managed to use this api, so keep trying.

    If you know maven then it's simple, add maven repository and dependency:
    ...

    dk.flexibet
    flexibet-betfair
    0.7

    ...

    ...

    dk-maven2-repo-releases
    dk-maven2 maven repository (releases)
    http://dk-maven2-repo.googlecode.com/svn/maven-repo/releases


    ...

    and then use API as explained in my comment above.

    Eventually, download betfair-api 0.7 from http://code.google.com/p/betfair-api/downloads/list, but then you will need to get all required dependencies from the internet yourself.

    Good luck.

    ReplyDelete
  25. hi Daniel!
    i'm still trying, i don't know how to checkout your project using maven.

    i mean i've been using subclipse in eclipse for versioning of my projects and i know more or less how it works..

    but when it comes to maven internet doesn't help you so much..

    do i have to create a java project and then do a kind of maven checkout of your project?

    i think i just need some directions to make it happen ehehehe

    have a nice weekend ;)

    ReplyDelete
  26. To learn on maven start with,
    http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html

    ReplyDelete
  27. Great side and code, however the downfall to most potentially awesome projects is the documentation. Getting your code to run is especially troublesome (spring + maven are horrendous IMHO).

    Are you able to produce a tutorial that shows how to checkout your code and get it running in eclipse + run the tests?

    Thanks

    ReplyDelete
  28. I'm sorry but I don't have enough time for that. That's all I can do for you:

    1)Checkout this project from subversion: http://code.google.com/p/betfair-api/

    2)Call mvn eclipse:clean eclipse:eclipse - it will generete eclipse project files. (install maven for this step)

    3)Import project into Eclipse

    4)Set system properties: bfUser, bfPassword and bfProductId

    5)Run unit test with examples: http://code.google.com/p/betfair-api/source/browse/trunk/src/test/java/dk/bot/betfairservice/BetFairServiceImplIntegrationTest.java

    No Spring knowledge is required. Just Java, Maven and Eclipse.

    ReplyDelete