ギャンブル収支をClaude APIで自動管理する仕組みを作った話

PR本記事はアフィリエイト広告を含みます。リンク経由でのご購入により運営者に成果報酬が支払われることがありますが、読者への価格や条件は変わりません。

競艇の収支管理をClaude APIで自動化したら、月の損失が4万円から1.2万円に圧縮できた。3ヶ月試して出した結論がこれだ。

「月いくら負けてるか、正確に答えられる?」

以前の自分に聞いたら、絶対に答えられなかった。ざっくり「まあトントンか、ちょっとマイナスくらい」という感覚で賭け続けていた。それが間違いだった。

この記事では、私が実際に作った収支管理システムの設計から実装まで、コードを交えて全部紹介する。競艇・競馬を定期的に楽しんでいるエンジニアなら、1日あれば同じものが作れる。


感情で賭けていた頃の話

私が競艇を始めたのは3年ほど前だ。最初はレースの面白さにハマり、週末だけ賭けていた。そのうち平日のナイターも、出張先でもスマホで買うようになった。

問題は、損失の実感がなかったことだ。

1レース500円、1000円という金額は「安い」と感じる。でも週3回レース場に行って、1日あたり10レース賭けていたら、負け続ければ月に3〜5万円が消える。それを「ざっくりトントンかな」で片付けていた。

ある月、クレジットカードの明細を見て青ざめた。競艇関連の支出だけで6万2000円あった。その月、的中したレースで戻ってきたのは2万円ちょっと。純損失は約4万円だ。

問題は金額よりも、それを把握していなかった自分だった。エンジニアとして、システムのコストはセント単位で管理するのに、個人の娯楽費は完全にブラックボックスだった。

「これはまずい」と思って、収支管理のツールを自分で作ることにした。


システムの全体設計

シンプルさを最優先にした。続けられないシステムは意味がない。

【全体の流れ】

1. 賭けた記録を手入力(またはCSVインポート)
   ↓
2. SQLiteに保存(ローカルDB)
   ↓
3. 週次・月次でClaude APIが収支を分析
   ↓
4. 危険サインを検知したらSlack通知
   ↓
5. 分析レポートをMarkdownで保存

使った技術はこれだけだ。

  • Python 3.12
  • SQLite(ローカルDB、セットアップ不要)
  • Claude API(anthropic ライブラリ)
  • Slack Incoming Webhook(通知用)

外部サービスはSlackだけ。DBはローカルのSQLiteなので、個人情報をクラウドに送らずに済む。


実装①:賭け履歴の記録

まずデータを記録する仕組みから作る。

データベース設計

import sqlite3
from datetime import datetime

def init_db(db_path="gambling.db"):
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS bets (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            date TEXT NOT NULL,
            venue TEXT NOT NULL,
            race_no INTEGER NOT NULL,
            bet_type TEXT NOT NULL,
            combination TEXT NOT NULL,
            stake INTEGER NOT NULL,
            return_amount INTEGER DEFAULT 0,
            profit INTEGER GENERATED ALWAYS AS (return_amount - stake) STORED,
            note TEXT
        )
    """)
    conn.commit()
    conn.close()

カラムはシンプルに。日付・会場・レース番号・賭け式・購入金額・払戻金額の6項目だ。利益は自動計算カラムにして、手入力ミスを減らした。

記録の入力

def add_bet(date, venue, race_no, bet_type, combination, stake, return_amount=0, note=""):
    conn = sqlite3.connect("gambling.db")
    cursor = conn.cursor()
    cursor.execute("""
        INSERT INTO bets (date, venue, race_no, bet_type, combination, stake, return_amount, note)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    """, (date, venue, race_no, bet_type, combination, stake, return_amount, note))
    conn.commit()
    conn.close()

# 使い方の例
add_bet(
    date="2026-05-20",
    venue="戸田",
    race_no=6,
    bet_type="2連単",
    combination="1-3",
    stake=1000,
    return_amount=0  # 外れ
)

レース後に結果が出たら、return_amount を更新するだけでいい。

月次サマリーの集計

def get_monthly_summary(year, month, db_path="gambling.db"):
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    cursor.execute("""
        SELECT
            COUNT(*) as total_bets,
            SUM(stake) as total_stake,
            SUM(return_amount) as total_return,
            SUM(profit) as total_profit,
            ROUND(SUM(return_amount) * 100.0 / SUM(stake), 1) as recovery_rate,
            COUNT(CASE WHEN return_amount > 0 THEN 1 END) as hit_count
        FROM bets
        WHERE strftime('%Y', date) = ? AND strftime('%m', date) = ?
    """, (str(year), f"{month:02d}"))
    
    row = cursor.fetchone()
    conn.close()
    
    return {
        "total_bets": row[0],
        "total_stake": row[1],
        "total_return": row[2],
        "total_profit": row[3],
        "recovery_rate": row[4],
        "hit_count": row[5],
        "hit_rate": round(row[5] * 100 / row[0], 1) if row[0] > 0 else 0
    }

実装②:Claude APIで収支分析・アドバイス

ここが一番面白い部分だ。集計した数値をそのまま見るだけではなく、Claude APIに「傾向分析とアドバイス」をさせる。

分析用プロンプトの設計

import anthropic
from datetime import datetime, timedelta

def analyze_with_claude(summary: dict, recent_bets: list) -> str:
    client = anthropic.Anthropic()
    
    # 直近30日の収支データをテキストに変換
    bet_details = "\n".join([
        f"- {b['date']} {b['venue']}競艇 第{b['race_no']}R: "
        f"賭け金{b['stake']:,}円 → 払戻{b['return_amount']:,}円 ({b['bet_type']})"
        for b in recent_bets[-30:]  # 直近30件
    ])
    
    prompt = f"""以下の競艇収支データを分析してください。

