trading_formulas 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in trading_formulas.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Matt Osentoski
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # TradingFormulas
2
+
3
+ This gem contains trading formulas for Technical Analysis and Derivatives
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'trading_formulas'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install trading_formulas
18
+
19
+ ## Usage
20
+
21
+ s = 50
22
+ k = 50
23
+ r = 0.10
24
+ sigma = 0.30
25
+ time = 0.50
26
+ option_price = TradingFormulas::BlackScholes.call(s, k, r, sigma, time)
27
+
28
+ ## Contributing
29
+
30
+ 1. Fork it
31
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
32
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
33
+ 4. Push to the branch (`git push origin my-new-feature`)
34
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ # Lines required for testing
5
+ require 'rake/testtask'
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'test'
8
+ end
9
+ desc "Run tests"
10
+ task :default => :test
@@ -0,0 +1,124 @@
1
+ module TradingFormulas
2
+ ##
3
+ # Author:: Matt.Osentoski (matt.osentoski@gmail.com)
4
+ #
5
+ # This module contains formulas based on bermudan equations
6
+ # Converted to Python from "Financial Numerical Recipes in C" by:
7
+ # Bernt Arne Odegaard
8
+ # http://finance.bi.no/~bernt/gcc_prog/index.html
9
+ #
10
+ class BermudanOptions
11
+
12
+ ##
13
+ # Bermudan Option (Call) using binomial approximations
14
+ # +s+: spot (underlying) price
15
+ # +k+: strike (exercise) price
16
+ # +r+: interest rate
17
+ # +q+: artificial "probability"
18
+ # +sigma+: volatility
19
+ # +time+: time to maturity
20
+ # +potential_exercise_times+: Array of potential exercise times. (Ex: [0.25, 0.75] for 1/4 and 3/4 of a year)
21
+ # +steps+: Number of steps in binomial tree
22
+ # *Returns* Option price
23
+ def self.call(s, k, r, q, sigma, time, potential_exercise_times, steps)
24
+ delta_t = time/steps
25
+ r_tmp = Math.exp(r*delta_t)
26
+ r_inv = 1.0/r_tmp
27
+ u = Math.exp(sigma*Math.sqrt(delta_t))
28
+ uu = u*u
29
+ d = 1.0/u
30
+ p_up = (Math.exp((r-q)*(delta_t))-d)/(u-d)
31
+ p_down = 1.0-p_up
32
+ prices = Array.new(steps+1)
33
+ call_values = Array.new(steps+1)
34
+
35
+ potential_exercise_steps = [] # create list of steps at which exercise may happen
36
+ (0..(potential_exercise_times.count)).each do |i|
37
+ t = potential_exercise_times[i].to_f
38
+ if ( (t>0.0) && (t<time) )
39
+ potential_exercise_steps << (t/delta_t).to_i
40
+ end
41
+ end
42
+ prices[0] = s*(d**steps) # fill in the endnodes.
43
+ (1..(steps+1)).each do |i|
44
+ prices[i] = uu*prices[i-1]
45
+ end
46
+ (0..(steps+1)).each do |i|
47
+ call_values[i] = [0.0, (prices[i]-k)].max
48
+ end
49
+ (steps-1).downto(0) do |step|
50
+ check_exercise_this_step = false
51
+ (0..(potential_exercise_steps.count)).each do |j|
52
+ if (step == potential_exercise_steps[j])
53
+ check_exercise_this_step = true
54
+ end
55
+ end
56
+ (0..(steps+1)).each do |i|
57
+ call_values[i] = (p_up*call_values[i+1].to_f+p_down*call_values[i].to_f)*r_inv
58
+ prices[i] = d*prices[i+1].to_f
59
+ if (check_exercise_this_step)
60
+ call_values[i] = [call_values[i].to_f,prices[i].to_f-k].max
61
+ end
62
+ end
63
+ end
64
+ return call_values[0]
65
+ end
66
+
67
+
68
+ ##
69
+ # Bermudan Option (Put) using binomial approximations
70
+ # +s+: spot (underlying) price
71
+ # +k+: strike (exercise) price
72
+ # +r+: interest rate
73
+ # +q+: artificial "probability"
74
+ # +sigma+: volatility
75
+ # +time+: time to maturity
76
+ # +potential_exercise_times+: Array of potential exercise times. (Ex: [0.25, 0.75] for 1/4 and 3/4 of a year)
77
+ # +steps+: Number of steps in binomial tree
78
+ # *Returns* Option price
79
+ def self.put(s, k, r, q, sigma, time, potential_exercise_times, steps)
80
+ delta_t=time/steps
81
+ r_tmp = Math.exp(r*delta_t)
82
+ r_inv = 1.0/r_tmp
83
+ u = Math.exp(sigma*Math.sqrt(delta_t))
84
+ uu = u*u
85
+ d = 1.0/u
86
+ p_up = (Math.exp((r-q)*delta_t)-d)/(u-d)
87
+ p_down = 1.0-p_up
88
+ prices = Array.new(steps+1)
89
+ put_values = Array.new(steps+1)
90
+
91
+ potential_exercise_steps = [] # create list of steps at which exercise may happen
92
+ (0..(potential_exercise_times.count)).each do |i|
93
+ t = potential_exercise_times[i].to_f
94
+ if ( (t>0.0) && (t<time) )
95
+ potential_exercise_steps << (t/delta_t).to_i
96
+ end
97
+ end
98
+ prices[0] = s*(d**steps) # fill in the endnodes.
99
+ (1..(steps+1)).each do |i|
100
+ prices[i] = uu*prices[i-1]
101
+ end
102
+ (0..(steps+1)).each do |i|
103
+ put_values[i] = [0.0, (k-prices[i])].max # put payoffs at maturity
104
+ end
105
+ (steps-1).downto(0) do |step|
106
+ check_exercise_this_step = false
107
+ (0..(potential_exercise_steps.count)).each do |j|
108
+ if (step == potential_exercise_steps[j])
109
+ check_exercise_this_step = true
110
+ end
111
+ end
112
+ (0..(steps+1)).each do |i|
113
+ put_values[i] = (p_up*put_values[i+1].to_f+p_down*put_values[i].to_f)*r_inv
114
+ prices[i] = d*prices[i+1].to_f
115
+ if (check_exercise_this_step)
116
+ put_values[i] = [put_values[i].to_f,k-prices[i].to_f].max
117
+ end
118
+ end
119
+ end
120
+ return put_values[0]
121
+ end
122
+
123
+ end
124
+ end