ipathelper
概要
ipathelper は、JRA(日本中央競馬会)のインターネット投票サービス「I-PAT」および地方競馬の投票システムに対して、 ログイン・入出金・馬券購入・購入履歴取得・オッズ取得・出馬表取得・お知らせ取得を Python から行うためのラッパーライブラリです。
中央競馬・地方競馬・海外競馬・WIN5 に対応
Windows 32bit / 64bit 環境で動作
GitHub では Python 以外の利用例も公開しています。 詳細な関数仕様については 関数仕様書 を参照してください。
インストール方法
$ pip install ipathelper
動作環境
OS: Windows 10 以降(32bit / 64bit)
Python: 3.12 以上
共通仕様
戻り値
全関数(None を返すものを除く)は int をビットフラグとして返します。 複数のフラグが同時に立つ場合があります。判定には AND 演算を使用してください。
ret = bet(bet_data_list, 1, 0)
if (ret & 1) == 1: # SUCCESS
print("成功")
if (ret & 4) == 4: # FAILED_CHUOU
print("中央競馬で失敗")
戻り値ビットフラグ一覧:
定数名 |
ビット |
意味 |
|---|---|---|
SUCCESS |
1 |
処理に成功 |
UNSUCCESS |
2 |
処理に失敗(パラメータ不正・残高不足等) |
FAILED_CHUOU |
4 |
中央競馬での処理に失敗 |
FAILED_CHIHOU |
8 |
地方競馬での処理に失敗 |
FAILED_COMMUNICATE_CHUOU |
16 |
中央競馬との通信に失敗 |
FAILED_COMMUNICATE_CHIHOU |
32 |
地方競馬との通信に失敗 |
FAILED_OUT_OF_SERVICE |
64 |
サービス時間外(login() のみ。下記参照) |
FAILED_OUT_OF_SERVICE は login() でのみ立ち、FAILED_CHUOU / FAILED_CHIHOU と 併せて立ちます(どちらの会場かはそちらで判別してください)。 ログインページ自体は受信できたのに、ログインに必要な要素が含まれていなかったことを意味します。
最も多い原因は 投票受付時間外です。特に地方競馬は営業時間外に必ずこの状態になります(不具合ではありません)。
メンテナンス中も同じ状態になるため、両者は区別できません。
このフラグが立った場合、即座のリトライは必ず失敗します。時間をおいて再試行してください。 ID・パスワード誤りや一時的な通信障害とは扱いを分けてください。
スレッドセーフ
通信を伴う関数は DLL 内部の単一ロックで直列化されます。複数スレッドから同時に呼び出しても 壊れませんが、先行する呼び出しが完了するまでブロックします (購入・入出金は通信と残高反映待ちを含むため、数分に及ぶことがあります)。
get_bet_instance / get_bet_instance_win5 は通信もグローバル状態の参照も行わない 純粋な入力変換のためロックを取りません。他の関数の通信中でも並行して呼び出せます。
DLL 内部で発生した例外は境界を越えず、すべて捕捉されて UNSUCCESS として返ります。
購入金額の上限
1回の送信あたりの合計購入金額は 1,000,000円(MAX_TOTAL_AMOUNT_PER_SEND)が上限です。 I-PAT 側でも同じ上限が課されており、 bet / bet_win5 / bet_win5_auto は送信前に検査し、超過する場合は 送信せずに UNSUCCESS を返します。
送信は 中央 255点/地方・WIN5 50点 ずつに自動分割され、上限はこの分割単位ごとに効きます。 1点だけでもこの上限が効くため、1点あたりの金額も実質 1,000,000円 が上限です。
前提条件
bet ・ deposit ・ withdraw ・ get_purchase_data などの関数は、 事前に login() が成功している必要があります。 未ログイン状態での呼び出しは UNSUCCESS を返します。
定数一覧
開催場(KAISAI)
中央競馬:
定数名 |
開催場 |
|---|---|
KAISAI_SAPPORO |
札幌 |
KAISAI_HAKODATE |
函館 |
KAISAI_FUKUSHIMA |
福島 |
KAISAI_NIIGATA |
新潟 |
KAISAI_TOKYO |
東京 |
KAISAI_NAKAYAMA |
中山 |
KAISAI_CHUKYO |
中京 |
KAISAI_KYOTO |
京都 |
KAISAI_HANSHIN |
阪神 |
KAISAI_KOKURA |
小倉 |
地方競馬:
定数名 |
開催場 |
|---|---|
KAISAI_SONODA |
園田 |
KAISAI_HIMEJI |
姫路 |
KAISAI_NAGOYA |
名古屋 |
KAISAI_MONBETSU |
門別 |
KAISAI_MORIOKA |
盛岡 |
KAISAI_MIZUSAWA |
水沢 |
KAISAI_URAWA |
浦和 |
KAISAI_FUNABASHI |
船橋 |
KAISAI_OI |
大井 |
KAISAI_KAWASAKI |
川崎 |
KAISAI_KASAMATSU |
笠松 |
KAISAI_KANAZAWA |
金沢 |
KAISAI_KOCHI |
高知 |
KAISAI_SAGA |
佐賀 |
海外競馬:
定数名 |
開催場 |
|---|---|
KAISAI_LONGCHAMP |
ロンシャン(フランス) |
KAISAI_SHATIN |
シャティン(香港) |
KAISAI_SANTAANITA |
サンタアニタ(アメリカ) |
KAISAI_DEAUVILLE |
ドーヴィル(フランス) |
KAISAI_CHURCHILLDOWNS |
チャーチルダウンズ(アメリカ) |
KAISAI_ABDULAZIZ |
キングアブドゥルアジーズ(サウジアラビア) |
KAISAI_ASCOT |
アスコット(イギリス) |
式別(SHIKIBETSU)
定数名 |
値 |
式別 |
|---|---|---|
SHIKIBETSU_WIN |
1 |
単勝 |
SHIKIBETSU_PLACE |
2 |
複勝 |
SHIKIBETSU_BRACKETQUINELLA |
3 |
枠連(買い目は馬番ではなく 枠番 1〜8。海外開催では購入不可) |
SHIKIBETSU_QUINELLA |
4 |
馬連 |
SHIKIBETSU_QUINELLAPLACE |
5 |
ワイド |
SHIKIBETSU_EXACTA |
6 |
馬単 |
SHIKIBETSU_TRIO |
7 |
三連複 |
SHIKIBETSU_TRIFECTA |
8 |
三連単 |
SHIKIBETSU_WINPLACE |
9 |
応援馬券(同一馬の単勝+複勝のセット) |
枠連(SHIKIBETSU_BRACKETQUINELLA)の注意点
買い目は馬番ではなく 枠番(1〜8) で指定します。9以上を指定すると UNSUCCESS で失敗します。
ゾロ目(同枠の2頭による決着)は同じ枠を2つ指定します("3-3")。 通常方式で枠を1つだけ指定した "3" も同じ意味です。
ゾロ目が成立する枠かどうかは検証しません。 その枠に2頭以上いるかは出馬表を見ないと 分からないためです。同枠のない枠でゾロ目を指定すると、購入時にサーバ側で失敗します。
海外開催では購入できません(UNSUCCESS)。
応援馬券(SHIKIBETSU_WINPLACE)の注意点
方式は HOUSHIKI_NORMAL(通常)のみ、買い目は 1頭のみ指定できます("7" のように馬番ひとつ)。 ボックス・フォーメーション・ながしは指定できません。
合計購入金額は指定金額の2倍になります(100円指定 = 単勝100円 + 複勝100円)。点数も2点として数えます。
単勝と複勝の2点として購入されるため、購入履歴には単勝と複勝が別々の馬券として現れます。
独立した2点として扱われるため、分割送信の境界で単勝と複勝が別チャンクに分かれ、 通信失敗時に 片方だけが成立する可能性があります。
get_odds() にこの式別は指定できません(UNSUCCESS)。単勝・複勝を個別に取得してください。
方式(HOUSHIKI)
定数名 |
方式 |
買い目の指定 |
|---|---|---|
HOUSHIKI_NORMAL |
通常 |
1点を指定 |
HOUSHIKI_FORMATION |
フォーメーション |
各列に複数馬番 |
HOUSHIKI_BOX |
ボックス |
1列に複数馬番(全組み合わせ) |
HOUSHIKI_WHEEL_1ST |
軸1頭ながし(1着流し) |
"軸-相手" |
HOUSHIKI_WHEEL_2ND |
2着ながし(馬単・三連単) |
"軸-相手" |
HOUSHIKI_WHEEL_3RD |
3着ながし(三連単) |
"軸-相手" |
HOUSHIKI_WHEEL_1ST_2ND |
軸2頭ながし(三連複)/1・2着ながし(三連単) |
三連複 "軸,軸-相手" /三連単 "1着軸-2着軸-相手" |
HOUSHIKI_WHEEL_1ST_3RD |
1・3着ながし(三連単) |
"1着軸-相手-3着軸" |
HOUSHIKI_WHEEL_2ND_3RD |
2・3着ながし(三連単) |
"相手-2着軸-3着軸" |
HOUSHIKI_WHEEL_MULTI_AXIS1 |
軸1頭ながしマルチ(馬単・三連単) |
"軸-相手"(全着順) |
HOUSHIKI_WHEEL_MULTI_AXIS2 |
軸2頭ながしマルチ(三連単のみ) |
"軸-軸-相手"(全着順) |
確定フラグ(DECISIONFLAG)
定数名 |
値 |
意味 |
|---|---|---|
DECISIONFLAG_PARSE_FAILED |
0 |
その明細を解析できなかった(下記参照) |
DECISIONFLAG_DEFAULT |
1 |
デフォルト |
DECISIONFLAG_NORMAL |
2 |
通常確定 |
DECISIONFLAG_DEADLINE |
3 |
発売締切 |
DECISIONFLAG_CANCEL |
4 |
キャンセル |
DECISIONFLAG_FLATMATESCANCEL |
5 |
仲間入力取消 |
DECISIONFLAG_HIT |
6 |
的中 |
DECISIONFLAG_MISS |
7 |
外れ |
DECISIONFLAG_BACK |
8 |
返還 |
DECISIONFLAG_PARTCANCEL |
9 |
一部取消 |
DECISIONFLAG_INVALID |
10 |
無効 |
DECISIONFLAG_SALECANCEL |
11 |
発売取消 |
DECISIONFLAG_PARSE_FAILED(0)は、その明細を解析できなかったことを表します。 通常の確定フラグは1始まりのため、この値が正常なフラグと衝突することはありません。 詳細は 購入明細の読み方 を参照してください。
券種(BETFLAG)
ST_TICKET_DATA_DETAIL.BetFlag の値です。
定数名 |
値 |
意味 |
|---|---|---|
BETFLAG_NORMAL |
0 |
通常 |
BETFLAG_WIN5 |
1 |
WIN5 |
BETFLAG_INTERNATIONAL |
2 |
海外(中央の購入履歴に混在します) |
その他の定数
購入日種類(DAYTYPE)は get_purchase_data() の結果に現れます。
定数名 |
意味 |
|---|---|
DAYTYPE_TODAY / DAYTYPE_BEFORE |
購入日(当日 / 前日) |
WEEKDAY_SUNDAY 〜 WEEKDAY_SATURDAY |
曜日(日曜=1 〜 土曜=7) |
ODDS_STATUS_NORMAL / ODDS_STATUS_CANCEL / ODDS_STATUS_UNACQUIRED |
オッズ状態(通常=0 / 発売中止=1 / オッズ未取得=2) |
RACE_STATUS_ON_SALE 〜 RACE_STATUS_UNKNOWN |
発売状態(発売中=0 / 発売終了=1 / 発売中止=2 / 発売前=3 / 取得できなかった=0xFF) |
WIN5_AUTO_SELECT / WIN5_AUTO_RANDOM |
bet_win5_auto() の購入方式(セレクト=2 / ランダム=3) |
LOG_LEVEL_TRACE 〜 LOG_LEVEL_ERROR |
set_log_callback() のログレベル(0〜3) |
上限・列数・既定値の定数:
定数名 |
値 |
用途 |
|---|---|---|
MAX_TOTAL_AMOUNT_PER_SEND |
1000000 |
1回の送信あたりの合計購入金額の上限(円)。1点あたりの上限も同じ値 |
MAX_WIN5_AUTO_BET_COUNT |
50 |
bet_win5_auto() で生成させられる点数の上限 |
UMABAN_COLUMN_COUNT |
3 |
ST_BET_DATA.Umaban の要素数 |
UMABAN_TICKET_COLUMN_COUNT |
5 |
購入明細の HorseNo1 〜 HorseNo5(WIN5 の5レース分を含む) |
WIN5_RACE_COUNT |
5 |
WIN5 のレース数 |
DEFAULT_RETRY_COUNT |
10 |
deposit() / withdraw() のリトライ回数の既定値 |
DEPOSIT_DEFAULT_VALUE |
1000 |
set_auto_deposit_flag() の入金額(円)の既定値 |
DEFAULT_CONFIRM_TIMEOUT |
10000 |
残高反映の確認タイムアウト(ms)の既定値 |
DEFAULT_BET_INTERVAL |
500 |
DLL 側の分割送信間隔(ms)の既定値 |
DEFAULT_WAIT_TIME |
1000 |
bet() / bet_win5() が既定で渡す分割送信間隔(ms) |
データ構造
ST_BET_DATA
get_bet_instance() で設定し、 bet() に渡す購入情報です。 フィールドを直接参照することで購入内容を確認できます。
betData = ST_BET_DATA()
get_bet_instance(KAISAI_TOKYO, 11, 2026, 4, 5,
HOUSHIKI_NORMAL, SHIKIBETSU_WIN, 100, "1", betData)
print(betData.TotalAmount) # 合計購入金額(円)
フィールド名 |
型 |
説明 |
|---|---|---|
Place |
int |
開催場(KAISAI 定数) |
RaceNo |
int |
レース番号 |
Youbi |
int |
曜日(WEEKDAY 定数。年月日から自動判定) |
Kaikata |
int |
方式(HOUSHIKI 定数。マルチ指定時は基底のながし方式へ変換される) |
Shikibetsu |
int |
式別(SHIKIBETSU 定数) |
Kingaku |
int |
1点あたりの購入金額(円) |
Umaban |
array |
買い目の各列を表すビットデータ(3列分) |
TotalAmount |
int |
合計購入金額(get_bet_instance が自動計算) |
Multi |
int |
マルチかどうか(0:通常 / 1:マルチ)。HOUSHIKI_WHEEL_MULTI_* 指定時に 1 になる |
ST_BET_DATA_WIN5
get_bet_instance_win5() で設定し、 bet_win5() に渡す WIN5 専用の購入情報です。
フィールド名 |
型 |
説明 |
|---|---|---|
Kingaku |
int |
1組み合わせあたりの購入金額(円) |
Youbi |
int |
曜日(WEEKDAY 定数) |
Umaban |
array |
5レース分の買い目を表すビットデータ |
ST_PURCHASE_DATA
get_purchase_data() が設定するルート構造体です。 ネイティブ側のメモリ解放は get_purchase_data() 内部で自動的に行われるため、 利用者側での解放処理は不要です(返却されるデータは Python 側にコピー済みです)。
TicketData にはログイン済みの会場すべての馬券が 中央 → 地方の順に連結されます。 残高・購入可能件数・当日/累計の金額は 合算しません(中央・地方は同じ即PAT 口座を 共有するため、どちらか一方の値をそのまま返します)。詳細は get_purchase_data を参照してください。
フィールド名 |
型 |
説明 |
|---|---|---|
AvailableBetCount |
int |
残購入可能件数 |
Balance |
int |
現在残高(円) |
DayPurchase |
int |
当日累計購入金額(円) |
DayHaraimodosi |
int |
当日累計払戻金額(円) |
TotalPurchase |
int |
合計購入金額(円) |
TotalHaraimodosi |
int |
合計払戻金額(円) |
TicketCount |
int |
馬券情報の件数 |
TicketData |
array |
馬券情報の配列(下記参照) |
TicketData の各要素(ST_TICKET_DATA):
フィールド名 |
型 |
説明 |
|---|---|---|
DayFlag |
int |
購入日(1:当日 / 2:前日) |
ReceiptNo |
int |
受付番号 |
Hour |
int |
購入時刻(時)。時刻を読み取れなかった受付では 0 |
Minute |
int |
購入時刻(分)。時刻を読み取れなかった受付では 0 |
Kingaku |
int |
購入金額(円) |
Payout |
int |
払戻金額(円) |
DetailCount |
int |
詳細情報の件数 |
DetailData |
array |
詳細情報の配列(下記参照) |
DetailData の各要素(ST_TICKET_DATA_DETAIL):
フィールド名 |
型 |
説明 |
|---|---|---|
DecisionFlag |
int |
確定フラグ(DECISIONFLAG 定数)。0 は その明細を解析できなかった |
BetFlag |
int |
券種(BETFLAG 定数。通常=0 / WIN5=1 / 海外=2) |
Kaisai |
int |
開催場(KAISAI 定数)。WIN5 の明細では 0xFF |
RaceNo |
int |
レース番号。WIN5 の明細では 0xFF |
Week |
int |
開催週。WIN5 の明細では 0xFF |
Method |
int |
方式(HOUSHIKI 定数)。WIN5 の明細では 0xFF |
Type |
int |
式別(SHIKIBETSU 定数)。WIN5 の明細では 0xFF |
HorseNo1 〜 HorseNo5 |
int |
買い目の各列を表すビットデータ(WIN5 を含めるため 5 列分) |
Multi |
int |
マルチ購入フラグ(1: マルチあり) |
関数リファレンス
login
I-PAT へログインします。中央競馬と地方競馬の両方へログインを試みます。
ret = login(inet_id, id, password, pars)
引数 |
型 |
説明 |
|---|---|---|
inet_id |
str |
I-NET ID |
id |
str |
ログイン ID |
password |
str |
パスワード |
pars |
str |
P-ARS 番号 |
戻り値パターン:
状態 |
返るフラグ |
|---|---|
両方成功 |
SUCCESS |
中央のみ失敗 |
SUCCESS | FAILED_CHUOU |
地方のみ失敗 |
SUCCESS | FAILED_CHIHOU |
両方失敗 |
FAILED_CHUOU | FAILED_CHIHOU |
受付時間外・メンテナンス中 |
上記に加えて FAILED_OUT_OF_SERVICE |
既ログイン |
UNSUCCESS |
ret = login(inet_id, id, password, pars)
if (ret & SUCCESS) == 0:
if (ret & FAILED_OUT_OF_SERVICE) != 0:
# 受付時間外・メンテナンス中。即時リトライは必ず失敗する
print("サービス時間外です。時間をおいて再試行してください")
else:
print("ログイン失敗")
logout
I-PAT からログアウトします。自動入金設定もリセットされます。
ret = logout() # -> int
ログアウト後、再度 login() を呼び出すまで他の関数は使用できません。
deposit
登録口座から I-PAT 残高へ入金します。
ret = deposit(depositValue, retryCount=DEFAULT_RETRY_COUNT)
引数 |
型 |
説明 |
|---|---|---|
depositValue |
int |
入金額(円)。100円以上かつ100円単位。 |
retryCount |
int |
準備段階のみ のリトライ回数。デフォルト: 10回(DEFAULT_RETRY_COUNT)。 |
入金指示の完了後、入金額が残高へ加算されたことを確認できるまで待機し、 反映を確認できた場合のみ成功 を返します。 set_auto_deposit_flag() の confirmTimeout(既定 10 秒)以内に反映されない場合は失敗です。
中央競馬へのログインが有効な場合は中央を優先し、失敗時は地方へフォールバックします。 ただし入金の実行に進んだ後は、その系統で失敗しても地方へフォールバックしません。
登録口座の金融機関は自動的に判定します (取得できない場合のみ、対応金融機関のコードを順に試行します)。
withdraw
I-PAT 残高を登録口座へ全額出金します。
ret = withdraw(retryCount=DEFAULT_RETRY_COUNT)
引数 |
型 |
説明 |
|---|---|---|
retryCount |
int |
準備段階のみ のリトライ回数。デフォルト: 10回(DEFAULT_RETRY_COUNT)。 |
出金額の指定は不要です。残高の全額が出金対象となります。
出金指示の完了後、残高が 0 になったことを確認できた場合のみ成功 を返します。 confirmTimeout 以内に反映されない場合は失敗です。
リトライの適用範囲・二重出金の防止・即PAT 会員専用・PayPay(アプリ)非対応である点は deposit() と同じです。
set_auto_deposit_flag
馬券購入前の残高不足時に自動で入金を行う機能を設定します。 有効化すると bet() / bet_win5() 実行時に残高不足が検出された場合、自動的に入金してから購入を行います。
ret = set_auto_deposit_flag(enable, depositValue=DEPOSIT_DEFAULT_VALUE,
confirmTimeout=DEFAULT_CONFIRM_TIMEOUT)
引数 |
型 |
説明 |
|---|---|---|
enable |
bool |
True で有効化、False で無効化 |
depositValue |
int |
自動入金額(円、100円単位)。デフォルト: 1,000(DEPOSIT_DEFAULT_VALUE) |
confirmTimeout |
int |
残高反映の確認タイムアウト(ms)。デフォルト: 10,000(DEFAULT_CONFIRM_TIMEOUT) |
入金後、残高への反映を最大 confirmTimeout ms 待機します。タイムアウトした場合は購入を中止します。
入金しても残高が購入金額に満たない場合は、入金を行わず UNSUCCESS を返します。
depositValue は enable=False の場合は検証されません。
confirmTimeout は自動入金だけでなく、deposit() / withdraw() の 残高反映待ちにも使用されます。反映が遅い環境では延長してください。
自動入金は deposit() と同じ経路を使うため、即PAT 会員専用・ PayPay(アプリ)非対応 という制約もそのまま当てはまります。
logout() を呼び出すと設定はリセットされます。
get_bet_instance
買い目文字列を解析し、 bet() に渡す``ST_BET_DATA`` を構築します。
betData = ST_BET_DATA()
ret = get_bet_instance(place, race_no, year, month, day,
houshiki, shikibetsu, kingaku, kaime, betData)
引数 |
型 |
説明 |
|---|---|---|
place |
int |
開催場(KAISAI 定数) |
race_no |
int |
レース番号 |
year |
int |
開催年(西暦 4桁) |
month |
int |
開催月(1〜12) |
day |
int |
開催日(1〜31) |
houshiki |
int |
方式(HOUSHIKI 定数) |
shikibetsu |
int |
式別(SHIKIBETSU 定数) |
kingaku |
int |
1点あたりの購入金額(円、100円単位)。100円以上 1,000,000円以下 |
kaime |
str |
買い目文字列(書式は後述) |
betData |
[out] ST_BET_DATA インスタンス |
成功すると betData.TotalAmount に合計購入金額が格納されます。
馬番は 1〜18(海外開催は 1〜24)の範囲で指定してください。 範囲外の馬番が含まれる場合、その馬番を無視するのではなく UNSUCCESS を返します (指定より少ない点数で購入されるのを防ぐためです)。
海外開催では枠連(SHIKIBETSU_BRACKETQUINELLA)を購入できません。 海外競馬に枠の概念が無いため、指定すると UNSUCCESS を返します。
合計購入金額の上限については「購入金額の上限」を参照してください。
本関数は通信もグローバル状態の参照も行わないため内部ロックを取りません。 bet() などの通信中でも並行して呼び出せます。
買い目文字列の書式
列の区切り: - (ハイフン)
同一列内の複数馬番の区切り: , (カンマ)
単勝 1番 -> "1"
馬連 通常 1-5 -> "1-5"
馬単 通常 3-7 -> "3-7"
三連複 通常 2-5-8 -> "2-5-8"
三連単 通常 1-3-5 -> "1-3-5"
馬連 フォーメーション 1・2番 vs 3・4・5番 -> "1,2-3,4,5"
三連複 フォーメーション 軸1番/相手A2・3番/相手B4・5・6番 -> "1-2,3-4,5,6"
三連単 フォーメーション 1着1番/2着2・3番/3着4・5番 -> "1-2,3-4,5"
馬連 ボックス 1・2・3・4番(6点) -> "1,2,3,4"
三連単 ボックス 1・2・3番(6点) -> "1,2,3"
ながし・マルチは houshiki に HOUSHIKI_WHEEL_* / HOUSHIKI_WHEEL_MULTI_* を指定します。
三連単 1着ながし 軸=1 / 相手=2,3,4 HOUSHIKI_WHEEL_1ST -> "1-2,3,4" (6点)
三連単 1・2着ながし 1着軸=1 / 2着軸=2 / 相手=3,4 HOUSHIKI_WHEEL_1ST_2ND -> "1-2-3,4"
馬連 ながし 軸=1 / 相手=2,3,4 HOUSHIKI_WHEEL_1ST -> "1-2,3,4"
三連単 軸1頭マルチ 軸=1 / 相手=2,3,4 HOUSHIKI_WHEEL_MULTI_AXIS1 -> "1-2,3,4" (全着順18点)
三連単 軸2頭マルチ 軸=1,2 / 相手=3,4 HOUSHIKI_WHEEL_MULTI_AXIS2 -> "1-2-3,4"
枠連は馬番ではなく 枠番(1〜8) で指定します。ゾロ目は同じ枠を2つ("3-3")。 応援馬券は 通常方式・1頭のみ("7")です。詳細は 式別(SHIKIBETSU) を参照してください。
bet
get_bet_instance() で構築した ST_BET_DATA の配列を一括購入します。 開催場に応じて中央・地方・海外に自動で振り分けられます。
betDataList = (ST_BET_DATA * n)()
betDataList[0] = betData
ret = bet(betDataList, n, waitMiliSeconds=DEFAULT_WAIT_TIME)
引数 |
型 |
説明 |
|---|---|---|
betDataList |
ST_BET_DATA の配列((ST_BET_DATA * n)() で作成) |
|
listCount |
int |
配列の要素数 |
waitMiliSeconds |
int |
分割購入時のリクエスト間隔(ms)。デフォルト: 1,000(DEFAULT_WAIT_TIME) |
購入件数が1回の上限(中央 255件 / 地方 50件)を超える場合、自動的に分割して購入します。 waitMiliSeconds はこの分割送信の間隔です。
開催場に応じて中央・地方・海外の適切なエンドポイントへ自動的に振り分けます。
購入前に残高と購入可能件数を確認します。自動入金が有効な場合は残高不足時に自動入金します。
1回の送信あたりの合計購入金額が 1,000,000円 を超える場合は、送信せずに UNSUCCESS を返します。
get_bet_instance_win5
WIN5 の買い目文字列を解析し、 bet_win5() に渡す``ST_BET_DATA_WIN5`` を構築します。
betDataWin5 = ST_BET_DATA_WIN5()
ret = get_bet_instance_win5(kingaku, year, month, day, kaime, betDataWin5)
引数 |
型 |
説明 |
|---|---|---|
kingaku |
int |
1組み合わせあたりの購入金額(円、100円単位)。100円以上 1,000,000円以下 |
year |
int |
開催年(西暦 4桁) |
month |
int |
開催月(1〜12) |
day |
int |
開催日(1〜31) |
kaime |
str |
5レース分の買い目(- でレース区切り) |
betDataWin5 |
[out] ST_BET_DATA_WIN5 インスタンス |
WIN5 の買い目文字列は必ず 5レース分 を - で区切って指定してください。 馬番は 1〜18 の範囲です。
各レース1頭ずつ -> "1-2-3-4-5"
一部のレースで複数頭指定 -> "1,2-3-4,5-6-7,8"
get_bet_instance() と同じく内部ロックを取りません。
bet_win5
get_bet_instance_win5() で構築した ST_BET_DATA_WIN5 を使って WIN5 を購入します。
ret = bet_win5(betDataWin5, waitMiliSeconds=DEFAULT_WAIT_TIME)
引数 |
型 |
説明 |
|---|---|---|
betDataWin5 |
ST_BET_DATA_WIN5 インスタンス |
|
waitMiliSeconds |
int |
分割購入時のリクエスト間隔(ms)。デフォルト: 1,000(DEFAULT_WAIT_TIME) |
1回の購入上限(50 組み合わせ)を超える場合は自動的に分割購入します。
get_purchase_data
当日・前日の馬券購入履歴(残高・累計金額・購入済み馬券一覧)を取得します。
purchaseData = ST_PURCHASE_DATA()
ret = get_purchase_data(purchaseData)
if (ret & 1) == 1:
print(f"残高: {purchaseData.Balance} 円")
for i in range(purchaseData.TicketCount):
ticket = purchaseData.TicketData[i]
print(f"受付No.{ticket.ReceiptNo} {ticket.Hour:02d}:{ticket.Minute:02d} {ticket.Kingaku}円")
# 履歴の欠けを検出したい場合は、SUCCESS と同時に立つ失敗フラグも見る
if (ret & FAILED_CHUOU) != 0:
print("※中央の履歴が欠けています")
if (ret & FAILED_CHIHOU) != 0:
print("※地方の履歴が欠けています")
中央と地方の両方に投票した場合
購入履歴は会場ごとに別々に保持されているため、ログイン済みの会場すべてから取得して連結します。 中央と地方の両方へ投票した購入も、1回の get_purchase_data() で両方の馬券が得られます。
項目 |
扱い |
|---|---|
馬券(TicketData) |
中央 → 地方の順に連結(各会場内は前日 → 当日) |
残高・購入可能件数・当日/累計の金額 |
合算しません。 中央・地方は同じ即PAT 口座を共有するため、どちらか一方の値をそのまま返します |
海外の馬券 |
中央の履歴に含まれます(明細の BetFlag が BETFLAG_INTERNATIONAL) |
片方の会場だけ取得に失敗した場合は、取得できた分を返したうえで FAILED_CHUOU / FAILED_CHIHOU を立てます。この場合 SUCCESS と 同時に立つため、 履歴の欠けを検出したいときはこれらのフラグも確認してください。 両方失敗した場合のみ SUCCESS は立ちません。
受付時刻を読み取れなかった受付は、その受付を捨てるのではなく Hour / Minute が 0 のまま返されます。金額・明細は正常です。
get_odds
指定レース・式別のオッズを取得します(中央競馬・地方競馬・海外競馬に対応)。 単勝・複勝は基本オッズ、枠連〜三連単は全通りのオッズ表を取得します (三連単18頭なら 4,896 点)。
oddsData = ST_ODDS_DATA()
ret = get_odds(place, race_no, shikibetsu, oddsData)
引数 |
型 |
説明 |
|---|---|---|
place |
int |
開催場(KAISAI 定数) |
race_no |
int |
レース番号 |
shikibetsu |
int |
式別(SHIKIBETSU 定数) |
oddsData |
[out] ST_ODDS_DATA インスタンス |
ネイティブ側のメモリは関数内部で自動解放されます。利用者側での解放は不要です。
オッズは 10 倍の整数(Odds)で格納されます。実際の倍率は Odds / 10.0。
複勝・ワイドは下限を Odds、上限を OddsHigh に格納します。
Status が 1(発売中止)/2(オッズ未取得)の場合、Odds / OddsHigh は 0 です。
全式別に対応します。開催場によって発売のない式別(地方の枠連等)は、 サーバ側のエラーまたは明細 0 件になります。
応援馬券(SHIKIBETSU_WINPLACE)はオッズの式別ではないため指定できません(UNSUCCESS)。 単勝・複勝を個別に取得してください。
海外開催にも対応しています。 ただし 中央競馬へのログインが必要 で、 海外競馬に枠は無いため 枠連を指定すると UNSUCCESS を返します。 取得できるオッズの内容は中央・地方と同じです。
指定した開催場が その日開催されていない場合は UNSUCCESS を返します。
oddsData.OddsDetail の各要素(ST_ODDS_DETAIL):
フィールド名 |
説明 |
|---|---|
Type |
式別(SHIKIBETSU 定数) |
Horse1 / Horse2 / Horse3 |
馬番/枠番(単複は1頭、馬連・ワイド・馬単・枠連は2頭、三連系は3頭) |
Status |
0:通常 1:発売中止 2:オッズ未取得 |
Odds / OddsHigh |
オッズ×10(複勝・ワイドは下限/上限) |
oddsData = ST_ODDS_DATA()
ret = get_odds(KAISAI_TOKYO, 11, SHIKIBETSU_QUINELLA, oddsData)
if (ret & 1) == 1:
print(f"オッズ更新時刻: {oddsData.OddsTime} / 明細数: {oddsData.DetailCount}")
for d in oddsData.OddsDetail:
kaime = str(d.Horse1)
if d.Horse2:
kaime += "-" + str(d.Horse2)
if d.Horse3:
kaime += "-" + str(d.Horse3)
odds = f"{d.Odds / 10.0:.1f}" if d.Status == 0 else "-"
print(f" {kaime} : {odds}")
get_race_card
指定レースの出馬表(出走馬一覧)を取得します(中央競馬・地方競馬・海外競馬に対応)。 各出走馬の枠番・馬番・馬名・性齢・馬体重・騎手・斤量・調教師・単勝人気・単勝/複勝オッズを取得します。
raceCard = ST_RACECARD_DATA()
ret = get_race_card(place, race_no, raceCard)
ネイティブ側のメモリは関数内部で自動解放されます。利用者側での解放は不要です。
raceCard.EntryData の各要素は ST_ENTRY_DETAIL です。
raceCard.RaceName はレース名(UTF-8 の文字列)です。取得できない場合は空文字です。
raceCard.Deadline は**発売締切時刻**("HH:MM")です。取得できない場合は空文字です。
raceCard.RaceStatus はそのレースの**発売状態**です(RACE_STATUS_ON_SALE =0 発売中 / RACE_STATUS_CLOSED =1 発売終了 / RACE_STATUS_CANCELED =2 発売中止 / RACE_STATUS_BEFORE_SALE =3 発売前 / RACE_STATUS_UNKNOWN =0xFF 取得できなかった)。締切時刻だけでは購入可否が判断できないため併せて参照してください。
RaceName ・ Deadline ・ RaceStatus の取得に 追加の通信は発生しません。
馬名・騎手名・調教師名などの文字列フィールドは UTF-8 の bytes です。利用時は .decode('utf-8') してください。
斤量・オッズは 10 倍の整数で格納されます。実際の値は / 10.0。
指定した開催場が その日開催されていない場合は UNSUCCESS を返します。
raceCard.EntryData の各要素(ST_ENTRY_DETAIL):
フィールド名 |
説明 |
|---|---|
Wakuban / Umaban |
枠番 / 馬番 |
HorseName / Sex / Age |
馬名(bytes) / 性別(bytes) / 年齢 |
WeightStatus / Weight / WeightDiffCode / WeightDiff |
馬体重の状態(0:通常 1:未発表 2:出走取消 3:計量不能) / 重量(kg) / 増減符号 / 増減量 |
Apprentice |
見習騎手コード(0:なし 1〜5:減量 9:女性騎手2kg減) |
JockeyName / Burden / TrainerName |
騎手名(bytes) / 斤量×10 / 調教師名(bytes) |
WinPopular |
単勝人気(0:データなし) |
WinOddsStatus / WinOdds |
単勝オッズの状態(0:通常 1:発売中止 2:未取得) / オッズ×10 |
PlaceOddsStatus / PlaceOddsLow / PlaceOddsHigh |
複勝オッズの状態 / 下限×10 / 上限×10 |
raceCard = ST_RACECARD_DATA()
ret = get_race_card(KAISAI_TOKYO, 11, raceCard)
if (ret & 1) == 1:
print(f"レース名: {raceCard.RaceName}")
print(f"締切: {raceCard.Deadline} / 発売状態: {raceCard.RaceStatus}")
print(f"オッズ更新時刻: {raceCard.OddsTime} / 出走頭数: {raceCard.EntryCount}")
for e in raceCard.EntryData:
name = e.HorseName.decode('utf-8')
sex = e.Sex.decode('utf-8')
jockey = e.JockeyName.decode('utf-8')
win = f"{e.WinOdds / 10.0:.1f}" if e.WinOddsStatus == 0 else "-"
print(f" {e.Umaban:2d}番 {name} {sex}{e.Age} "
f"斤量{e.Burden / 10.0:.1f} 騎手:{jockey} 単勝:{win} 人気:{e.WinPopular}")
get_kaisai_list
本日開催されている開催場の一覧を取得します(中央競馬・地方競馬・海外競馬に対応)。 開催場ごとに、レース番号・発売締切時刻・発売状態・レース名も併せて返します。
kaisaiData = ST_KAISAI_DATA()
ret = get_kaisai_list(kaisaiData)
ログイン済みの系統を対象とし、海外は中央にログインしていれば含まれます。
系統ごとに1回ずつ、最大3回の通信で全開催場が得られます。 「どの開催場が開催中か」を調べるために get_race_card() を開催場の数だけ呼ぶ必要はありません。
片方の系統だけ失敗した場合は、取得できた分を返したうえで FAILED_CHUOU / FAILED_CHIHOU を立てます(SUCCESS と同時に立ちます)。
開催が1つも無い場合は KaisaiCount が 0 で成功します。
ネイティブ側のメモリは関数内部で自動解放されます。利用者側での解放は不要です。
kaisaiData.KaisaiData の各要素(ST_KAISAI_ITEM):
フィールド名 |
説明 |
|---|---|
Place |
開催場(KAISAI 定数) |
RaceCount |
レース数 |
RaceData |
レース一覧(ST_KAISAI_RACE のリスト) |
RaceData の各要素(ST_KAISAI_RACE):
フィールド名 |
説明 |
|---|---|
RaceNo |
レース番号(1始まり) |
RaceStatus |
発売状態(RACE_STATUS_*) |
Deadline |
発売締切時刻 “HH:MM”(bytes。取得できない場合は空) |
RaceName |
レース名(bytes。取得できない場合は空。海外開催でも取得できます) |
from ipathelper import *
kaisaiData = ST_KAISAI_DATA()
ret = get_kaisai_list(kaisaiData)
if (ret & 1) == 1:
print(f"本日の開催: {kaisaiData.KaisaiCount} 場")
for item in kaisaiData.KaisaiData:
print(f"開催場コード {item.Place} ({item.RaceCount}R)")
for race in item.RaceData:
name = race.RaceName.decode('utf-8')
deadline = race.Deadline.decode('utf-8')
print(f" {race.RaceNo:2d}R {deadline:5s} 状態={race.RaceStatus} {name}")
get_notice
現在有効なお知らせを取得します(中央競馬・地方競馬に対応)。 強制表示お知らせ本文(Message)に加え、お知らせ一覧(ItemData)を全件取得します。
notice = ST_NOTICE_DATA()
ret = get_notice(notice)
ログイン済みのセッションが必要です(中央を優先し、失敗時は地方へフォールバックします)。
ネイティブ側のメモリは関数内部で自動解放されます。利用者側での解放は不要です。
notice.ItemData の各要素は ST_NOTICE_ITEM です。
Title / Date / Url などの文字列フィールドは UTF-8 の bytes です。利用時は .decode('utf-8') してください。
お知らせが無い場合は Message が空文字・ItemCount が 0 で成功します。
Message は HTML を含むことがあり、2048 バイトで打ち切られます(Title は 512 バイト、Url は 1024 バイト)。 古い版の DLL では打ち切り位置が文字の途中になることがあり、.decode('utf-8') が UnicodeDecodeError になる場合があります。最新版へ更新するか、 .decode('utf-8', errors='replace') で安全に読み取ってください。
notice.ItemData の各要素(ST_NOTICE_ITEM):
フィールド名 |
説明 |
|---|---|
Title / Date |
タイトル(bytes) / 日付テキスト(bytes) |
Url / Icon / Color |
リンクURL(bytes) / アイコン(bytes) / 日付表示色(bytes) |
notice = ST_NOTICE_DATA()
ret = get_notice(notice)
if (ret & 1) == 1:
if notice.Message:
print(f"強制表示: {notice.Message}")
print(f"お知らせ {notice.ItemCount} 件")
for item in notice.ItemData:
title = item.Title.decode('utf-8')
date = item.Date.decode('utf-8')
url = item.Url.decode('utf-8')
print(f" [{date}] {title} {url}")
bet_win5_auto
WIN5 を「セレクト」または「ランダム」で購入します。買い目を指定する bet_win5 と違い、 買い目はサーバが生成します。
bet_win5_auto(mode, axisUmaban, betCount, kingaku, year, month, day)
方式 |
動作 |
|---|---|
WIN5_AUTO_SELECT (2) |
axisUmaban で軸馬を指定し、0 にしたレースはサーバが選ぶ (0 にできるのは 1〜4 レース) |
WIN5_AUTO_RANDOM (3) |
5 レースすべてサーバが選ぶ(axisUmaban は None で可) |
生成された買い目はそのまま購入されます。 内容を事前に確認する手段はないため、 呼び出す前に必ず利用者の確認を取ってください。
セレクトは「一部のレースだけ軸を決めて、残りをサーバに選ばせる」方式です。 0(おまかせ)にするレース数は 1〜4 でなければならず、 次の 2 つは送信せずに UNSUCCESS を返します。
指定
例
理由
全レース 0
"0,0,0,0,0"
ランダムと同じになりセレクトの意味がありません。WIN5_AUTO_RANDOM を使ってください
0 が1つも無い
"3,7,1,5,2"
買い目が1通りに決まり、依頼した点数を生成できません。bet_win5 で直接指定してください
点数の上限は 50 点(MAX_WIN5_AUTO_BET_COUNT)で、bet_win5 と違い 分割送信は行いません。
合計金額はサーバが生成した買い目から算出され、1,000,000 円(MAX_TOTAL_AMOUNT_PER_SEND)を 超える場合は送信せずに UNSUCCESS を返します。
WIN5 は中央競馬のみ対応です。
from ipathelper import bet_win5_auto, WIN5_AUTO_SELECT, WIN5_AUTO_RANDOM
# ランダムで 10 点 × 100円
ret = bet_win5_auto(WIN5_AUTO_RANDOM, None, 10, 100, 2026, 8, 9)
# セレクト: 1R の軸だけ決めて 20 点 × 100円
ret = bet_win5_auto(WIN5_AUTO_SELECT, "6,0,0,0,0", 20, 100, 2026, 8, 9)
set_log_callback
DLL 内部のログを受け取るハンドラを登録します(None で解除)。 Release ビルドの DLL でも取得できます。
set_log_callback(handler, minLevel=LOG_LEVEL_INFO)
入出金の失敗調査にはこの API が必須です。 入出金はサーバレンダリングの HTML フォームで、 erc / erm のような機械可読なエラーコードを返しません。失敗した段階・画面 ID・ 画面タイトルは LOG_LEVEL_ERROR で通知されますが、サーバ側の拒否理由が載る 応答本文の抜粋は LOG_LEVEL_TRACE を指定したときのみ通知されます。
ログレベル |
説明 |
|---|---|
LOG_LEVEL_TRACE |
詳細トレース。入出金失敗時の応答本文の抜粋はこのレベルのみ |
LOG_LEVEL_INFO |
情報(既定) |
LOG_LEVEL_WARN |
警告 |
LOG_LEVEL_ERROR |
エラー。失敗した段階・画面 ID・タイトルはこのレベル |
ハンドラは handler(level: int, message: str) の形で呼ばれます。 message は UTF-8 からデコード済みの str です(他の API の bytes と異なります)。
ハンドラは DLL 内部ロックを保持したまま呼ばれます。 ハンドラ内から本モジュールの API を呼び返さないでください(デッドロックします)。
login 実行中は中央・地方の 2 スレッドから同時に呼ばれます。
None を渡して戻った時点で実行中のハンドラは存在しないため、対象を安全に破棄できます。
応答本文の抜粋には口座番号や残高が含まれ得ます。LOG_LEVEL_TRACE は調査時のみ指定し、 ログの取り扱いに注意してください。
from ipathelper import set_log_callback, LOG_LEVEL_INFO, LOG_LEVEL_TRACE
def on_log(level, message):
print(f"[{level}] {message}")
set_log_callback(on_log, LOG_LEVEL_INFO) # 調査時は LOG_LEVEL_TRACE
# ... 各 API を実行 ...
set_log_callback(None) # 解除してからハンドラの対象を破棄する
購入明細の読み方
get_purchase_data() が返す ST_TICKET_DATA_DETAIL は、 購入時の指定そのものではなく、投票内容から復元した値です。 HorseNo1 〜 HorseNo5 の各列が何を指すかは Method(方式)と Type(式別)の 組み合わせで変わります。 列を機械的に - で連結すると誤った買い目になります。
HorseNo のビット表現
bit 0 が馬番 1、bit 1 が馬番 2 … と続きます。判定は (horse_no & (1 << (馬番 - 1))) != 0 です。
枠連(SHIKIBETSU_BRACKETQUINELLA)だけは馬番ではなく枠番で、 bit 0 が枠 1、bit 7 が枠 8 です。
有効なビットの範囲は 国内 18 頭 / 海外 24 頭 / 枠連 8 枠。範囲外のビットは立ちません。
使わない列は 0 です。0 は「指定なし」ではなく「その方式・式別には存在しない列」を 意味します。列がいくつあるかは必ず下表で判断してください。
HorseNo4 と HorseNo5 は WIN5 専用です。WIN5 以外の明細では常に 0 で、 使うのは HorseNo1 〜 HorseNo3 だけです。
def umaban(mask, max_no=18):
'''1つの列から馬番の一覧を取り出す'''
return [n for n in range(1, max_no + 1) if mask & (1 << (n - 1))]
Method / Type とマルチ
Method は HOUSHIKI、Type は SHIKIBETSU と同じ数値です。
応援馬券(SHIKIBETSU_WINPLACE = 9)は Type に現れません。 単勝+複勝の2点として購入されるため、履歴には Type が 1(単勝)と 2(複勝)の 別々の馬券として並びます。
HorseNo の列の意味(方式 × 式別)
— は使用しない列(常に 0)です。
通常(Method = 0)
式別 |
HorseNo1 |
HorseNo2 |
HorseNo3 |
|---|---|---|---|
単勝(1) / 複勝(2) |
馬 1 頭 |
— |
— |
枠連(3) |
枠 2 つ(ゾロ目は 1 つだけ) |
— |
— |
馬連(4) / ワイド(5) |
馬 2 頭(順不同なので同じ列) |
— |
— |
馬単(6) |
1 着馬 |
2 着馬 |
— |
三連複(7) |
馬 3 頭(順不同なので同じ列) |
— |
— |
三連単(8) |
1 着馬 |
2 着馬 |
3 着馬 |
フォーメーション(Method = 1)
式別 |
HorseNo1 |
HorseNo2 |
HorseNo3 |
|---|---|---|---|
枠連(3) |
1 枠目群 |
2 枠目群 |
同枠(ゾロ目)群 ← 枠の選択ではない |
馬連(4) / ワイド(5) / 馬単(6) |
1 列目 |
2 列目 |
— |
三連複(7) / 三連単(8) |
1 列目 |
2 列目 |
3 列目 |
ボックス(Method = 2)
枠連(3)〜三連単(8) のいずれも、選択した馬(枠)すべてが HorseNo1 に入ります (HorseNo2 / HorseNo3 は 0)。
軸1頭系のながし(Method = 3 / 4 / 5 / 9) — 列は「軸」と「相手」です。
Method |
式別 |
HorseNo1 |
HorseNo2 |
HorseNo3 |
|---|---|---|---|---|
3 |
枠連(3) / 馬連(4) / ワイド(5) |
軸 |
相手 |
— |
3 |
馬単(6) / 三連単(8) |
軸(1 着) |
相手 |
— |
3 |
三連複(7) |
軸 1 頭 |
相手 |
— |
4 |
馬単(6) / 三連単(8) |
軸(2 着) |
相手 |
— |
5 |
三連単(8) |
軸(3 着) |
相手 |
— |
9 |
馬単(6) / 三連単(8) |
軸 |
相手 |
— |
軸2頭系のながし(Method = 6 / 7 / 8 / 10)
三連複(式別 7・Method = 6)は順不同のため着順の意味を持たず、 HorseNo1 に軸 2 頭がまとめて入り、HorseNo2 が相手です(HorseNo3 は 0)。
三連単(式別 8)は 列がそのまま着順 になります。 軸 2 頭が入る列を方式が表し、残り 1 列が相手です。
Method |
HorseNo1(1 着) |
HorseNo2(2 着) |
HorseNo3(3 着) |
|---|---|---|---|
6(1・2着ながし) |
軸 |
軸 |
相手 |
7(1・3着ながし) |
軸 |
相手 |
軸 |
8(2・3着ながし) |
相手 |
軸 |
軸 |
10(軸2頭ながしマルチ) |
軸 |
軸 |
相手 |
枠連の表示に関する注意
枠連は 列の数が他の式別と違うため、三連単などと同じ描画処理を通すと誤った表示になります。
通常方式: 買い目は HorseNo1 の枠だけで表せます。 ゾロ目のときは枠が 1 つしか立ちません。 1 つしか立っていない場合は同じ枠を 2 回並べて 8-8 と表示してください。
フォーメーション: 表示に使うのは HorseNo1(1 枠目群)と HorseNo2(2 枠目群)だけです。 HorseNo3 は「1 枠目群と 2 枠目群の両方に現れた枠 = その枠をゾロ目としても買っている」ことを 示す印で、3 つ目の枠の選択ではありません。
買い目 |
HorseNo1 |
HorseNo2 |
HorseNo3 |
点数 |
正しい表示 |
|---|---|---|---|---|---|
1,2,3 → 4,5 |
1,2,3 |
4,5 |
(なし) |
6 |
1,2,3 - 4,5 |
1,2,3 → 2,3,4 |
1,2,3 |
2,3,4 |
2,3 |
8 |
1,2,3 - 2,3,4(うち 2-2, 3-3 はゾロ目) |
8 → 8 |
8 |
8 |
8 |
1 |
8-8(ゾロ目 1 点) |
3 行目を 8-8-8 と表示するのは誤りです。
WIN5 の明細
BetFlag が BETFLAG_WIN5 の明細では、HorseNo1 〜 HorseNo5 が** 第 1〜第 5 レースの馬番**に対応します。 レース単位の情報を持たないため、Kaisai ・ RaceNo ・ Week ・ Method ・ Type には 意味のある値が入りません(すべて 0xFF = 255)。
WIN5 の判定は BetFlag で行うのが確実です。
解析できなかった明細
1 件の明細を解析できなかった場合、その明細は DecisionFlag が DECISIONFLAG_PARSE_FAILED(0)になります。 通常の確定フラグは 1 始まりのため、この値が正常なフラグと衝突することはありません。
フィールド |
解析できなかった明細の値 |
|---|---|
DecisionFlag |
DECISIONFLAG_PARSE_FAILED(0) |
BetFlag |
その受付の券種(どの種別の明細が壊れたか分かるように残ります) |
Kaisai / RaceNo / Week / Method / Type / HorseNo1〜HorseNo5 / Multi |
すべて 0 |
他の明細・他の受付は正常に返されます。 1 件の破損で購入履歴全体を失わないための仕様です。
Method / Type に 0xFF は入りません(WIN5 の判定と衝突させないため)。
1 件も解析できなかった場合は get_purchase_data() 自体が失敗します。 空の履歴として黙って返さないためです。
金額は明細ではなく ST_TICKET_DATA の Kingaku / Payout に入っているため、 金額の集計はこの状況でも正しく行えます。
海外開催の明細
BetFlag が BETFLAG_INTERNATIONAL の明細も、列の意味は上表と 完全に同じです。 違いは次の 2 点だけです。
馬番の上限が 24(国内は 18)。
枠連が存在しません(Type に 3 は現れません)。
買い目を復元できない場合
方式と式別の組み合わせが I-PAT に存在しないものだった場合、HorseNo1 〜 HorseNo5 は 5 列すべて 0 になります(Method / Type / Multi にはそのままの値が入ります)。 正常な購入履歴では発生しませんが、サーバの仕様変更で未知の方式が返った場合にこの形になります。 列がすべて 0 の明細は「買い目なし」として扱ってください。 金額の集計には影響しません。
使用例
基本フロー(ログイン〜単勝購入〜ログアウト)
from ipathelper import *
def main():
try:
# ログイン
ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
if (ret & 1) != 1:
print("ログインに失敗しました。")
return
# 購入情報の構築(東京 11R、単勝、1番、100円)
betData = ST_BET_DATA()
ret = get_bet_instance(
KAISAI_TOKYO, 11,
2026, 4, 5,
HOUSHIKI_NORMAL, SHIKIBETSU_WIN,
100, "1",
betData
)
if (ret & 1) != 1:
print("購入情報の構築に失敗しました。")
return
print(f"合計購入金額: {betData.TotalAmount} 円")
# 馬券購入
betDataList = (ST_BET_DATA * 1)()
betDataList[0] = betData
ret = bet(betDataList, 1)
if (ret & 1) != 1:
print("馬券購入に失敗しました。")
return
print("購入成功")
finally:
logout()
if __name__ == '__main__':
main()
複数買い目の一括購入
from ipathelper import *
def main():
try:
ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
if (ret & 1) != 1:
return
bet_list = [
# (開催場, R, 年, 月, 日, 方式, 式別, 金額, 買い目)
(KAISAI_TOKYO, 11, 2026, 4, 5, HOUSHIKI_NORMAL, SHIKIBETSU_WIN, 100, "3"),
(KAISAI_HANSHIN, 10, 2026, 4, 5, HOUSHIKI_BOX, SHIKIBETSU_QUINELLA, 200, "1,3,5,7"),
(KAISAI_NAKAYAMA, 9, 2026, 4, 5, HOUSHIKI_FORMATION, SHIKIBETSU_TRIFECTA, 100, "1-2,3-4,5"),
# 地方競馬も同じ配列に混在させることができる
(KAISAI_OI, 8, 2026, 4, 5, HOUSHIKI_NORMAL, SHIKIBETSU_EXACTA, 100, "5-8"),
]
n = len(bet_list)
betDataList = (ST_BET_DATA * n)()
for i, (place, r, y, m, d, houshiki, shikibetsu, kingaku, kaime) in enumerate(bet_list):
tmp = ST_BET_DATA()
ret = get_bet_instance(place, r, y, m, d, houshiki, shikibetsu, kingaku, kaime, tmp)
if (ret & 1) != 1:
print(f"[{i}] 購入情報の構築に失敗しました。")
return
betDataList[i] = tmp
# 4件を一括購入(中央・地方は自動振り分け)
ret = bet(betDataList, n)
if (ret & 1) == 1:
print("全件購入成功")
if (ret & 4) == 4:
print("中央競馬の一部または全部が失敗")
if (ret & 8) == 8:
print("地方競馬の一部または全部が失敗")
finally:
logout()
if __name__ == '__main__':
main()
WIN5 の購入
from ipathelper import *
def main():
try:
ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
if (ret & 1) != 1:
return
betDataWin5 = ST_BET_DATA_WIN5()
# レース1: 1・2番 / レース2: 3番 / レース3: 4・5番 / レース4: 6番 / レース5: 7・8番
# -> 2x1x2x1x2 = 8通り、計 800円
ret = get_bet_instance_win5(100, 2026, 4, 5, "1,2-3-4,5-6-7,8", betDataWin5)
if (ret & 1) != 1:
print("WIN5 購入情報の構築に失敗しました。")
return
ret = bet_win5(betDataWin5)
if (ret & 1) == 1:
print("WIN5 購入成功")
else:
print("WIN5 購入失敗")
finally:
logout()
if __name__ == '__main__':
main()
入金・出金
from ipathelper import *
def main():
try:
ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
if (ret & 1) != 1:
return
# 入金(2,000円)
ret = deposit(2000)
if (ret & 1) == 1:
print("入金成功")
# 入金(準備段階のリトライを最大 3 回に制限)
ret = deposit(1000, retryCount=3)
if (ret & 1) != 1:
print("入金できませんでした。原因は set_log_callback のログで確認する。")
# 全額出金
ret = withdraw()
if (ret & 1) == 1:
print("出金成功")
finally:
logout()
if __name__ == '__main__':
main()
自動入金を有効にして購入
from ipathelper import *
def main():
try:
ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
if (ret & 1) != 1:
return
# 残高不足時に 3,000円 自動入金、反映確認タイムアウト 15秒
set_auto_deposit_flag(True, 3000, confirmTimeout=15000)
betData = ST_BET_DATA()
ret = get_bet_instance(
KAISAI_TOKYO, 11, 2026, 4, 5,
HOUSHIKI_FORMATION, SHIKIBETSU_TRIFECTA,
100, "1-2,3,4-5,6,7", betData
)
if (ret & 1) != 1:
return
betDataList = (ST_BET_DATA * 1)()
betDataList[0] = betData
# 残高不足なら自動的に 3,000円 入金してから購入
ret = bet(betDataList, 1)
if (ret & 1) == 1:
print("購入成功")
else:
print("購入失敗(残高不足またはタイムアウト)")
finally:
logout()
if __name__ == '__main__':
main()
購入履歴の取得
from ipathelper import *
def main():
try:
ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
if (ret & 1) != 1:
return
purchaseData = ST_PURCHASE_DATA()
ret = get_purchase_data(purchaseData)
if (ret & 1) == 1:
print(f"残高 : {purchaseData.Balance} 円")
print(f"残購入可能数 : {purchaseData.AvailableBetCount} 件")
print(f"当日購入金額 : {purchaseData.DayPurchase} 円")
print(f"当日払戻金額 : {purchaseData.DayHaraimodosi} 円")
print(f"累計購入金額 : {purchaseData.TotalPurchase} 円")
print(f"累計払戻金額 : {purchaseData.TotalHaraimodosi} 円")
print(f"馬券件数 : {purchaseData.TicketCount} 件")
print("--------------------------------")
for i in range(purchaseData.TicketCount):
ticket = purchaseData.TicketData[i]
day_label = "当日" if ticket.DayFlag == 1 else "前日"
print(f"[受付No.{ticket.ReceiptNo:02d}] "
f"{day_label} "
f"{ticket.Hour:02d}:{ticket.Minute:02d}購入 "
f"{ticket.Kingaku}円 "
f"(払戻: {ticket.Payout}円) "
f"詳細{ticket.DetailCount}点")
for j in range(ticket.DetailCount):
detail = ticket.DetailData[j]
# 解析できなかった明細は買い目が入っていないので飛ばす
if detail.DecisionFlag == DECISIONFLAG_PARSE_FAILED:
print(f" 詳細[{j}]: 解析できませんでした")
continue
status_map = {
DECISIONFLAG_HIT: "的中",
DECISIONFLAG_MISS: "外れ",
DECISIONFLAG_BACK: "返還",
DECISIONFLAG_CANCEL: "取消",
DECISIONFLAG_NORMAL: "確定",
DECISIONFLAG_DEADLINE: "締切",
}
status = status_map.get(detail.DecisionFlag, "不明")
multi = "[マルチ]" if detail.Multi else ""
# WIN5 は Kaisai / RaceNo / Method / Type に意味のある値が入らない
if detail.BetFlag == BETFLAG_WIN5:
print(f" 詳細[{j}]: {status} WIN5")
continue
# 買い目の復元は「購入明細の読み方」を参照
# (列の意味が方式・式別で変わる)
print(f" 詳細[{j}]: {status} {multi} "
f"R{detail.RaceNo} 方式:{detail.Method} 式別:{detail.Type}")
# 履歴の欠けを検出したい場合は、SUCCESS と同時に立つ失敗フラグも見る
if (ret & FAILED_CHUOU) != 0:
print("※中央の履歴が欠けています")
if (ret & FAILED_CHIHOU) != 0:
print("※地方の履歴が欠けています")
# メモリ解放は get_purchase_data 内部で自動実行される
finally:
logout()
if __name__ == '__main__':
main()
エラーハンドリング
from ipathelper import *
# 戻り値のビットフラグを一括確認するユーティリティ関数
def print_return_value(func_name: str, ret: int):
flags = []
if (ret & 1): flags.append("SUCCESS")
if (ret & 2): flags.append("UNSUCCESS")
if (ret & 4): flags.append("FAILED_CHUOU")
if (ret & 8): flags.append("FAILED_CHIHOU")
if (ret & 16): flags.append("FAILED_COMMUNICATE_CHUOU")
if (ret & 32): flags.append("FAILED_COMMUNICATE_CHIHOU")
if (ret & 64): flags.append("FAILED_OUT_OF_SERVICE")
print(f"[{func_name}] {' | '.join(flags)}")
def main():
try:
ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
print_return_value("login", ret)
if (ret & 1) != 1:
if (ret & 64) == 64:
# 受付時間外・メンテナンス中。即時リトライは必ず失敗する
print("サービス時間外です。時間をおいて再試行してください。")
else:
print("ログインに失敗しました。処理を中止します。")
return
# 中央・地方のログイン状態を個別確認
if (ret & 4) == 4:
print("警告: 中央競馬ログイン失敗。中央競馬の馬券は購入できません。")
if (ret & 8) == 8:
print("警告: 地方競馬ログイン失敗。地方競馬の馬券は購入できません。")
betData = ST_BET_DATA()
ret = get_bet_instance(KAISAI_TOKYO, 11, 2026, 4, 5,
HOUSHIKI_NORMAL, SHIKIBETSU_WIN, 100, "5", betData)
print_return_value("get_bet_instance", ret)
if (ret & 1) == 1:
betDataList = (ST_BET_DATA * 1)()
betDataList[0] = betData
ret = bet(betDataList, 1)
print_return_value("bet", ret)
# 通信エラー時は再ログインを試みる
if (ret & 1) != 1 and (ret & 16) == 16:
print("通信エラー。再ログインを試みます。")
logout()
login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
finally:
logout()
if __name__ == '__main__':
main()
対応金融機関
入出金に使用できる金融機関は以下の通りです。
金融機関名 |
コード |
|---|---|
PayPay 銀行 |
2033 |
楽天銀行 |
2036 |
三井住友銀行 |
2009 |
三菱 UFJ 銀行 |
2005 |
住信 SBI ネット銀行 |
2038 |
ゆうちょ銀行 |
2900 |
りそな銀行 |
2010 |
埼玉りそな銀行 |
2017 |
au じぶん銀行 |
2039 |
登録口座の金融機関は自動的に判定します。判定できない場合のみ、上記のコードを 先頭から順に試行し、登録されている口座が見つかった時点でその口座を使用します。
DLL のアンロード
DLL は import ipathelper 時に自動ロードされ、プログラム終了時に自動解放されます。 通常は利用者が意識する必要はありません。
明示的に解放したい場合は、次の順序を守ってください。
すべての API 呼び出しが戻っていることを確認する(他スレッドで実行中の呼び出しが1つも無い状態にする)
logout() を呼ぶ
set_log_callback(None) を呼んでコールバックを解除する
解放する
実行中の呼び出しが残ったまま解放すると動作は未定義です。
set_log_callback(None) から戻った時点で実行中のハンドラは存在しないことが保証されます。 解除せずに解放すると、DLL 内から既に無効なコールバックを呼ぶ可能性があります。
logout() を省略してもローカルの後始末は行われますが、 サーバ側のセッションはログアウトされないまま残ります。
開発者向け: リリース手順
公開は GitHub Actions が自動で行います。手元での公開作業は不要です (deploy_prd.bat などのバッチは廃止しました)。
リポジトリ構成
ipathelper/
├── .github/workflows/release.yml ... バージョン更新・ビルド・PyPI 公開を行う
├── pyproject.toml ... [project] の version を release.yml が自動更新する
└── ipathelper/
├── __init__.py ... DLL の読み込み・解放
├── ipathelper.py ... 各 API のラッパー
├── x64/IpatHelper.dll
└── x86/IpatHelper.dll
自動公開の流れ
IpatHelperNative の CI がビルドした IpatHelper.dll を ipathelper/x64/ と ipathelper/x86/ へ push してくると、それを合図に release.yml が起動して次を順に行います。
pyproject.toml の [project] セクションから version を読み取り、パッチ番号を +1 して書き戻す
dist を削除して uv build
PyPI へ公開する
バージョン更新をコミットして master へ push する
DLL のパスが変わったときだけ起動するため、他のコミットでは公開は走りません。
手動で公開する
DLL を更新していないタイミングで公開したい場合は、GitHub の Actions タブから Release to PyPI を workflow_dispatch で実行します。入力は 2 つです。
入力 |
意味 |
|---|---|
target |
pypi``(既定)または ``testpypi |
dryrun |
true にするとバージョン更新も公開も行わず、ビルドのみ確認する |
testpypi を選ぶ場合のみ、リポジトリの secret に TESTPYPI_API_TOKEN が必要です (TestPyPI 側には publisher を登録していないため、こちらはトークン方式です)。
Metadata
Release files for ipathelper 2.0.48
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ipathelper-2.0.48.tar.gz | 375.6 kB | Without provenance | Details for ipathelper-2.0.48.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ipathelper-2.0.48-py3-none-any.whl | Python 3 | none | any | Details for ipathelper-2.0.48-py3-none-any.whl |
Total release size: 729.9 kB
Release files / ipathelper-2.0.48.tar.gz
| Download URL | ipathelper-2.0.48.tar.gz |
|---|---|
| Size | 375.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3de6d1c0b6f6d579f636568edf2ebe1effc15562306097e75ad7d3f9bf403a50
|
|
BLAKE2b-256 checksum How to use checksums |
89c0b7b690b61d5b27855fb8cbbdeed3ce0f606f248194a58765e7ceca7d3592
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.16 {"installer":{"name":"uv","version":"0.12.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / ipathelper-2.0.48-py3-none-any.whl
| Download URL | ipathelper-2.0.48-py3-none-any.whl |
|---|---|
| Size | 354.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
398b2eb1e69a36db8a66f43139c8d2034566f7b84bd8eea14e18983efb21db85
|
|
BLAKE2b-256 checksum How to use checksums |
389ad073baaf47ec75c07c8bbb3dbd267be70deba128770f3a06ee50039e58e8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.16 {"installer":{"name":"uv","version":"0.12.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for ipathelper 2.0.48
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.