rupee 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
data/.autotest ADDED
@@ -0,0 +1,4 @@
1
+ begin
2
+ require "test_notifier/runner/autotest"
3
+ rescue LoadError
4
+ end
data/README.rdoc CHANGED
@@ -66,9 +66,9 @@ Fargo using the following (note that you only need to <tt>require</tt> the
66
66
  wfc.change
67
67
  #=> 0.17
68
68
 
69
- <tt>wfc.get</tt> will return a hash of the requested information for the security.
70
- Each valid parameter will also have its own utility method. The results will
71
- update every <tt>wfc.frequency</tt> seconds (defaults to 15).
69
+ <tt>wfc.get</tt> will return a hash of the requested information for the
70
+ security. Each valid parameter will also have its own utility method. The
71
+ results will update every <tt>wfc.frequency</tt> seconds (defaults to 15).
72
72
 
73
73
  Got it? Good. This will surely help you collect some rupees in real life.
74
74
 
@@ -95,8 +95,8 @@ faster than the same thing in Ruby.
95
95
  Also, if you're doing a valuation on a one-off set of examples (e.g. in a Monte
96
96
  Carlo simulation), you probably don't want to create an object every time.
97
97
  Something like <tt>Rupee::Option.black_scholes ...</tt> should work just fine.
98
- Creating a <tt>Rupee::Option</tt> object takes roughly the same amount of time as
99
- running <tt>Rupee::Option.black_scholes</tt> a dozen times.
98
+ Creating a <tt>Rupee::Option</tt> object takes roughly the same amount of time
99
+ as running <tt>Rupee::Option.black_scholes</tt> a dozen times.
100
100
 
101
101
  However, if you're creating and reusing an object, I strongly recommend
102
102
  preserving the object orientation of Ruby: the penalty for using a new instance
data/ext/rupee/rupee.h CHANGED
@@ -16,6 +16,7 @@ double simple_df(double r, double time, bool discrete);
16
16
 
17
17
  /* Statistics */
18
18
  double cnd(double);
19
+ double std(double *, int);
19
20
  void init_distribution();
20
21
 
21
22
  /* Options */
@@ -0,0 +1,111 @@
1
+ #include "rupee.h"
2
+
3
+ #define PI 3.1415926536
4
+
5
+ double
6
+ cnd(z)
7
+ double z;
8
+ {
9
+ double L, K, dCND;
10
+ static const double b = 0.2316419;
11
+ static const double a1 = 0.31938153;
12
+ static const double a2 = 0.356563782;
13
+ static const double a3 = 1.781477937;
14
+ static const double a4 = 1.821255978;
15
+ static const double a5 = 1.330274429;
16
+
17
+ L = fabs(z);
18
+ K = 1.0 / (1.0 + b * L);
19
+
20
+ dCND = 1.0 - 1.0 / sqrt(2.0 * PI) *
21
+ exp(-L * L / 2.0) *
22
+ (a1 * K -
23
+ a2 * K * K +
24
+ a3 * K * K * K -
25
+ a4 * K * K * K * K +
26
+ a5 * K * K * K * K * K);
27
+
28
+ if (z < 0.0)
29
+ return 1.0 - dCND;
30
+ else
31
+ return dCND;
32
+ }
33
+
34
+ double
35
+ mean(values, len)
36
+ double *values;
37
+ int len;
38
+ {
39
+ double result;
40
+ int i;
41
+ result = 0;
42
+
43
+ for (i = 0; i < len; i++)
44
+ result += values[i];
45
+
46
+ return result / len;
47
+ }
48
+
49
+ double
50
+ std(values, len)
51
+ double *values;
52
+ int len;
53
+ {
54
+ double bar_x, result;
55
+ int i;
56
+ result = 0;
57
+
58
+ bar_x = mean(values, len);
59
+
60
+ for (i = 0; i < len; i++)
61
+ result += pow(values[i] - bar_x, 2);
62
+
63
+ return sqrt(result / (len - 1));
64
+ }
65
+
66
+ /* call-seq: cnd(z)
67
+ *
68
+ * Returns the standard normal cumulative distribution (has a mean of zero and
69
+ * a standard deviation of one).
70
+ *
71
+ * ==== Arguments
72
+ *
73
+ * * +z+ - The value for which you want the distribution
74
+ */
75
+ static VALUE
76
+ rupee_cnd(self, _z)
77
+ VALUE self, _z;
78
+ {
79
+ return rb_float_new(cnd(NUM2DBL(_z)));
80
+ }
81
+
82
+ static VALUE
83
+ rupee_std(self, _values)
84
+ VALUE self, _values;
85
+ {
86
+ int len = RARRAY_LEN(_values);
87
+ double *values;
88
+
89
+ rtofa(values, _values, len);
90
+
91
+ return rb_float_new(std(values, len));
92
+ }
93
+
94
+ void
95
+ init_distribution()
96
+ {
97
+ VALUE klass, singleton;
98
+
99
+ #if 0
100
+ VALUE module = rb_define_module("Rupee");
101
+ #endif
102
+
103
+ klass = rb_define_class_under(module, "Statistics", rb_cObject);
104
+ singleton = rb_singleton_class(klass);
105
+
106
+ rb_define_singleton_method(klass, "cumulative_normal_distribution", rupee_cnd, 1);
107
+ rb_define_alias(singleton, "cnd", "cumulative_normal_distribution");
108
+ rb_define_singleton_method(klass, "standard_deviation", rupee_std, 1);
109
+ rb_define_alias(singleton, "std", "standard_deviation");
110
+ rb_define_alias(singleton, "stdev", "standard_deviation");
111
+ }
@@ -7,10 +7,10 @@ module Rupee
7
7
  # by Michael Neumann (with some revisions)
