⚾ KBO 사용 가이드

처음 오셨군요! 아래 순서대로 하나씩 따라 하면 돼요. 어려운 낱말은 처음 나올 때 쉽게 설명해 드릴게요.

1단계 · 오늘 경기 스탯 불러오기

경기·팀 타격·선발투수 스탯은 집 컴퓨터에서 아침에 미리 올려둔 걸 그대로 받아와요. (집에서 KBO자료올리기 아이콘을 하루 한 번 누르면 준비 끝이에요.)

1
☁️ 오늘 자료 불러오기
① 아래 📋 오늘 경기 일괄분석 칸 위의 ☁️ 오늘 자료 불러오기 (폰) 버튼을 눌러요
② 오늘 경기·팀 타격·선발투수 스탯이 입력칸에 자동으로 채워져요
③ '아직 오늘 저장된 자료가 없어요'라고 뜨면, 집 컴퓨터에서 KBO자료올리기 아이콘을 먼저 눌러 올려주세요

2단계 · 벳맨 배당을 바로 아랫줄에 붙여넣고 실행

2
불러온 스탯 맨 아래에 배당 이어붙이기
① 1단계에서 자동으로 채워진 내용의 맨 아랫줄에 이어서 오늘 벳맨 배당을 경기별 블록으로 붙여넣어요
② 배당을 정리해야 하면, 아래 회색 상자의 '복사'를 눌러 Claude 같은 AI에게 벳맨(betman.co.kr) 배당 화면과 함께 주면 이 형식으로 만들어 줘요 (스탯은 이미 불러왔으니 배당만 만들면 돼요)
오늘 벳맨(betman.co.kr) 프로토 승부식의 KBO 배당을 아래 형식으로만 정리해줘. 다른 설명은 필요 없어.
경기마다 블록 하나씩. 배당은 홈팀 먼저, 핸디캡은 홈팀 라인(+/- 부호 포함) 먼저, 언더오버는 기준점 먼저·언더 먼저. 없는 마켓 줄은 생략.
블록 제목에는 벳맨에 적힌 경기 시각(한국시간)을 ` · MM.DD HH:MM` 형태로 꼭 붙여줘.
같은 두 팀이 하루에 두 경기(더블헤더)면 두 블록 모두 시각을 넣고, 벳맨에 1차전/2차전 표기가 있으면 제목 끝에 (1차전)/(2차전)도 붙여줘.

[벳맨 배당 - 롯데 vs KIA · 08.18 18:30]
승패: 1.69 1.84
승1패: 2.35 3.35 2.35
핸디: -2.5 2.92 1.26
언더오버: 9.5 1.75 1.77
전반승무패: 1.92 6.10 2.15
전반핸디: -1.5 2.64 1.32
전반언더오버: 4.5 1.96 1.60
3
일괄분석 실행
'📋 일괄분석 실행' 버튼을 누르면 모든 경기의 7개 마켓 EV가 한 번에 계산돼요
4
경기 카드에서 결장·불펜 체크하기
핵심 선수 결장이나 불펜 혹사는 자동으로 알 수 없어요. 뉴스를 확인한 뒤 각 경기 카드의 체크박스를 누르면 그 경기만 즉시 다시 계산돼요.

3단계 · 픽 저장하고 기록 남기기

5
베팅할 픽만 체크하고 저장하기
① 결과 표에서 실제로 돈을 걸 예측(픽) 옆의 네모 칸만 체크해요
'일괄 픽 기록 저장' 버튼을 눌러요 — 체크한 픽은 '베팅', 나머지 계산 픽도 참고용으로 함께 저장돼요(모델 검증에 쓰여요)
③ 여러 경기를 묶어 걸고 싶으면 '🤝 추천 조합 보기''✅ 체크한 픽 조합 평가'를 눌러 조합 EV를 확인해요
6
구글 스프레드시트에 자동 저장하기 (선택사항)
'Apps Script Web App URL'이라는 특별한 인터넷 주소를 한 번만 입력해두면, 그 뒤로는 픽을 저장할 때마다 구글 스프레드시트에도 자동으로 기록돼요.
① 아래쪽 📒 기록 · 피드백 루프 칸에 그 주소를 붙여넣어요
② 경기가 끝나면 실제 점수를 표에 입력해요
'스프레드시트에 저장' 버튼을 누르면 최종 결과가 구글 시트에 저장되고, 이 화면의 기록은 깨끗하게 비워져요

픽 등급(티어) 뜻

EV(기댓값)는 이 픽으로 돈을 벌 가능성이 얼마나 높은지 알려주는 점수예요. 이 점수를 5단계 등급으로 나눠서 보여줘요.

가치픽 — 최고예요! 지금 바로 볼만한 픽 (EV +8% 이상)
A — 아주 좋아요 (EV +5~8%)
B — 괜찮아요 (EV +2.5~5%)
C — 보통이에요 (EV 0~2.5%)
관망 — 지금은 넘기는 게 좋아요 (EV 0% 미만)
⚠️ 이 사이트는 숫자로 확률만 계산해주는 도구예요. 결과를 100% 보장하지 않으니 참고만 하시고, 안전하고 책임감 있게 즐기세요.

⚾ MLB 사용 가이드

MLB는 컴퓨터가 선수 실력 숫자(스탯)를 자동으로 가져와 줘요! KBO보다 훨씬 쉬워요.

1단계 · 경기 자동으로 불러오기

1
날짜 고르고 경기 불러오기
① 화면 위쪽에서 보고 싶은 날짜를 골라요
'경기 불러오기' 버튼을 눌러요
③ 그 날 열리는 모든 경기 목록이 나와요
2
스탯은 전부 자동이에요
경기마다 필요한 숫자들은 분석할 때 저절로 수집돼요. 손으로 직접 입력할 게 없어요!
· 선발 FIP — 투수가 얼마나 잘 던지는지 보여주는 숫자
· wRC+ — 타자들이 얼마나 잘 치는지 보여주는 숫자
· 불펜 FIP — 구원투수들 실력을 보여주는 숫자
· 구장·날씨 — 어느 야구장인지, 바람·기온 영향까지
⚠️ 가끔 자동으로 숫자를 못 가져올 때가 있어요(이걸 'CORS 오류'라고 불러요). 이럴 땐 위쪽의 'CORS 프록시' 칸에 프록시 주소를 넣고 '경기 불러오기'부터 다시 시도하면 돼요.

2단계 · 벳맨 배당을 AI에게 바로 물어보기

