Exemplo n.º 1
0
def run_stat():
    from bet import FlatLimitedProfiter
    assert predicts_db_hnd is not None, 'not opened db'

    def get_rnd(rnd_db):
        return rnd_db.split(';')[0]

    def get_prof_coef_result():
        nonlocal set2_loss_mched_cnt
        if rec.case_name == 'decided_00':
            return rec.bf_live_coef_matched, bool(rec.predict_result)
        elif rec.case_name == 'secondset_00':
            coef = 1 + (rec.bf_live_coef_matched - 1) * 0.4
            iswin = bool(rec.predict_result)
            if not iswin:
                set2_loss_mched_cnt += 1
                win_one_of = 4
                if (set2_loss_mched_cnt % win_one_of) == 0:
                    # assume win 1 of win_one_of by hedging, our plr looks ok
                    iswin = True
            return coef, iswin
        return None, None

    def do_profiter():
        if rec.bf_live_coef_matched is not None:
            prof_coef, prof_res = get_prof_coef_result()
            if prof_coef is not None:
                profiter.calculate_bet(coef=prof_coef, iswin=prof_res)

    set2_loss_mched_cnt = 0
    wl = WinLoss()
    surf_wl_dct = defaultdict(WinLoss)
    rnd_wl_dct = defaultdict(WinLoss)
    bystartbook_wl = WinLoss()
    book_start_chances = []
    profiter = FlatLimitedProfiter(start_money=9)
    predicts_db_hnd.query_predicts()
    for rec in predicts_db_hnd.records:
        if (rec.predict_result in (0, 1)
                and (not args.sex or (args.sex == rec.sex))
                and (not args.casename or (rec.case_name == args.casename))
                and (args.rejected is None or
                     (args.rejected == 1 and rec.rejected == args.rejected) or
                     (args.rejected == 0 and rec.rejected in (-1, 0)))
                and (not args.minproba or (rec.predict_proba >= args.minproba))
                and (not args.maxproba or (rec.predict_proba <= args.maxproba))
                and (args.opener is None or (args.opener and
                                             ('OPENER' in rec.comments)) or
                     (not args.opener and ('CLOSER' in rec.comments)))):
            predict_ok = bool(rec.predict_result)
            if args.stat_use_matchwinner_only:
                predict_ok = bool(rec.back_win_match)
            # print(f"{rec.back_name} {rec.oppo_name} -> {predict_ok}")
            wl.hit(iswin=predict_ok)
            surf_wl_dct[rec.surface].hit(iswin=predict_ok)
            rnd_wl_dct[get_rnd(rec.rnd)].hit(iswin=predict_ok)
            book_start_chances.append(rec.book_start_chance)
            do_profiter()
            if (rec.back_win_match in (0, 1)
                    and abs(rec.book_start_chance - 0.5) > 0.001):
                bystartbook_win = (bool(rec.back_win_match) is
                                   (rec.book_start_chance > 0.5))
                bystartbook_wl.hit(bystartbook_win)

    print(f"stat: {wl} nw: {wl.win_count} nl: {wl.loss_count}")
    pprint([(s, str(w).strip()) for s, w in surf_wl_dct.items()])
    pprint([(r, str(w).strip()) for r, w in rnd_wl_dct.items()])
    if book_start_chances:
        avg_book_start_chance = round(
            sum(book_start_chances) / len(book_start_chances), 3)
    else:
        avg_book_start_chance = None
    print(f"avg book_start_chance: {avg_book_start_chance}")
    print(f"profit by matched coefs: {profiter}")
    print(f"bystartbook wl : {bystartbook_wl}")
