#!/usr/bin/perl
# 時系列オッズ取得用のスクリプトです。
use strict ;
use Win32::OLE ;
use Win32::OLE::Variant ;
#===========================================================================#
my $pass = 'h:/DATA/RT_DATA/' ; # 時系列データ格納場所 ★
my $tpass = 'h:/DATA/SE_DATA/' ; # TARGET 成績データパス ★
my $year = 2006 ; # 年を指定 ★
my $fromm = 1 ; # 何月から ★
my $fromd = 28 ; # 何日から ★
my $fromt = 0 ; # 時〜 ★
# --------------------------------------------------------------------------#
{
$pass .= 'JI_' . $year ;
mkdir $pass unless -d $pass ;
$pass .= '/' ;
}
# --------------------------------------------------------------------------#
my $jktf = [ '0B41', 970, 'JT' ] ; # 時系列単複枠
my $jkur = [ '0B42', 2050, 'JU' ] ; # 時系列馬連
#############################################################################
my $jvd = &jv_first ; # ← ぜったい必要
&jv_init() ; # ← ぜったい必要
#---------------------------------------------------------------------------#
&main() ;
&jv_close() ;
################### 以下、JV-Link サブルーチン *****************************#
sub jv_first {
my $jvd ;
eval { $jvd = Win32::OLE->GetActiveObject( 'JVDTLab.JVLink' ) } ;
die "JVLink not installed" if $@ ;
unless (defined $jvd) {
$jvd = Win32::OLE->new( 'JVDTLab.JVLink', sub { $_[0]->Quit ; } )
or die "残念〜。 cannot start JVLink !" ;
}
return $jvd ;
}
sub jv_init { # JVLink 初期化
my $sid = 'UNKNOWN' ;
my $rtn = $jvd->JVInit( $sid ) ;
if( $rtn == 0 ) {
print "初期化は正常です。\n" ;
my $version = $jvd->m_JVLinkVersion ;
print "JVLink Version; $version \n" ;
} else {
die "適切な sid ではありません。$rtn\n" ;
}
}
sub jv_close { # JVClose
my $rtn = $jvd->JVClose() ;
print "JVClose エラー。$rtn\n" if $rtn == -1 ;
}
#===========================================================================#
sub main {
my @keys ;
my $ymdbr ;
my $sfile = "${tpass}${year}/SCHD${year}.dat" ;
my $ftime = sprintf "%s%02d%02d%02d", $year, $fromm, $fromd, $fromt ;
open DAT, $sfile or die " Can't open $sfile \n" ;
while ( <DAT> ) {
my ( $m, $n ) = unpack '@2 A1 @11 A10', $_ ;
next unless $m == 3 ; # 開催された日以外は外す
next if $n < $ftime ;
push @keys, $n ;
}
close DAT ;
# -----------------------------------------------------------------
for my $i ( @keys ) {
for my $j ( 1..12 ) {
my $jj = sprintf "%02d", $j ;
$ymdbr = $i . $jj ;
&get_jikr( $jktf ) ; # 単複枠
&get_jikr( $jkur ) ; # 馬連
}
}
sub get_jikr { # 引数はリファレンス( 種別ID、仮サイズ、ヘッダ )
my ( $ds, $bs, $hd ) = @{ shift() } ;
my $rtn = $jvd->JVRTOpen( $ds, $ymdbr ) ;
my $i = 0 ;
RTR: while ( $rtn < -400 or $rtn == -1 ){
sleep 1 ;
$rtn = $jvd->JVRTOpen( $ds, $ymdbr ) ;
$i++ ;
last RTR if $i > 2 ;
}
my $dir = $pass ;
my ( $nenn, $dname ) = unpack 'A4A4', $ymdbr ;
$dir .= $dname ;
mkdir $dir unless -d $dir ;
$dir .= '/' ;
if( $rtn == 0 ) {
my $bsize = Variant( VT_I4, $bs ) ;
my $pbuf = Variant( VT_UI1, "\x00" x $bs ) ;
my $buff = Variant( VT_BSTR|VT_BYREF, \$pbuf ) ;
my $fn = Variant( VT_BSTR|VT_BYREF, '' ) ; # ファイル名
my $flg ;
my $i = 0 ;
my $id ;
my @dat = () ;
while ( $flg = $jvd->JVRead( $buff, $bsize, $fn ) ) {
if( $flg > 0 ) {
my $line = $buff->Value() ;
$id = substr( $line, 11, 16 ) if $i == 0 ;
$dat[$i] = $line ;
$i++ ;
} elsif( $flg == -1 ) {
my $fname = $dir . $hd . $id . '.DAT' ;
open DAT, ">$fname" ;
for ( @dat ) {
s/\x00+//g ; s/\r// ;
print DAT $_ ;
}
close DAT ;
@dat = () ; $i = 0 ;
print "\t\t読み込み完了。→ : $fn\n" ;
} else {
print " 時系列データ・読み込みエラー。 $flg\n" ;
}
}
} elsif( $rtn == -1 ) {
print "時系列・該当データがありません。$rtn\n" ;
} elsif ( $rtn == -504 ) {
print "サーバーメンテナンス中。\n" ;
} else {
print "OPENエラー。$rtn\n" ;
}
&jv_close() ;
}
}
__END__
最近、時系列データを観察するようになってから、これが購入馬券決定に欠かせない要素の一つ
だ
#!/usr/bin/perl -w
# 乗替り初騎乗データをTARGETから抽出するスクリプト
# raceID 場(jo:2)年(yy:2)回(kai:1)日(nch:1)RNo.(rn:2)馬番(ub:2)旧
# 年月日(yyyymmdd:4+2+2)場(jo:2)回(kai:2)日(nch:2)RNo.(rn:2)馬番(ub:2)新
# 2006.02.08
# ★ の部分は、環境に応じて修正
use strict ;
my $dtpass = 'H:/DATA/SE_DATA' ; # ★ TARGET のSE_DATA パス
my $outF = 'allse.txt' ; # ★ 出力ファイル名
my $byear = 2000 ; # ★ データ取得の最初の年を決める
my $eyear = 2006 ; # ★ 最後の年
my $kako = 3 ; # ★ 何年前まで( 一応3年 )適当に
my %alls ;
for my $year ( $byear .. $eyear ) {
my @files = grep { -e } glob "$dtpass/$year/SU*.IDX" ;
for my $file ( @files ) {
my $kai = substr ( $file, -6, 1 ) ; # 回
my $jo = substr ( $file, -5, 1 ) ; # 場
print "$kai $jo \n" ; # for DBG
open DAT, $file or die "Can't Open $file \n" ;
while ( <DAT> ) {
chomp ;
next unless /^\d/ ; # 行頭に数字がなければスキップ
my ( $mmdd, $nch, $rn, $ub, $ucd, $kcd ) =
unpack '@0 A4 @4 A1 @5 A2 @8 A2 @10 A8 @48 A5', $_ ;
my $line = join '', $year, $mmdd, $kcd, $jo, $kai, $nch, $rn, $ub ;
push @{$alls{$ucd}}, $line ; # ハッシュに配列データを入れる
}
close DAT ;
}
}
# --------------------- ここまでが取得 -- これから出力 -------------------
open OUT, ">$outF" ;
foreach my $cd ( sort keys %alls ) {
my @allse = @{$alls{$cd}} ; # 無駄なコピーかもしれないが
my $num = $#allse ; # 最後の添え字( $#allse == @allse - 1 )
next unless $num > 0 ; # 戦歴が1回しかなければパス
my @sorted = sort { substr( $b, 0, 8 ) <=> substr( $a, 0, 8 ) } @allse ;
foreach my $i ( 0 .. $num-1 ) { # 対象レースを順に
my ( $year, $mmdd, $kcd, $jo, $knrb ) = unpack 'A4A4A5A1A6', $sorted[$i] ;
last if $eyear > $year + $kako ; # 出力期間制限をここでしている
my $yy = substr( $year, 2, 2) ; # 西暦年の下2桁
$jo = $jo eq 'A' ? 10 : sprintf "%02d", $jo ;
my $raceID = join '', $jo, $yy, $knrb ; # 繋ぎ合わせて raceID を
foreach my $j ( $i+1 .. $num ) { # 過去のレースを順に
last if $kcd eq substr( $sorted[$j], 8, 5 ) ;
print OUT "$raceID\n" if $j == $num ; # 最後まで一致しなければOK!
}
}
}
close OUT ;
__END__
TARGET の SE_DATA からの抽出方法は上の通りです。他にも応用が利くと思います。念のため、ここに置いておきます ⇒ スクリプト (allse.pl)(2006.02.08)
簡単と書くだけではアレなので、 ここに ⇒ スクリプト (alls.pl)(2006.02.09)
その分、時間は少し余計にかかります。