package daemon /* Футбольная стратегия. ТБ 0.5 в 1м тайме */ import ( "fmt" "gordenko.dev/dima/flashscore" "gordenko.dev/dima/onexbet" "gordenko.dev/dima/tipper/model" ) /* Алгоритм 2 ТБ 0.5 в Матче До матча: ТБ 2.5 (в матче) <=1.7 В 75% игр был гол В Лайве: Сумма атак обычных и опасных >= 135 6 ударов в сторону ворот OFF TARGET 4 удара в створ ON TARGET До 70 минуты */ type Over05 struct { id int64 notifyInTelegram bool isChampAccepted func(string) bool } func NewOver05(opt StrategyOptions) Over05 { if opt.ID == 0 { panic("StrategyID not defined") } s := Over05{} s.id = opt.ID s.notifyInTelegram = opt.NotifyInTelegram s.isChampAccepted = opt.IsChampAccepted return s } func (s Over05) ID() int64 { return s.id } func (s Over05) ShortName() string { return fmt.Sprintf("#%d FT Over 0.5", s.id) } func (s Over05) IsNotifyInTelegram() bool { return s.notifyInTelegram } func (s Over05) GetTelegramTipPattern() string { return `Сигнал # %d. Будет ГОЛ! Алгоритм %d Тотал Больше 0.5 Футбол. %s. %s %s - %s Коэф. %.3f` } type isInterestingNotesOver05 struct { PriceOver25 float64 `json:"Over 2.5 price"` MatchesAnalysed int `json:"matchesAnalysed"` HasGoalInMatches int `json:"hasGoalInMatches"` GoalsPercent float64 `json:"goalsPercent"` } func (s Over05) IsInteresting(report *TeamMatch) (notes interface{}, _ bool) { var ( priceOver25 float64 foundPriceOver25 bool //f flashscore.TotalOffer ) 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.7 { return } var ( matchCount int hasGoalsInMatchCount int ) for _, match := range report.HomeTeamMatches { if match.HomeGoals > 0 || match.AwayGoals > 0 { hasGoalsInMatchCount++ } matchCount++ } for _, match := range report.AwayTeamMatches { if match.HomeGoals > 0 || match.AwayGoals > 0 { hasGoalsInMatchCount++ } matchCount++ } for _, match := range report.H2H { if match.HomeGoals > 0 || match.AwayGoals > 0 { hasGoalsInMatchCount++ } matchCount++ } if matchCount == 0 { return } // matchCount - 100% // goalsInMatchCount - x% goalsPercent := float64(hasGoalsInMatchCount*100) / float64(matchCount) if goalsPercent < 75 { return } obj := isInterestingNotesOver05{ PriceOver25: priceOver25, MatchesAnalysed: matchCount, HasGoalInMatches: hasGoalsInMatchCount, GoalsPercent: goalsPercent, } //buf, _ := json.MarshalIndent(obj, "", " ") return obj, true } func (s Over05) GetTip(match *TeamMatch, upd onexbet.TeamLiveMatchData) (_ string, _ *BetDetails, _ TipCode) { if upd.CurrentTime == 0 { // ВАЖНО! // Матч еще не начался. Избегаем деления на 0 при вычислении attacksRatio return "матч не начался", nil, Waiting } // Прогнозы даем до 70 минуты включительно. maxTime := 70 * 60 if upd.CurrentTime > maxTime { return "70 минут уже отыграли", 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.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 } // attacks := upd.HomeAttacks + upd.AwayAttacks + upd.HomeDangerousAttacks + upd.AwayDangerousAttacks shotsOffTarget := upd.HomeShotsOffTarget + upd.AwayShotsOffTarget shotsOnTarget := upd.HomeShotsOnTarget + upd.AwayShotsOnTarget if attacks < 135 { return fmt.Sprintf("%d атак < 135", attacks), nil, Waiting } if shotsOffTarget < 6 { return fmt.Sprintf("%d shotsOffTarget < 6", shotsOffTarget), nil, Waiting } if shotsOnTarget < 4 { return fmt.Sprintf("%d shotsOnTarget < 4", shotsOnTarget), nil, Waiting } return "", &BetDetails{ Market: MarketTotal, Side: SideOver, Param: "0.5", Price: currentPrice, }, Bet } func (s Over05) GetResult(tip model.Tip, stats onexbet.TeamMatchResult) (_ *TipResult) { //buf, _ := json.MarshalIndent(stats, "", " ") //fmt.Printf("%s\n", buf) if stats.Status != onexbet.StatusMatchCompleted { return } res := new(TipResult) goals := stats.HomePoints + stats.AwayPoints if goals > 0 { res.Status = model.Won } else { res.Status = model.Lost } res.Result = fmt.Sprintf("счет: %d-%d", stats.HomePoints, stats.AwayPoints) return res }