'배당'이란 이 경기에 돈을 걸어서 이기면 원래 건 돈의 몇 배를 받는지 알려주는 숫자예요. 스크린샷 없이 AI가 벳맨 사이트를 직접 읽고 정리해 줘요.

3
AI에게 벳맨 MLB 배당 정리 요청하기
① 아래 회색 상자 오른쪽 위의 '복사'를 눌러 Claude 같은 AI에게 줘요
② AI가 벳맨(betman.co.kr) 프로토 승부식 화면을 직접 열어 오늘 MLB 배당을 읽고 이 형식으로 정리해 줘요
오늘 벳맨(betman.co.kr) 프로토 승부식의 MLB 배당을 아래 형식으로만 정리해줘. 다른 설명은 필요 없어.
경기마다 블록 하나씩. 배당은 홈팀 먼저, 핸디캡은 홈팀 라인(+/- 부호 포함) 먼저, 언더오버는 기준점 먼저·언더 먼저. 없는 마켓 줄은 생략.
블록 제목에는 벳맨에 적힌 경기 시각(한국시간)을 ` · MM.DD HH:MM` 형태로 꼭 붙여줘.
같은 두 팀이 하루에 두 경기(더블헤더)면 두 블록 모두 시각을 넣고, 벳맨에 1차전/2차전 표기가 있으면 제목 끝에 (1차전)/(2차전)도 붙여줘.

[벳맨 배당 - 다저스 vs 자이언츠 · 08.18 11:10]
승패: 1.65 2.20
승1패: 2.10 3.40 2.60
핸디: -1.5 1.95 1.85
언더오버: 8.5 1.90 1.90
4
AI가 준 답을 배당 입력 칸에 붙여넣기 → 일괄분석 실행
① AI가 답해준 글자를 전부 선택해서 복사해요
📋 오늘 경기 일괄분석 칸 안의 배당 입력란에 붙여넣어요 (경기마다 팀명 줄이 있어야 해요 — 한 경기만 붙여넣어도 돼요)
'📋 일괄분석 실행' 버튼을 누르면 전 경기의 스탯 수집과 EV 계산이 한 번에 실행돼요

3단계 · 결과 확인하고 저장하기

5
결과 확인하고 픽 저장하기
① '오늘 경기 일괄분석' 아래에 경기별 결과 카드가 나와요
② 실제로 베팅할 픽 옆의 네모 칸에 체크해요 (체크 안 한 픽은 '참고용'으로 함께 기록돼요)
'일괄 픽 기록 저장' 버튼을 눌러요
④ 여러 경기를 묶고 싶으면 '🤝 추천 조합 보기''✅ 체크한 픽 조합 평가'를 눌러보세요
6
구글 스프레드시트에 자동 저장하기 (선택사항)
'Apps Script Web App URL'이라는 특별한 인터넷 주소를 한 번만 입력해두면, 그 뒤로는 픽을 저장할 때마다 구글 스프레드시트에도 자동으로 기록돼요.
① 아래쪽 📒 기록 · 피드백 루프 칸에 그 주소를 붙여넣어요
② 경기가 끝나면 실제 점수를 표에 입력해요
'스프레드시트에 저장' 버튼을 누르면 최종 결과가 구글 시트에 저장되고, 이 화면의 기록은 깨끗하게 비워져요

픽 등급(티어) 뜻

EV(기댓값)는 이 픽으로 돈을 벌 가능성이 얼마나 높은지 알려주는 점수예요. 이 점수를 5단계 등급으로 나눠서 보여줘요.

가치픽 — 최고예요! 지금 바로 볼만한 픽 (EV +8% 이상)
A — 아주 좋아요 (EV +5~8%)
B — 괜찮아요 (EV +2.5~5%)
C — 보통이에요 (EV 0~2.5%)
관망 — 지금은 넘기는 게 좋아요 (EV 0% 미만)
⚠️ 이 사이트는 숫자로 확률만 계산해주는 도구예요. 결과를 100% 보장하지 않으니 참고만 하시고, 안전하고 책임감 있게 즐기세요.

🏀 NBA 사용 가이드

NBA도 MLB처럼 컴퓨터가 팀 실력 숫자(스탯)를 자동으로 가져와 줘요!

1단계 · 경기 자동으로 불러오기

1
날짜 고르고 경기 불러오기
① 화면 위쪽에서 보고 싶은 날짜를 골라요. 미국 현지 날짜 기준이에요 — 한국 시간 오전에 하는 경기는 보통 미국의 '어제' 날짜예요
'경기 불러오기' 버튼을 눌러요
③ 그 날 열리는 모든 경기 목록이 나와요
2
스탯은 전부 자동이에요
경기마다 필요한 숫자들은 분석할 때 저절로 수집돼요. 손으로 직접 입력할 게 없어요!
· ORtg — 공격을 얼마나 잘하는지 보여주는 숫자 (높을수록 좋아요)
· DRtg — 수비를 얼마나 잘하는지 보여주는 숫자 (낮을수록 좋아요)
· Pace — 경기가 얼마나 빠르게 진행되는지 보여주는 숫자
· 백투백(어제도 경기한 팀)·상대전적·3점 매치업까지 자동이에요
⚠️ 주전 선수가 부상으로 못 나오는지는 자동으로 알 수 없어요. 계산이 끝나면 각 경기 카드의 '핵심 결장' 체크박스를 직접 켜 주세요 — 바로 다시 계산돼요.
⚠️ 가끔 자동으로 숫자를 못 가져올 때가 있어요(이걸 'CORS 오류'라고 불러요). 이럴 땐 MLB 탭의 'CORS 프록시' 칸에 프록시 주소를 넣고 '경기 불러오기'부터 다시 시도하면 돼요.

2단계 · 배당(이기면 받는 배수) 넣기

'배당'이란 이 경기에 돈을 걸어서 이기면 원래 건 돈의 몇 배를 받는지 알려주는 숫자예요.

3
베트맨 배당 화면 캡처해서 AI에게 보내기
① 베트맨 사이트에서 오늘 경기의 배당 화면을 스크린샷(화면 캡처)해요
② 아래 회색 상자 오른쪽 위의 '복사' 버튼을 눌러요 (AI에게 보낼 질문 글이 복사돼요)
③ Claude나 Gemini 같은 AI 채팅 화면을 열고, 방금 찍은 스크린샷과 방금 복사한 글을 함께 붙여넣어 보내요
이 베트맨 NBA 배당 스크린샷의 수치를 아래 형식으로만 출력해줘. 경기마다 첫 줄에 "홈팀 vs 원정팀" 팀명 줄을 쓰고, 없는 마켓은 생략해. 여러 경기면 경기 사이에 빈 줄 하나. 다른 설명은 필요 없어.