8
8
  #
9
9
  # http://www.espenhaug.com/black_scholes.html
10
- def black_scholes(callPutFlag, s, x, t, r, v)
10
+ def black_scholes(call_put_flag, s, x, t, r, v)
11
11
  d1 = (Math.log(s / x) + (r + v * v / 2.0) * t) / (v * Math.sqrt(t))
12
12
  d2 = d1 - v * Math.sqrt(t)
13
- if callPutFlag == 'c'
13
+ if call_put_flag == 'c'
14
14
  s * cnd(d1) - x * Math.exp(-r * t) * cnd(d2)
15
15
  else
16
16
  x * Math.exp(-r * t) * cnd(-d2) - s * cnd(-d1)
@@ -19,12 +19,6 @@ module Rupee
19
19
 
20
20
  private
21
21
 
22
- A1 = 0.31938153 # :nodoc:
23
- A2 = -0.356563782 # :nodoc:
24
- A3 = 1.781477937 # :nodoc:
25
- A4 = -1.821255978 # :nodoc:
26
- A5 = 1.330274429 # :nodoc:
27
-
28
22
  # Cumulative normal distribution
29
23
  #
30
24
  # by Michael Neumann (with some revisions)
@@ -34,9 +28,12 @@ module Rupee
34
28
  l = x.abs
35
29
  k = 1.0 / (1.0 + 0.2316419 * l)
36
30
  w = 1.0 - 1.0 / Math.sqrt(2 * Math::PI) * Math.exp(-l * l / 2.0) *
37
- (A1 * k + A2 * k * k + A3 * (k ** 3) + A4 * (k ** 4) + A5 * (k ** 5))
31
+ ( 0.31938153 * k +
32
+ -0.356563782 * (k ** 2) +
33
+ 1.781477937 * (k ** 3) +
34
+ -1.821255978 * (k ** 4) +
35
+ 1.330274429 * (k ** 5))
38
36
  w = 1.0 - w if x < 0
39
- return w
40
37
  end
41
38
  end
42
39
  end
data/lib/rupee/option.rb CHANGED
@@ -24,7 +24,8 @@ module Rupee
24
24
  attr_alias :value, :price
25
25
 
26
26
  def black_scholes
27
- @value = self.class.black_scholes @type.to_s, @underlying, @strike, @time, @rate, @div_yield, @volatility
27
+ @value = self.class.black_scholes @type.to_s, @underlying, @strike,
28
+ @time, @rate, @div_yield, @volatility
28
29
  end
29
30
  end
30
31
 
data/lib/rupee/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Rupee
2
2
  # The current version
3
- VERSION = "0.1.6"
3
+ VERSION = "0.1.7"
4
4
  end
@@ -2,14 +2,26 @@ require File.dirname(__FILE__) + "/../spec_helper"
2
2
 
3
3
  describe Rupee::Option do
4
4
  describe "European option valuation" do
5
+ before :each do
6
+ @tolerance = 0.0001
7
+ @call = Rupee::Option.new(
8
+ :underlying => 60,
9
+ :strike => 65,
10
+ :time => 0.25,
11
+ :rate => 0.08,
12
+ :div_yield => 0,
13
+ :volatility => 0.3
14
+ )
15
+ end
16
+
5
17
  describe "using the Black-76 model" do
