Reputation: 109
I have below output in some variable in my perl script-the out output is actually coming from some executable which I am storing in variable $retval in this case- example below
my $retval=`imp_vol -u 110.5 -s 110.9 -p 0.005 -t 0.041 -c 1`
Black Scholes NVol = 1.19711
Black Scholes NDelta = 0.0494522
Black Scholes NGamma = 0.42176
Black Scholes NTheta = -0.302207
Black Scholes NVega = 0.0207006
Black Scholes Vol = 0.0108141
Black Scholes Delta = 0.049565
Black Scholes Gamma = 0.42329
Black Scholes Theta = -0.302212
Black Scholes Vega = 2.29159
Here imp_vol is my executable with different parameters..and it prints different BLack Scholes values.Now My purpose is to get all the Black Scholes Values-Below is what I am using currently using in perl script-
if($retval=~/\s*Black\s+Scholes\s+Vol\s*\=\s*(.*)/i){
$vol=$1;
}
if($retval=~/\s*Black\s+Scholes\s+Delta\s*\=\s*(.*)/i){
$delta=$1;
}
if($retval=~/\s*Black\s+Scholes\s+Gamma\s*\=\s*(.*)/i){
$gamma=$1;
}
if($retval=~/\s*Black\s+Scholes\s+Theta\s*\=\s*(.*)/i){
$theta=$1;
}
if($retval=~/\s*Black\s+Scholes\s+Vega\s*\=\s*(.*)/i){
$vega=$1;
}
if($retval=~/\s*Black\s+Scholes\s+NVol\s*\=\s*(.*)/i){
$nvol=$1;
}
if($retval=~/\s*Black\s+Scholes\s+NDelta\s*\=\s*(.*)/i){
$ndelta=$1;
}
if($retval=~/\s*Black\s+Scholes\s+NGamma\s*\=\s*(.*)/i){
$ngamma=$1;
}
if($retval=~/\s*Black\s+Scholes\s+NTheta\s*\=\s*(.*)/i){
$ntheta=$1;
}
if($retval=~/\s*Black\s+Scholes\s+NVega\s*\=\s*(.*)/i){
$nvega=$1;
}
Any help will be applauded
Upvotes: 4
Views: 136
Reputation: 126722
First of all you should put the text returned by the backticks imp_val ...
into an array instead of a scalar. That will split it into lines and make it much easier to handle.
Then you can process it into a hash using just map
with a regular expression. It looks like this. Note that I have used Data::Dump
and dd
only to demonstrate the resulting hash structure: you would not need it in your own code
use strict;
use warnings;
use Data::Dump;
my @retval = `imp_vol -u 110.5 -s 110.9 -p 0.005 -t 0.041 -c 1`;
my %scholes = map { /(\w+)\s*=\s*(-?[\d.]+)/ } @retval;
dd \%scholes;
output given the data you show in your question
{
Delta => 0.049565,
Gamma => 0.42329,
NDelta => 0.0494522,
NGamma => 0.42176,
NTheta => -0.302207,
NVega => 0.0207006,
NVol => 1.19711,
Theta => -0.302212,
Vega => 2.29159,
Vol => 0.0108141,
}
Update
From your other comments it looks like you want a subroutine to return a specific sequence of values. I suggest that this code would be best:
use strict;
use warnings;
use Data::Dump;
sub scholes {
my @retval=`imp_vol -u 110.5 -s 110.9 -p 0.005 -t 0.041 -c 1`;
my %scholes = map { /(\w+)\s*=\s*(-?[\d.]+)/ } @retval;
return @scholes{qw/ Vol Delta Gamma Theta Vega NVol NDelta NGamma NTheta NVega /};
}
dd [ scholes ];
output
[
0.0108141,
0.049565,
0.42329,
-0.302212,
2.29159,
1.19711,
-0.302207,
0.0207006,
0.0494522,
0.42176,
]
Upvotes: 1
Reputation: 97948
You can instead collect them in a hash:
use strict;
use warnings;
my $retval = <<HERE;
Black Scholes NVol = 1.19711
Black Scholes NDelta = 0.0494522
Black Scholes NGamma = 0.42176
Black Scholes NTheta = -0.302207
Black Scholes NVega = 0.0207006
Black Scholes Vol = 0.0108141
Black Scholes Delta = 0.049565
Black Scholes Gamma = 0.42329
Black Scholes Theta = -0.302212
Black Scholes Vega = 2.29159
HERE
my %h;
while ($retval =~ /Black\s+Scholes\s+(\S*)\s*\=\s*(\S*)/ig) {
$h{lc $1} = $2;
}
for my $k (keys %h) {
print "$k, $h{$k}\n";
}
Produces:
ntheta, -0.302207
nvega, 0.0207006
ndelta, 0.0494522
vol, 0.0108141
theta, -0.302212
ngamma, 0.42176
nvol, 1.19711
vega, 2.29159
delta, 0.049565
gamma, 0.42329
Upvotes: 4