Exemplo n.º 2
0
class CalcSrvRatio(Calc):

    feat_corename = "srv_ratio"  # win ratio

    complete_usial_game: Dict[Scr, Scr] = {
        (0, 3): (8, 6),  # from 0:40
        (1, 3): (8, 6),  # from 15:40
        (2, 3): (6, 4),  # from 30:40
        (0, 2): (7, 5),  # from 0:30
        (1, 2): (5, 3),  # from 15:30
        (0, 1): (6, 4),  # from 0:15
        (0, 0): (4, 2),  # from 0:0
        (1, 0): (4, 1),  # from 15:0
        (1, 1): (4, 2),  # from 15:15
        (2, 0): (4, 1),  # from 30:0
        (2, 1): (4, 2),  # from 30:15
        (2, 2): (5, 3),  # from 30:30
        (3, 3): (6, 4),  # from 40:40
        (3, 2): (4, 2),  # from 40:30
        (3, 1): (4, 1),  # from 40:15
        (3, 0): (4, 0),  # from 40:0
    }

    @staticmethod
    def complete_usial_fin_score(fin_scr: Scr) -> Scr:
        """suppose: game winner is left in fin_scr"""
        if fin_scr[0] >= 4 and fin_scr[0] >= (fin_scr[1] + 2):
            return fin_scr  # ok need not complete
        res_fin_scr = CalcSrvRatio.complete_usial_game.get(fin_scr)
        if res_fin_scr is not None:
            return res_fin_scr
        if abs(fin_scr[0] - fin_scr[1]) <= 1:
            x = max(4, fin_scr[0] + 2)
            return x, fin_scr[1]
        log.warn(
            f"lose fin {fin_scr} game winner CalcSrvRatio::complete_usial_fin_score"
        )
        return 5, 4

    def __init__(self):
        self.fst_wl = WinLoss()
        self.snd_wl = WinLoss()

    def result_features(self, prefix: str) -> List[Feature]:
        f1, f2 = make_pair(
            fst_name=f"{prefix}_fst_{self.feat_corename}",
            snd_name=f"{prefix}_snd_{self.feat_corename}",
            fst_value=self.fst_wl.ratio,
            snd_value=self.snd_wl.ratio,
        )
        return [f1, f2]

    def cumul_result_features(self, prefix: str,
                              others: "List[CalcSrvRatio]") -> List[Feature]:
        fst_wl = reduce(lambda x, y: x + y, [o.fst_wl for o in others],
                        self.fst_wl)
        snd_wl = reduce(lambda x, y: x + y, [o.snd_wl for o in others],
                        self.snd_wl)
        f1, f2 = make_pair(
            fst_name=f"{prefix}_fst_{self.feat_corename}",
            snd_name=f"{prefix}_snd_{self.feat_corename}",
            fst_value=fst_wl.ratio,
            snd_value=snd_wl.ratio,
        )
        return [f1, f2]

    def proc_set(self, setitems: SetItems):
        for _, dg in setitems:
            if not dg.tiebreak:
                self._proc_usial_game(dg)
            else:
                self._proc_tiebreak(setitems, dg)

    def _proc_tiebreak(self, setitems: SetItems, dg):
        scr = (0, 0)
        for pnt in dg:
            if pnt.serve(left=True):
                srv_win = pnt.win(left=True)
                self.fst_wl.hit(srv_win)
                scr = (scr[0] + 1, scr[1]) if srv_win else (scr[0], scr[1] + 1)
            else:
                srv_win = pnt.win(left=False)
                self.snd_wl.hit(srv_win)
                scr = (scr[0], scr[1] + 1) if srv_win else (scr[0] + 1, scr[1])

        if scr <= setitems.tie_scr and scr != setitems.tie_scr:
            # approximate finishing
            x_add, y_add = setitems.tie_scr[0] - scr[0], setitems.tie_scr[
                1] - scr[1]
            x_win, x_lose = x_add // 2, y_add // 2
            self.fst_wl.add_win(x_win)
            self.fst_wl.add_loss(x_lose)
            y_win, y_lose = y_add // 2, x_add // 2
            self.snd_wl.add_win(y_win)
            self.snd_wl.add_loss(y_lose)

    def _proc_usial_game(self, dg):
        fin_scr = dg.final_num_score(before=False) or (0, 0)
        wl = self.fst_wl if dg.left_opener else self.snd_wl
        if dg.hold:
            res_fin_scr = self.complete_usial_fin_score(fin_scr)
        else:
            # game winner is right in fin_scr
            res_fin_scr = self.complete_usial_fin_score(
                co.reversed_tuple(fin_scr))
            res_fin_scr = co.reversed_tuple(
                res_fin_scr)  # we got again right dominate
        wl.add_win(res_fin_scr[0])
        wl.add_loss(res_fin_scr[1])