package daemon /* Футбольная стратегия. ТБ 0.5 в 1м тайме */ import ( "fmt" "gordenko.dev/dima/flashscore" "gordenko.dev/dima/onexbet" "gordenko.dev/dima/tipper/model" ) type P1Over05 struct { id int64 notifyInTelegram bool isChampAccepted func(string) bool } func NewP1Over05(opt StrategyOptions) P1Over05 { if opt.ID == 0 { panic("StrategyID not defined") } s := P1Over05{} s.id = opt.ID s.notifyInTelegram = opt.NotifyInTelegram s.isChampAccepted = opt.IsChampAccepted return s } func (s P1Over05) ID() int64 { return s.id } func (s P1Over05) ShortName() string { return fmt.Sprintf("#%d H1 Over 0.5", s.id) } func (s P1Over05) IsNotifyInTelegram() bool { return s.notifyInTelegram } func (s P1Over05) GetTelegramTipPattern() string { return `Сигнал # %d. Будет ГОЛ! Алгоритм %d Первый тайм, Тотал Больше 0.5 Футбол. %s. %s %s - %s Коэф. %.3f` } type isInterestingNotesP1Over05 struct { PriceOver25 float64 `json:"Over 2.5 price"` MatchesAnalysed int `json:"matchesAnalysed"` HasGoalInP1Matches int `json:"hasGoalInP1Matches"` P1GoalsPercent float64 `json:"p1GoalsPercent"` } func (s P1Over05) IsInteresting(report *TeamMatch) (notes interface{}, _ bool) { var ( priceOver25 float64 foundPriceOver25 bool ) for _, total := range report.Odds.FullTimeTotal { if total.Total != "2.5" { continue } // 2.5 for _, offer := range total.Offers { if offer.Bookmaker == flashscore.Bookmaker1xBet { priceOver25 = offer.Over foundPriceOver25 = true break } } if foundPriceOver25 { break } else { // 1xBet не нашли // Берем первый коэф. if len(total.Offers) > 0 { priceOver25 = total.Offers[0].Over foundPriceOver25 = true } break } } if priceOver25 > 1.58 { return } var ( hasStatsMatchCount int hasGoalsInP1MatchCount int ) for _, match := range report.HomeTeamMatches { if match.HasScoreByPeriods { hasStatsMatchCount++ if match.P1HomeGoals > 0 || match.P1AwayGoals > 0 { hasGoalsInP1MatchCount++ } } } for _, match := range report.AwayTeamMatches { if match.HasScoreByPeriods { hasStatsMatchCount++ if match.P1HomeGoals > 0 || match.P1AwayGoals > 0 { hasGoalsInP1MatchCount++ } } } for _, match := range report.H2H { if match.HasScoreByPeriods { hasStatsMatchCount++ if match.P1HomeGoals > 0 || match.P1AwayGoals > 0 { hasGoalsInP1MatchCount++ } } } if hasStatsMatchCount == 0 { return } // hasStatsMatchCount - 100% // hasGoalsInP1MatchCount - x% p1GoalsPercent := float64(hasGoalsInP1MatchCount*100) / float64(hasStatsMatchCount) if p1GoalsPercent < 75 { return } obj := isInterestingNotesP1Over05{ PriceOver25: priceOver25, MatchesAnalysed: hasStatsMatchCount, HasGoalInP1Matches: hasGoalsInP1MatchCount, P1GoalsPercent: p1GoalsPercent, } //buf, _ := json.MarshalIndent(obj, "", " ") return obj, true } func (s P1Over05) GetTip(match *TeamMatch, upd onexbet.TeamLiveMatchData) (_ string, _ *BetDetails, _ TipCode) { if upd.CurrentTime == 0 { // ВАЖНО! // Матч еще не начался. Избегаем деления на 0 при вычислении attacksRatio return "матч не начался", nil, Waiting } // Прогнозы даем до 20 минуты включительно. maxTime := 20 * 60 if upd.CurrentTime > maxTime { return "20 минут уже отыграли", nil, Unwatch } if upd.HomeGoals > 0 || upd.AwayGoals > 0 { // Если гол уже забили - выходим return "гол уже забили", nil, Unwatch } // Ищем тотал Больше 0.5 // Минимальный курс minPrice := 1.5 var ( minPriceCheckPassed bool currentPrice float64 ) for _, over := range upd.H1.Total.Over { if over.Param == "0.5" { if over.Price < minPrice { return fmt.Sprintf("коэф. %.2f < %.2f", over.Price, minPrice), nil, Waiting } currentPrice = over.Price minPriceCheckPassed = true break } } if !minPriceCheckPassed { return "тотал 0.5 не найден", nil, Waiting } // соотношение атак по времени >= 2.1 (за 10 минут от 21 атаки) attacks := upd.HomeAttacks + upd.AwayAttacks shotsOffTarget := upd.HomeShotsOffTarget + upd.AwayShotsOffTarget attacksRatio := float64(attacks*60) / float64(upd.CurrentTime) if attacksRatio < 2.1 { return fmt.Sprintf("отношение атак ко времени %.2f < 2.1", attacksRatio), nil, Waiting } if shotsOffTarget < 3 { return fmt.Sprintf("%d shotsOffTarget < 6", shotsOffTarget), nil, Waiting } return "", &BetDetails{ Market: MarketTotalH1, Side: SideOver, Param: "0.5", Price: currentPrice, }, Bet } func (s P1Over05) GetResult(tip model.Tip, stats onexbet.TeamMatchResult) (_ *TipResult) { //buf, _ := json.MarshalIndent(stats, "", " ") //fmt.Printf("%s\n", buf) if stats.Status != onexbet.StatusMatchCompleted { return } h1, ok := stats.ScoreByPeriods[1] if !ok { return } //if stats.H1 == nil || stats.H2 == nil { //return //} res := new(TipResult) h1Goals := h1.HomePoints + h1.AwayPoints if h1Goals > 0 { res.Status = model.Won } else { res.Status = model.Lost } res.Result = fmt.Sprintf("1й тайм: %d-%d", h1.HomePoints, h1.AwayPoints) return res }