2022-11-12 02:27:46 +01:00

941 lines
40 KiB
Ruby

module Integrations
class Betburger
include HTTParty
attr_reader :access_token
URIS = {
live: 'https://rest-api-lv.betburger.com/api/v1/valuebets/bot_pro_search',
prematch: 'https://rest-api-pr.betburger.com/api/v1/valuebets/bot_pro_search',
}.freeze.with_indifferent_access
def initialize(tipster_account=nil)
super()
tipster_account ||= TipsterAccount.find_by(id: ENV['TIPSTER_ACCOUNT'])
@access_token = tipster_account.apikey
end
def pull_and_save_tips(source)
url = URIS[source.source_type]
return unless url
response = self.class.post(url, { body: { per_page: 32, search_filter: source.filters, access_token: @access_token } })
source.tip_source_data.create(data: response)
end
def process_subscription_tips(subscription:, data:,place_bets: true)
return unless subscription
tsd = data || subscription.tip_source_data.last
# tips already processed
return if subscription.subscription_runs.where(tip_source_data_id: tsd.id).exists?
json = tsd.data
return unless json['total_by_filter'].to_i.positive?
percentages = {}
vb_refs = json['source']['value_bets']
vb_refs.each do |vb_ref|
percentages[vb_ref['bet_id']] = { percent: vb_ref['percent'] }
end
bet_refs = json['bets']
stats = { non_valuebet: 0, unsupported_exchange: 0, duplicate: 0, processed: 0 }
bet_refs.each do |bf|
place_this_bet = place_bets
unless bf['is_value_bet'] == true
stats[:non_valuebet] += 1
next
end
exchange = exchanges[(bf['bookmaker_id']).to_s]
unless exchange
stats[:unsupported_exchange] += 1
next
end
tipster_event_id = bf['event_id']
log = []
bet_id = bf['id']
vb = populate_bet_hash(subscription, bet_id, bf, exchange, log, percentages, tipster_event_id)
# on live betting, strictly adhere to max_odds rule. Otherwise bet on all odds to generate learning data.
odds_within_range = vb[:tip_provider_odds].to_f.between?( subscription.exchange_account.current_stake_strategy[:min_odds_to_bet], subscription.exchange_account.current_stake_strategy[:max_odds_to_bet])
ev_within_range = vb[:tip_provider_percent].to_f.between?( subscription.exchange_account.current_stake_strategy[:min_ev], subscription.exchange_account.current_stake_strategy[:max_ev])
unless odds_within_range && ev_within_range
log << "[Parsing] Tip provider odds not within #{subscription.exchange_account.current_stake_strategy[:min_odds_to_bet]} and #{subscription.exchange_account.current_stake_strategy[:max_odds_to_bet]}" unless odds_within_range
log << "[Parsing] Tip provider EV not within #{subscription.exchange_account.current_stake_strategy[:min_ev]} and #{subscription.exchange_account.current_stake_strategy[:max_ev]}" unless ev_within_range
vb[:outcome] = 'ignored'
place_this_bet = false
end
vb[:log] = log
skip_duplicate_event_check = false
duplicates = subscription.exchange_account.my_bets.where(tip_provider_bet_id: bet_id)
if duplicates.exists?
stats[:duplicate] += 1
if duplicates.retryable_bets.count.positive?
bet = duplicates.retryable_bets.last #only supporting 1 duplicate!
bet.log = []
bet.update(vb)
skip_duplicate_event_check = true
else
next
end
end
unless skip_duplicate_event_check
next if subscription.exchange_account.my_bets.where(tip_provider_event_id: tipster_event_id).exists? && !subscription.exchange_account.allow_multiple_bets_per_event
end
begin
bet ||= Bet.unscoped.create(vb)
if bet && place_this_bet && vb[:exchange_market_details]
BetPlacementService.perform_later(bet: bet)
end
rescue Exception => e
puts "Something weird happened: #{e.message}"
end
stats[:processed] += 1
end
subscription.subscription_runs.create(tip_source_data_id: tsd.id, log: ["Payload: #{bet_refs.size}. #{stats}"])
end
def populate_bet_hash(subscription, bet_id, bf, exchange, log, percentages, tipster_event_id)
vb = { tip_provider_id: 'betburger', tip_provider_bet_id: bet_id }
vb[:exchange_id] = exchange
vb[:exchange_account_id] = subscription.exchange_account.id
vb[:tip_provider_event_id] = tipster_event_id
vb[:tip_provider_odds] = bf['koef'] # what the tip provider says the odds are from the exchange
vb[:exchange_event_id] = bf['bookmaker_event_direct_link'] # may be blank
vb[:team1] = bf['team1_name']
vb[:team2] = bf['team2_name']
vb[:period] = periods[bf['period_id'].to_s.to_sym] unless bf['period_id'].blank?
vb[:exchange_event_name] = vb[:team1]
vb[:exchange_event_name] += " v #{vb[:team2]}" unless vb[:team2].blank?
vb[:exchange_event_id] = bf['bookmaker_event_direct_link'] # may be blank
vb[:tip_provider_percent] = percentages[bet_id][:percent] # dunno what this is used for
tip_market_details = {}
tip_market_details[:market] = variations[bf['market_and_bet_type']&.to_s]
tip_market_details[:params] = bf['market_and_bet_type_param']&.to_s
vb[:tip_provider_market_details] = tip_market_details
exchange_market_details = map_exchange_market_details(exchange, tip_market_details, vb[:team1], vb[:team2])
vb[:original_json] = bf
if exchange_market_details
vb[:exchange_market_details] = exchange_market_details
else
vb[:outcome] = 'ignored'
log << '[Parsing] Unsupported market/selection'
end
vb
end
def exchanges
@exchanges ||= {
'11' => 'betfair'
}
end
def map_exchange_market_details(exchange, tip_market_details, team1, team2)
market_mapping = mapped_markets(exchange)
return unless market_mapping
rtn = market_mapping[tip_market_details[:market]]&.clone
return unless rtn
swaps = { 'Team1' => team1, 'Team2' => team2, '%s' => tip_market_details[:params]}
if tip_market_details[:params]
rounded = tip_market_details[:params].to_f.round
swaps['%rounded_s'] = "#{rounded.positive? ? '+':''}#{rounded}" if tip_market_details[:params]
swaps['%rounded_positive_s'] = "#{rounded.abs}"
swaps['%nearest_half_over_s'] = determine_nearest_half(tip_market_details[:params], 'over') if tip_market_details[:params]
swaps['%nearest_half_under_s'] = determine_nearest_half(tip_market_details[:params], 'under') if tip_market_details[:params]
end
swaps.keys.each do |k|
rtn[:market] = rtn[:market].sub(k, swaps[k])
rtn[:selection] = rtn[:selection].sub(k, swaps[k])
end
if rtn.key?(:handicap)
rtn[:handicap] = tip_market_details[:params].to_f
end
rtn
end
def determine_nearest_half(line, direction )
line_f = line.to_f - line.to_i
return line if line_f == 0.5
line_f = line.to_i + 0.5
line_f -= 1 if direction == 'over'
line_f += 1 if direction == 'under'
line_f.to_s
end
def mapped_markets(key)
# this is ready for other exchanges
@mapped_markets ||= { 'betfair' => betfair_markets }
@mapped_markets[key]
end
def betfair_markets
{
'Team1 Win' => { market: 'Match Odds', selection: 'Team1' },
'Team2 Win' => { market: 'Match Odds', selection: 'Team2' },
'X' => { market: 'Match Odds', selection: 'The Draw' },
'1' => { market: 'Match Odds', selection: 'Team1' },
'2' => { market: 'Match Odds', selection: 'Team2' },
'1X' => { market: 'Double Chance', selection: 'Home or Draw' },
'12' => { market: 'Double Chance', selection: 'Home or Away' },
'X2' => { market: 'Double Chance', selection: 'Draw or Away' },
'Total Over(%s)' => { market: 'Over/Under %nearest_half_over_s Goals', selection: 'Over %nearest_half_over_s Goals' },
'Total Over(%s) for Team1' => { market: 'Team1 Over/Under %nearest_half_over_s Goals', selection: 'Over %nearest_half_over_s Goals' },
'Total Over(%s) for Team2' => { market: 'Team2 Over/Under %nearest_half_over_s Goals', selection: 'Over %nearest_half_over_s Goals' },
'Total Under(%s)' => { market: 'Over/Under %nearest_half_under_s Goals', selection: 'Under %nearest_half_under_s Goals' },
'Total Under(%s) for Team1' => { market: 'Team1 Over/Under %nearest_half_under_s Goals', selection: 'Under %nearest_half_under_s Goals' },
'Total Under(%s) for Team2' => { market: 'Team2 Over/Under %nearest_half_under_s Goals', selection: 'Under %nearest_half_under_s Goals' },
'Asian Handicap1(%s)' => { market: 'Asian Handicap', selection: 'Team1' },
'Asian Handicap1(0.0)/Draw No Bet' => { market: 'Draw no Bet', selection: 'Team1' },
'Asian Handicap2(0.0)/Draw No Bet' => { market: 'Draw no Bet', selection: 'Team2' },
'Asian Handicap2(%s)' => { market: 'Asian Handicap', selection: 'Team2' },
'European Handicap1(%s)' => { market: 'Team1 +%rounded_positive_s', selection: 'Team1 %rounded_s' },
'European Handicap2(%s)' => { market: 'Team1 +%rounded_positive_s', selection: 'Team2 %rounded_s' },
'European HandicapX(%s)' => { market: 'Team1 +%rounded_positive_s', selection: 'Draw' },
'Both to score' => { market: 'Both teams to score?', selection: 'Yes' },
'One scoreless' => { market: 'Both teams to score?', selection: 'No' },
'Only one to score' => { market: 'Both teams to score?', selection: 'No' },
'Odd' => { market: 'Total Goals Odd/Even', selection: 'Odd' },
'Even' => { market: 'Total Goals Odd/Even', selection: 'Even' },
'Mat' => { market: 'Total Goals Odd/Even', selection: 'Even' },
}
end
def variations
@variations ||=
{ '1' => 'Team1 Win',
'2' => 'Team2 Win',
'3' => 'Asian Handicap1(0.0)/Draw No Bet',
'4' => 'Asian Handicap2(0.0)/Draw No Bet',
'5' => 'European Handicap1(%s)',
'6' => 'European HandicapX(%s)',
'7' => 'European Handicap2(%s)',
'8' => 'Both to score',
'9' => 'One scoreless',
'10' => 'Only one to score',
'11' => '1',
'12' => 'X',
'13' => '2',
'14' => '1X',
'15' => 'X2',
'16' => '12',
'17' => 'Asian Handicap1(%s)',
'18' => 'Asian Handicap2(%s)',
'19' => 'Total Over(%s)',
'20' => 'Total Under(%s)',
'21' => 'Total Over(%s) for Team1',
'22' => 'Total Under(%s) for Team1',
'23' => 'Total Over(%s) for Team2',
'24' => 'Total Under(%s) for Team2',
'25' => 'Odd',
'26' => 'Even',
'27' => '1 - Yellow Cards',
'28' => 'X - Yellow Cards',
'29' => '2 - Yellow Cards',
'30' => '1X - Yellow Cards',
'31' => '12 - Yellow Cards',
'32' => 'X2 - Yellow Cards',
'33' => 'Asian Handicap1(%s) - Yellow Cards',
'34' => 'Asian Handicap2(%s) - Yellow Cards',
'35' => 'Total Over(%s) - Yellow Cards',
'36' => 'Total Under(%s) - Yellow Cards',
'37' => 'Total Under(%s) for Team1 - Yellow Cards',
'38' => 'Total Over(%s) for Team1 - Yellow Cards',
'39' => 'Total Under(%s) for Team2 - Yellow Cards',
'40' => 'Total Over(%s) for Team2 - Yellow Cards',
'41' => 'Even - Yellow Cards',
'42' => 'Odd - Yellow Cards',
'43' => '1 - Corners',
'44' => 'X - Corners',
'45' => '2 - Corners',
'46' => '1X - Corners',
'47' => '12 - Corners',
'48' => 'X2 - Corners',
'49' => 'Asian Handicap1(%s) - Corners',
'50' => 'Asian Handicap2(%s) - Corners',
'51' => 'Total Over(%s) - Corners',
'52' => 'Total Under(%s) - Corners',
'53' => 'Total Under(%s) for Team1 - Corners',
'54' => 'Total Over(%s) for Team1 - Corners',
'55' => 'Total Under(%s) for Team2 - Corners',
'56' => 'Total Over(%s) for Team2 - Corners',
'57' => 'Odd - Corners',
'58' => 'Even - Corners',
'63' => 'Red card - yes',
'64' => 'No red card',
'65' => 'Penalty - yes',
'66' => 'No penalty',
'67' => 'Score (%s)',
'68' => 'Total Over(%s) - Tie Break',
'69' => 'Total Under(%s) - Tie Break',
'70' => 'Score (%s) - not',
'71' => 'Any substitute to score a goal - yes',
'72' => 'Any substitute to score a goal - no',
'73' => 'Team1 to win by exactly 1 goal - yes',
'74' => 'Team1 to win by exactly 1 goal - no',
'75' => 'Team2 to win by exactly 1 goal - yes',
'76' => 'Team2 to win by exactly 1 goal - no',
'77' => 'Team1 to win by exactly 2 goals - yes',
'78' => 'Team1 to win by exactly 2 goals - no',
'79' => 'Team1 to win by exactly 3 goals - yes',
'80' => 'Team1 to win by exactly 3 goals - no',
'81' => 'Team2 to win by exactly 2 goals - yes',
'82' => 'Team2 to win by exactly 2 goals - no',
'83' => 'Team2 to win by exactly 3 goals - yes',
'84' => 'Team2 to win by exactly 3 goals - no',
'85' => 'Team1 to win to Nil - yes',
'86' => 'Team1 to win to Nil - no',
'87' => 'Team2 to win to Nil - yes',
'88' => 'Team2 to win to Nil - no',
'89' => 'Team1 to win either halves - yes',
'90' => 'Team1 to win either halves - no',
'91' => 'Team2 to win either halves - yes',
'92' => 'Team2 to win either halves - no',
'93' => 'Draw in either half - yes',
'94' => 'Draw in either half - no',
'95' => 'Team1 to win in both halves - yes',
'96' => 'Team1 to win in both halves - no',
'97' => 'Team2 to win in both halves - yes',
'98' => 'Team2 to win in both halves - no',
'99' => 'Team1 to win and Total Over 2.5 - yes',
'100' => 'Team1 to win and Total Over 2.5 - no',
'101' => 'Team1 to win and Total Under 2.5 - yes',
'102' => 'Team1 to win and Total Under 2.5 - no',
'103' => 'Team2 to win and Total Over 2.5 - yes',
'104' => 'Team2 to win and Total Over 2.5 - no',
'105' => 'Team2 to win and Total Under 2.5 - yes',
'106' => 'Team2 to win and Total Under 2.5 - no',
'107' => 'Draw in both half - yes',
'108' => 'Draw in both half - no',
'109' => 'Draw and Total Over 2.5 - yes',
'110' => 'Draw and Total Over 2.5 - no',
'111' => 'Draw and Total Under 2.5 - yes',
'112' => 'Draw and Total Under 2.5 - no',
'113' => 'Goals in both halves - yes',
'114' => 'Goals in both halves - no',
'115' => 'Team1 to score in both halves - yes',
'116' => 'Team1 to score in both halves - no',
'117' => 'Team2 to score in both halves - yes',
'118' => 'Team2 to score in both halves - no',
'119' => 'Double - yes',
'120' => 'Double - no',
'121' => 'Hattrick - yes',
'122' => 'Hattrick - no',
'123' => 'Own goal - yes',
'124' => 'Own goal - no',
'125' => 'Both halves &gt; 1.5 goals - yes',
'126' => 'Both halves &gt; 1.5 goals - no',
'127' => 'Both halves &lt; 1.5 goals - yes',
'128' => 'Both halves &lt; 1.5 goals - no',
'129' => 'Sets (%s)',
'130' => 'Sets (%s) - not',
'131' => 'Asian Handicap1(%s) - Sets',
'132' => 'Asian Handicap2(%s) - Sets',
'133' => 'Total Over(%s) - Sets',
'134' => 'Total Under(%s) - Sets',
'135' => 'Team1/Team1',
'136' => 'Team1/Team1 - no',
'137' => 'Team1/Draw',
'138' => 'Team1/Draw - no',
'139' => 'Team1/Team2',
'140' => 'Team1/Team2 - no',
'141' => 'Draw/Team1',
'142' => 'Draw/Team1 - no',
'143' => 'Draw/Draw',
'144' => 'Draw/Draw - no',
'145' => 'Draw/Team2',
'146' => 'Draw/Team2 - no',
'147' => 'Team2/Team1',
'148' => 'Team2/Team1 - no',
'149' => 'Team2/Draw',
'150' => 'Team2/Draw - no',
'151' => 'Team2/Team2',
'152' => 'Team2/Team2 - no',
'153' => 'Exact (%s)',
'154' => 'Exact (%s) - no',
'155' => 'Exact (%s) for Team1',
'156' => 'Exact (%s) for Team1 - no',
'157' => 'Exact (%s) for Team2',
'158' => 'Exact (%s) for Team2 - no',
'159' => 'More goals in the 1st half',
'160' => 'Equal goals in halves',
'161' => 'More goals in the 2nd half',
'162' => '1 half most goals (draw no bet)',
'163' => '2 half most goals (draw no bet)',
'164' => 'Team1 - 1st goal',
'165' => 'No goal',
'166' => 'Team2 - 1st goal',
'167' => 'Team1 - 1st goal (draw no bet)',
'168' => 'Team2 - 1st goal (draw no bet)',
'169' => 'Team1 - Last goal',
'170' => 'No goal',
'171' => 'Team2 - Last goal',
'172' => 'Team1 - Last goal (draw no bet)',
'173' => 'Team2 - Last goal (draw no bet)',
'174' => 'Total Over(%s) - Aces',
'175' => 'Total Under(%s) - Aces',
'176' => 'Total Over(%s) for Team1 - Aces',
'177' => 'Total Under(%s) for Team1 - Aces',
'178' => 'Total Over(%s) for Team2 - Aces',
'179' => 'Total Under(%s) for Team2 - Aces',
'180' => 'Total Over(%s) - Double Faults',
'181' => 'Total Under(%s) - Double Faults',
'182' => 'Total Over(%s) for Team1 - Double Faults',
'183' => 'Total Under(%s) for Team1 - Double Faults',
'184' => 'Total Over(%s) for Team2 - Double Faults',
'185' => 'Total Under(%s) for Team2 - Double Faults',
'186' => 'Total Over(%s) for Team1 - 1st Serve',
'187' => 'Total Under(%s) for Team1 - 1st Serve',
'188' => 'Total Over(%s) for Team2 - 1st Serve',
'189' => 'Total Under(%s) for Team2 - 1st Serve',
'190' => 'Asian Handicap1(%s) - Aces',
'191' => 'Asian Handicap2(%s) - Aces',
'192' => 'Asian Handicap1(%s) - Double Faults',
'193' => 'Asian Handicap2(%s) - Double Faults',
'194' => 'Asian Handicap1(%s) - 1st Serve',
'195' => 'Asian Handicap2(%s) - 1st Serve',
'196' => 'Player1 - 1st Ace',
'197' => 'Player2 - 1st Ace',
'198' => 'Player1 - 1st Double Fault',
'199' => 'Player2 - 1st Double Fault',
'200' => 'Player1 - 1st Break',
'201' => 'Player2 - 1st Break',
'202' => 'Player1 - 1st Break',
'203' => 'No break - 1st Break',
'204' => 'Player2 - 1st Break',
'205' => '6-0 Set - yes',
'206' => '6-0 Set - no',
'207' => 'Win From Behind - yes',
'208' => 'Win From Behind - no',
'209' => 'Exact (%s) - Sets',
'210' => 'Exact (%s) - Sets - no',
'211' => 'Team1 - 1st corner',
'212' => 'No corners',
'213' => 'Team2 - 1st corner',
'214' => 'Team1 - Last corner',
'215' => 'No corners',
'216' => 'Team2 - Last corner',
'217' => 'Team1 - 1st Yellow Card',
'218' => 'No Yellow Card',
'219' => 'Team2 - 1st Yellow Card',
'220' => 'Team1 - Last Yellow Card',
'221' => 'No Yellow Card',
'222' => 'Team2 - Last Yellow Card',
'223' => 'Team1 - 1st offside',
'224' => 'No offsides',
'225' => 'Team2 - 1st offside',
'226' => 'Team1 - Last offside',
'227' => 'No offsides',
'228' => 'Team2 - Last offside',
'229' => '1st substitution - 1 half',
'230' => '1st substitution - intermission',
'231' => '1st substitution - 2 half',
'232' => '1st goal - 1 half',
'233' => 'No goal',
'234' => '1st goal - 2 half',
'235' => 'Team1 - 1st subs',
'236' => 'Team2 - 1st subs',
'237' => 'Team1 - Last subs',
'238' => 'Team2 - Last subs',
'239' => '1 - Shots on goal',
'240' => 'X - Shots on goal',
'241' => '2 - Shots on goal',
'242' => '1X - Shots on goal',
'243' => '12 - Shots on goal',
'244' => 'X2 - Shots on goal',
'245' => 'Asian Handicap1(%s) - Shots on goal',
'246' => 'Asian Handicap2(%s) - Shots on goal',
'247' => 'Total Over(%s) - Shots on goal',
'248' => 'Total Under(%s) - Shots on goal',
'249' => 'Total Over(%s) for Team1 - Shots on goal',
'250' => 'Total Under(%s) for Team1 - Shots on goal',
'251' => 'Total Over(%s) for Team2 - Shots on goal',
'252' => 'Total Under(%s) for Team2 - Shots on goal',
'253' => 'Odd - Shots on goal',
'254' => 'Even - Shots on goal',
'255' => '1 - Fouls',
'256' => 'X - Fouls',
'257' => '2 - Fouls',
'258' => '1X - Fouls',
'259' => '12 - Fouls',
'260' => 'X2 - Fouls',
'261' => 'Asian Handicap1(%s) - Fouls',
'262' => 'Asian Handicap2(%s) - Fouls',
'263' => 'Total Over(%s) - Fouls',
'264' => 'Total Under(%s) - Fouls',
'265' => 'Total Over(%s) for Team1 - Fouls',
'266' => 'Total Under(%s) for Team1 - Fouls',
'267' => 'Total Over(%s) for Team2 - Fouls',
'268' => 'Total Under(%s) for Team2 - Fouls',
'269' => 'Odd - Fouls',
'270' => 'Even - Fouls',
'271' => '1 - Offsides',
'272' => 'X - Offsides',
'273' => '2 - Offsides',
'274' => '1X - Offsides',
'275' => '12 - Offsides',
'276' => 'X2 - Offsides',
'277' => 'Asian Handicap1(%s) - Offsides',
'278' => 'Asian Handicap2(%s) - Offsides',
'279' => 'Total Over(%s) - Offsides',
'280' => 'Total Under(%s) - Offsides',
'281' => 'Total Over(%s) for Team1 - Offsides',
'282' => 'Total Under(%s) for Team1 - Offsides',
'283' => 'Total Over(%s) for Team2 - Offsides',
'284' => 'Total Under(%s) for Team2 - Offsides',
'285' => 'Odd - Offsides',
'286' => 'Even - Offsides',
'287' => 'Team1 to Win From Behind - yes',
'288' => 'Team1 to Win From Behind - no',
'289' => 'Team2 to Win From Behind - yes',
'290' => 'Team2 to Win From Behind - no',
'291' => 'Both To Score and W1 - yes',
'292' => 'Both To Score and W1 - no',
'293' => 'Both To Score and W2 - yes',
'294' => 'Both To Score and W2 - no',
'295' => 'Both To Score and Draw - yes',
'296' => 'Both To Score and Draw - no',
'297' => 'Exact (%s) - Added time',
'298' => 'Exact (%s) - Added time - no',
'299' => 'Total Over(%s) - Added time',
'300' => 'Total Under(%s) - Added time',
'301' => 'Home No Bet - W2',
'302' => 'Home No Bet - Draw',
'303' => 'Home No Bet - No Draw',
'304' => 'Away No Bet - W1',
'305' => 'Away No Bet - Draw',
'306' => 'Away No Bet - No Draw',
'307' => 'Total Over(%s) - Subs',
'308' => 'Total Under(%s) - Subs',
'309' => 'Total Over(%s) for Team1 - Subs',
'310' => 'Total Under(%s) for Team1 - Subs',
'311' => 'Total Over(%s) for Team2 - Subs',
'312' => 'Total Under(%s) for Team1 - Subs',
'313' => '1 - Ball possession',
'314' => 'X - Ball possession',
'315' => '2 - Ball possession',
'316' => '1X - Ball possession',
'317' => '12 - Ball possession',
'318' => 'X2 - Ball possession',
'319' => 'Asian Handicap1(%s) - Ball possession',
'320' => 'Asian Handicap2(%s) - Ball possession',
'321' => 'Total Over(%s) for Team1 - Ball possession',
'322' => 'Total Under(%s) for Team1 - Ball possession',
'323' => 'Total Over(%s) for Team2 - Ball possession',
'324' => 'Total Under(%s) for Team2 - Ball possession',
'325' => 'Team1 - 1st corner',
'326' => 'Team2 - 1st corner',
'327' => 'Team1 - Last corner',
'328' => 'Team2 - Last corner',
'329' => 'Team1 - 1st Yellow Card',
'330' => 'Team2 - 1st Yellow Card',
'331' => 'Team1 - Last Yellow Card',
'332' => 'Team2 - Last Yellow Card',
'333' => 'Team1 - 1st offside',
'334' => 'Team2 - 1st offside',
'335' => 'Team1 - Last offside',
'336' => 'Team2 - Last offside',
'337' => 'Home No Bet - No W2',
'338' => 'Away No Bet - No W1',
'339' => '1X and Total Over 2.5 - yes',
'340' => '1X and Total Over 2.5 - no',
'341' => '1X and Total Under 2.5 - yes',
'342' => '1X and Total Under 2.5 - no',
'343' => 'X2 and Total Over 2.5 - yes',
'344' => 'X2 and Total Over 2.5 - no',
'345' => 'X2 and Total Under 2.5 - yes',
'346' => 'X2 and Total Under 2.5 - no',
'348' => 'Overtime - yes',
'351' => 'Overtime - no',
'354' => 'Score Draw - yes',
'357' => 'Score Draw - no',
'360' => 'Race to 2 - Team1',
'363' => 'Race to 2 - Team2',
'366' => 'Race to 2 - Team1',
'369' => 'Race to 2 - neither',
'372' => 'Race to 2 - Team2',
'375' => 'Race to 3 - Team1',
'378' => 'Race to 3 - Team2',
'381' => 'Race to 3 - Team1',
'384' => 'Race to 3 - neither',
'387' => 'Race to 3 - Team2',
'390' => 'Race to 4 - Team1',
'393' => 'Race to 4 - Team2',
'396' => 'Race to 4 - Team1',
'399' => 'Race to 4 - neither',
'402' => 'Race to 4 - Team2',
'405' => 'Race to 5 - Team1',
'408' => 'Race to 5 - Team2',
'411' => 'Race to 5 - Team1',
'414' => 'Race to 5 - neither',
'417' => 'Race to 5 - Team2',
'420' => 'Race to 10 - Team1',
'423' => 'Race to 10 - Team2',
'426' => 'Race to 10 - Team1',
'429' => 'Race to 10 - neither',
'432' => 'Race to 10 - Team2',
'435' => 'Race to 15 - Team1',
'438' => 'Race to 15 - Team2',
'441' => 'Race to 15 - Team1',
'444' => 'Race to 15 - neither',
'447' => 'Race to 15 - Team2',
'450' => 'Race to 20 - Team1',
'453' => 'Race to 20 - Team2',
'456' => 'Race to 20 - Team1',
'459' => 'Race to 20 - neither',
'462' => 'Race to 20 - Team2',
'467' => 'Team1 - Next goal (draw no bet)',
'470' => 'Team2 - Next goal (draw no bet)',
'473' => 'Team1 - Next goal',
'476' => 'No next goal',
'479' => 'Team2 - Next goal',
'481' => '1st - yes',
'484' => '1st - no',
'487' => '1st-3rd - yes',
'490' => '1st-3rd - no',
'493' => 'W1',
'496' => 'W2',
'499' => 'TO(%s) - Hits',
'502' => 'TU(%s) - Hits',
'505' => 'TO(%s) for Team1 - Hits',
'508' => 'TU(%s) for Team1 - Hits',
'511' => 'TO(%s) for Team2 - Hits',
'514' => 'TU(%s) for Team2 - Hits',
'517' => 'TO(%s) - Errors',
'520' => 'TU(%s) - Errors',
'523' => 'TO(%s) - Hits+Errors+Runs',
'526' => 'TU(%s) - Hits+Errors+Runs',
'529' => 'AH1(%s) - Hits',
'532' => 'AH2(%s) - Hits',
'535' => '1 - Hits',
'538' => 'X - Hits',
'541' => '2 - Hits',
'546' => 'Team1 Win - Kills',
'549' => 'Team2 Win - Kills',
'552' => 'Asian Handicap1(%s) - Kills',
'555' => 'Asian Handicap2(%s) - Kills',
'558' => 'Total Over(%s) - Kills',
'561' => 'Total Under(%s) - Kills',
'564' => 'Total Over(%s) for Team1 - Kills',
'567' => 'Total Under(%s) for Team1 - Kills',
'570' => 'Total Over(%s) for Team2 - Kills',
'573' => 'Total Under(%s) for Team2 - Kills',
'574' => 'W1 - 1st blood',
'575' => 'W2 - 1st blood',
'576' => 'W1 - 1st tower',
'577' => 'W2 - 1st tower',
'578' => 'W1 - 1st dragon',
'579' => 'W2 - 1st dragon',
'580' => 'W1 - 1st baron',
'581' => 'W2 - 1st baron',
'582' => 'W1 - 1st inhibitor',
'583' => 'W2 - 1st inhibitor',
'584' => 'W1 - 1st roshan',
'585' => 'W2 - 1st roshan',
'586' => 'Win pistol rounds - Yes',
'587' => 'Win pistol rounds - No',
'588' => 'TO(%s) - Duration',
'589' => 'TU(%s) - Duration',
'590' => 'TO(%s) - Barons',
'591' => 'TU(%s) - Barons',
'592' => 'TO(%s) - Inhibitors',
'593' => 'TU(%s) - Inhibitors',
'594' => 'TO(%s) - Towers',
'595' => 'TU(%s) - Towers',
'596' => 'TO(%s) - Dragons',
'597' => 'TU(%s) - Dragons',
'598' => 'TO(%s) - Roshans',
'599' => 'TU(%s) - Roshans',
'600' => 'TO(%s) for Team1 - Sets',
'601' => 'TO(%s) for Team1 - Sets',
'602' => 'TO(%s) for Team2 - Sets',
'603' => 'TO(%s) for Team2 - Sets',
'604' => 'W1 - Longest TD',
'605' => 'W2 - Longest TD',
'606' => 'W1 - Longest FG',
'607' => 'W2 - Longest FG',
'608' => 'Touchdown - Yes',
'609' => 'Touchdown - No',
'610' => 'Safety - Yes',
'611' => 'Safety - No',
'612' => 'First score TD - Yes',
'613' => 'First score TD - No',
'614' => 'Both teams 10 pts - Yes',
'615' => 'Both teams 10 pts - No',
'616' => 'Both teams 15 pts - Yes',
'617' => 'Both teams 15 pts - No',
'618' => 'Both teams 20 pts - Yes',
'619' => 'Both teams 20 pts - No',
'620' => 'Both teams 25 pts - Yes',
'621' => 'Both teams 25 pts - No',
'622' => 'Both teams 30 pts - Yes',
'623' => 'Both teams 30 pts - No',
'624' => 'Both teams 35 pts - Yes',
'625' => 'Both teams 35 pts - No',
'626' => 'Both teams 40 pts - Yes',
'627' => 'Both teams 40 pts - No',
'628' => 'Both teams 45 pts - Yes',
'629' => 'Both teams 45 pts - No',
'630' => 'Both teams 50 pts - Yes',
'631' => 'Both teams 50 pts - No',
'632' => 'Highest Scoring Quarter - 1st',
'633' => 'Highest Scoring Quarter - 2nd',
'634' => 'Highest Scoring Quarter - 3rd',
'635' => 'Highest Scoring Quarter - 4th',
'636' => 'Highest Scoring Quarter - Tie',
'637' => 'TO(%s) - Field Goals',
'638' => 'TU(%s) - Field Goals',
'639' => 'TO(%s) - Touchdowns',
'640' => 'TU(%s) - Touchdowns',
'641' => 'TO(%s) - Longest TD, distance',
'642' => 'TU(%s) - Longest TD, distance',
'643' => 'TO(%s) - Longest FG, distance',
'644' => 'TU(%s) - Longest FG, distance',
'645' => 'TO(%s) for Team1 - Field Goals',
'646' => 'TU(%s) for Team1 - Field Goals',
'647' => 'TO(%s) for Team2 - Field Goals',
'648' => 'TU(%s) for Team2 - Field Goals',
'649' => 'TO(%s) for Team1 - Touchdowns',
'650' => 'TU(%s) for Team1 - Touchdowns',
'651' => 'TO(%s) for Team2 - Touchdowns',
'652' => 'TU(%s) for Team2 - Touchdowns',
'653' => 'AH1(%s) - Maps',
'654' => 'AH2(%s) - Maps',
'655' => 'TO(%s) - Maps',
'656' => 'TU(%s) - Maps',
'657' => 'TO(%s) for Team1 - Maps',
'658' => 'TU(%s) for Team1 - Maps',
'659' => 'TO(%s) for Team2 - Maps',
'660' => 'TU(%s) for Team2 - Maps',
'661' => 'Maps (%s)',
'662' => 'Maps (%s) - not',
'663' => 'Exact (%s) - Maps',
'664' => 'Exact (%s) - Maps - no',
'665' => 'Win both pistol rounds - Yes',
'666' => 'Win both pistol rounds - No',
'667' => 'Team1 to win both pistol rounds - Yes',
'668' => 'Team1 to win both pistol rounds - No',
'669' => 'Team2 to win both pistol rounds - Yes',
'670' => 'Team1 to win both pistol rounds - No',
'671' => 'Team1 to win at least 1 set - Yes',
'672' => 'Team1 to win at least 1 set - No',
'673' => 'Team2 to win at least 1 set - Yes',
'674' => 'Team1 to win at least 1 set - No',
'675' => 'Team1 to win at least 1 map - Yes',
'676' => 'Team1 to win at least 1 map - No',
'677' => 'Team2 to win at least 1 map - Yes',
'678' => 'Team1 to win at least 1 map - No',
'679' => 'Both teams kill a dragon - Yes',
'680' => 'Both teams kill a dragon - No',
'681' => 'Both teams kill a baron - Yes',
'682' => 'Both teams kill a baron - No',
'683' => 'W1 - 1st Barracks',
'684' => 'W2 - 1st Barracks',
'685' => 'W1 - 1st Double Kill',
'686' => 'W2 - 1st Double Kill',
'687' => 'TO(%s) - Barracks',
'688' => 'TU(%s) - Barracks',
'689' => 'TO(%s) - Double Kills',
'690' => 'TU(%s) - Double Kills',
'691' => 'AH1(%s) - Barons',
'692' => 'AH2(%s) - Barons',
'693' => 'AH1(%s) - Dragons',
'694' => 'AH2(%s) - Dragons',
'695' => 'AH1(%s) - Towers/Turrets',
'696' => 'AH2(%s) - Towers/Turrets',
'697' => '1 - 3-points',
'698' => 'X - 3-points',
'699' => '2 - 3-points',
'700' => '1 - Rebounds',
'701' => 'X - Rebounds',
'702' => '2 - Rebounds',
'703' => '1 - Assists',
'704' => 'X - Assists',
'705' => '2 - Assists',
'706' => '1X - 3-points',
'707' => 'X2 - 3-points',
'708' => '12 - 3-points',
'709' => '1X - Rebounds',
'710' => 'X2 - Rebounds',
'711' => '12 - Rebounds',
'712' => '1X - Assists',
'713' => 'X2 - Assists',
'714' => '12 - Assists',
'715' => 'AH1(%s) - 3-points',
'716' => 'AH2(%s) - 3-points',
'717' => 'AH1(%s) - Rebounds',
'718' => 'AH2(%s) - Rebounds',
'719' => 'AH1(%s) - Assists',
'720' => 'AH2(%s) - Assists',
'721' => 'TO(%s) - 3-points',
'722' => 'TU(%s) - 3-points',
'723' => 'TO(%s) - Rebounds',
'724' => 'TU(%s) - Rebounds',
'725' => 'TO(%s) - Assists',
'726' => 'TU(%s) - Assists',
'727' => 'TO(%s) for Team1 - 3-points',
'728' => 'TU(%s) for Team1 - 3-points',
'729' => 'TO(%s) for Team1 - Rebounds',
'730' => 'TU(%s) for Team1 - Rebounds',
'731' => 'TO(%s) for Team1 - Assists',
'732' => 'TU(%s) for Team1 - Assists',
'733' => 'TO(%s) for Team2 - 3-points',
'734' => 'TU(%s) for Team2 - 3-points',
'735' => 'TO(%s) for Team2 - Rebounds',
'736' => 'TU(%s) for Team2 - Rebounds',
'737' => 'TO(%s) for Team2 - Assists',
'738' => 'TU(%s) for Team2 - Assists',
'739' => 'W1 - 180s',
'740' => 'W2 - 180s',
'741' => 'AH1(%s) - 180s',
'742' => 'AH2(%s) - 180s',
'743' => 'TO(%s) - 180s',
'744' => 'TU(%s) - 180s',
'745' => '1 - Cards',
'746' => 'X - Cards',
'747' => '2 - Cards',
'748' => '1 - Booking points',
'749' => 'X - Booking points',
'750' => '2 - Booking points',
'751' => '1X - Cards',
'752' => 'X2 - Cards',
'753' => '12 - Cards',
'754' => '1X - Booking points',
'755' => 'X2 - Booking points',
'756' => '12 - Booking points',
'757' => 'AH1(%s) - Cards',
'758' => 'AH2(%s) - Cards',
'759' => 'AH1(%s) - Booking points',
'760' => 'AH2(%s) - Booking points',
'761' => 'TO(%s) - Cards',
'762' => 'TU(%s) - Cards',
'763' => 'TO(%s) - Booking points',
'764' => 'TU(%s) - Booking points',
'765' => 'TO(%s) for Team1 - Cards',
'766' => 'TU(%s) for Team1 - Cards',
'767' => 'TO(%s) for Team1 - Booking points',
'768' => 'TU(%s) for Team1 - Booking points',
'769' => 'TO(%s) for Team2 - Cards',
'770' => 'TU(%s) for Team2 - Cards',
'771' => 'TO(%s) for Team2 - Booking points',
'772' => 'TU(%s) for Team2 - Booking points',
'773' => 'Odd - Cards',
'774' => 'Even - Cards',
'775' => 'Odd - Booking points',
'776' => 'Even - Booking points' }
end
def periods
@periods ||=
{
'1': 'match (pairs)',
'2': 'with OT and SO',
'3': 'with OT',
'4': 'regular time', #match odds
'5': '1st',
'6': '2nd',
'7': '3rd',
'8': '4th',
'9': '5th',
'10': '1st half', #first
'13': '2nd half',
'14': '1 set, 01 game',
'15': '1 set, 02 game',
'16': '1 set, 03 game',
'17': '1 set, 04 game',
'18': '1 set, 05 game',
'19': '1 set, 06 game',
'20': '1 set, 07 game',
'21': '1 set, 08 game',
'22': '1 set, 09 game',
'23': '1 set, 10 game',
'24': '1 set, 11 game',
'25': '1 set, 12 game',
'26': '1 set, 13 game',
'44': '2 set, 01 game',
'45': '2 set, 02 game',
'46': '2 set, 03 game',
'47': '2 set, 04 game',
'48': '2 set, 05 game',
'49': '2 set, 06 game',
'50': '2 set, 07 game',
'51': '2 set, 08 game',
'52': '2 set, 09 game',
'53': '2 set, 10 game',
'54': '2 set, 11 game',
'55': '2 set, 12 game',
'56': '2 set, 13 game',
'57': '3 set, 01 game',
'58': '3 set, 02 game',
'59': '3 set, 03 game',
'60': '3 set, 04 game',
'61': '3 set, 05 game',
'62': '3 set, 06 game',
'63': '3 set, 07 game',
'64': '3 set, 08 game',
'65': '3 set, 09 game',
'66': '3 set, 10 game',
'67': '3 set, 11 game',
'68': '3 set, 12 game',
'71': '3 set, 13 game',
'76': '6th',
'78': '7th',
'86': 'regular time',
'92': 'regular time',
'93': '1st half',
'95': 'to qualify',
'96': '8th',
'97': '9th',
'113': '4 set, 01 game',
'114': '4 set, 02 game',
'115': '4 set, 03 game',
'116': '4 set, 04 game',
'117': '4 set, 05 game',
'118': '4 set, 06 game',
'119': '4 set, 07 game',
'120': '4 set, 08 game',
'121': '4 set, 09 game',
'122': '4 set, 10 game',
'123': '4 set, 11 game',
'124': '4 set, 12 game',
'125': '5 set, 01 game',
'126': '5 set, 02 game',
'127': '5 set, 03 game',
'128': '5 set, 04 game',
'129': '5 set, 05 game',
'130': '5 set, 06 game',
'131': '5 set, 07 game',
'132': '5 set, 08 game',
'133': '5 set, 09 game',
'134': '5 set, 10 game',
'156': '4 set, 13 game',
'159': '5 set, 11 game',
'161': '5 set, 12 game',
'169': '5 set, 13 game',
'223': 'regular time',
'243': '1st half',
'245': '2nd half',
'246': '2nd half',
'317': '1st half',
'318': '2nd half',
'4091': 'regular time', #match odds
'4094': '1st half'
}
end
end
end