[홈팀명] vs [원정팀명]
승패: [홈배당] [원정배당]
핸디: [홈핸디라인(+/-부호포함)] [홈배당] [원정배당]
언더오버: [기준점수] [언더배당] [오버배당]
4
AI가 준 답을 배당 입력 칸에 붙여넣기 → 일괄분석 실행
① AI가 답해준 글자를 전부 선택해서 복사해요
📋 오늘 경기 일괄분석 칸 안의 배당 입력란에 붙여넣어요 (경기마다 팀명 줄이 있어야 해요 — 한 경기만 붙여넣어도 돼요)
'📋 일괄분석 실행' 버튼을 누르면 전 경기의 스탯 수집과 EV 계산이 한 번에 실행돼요

3단계 · 결과 확인하고 저장하기

5
결과 확인하고 픽 저장하기
① '오늘 경기 일괄분석' 아래에 경기별 결과 카드가 나와요
② 부상 결장이 있는 팀은 카드의 '핵심 결장' 체크를 켜요 (바로 다시 계산돼요)
③ 실제로 베팅할 픽 옆의 네모 칸에 체크해요 (체크 안 한 픽은 '참고용'으로 함께 기록돼요)
'일괄 픽 기록 저장' 버튼을 눌러요
⑤ 여러 경기를 묶고 싶으면 '🤝 추천 조합 보기''✅ 체크한 픽 조합 평가'를 눌러보세요
6
경기 끝나면 점수 입력하기
NBA는 연장까지 다 끝난 최종 점수를 기록 표에 입력하면 돼요. 그러면 맞았는지(W) 틀렸는지(L) 자동으로 판정돼요. 구글 스프레드시트 연동은 KBO·MLB와 똑같이 쓰면 돼요.

픽 등급(티어) 뜻

EV(기댓값)는 이 픽으로 돈을 벌 가능성이 얼마나 높은지 알려주는 점수예요. 이 점수를 5단계 등급으로 나눠서 보여줘요.

가치픽 — 최고예요! 지금 바로 볼만한 픽 (EV +8% 이상)
A — 아주 좋아요 (EV +5~8%)
B — 괜찮아요 (EV +2.5~5%)
C — 보통이에요 (EV 0~2.5%)
관망 — 지금은 넘기는 게 좋아요 (EV 0% 미만)
⚠️ 이 사이트는 숫자로 확률만 계산해주는 도구예요. 결과를 100% 보장하지 않으니 참고만 하시고, 안전하고 책임감 있게 즐기세요.

⚽ 해외축구 사용 가이드

EPL·라리가·세리에A·분데스리가를 지원해요. 축구는 야구·농구와 달리 무승부가 자주 나와서, 무승부도 항상 하나의 픽 후보로 함께 평가해요.

1단계 · 리그 고르고 경기 자동으로 불러오기

1
리그 선택
화면 위쪽의 리그 버튼(EPL·라리가·세리에A·분데스리가) 중 하나를 눌러요. 마지막에 고른 리그는 기억돼요. 리그마다 득점 수준과 무승부 성향이 달라서, '리그 기준값' 카드의 숫자도 리그별로 따로 관리돼요.
2
경기 불러오기 — 스탯은 전부 자동이에요
'경기 불러오기' 버튼을 눌러요 — Understat라는 축구 통계 사이트에서 예정 경기와 팀 실력 숫자를 가져와요
② 경기마다 필요한 숫자들은 분석할 때 저절로 수집돼요. 손으로 직접 입력할 게 없어요!
· xG(기대득점) — 슛의 위치·상황을 바탕으로 '보통 이 슛이면 몇 골'인지 계산한 숫자예요. 실제 골보다 팀의 진짜 공격력을 더 잘 보여줘요
· 피xG — 상대에게 내준 xG예요. 낮을수록 수비가 좋다는 뜻이에요
· 상대전적(상성) — 두 팀의 최근 리그 맞대결(지난 시즌 포함, 최대 4경기)에서 어느 쪽이 내용상 우세했는지
· 분위기 지수 — 최근 5경기에서 기대(xG)보다 실제 결과가 좋았던 '상승세' 팀인지
· 리그 일정상 3일 안에 경기한 팀이면 '피로'도 자동으로 반영돼요
⚠️ 핵심 선수 결장, 챔피언스리그 같은 유럽대항전 일정, 팀의 동기부여(강등권 혈투인지, 시즌이 다 끝난 팀인지)는 자동으로 알 수 없어요. 계산이 끝나면 각 경기 카드의 체크박스를 직접 켜 주세요 — 바로 다시 계산돼요.
⚠️ 가끔 자동으로 숫자를 못 가져올 때가 있어요(이걸 'CORS 오류'라고 불러요). 이럴 땐 MLB 탭의 'CORS 프록시' 칸에 프록시 주소를 넣고 '경기 불러오기'부터 다시 시도하면 돼요.

2단계 · 배당(이기면 받는 배수) 넣기

'배당'이란 이 경기에 돈을 걸어서 이기면 원래 건 돈의 몇 배를 받는지 알려주는 숫자예요.

3
베트맨 배당 화면 캡처해서 AI에게 보내기
① 베트맨 사이트에서 해당 경기의 배당 화면을 스크린샷(화면 캡처)해요
② 아래 회색 상자 오른쪽 위의 '복사' 버튼을 눌러요 (AI에게 보낼 질문 글이 복사돼요)
③ Claude나 Gemini 같은 AI 채팅 화면을 열고, 방금 찍은 스크린샷과 방금 복사한 글을 함께 붙여넣어 보내요
이 베트맨 해외축구 배당 스크린샷의 수치를 아래 형식으로만 출력해줘. 경기마다 첫 줄에 "홈팀 vs 원정팀" 팀명 줄을 영문 공식 팀명으로 쓰고(예: Arsenal vs Chelsea), 없는 마켓은 생략해. 여러 경기면 경기 사이에 빈 줄 하나. 핸디캡 라인이 0.5 단위(무 항목이 없는 경기)면 무배당은 생략해. 다른 설명은 필요 없어.

