istox 0.1.79 → 0.1.80
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +6 -8
- data/lib/istox.rb +1 -0
- data/lib/istox/helpers/f_math.rb +7 -0
- data/lib/istox/quant/bond.rb +93 -0
- data/lib/istox/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f353767534ea557387933b8cc9451413f78737cef852474123b288530a04707c
|
4
|
+
data.tar.gz: be7b7ac8a4d46659bdbcfc9b2437fa4b4d9d981fbb06d72c154ec67479094b53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f120c7f2ad80487a744c1da0c0e2d80a6fdf3f57ef3d67560f777d256e9301857073a73352ffa1d392fa2aa28beb7db7277f78965b15fa66123517e6ea00828f
|
7
|
+
data.tar.gz: 5882f068e496f72ce5ae8c35276e5c1510ebcd5f41aaa04e138c2bc1074ad1542138717fadedc6403dce05a4adfde07cd3b068fee73c9641456705f6e77ea6a7
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
istox (0.1.
|
4
|
+
istox (0.1.79)
|
5
5
|
binding_of_caller
|
6
6
|
bunny (>= 2.12.0)
|
7
7
|
graphlient
|
@@ -68,7 +68,6 @@ GEM
|
|
68
68
|
uniform_notifier (~> 1.11.0)
|
69
69
|
bunny (2.14.2)
|
70
70
|
amq-protocol (~> 2.3, >= 2.3.0)
|
71
|
-
byebug (8.2.5)
|
72
71
|
concurrent-ruby (1.1.4)
|
73
72
|
crass (1.0.4)
|
74
73
|
database_cleaner (1.6.2)
|
@@ -89,21 +88,21 @@ GEM
|
|
89
88
|
ffi (1.11.1)
|
90
89
|
globalid (0.4.2)
|
91
90
|
activesupport (>= 4.2.0)
|
92
|
-
google-protobuf (3.9.1)
|
91
|
+
google-protobuf (3.9.1-universal-darwin)
|
93
92
|
googleapis-common-protos-types (1.0.4)
|
94
93
|
google-protobuf (~> 3.0)
|
95
94
|
graphlient (0.3.6)
|
96
95
|
faraday
|
97
96
|
faraday_middleware
|
98
97
|
graphql-client
|
99
|
-
graphql (1.9.
|
98
|
+
graphql (1.9.11)
|
100
99
|
graphql-client (0.15.0)
|
101
100
|
activesupport (>= 3.0)
|
102
101
|
graphql (~> 1.8)
|
103
|
-
grpc (1.
|
102
|
+
grpc (1.23.0-universal-darwin)
|
104
103
|
google-protobuf (~> 3.8)
|
105
104
|
googleapis-common-protos-types (~> 1.0)
|
106
|
-
grpc-tools (1.
|
105
|
+
grpc-tools (1.23.0)
|
107
106
|
gruf (2.7.0)
|
108
107
|
activesupport (> 4)
|
109
108
|
concurrent-ruby (> 1)
|
@@ -217,7 +216,6 @@ PLATFORMS
|
|
217
216
|
DEPENDENCIES
|
218
217
|
bullet (~> 5.7.5)
|
219
218
|
bundler (~> 1.16)
|
220
|
-
byebug
|
221
219
|
database_cleaner (~> 1.6.0)
|
222
220
|
factory_bot_rails (~> 4.8.2)
|
223
221
|
faker (~> 1.7.3)
|
@@ -229,4 +227,4 @@ DEPENDENCIES
|
|
229
227
|
sqlite3 (~> 1.3.6)
|
230
228
|
|
231
229
|
BUNDLED WITH
|
232
|
-
1.17.
|
230
|
+
1.17.3
|
data/lib/istox.rb
CHANGED
data/lib/istox/helpers/f_math.rb
CHANGED
@@ -47,7 +47,14 @@ module Istox
|
|
47
47
|
x = to_fixed(x)
|
48
48
|
y = to_fixed(y)
|
49
49
|
|
50
|
+
return ::BigDecimal.new("1").to_s if x == y
|
51
|
+
|
50
52
|
fixed_1 = ::BigDecimal.new("1e18")
|
53
|
+
|
54
|
+
if (((x.div(y, 100)).modulo(BigDecimal.new(10)) == 0) && (x.modulo(y) == 0))
|
55
|
+
return from_fixed((x.div(y, 100).mult(fixed_1, 100)))
|
56
|
+
end
|
57
|
+
|
51
58
|
r_y = fixed_1.mult(fixed_1, 100).truncate(0).div(y, 100).truncate(0)
|
52
59
|
|
53
60
|
result = from_fixed(x.mult(r_y, 100).truncate(0).div(fixed_1, 100).truncate(0))
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
# This class is modified for ISTOX use case based on open source Bondie
|
5
|
+
|
6
|
+
# YTM based on price and date:
|
7
|
+
|
8
|
+
# bond = Istox::Quant::Bond.new(coupon: 0.0622, maturity_date: Date.parse('2016-08-22'), coupon_frequency: 4)
|
9
|
+
# bond.ytm(Date.parse('2015-09-07'), price: 100.8)
|
10
|
+
# It will not count exact yield, but it will approximate it - you can set maximum approximation error by adding approximation_error parameter to the method.
|
11
|
+
|
12
|
+
# You can also check interest payments dates:
|
13
|
+
|
14
|
+
# bond = Istox::Quant::Bond.new(coupon: 0.0622, maturity_date: Date.parse('2016-08-22'), coupon_frequency: 4)
|
15
|
+
# bond.interest_payments(Date.parse('2015-09-07'))
|
16
|
+
# Currently it will not skip weekends or other days without bond quotations, so it can be inaccurate.
|
17
|
+
|
18
|
+
# Also it's possible to check price on which it will generate given yield:
|
19
|
+
|
20
|
+
# bond = Istox::Quant::Bond.new(coupon: 0.0622, maturity_date: Date.parse('2016-08-22'), coupon_frequency: 4)
|
21
|
+
# bond.price(0.05156, Date.parse('2015-09-07'))
|
22
|
+
|
23
|
+
|
24
|
+
module Istox
|
25
|
+
module Quant
|
26
|
+
class Bond
|
27
|
+
|
28
|
+
DEFAULT_APPROXIMATION_ERROR = 0.0001
|
29
|
+
|
30
|
+
def initialize(coupon: nil, maturity_date: nil, coupon_frequency: nil, face_value: 100, days_of_year: 365)
|
31
|
+
@coupon = coupon
|
32
|
+
@maturity_date = maturity_date
|
33
|
+
@coupon_frequency = coupon_frequency
|
34
|
+
@days_of_year = days_of_year
|
35
|
+
@face_value = face_value
|
36
|
+
end
|
37
|
+
|
38
|
+
def price(ytm, date, fees: 0)
|
39
|
+
price_for_irr(irr_from_ytm(ytm), date, fees: fees)
|
40
|
+
end
|
41
|
+
|
42
|
+
def interest_payments(from_date)
|
43
|
+
payments = []
|
44
|
+
date = @maturity_date
|
45
|
+
while date >= from_date
|
46
|
+
payments << date
|
47
|
+
date = date.prev_month(12/@coupon_frequency)
|
48
|
+
end
|
49
|
+
payments.sort
|
50
|
+
end
|
51
|
+
|
52
|
+
def ytm(date, price: 100, fees: 0, approximation_error: DEFAULT_APPROXIMATION_ERROR)
|
53
|
+
ytm_down, ytm_up = ytm_limits(price, date, fees: fees)
|
54
|
+
approximate_ytm(ytm_down, ytm_up, price, date, fees: fees, approximation_error: approximation_error)
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def irr_from_ytm(ytm)
|
61
|
+
(ytm/@coupon_frequency.to_f + 1) ** @coupon_frequency - 1
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def approximate_ytm(ytm_down, ytm_up, price, date, fees: 0, approximation_error: DEFAULT_APPROXIMATION_ERROR)
|
66
|
+
approx_ytm = (ytm_up + ytm_down) / 2.0
|
67
|
+
return approx_ytm if ((ytm_up - approx_ytm)/approx_ytm).abs <= approximation_error
|
68
|
+
p = price(approx_ytm, date, fees: fees)
|
69
|
+
ytm_down, ytm_up = p < price ? [ytm_down, approx_ytm] : [approx_ytm, ytm_up]
|
70
|
+
approximate_ytm(ytm_down, ytm_up, price, date, fees: fees, approximation_error: approximation_error)
|
71
|
+
end
|
72
|
+
|
73
|
+
def ytm_limits(price, date, fees: 0)
|
74
|
+
ytm_up = 0.1
|
75
|
+
ytm_up *= 10 while price(ytm_up, date, fees: fees) > price
|
76
|
+
# IRR will be never lower than -1, so YTM should be never lower than -coupon_frequency (see irr_from_ytm)
|
77
|
+
ytm_down = price(0, date, fees: fees) > price ? 0.0 : -@coupon_frequency.to_f
|
78
|
+
[ytm_down, ytm_up]
|
79
|
+
end
|
80
|
+
|
81
|
+
def price_for_irr(irr, date, fees: 0)
|
82
|
+
raise "Date is after maturity_date!" if date > @maturity_date
|
83
|
+
last = date
|
84
|
+
interest_payments(date).map do |payday|
|
85
|
+
interest = @coupon * @face_value * ((payday-last)/@days_of_year)
|
86
|
+
interest += @face_value if payday == @maturity_date
|
87
|
+
last = payday
|
88
|
+
interest / ((1+irr) ** ((payday-date)/@days_of_year))
|
89
|
+
end.inject(:+) / (1+fees)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/istox/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: istox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.80
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Siong Leng
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -305,6 +305,7 @@ files:
|
|
305
305
|
- lib/istox/migrations/create_blockchain_receipts.rb
|
306
306
|
- lib/istox/models/blockchain_receipt.rb
|
307
307
|
- lib/istox/models/concerns/blockchain_receipt_query.rb
|
308
|
+
- lib/istox/quant/bond.rb
|
308
309
|
- lib/istox/version.rb
|
309
310
|
homepage: http://www.abc.com
|
310
311
|
licenses: []
|
@@ -324,8 +325,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
324
325
|
- !ruby/object:Gem::Version
|
325
326
|
version: '0'
|
326
327
|
requirements: []
|
327
|
-
|
328
|
-
rubygems_version: 2.7.8
|
328
|
+
rubygems_version: 3.0.6
|
329
329
|
signing_key:
|
330
330
|
specification_version: 4
|
331
331
|
summary: istox backend shared gem
|