Math-Business-BlackscholesMerton
view release on metacpan or search on metacpan
lib/Math/Business/BlackScholesMerton/Binaries.pm
lib/Math/Business/BlackScholesMerton/NonBinaries.pm
t/00-check-deps.t
t/00-compile.t
t/00-report-prereqs.dd
t/00-report-prereqs.t
t/BlackScholes.t
t/barrier_infinity.t
t/barrier_zero.t
t/benchmark.t
t/get_min_iterations_pelsser.t
t/get_stability_constant_pelsser_1997.t
t/lib/Roundnear.pm
t/min_accuracy_pelsser.t
t/negative_rate.t
t/price_test.t
t/pricing_params.csv
t/rc/.perlcriticrc
t/rc/.perltidyrc
t/small_value_mu.t
t/smalltime.t
lib/Math/Business/BlackScholesMerton/Binaries.pm view on Meta::CPAN
# one barrier is already hit (can happen due to shift markup):
if ($S >= $U or $S <= $D) {
return $w ? exp(-$t * $r_q) : 1;
}
#
# SANITY CHECKS
#
# For extreme cases, the price will be wrong due the values in the
# infinite series getting too large or too small, which causes
# roundoff errors in the computer. Thus no matter how many iterations
# you make, the errors will never go away.
#
# For example try this:
#
# my ($S, $U, $D, $t, $r, $q, $vol, $w)
# = (100.00, 118.97, 99.00, 30/365, 0.1, 0.02, 0.01, 1);
# $up_price = Math::Business::BlackScholesMerton::Binaries::ot_up_ko_down_pelsser_1997(
# $S,$U,$D,$t,$r,$q,$vol,$w);
# $down_price= Math::Business::BlackScholesMerton::Binaries::ot_down_ko_up_pelsser_1997(
# $S,$U,$D,$t,$r,$q,$vol,$w);
lib/Math/Business/BlackScholesMerton/Binaries.pm view on Meta::CPAN
my $mu_dash = sqrt(max(0, ($mu_new * $mu_new) + (2 * $sigma * $sigma * $r_q * (1 - $w))));
my $series_part = 0;
my $hyp_part = 0;
# These constants will determine whether or not this contract can be
# evaluated to a predefined accuracy. It is VERY IMPORTANT because
# if these conditions are not met, the prices can be complete nonsense!!
my $stability_constant = get_stability_constant_pelsser_1997($S, $U, $D, $t, $r_q, $mu, $sigma, $w, $eta, 1);
# The number of iterations is important when recommending the
# range of the upper/lower barriers on our site. If we recommend
# a range that is too big and our iteration is too small, the
# price will be wrong! We must know the rate of convergence of
# the formula used.
my $iterations_required = get_min_iterations_pelsser_1997($S, $U, $D, $t, $r_q, $mu, $sigma, $w);
for (my $k = 1; $k < $iterations_required; $k++) {
my $lambda_k_dash = (0.5 * (($mu_dash * $mu_dash) / ($sigma * $sigma) + ($k * $k * $pi * $pi * $sigma * $sigma) / ($h * $h)));
my $phi = ($sigma * $sigma) / ($h * $h) * exp(-$lambda_k_dash * $t) * $k / $lambda_k_dash;
$series_part += $phi * $pi * sin($k * $pi * ($h - $x) / $h);
#
# Note that greeks may also call this function, and their
# stability constant will differ. However, for simplicity
# we will not bother (else the code will get messy), and
lib/Math/Business/BlackScholesMerton/Binaries.pm view on Meta::CPAN
sub ot_down_ko_up_pelsser_1997 {
my ($S, $U, $D, $t, $r_q, $mu, $sigma, $w) = @_;
my $mu_new = $mu - (0.5 * $sigma * $sigma);
my $x = log($S / $D);
return exp(-$mu_new * $x / ($sigma * $sigma)) * common_function_pelsser_1997($S, $U, $D, $t, $r_q, $mu, $sigma, $w, 0);
}
=head2 get_min_iterations_pelsser_1997
USAGE
my $min = get_min_iterations_pelsser_1997($S, $U, $D, $t, $r_q, $mu, $sigma, $w, $accuracy)
DESCRIPTION
An estimate of the number of iterations required to achieve a certain
level of accuracy in the price.
=cut
sub get_min_iterations_pelsser_1997 {
my ($S, $U, $D, $t, $r_q, $mu, $sigma, $w, $accuracy) = @_;
if (not defined $accuracy) {
$accuracy = $MIN_ACCURACY_UPORDOWN_PELSSER_1997;
}
if ($accuracy > $MIN_ACCURACY_UPORDOWN_PELSSER_1997) {
$accuracy = $MIN_ACCURACY_UPORDOWN_PELSSER_1997;
} elsif ($accuracy <= 0) {
$accuracy = $MIN_ACCURACY_UPORDOWN_PELSSER_1997;
}
my $it_up = _get_min_iterations_ot_up_ko_down_pelsser_1997($S, $U, $D, $t, $r_q, $mu, $sigma, $w, $accuracy);
my $it_down = _get_min_iterations_ot_down_ko_up_pelsser_1997($S, $U, $D, $t, $r_q, $mu, $sigma, $w, $accuracy);
my $min = max($it_up, $it_down);
return $min;
}
=head2 _get_min_iterations_ot_up_ko_down_pelsser_1997
USAGE
my $k_min = _get_min_iterations_ot_up_ko_down_pelsser_1997($S, $U, $D, $t, $r_q, $mu, $sigma, $w, $accuracy)
DESCRIPTION
An estimate of the number of iterations required to achieve a certain
level of accuracy in the price for ONETOUCH-UP-KNOCKOUT-DOWN.
=cut
sub _get_min_iterations_ot_up_ko_down_pelsser_1997 {
my ($S, $U, $D, $t, $r_q, $mu, $sigma, $w, $accuracy) = @_;
if (!defined $accuracy) {
die "accuracy required";
}
my $pi = Math::Trig::pi;
my $h = log($U / $D);
my $x = log($S / $D);
lib/Math/Business/BlackScholesMerton/Binaries.pm view on Meta::CPAN
my $mu_dash = sqrt(max(0, ($mu_new * $mu_new) + (2 * $sigma * $sigma * $r_q * (1 - $w))));
my $A = ($mu_dash * $mu_dash) / (2 * $sigma * $sigma);
my $B = ($pi * $pi * $sigma * $sigma) / (2 * $h * $h);
my $delta_dash = $accuracy;
my $delta = $delta_dash * exp(-$mu_new * ($h - $x) / ($sigma * $sigma)) * (($h * $h) / ($pi * $sigma * $sigma));
# This can happen when stability condition fails
if ($delta * $B <= 0) {
die "(_get_min_iterations_ot_up_ko_down_pelsser_1997) Cannot "
. "evaluate minimum iterations because too many iterations "
. "required!! delta=$delta, B=$B for input parameters S=$S, "
. "U=$U, D=$D, t=$t, r_q=$r_q, mu=$mu, sigma=$sigma, w=$w, "
. "accuracy=$accuracy";
}
# Check that condition is satisfied
my $condition = max(exp(-$A * $t) / ($B * $delta), 1);
my $k_min = log($condition) / ($B * $t);
$k_min = sqrt($k_min);
lib/Math/Business/BlackScholesMerton/Binaries.pm view on Meta::CPAN
return $MIN_ITERATIONS_UPORDOWN_PELSSER_1997;
} elsif ($k_min > $MAX_ITERATIONS_UPORDOWN_PELSSER_1997) {
return $MAX_ITERATIONS_UPORDOWN_PELSSER_1997;
}
return int($k_min);
}
=head2 _get_min_iterations_ot_down_ko_up_pelsser_1997
USAGE
DESCRIPTION
An estimate of the number of iterations required to achieve a certain
level of accuracy in the price for ONETOUCH-UP-KNOCKOUT-UP.
=cut
sub _get_min_iterations_ot_down_ko_up_pelsser_1997 {
my ($S, $U, $D, $t, $r_q, $mu, $sigma, $w, $accuracy) = @_;
my $h = log($U / $D);
my $mu_new = $mu - (0.5 * $sigma * $sigma);
$accuracy = $accuracy * exp($mu_new * $h / ($sigma * $sigma));
return _get_min_iterations_ot_up_ko_down_pelsser_1997($S, $U, $D, $t, $r_q, $mu, $sigma, $w, $accuracy);
}
=head2 range
USAGE
my $price = range($S, $U, $D, $t, $r_q, $mu, $sigma, $w)
PARAMS
$S stock price
$t time (1 = 1 year)
t/get_min_iterations_pelsser.t view on Meta::CPAN
use Roundnear;
my $S = 1.35;
my $barrier_u = 1.36;
my $barrier_l = 1.34;
my $t = 7 / 365;
my $sigma = 0.11;
my $r = 0.002;
my $q = 0.001;
my $min_iterations =
Math::Business::BlackScholesMerton::Binaries::get_min_iterations_pelsser_1997($S, $barrier_u, $barrier_l, $t, $r, $r - $q, $sigma, 0,);
ok($min_iterations == 16, 'min_iterations (no accuracy specified)');
$min_iterations =
Math::Business::BlackScholesMerton::Binaries::get_min_iterations_pelsser_1997($S, $barrier_u, $barrier_l, $t, $r, $r - $q, $sigma, 0, 1);
ok($min_iterations == 16, 'min_iterations (accuracy 1)');
$min_iterations =
Math::Business::BlackScholesMerton::Binaries::get_min_iterations_pelsser_1997($S, $barrier_u, $barrier_l, $t, $r, $r - $q, $sigma, 0, -1);
ok($min_iterations == 16, 'min_iterations (accuracy 1)');
throws_ok {
$min_iterations =
Math::Business::BlackScholesMerton::Binaries::_get_min_iterations_ot_up_ko_down_pelsser_1997($S, $barrier_u, $barrier_l, $t, $r, $r - $q,
$sigma, 0);
}
qr/accuracy required/, 'accuracy required';
throws_ok {
$min_iterations =
Math::Business::BlackScholesMerton::Binaries::_get_min_iterations_ot_up_ko_down_pelsser_1997($S, $barrier_u, $barrier_l, $t, $r, $r - $q,
$sigma, 0, -1);
}
qr/too many iterations required/, 'too many iterations required';
$Math::Business::BlackScholesMerton::Binaries::MIN_ITERATIONS_UPORDOWN_PELSSER_1997 = -1;
$Math::Business::BlackScholesMerton::Binaries::MAX_ITERATIONS_UPORDOWN_PELSSER_1997 = -1;
$min_iterations =
Math::Business::BlackScholesMerton::Binaries::_get_min_iterations_ot_up_ko_down_pelsser_1997($S, $barrier_u, $barrier_l, $t, $r, $r - $q, $sigma,
0, 1);
ok($min_iterations == -1, 'min_iterations (accuracy 1)');
Test::NoWarnings::had_no_warnings();
done_testing();
xt/author/eol.t view on Meta::CPAN
'lib/Math/Business/BlackScholesMerton/Binaries.pm',
'lib/Math/Business/BlackScholesMerton/NonBinaries.pm',
't/00-check-deps.t',
't/00-compile.t',
't/00-report-prereqs.dd',
't/00-report-prereqs.t',
't/BlackScholes.t',
't/barrier_infinity.t',
't/barrier_zero.t',
't/benchmark.t',
't/get_min_iterations_pelsser.t',
't/get_stability_constant_pelsser_1997.t',
't/lib/Roundnear.pm',
't/min_accuracy_pelsser.t',
't/negative_rate.t',
't/price_test.t',
't/pricing_params.csv',
't/rc/.perlcriticrc',
't/rc/.perltidyrc',
't/small_value_mu.t',
't/smalltime.t',
( run in 0.547 second using v1.01-cache-2.11-cpan-5511b514fd6 )