[홈팀명(영문)] vs [원정팀명(영문)]
승무패: [홈배당] [무배당] [원정배당]
핸디캡: [홈핸디라인(+/-부호포함)] [홈배당] [무배당] [원정배당]
언더오버: [기준골] [언더배당] [오버배당]
4
AI가 준 답을 배당 입력 칸에 붙여넣기 → 일괄분석 실행
① AI가 답해준 글자를 전부 선택해서 복사해요
📋 예정 경기 일괄분석 칸 안의 배당 입력란에 붙여넣어요 (경기마다 팀명 줄이 있어야 해요 — 한 경기만 붙여넣어도 돼요. 영문 팀명을 권장하지만 주요 구단은 한글도 인식해요)
'📋 일괄분석 실행' 버튼을 누르면 전 경기의 스탯 수집과 EV 계산이 한 번에 실행돼요

3단계 · 결과 확인하고 저장하기

5
결과 확인하고 픽 저장하기
① '예정 경기 일괄분석' 아래에 경기별 결과 카드가 나와요 — 승무패(무승부 포함!)·핸디캡·언더오버의 EV를 확인해요. 배당이 말하는 확률(de-vig)과 모델 확률의 차이가 곧 가치예요
② 결장·유럽대항전 피로·동기부여가 있는 팀은 카드의 체크박스를 켜요 (바로 다시 계산돼요)
③ 실제로 베팅할 픽 옆의 네모 칸에 체크해요 (체크 안 한 픽은 '참고용'으로 함께 기록돼요)
'일괄 픽 기록 저장' 버튼을 눌러요
⑤ 여러 경기를 묶고 싶으면 '🤝 추천 조합 보기''✅ 체크한 픽 조합 평가'를 눌러보세요
6
경기 끝나면 점수 입력하기
기록 표에 90분(연장 제외) 최종 점수를 입력하면 맞았는지(W) 틀렸는지(L) 자동으로 판정돼요. 구글 스프레드시트 연동은 다른 종목과 똑같이 쓰면 돼요.

픽 등급(티어) 뜻

EV(기댓값)는 이 픽으로 돈을 벌 가능성이 얼마나 높은지 알려주는 점수예요. 이 점수를 5단계 등급으로 나눠서 보여줘요.

가치픽 — 최고예요! 지금 바로 볼만한 픽 (EV +8% 이상)
A — 아주 좋아요 (EV +5~8%)
B — 괜찮아요 (EV +2.5~5%)
C — 보통이에요 (EV 0~2.5%)
관망 — 지금은 넘기는 게 좋아요 (EV 0% 미만)
⚠️ 이 사이트는 숫자로 확률만 계산해주는 도구예요. 결과를 100% 보장하지 않으니 참고만 하시고, 안전하고 책임감 있게 즐기세요.

🔒 접근 비밀번호

EV Bet · 스포츠 배당 가치분석

de-vig 확률 · P_model · EV · 켈리 기준 스테이크

Betman Odds · Quantitative Value Analysis

그 배당, 실제 확률보다
후한가요?

배트맨 공식 배당에서 마진(vig)을 걷어내 시장의 내재 확률을 구하고, 포아송·정규분포 기반 통계 모델의 확률과 비교합니다. 둘의 차이가 곧 기댓값(EV) — 이 도구는 EV가 양수인 픽만 골라냅니다.

현재 모든 기능 무료 제공

How It Works

세 단계, 전부 공개된 수식으로.

블랙박스 픽방이 아닙니다. 어떤 숫자가 들어가 어떤 계산을 거치는지 전 과정이 화면에 그대로 표시됩니다.

p_fair = (1/odds) / Σ(1/odds)

1 · 시장의 거품 제거

배당의 역수 합은 항상 1을 넘습니다 — 그 초과분이 마진(vig)입니다. de-vig 정규화로 마진을 걷어내 시장의 순수한 내재 확률을 복원합니다.

P_model = f(스탯, 분포모델)

2 · 모델 확률 추정

야구는 FIP·wRC+·GB%·ISO·구장·날씨 보정을 거친 포아송/정규 모델, 농구는 ORtg·DRtg·페이스 기반 마진 정규분포, 축구는 xG 포아송 모델로 경기별 확률을 계산합니다.

EV = P_model × odds − 1

3 · EV와 배팅 크기

모델 확률이 내재 확률을 이길 때만 EV가 양수가 됩니다. 권장 비중은 쿼터 켈리(¼ Kelly)에 뱅크롤 2% 상한을 걸어 보수적으로 산출합니다.

Tier System

모든 픽이 같지 않습니다.

EV 크기에 따라 5개 등급으로 나눕니다. 등급이 낮으면 낮다고, 우위가 없으면 없다고 말하는 것이 이 도구의 규칙입니다.

가치픽EV ≥ +8%단폴더 후보
최우선 검토
A+5 ~ 8%뚜렷한 우위
B+2.5 ~ 5%완만한 우위
C0 ~ +2.5%경계선
신중 접근
관망EV < 0배팅 비권장
오늘은 쉬는 날

Coverage · 리그 선택

5개 리그, 리그마다 다른 모델.

카드를 누르면 해당 리그 분석 화면으로 이동합니다. 종목의 득점 구조가 다르면 확률 모델도 달라야 합니다.

KBO

승패 · 핸디캡 · 승1패 · 언더오버 + 전반 3마켓. 선발 FIP와 팀 타격 지표, 구장 팩터, 날씨 보정까지 반영하는 가장 깊은 모델.

풀게임 7마켓

MLB

MLB StatsAPI 연동으로 선발·팀 스탯이 자동으로 채워집니다. 경기 선택 후 배당만 입력하면 끝.

4마켓 · 자동채움
🏀

NBA

ORtg·DRtg·페이스 기반 마진 모델. 백투백 자동 판정, 3점 스타일 매치업, 상대전적 보정 포함.

3마켓 · 자동채움

해외축구

EPL · 라리가 · 세리에A · 분데스리가. xG 기반 포아송 모델로 승무패·핸디캡·언더오버를 평가합니다.

3마켓 · 자동채움

NPB

일본프로야구. KBO 모델 이식 — 선발 FIP·타선 wRC+·ISO 보정, 텍스트 붙여넣기 일괄분석. 초기 미검증 모델로 보수적 등급을 적용합니다.

4마켓 · 일괄

ROADMAP → 픽 성과 대시보드(적중률·ROI 공개) · 프리미엄 기능 단계적 도입 예정

Principles

이 도구가 하지 않는 것.

수익을 보장하지 않습니다

EV는 장기 기댓값이지 오늘의 결과 예언이 아닙니다. +EV 픽도 절반 가까이는 집니다 — 이기는 건 확률이 아니라 반복입니다.

매일 픽을 만들어내지 않습니다

우위가 없는 날엔 관망을 출력합니다. 억지로 픽을 뽑는 도구는 도구가 아니라 유혹입니다.

