#!/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)
その分、時間は少し余計にかかります。