1st
This commit is contained in:
249
daemon/p1over05.go
Executable file
249
daemon/p1over05.go
Executable file
@@ -0,0 +1,249 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user