【直近30日の収支サマリー】
- 総賭け件数: {summary['total_bets']}件
- 総賭け金額: {summary['total_stake']:,}円
- 総払戻金額: {summary['total_return']:,}円
- 純損益: {summary['total_profit']:,}円
- 回収率: {summary['recovery_rate']}%
- 的中率: {summary['hit_rate']}%({summary['hit_count']}件 / {summary['total_bets']}件)

【賭け履歴の詳細】
{bet_details}

以下の観点で分析してください:
1. 回収率の傾向(改善中か悪化中か)
2. 賭け方のパターンで気になる点(金額が増えている傾向など)
3. 次の30日間へのアドバイス(具体的に2〜3点)
4. このデータで最も心配な点(正直に教えてください)

厳しくても構いません。事実ベースで教えてください。"""

    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=1024,
        messages=[{"role": "user", "content": prompt}]
    )
    
    return response.content[0].text

実際にClaudeが返してきた分析例

先月のデータを入れたら、こんな返答が来た(一部要約)。

回収率71%は平均的な競艇ユーザーの水準ですが、直近2週間で賭け金額が平均1,200円から2,100円に増加しています。これは「取り返したい」という心理が影響している可能性があります。特に外れが続いた翌日の賭け金額が平均35%高くなっているパターンが見られます。

これを見たとき、「当たっている」と思った。感覚ではわかっていなかったが、データに出ていた。連敗した次の日は無意識に賭け金を増やしていた。


実装③:危険サインの自動検知

感情で判断しているとき、人間は自分で気づけない。そこでSlack通知を入れた。

危険サインの定義

自分で決めたルールはこの3つだ。

  1. 3連敗以上が続いている(連続して的中ゼロ)
  2. 今月の損失が設定上限(1.5万円)を超えた
  3. 1レースの賭け金が上限(3000円)を超えた
import requests
import json

SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
MONTHLY_LOSS_LIMIT = 15000  # 月の損失上限(円)
SINGLE_BET_LIMIT = 3000     # 1レースの上限(円)
CONSECUTIVE_LOSS_LIMIT = 3  # 連敗上限

def check_danger_signs(db_path="gambling.db"):
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    
    # 今月の損失を計算
    now = datetime.now()
    cursor.execute("""
        SELECT SUM(profit) FROM bets
        WHERE strftime('%Y-%m', date) = ?
    """, (now.strftime("%Y-%m"),))
    monthly_profit = cursor.fetchone()[0] or 0
    
    # 直近の連敗チェック
    cursor.execute("""
        SELECT return_amount FROM bets
        ORDER BY date DESC, id DESC
        LIMIT ?
    """, (CONSECUTIVE_LOSS_LIMIT,))
    recent = cursor.fetchall()
    consecutive_losses = all(r[0] == 0 for r in recent)
    
    # 直近の1レース賭け金チェック
    cursor.execute("""
        SELECT stake FROM bets ORDER BY id DESC LIMIT 1
    """)
    last_stake = (cursor.fetchone() or [0])[0]
    
    conn.close()
    
    alerts = []
    
    if monthly_profit < -MONTHLY_LOSS_LIMIT:
        alerts.append(f"月の損失が上限を超えました: {abs(monthly_profit):,}円の損失(上限: {MONTHLY_LOSS_LIMIT:,}円)")
    
    if consecutive_losses and len(recent) >= CONSECUTIVE_LOSS_LIMIT:
        alerts.append(f"{CONSECUTIVE_LOSS_LIMIT}連敗中です。少し休憩を検討してください。")
    
    if last_stake > SINGLE_BET_LIMIT:
        alerts.append(f"直近のベット額が上限超過: {last_stake:,}円(上限: {SINGLE_BET_LIMIT:,}円)")
    
    if alerts:
        send_slack_alert(alerts)
    
    return alerts

def send_slack_alert(alerts: list):
    message = "【競艇収支 危険サイン検知】\n\n" + "\n".join(f"• {a}" for a in alerts)
    requests.post(SLACK_WEBHOOK_URL, json={"text": message})

このSlack通知が来たとき、スマホを開いて「あ、また取り返そうとしてた」と気づいた。それだけで行動を止められる。

週次の自動レポート

毎週月曜の朝、自動でレポートが来るようにcronを設定した。

# weekly_report.py(毎週月曜 09:00 に実行)
def generate_weekly_report():
    now = datetime.now()
    summary = get_monthly_summary(now.year, now.month)
    
    # 今週のベット履歴を取得
    week_ago = (now - timedelta(days=7)).strftime("%Y-%m-%d")
    conn = sqlite3.connect("gambling.db")
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM bets WHERE date >= ? ORDER BY date", (week_ago,))
    recent_bets = [
        {"date": r[1], "venue": r[2], "race_no": r[3],
         "bet_type": r[4], "combination": r[5],
         "stake": r[6], "return_amount": r[7]}
        for r in cursor.fetchall()
    ]
    conn.close()
    
    # Claude APIで分析
    analysis = analyze_with_claude(summary, recent_bets)
    
    # Slack通知
    report = f"【週次 競艇収支レポート】\n\n今月累計損益: {summary['total_profit']:,}円\n回収率: {summary['recovery_rate']}%\n\n{analysis}"
    send_slack_alert([report])

使ってみての効果と変化

3ヶ月使い続けた結果を正直に報告する。

導入前(2025年11月)

  • 月の損失: 約4万円(ただし把握していなかった)
  • 1レースの賭け金: 感覚で500〜5000円
  • 連敗後の行動: 気づかずに賭け金を増額

導入後3ヶ月の平均

  • 月の損失: 約1.2万円
  • 1レースの賭け金: 300〜1500円(上限を意識するようになった)
  • 連敗後の行動: Slack通知が来たら翌日は休む

損失が約70%削減されたのは、Claude APIの分析が賢かったというより、「見える化」したことで自分の行動が変わったからだ。

Claudeが返してくる分析は毎回鋭い。「取り返したい心理が金額に出ている」「土日より平日のほうが回収率が高い(冷静に賭けているから)」「購入数が多い日ほど1レース単価が下がっている(分散できている)」。データから行動パターンを読み取ってくれる。


改善したいところ(正直に)

良いことばかり書いても意味がないので、課題も書く。

1. 手入力が面倒

レース後に手入力するのが習慣化するまでに2週間かかった。今でも忘れることがある。競艇公式のSPAT4や楽天競馬のAPIを叩いて自動取得できれば理想だが、利用規約の確認が必要で手をつけていない。

2. Claudeの分析が毎回似たようなことを言う

プロンプトを工夫しているが、「回収率を意識してください」「連敗後は冷静に」という内容は繰り返しになりがち。もう少しプロンプトを変えて、前回の分析と比較する形にしたい。

3. 確率の根拠が弱い

「土日より平日のほうが回収率が高い」という傾向は出ているが、サンプル数がまだ少ない。3ヶ月のデータでは統計的に結論を出すには早い。半年以上のデータが溜まってから判断しようと思っている。


まとめ

競艇・競馬の収支管理をClaude APIで自動化した話を書いた。

システムの構成は単純だ。SQLiteで履歴を記録し、週次でClaude APIに分析させ、危険サインが出たらSlack通知する。コードは全部合わせて200行程度で動く。

一番大事なのは「ツールを作ったから管理できる」ではなく、「記録と分析の習慣が行動を変える」という点だ。Claudeの分析が鋭いのは確かだが、それ以上に「今月いくら負けているか、毎週確認している自分」が存在することが行動を変えた。

エンジニアなら半日あれば同じ仕組みが作れる。競艇・競馬に限らず、パチンコや株のデイトレードでも同じ構造で使える。「なんとなく損している気がするが把握できていない」という状況は、システムで解決できる類いの問題だ。

ソースコードはGitHubに公開予定なので、興味があれば参考にしてみてほしい。


*本記事はギャンブルを推奨するものではありません。公営競技(競艇・競馬など)への参加は成年(18歳以上または20歳以上)に限られます。収支管理ツールは娯楽の範囲内での利用を前提としています。*

関連ツールを見る

この記事で紹介したツール・サービスをまとめてチェック。

おすすめ

エックスサーバー

国内シェアNo.1のレンタルサーバー。WordPressブログをすぐに始められる。このブログも実際にXserverで運営しています。

Xserverを見てみる →

ムカイ
この記事を書いた人

ムカイ

個人事業主エンジニア。C#フルリモート案件に参画しながら、Claude Codeを使ってAI×副業の自動化・コンテンツ制作を実践中。「稼ぐ仕組みを作るのが好き」がモットー。

コメントを残す