계산을 숨기지 않습니다

내재확률, 모델확률, EV, 켈리 비중 — 모든 중간값이 표로 공개됩니다. 판단의 주체는 언제나 사용자입니다.

오늘 경기, 숫자로 먼저 보세요.

현재 모든 기능 무료

리그 선택하고 분석 시작 →
⚠️ 본 서비스는 국민체육진흥공단 배트맨이 공식 발행한 배당률을 통계적으로 분석하는 참고용 확률 추정 도구입니다. 어떠한 수익도 보장하지 않으며, 배팅의 판단과 책임은 전적으로 이용자 본인에게 있습니다. 감당 가능한 금액으로, 책임감 있는 배팅을 하세요.
19체육진흥투표권 구매는 만 19세 이상만 가능합니다. EV Bet · de-vig → P_model → EV → ¼ Kelly

최근 폼 가중치 35%

혼합값 = (1−w)×시즌 + w×최근5. 최근값 칸을 비우면 시즌값만 사용. 표본 작으면 보수적으로(권장 30~40%).

📋 오늘 경기 일괄분석

라인업 직전/날씨급변/저유동성 — 미체크 시 승패·언더오버 EV 문턱 +10%
Claude에게 받은 '경기 · 팀 타격 · 선발투수 · 벳맨 배당' 텍스트를 통째로 붙여넣고 '일괄분석 실행'을 누르면 모든 경기의 7마켓 EV가 한 번에 계산돼요. ⚠️ 핵심 결장·불펜 혹사는 자동으로 알 수 없어요 — 계산 후 각 경기 카드의 체크박스로 반영하세요(즉시 재계산).

🤖 자동입력 (MLB StatsAPI 직접호출)

날짜 선택 → '경기 불러오기' → 아래 배당 입력칸에 배당을 붙여넣고 '📋 일괄분석 실행'을 누르면 전 경기 일괄분석이 실행돼요. CORS 차단 시 프록시 URL 입력 후 재시도 (사용법 📖 참고).

📋 오늘 경기 일괄분석

MLB는 효율시장 — 미체크 시 승패·언더오버 EV 문턱 +10%
위에서 '경기 불러오기' 실행 → 아래 칸에 경기별 배당을 팀명 줄과 함께 붙여넣고 '📋 일괄분석 실행'을 누르면 전 경기 EV가 여기에 계산돼요. 선발 FIP·타선·불펜·구장·날씨는 자동 수집돼요.

⚽ 리그 선택 · 자동입력 (Understat)

리그 선택 → '경기 불러오기' → 아래 배당 입력칸에 배당을 붙여넣고 '📋 일괄분석 실행'을 누르면 전 경기 일괄분석이 실행돼요. CORS 차단 시 MLB 탭에 저장한 프록시 URL을 자동으로 함께 사용해요.

📋 예정 경기 일괄분석

리그마다 득점 수준·홈 이점·무승부 성향이 달라서 기준값을 따로 써요. 기본값은 2025/26 시즌 실측이고, 수정하면 리그별로 저장돼요 — 시즌이 바뀌면 '경기 불러오기'가 평균 득점·xG를 자동 갱신해요(홈 배수·ρ는 직접 관리). ρ는 음수일수록 무승부 확률을 높여요(권장 −0.03 ~ −0.10).
결장 속보/라인 급변/저유동성 — 미체크 시 승무패·언더오버 EV 문턱 +10%
위에서 '경기 불러오기' 실행 → 아래 칸에 경기별 배당을 팀명 줄(영문 권장, 주요 구단은 한글도 인식)과 함께 붙여넣고 '📋 일괄분석 실행'을 누르면 전 경기 EV가 여기에 계산돼요. 두 팀 xG·피xG(시즌+최근5)·상대전적(상성)·분위기·3일 내 경기는 자동 수집돼요. ⚠️ 핵심 선수 결장·유럽대항전 일정·동기부여는 자동으로 알 수 없어요 — 계산 후 각 경기 카드의 체크박스로 반영하세요(즉시 재계산). 무승부는 승무패에서 항상 독립 후보로 평가되고, 정수 핸디 라인은 '핸디 무' 포함 3지선다로 계산돼요.

🤖 자동입력 (NBA 공식 데이터)

날짜는 미국 현지 기준이에요 (한국 시간으로는 보통 다음날 오전 경기). '경기 불러오기' 후 아래 배당 입력칸에 배당을 붙여넣고 '📋 일괄분석 실행'을 누르면 전 경기 일괄분석이 실행돼요. CORS 차단 시 MLB 탭에 저장한 프록시 URL을 자동으로 함께 사용해요.

📋 오늘 경기 일괄분석

부상 속보/라인 급변/저유동성 — 미체크 시 승패·언더오버 EV 문턱 +10%
위에서 '경기 불러오기' 실행 → 아래 칸에 경기별 배당을 팀명 줄과 함께 붙여넣고 '📋 일괄분석 실행'을 누르면 전 경기 EV가 여기에 계산돼요. ORtg·DRtg·Pace(시즌+최근10)·3점 매치업·백투백·상대전적은 자동 수집돼요. ⚠️ 핵심 선수 결장은 자동으로 알 수 없어요 — 계산 후 각 경기 카드의 '핵심 결장' 체크로 반영하세요(즉시 재계산).
⚠️ 초기 미검증 모델 · 보수적 등급 적용 중 — 검증 표본 축적 전까지 참고용

📋 오늘 경기 일괄분석

☁️ 오늘 자료 불러오기로 스탯을 채우고 → ② 그 맨 아래에 벳맨 배당 블록을 이어붙인 뒤 → ③ '일괄분석 실행'을 누르면 모든 경기의 4마켓 EV가 한 번에 계산돼요. 스탯이 없는 경기는 기본값(wRC+ 100·리그평균 FIP)으로 계산되며 경고가 표시돼요. ⚠️ 핵심 결장·불펜 혹사는 자동으로 알 수 없어요 — 계산 후 각 경기 카드의 체크박스로 반영하세요(즉시 재계산).
② 불러온 스탯의 맨 아랫줄에 이어서 오늘 벳맨 배당을 붙여넣어요. 아래 '복사'를 눌러 Claude 같은 AI에게 벳맨(betman.co.kr) 배당 화면과 함께 주면 이 형식으로 만들어 줘요. (스탯은 이미 불러왔으니 배당만 만들면 돼요)
오늘 벳맨(betman.co.kr) 프로토 승부식의 일본프로야구(NPB) 배당을 아래 형식으로만 정리해줘. 다른 설명은 필요 없어.
경기마다 블록 하나씩. 팀명은 아래 12개 한글 표기만 써: 요미우리 한신 DeNA 히로시마 야쿠르트 주니치 소프트뱅크 니혼햄 오릭스 라쿠텐 롯데 세이부.
배당은 홈팀 먼저, 핸디캡은 홈팀 라인(+/- 부호 포함) 먼저, 언더오버는 기준점 먼저·언더 먼저. 4줄 모두 있어야 계산되니 빠진 마켓이 있으면 그 경기는 통째로 빼줘.
블록 제목에는 벳맨에 적힌 경기 시각(한국시간)을 ` · MM.DD HH:MM` 형태로 꼭 붙여줘.
같은 두 팀이 하루에 두 경기(더블헤더)면 두 블록 모두 시각을 넣고, 벳맨에 1차전/2차전 표기가 있으면 제목 끝에 (1차전)/(2차전)도 붙여줘.

