ice hockey eval
This commit is contained in:
parent
30a6373990
commit
252bf04b1e
|
|
@ -122,6 +122,58 @@ type BasketballResultResponse struct {
|
|||
ConfirmedAt string `json:"confirmed_at"`
|
||||
Bet365ID string `json:"bet365_id"`
|
||||
}
|
||||
type IceHockeyResultResponse struct {
|
||||
ID string `json:"id"`
|
||||
SportID string `json:"sport_id"`
|
||||
Time string `json:"time"`
|
||||
TimeStatus string `json:"time_status"`
|
||||
League struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CC string `json:"cc"`
|
||||
} `json:"league"`
|
||||
Home struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ImageID string `json:"image_id"`
|
||||
CC string `json:"cc"`
|
||||
} `json:"home"`
|
||||
Away struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ImageID string `json:"image_id"`
|
||||
CC string `json:"cc"`
|
||||
} `json:"away"`
|
||||
SS string `json:"ss"`
|
||||
Scores struct {
|
||||
FirstPeriod Score `json:"1"`
|
||||
SecondPeriod Score `json:"2"`
|
||||
ThirdPeriod Score `json:"3"`
|
||||
TotalScore Score `json:"5"`
|
||||
} `json:"scores"`
|
||||
|
||||
Stats struct {
|
||||
Shots []string `json:"shots"`
|
||||
Penalties []string `json:"penalties"`
|
||||
GoalsOnPowerPlay []string `json:"goals_on_power_play"`
|
||||
SSeven []string `json:"s7"`
|
||||
} `json:"stats"`
|
||||
Extra struct {
|
||||
HomePos string `json:"home_pos"`
|
||||
AwayPos string `json:"away_pos"`
|
||||
AwayManager map[string]string `json:"away_manager"`
|
||||
HomeManager map[string]string `json:"home_manager"`
|
||||
NumberOfPeriods string `json:"numberofperiods"`
|
||||
PeriodLength string `json:"periodlength"`
|
||||
StadiumData map[string]string `json:"stadium_data"`
|
||||
Length string `json:"length"`
|
||||
Round string `json:"round"`
|
||||
} `json:"extra"`
|
||||
Events []map[string]string `json:"events"`
|
||||
HasLineup int `json:"has_lineup"`
|
||||
ConfirmedAt string `json:"confirmed_at"`
|
||||
Bet365ID string `json:"bet365_id"`
|
||||
}
|
||||
|
||||
type Score struct {
|
||||
Home string `json:"home"`
|
||||
|
|
|
|||
|
|
@ -30,23 +30,35 @@ const (
|
|||
BASKETBALL_DOUBLE_RESULT BasketBallMarket = 1517 //"double_result"
|
||||
BASKETBALL_MATCH_RESULT_AND_TOTAL BasketBallMarket = 181125 //"match_result_and_total"
|
||||
BASKETBALL_MATCH_HANDICAP_AND_TOTAL BasketBallMarket = 181126 //"match_handicap_and_total"
|
||||
BASKETBALL_RACE_TO_20_POINTS BasketBallMarket = 1503 //"race_to_20_points"
|
||||
BASKETBALL_TIED_AT_END_OF_REGULATION BasketBallMarket = 181127 //"tied_at_end_of_regulation"
|
||||
BASKETBALL_QUARTER_CORRECT_SCORE BasketBallMarket = 181276 //"quarter_correct_score"
|
||||
|
||||
// Half Props
|
||||
BASKETBALL_FIRST_HALF_TEAM_TOTALS BasketBallMarket = 181159 //"1st_half_team_totals"
|
||||
BASKETBALL_FIRST_HALF_WINNING_MARGIN BasketBallMarket = 181185 //"1st_half_winning_margin"
|
||||
BASKETBALL_FIRST_HALF_RESULT_AND_TOTAL BasketBallMarket = 181181 //"1st_half_result_and_total"
|
||||
BASKETBALL_FIRST_HALF_HANDICAP_AND_TOTAL BasketBallMarket = 181182 //"1st_half_handicap_and_total"
|
||||
BASKETBALL_FIRST_HALF_RACE_TO_POINTS BasketBallMarket = 181186 //"1st_half_race_to_(points)"
|
||||
BASKETBALL_FIRST_HALF_BOTH_TEAMS_TO_SCORE_X_POINTS BasketBallMarket = 181195 //"1st_half_both_teams_to_score_x_points"
|
||||
BASKETBALL_FIRST_HALF_TEAM_TO_SCORE_X_POINTS BasketBallMarket = 181198 //"1st_half_team_to_score_x_points"
|
||||
BASKETBALL_FIRST_HALF_MONEY_LINE_3_WAY BasketBallMarket = 181183 //"1st_half_money_line_3_way"
|
||||
|
||||
// Others
|
||||
BASKETBALL_GAME_TOTAL_ODD_EVEN BasketBallMarket = 180013 //"game_total_odd_even"
|
||||
BASKETBALL_FIRST_QUARTER_TOTAL_ODD_EVEN BasketBallMarket = 180170 //"1st_quarter_total_odd_even"
|
||||
BASKETBALL_HIGHEST_SCORING_HALF BasketBallMarket = 181131 //"highest_scoring_half"
|
||||
BASKETBALL_HIGHEST_SCORING_QUARTER BasketBallMarket = 181132 //"highest_scoring_quarter"
|
||||
BASKETBALL_FIRST_HALF_DOUBLE_CHANCE BasketBallMarket = 181184 //"1st_half_double_chance"
|
||||
BASKETBALL_FIRST_HALF_TOTAL_ODD_EVEN BasketBallMarket = 181204 //"1st_half_total_odd_even"
|
||||
BASKETBALL_FIRST_QUARTER_HANDICAP_AND_TOTAL BasketBallMarket = 181243 //"1st_quarter_handicap_and_total"
|
||||
BASKETBALL_FIRST_QUARTER_DOUBLE_CHANCE BasketBallMarket = 181245 //"1st_quarter_double_chance"
|
||||
BASKETBALL_GAME_TOTAL_ODD_EVEN BasketBallMarket = 180013 //"game_total_odd_even"
|
||||
BASKETBALL_FIRST_QUARTER_TOTAL_ODD_EVEN BasketBallMarket = 180170 //"1st_quarter_total_odd_even"
|
||||
BASKETBALL_FIRST_QUARTER_MARGIN_OF_VICTORY BasketBallMarket = 180180 //"1st_quarter_margin_of_victory"
|
||||
BASKETBALL_HIGHEST_SCORING_HALF BasketBallMarket = 181131 //"highest_scoring_half"
|
||||
BASKETBALL_HIGHEST_SCORING_QUARTER BasketBallMarket = 181132 //"highest_scoring_quarter"
|
||||
BASKETBALL_FIRST_HALF_DOUBLE_CHANCE BasketBallMarket = 181184 //"1st_half_double_chance"
|
||||
BASKETBALL_FIRST_HALF_TOTAL_ODD_EVEN BasketBallMarket = 181204 //"1st_half_total_odd_even"
|
||||
BASKETBALL_FIRST_QUARTER_3_WAY_LINES BasketBallMarket = 181212 //"1st_quarter_3_way_lines"
|
||||
BASKETBALL_FIRST_QUARTER_RESULT_AND_TOTAL BasketBallMarket = 181242 //"1st_quarter_result_and_total"
|
||||
BASKETBALL_FIRST_QUARTER_HANDICAP_AND_TOTAL BasketBallMarket = 181243 //"1st_quarter_handicap_and_total"
|
||||
BASKETBALL_FIRST_QUARTER_DOUBLE_CHANCE BasketBallMarket = 181245 //"1st_quarter_double_chance"
|
||||
BASKETBALL_FIRST_QUARTER_RACE_TO_POINTS BasketBallMarket = 181248 //"1st_quarter_race_to_(points)"
|
||||
BASKETBALL_FIRST_QUARTER_BOTH_TEAMS_TO_SCORE_X_POINTS BasketBallMarket = 181252 //"1st_quarter_both_teams_to_score_x_points"
|
||||
BASKETBALL_FIRST_QUARTER_TEAM_TO_SCORE_X_POINTS BasketBallMarket = 181255 //"1st_quarter_team_to_score_x_points"
|
||||
|
||||
// Quarter Props
|
||||
BASKETBALL_FIRST_QUARTER_TEAM_TOTALS BasketBallMarket = 181220 //"1st_quarter_team_totals"
|
||||
|
|
@ -62,8 +74,10 @@ const (
|
|||
type IceHockeyMarket int64
|
||||
|
||||
const (
|
||||
// Main
|
||||
ICE_HOCKEY_GAME_LINES IceHockeyMarket = 972
|
||||
|
||||
ICE_HOCKEY_FIRST_PERIOD IceHockeyMarket = 1531
|
||||
ICE_HOCKEY_GAME_LINES IceHockeyMarket = 972
|
||||
ICE_HOCKEY_THREE_WAY IceHockeyMarket = 170008
|
||||
ICE_HOCKEY_DRAW_NO_BET IceHockeyMarket = 170447
|
||||
ICE_HOCKEY_DOUBLE_CHANCE IceHockeyMarket = 170038
|
||||
|
|
@ -78,70 +92,76 @@ const (
|
|||
)
|
||||
|
||||
// TODO: Move this into the database so that it can be modified dynamically
|
||||
var SupportedMarkets = map[string]MarketConfig{
|
||||
"football": {
|
||||
Sport: "football",
|
||||
MarketCategories: map[string]bool{
|
||||
"main": true,
|
||||
"asian_lines": true,
|
||||
"goals": true,
|
||||
"half": true,
|
||||
},
|
||||
MarketTypes: map[int64]bool{
|
||||
int64(FOOTBALL_FULL_TIME_RESULT): true, //"full_time_result"
|
||||
int64(FOOTBALL_DOUBLE_CHANCE): true, //"double_chance"
|
||||
int64(FOOTBALL_GOALS_OVER_UNDER): true, //"goals_over_under"
|
||||
int64(FOOTBALL_CORRECT_SCORE): true, //"correct_score"
|
||||
int64(FOOTBALL_ASIAN_HANDICAP): true, //"asian_handicap"
|
||||
int64(FOOTBALL_GOAL_LINE): true, //"goal_line"
|
||||
int64(FOOTBALL_HALF_TIME_RESULT): true, //"half_time_result"
|
||||
int64(FOOTBALL_FIRST_HALF_ASIAN_HANDICAP): true, //"1st_half_asian_handicap"
|
||||
int64(FOOTBALL_FIRST_HALF_GOAL_LINE): true, //"1st_half_goal_line"
|
||||
int64(FOOTBALL_FIRST_TEAM_TO_SCORE): true, //"first_team_to_score"
|
||||
int64(FOOTBALL_GOALS_ODD_EVEN): true, //"goals_odd_even"
|
||||
int64(FOOTBALL_DRAW_NO_BET): true, //"draw_no_bet"
|
||||
},
|
||||
},
|
||||
|
||||
"basketball": {
|
||||
Sport: "basketball",
|
||||
MarketCategories: map[string]bool{
|
||||
"main": true,
|
||||
"main_props": true,
|
||||
"others": true,
|
||||
"quarter_props": true,
|
||||
"team_props": true,
|
||||
"half_props": true,
|
||||
},
|
||||
MarketTypes: map[int64]bool{
|
||||
var SupportedMarkets = map[int64]bool{
|
||||
|
||||
int64(BASKETBALL_GAME_LINES): true,
|
||||
int64(BASKETBALL_FIRST_HALF): true,
|
||||
int64(BASKETBALL_FIRST_QUARTER): true,
|
||||
int64(BASKETBALL_RESULT_AND_BOTH_TEAMS_TO_SCORE_X_POINTS): true,
|
||||
int64(BASKETBALL_DOUBLE_RESULT): true,
|
||||
int64(BASKETBALL_MATCH_RESULT_AND_TOTAL): true,
|
||||
int64(BASKETBALL_MATCH_HANDICAP_AND_TOTAL): false,
|
||||
int64(BASKETBALL_GAME_TOTAL_ODD_EVEN): true,
|
||||
int64(BASKETBALL_TEAM_TOTALS): true,
|
||||
int64(BASKETBALL_TEAM_TOTAL_ODD_EVEN): true,
|
||||
// Football Markets
|
||||
int64(FOOTBALL_FULL_TIME_RESULT): true, //"full_time_result"
|
||||
int64(FOOTBALL_DOUBLE_CHANCE): true, //"double_chance"
|
||||
int64(FOOTBALL_GOALS_OVER_UNDER): true, //"goals_over_under"
|
||||
int64(FOOTBALL_CORRECT_SCORE): true, //"correct_score"
|
||||
int64(FOOTBALL_ASIAN_HANDICAP): true, //"asian_handicap"
|
||||
int64(FOOTBALL_GOAL_LINE): true, //"goal_line"
|
||||
int64(FOOTBALL_HALF_TIME_RESULT): true, //"half_time_result"
|
||||
int64(FOOTBALL_FIRST_HALF_ASIAN_HANDICAP): true, //"1st_half_asian_handicap"
|
||||
int64(FOOTBALL_FIRST_HALF_GOAL_LINE): true, //"1st_half_goal_line"
|
||||
int64(FOOTBALL_FIRST_TEAM_TO_SCORE): true, //"first_team_to_score"
|
||||
int64(FOOTBALL_GOALS_ODD_EVEN): true, //"goals_odd_even"
|
||||
int64(FOOTBALL_DRAW_NO_BET): true, //"draw_no_bet"
|
||||
|
||||
int64(BASKETBALL_FIRST_HALF_TEAM_TOTALS): true,
|
||||
int64(BASKETBALL_FIRST_HALF_WINNING_MARGIN): false,
|
||||
int64(BASKETBALL_FIRST_HALF_HANDICAP_AND_TOTAL): true,
|
||||
int64(BASKETBALL_FIRST_HALF_BOTH_TEAMS_TO_SCORE_X_POINTS): true,
|
||||
int64(BASKETBALL_FIRST_HALF_MONEY_LINE_3_WAY): true,
|
||||
int64(BASKETBALL_FIRST_HALF_DOUBLE_CHANCE): true,
|
||||
int64(BASKETBALL_FIRST_HALF_TOTAL_ODD_EVEN): true,
|
||||
int64(BASKETBALL_HIGHEST_SCORING_HALF): true,
|
||||
// Basketball Markets
|
||||
int64(BASKETBALL_GAME_LINES): true,
|
||||
int64(BASKETBALL_RESULT_AND_BOTH_TEAMS_TO_SCORE_X_POINTS): true,
|
||||
int64(BASKETBALL_DOUBLE_RESULT): true,
|
||||
int64(BASKETBALL_MATCH_RESULT_AND_TOTAL): true,
|
||||
int64(BASKETBALL_MATCH_HANDICAP_AND_TOTAL): false,
|
||||
int64(BASKETBALL_GAME_TOTAL_ODD_EVEN): true,
|
||||
int64(BASKETBALL_TEAM_TOTALS): true,
|
||||
int64(BASKETBALL_TEAM_TOTAL_ODD_EVEN): true,
|
||||
int64(BASKETBALL_RACE_TO_20_POINTS): false,
|
||||
int64(BASKETBALL_TIED_AT_END_OF_REGULATION): false,
|
||||
|
||||
int64(BASKETBALL_FIRST_QUARTER_HANDICAP_AND_TOTAL): false,
|
||||
int64(BASKETBALL_FIRST_QUARTER_DOUBLE_CHANCE): true,
|
||||
int64(BASKETBALL_FIRST_QUARTER_TEAM_TOTALS): true,
|
||||
int64(BASKETBALL_FIRST_QUARTER_WINNING_MARGIN): true,
|
||||
int64(BASKETBALL_FIRST_QUARTER_TOTAL_ODD_EVEN): true,
|
||||
int64(BASKETBALL_HIGHEST_SCORING_QUARTER): true,
|
||||
int64(BASKETBALL_TEAM_WITH_HIGHEST_SCORING_QUARTER): true,
|
||||
},
|
||||
},
|
||||
int64(BASKETBALL_FIRST_HALF): true,
|
||||
int64(BASKETBALL_FIRST_HALF_TEAM_TOTALS): true,
|
||||
int64(BASKETBALL_FIRST_HALF_WINNING_MARGIN): false,
|
||||
int64(BASKETBALL_FIRST_HALF_HANDICAP_AND_TOTAL): true,
|
||||
int64(BASKETBALL_FIRST_HALF_BOTH_TEAMS_TO_SCORE_X_POINTS): true,
|
||||
int64(BASKETBALL_FIRST_HALF_MONEY_LINE_3_WAY): true,
|
||||
int64(BASKETBALL_FIRST_HALF_DOUBLE_CHANCE): true,
|
||||
int64(BASKETBALL_FIRST_HALF_TOTAL_ODD_EVEN): true,
|
||||
int64(BASKETBALL_HIGHEST_SCORING_HALF): true,
|
||||
int64(BASKETBALL_FIRST_HALF_RESULT_AND_TOTAL): false,
|
||||
int64(BASKETBALL_FIRST_HALF_RACE_TO_POINTS): false,
|
||||
int64(BASKETBALL_FIRST_HALF_TEAM_TO_SCORE_X_POINTS): false,
|
||||
|
||||
int64(BASKETBALL_FIRST_QUARTER): true,
|
||||
int64(BASKETBALL_FIRST_QUARTER_HANDICAP_AND_TOTAL): false,
|
||||
int64(BASKETBALL_FIRST_QUARTER_DOUBLE_CHANCE): true,
|
||||
int64(BASKETBALL_FIRST_QUARTER_TEAM_TOTALS): true,
|
||||
int64(BASKETBALL_FIRST_QUARTER_WINNING_MARGIN): false,
|
||||
int64(BASKETBALL_FIRST_QUARTER_TOTAL_ODD_EVEN): true,
|
||||
int64(BASKETBALL_HIGHEST_SCORING_QUARTER): true,
|
||||
int64(BASKETBALL_TEAM_WITH_HIGHEST_SCORING_QUARTER): true,
|
||||
int64(BASKETBALL_QUARTER_CORRECT_SCORE): false,
|
||||
int64(BASKETBALL_FIRST_QUARTER_3_WAY_LINES): false,
|
||||
int64(BASKETBALL_FIRST_QUARTER_RESULT_AND_TOTAL): false,
|
||||
int64(BASKETBALL_FIRST_QUARTER_RACE_TO_POINTS): false,
|
||||
int64(BASKETBALL_FIRST_QUARTER_BOTH_TEAMS_TO_SCORE_X_POINTS): false,
|
||||
int64(BASKETBALL_FIRST_QUARTER_TEAM_TO_SCORE_X_POINTS): false,
|
||||
int64(BASKETBALL_FIRST_QUARTER_MARGIN_OF_VICTORY): false,
|
||||
|
||||
// Ice Hockey Markets
|
||||
int64(ICE_HOCKEY_GAME_LINES): true,
|
||||
int64(ICE_HOCKEY_FIRST_PERIOD): true,
|
||||
int64(ICE_HOCKEY_THREE_WAY): true,
|
||||
int64(ICE_HOCKEY_DRAW_NO_BET): true,
|
||||
int64(ICE_HOCKEY_DOUBLE_CHANCE): true,
|
||||
int64(ICE_HOCKEY_WINNING_MARGIN): true,
|
||||
int64(ICE_HOCKEY_HIGHEST_SCORING_PERIOD): true,
|
||||
int64(ICE_HOCKEY_TIED_AFTER_REGULATION): true,
|
||||
int64(ICE_HOCKEY_WHEN_WILL_MATCH_END): false,
|
||||
int64(ICE_HOCKEY_GAME_TOTAL_ODD_EVEN): true,
|
||||
|
||||
int64(ICE_HOCKEY_ALTERNATIVE_PUCK_LINE_TWO_WAY): false,
|
||||
int64(ICE_HOCKEY_ALTERNATIVE_TOTAL_TWO_WAY): false,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ func evaluateGoalLine(outcome domain.BetOutcome, score struct{ Home, Away int })
|
|||
|
||||
func evaluateFirstTeamToScore(outcome domain.BetOutcome, events []map[string]string) (domain.OutcomeStatus, error) {
|
||||
for _, event := range events {
|
||||
if strings.Contains(event["text"], "1st Goal") {
|
||||
if strings.Contains(event["text"], "1st Goal") || strings.Contains(event["text"], "Goal 1") {
|
||||
if strings.Contains(event["text"], outcome.HomeTeamName) && outcome.OddName == "1" {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
} else if strings.Contains(event["text"], outcome.AwayTeamName) && outcome.OddName == "2" {
|
||||
|
|
@ -228,7 +228,8 @@ func evaluateGameLines(outcome domain.BetOutcome, score struct{ Home, Away int }
|
|||
switch outcome.OddName {
|
||||
case "Money Line":
|
||||
return evaluateMoneyLine(outcome, score)
|
||||
case "Spread":
|
||||
|
||||
case "Spread", "Line":
|
||||
// Since Spread betting is essentially the same thing
|
||||
return evaluateAsianHandicap(outcome, score)
|
||||
case "Total":
|
||||
|
|
@ -251,7 +252,11 @@ func evaluateMoneyLine(outcome domain.BetOutcome, score struct{ Home, Away int }
|
|||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
return domain.OUTCOME_STATUS_LOSS, nil
|
||||
|
||||
case "Tie", "Draw":
|
||||
if score.Home == score.Away {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
return domain.OUTCOME_STATUS_LOSS, nil
|
||||
default:
|
||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd name: %s", outcome.OddName)
|
||||
}
|
||||
|
|
@ -283,6 +288,11 @@ func evaluateTotalOverUnder(outcome domain.BetOutcome, score struct{ Home, Away
|
|||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
return domain.OUTCOME_STATUS_LOSS, nil
|
||||
} else if overUnderStr[0] == "E" {
|
||||
if totalScore == threshold {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
return domain.OUTCOME_STATUS_LOSS, nil
|
||||
}
|
||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid odd header: %s", outcome.OddHeader)
|
||||
}
|
||||
|
|
@ -553,7 +563,7 @@ func evaluateHighestScoringQuarter(outcome domain.BetOutcome, firstScore struct{
|
|||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
case "Tie":
|
||||
if fourthQuarterTotal == firstQuarterTotal && fourthQuarterTotal == secondQuarterTotal && fourthQuarterTotal == thirdQuarterTotal {
|
||||
if firstQuarterTotal == secondQuarterTotal || secondQuarterTotal == thirdQuarterTotal || thirdQuarterTotal == fourthQuarterTotal {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
default:
|
||||
|
|
@ -612,3 +622,90 @@ func evaluateHandicapAndTotal(outcome domain.BetOutcome, score struct{ Home, Awa
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
func evaluateWinningMargin(outcome domain.BetOutcome, score struct{ Home, Away int }) (domain.OutcomeStatus, error) {
|
||||
|
||||
marginSplit := strings.Split(outcome.OddName, "")
|
||||
if len(marginSplit) < 1 {
|
||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", outcome.OddName)
|
||||
}
|
||||
|
||||
margin, err := strconv.ParseInt(marginSplit[0], 10, 64)
|
||||
if err != nil {
|
||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", outcome.OddName)
|
||||
}
|
||||
|
||||
isGtr := false
|
||||
if len(marginSplit) == 2 {
|
||||
isGtr = marginSplit[1] == "+"
|
||||
}
|
||||
switch outcome.OddHeader {
|
||||
case "1":
|
||||
if score.Home == (score.Away + int(margin)) {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
} else if isGtr && score.Home > (score.Away+int(margin)) {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
return domain.OUTCOME_STATUS_LOSS, nil
|
||||
case "2":
|
||||
if (score.Home + int(margin)) == score.Away {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
} else if isGtr && (score.Home+int(margin)) > score.Away {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
return domain.OUTCOME_STATUS_LOSS, nil
|
||||
}
|
||||
|
||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddheader: %s", outcome.OddHeader)
|
||||
}
|
||||
|
||||
func evaluateHighestScoringPeriod(outcome domain.BetOutcome, firstScore struct{ Home, Away int }, secondScore struct{ Home, Away int }, thirdScore struct{ Home, Away int }) (domain.OutcomeStatus, error) {
|
||||
firstPeriodTotal := firstScore.Home + firstScore.Away
|
||||
secondPeriodTotal := secondScore.Home + secondScore.Away
|
||||
thirdPeriodTotal := thirdScore.Home + thirdScore.Away
|
||||
|
||||
switch outcome.OddName {
|
||||
case "Period 1":
|
||||
if firstPeriodTotal > secondPeriodTotal && firstPeriodTotal > thirdPeriodTotal {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
case "Period 2":
|
||||
if secondPeriodTotal > firstPeriodTotal && secondPeriodTotal > thirdPeriodTotal {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
case "Period 3":
|
||||
if thirdPeriodTotal > firstPeriodTotal && thirdPeriodTotal > secondPeriodTotal {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
case "Tie":
|
||||
if firstPeriodTotal == secondPeriodTotal || secondPeriodTotal == thirdPeriodTotal {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
default:
|
||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", outcome.OddName)
|
||||
}
|
||||
return domain.OUTCOME_STATUS_LOSS, nil
|
||||
}
|
||||
|
||||
func evaluateTiedAfterRegulation(outcome domain.BetOutcome, scores []struct{ Home, Away int }) (domain.OutcomeStatus, error) {
|
||||
totalScore := struct{ Home, Away int }{0, 0}
|
||||
for _, score := range scores {
|
||||
totalScore.Home += score.Home
|
||||
totalScore.Away += score.Away
|
||||
}
|
||||
switch outcome.OddName {
|
||||
case "Yes":
|
||||
if totalScore.Home == totalScore.Away {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
return domain.OUTCOME_STATUS_LOSS, nil
|
||||
case "No":
|
||||
if totalScore.Home != totalScore.Away {
|
||||
return domain.OUTCOME_STATUS_WIN, nil
|
||||
}
|
||||
return domain.OUTCOME_STATUS_LOSS, nil
|
||||
}
|
||||
|
||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("invalid oddname: %s", outcome.OddName)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -213,6 +213,12 @@ func (s *Service) fetchResult(ctx context.Context, eventID, oddID, marketID, spo
|
|||
s.logger.Error("Failed to parse basketball", "event_id", eventID, "market_id", marketID, "error", err)
|
||||
return domain.CreateResult{}, err
|
||||
}
|
||||
case domain.ICE_HOCKEY:
|
||||
result, err = s.parseIceHockey(resultResp.Results[0], eventID, oddID, marketID, outcome)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to parse ice hockey", "event id", eventID, "market_id", marketID, "error", err)
|
||||
return domain.CreateResult{}, err
|
||||
}
|
||||
default:
|
||||
s.logger.Error("Unsupported sport", "sport", sportID)
|
||||
return domain.CreateResult{}, fmt.Errorf("unsupported sport: %v", sportID)
|
||||
|
|
@ -283,6 +289,34 @@ func (s *Service) parseBasketball(response json.RawMessage, eventID, oddID, mark
|
|||
|
||||
}
|
||||
|
||||
func (s *Service) parseIceHockey(response json.RawMessage, eventID, oddID, marketID int64, outcome domain.BetOutcome) (domain.CreateResult, error) {
|
||||
var iceHockeyRes domain.IceHockeyResultResponse
|
||||
if err := json.Unmarshal(response, &iceHockeyRes); err != nil {
|
||||
s.logger.Error("Failed to unmarshal football result", "event_id", eventID, "error", err)
|
||||
return domain.CreateResult{}, err
|
||||
}
|
||||
if iceHockeyRes.TimeStatus != "3" {
|
||||
s.logger.Warn("Match not yet completed", "event_id", eventID)
|
||||
return domain.CreateResult{}, fmt.Errorf("match not yet completed")
|
||||
}
|
||||
|
||||
status, err := s.evaluateIceHockeyOutcome(outcome, iceHockeyRes)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to evaluate outcome", "event_id", eventID, "market_id", marketID, "error", err)
|
||||
return domain.CreateResult{}, err
|
||||
}
|
||||
|
||||
return domain.CreateResult{
|
||||
BetOutcomeID: 0,
|
||||
EventID: eventID,
|
||||
OddID: oddID,
|
||||
MarketID: marketID,
|
||||
Status: status,
|
||||
Score: iceHockeyRes.SS,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func parseScore(home string, away string) struct{ Home, Away int } {
|
||||
homeVal, _ := strconv.Atoi(strings.TrimSpace(home))
|
||||
awaVal, _ := strconv.Atoi(strings.TrimSpace(away))
|
||||
|
|
@ -311,8 +345,7 @@ func parseStats(stats []string) struct{ Home, Away int } {
|
|||
// evaluateOutcome determines the outcome status based on market type and odd
|
||||
func (s *Service) evaluateFootballOutcome(outcome domain.BetOutcome, finalScore, firstHalfScore struct{ Home, Away int }, corners struct{ Home, Away int }, events []map[string]string) (domain.OutcomeStatus, error) {
|
||||
|
||||
marketConfig := domain.SupportedMarkets["football"]
|
||||
if !marketConfig.MarketTypes[outcome.MarketID] {
|
||||
if !domain.SupportedMarkets[outcome.MarketID] {
|
||||
s.logger.Warn("Unsupported market type", "market_name", outcome.MarketName)
|
||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported market type: %s", outcome.MarketName)
|
||||
}
|
||||
|
|
@ -349,8 +382,7 @@ func (s *Service) evaluateFootballOutcome(outcome domain.BetOutcome, finalScore,
|
|||
}
|
||||
|
||||
func (s *Service) evaluateBasketballOutcome(outcome domain.BetOutcome, res domain.BasketballResultResponse) (domain.OutcomeStatus, error) {
|
||||
marketConfig := domain.SupportedMarkets["basketball"]
|
||||
if !marketConfig.MarketTypes[outcome.MarketID] {
|
||||
if !domain.SupportedMarkets[outcome.MarketID] {
|
||||
s.logger.Warn("Unsupported market type", "market_name", outcome.MarketName)
|
||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported market type: %s", outcome.MarketName)
|
||||
}
|
||||
|
|
@ -416,3 +448,42 @@ func (s *Service) evaluateBasketballOutcome(outcome domain.BetOutcome, res domai
|
|||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("market type not implemented: %s", outcome.MarketName)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) evaluateIceHockeyOutcome(outcome domain.BetOutcome, res domain.IceHockeyResultResponse) (domain.OutcomeStatus, error) {
|
||||
if !domain.SupportedMarkets[outcome.MarketID] {
|
||||
s.logger.Warn("Unsupported market type", "market_name", outcome.MarketName)
|
||||
return domain.OUTCOME_STATUS_PENDING, fmt.Errorf("unsupported market type: %s", outcome.MarketName)
|
||||
}
|
||||
finalScore := parseSS(res.SS)
|
||||
firstPeriod := parseScore(res.Scores.FirstPeriod.Home, res.Scores.FirstPeriod.Away)
|
||||
secondPeriod := parseScore(res.Scores.SecondPeriod.Home, res.Scores.SecondPeriod.Away)
|
||||
thirdPeriod := parseScore(res.Scores.ThirdPeriod.Home, res.Scores.ThirdPeriod.Away)
|
||||
|
||||
regulation := []struct{ Home, Away int }{
|
||||
firstPeriod,
|
||||
secondPeriod,
|
||||
thirdPeriod,
|
||||
}
|
||||
switch outcome.MarketID {
|
||||
case int64(domain.ICE_HOCKEY_GAME_LINES):
|
||||
return evaluateGameLines(outcome, finalScore)
|
||||
case int64(domain.ICE_HOCKEY_THREE_WAY):
|
||||
return evaluateGameLines(outcome, finalScore)
|
||||
case int64(domain.ICE_HOCKEY_FIRST_PERIOD):
|
||||
return evaluateGameLines(outcome, firstPeriod)
|
||||
case int64(domain.ICE_HOCKEY_DRAW_NO_BET):
|
||||
return evaluateDrawNoBet(outcome, finalScore)
|
||||
case int64(domain.ICE_HOCKEY_DOUBLE_CHANCE):
|
||||
return evaluateDoubleChance(outcome, finalScore)
|
||||
case int64(domain.ICE_HOCKEY_WINNING_MARGIN):
|
||||
return evaluateWinningMargin(outcome, finalScore)
|
||||
case int64(domain.ICE_HOCKEY_HIGHEST_SCORING_PERIOD):
|
||||
return evaluateHighestScoringPeriod(outcome, firstPeriod, secondPeriod, thirdPeriod)
|
||||
case int64(domain.ICE_HOCKEY_TIED_AFTER_REGULATION):
|
||||
return evaluateTiedAfterRegulation(outcome, regulation)
|
||||
case int64(domain.ICE_HOCKEY_GAME_TOTAL_ODD_EVEN):
|
||||
return evaluateGoalsOddEven(outcome, finalScore)
|
||||
}
|
||||
|
||||
return domain.OUTCOME_STATUS_PENDING, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,8 +38,7 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S
|
|||
// },
|
||||
// },
|
||||
{
|
||||
// spec: "0 */15 * * * *", // Every 15 minutes
|
||||
spec: "0 0 * * * *", // TODO: Every hour because of the 3600 requests per hour limit
|
||||
spec: "0 */15 * * * *", // Every 15 minutes
|
||||
task: func() {
|
||||
if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
|
||||
log.Printf("FetchNonLiveOdds error: %v", err)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,13 @@ func (a *App) initAppRoutes() {
|
|||
a.eventSvc,
|
||||
)
|
||||
|
||||
a.fiber.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.JSON(fiber.Map{
|
||||
"message": "Welcome to the FortuneBet API",
|
||||
"version": "1.0.1",
|
||||
})
|
||||
})
|
||||
|
||||
// Auth Routes
|
||||
a.fiber.Post("/auth/login", h.LoginCustomer)
|
||||
a.fiber.Post("/auth/refresh", h.RefreshToken)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user