rupee 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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