1.予想ソフトの作り方 |
JRA-VANデータを使う予想ソフトを作るための大きなポイントは2つです。
(1)どのようなソフトにするかというコンセプト(アイデア)・・・What
(2)プログラミングのテクニック(スキル)・・・How
(1)は、いわば何を作るか、つまりWhatでどんな機能のものを作るかで、オリジナルソフトには一番肝心なエッセンス−これはシークレットにしておく方がいいでしょう。理由は2つあります。
@1つは、個人の経験や予想理論を基にした貴重なアイデアですから、他の人に真似されないように。。。
Aもう1つは、私のように自分の予想理論がなく、人のアイデアを寄せ集めて作るために、秘密にして置かないと恥ずかしい、という場合もありますが。。。(でも競馬の本を買っての上なので勘弁していただきましょう)(^
^;;
(2)は、アイデアを具体的な形にするためのスキル。いわばHowで、どのように作るか。データをどのように計算して、どのように表示するか。アイデアがすばらしくて、十分なスキルがあれば、売れるソフトが作れます(そういう方はここには用はありませんので、どうぞお引取りを)。
ここはアイデアはあるけど、スキルにちょっと自信がないという人のためのサイトです。といって万年初心者の私なので、スマートにはできませんが、動けばいいやという方針で進めます。
ここではExcelに付属しているVBA(Visual Basic for Application)という言語を利用してプログラムを作ります。VBAはVisual
Basicの一種で、処理速度は遅いですが、まあ実用にはなると思います。初心者にとってはプログラムはなかなかとっつきにくいですが、判るところを少しずつ増やし、根気よく取り組めば、必ずできます。
プログラミングは楽しい!! あなたも競馬でプログラムをモノにしませんか。競馬が当たらなくても楽しめますよ。。。
アイデアもスキルもないが、自分でじっくりと作る根気もない、という方には、市販ソフトを購入することをお勧めします。。。 |
もう少し説明をすると。。。
(1)What--コンセプト(アイデア)や予想理論
これは料理にたとえれば、あっさりとした麺類か、ヘビーなフルコースに仕上げるか。血統のデータベースにするか、スピード指数をベースにするか、あるいはオッズの動きを見るか。。。アナタのこだわりの”味”を出してください。
私が普段使うソフトは、色々な人のアイデアを寄せ集めたもので、タイム指数や、SD指数を使ったり、市販の本を参考にしたり、オッズの変化も見るという鍋物のようなものです。
|
|
(2)How--プログラミング・テクニック
これは料理で言えば、どのような材料(データ)をどのように料理するか。簡単な素材でも名料理人の腕にかかれば、すごい一品になりますが、腕前によっては素材を活かしきれない、ということに。私はいまだにそうですが。。。
ここで使うJRA-VANのデータは、素材としては十分でしょう。
料理するには、
@データの仕組み(構造)を理解すること。
Aデータの解析方法
*データの取り込み方(検索、解読、抽出)
*データのセーブやロード
*データの計算や加工(オッズや連対率、スピード指数など)や計算結果の表示
等が必要です。
|
|
プログラミング・テクニックをアップするには?
@予想ソフトに必要なパーツ・プログラムを理解する。
ソフトの流れを考えて、全体をどのような構成・順番でつくるのかを決め、細分化します。その中で使うプログラムはどのようなものが必要かを推定して、参考書等で近いプログラムを探して理解します。そして自分のプログラムに合わせるにはどこを変えればいいかを考えます。最初はこの作業がうまくいかないでしょう。慣れないとどんなプログラムが必要かがわからないからです。しかし、漠然とでもいいですから、自分で考えること、あるいは参考書のプログラムを予想ソフトに利用するにはどうすればいいのかなという眼で見ていくと必ずヒントになります。
AJRA-VANのソフトウエア工房などのプログラム例やサポートを読む。
これも最初は難しいかもしれません。書かれていることがチンプンカンプンで、あきらめてしまうかもしれませんが、根気よく理解できるものを増やすつもりで読んでいくと、いろんな関係が少しずつ理解できていくと思います。
下記のサイトはまず入り口として参考になるので必読です。
予想ソフトの参考になるJRA-VAN Data Labサイト
(URLは時々変わる場合がありますので、注意してください)
|
2.JRA-VAN Data Labのデータ構造とデータ構造型定義 |
JRA-VANデータ(JV-Data)は、基本的には「固定長バイト」のデータで構成されたテキスト型データです。
JV-Dataの内の代表的な「レース詳細」(レコード種別ID=RA)データの構造イメージは下図のようになっています。図の右側の細長い短冊が「1つのレースを定義するレコード」になっています。レコードに含まれるデータはデータの中身によって「位置」と「データの長さ」が決められています。
例えば最初の2バイトは「レコード種別ID」でこの短冊がどういうデータなのかという種類を区別する記号が割り当てられ、次の3バイト目から1バイト長のデータは「データ区分」としてこのレコードが前日情報なのか、月曜日の成績確定情報なのかなどの区別を示し、次の4バイト目から8バイト長のデータは「データ作成年月日」でいつ作られたレコードかを示し、さらに次の12バイト目から・・・という具合に最後のデータ区切りまで細かく位置が決められていて、全部で”1272バイト”の長さで提供されるというわけです。
このデータの”何バイト目から何バイト”を正しく読み取れば、必要な情報が得られるわけです。JRA-VANのサンプルソフトには、この情報を読み取る関数がふくまれています。このデータの位置と中身については「JRA-VAN
Data Lab. JVData仕様書」を見てください。
慣れないととっつきにくいデータ構造型ですが、理解すれば便利なものです。
(1)JV-Dataは、レコード種別によって長さの決まった「固定長データ」で提供される。短いもので数十バイトから、三連単オッズのように長いデータで80kバイトまで。
(2)レコードの長さは「固定」で、未勝利戦でもG1レースでもレコードの長さは同じで、使わない箇所は「スペース」などの空白データで埋められています。
(3)レコードの数は、その日の開催レース数や出走頭数により変化する。つまり、3場所開催なら「レース詳細(RA)」のレコード数は最大36個、2場所なら24個が提供されます。
いわば、細長いレコードを細かい間仕切りで区切られた各階の「部屋」とすると「レース詳細」データは全体で図の左のように36階建てのビルのような形になっています。各階の部屋には無人(データがない)の箇所もあったり、データの中身は異なったりしますが、間取りと部屋の大きさは各階すべて同じです。
(4)すべて同じ間取りのレコードを互いに区別する情報が、図の太い線で囲まれた「レース開催情報」の部分で、ここに開催年月日や開催場所、レース番号などの情報が含まれています。ここを解読すれば、どの場所の何レースかが特定できます。レコード種別IDが異なってもこの識別できる情報が必ず含まれています。

同様にやはり代表的な「馬毎レース情報」(レコード種別ID=SE)のイメージを下図に示します。
馬毎レース情報というのは出走馬のデータなので、レコード数は1日分で最大3場所x12レースx18頭=648個になります。
各レコードの構成は"RA"データの場合と同じように各データの位置や長さは固定です。馬毎レース情報の場合は、識別データとして、「レース開催情報」のほかに、「馬番・枠番」や「血統登録番号」があります。馬番や枠番はレースが変ると変りますが、「血統登録番号」は各競走馬固有のもので、データベースでは重要なキーインデックスになります。

|
データ構造型とは?
JRA-VANのデータはデータ構造型で定義されています。というと分かりにくいですが、上図のようにデータを区切り別にあるいは階層的にまとめて定義しているようなものと考えます。
下図にJRA-VAN Data Lab.のサンプルソフト(Excel版)に含まれているデータ構造型定義の一部を示します。はじめの方の<レコードヘッダ>や<競走識別情報1>という部分はいろいろな定義の中で共通に使われる定義です。一方、<コーナー通過順位>という部分は、「レース詳細」という構造体定義の中でのみ使われる定義です。
「レース詳細」(Public Type JV_RA_RACE)というデータの定義の中を見ると、単にAs Stringと文字列で定義している部分もありますが、id
As RACE_ID のように別に定義されたものを使って変数(id)を定義するという部分もいくつかあります。


上図の"RA"データは、サンプルソフトでは mRaData As JV_RA_RACEのように定義されます。つまりレコードの1つがJV_RA_RACEの構成をもち、内部はいろいろな項目で定義されています。このようにデータをあるまとまった区切りや階層的にして定義することを構造型といいます。
例えば、「レース詳細(RA)」のデータから、
@レコード種別を取得するには、mRaData.head.RecordSpec とします(headというRECORD_IDの部分の中のRecordSpecを読み出す)。
Aレース番号を取得するには、mRaData.id.RaceNum とします。
B登録頭数を取得するには、mRaData.TourokuTosu とします。
実際の使用例は本文の中の例を見てください。 |
3.JRA-VAN Data Lab データ(JV-Data)のファイル名 |
JRA-VANデータをダウンロードする場合は、ファイル名がキーとなります。このファイル名は「データ種別ID」と「開催日付」及び「データ作成日付」などを組み合わせた形になっています。
ファイル名の決め方の詳細は不明ですが、4種類あり、大体下記のようになっています。
(1)「レース詳細」データの場合
RAXXYYYYMMDDYYYYMMDDHHMMSS.jvd
それぞれの記号の意味は、
先頭の2文字がデータの種類により固有の記号が割り当てられています。レース詳細なら"RA"、馬毎レース情報なら"SE"、払戻情報なら"HR"など。「JRA-VAN
Data Lab. JVData仕様書」のレコード種別ID項目に掲載されています。
XX:これはデータが作成されたタイミングによってある決まった文字列が割り当てられているようですが、内容は公開されていません。JRA-VANはこの文字列を識別記号として使うことを推奨していません(大体固定されているようですが)。
YYYYMMDD:開催日日付。レースが開催される年月日。
つぎのYYYYMMDDHHMMSSは、データが作成された日付・時刻を示すようです。
この長いファイル名を持つデータは次の速報系の(2)(3)(4)以外のデータです。
(2)0B30YYYYMMDDJJRR.jvd形式
これは速報系データのうち、全賭式オッズデータのファイル名の形式です。
0B30:ゼロビーサンゼロ。速報系全賭式オッズデータのデータ種別ID。
YYYYMMDD:レース開催年月日。
JJ:開催場所コード番号。
RR:レース番号。
0B30オッズデータには、単・複・枠連、馬連、ワイド、馬単、三連複、三連単のデータが含まれます。
0B31データは単・複・枠連、0B32は馬連、0B33はワイド、0B34は馬単、0B35は三連複、0B36は三連単の単独データです。
(3)0B11YYYYMMDD.jvd形式
これは速報系データのうち、「開催変更情報」(0B14)、「馬体重」(0B11)、「速報レース情報」(0B12)、「データマイニング情報」(0B13)などに使われるファイル名です。
0B11:データ種別ID。この場合は馬体重情報。
YYYYMMDD:レース開催日付。
(4)0B410000000000YYYYMMDDJJRR.jvd形式
これは速報系データのうち、時系列オッズデータの「単複枠オッズ」(0B41)、「馬連オッズ」(0B42)のファイル名の形式です。
0B41:ゼロビーヨンイチ。オッズ種類のID。今のところ時系列データは、"0B41","0B42"が提供されています。
間に10桁の"0"(ゼロ)をはさみ、(2)と同じ形式の識別情報が続きます。 |
4.JV-Dataの種類 |
下表は、JV-Dataで使われるデータフォーマットの種類の一覧です(サンプルプログラムの標準モジュール:JVlink_Stluctに記述されています)。全部で29種類のデータがあり、それぞれ固有のデータ構造体で定義されます。データセット関数というのは、ダウンロードしたデータをデータ構造体に代入する関数(サブルーチン)です。
このデータセット関数を使うことでJV-Dataが使いやすくなります。
番号 |
フォーマット名 |
データ構造体名 |
データセット関数名 |
備考 |
1 |
特別登録馬 |
JV_TK_TOKUUMA |
SetData_TK |
|
2 |
レース詳細 |
JV_RA_RACE |
SetData_RA |
|
3 |
馬毎レース情報 |
JV_SE_RACE_UMA |
SetData_SE |
|
4 |
払戻 |
JV_HR_PAY |
SetData_HR |
|
5 |
票数1 |
JV_H1_HYOSU_ZENKAKE |
SetData_H1 |
三連単以外 |
6 |
票数6 |
JV_H6_HYOSU_SANRENTAN |
SetData_H6 |
三連単のみ |
7 |
オッズ1 |
JV_O1_ODDS_TANFUKUWAKU |
SetData_O1 |
単複枠連オッズ |
8 |
オッズ2 |
JV_O2_ODDS_UMAREN |
SetData_O2 |
馬連オッズ |
9 |
オッズ3 |
JV_O3_ODDS_WIDE |
SetData_O3 |
ワイドオッズ |
10 |
オッズ4 |
JV_O4_ODDS_UMATAN |
SetData_O4 |
馬単オッズ |
11 |
オッズ5 |
JV_O5_ODDS_SANREN |
SetData_O5 |
三連複オッズ |
12 |
オッズ6 |
JV_O6_ODDS_SANRENTAN |
SetData_O6 |
三連単オッズ |
13 |
競走馬マスタ |
JV_UM_UMA |
SetData_UM |
|
14 |
騎手マスタ |
JV_KS_KISYU |
SetData_KS |
|
15 |
調教師マスタ |
JV_CH_CHOKYOSI |
SetData_CH |
|
16 |
生産者マスタ |
JV_BR_BREEDER |
SetData_BR |
|
17 |
馬主マスタ |
JV_BN_BANUSI |
SetData_BN |
|
18 |
繁殖馬マスタ |
JV_HN_HANSYOKU |
SetData_HN |
|
19 |
産駒マスタ |
JV_SK_SANKU |
SetData_SK |
|
20 |
レコードマスタ |
JV_RC_RECORD |
SetData_RC |
|
21 |
坂路調教 |
JV_HC_HANRO |
SetData_HC |
|
22 |
馬体重 |
JV_WH_BATAIJYU |
SetData_WH |
|
23 |
天候馬場状態 |
JV_WE_WEATHER |
SetData_WE |
|
24 |
出走取消・競走除外 |
JV_AV_INFO |
SetData_AV |
|
25 |
騎手変更 |
JV_JC_INFO |
SetData_JC |
|
26 |
発走時刻変更 |
JV_TC_INFO |
SetData_TC |
|
27 |
コース変更 |
JV_CC_INFO |
SetData_CC |
|
28 |
データマイニング予想 |
JV_DM_INFO |
SetData_DM |
|
29 |
開催スケジュール |
JV_YS_SCHEDULE |
SetData_YS |
|
実際のソフトで使う場合には、下図のようにダウンロードしたデータを必要なデータセット関数でデータをセットして初めて利用できると考えてください。

サンプルプログラムの標準モジュール(JVLink_Stluct)には他にも共通のデータ構造体やバイト長データを切り出す重要な関数などが定義されています。
|
5.JV-Dataのファイルの読み方 |
** 馬主マスタ”BN”を例にしたダウンロード **
(1)JVLinkでダウンロードしたデータを表示する場合(サンプルソフトと同じ)
@追加する定義
Dim mBnData As JV_BN_BANUSI ‘(サンプルソフトの馬主マスタの定義参照)
Dim j As Integer, k As Integer
A参考コード
Dim i As Integer
i = 0
retVal = 1
While retVal <> 0
'JVOpenで指定したデータを1レコードずつ取り込み
retVal = JVLink1.JVRead(buff, 40000,
filename)
If Left(buff, 2) = "BN" Then ‘馬主マスタの場合
'JVData構造体にBNのレコードをセットする
Call SetData_BN(buff, mBnData)
‘←データセット関数利用
'Sheet1の表示箇所に表示
Sheet1.Cells(4 + i, 2) =
mBnData.BanusiCode ‘馬主コード
Sheet1.Cells(4 + i, 3) = mBnData.BanusiName ‘馬主名(法人格無)
Sheet1.Cells(4 + i, 4) = mBnData.Fukushoku ‘服色標示
‘繰り返し表示(本年・累計賞金、着回数データ)
For j= 0 To 1
Sheet1.Cells(4 + i, 5 + 9 * j) =
mBnData.HonRuikei(j).SetYear
Sheet1.Cells(4 + i, 6 + 9 * j) =
mBnData.HonRuikei(j).HonSyokinTotal
Sheet1.Cells(4 + i, 7 + 9 * j) =
mBnData.HonRuikei(j).Fukasyokin
For k= 0 To 5
Sheet1.Cells(4+i,8+9*j + k) =
mBnData.HonRuikei(j).Chakukaisu(k)
Next k
Next j
i = i + 1
‘(2)のいったん配列に読み込む場合はここに追加(後述)
End If
Label1.Caption = buff
DoEvents
Wend
JVLink.JVClose
上記でSheet1にデータセット関数で読み込んだデータが表示されると思います。馬主は法人格のものは表示していないので歯抜けになるかも、また繰り返し表示の部分はセル位置がずれてるかもしれませんので、適当にj,k列位置を計算してください。
(2)JVLinkでダウンロードしたデータをいったん配列に読み込む場合
以下を追加
@ 標準モジュール内(NENGAPPIの定義と同じモジュール)
Public BnData( ) As String ‘馬主マスタ配列
A (1)と同じプロシージャ内
Dim FileData(1) As String
‘ファイル名保存
ReDim BnData(1 To 1296) As String
‘仮馬主マスタ配列
B 上記の(後述)の部分に下記コードを挿入
BnData(i)= Left(buff, Len(buff) -2 ) ‘バッファデータを配列に読み込む
C上記のJVLink.JVClose の後に追加(BnData配列のセーブとロード)
‘セーブ
'----- ファイルへの代入 -----
If retVal = -1 Then 'データの区切り
If Left(filename, 2) = "BN"
Then '馬主マスタデータ
FileData(1) = Left(filename,
Len(filename) - 4) & ".dat"
End If
End If
CopyFile$ = COPY_DIR & NENGAPPI &
"\" & FileData(1)
'馬主マスタ
FileNo = FreeFile
Open CopyFile$ For Output As #FileNo
For q = 1 To i
Print #FileNo, BnData(q)
Next q
Close #FileNo
‘ロード
CopyFile$ = COPY_DIR & NENGAPPI &
"\BN*.dat" '馬主マスター
If Dir(CopyFile$) <> ""
Then
filename = Dir(CopyFile$)
FileData(1) = filename
CopyFile$ = COPY_DIR & NENGAPPI
& "\" & filename
FileNo = FreeFile
Open CopyFile$ For Input As #FileNo
'データ数(k)を求める
k = FileLen(CopyFile$) / 477 '477は馬主データのサイズ(バイト)
ReDim BnData(1 to k) As String
For i = 1 To k
Line Input #FileNo, BnData(i)
Next i
Close #FileNo
End If
ReDim BnData(1
To 1296)のデータサイズ1296は「土日分」で最大1296頭の馬主がすべて違う場合の想定のため。実際には600くらいで十分? 1296というのは仮のサイズで、最初は馬主数が分からないので、最大に設定しておき、読みながらカウントI=I+1していけば最後のIが馬主数になります。セーブするときにI分だけセーブします。ロードするときはファイル長を477バイトで割ったサイズkが馬主数なので、最大k分のデータを読み込みます。
以上でコードは終わりです。うまくいった場合にはディレクトリ内にBNxxxx.datファイルができているはずです。ロード部分はセーブしたものを読み出すためのサンプルなので、なくても構いませんが、これを使ってデータセット関数でCall SetData_BN(buff, mBnData)のbuff部分をBnData(i)に置き換えれば、iを変化して配列の中身を次々にmBnDataにセットすることができます。BnData(i)の形にしてしまえば別にSetData_BNを使う必要もないのですが、半角・全角の処理をやってくれるのは楽かなと思います。
以上は”BN”のデータで説明しましたが、他のデータでも基本的には同じです。FileData(1)というのは他のデータも同様にセーブするときにこのサイズを増やせば類似の方法でセーブできという便宜上のものなので、”BN”しかセーブしない場合は、A$とかでも構いません。
|