[벳맨 배당 - 주니치 vs 한신 · 08.18 18:00]
승패: 2.40 1.39
승1패: 4.20 2.75 1.83
핸디: +2.5 1.37 2.46
언더오버: 5.5 1.80 1.72
계산 근거

📒 기록 · 피드백 루프

☁️ Google Sheets 연동 미연결
기기마다 처음 1회: Apps Script Web App URL 입력 → 같은 URL을 넣은 모든 기기가 열 때마다 최신 저장값(픽)으로 자동 동기화됩니다. 코드를 수정한 뒤에는 아래 [B] 재배포만 하면 됩니다 — 처음부터 다시 만들 필요 없어요.
(Apps Script 설치 · 재배포 방법)
[A] 최초 설치 — 계정당 딱 한 번만
① 새 구글 스프레드시트를 만들어요 (sheets.new 접속, 또는 드라이브에서 '새로 만들기 → Google 스프레드시트')
② 위쪽 메뉴에서 확장 프로그램 → Apps Script를 클릭해요
③ 편집 화면에 있는 기존 코드를 전부 지우고, 아래 '복사' 버튼으로 코드를 복사해서 붙여넣어요
④ 위쪽 저장(디스켓 모양) 아이콘을 눌러요
⑤ 오른쪽 위 배포 → 새 배포를 클릭해요 — '새 배포'는 여기, 최초 1회에만 씁니다
⑥ '유형 선택' 옆 톱니바퀴 아이콘을 누르고 웹 앱을 선택해요
⑦ 실행 사용자는 , 액세스 권한이 있는 사용자는 반드시 전체로 선택해요 (다른 걸 고르면 사이트에서 연결이 안 돼요)
⑧ '배포' 버튼을 눌러요 → 처음 한 번은 구글이 권한을 확인해요. '액세스 승인' → 본인 계정을 선택해요
⚠️ 이때 "Google에서 이 앱을 확인하지 않았습니다"라는 빨간 경고 화면이 뜰 수 있어요. 내가 직접 만든 스크립트라 안전하니 당황하지 말고, 화면 왼쪽 아래 고급을 누른 뒤 맨 아래 '(프로젝트 이름)(으)로 이동(안전하지 않음)'을 눌러 계속 진행하세요.
→ 다음 화면에서 요청 권한을 확인하고 허용을 누르면 완료돼요
⑨ 배포가 끝나면 …/exec로 끝나는 웹 앱 URL이 나와요. 이 주소를 복사해요
⑩ 위 'Apps Script Web App URL' 칸에 붙여넣고 '연결 테스트' 버튼을 눌러 "✅ 연결 성공"이 뜨는지 확인해요

[B] 코드를 수정한 뒤 재배포 — 앞으로는 항상 이것만
① 편집 화면의 코드를 전부 지우고 아래 최신 코드를 붙여넣은 뒤 저장해요
② 오른쪽 위 배포 → 배포 관리를 클릭해요
연필(수정) 아이콘을 누르고, 버전을 '새 버전'으로 바꾼 뒤 배포를 눌러요
URL은 그대로 유지돼요 — 앱에 입력한 주소를 다시 바꿀 필요가 없어요
⑤ 위 '연결 테스트'를 눌러 "✅ 연결 성공"이 뜨는지 확인해요
🚨 재배포할 때 '새 배포'를 누르지 마세요 — 연동이 끊깁니다
'새 배포'는 매번 새 URL을 만들어요. 앱에 입력해 둔 주소는 그대로 옛 배포를 계속 부르기 때문에, 코드를 고쳐도 앱에는 영영 반영되지 않아요. 화면에는 "연결 성공"이 뜨는데 새 기능만 조용히 안 되는 상태가 돼요.
※ 실제 사고: 활성 배포가 2개가 되어 9일 동안 옛 코드가 돌았어요.

배포 목록에 항목이 여러 개라면 — '배포 관리' 화면에서 위 URL 칸에 입력한 주소와 웹 앱 URL이 같은 항목을 골라 연필로 수정해야 해요. 엉뚱한 항목을 새 버전으로 올리면 앱이 부르는 배포는 여전히 낡은 채로 남아요.
쓰지 않는 배포는 배포 관리 → 점 세 개 → 보관 처리로 정리해 두면 다음에 헷갈리지 않아요.
💡 '연결 테스트'가 배포된 코드의 버전을 앱 코드와 비교해요 — 낡았으면 "배포된 코드가 낡았습니다"라고 알려줘요.
function doGet(e){
  var action=e.parameter.action;
  if(action==='ping')return json_({ok:true,v:4});
  if(action==='getPicks')return json_({picks:readAll_()});
  if(action==='getTeamDB')return json_(readTeamDB_());
  if(action==='getKbo')return json_(readKbo_());
  if(action==='getNpb')return json_(readNpb_());
  if(action==='getCloseOdds')return json_(readCloseOdds_());
  return json_({ok:false,error:'unknown action'});
}

function doPost(e){
  var lock=LockService.getScriptLock();
  lock.waitLock(20000);
  try{
    var body=JSON.parse(e.postData.contents);
    if(body.action==='appendPicks'||body.action==='upsertPicks'){upsertPicks_(body.picks||[],false);return json_({ok:true,v:3});}
    if(body.action==='syncFinalPicks'){upsertPicks_(body.picks||[],true);return json_({ok:true,v:3});}
    if(body.action==='deletePicks'){deletePicks_(body.keys||[]);return json_({ok:true,v:3});}
    if(body.action==='saveTeamDB'){var t=saveTeamDB_(body.teamDB||{});return json_({ok:true,v:2,savedAt:t});}
    if(body.action==='saveKbo'){var tk=saveKbo_(String(body.text||''));return json_({ok:true,savedAt:tk});}
    if(body.action==='saveNpb'){var tn=saveNpb_(String(body.text||''));return json_({ok:true,savedAt:tn});}
    if(body.action==='saveCloseOdds'){var tc=saveCloseOdds_(String(body.league||''),String(body.text||''));return json_({ok:true,savedAt:tc});}
    return json_({ok:false,error:'unknown action'});
  }finally{lock.releaseLock();}
}

