use strict;
use warnings;
use Test::More;

BEGIN {
    use_ok('PDL');
    use_ok('PDL::NiceSlice');
    use_ok('PDL::Finance::TA');
};
use_ok('App::financeta::language');
use_ok('App::financeta::indicators');

my $lang = new_ok( 'App::financeta::language' => [ debug => 0 ] );

my $test = <<'TEST';
### START OF AUTOGENERATED CODE - DO NOT EDIT
#### The list of variables that you can use is below:
#### $open
#### $high
#### $low
#### $close
#### $macd_12_26_9
#### $macdsig_12_26_9
#### $macdhist_12_26_9
#### END OF AUTOGENERATED CODE
no short trades;
buy at $open WHEN $macdhist_12_26_9
  becomes positive AND $macd_12_26_9 crosses $macdsig_12_26_9 FROM BELOW;
sell at
  $high WHEN $macdhist_12_26_9 becomes negative AND $macd_12_26_9 crosses $macdsig_12_26_9
  from above;
TEST
my $output = $lang->compile(
    $test,
    [
        qw/
          open
          high
          low
          close
          macd_12_26_9
          macdsig_12_26_9
          macdhist_12_26_9
          /
    ]
);
isnt( $output, undef, 'compiler can parse rules' );
note($output);
my $coderef = $lang->generate_coderef($output);
is( ref $coderef, 'CODE', 'can eval output into a code-ref' )
  or diag("\$coderef is $coderef");

my $ohlc = randsym( 300, 5 ) + 2.5;
$ohlc ( , (0) ) .= sequence(300);    # set the time to be incremental

#note($ohlc);

my $indicators = new_ok('App::financeta::indicators');

my $macdfix_output = $indicators->execute_ohlcv(
    $ohlc,
    {
        func   => 'MACD Fixed to 12/26',
        group  => 'Momentum Indicators',
        params => { InSignalPeriod => 9, },
    },
);
is( ref $macdfix_output, 'ARRAY', 'macd output is valid' );
my $macd_12_26_9     = $macdfix_output->[0]->[1];
my $macdsig_12_26_9  = $macdfix_output->[1]->[1];
my $macdhist_12_26_9 = $macdfix_output->[2]->[1];
note( $macd_12_26_9->dims );
note( $macdsig_12_26_9->dims );
note( $macdhist_12_26_9->dims );

my $coderef_test = sub {
    my $open             = shift;
    my $high             = shift;
    my $low              = shift;
    my $close            = shift;
    my $macd_12_26_9     = shift;
    my $macdsig_12_26_9  = shift;
    my $macdhist_12_26_9 = shift;
    my $buys             = zeroes( $close->dims );
    my $sells            = zeroes( $close->dims );
    my $lookback         = 1;
    my $idx_0            = xvals( $macdhist_12_26_9->dims ) - $lookback;
    $idx_0 = $idx_0->setbadif( $idx_0 < 0 )->setbadtoval(0);
    my $idx_1 = xvals( $macd_12_26_9->dims ) - $lookback;
    $idx_1 = $idx_1->setbadif( $idx_1 < 0 )->setbadtoval(0);
    my $idx_2 =
    which( ( $macdhist_12_26_9 >= 0.000001 ) &
        ( $macdhist_12_26_9->index($idx_0) < 0.000001 ) &
        ( $macd_12_26_9->index($idx_1) <
            $macdsig_12_26_9->index($idx_1) ) &
        ( $macd_12_26_9 > $macdsig_12_26_9 ) );
    $buys->index($idx_2) .= $open->index($idx_2);
    my $idx_3 = xvals( $macdhist_12_26_9->dims ) - $lookback;
    $idx_3 = $idx_3->setbadif( $idx_3 < 0 )->setbadtoval(0);
    my $idx_4 = xvals( $macd_12_26_9->dims ) - $lookback;
    $idx_4 = $idx_4->setbadif( $idx_4 < 0 )->setbadtoval(0);
    my $idx_5 =
    which( ( $macdhist_12_26_9 <= -0.000001 ) &
        ( $macdhist_12_26_9->index($idx_3) > -0.000001 ) &
        ( $macd_12_26_9->index($idx_4) >
            $macdsig_12_26_9->index($idx_4) ) &
        ( $macd_12_26_9 < $macdsig_12_26_9 ) );
    $sells->index($idx_5) .= $high->index($idx_5);
    return { buys => $buys, sells => $sells, long => 1, short => 0 };
};

my $result = &$coderef(
    $ohlc ( , (1) ),
    $ohlc ( , (2) ),
    $ohlc ( , (3) ),
    $ohlc ( , (4) ),
    $macd_12_26_9,
    $macdsig_12_26_9,
    $macdhist_12_26_9
);
is( ref $result,          'HASH', 'results is a hashref' );
is( ref $result->{buys},  'PDL',  'buys is a PDL' );
is( ref $result->{sells}, 'PDL',  'sells is a PDL' );
is($result->{short}, 0, 'no short trades');
is($result->{long}, 1, 'allow long trades');
note( $result->{buys} );
note( $result->{sells} );

# end of testing
done_testing();
__END__
### COPYRIGHT: 2013-2023. Vikas N. Kumar. All Rights Reserved.
### AUTHOR: Vikas N Kumar <vikas@cpan.org>
### DATE: 3rd Sept 2014
### LICENSE: Refer LICENSE file
