em-betfair 0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile +8 -0
  3. data/README.md +47 -0
  4. data/Rakefile +1 -0
  5. data/em-betfair.gemspec +25 -0
  6. data/examples/scrape_betfair.rb +88 -0
  7. data/lib/em-betfair/betfair_client.rb +126 -0
  8. data/lib/em-betfair/response.rb +41 -0
  9. data/lib/em-betfair/response_parser.rb +135 -0
  10. data/lib/em-betfair/soap_renderer.rb +29 -0
  11. data/lib/em-betfair/views/exchange/get_all_markets.haml +23 -0
  12. data/lib/em-betfair/views/exchange/get_market.haml +12 -0
  13. data/lib/em-betfair/views/exchange/get_market_prices_compressed.haml +12 -0
  14. data/lib/em-betfair/views/exchange/get_market_traded_volume_compressed.haml +12 -0
  15. data/lib/em-betfair/views/global/get_all_event_types.haml +12 -0
  16. data/lib/em-betfair/views/global/login.haml +11 -0
  17. data/lib/em-betfair/views/global/retrieve_limb_message.haml +9 -0
  18. data/lib/em-betfair/views/global/submit_limb_message.haml +14 -0
  19. data/lib/em-betfair.rb +4 -0
  20. data/spec/functional/betfair_client_spec.rb +149 -0
  21. data/spec/remote/betfair_client_spec.rb +69 -0
  22. data/spec/spec_helper.rb +17 -0
  23. data/spec/support/canned_responses/get_all_markets.xml +18 -0
  24. data/spec/support/canned_responses/get_all_markets_no_session.xml +18 -0
  25. data/spec/support/canned_responses/get_market.xml +3 -0
  26. data/spec/support/canned_responses/get_market_prices_compressed.xml +18 -0
  27. data/spec/support/canned_responses/get_market_traded_volume_compressed.xml +20 -0
  28. data/spec/support/canned_responses/login_failed.xml +19 -0
  29. data/spec/support/canned_responses/login_ok.xml +19 -0
  30. data/spec/support/canned_responses/soap_fault.xml +9 -0
  31. data/spec/unit/response_parser_spec.rb +45 -0
  32. metadata +143 -0
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ Gemfile.lock
3
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gem "eventmachine"
5
+ gem "em-http-request"
6
+ gem "rspec"
7
+ gem "haml"
8
+ gem "nokogiri"
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Betfair API client using Eventmachine and EM-Http
2
+
3
+ em-betfair is a work in progress evented client for the Betfair API. The following API calls have been implemented :
4
+
5
+ - login
6
+ - getMarket
7
+ - getAllMarkets
8
+ - getMarketPricesCompressed
9
+ - getMarketTradedVolumeCompressed
10
+
11
+ # Usage
12
+
13
+ gem install em-betfair
14
+
15
+ gem "em-betfair", "~> 0.1"
16
+
17
+ Create an instance of the client
18
+
19
+ config = {
20
+ "username" => "<YOUR BETFAIR USERNAME>",
21
+ "password" => "<YOUR BETFAIR PASSWORD>",
22
+ "product_id" => "<YOUR BETFAIR PRODUCTID>",
23
+ "exchange_endpoint" => "https://api.betfair.com/exchange/v5/BFExchangeService",
24
+ "global_endpoint" => "https://api.betfair.com/global/v3/BFGlobalService"
25
+ }
26
+ bf_client = Betfair::Client.new(config)
27
+
28
+ Making a call to the API:
29
+
30
+ EM::run {
31
+ bf_client.get_all_markets do |rsp|
32
+
33
+ rsp.raw_response # access the raw response body
34
+ rsp.parsed_response # access the Nokogiri XML object of the raw response
35
+ rsp.hash_response # access a hash of the response data
36
+
37
+ rsp.successfull # boolean for success
38
+ rsp.error # API error messge if not successfull
39
+
40
+ end
41
+ }
42
+
43
+ Note, logging in to the API is handled internally by the client.
44
+
45
+ # Ruby versions
46
+
47
+ Tested on 1.9.2 but should work on 1.8.7 too.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "em-betfair"
5
+ s.version = "0.2"
6
+ s.authors = ["George Sheppard"]
7
+ s.email = ["george@fuzzmonkey.co.uk"]
8
+ s.homepage = "https://github.com/fuzzmonkey/em-betfair"
9
+ s.summary = %q{Betfair API client using Eventmachine and EM-Http}
10
+ s.description = %q{em-betfair is a work in progress evented client for the Betfair API}
11
+
12
+ s.rubyforge_project = "em-betfair"
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_development_dependency "rspec"
20
+ s.add_runtime_dependency "eventmachine"
21
+ s.add_runtime_dependency "em-http-request"
22
+ s.add_runtime_dependency "haml"
23
+ s.add_runtime_dependency "nokogiri"
24
+
25
+ end
@@ -0,0 +1,88 @@
1
+ # Example script to scrape the Betfair API for prices and store them in redis as json strings.
2
+
3
+ # WARNING - Beware of the Betfair data usage limits!!!
4
+
5
+ require 'eventmachine'
6
+ require 'em-betfair'
7
+ require 'date'
8
+ require 'time'
9
+ require 'redis'
10
+ require 'json'
11
+
12
+ # Not requiring activesupport just to get ordanalize
13
+ class Fixnum
14
+ def ordinalize
15
+ if (11..13).include?(self % 100)
16
+ "#{self}th"
17
+ else
18
+ case self % 10
19
+ when 1; "#{self}st"
20
+ when 2; "#{self}nd"
21
+ when 3; "#{self}rd"
22
+ else "#{self}th"
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ EM::run {
29
+
30
+ config = {
31
+ "username" => "<YOUR BETFAIR USERNAME>",
32
+ "password" => "<YOUR BETFAIR PASSWORD>",
33
+ "product_id" => "<YOUR BETFAIR PRODUCTID>",
34
+ "exchange_endpoint" => "https://api.betfair.com/exchange/v5/BFExchangeService",
35
+ "global_endpoint" => "https://api.betfair.com/global/v3/BFGlobalService"
36
+ }
37
+
38
+ bf_client = Betfair::Client.new(config)
39
+ redis_client = Redis.new
40
+ timers = {}
41
+ num_timers = 0
42
+
43
+ # Fetch all the horse racing markets in the UK for today
44
+ bf_client.get_all_markets ["GBR"], [7], "#{Date.today} 00:00:00", "#{Date.today} 23:59:00" do |response|
45
+
46
+ response.hash_response["market_data"].each do |market_id,market_hash|
47
+
48
+ menu_path = market_hash["menu_path"]
49
+ track_name = menu_path.match(/\\.+\\.+\\(\w+\s{0,1}\w*)/)[1]
50
+
51
+ # Lets just fetch the 'real' markets rather than AvB, Antepost, Place etc
52
+ next unless track_name && !market_hash["name"].match(/To Be Placed/) && !menu_path.match(/ANTEPOST/) && !menu_path.match(/Forecast/) && track_name.match(/#{Date.today.day.ordinalize}/)
53
+
54
+ # Fetch the runners
55
+ bf_client.get_market market_id do |market_response|
56
+ market_details = market_response.hash_response
57
+ puts "Got market #{market_id} #{track_name} #{market_hash["name"]} #{Time.parse(market_details["market_time"])}"
58
+ runners = market_details["runners"]
59
+
60
+ # If the market is active, setup some periodical timers
61
+ next unless market_details["status"] == "ACTIVE"
62
+
63
+ # would be nice to get the data from getSilks here
64
+ redis_client.hset track_name, market_hash["name"], {"market_details" => market_details, "prices" => nil}.to_json
65
+
66
+ next if num_timers > 59 # free API restriction
67
+
68
+ # Update the odds every 60 seconds
69
+ timers[market_id] = EventMachine::PeriodicTimer.new(60) do
70
+ num_timers += 1
71
+ bf_client.get_market_prices_compressed market_id do |prices_response|
72
+ puts "Fetching prices for #{market_id}"
73
+ price_data = prices_response.hash_response
74
+ timers[market_id].cancel if timers[market_id] && price_data["status"] != "ACTIVE"
75
+ race = redis_client.hget track_name, market_hash["name"]
76
+ race_hash = JSON.parse(race)
77
+ race_hash["prices"] = price_data
78
+ redis_client.hset track_name, market_hash["name"], race_hash.to_json
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+
88
+ }
@@ -0,0 +1,126 @@
1
+ require 'uri'
2
+ require 'em-http'
3
+ require 'nokogiri'
4
+ #require 'tzinfo'
5
+
6
+ module Betfair
7
+
8
+ BETFAIR_TIME_ZONES = {"RSA"=>"Africa/Johannesburg", "AST"=>"US/Arizona", "MST"=>"US/Mountain", "JPT"=>"Japan", "HK"=>"Hongkong", "GMT"=>"GMT", "PKT"=>"Etc/GMT-5", "UAE"=>"Asia/Dubai", "CST"=>"US/Central", "AKST"=>"US/Alaska", "BRT"=>"Brazil/East", "INT"=>"Asia/Calcutta", "SMT"=>"America/Santiago", "MSK"=>"Europe/Moscow", "AWST"=>"Australia/Perth", "PST"=>"US/Pacific", "EST"=>"US/Eastern", "KMT"=>"Jamaica", "CET"=>"CET", "ANST"=>"Australia/Darwin", "ACST"=>"Australia/Adelaide", "NZT"=>"NZ", "UKT"=>"Europe/London", "AMT"=>"Brazil/West", "THAI"=>"Asia/Bangkok", "SJMT"=>"America/Costa_Rica", "HST"=>"US/Hawaii", "EET"=>"EET", "AEST"=>"Australia/Sydney", "IEST"=>"America/Indiana/Indianapolis", "AQST"=>"Australia/Queensland"}
9
+
10
+ class Client
11
+
12
+ attr_accessor :session_token
13
+
14
+ # config - hash of betfair credentials & API endpoints
15
+ # { "username" => "<YOUR BETFAIR USERNAME>", "password" => "<YOUR BETFAIR PASSWORD>", "product_id" => "<YOUR BETFAIR PRODUCTID>", "exchange_endpoint" => "https://api.betfair.com/exchange/v5/BFExchangeService", "global_endpoint" => "https://api.betfair.com/global/v3/BFGlobalService" }
16
+ def initialize config
17
+ @config = config
18
+ @session_token = nil
19
+ end
20
+
21
+ # Creates a session on the Betfair API, used by Betfair::Client internally to maintain session.
22
+ def login &block
23
+ build_request "global", "login", {"username" => @config["username"], "password" => @config["password"], "product_id" => @config["product_id"]}, block
24
+ end
25
+
26
+ # Returns all the available markets on Betfair.
27
+ #
28
+ # countries - array of ISO 3166-1 country codes
29
+ # event_type_ids - array of Betfair event ids
30
+ # to_date - DateTime
31
+ # from_date - DateTime
32
+ def get_all_markets countries=nil, event_type_ids=nil, to_date=nil, from_date=nil, &block
33
+ with_session do
34
+ build_request "exchange", "get_all_markets", {"countries" => countries, "event_type_ids" => event_type_ids, "to_date" => to_date, "from_date" => from_date}, block
35
+ end
36
+ end
37
+
38
+ # Returns the details of a specifc market
39
+ #
40
+ # market_id - Betfair market ID
41
+ def get_market market_id, &block
42
+ with_session do
43
+ build_request "exchange", "get_market", {"market_id" => market_id }, block
44
+ end
45
+ end
46
+
47
+ # Returns the compressed market prices
48
+ #
49
+ # market_id - Betfair market ID
50
+ # currency_code - three letter ISO 4217 country code
51
+ def get_market_prices_compressed market_id, currency_code=nil, &block
52
+ with_session do
53
+ build_request "exchange", "get_market_prices_compressed", {"market_id" => market_id, "currency_code" => currency_code}, block
54
+ end
55
+ end
56
+
57
+ # Returns the compressed traded volumes
58
+ #
59
+ # market_id - Betfair market ID
60
+ # currency_code - three letter ISO 4217 country code
61
+ def get_market_traded_volume_compressed market_id, currency_code=nil, &block
62
+ with_session do
63
+ build_request "exchange", "get_market_traded_volume_compressed", {"market_id" => market_id, "currency_code" => currency_code}, block
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ # Builds the EM::Http request object
70
+ #
71
+ # service_name - the endpoint to use (exchange or global)
72
+ # action - the API method to call on the API
73
+ # data - hash of parameters to populate the SOAP request
74
+ # block - the ballback for this request
75
+ def build_request service_name, action, data={}, block
76
+ request_data = { :data => data.merge!({"session_token" => @session_token}) }
77
+ soap_req = Betfair::SOAPRenderer.new( service_name, action ).render( request_data )
78
+ url = get_endpoint service_name
79
+ headers = { 'SOAPAction' => action, 'Accept-Encoding' => 'gzip,deflate', 'Content-type' => 'text/xml;charset=UTF-8' }
80
+ req = EventMachine::HttpRequest.new(url).post :body => soap_req, :head => headers
81
+ req.errback { block.call(Response.new(nil,nil,false,"Error connecting to the API")) }
82
+ req.callback { parse_response(req.response,block) }
83
+ end
84
+
85
+ # Parses the API response, building a response object
86
+ #
87
+ # raw_rsp - response body from EM:Http request
88
+ # block - callback for this request
89
+ def parse_response raw_rsp, block
90
+ parsed_response = Nokogiri::XML raw_rsp
91
+
92
+ soap_fault = parsed_response.xpath("//faultstring").first
93
+ if soap_fault
94
+ block.call(Response.new(raw_rsp,parsed_response,false,soap_fault.text))
95
+ return
96
+ end
97
+
98
+ api_error = parsed_response.xpath("//header/errorCode").text
99
+ method_error = parsed_response.xpath("//errorCode").last.text
100
+
101
+ error_rsp = api_error == "OK" ? method_error : api_error
102
+ unless api_error == "OK" && method_error == "OK"
103
+ @session_token = nil if [api_error,method_error].include?("NO_SESSION") # so we try and login on the next request
104
+ block.call(Response.new(raw_rsp,parsed_response,false,error_rsp))
105
+ return
106
+ end
107
+
108
+ @session_token = parsed_response.xpath("//sessionToken").text
109
+
110
+ block.call Response.new(raw_rsp,parsed_response,true)
111
+ end
112
+
113
+ def with_session
114
+ yield unless @session_token.nil?
115
+ login do |response|
116
+ yield
117
+ end
118
+ end
119
+
120
+ def get_endpoint service_name
121
+ return @config["#{service_name}_endpoint"]
122
+ end
123
+
124
+ end
125
+
126
+ end
@@ -0,0 +1,41 @@
1
+ # Stolen from Rails 3
2
+ def underscore(camel_cased_word)
3
+ camel_cased_word.to_s.gsub(/::/, '/').
4
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
5
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
6
+ tr("-", "_").
7
+ downcase
8
+ end
9
+
10
+ module Betfair
11
+
12
+ class Response
13
+ include ResponseParser
14
+
15
+ attr_accessor :raw_response # response string
16
+ attr_accessor :parsed_response # response xml
17
+ attr_accessor :successfull
18
+ attr_accessor :error
19
+
20
+ def initialize raw, parsed, successfull, error=""
21
+ @raw_response = raw
22
+ @parsed_response = parsed
23
+ @successfull = successfull
24
+ @error = error
25
+ end
26
+
27
+ # lazy loaded
28
+ def hash_response
29
+ method = get_response_type
30
+ self.send method.to_sym, self.parsed_response if method && self.respond_to?(method)
31
+ end
32
+
33
+ def get_response_type
34
+ return nil unless self.parsed_response.respond_to?(:xpath)
35
+ response_type = self.parsed_response.xpath("//ns:Envelope/ns:Body", "ns" => "http://schemas.xmlsoap.org/soap/envelope/").first.elements.first.name
36
+ underscore(response_type.gsub("Response",""))
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,135 @@
1
+ module Betfair
2
+
3
+ # TODO - version this to handle changes in the API
4
+ # TODO - this might be nicer as a structs style setup. e.g
5
+ # markets_rsp = GetAllMarkets.new(parsed_response)
6
+ module ResponseParser
7
+
8
+ # TODO - handle timezones, return local & utc time
9
+ # tz = TZInfo::Timezone.get(new_time_zone)
10
+ # race_time = tz.utc_to_local(race_time)
11
+
12
+ # TODO - return values as proper types rather than strings
13
+
14
+ def login xml
15
+ {"currency" => xml.xpath("//currency").text}
16
+ end
17
+
18
+ def get_all_markets xml
19
+ market_data = xml.xpath("//marketData").text
20
+ all_markets_hash = {"market_data" => {}}
21
+ market_data.split(":").each do |market|
22
+ market_fields = market.split("~")
23
+ next unless market_fields.size >= 16 #incase they append more fields
24
+ market_hash = {}
25
+ market_hash["id"] = market_fields[0]
26
+ market_hash["name"] = market_fields[1]
27
+ market_hash["type"] = market_fields[2]
28
+ market_hash["status"] = market_fields[3]
29
+ market_hash["date"] = Time.at(market_fields[4].to_i/1000).utc #Epoc time
30
+ market_hash["menu_path"] = market_fields[5]
31
+ market_hash["event_hierarchy"] = market_fields[6]
32
+ market_hash["bet_delay"] = market_fields[7]
33
+ market_hash["exchange_id"] = market_fields[8]
34
+ market_hash["country_code"] = market_fields[9]
35
+ market_hash["last_refresh"] = Time.at(market_fields[10].to_i/1000).utc #Epoc time
36
+ market_hash["num_runners"] = market_fields[11]
37
+ market_hash["num_winners"] = market_fields[12]
38
+ market_hash["total_amount_matched"] = market_fields[13]
39
+ market_hash["bsp_market"] = market_fields[14] == "Y"
40
+ market_hash["turning_in_play"] = market_fields[15] == "Y"
41
+
42
+ all_markets_hash["market_data"][market_fields[0]] = market_hash
43
+ end
44
+ all_markets_hash
45
+ end
46
+
47
+ def get_market xml
48
+ market_hash = {}
49
+ market_hash["id"] = xml.xpath("//market/marketId").text
50
+ market_hash["status"] = xml.xpath("//market/marketStatus").text
51
+ market_hash["parent_id"] = xml.xpath("//market/parentEventId").text
52
+ market_hash["country_code"] = xml.xpath("//market/countryISO3").text
53
+ market_hash["event_type"] = xml.xpath("//market/eventTypeId").text
54
+ market_hash["base_rate"] = xml.xpath("//market/marketBaseRate").text
55
+ market_hash["market_name"] = xml.xpath("//market/name").text
56
+ market_hash["num_winners"] = xml.xpath("//market/numberOfWinners").text
57
+ market_hash["market_time"] = xml.xpath("//market/marketTime").text
58
+
59
+ market_hash["runners"] = []
60
+
61
+ xml.xpath("//runners").children.each do |xml_runner|
62
+ name = xml_runner.xpath("name").text
63
+ selection_id = xml_runner.xpath("selectionId").text
64
+ market_hash["runners"].push({"selection_id" => selection_id, "name" => name})
65
+ end
66
+
67
+ market_hash
68
+ end
69
+
70
+ def get_market_prices_compressed xml
71
+ prices_hash = {}
72
+ prices = xml.xpath("//marketPrices").text
73
+ # Betfair uses colons as a seperator and escaped colons as a different seperator, grr.
74
+ # [1..-1] removes the first empty string
75
+ prices_data = prices.gsub('\:', 'ECSCOLON')[1..-1].split(":")
76
+
77
+ header_data = prices_data.slice!(0).gsub("ECSCOLON",":").split("~")
78
+
79
+ # TODO - parse removed runners properly
80
+ ["market_id","currency","status","in_play_delay","num_winners","market_info","discount_allowed","market_base_rate","refresh_time","removed_runners","bsp_market"].each_with_index do |field,index|
81
+ prices_hash[field] = header_data.at(index)
82
+ end
83
+
84
+ prices_data.each do |runner|
85
+ runner_hash = {}
86
+ runner_info, lay_prices, back_prices = runner.split("|")
87
+ runner_data = runner_info.split("~")
88
+
89
+ ["selection_id","order_index","total_matched","last_price_matched","handicap","reduction_factor","vacant","asian_line_id","far_sp_price","near_sp_price","actual_sp_price"].each_with_index do |field,index|
90
+ runner_hash[field] = runner_data.at(index)
91
+ end
92
+
93
+ runner_hash["lay_prices"] = []
94
+ lay_prices.split("~").each_slice(4) do |prices|
95
+ runner_hash["lay_prices"].push({"odds" => prices[0], "amount" => prices[1], "type" => prices[2], "depth" => prices[3]})
96
+ end
97
+
98
+ runner_hash["back_prices"] = []
99
+ back_prices.split("~").each_slice(4) do |prices|
100
+ runner_hash["back_prices"].push({"odds" => prices[0], "amount" => prices[1], "type" => prices[2], "depth" => prices[3]})
101
+ end
102
+
103
+ prices_hash[runner_hash["selection_id"]] = runner_hash
104
+ end
105
+ prices_hash
106
+ end
107
+
108
+ def get_market_traded_volume_compressed xml
109
+ traded_volumne_hash = {}
110
+ traded = xml.xpath("//tradedVolume").text
111
+ market_id = xml.xpath("//marketId").text
112
+ currency = xml.xpath("//currencyCode").text
113
+ # Betfair uses colons as a seperator and escaped colons as a different seperator, grr.
114
+ # [1..-1] removes the first empty string
115
+ traded_data = traded.gsub(/\\:/, "ECSCOLON")[1..-1].split(":")
116
+ traded_data.each do |runner|
117
+ # TODO - replace ECSCOLON with :
118
+ runner_hash = {"traded_amounts" => []}
119
+ runner_data = runner.split("|")
120
+ header_data = runner_data.slice!(0).split("~")
121
+ ["selection_id", "asian_line_id", "bsp", "total_bsp_back_matched", "total_bsp_liability_matched"].each_with_index do |field,index|
122
+ runner_hash[field] = header_data.at(index)
123
+ end
124
+ runner_data.each do |traded_amount|
125
+ odds, total_matched = traded_amount.split("~")
126
+ runner_hash["traded_amounts"].push({"odds" => odds, "total_matched" => total_matched})
127
+ end
128
+ traded_volumne_hash[runner_hash["selection_id"]] = runner_hash
129
+ end
130
+ traded_volumne_hash
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,29 @@
1
+ require 'haml'
2
+ require 'pathname'
3
+
4
+ module Betfair
5
+
6
+ # Utility class to render a SOAP request from a haml file, embedding data
7
+ # elements as necessary
8
+ class SOAPRenderer
9
+
10
+ def initialize service, soap_name
11
+ base = Pathname.new(__FILE__).realpath.parent
12
+ file = "#{base}/views/#{service}/#{soap_name}.haml"
13
+ unless File.exists?( file )
14
+ $log.error "Cannot find HAML: #{file}" unless $log.nil?
15
+ raise "Cannot find HAML: #{file}"
16
+ end
17
+ @engine = Haml::Engine.new( File.read( file ) ) # this is quite expensive, might be better to keep a hash of renderers
18
+ end
19
+
20
+ def render content
21
+ content.each do |key,value|
22
+ self.instance_variable_set( "@#{key}", value )
23
+ end
24
+ @engine.render( self )
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,23 @@
1
+ %soapenv:Envelope{ "xmlns:soapenv"=> "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:bfex"=>"http://www.betfair.com/publicapi/v5/BFExchangeService/", "xmlns:v5" => 'http://www.betfair.com/publicapi/types/exchange/v5/' }
2
+ %soapenv:Header
3
+ %soapenv:Body
4
+ %bfex:getAllMarkets
5
+ %bfex:request
6
+ %header
7
+ - if @data["client_stamp"]
8
+ %clientStamp= @data["client_stamp"]
9
+ %sessionToken= @data["session_token"]
10
+ - if @data["locale"]
11
+ %locale= @data["locale"]
12
+ - if @data["event_type_ids"]
13
+ %eventTypeIds
14
+ - @data["event_type_ids"].each do |event_id|
15
+ %int=event_id
16
+ - if @data["countries"]
17
+ %countries
18
+ - @data["countries"].each do |cc|
19
+ %Country= cc
20
+ - if @data["from_date"]
21
+ %fromDate= @data["from_date"]
22
+ - if @data["to_date"]
23
+ %toDate= @data["to_date"]
@@ -0,0 +1,12 @@
1
+ %soapenv:Envelope{"xmlns:soapenv" => "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:bfex" => "http://www.betfair.com/publicapi/v5/BFExchangeService/" }
2
+ %soapenv:Header
3
+ %soapenv:Body
4
+ %bfex:getMarket
5
+ %bfex:request
6
+ %header
7
+ - if @data["client_stamp"]
8
+ %clientStamp= @data["client_stamp"]
9
+ %sessionToken= @data["session_token"]
10
+ - if @data["locale"]
11
+ %locale= @data["locale"]
12
+ %marketId= @data["market_id"]
@@ -0,0 +1,12 @@
1
+ %Envelope{ "xmlns:bfex" => 'http://www.betfair.com/publicapi/v5/BFExchangeService/', "xmlns:soapenv" => 'http://schemas.xmlsoap.org/soap/envelope/'}
2
+ %soapenv:Header
3
+ %soapenv:Body
4
+ %bfex:getMarketPricesCompressed
5
+ %bfex:request
6
+ %header
7
+ - if @data["client_stamp"]
8
+ %clientStamp= @data["client_stamp"]
9
+ %sessionToken= @data["session_token"]
10
+ - if @data["currency_code"]
11
+ %currencyCode= @data["currency_code"]
12
+ %marketId= @data["market_id"]
@@ -0,0 +1,12 @@
1
+ %Envelope{ "xmlns:bfex" => 'http://www.betfair.com/publicapi/v5/BFExchangeService/', "xmlns:soapenv" => 'http://schemas.xmlsoap.org/soap/envelope/'}
2
+ %soapenv:Header
3
+ %soapenv:Body
4
+ %bfex:getMarketTradedVolumeCompressed
5
+ %bfex:request
6
+ %header
7
+ - if @data["client_stamp"]
8
+ %clientStamp= @data["client_stamp"]
9
+ %sessionToken= @data["session_token"]
10
+ - if @data["currency_code"]
11
+ %currencyCode= @data["currency_code"]
12
+ %marketId= @data["market_id"]
@@ -0,0 +1,12 @@
1
+ %soapenv:Envelope{"xmlns:soapenv"=>"http://schemas.xmlsoap.org/soap/envelope/", "xmlns:bfg"=> "http://www.betfair.com/publicapi/v3/BFGlobalService/" }
2
+ %soapenv:Header/
3
+ %soapenv:Body
4
+ %bfg:getAllEventTypes
5
+ %bfg:request
6
+ %header
7
+ - if @data["client_stamp"]
8
+ %clientStamp= @data["client_stamp"]
9
+ %sessionToken= @data["session_token"]
10
+ - if @data["locale"]
11
+ %locale= @data["locale"]
12
+
@@ -0,0 +1,11 @@
1
+ %soapenv:Envelope{ "xmlns:soapenv"=> "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:bfg"=> "http://www.betfair.com/publicapi/v3/BFGlobalService/" }
2
+ %soapenv:Header
3
+ %soapenv:Body
4
+ %bfg:login
5
+ %bfg:request
6
+ %ipAddress= @data['ip_address']||0
7
+ %locationId= @data['location_id']||0
8
+ %password= @data['password']
9
+ %productId= @data['product_id']
10
+ %username= @data['username']
11
+ %vendorSoftwareId= @data['vender_software_id']||0
@@ -0,0 +1,9 @@
1
+ %soapenv:Envelope{ "xmlns:soapenv"=> "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:bfg"=> "http://www.betfair.com/publicapi/v3/BFGlobalService/" }
2
+ %soapenv:Header
3
+ %soapenv:Body
4
+ %bfg:retrieveLIMBMessage
5
+ %bfg:request
6
+ %header
7
+ - if @data["client_stamp"]
8
+ %clientStamp= @data["client_stamp"]
9
+ %sessionToken= @data["session_token"]
@@ -0,0 +1,14 @@
1
+ %soapenv:Envelope{ "xmlns:soapenv"=> "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:bfg"=> "http://www.betfair.com/publicapi/v3/BFGlobalService/", "xmlns:v3" => "http://www.betfair.com/publicapi/types/global/v3/" }
2
+ %soapenv:Header
3
+ %soapenv:Body
4
+ %bfg:submitLIMBMessage>
5
+ %bfg:request
6
+ %header
7
+ - if @data["client_stamp"]
8
+ %clientStamp= @data["client_stamp"]
9
+ %sessionToken= @data["session_token"]
10
+ %password= @data["password"]
11
+ %submitPasswordChangeMessage
12
+ %messageId= @data["message_id"]
13
+ %newPassword= @data["new_password"]
14
+ %newPasswordRepeat= @data["new_password"]
data/lib/em-betfair.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'em-betfair/soap_renderer'
2
+ require 'em-betfair/response_parser'
3
+ require 'em-betfair/response'
4
+ require 'em-betfair/betfair_client'