// 새 열은 반드시 배열 '끝'에만 추가 — 중간 삽입 시 기존 시트의 데이터 행과 열 위치가 어긋남
var HEADERS=['savedAt','date','league','match','market','pick','P','fair','ev','odds','stake','score','tier','expTotal','expMargin','actHome','actAway','actH1Home','actH1Away','hFIP','aFIP','hWRC','aWRC','hBP','aBP','hGB','aGB','PF','weather','wWeight','edge','result','archived','closeOdds','staked','closeLine'];

function sheet_(){
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  var sh=ss.getSheetByName('Picks');
  if(!sh){ sh=ss.insertSheet('Picks'); sh.appendRow(HEADERS); }
  if(sh.getMaxColumns()<HEADERS.length)sh.insertColumnsAfter(sh.getMaxColumns(),HEADERS.length-sh.getMaxColumns());
  if(sh.getRange(1,HEADERS.length).getValue()!==HEADERS[HEADERS.length-1])sh.getRange(1,1,1,HEADERS.length).setValues([HEADERS]);
  return sh;
}

var TEAMDB_HEADERS=['team','wrc','wrcR','slg','avg','savedAt'];

function teamDbSheet_(){
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  var sh=ss.getSheetByName('TeamDB');
  if(!sh){ sh=ss.insertSheet('TeamDB'); sh.appendRow(TEAMDB_HEADERS); }
  return sh;
}

function saveTeamDB_(teamDB){
  var sh=teamDbSheet_();
  var savedAt=new Date().toISOString(); // 저장 시각은 서버가 찍음 — 기기 시계가 어긋나도 순서 보장
  sh.clearContents();
  sh.appendRow(TEAMDB_HEADERS);
  Object.keys(teamDB).forEach(function(team){
    var t=teamDB[team]||{};
    sh.appendRow([team, t.wrc==null?'':t.wrc, t.wrcR==null?'':t.wrcR, t.slg==null?'':t.slg, t.avg==null?'':t.avg, savedAt]);
  });
  return savedAt;
}

function readTeamDB_(){
  var sh=teamDbSheet_();
  var data=sh.getDataRange().getValues();
  var db={}, savedAt='';
  for(var i=1;i<data.length;i++){
    var row=data[i]; if(!row[0])continue;
    db[row[0]]={wrc:row[1]===''?null:row[1], wrcR:row[2]===''?null:row[2], slg:row[3]===''?null:row[3], avg:row[4]===''?null:row[4]};
    if(row[5])savedAt=row[5] instanceof Date?row[5].toISOString():String(row[5]);
  }
  return {teamDB:db, savedAt:savedAt};
}

// KBO 하루치 스탯 텍스트(경기·팀타격·선발 블록)를 한 칸에 통째로 저장 — 집에서 올리고 폰에서 그대로 불러옴
function kboSheet_(){
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  var sh=ss.getSheetByName('KBO');
  if(!sh){ sh=ss.insertSheet('KBO'); sh.appendRow(['text','savedAt']); }
  return sh;
}
function saveKbo_(text){
  var sh=kboSheet_();
  var savedAt=new Date().toISOString(); // 저장 시각은 서버가 찍음
  sh.clearContents();
  sh.appendRow(['text','savedAt']);
  sh.appendRow([text, savedAt]);
  return savedAt;
}
function readKbo_(){
  var sh=kboSheet_();
  var data=sh.getDataRange().getValues();
  if(data.length<2)return {text:'',savedAt:''};
  var row=data[1];
  var savedAt=row[1] instanceof Date?row[1].toISOString():String(row[1]||'');
  return {text:String(row[0]||''), savedAt:savedAt};
}

// NPB 하루치 스탯 텍스트([경기N] 블록)를 한 칸에 통째로 저장 — KBO와 같은 방식, 시트만 분리
function npbSheet_(){
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  var sh=ss.getSheetByName('NPB');
  if(!sh){ sh=ss.insertSheet('NPB'); sh.appendRow(['text','savedAt']); }
  return sh;
}
function saveNpb_(text){
  var sh=npbSheet_();
  var savedAt=new Date().toISOString(); // 저장 시각은 서버가 찍음
  sh.clearContents();
  sh.appendRow(['text','savedAt']);
  sh.appendRow([text, savedAt]);
  return savedAt;
}
function readNpb_(){
  var sh=npbSheet_();
  var data=sh.getDataRange().getValues();
  if(data.length<2)return {text:'',savedAt:''};
  var row=data[1];
  var savedAt=row[1] instanceof Date?row[1].toISOString():String(row[1]||'');
  return {text:String(row[0]||''), savedAt:savedAt};
}

// 마감배당(배트맨 고정배당) 텍스트 — 리그마다 한 행. 리그별로 나눠야 MLB 수집이 KBO 값을 지우지 않는다.
function closeOddsSheet_(){
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  var sh=ss.getSheetByName('CloseOdds');
  if(!sh){ sh=ss.insertSheet('CloseOdds'); sh.appendRow(['league','text','savedAt']); }
  return sh;
}
function saveCloseOdds_(league,text){
  var sh=closeOddsSheet_();
  var savedAt=new Date().toISOString(); // 저장 시각은 서버가 찍음
  var data=sh.getDataRange().getValues();
  for(var i=1;i<data.length;i++){
    if(String(data[i][0])===league){ sh.getRange(i+1,1,1,3).setValues([[league,text,savedAt]]); return savedAt; }
  }
  sh.appendRow([league,text,savedAt]);
  return savedAt;
}
function readCloseOdds_(){
  var sh=closeOddsSheet_();
  var data=sh.getDataRange().getValues();
  var out=[];
  for(var i=1;i<data.length;i++){
    if(!data[i][0])continue;
    var savedAt=data[i][2] instanceof Date?data[i][2].toISOString():String(data[i][2]||'');
    out.push({league:String(data[i][0]), text:String(data[i][1]||''), savedAt:savedAt});
  }
  return {entries:out};
}