6
18
  describe "on a call option of price $60, strike $65, time to expiry 0.25, risk-free rate 8%, and volatility 30%" do
7
19
  it "should return $1.7202 for a call" do
8
- Rupee::Option.black76("c", 60, 65, 0.25, 0.08, 0.3).round(4).should == 1.7202
20
+ Rupee::Option.black76("c", 60, 65, 0.25, 0.08, 0.3).should be_within(@tolerance).of 1.7202
9
21
  end
10
22
 
11
23
  it "should return $6.6212 for a put" do
12
- Rupee::Option.black76("p", 60, 65, 0.25, 0.08, 0.3).round(4).should == 6.6212
24
+ Rupee::Option.black76("p", 60, 65, 0.25, 0.08, 0.3).should be_within(@tolerance).of 6.6212
13
25
  end
14
26
  end
15
27
  end
@@ -17,13 +29,13 @@ describe Rupee::Option do
17
29
  describe "using the generalized Black-Scholes model" do
18
30
  describe "on a call option of price $60, strike $65, time to expiry 0.25, risk-free rate 8%, and volatility 30%" do
19
31
  it "should return $1.7202 for a call" do
20
- Rupee::Option.generalized_black_scholes("c", 60, 65, 0.25, 0.08, 0, 0.3).round(4).should == 1.7202
21
- Rupee::Option.gbs("c", 60, 65, 0.25, 0.08, 0, 0.3).round(4).should == 1.7202
32
+ Rupee::Option.generalized_black_scholes("c", 60, 65, 0.25, 0.08, 0, 0.3).should be_within(@tolerance).of 1.7202
33
+ Rupee::Option.gbs("c", 60, 65, 0.25, 0.08, 0, 0.3).should be_within(@tolerance).of 1.7202
22
34
  end
23
35
 
24
36
  it "should return $6.6212 for a put" do
25
- Rupee::Option.generalized_black_scholes("p", 60, 65, 0.25, 0.08, 0, 0.3).round(4).should == 6.6212
26
- Rupee::Option.gbs("p", 60, 65, 0.25, 0.08, 0, 0.3).round(4).should == 6.6212
37
+ Rupee::Option.generalized_black_scholes("p", 60, 65, 0.25, 0.08, 0, 0.3).should be_within(@tolerance).of 6.6212
38
+ Rupee::Option.gbs("p", 60, 65, 0.25, 0.08, 0, 0.3).should be_within(@tolerance).of 6.6212
27
39
  end
28
40
  end
29
41
  end
@@ -31,13 +43,14 @@ describe Rupee::Option do
31
43
  describe "using the Black-Scholes model" do
32
44
  describe "on a call option of price $60, strike $65, time to expiry 0.25, risk-free rate 8%, and volatility 30%" do
33
45
  it "should return $1.7202 for a call" do
34
- Rupee::Option.black_scholes("c", 60, 65, 0.25, 0.08, 0, 0.3).round(4).should == 2.1334
35
- Rupee::Option.bs("c", 60, 65, 0.25, 0.08, 0, 0.3).round(4).should == 2.1334
46
+ Rupee::Option.black_scholes("c", 60, 65, 0.25, 0.08, 0, 0.3).should be_within(@tolerance).of 2.1334
47
+ Rupee::Option.bs("c", 60, 65, 0.25, 0.08, 0, 0.3).should be_within(@tolerance).of 2.1334
48
+ @call.black_scholes.should be_within(@tolerance).of 2.1334
36
49
  end
37
50
 
38
51
  it "should return $6.6212 for a put" do
39
- Rupee::Option.black_scholes("p", 60, 65, 0.25, 0.08, 0, 0.3).round(4).should == 5.8463
40
- Rupee::Option.bs("p", 60, 65, 0.25, 0.08, 0, 0.3).round(4).should == 5.8463
52
+ Rupee::Option.black_scholes("p", 60, 65, 0.25, 0.08, 0, 0.3).should be_within(@tolerance).of 5.8463
53
+ Rupee::Option.bs("p", 60, 65, 0.25, 0.08, 0, 0.3).should be_within(@tolerance).of 5.8463
41
54
  end
42
55
  end
43
56
  end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe Rupee::Statistics do
