PERL从两个输入文件计算和输出比率调整的时间序列(OHLC)

时间:2011-02-02 20:35:56

标签: perl

  

我想合并两分钟一次   带PERL和调整的系列文件   输入数据输出比率   调整时间序列。

     

我在阅读两篇文章时遇到了麻烦   文件同时设计控制(循环?)架构。

     

我需要能够从FileA读取一行,从fileB读取一行   比较日期和时间值。从   将要么计算   调整时间序列。

    my $cntA = 1 ;
    my $cntB = 1 ;

    if ($cntA == 1 ) { 
        unlink ("$rATS");

        #open files
        open(FA, $fileA) or die "Error opening data file: $fileA $!\n"; 
        open(FB, $fileB) or die "Error opening data file: $fileB $!\n";

        open(MYOUTFILE, ">> $rATS") || die("unable to open $fileName");
        #header
        print MYOUTFILE "Date,Time,Open,High,Low,Close\n";

    }

    =item
        #possible controlling loop 
        foreach my $SymA (@filesA){ 
            foreach my $SumB (@filesB){
                print "$filesASym  $filesBSym\n"; 
    =cut


    while (<FA>) {  
        my @fieldsA  = split /,/,$_;
        #if ($fieldsA[0] != $DateA) { $closeYA = $CloseA ;}
        my $DateA       = $fieldsA[0] ;
        my $TimeA       = $fieldsA[1] ;
        my $OpenA       = $fieldsA[2] ;
        my $HighA       = $fieldsA[3] ;
        my $LowA        = $fieldsA[4] ;
        my $CloseA      = $fieldsA[5] ;
        my $VolumeA     = $fieldsA[6] ;
        my $OpenIntA    = $fieldsA[7] ;


        my $lineNumA = $. ;
        print "line num A: $lineNumA\n\n";

        $cntA++;
        last if $cntA != 0 ;
    }

    while (<FB>) {  
        my @fieldsB  = split /,/,$_;
        #if ($fieldsB[0] != $DateB) { $closeYB = $CloseB ;}
        my $DateB       = $fieldsB[0] ;
        my $TimeB       = $fieldsB[1] ;
        my $OpenB       = $fieldsB[2] ;
        my $HighB       = $fieldsB[3] ;
        my $LowB        = $fieldsB[4] ;
        my $CloseB      = $fieldsB[5] ;
        my $VolumeB     = $fieldsB[6] ;
        my $OpenIntB    = $fieldsB[7] ;

        $cntB++;
        last if $cntB != 0 ;
    }

    close(FA)           || die("unable to close $fileA") ;
    close(FB)           || die("unable to close $fileB") ;
    close(MYOUTFILE)    || die("unable to close $fileName") ;

    =item

sub ratio ($$) {
    my $ratioAB;

    if ($_[0] > $_[1])  { $ratioAB = eval { $_[1] / $_[0]; } ; } warn $@ if $@ ;
    if ($_[0] <= $_[0]) { $ratioAB = eval { $_[0] / $_[1]; } ; } warn $@ if $@ ;  
    return  sprintf("%.2f", $ratioAB) ;
}

sub calcOHLC {
    if ($closeYA > $closeYB) {  
        $open  = sprintf("%.2f",$ratio * $openA - $openB);
        $close = sprintf("%.2f",$ratio * $closeA - $closeB);
        $high  = sprintf("%.2f",$ratio * $highA - $highB); 
        $low   = sprintf("%.2f",$ratio * $lowA - $lowB); 
    }

    if ($closeYA <= $closeYB ) { 
        $open  = sprintf("%.2f",$openA - $ratio * $openB);
        $close = sprintf("%.2f",$closeA - $ratio * $closeB);
        $high  = sprintf("%.2f",$highA - $ratio * $highB);
        $low   = sprintf("%.2f",$lowA - $ratio * $lowB);
    }
    return undef;
}

    sub outputFile{
        print MYOUTFILE "$Date" . "," . "$Time" . "," . "$Open" . "," . "$High" . "," . "$Low" . "," . "$Close" . "\n";
    }
    =cut

示例数据:

    CVX File:
    1/28/2011   957     94.21   94.21   94      94      83424   1357498
    1/28/2011   958     94.02   94.11   94.02   94.1    41351   1398849
    1/28/2011   959     94.1    94.11   94.06   94.1    27715   1426564
    1/28/2011   1000    94.1    94.11   94.06   94.1    27715   1426564
    1/28/2011   1001    94.18   94.2    94.04   94.07   61584   1523943
    1/28/2011   1002    94.07   94.2    94.04   94.06   67352   1591295
    1/28/2011   1003    94.07   94.2    94.04   94.06   67352   1591295
    1/28/2011   1004    94.09   94.16   94.02   94.12   42852   1684278

    XOM File:
    1/28/2011   957     79.59   79.59   79.53   79.55   78759   1997094
    1/28/2011   958     79.59   79.59   79.53   79.55   78759   1997094
    1/28/2011   959     79.62   79.64   79.58   79.58   77559   2107813
    1/28/2011   1000    79.58   79.6    79.58   79.6    87640   2195453
    1/28/2011   1001    79.6    79.61   79.54   79.55   88442   2283895
    1/28/2011   1002    79.6    79.61   79.54   79.55   88442   2283895
    1/28/2011   1003    79.57   79.59   79.55   79.57   54073   2408315
    1/28/2011   1004    79.57   79.58   79.5    79.52   118655  2526970

    ratio as of 1/27/2011 = 79.88/94.75 = .84 
    since CVX is higher XOM/CVX
    (CVX * .84) - XOM for output on 1/28/2011

    Output file
    Date        time    open    high    low     close
    1/28/2011   957     -0.45   -0.45   -0.57   -0.59
    1/28/2011   958     -0.61   -0.54   -0.55   -0.51
    1/28/2011   959     -0.58   -0.59   -0.57   -0.54
    1/28/2011   1000    -0.54   -0.55   -0.57   -0.56
    1/28/2011   1001    -0.49   -0.48   -0.55   -0.53
    1/28/2011   1002    -0.58   -0.48   -0.55   -0.54
    1/28/2011   1003    -0.55   -0.46   -0.56   -0.56
    1/28/2011   1004    -0.53   -0.49   -0.52   -0.46

1 个答案:

答案 0 :(得分:1)

有点不清楚你的意思是“为了处理fileA和fileB并且每个都有一行来计算,但保持某种主循环迭代”。

如果你的意思是希望并行进入2个文件,你可以很容易地做到 - 保持1个循环,每次迭代从每个文件中读取1行。我的代码有点模糊,因为我不知道你想做什么

my ($done, $done_with_A, $done_with_B, $lineA, $lineB) = (0, 0, 0);
while (!$done_with_A || !$done_with_B) {
    if (!$done_with_A) {
        $lineA = <FA>;
    }
    if (!$done_with_B) {
        $lineB = <FB>;
    }
    ($done_with_A, $done_with_B) = are_we_done($lineA, $lineB); 
             # $lineA, $lineB are undef when the files are done.
    process($lineA, $lineB);
}

如果你需要能够从fileA处理多行,为fileB处理1行(反之亦然),那么它会更加复杂 - 你在缓冲区中累积行:

my ($done, $read_from_A, $read_from_B, $done_with_A, $done_with_B, $lineA, $lineB) = (0, 1, 1, 0, 0);
my (@buffer_A, @buffer_B);
while (!$done_with_A || !$done_with_B) {
    if (!$done_with_A && $need_to_read_from_A) {
        $lineA = <FA>;
    }
    if (!$done_with_B && $need_to_read_from_B) {
        $lineB = <FB>;
    }
    ($done_with_A, $done_with_B) = are_we_done($lineA, $lineB); 
             # $lineA, $lineB are undef when the files are done.
    if ( need_more_lines_from_A($lineA, $lineB) ) {
        $read_from_A = 1;
        $read_from_B = 0; # $lineB stays the same
        push @buffer_A, $lineA;
        next;
    }
    if ( need_more_lines_from_B($lineA, $lineB) ) {
        $read_from_A = 0; # $lineA stays the same
        $read_from_B = 1; 
        push @buffer_B, $lineB;
        next;
    }
    push @buffer_A, $lineA;
    push @buffer_B, $lineB;
    process(@buffer_A, @buffer_A);
    @buffer_B = (); @buffer_B = (); # Reset the buffers
    $read_from_A = 0; $read_from_B = 0; # Read next batch.
}