function json_(obj){
  return ContentService.createTextOutput(JSON.stringify(obj)).setMimeType(ContentService.MimeType.JSON);
}

// 픽 식별키: 저장시각(초 단위 정규화)|리그|경기|마켓|픽 — 사이트 쪽 pickKey와 동일 규칙.
// v3: league·match를 키에 추가(이전엔 savedAt|market|pick뿐이라, 같은 배치 저장(=savedAt 동일)에
// 여러 경기가 "승패/기준팀승"처럼 같은 마켓·픽 문구를 공유하면 서로 다른 경기인데도 같은 행으로 겹쳐써졌음).
function keyOf_(savedAt,date,league,match,market,pick){
  var s=savedAt instanceof Date?savedAt.toISOString():String(savedAt||date||'');
  var t=Date.parse(s);
  var norm=isNaN(t)?s:new Date(t).toISOString().slice(0,19);
  return norm+'|'+(league||'')+'|'+(match||'')+'|'+market+'|'+pick;
}

// 같은 키의 픽이 있으면 그 행을 갱신, 없으면 추가. finalize=true면 아카이브 표시(모든 기기 목록에서 제외)
function upsertPicks_(picks,finalize){
  var sh=sheet_();
  var data=sh.getDataRange().getValues();
  var rowByKey={};
  for(var i=1;i<data.length;i++){rowByKey[keyOf_(data[i][0],data[i][1],data[i][2],data[i][3],data[i][4],data[i][5])]=i;}
  picks.forEach(function(p){
    if(finalize)p.archived='1';
    var key=keyOf_(p.savedAt,p.date,p.league,p.match,p.market,p.pick);
    var i=rowByKey[key];
    if(i===-1)return;
    if(i!==undefined){
      var row=HEADERS.map(function(h,c){ var v=p[h]!==undefined?p[h]:data[i][c]; return v===undefined?'':v; });
      sh.getRange(i+1,1,1,HEADERS.length).setValues([row]);
      data[i]=row;
    } else {
      sh.appendRow(HEADERS.map(function(h){ return p[h]!==undefined?p[h]:''; }));
      rowByKey[key]=-1;
    }
  });
}

function deletePicks_(keys){
  var sh=sheet_();
  var data=sh.getDataRange().getValues();
  var set={}; keys.forEach(function(k){set[k]=true;});
  for(var i=data.length-1;i>=1;i--){
    if(set[keyOf_(data[i][0],data[i][1],data[i][2],data[i][3],data[i][4],data[i][5])])sh.deleteRow(i+1);
  }
}

function readAll_(){
  var sh=sheet_();
  var data=sh.getDataRange().getValues();
  var picks=[];
  for(var i=1;i<data.length;i++){
    var row=data[i]; if(!row[0]&&!row[1])continue;
    var obj={}; HEADERS.forEach(function(h,idx){ obj[h]=row[idx]!==undefined?row[idx]:''; });
    picks.push(obj);
  }
  return picks;
}
① 채점
② 기록 보완
③ 내보내기 · 마무리
① 경기가 끝나면 🏁 결과 조회로 점수를 채우고, 노란칸을 확인한 뒤 ✅ 조회결과 확정을 누르세요 — 세 리그(MLB·KBO·NPB)를 한 번에 조회하고 한 번에 확정합니다. 한 리그만 보려면 로그 위의 리그 칩을 눌러 좁힌 뒤 조회하세요. 벳맨에 스코어가 안 올라온 MLB 경기는 아래 표에 직접 입력해 주세요. 전반 마켓은 5회말 기준입니다. → ② 💵 마감배당 기입은 경기가 끝난 뒤 집 컴퓨터에서 마감배당올리기를 다시 실행한 다음에 눌러야 값이 들어옵니다(경기 전 수집분은 장중 배당이라 건너뜁니다). → ③ 📤 완료된 픽 최종 저장채점·마감배당이 다 채워진 픽만 시트에 확정하고 사이트에서 치웁니다 — 진행 중인 픽은 그대로 남으니 아무 때나 눌러도 됩니다. 저장된 스프레드시트를 Claude에게 공유/첨부하면 캘리브레이션·오차·계수 보정 피드백과 개선 로드맵을 받을 수 있습니다.
📊 성과 · 캘리브레이션 (💰 실전 성과=베팅 체크한 픽 / 📊 전체 캘리브레이션=참고용 전체 픽 · 관망 제외 · 점수 입력된 픽만 · 전반 마켓은 5회말 종료 기준)
날짜리그경기P배당마감배당픽점수(/100)실제 홈실제 원정삭제
📋 Claude 피드백 요청 프롬프트
이 구글 스프레드시트는 KBO·MLB 베팅 EV 예측 모델의 픽 기록입니다. 각 열 의미:
- market: 마켓종류 | pick: 최선픽 | P_model: 모델예측확률 | devig: 배당내재확률 | ev: 기댓값
- hFIP/aFIP: 홈·원정 선발FIP | hWRC/aWRC: 홈·원정 wRC+ | PF: 구장계수
- actHome/actAway: 최종점수 | actH1Home/actH1Away: 5회말 기준 전반점수 | result: W/L/P
- closeOdds: 마감배당(경기 직전 배당) — CLV(잡은 배당/마감배당−1) 분석용, 빈칸이면 미기록
- closeLine: 마감 라인 — 배트맨의 홈(기준팀) 기준 원값 그대로(핸디 -2.5 / 언더오버 9.5). 부호를 뒤집지 않은 원자료입니다.
  픽의 라인(pick에 적힌 값)과 비교하면 시장이 내 픽 쪽으로 움직였는지 알 수 있습니다. 기준팀 핸디·언더 픽은
  (픽 라인 − closeLine), 상대팀 핸디·오버 픽은 그 반대 부호가 양수일 때 '시장 동의'입니다.
  라인이 움직인 픽은 마감배당이 다른 상품이라 closeOdds가 비어 있어도 closeLine은 채워집니다.

아래 순서로 분석해주세요:
1. 마켓별 적중률·ROI 요약표
2. P_model 캘리브레이션 — 예측확률 구간별 실제 적중률 비교
3. FIP·wRC+ 등 입력변수와 오차의 상관관계 (과대평가·과소평가 패턴)
4. 계수 보정 제안 (fipCoefKBO·wrcFactor·sigF 등 조정 방향)
5. 마켓별 전략 개선점 (전반 마켓 포함)
6. 위 분석을 바탕으로 계수·모델 개선 로드맵을 우선순위와 함께 제시