4
+ it "cumulative normal distribution should return 50% for 0" do
5
+ Rupee::Statistics.cnd(0).round(4).should == 0.5
6
+ end
7
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rupee
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-09-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
- requirement: &70967150 !ruby/object:Gem::Requirement
16
+ requirement: &68970630 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '1.0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70967150
24
+ version_requirements: *68970630
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70966890 !ruby/object:Gem::Requirement
27
+ requirement: &68970360 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '2.0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70966890
35
+ version_requirements: *68970360
36
36
  description: ! " rupee aims to provide user-friendly tools for
37
37
  use in\n financial gems and applications.\n"
38
38
  email:
@@ -42,6 +42,7 @@ extensions:
42
42
  - ext/rupee/extconf.rb
43
43
  extra_rdoc_files: []
44
44
  files:
45
+ - .autotest
45
46
  - .gitignore
46
47
  - .rspec
47
48
  - COPYING
@@ -49,12 +50,12 @@ files:
49
50
  - README.rdoc
50
51
  - Rakefile
51
52
  - ext/rupee/bond.c
52
- - ext/rupee/distribution.c
53
53
  - ext/rupee/extconf.rb
54
54
  - ext/rupee/future.c
55
55
  - ext/rupee/option.c
56
56
  - ext/rupee/rupee.c
57
57
  - ext/rupee/rupee.h
58
+ - ext/rupee/statistics.c
58
59
  - ext/rupee/util.c
59
60
  - lib/rupee.rb
60
61
  - lib/rupee/benchmark.rb
@@ -65,9 +66,9 @@ files:
65
66
  - lib/rupee/version.rb
66
67
  - rupee.gemspec
67
68
  - spec/c/bond_spec.rb
68
- - spec/c/distribution_spec.rb
69
69
  - spec/c/future_spec.rb
70
70
  - spec/c/option_spec.rb
71
+ - spec/c/statistics_spec.rb
71
72
  - spec/import/quote_spec.rb
72
73
  - spec/spec_helper.rb
73
74
  - tasks/benchmark.rake
@@ -98,7 +99,7 @@ specification_version: 3
98
99
  summary: Financial tools for Ruby
99
100
  test_files:
100
101
  - spec/c/bond_spec.rb
101
- - spec/c/distribution_spec.rb
102
102
  - spec/c/future_spec.rb
103
103
  - spec/c/option_spec.rb
104
+ - spec/c/statistics_spec.rb
104
105
  - spec/import/quote_spec.rb
@@ -1,63 +0,0 @@
1
- #include "rupee.h"
2
-
3
- #define PI 3.1415926536
4
-
5
- double
6
- cnd(z)
7
- double z;
8
- {
9
- double L, K, dCND;
10
- static const double b = 0.2316419;
11
- static const double a1 = 0.31938153;
12
- static const double a2 = 0.356563782;
13
- static const double a3 = 1.781477937;
14
- static const double a4 = 1.821255978;
15
- static const double a5 = 1.330274429;
16
-
17
- L = fabs(z);
18
- K = 1.0 / (1.0 + b * L);
19
-
20
- dCND = 1.0 - 1.0 / sqrt(2.0 * PI) *
21
- exp(-L * L / 2.0) *
22
- (a1 * K -
23
- a2 * K * K +
24
- a3 * K * K * K -
25
- a4 * K * K * K * K +
26
- a5 * K * K * K * K * K);
27
-
28
- if (z < 0.0)
29
- return 1.0 - dCND;
30
- else
31
- return dCND;
32
- }
33
-
34
- /* call-seq: cnd(z)
35
- *
36
- * Returns the standard normal cumulative distribution (has a mean of zero and
37
- * a standard deviation of one).
38
- *
39
- * ==== Arguments
40
- *
41
- * * +z+ - The value for which you want the distribution
42
- */
43
- static VALUE
44
- rupee_cnd(self, rz)
45
- VALUE self, rz;
46
- {
47
- return rb_float_new(cnd(NUM2DBL(rz)));
48
- }
49
-
50
- void
51
- init_distribution()
52
- {
53
- VALUE klass, singleton;
54
-
55
- #if 0
56
- VALUE module = rb_define_module("Rupee");
57
- #endif
58
-
59
- klass = rb_define_class_under(module, "Distribution", rb_cObject);
60
- singleton = rb_singleton_class(klass);
61
-
62
- rb_define_singleton_method(klass, "cnd", rupee_cnd, 1);
63
- }
@@ -1,7 +0,0 @@
1
- require File.dirname(__FILE__) + "/../spec_helper"
2
-
3
- describe "Cumulative normal distribution" do
4
- it "should return a probability of 50% for 0" do
5
- Rupee::Distribution.cnd(0).round(4).should == 0.5
6
- end
7
- end