开发者

PERL calculate and output ratio adjusted time series ( OHLC ) from two input files [closed]

开发者 https://www.devze.com 2023-02-08 09:13 出处:网络
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical andcannot be reasonably answered in its current form. For help clari
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. Closed 12 years ago.

I wish to merge two one minute time series files with PERL and adjusting the input data to output a ratio adjusted time series.

I am having troubles with reading two files at the same time and designing the control (loop?) architecture.

I need to able to read one line from FileA and one line from fileB and compare the date and time values. From there will either calculate the adjusted time series.

    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 $rat开发者_Python百科ioAB;

    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

Sample Data:

    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


It's a little bit unclear what you mean by "in order to process fileA and fileB and have both a line from each to calc, yet keep some sort of master loop iterating".

if you mean that you wish to advance in 2 files in parallel, you can do it fairly easily - keep 1 loop, and read 1 line from each file per iteration. My code below is a bit vague since I don't know what you want to do

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);
}

If you need to be able to possibly process several lines from fileA for 1 line for fileB (or vice versa), its a bit more complicated - you accumulate lines in buffers:

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.
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号