roi_calculator 0.1.6 → 2.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: aa2c97345de8a5850cb277f0a4bad5ca2d3512f8
4
- data.tar.gz: 46f5fea5dddadb7edcad096a2d65d42464d39dbc
2
+ SHA256:
3
+ metadata.gz: 04b1f92abea56c262e66f32551040c1ec5e6bed8e42ae60cf1867d98b36fa7e0
4
+ data.tar.gz: 1d6d9209fe7152a599be99b6effa158696692d0faefd0e089a2b8352d478eed5
5
5
  SHA512:
6
- metadata.gz: 61fde865b0bf5a8a7f2945a1abec2ee8ca878afa37672dc54486855aaeeb81271a49938d5a9147e4dd21550763057a223830d567e9f314ec5569604682a74a0f
7
- data.tar.gz: adbe27a0753c207317ba7f80264cc5b75a0b528bce1474e9f582e4978c016d9ac1eb40da8a87c477c69b694876c56633bbdd472a79c7400927d09e650fd86fb3
6
+ metadata.gz: e3ea5605bdbcdee6a856dc0c900db73c26d403ee2f75074fec8599abb481625021aa14c7bc1301a83f50956427677ce5547744bb6a2dc576615bf8058df1e814
7
+ data.tar.gz: 117182e61665f1550ca3676933f2ba97358eae87425ceb0cf0f2affbb9b21789ec95e5277f2234614c4eb21032f3af2a74953ae547ef8193c2a77f37cb71e7df
@@ -1 +1 @@
1
- ruby-2.2.5
1
+ ruby-2.5.0
@@ -0,0 +1,21 @@
1
+ image: ruby:2.5.0
2
+
3
+ pipelines:
4
+ default:
5
+ - step:
6
+ script:
7
+ - git archive --remote=git@bitbucket.org:guideinvestimentos/rails_defaults.git HEAD .rubocop.yml | tar -x
8
+ - bundle install
9
+ - gem install rubocop
10
+ - rspec -fdoc
11
+ - rubocop .
12
+
13
+ branches:
14
+ master:
15
+ - step:
16
+ script:
17
+ - gem build roi_calculator.gemspec
18
+ - mkdir -p ~/.gem
19
+ - curl -u $RUBYGEMS_USERNAME:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
20
+ - chmod 0600 ~/.gem/credentials
21
+ - gem push $(ls *.gem)
data/lib/roi.rb CHANGED
@@ -1,7 +1,9 @@
1
- require "roi/rentability"
2
- require "roi/rentability_line"
3
- require "roi/rentability_periods"
4
- require "roi/financial_result"
1
+ # frozen_string_literal: true
2
+
3
+ require 'roi/rentability'
4
+ require 'roi/rentability_line'
5
+ require 'roi/rentability_periods'
6
+ require 'roi/gross_profit'
5
7
 
6
8
  module ROI
7
9
  end
@@ -1,9 +1,11 @@
1
- require "work_day"
2
- require "active_support"
3
- require "active_support/core_ext/date"
1
+ # frozen_string_literal: true
2
+
3
+ require 'work_day'
4
+ require 'active_support'
5
+ require 'active_support/core_ext/date'
4
6
 
5
7
  module ROI
6
- class FinancialResult
8
+ class GrossProfit
7
9
  attr_reader :start_date, :end_date, :rentabilities
8
10
 
9
11
  def initialize(rentabilities, start_date, end_date)
@@ -14,7 +16,7 @@ module ROI
14
16
 
15
17
  def current_month
16
18
  scope_start = WorkDay.next_after(end_date.beginning_of_month, 0)
17
- format_financial(scope_start, end_date)
19
+ format_gross_profit(scope_start, end_date)
18
20
  end
19
21
 
20
22
  def months(amount)
@@ -24,41 +26,43 @@ module ROI
24
26
 
25
27
  def current_year
26
28
  scope_start = WorkDay.next_after(end_date.beginning_of_year, 0)
27
- format_financial(scope_start, end_date)
29
+ format_gross_profit(scope_start, end_date)
28
30
  end
29
31
 
30
32
  def years_ago(amount)
31
33
  scope_end = (end_date - amount.year).end_of_year
32
34
  scope_start = scope_end.beginning_of_year
33
- format_financial(scope_start, scope_end)
35
+ format_gross_profit(scope_start, scope_end)
34
36
  end
35
37
 
36
38
  def portfolio
37
- format_financial(start_date, end_date)
39
+ format_gross_profit(start_date, end_date)
38
40
  end
39
41
 
40
42
  private
43
+
41
44
  def scoped_rentabilities(scope_start, scope_end)
42
45
  rentabilities.values.select.each do |line|
43
- line.date.between?(scope_start, scope_end)
46
+ line.reference_date.between?(scope_start, scope_end)
44
47
  end
45
48
  end
46
49
 
47
- def format_financial(scope_start, scope_end)
50
+ def format_gross_profit(scope_start, scope_end)
48
51
  return unless scope_start && scope_end
52
+
49
53
  total = scoped_rentabilities(scope_start, scope_end).sum do |line|
50
- line.try(:daily_result) || 0
54
+ line.try(:gross_profit) || 0
51
55
  end.round(2)
52
- total != 0 ? total : nil
56
+ total.zero? ? nil : total
53
57
  end
54
58
 
55
59
  def check_gaps_and_format(scope_start, scope_end)
56
- if scope_start >= start_date
57
- scoped_rentabilities(scope_start, scope_end).each do |line|
58
- return if line.try(:have_position) == false
59
- end
60
- format_financial(scope_start, scope_end)
60
+ return unless scope_start >= start_date
61
+
62
+ scoped_rentabilities(scope_start, scope_end).each do |line|
63
+ return nil if line.try(:have_position) == false
61
64
  end
65
+ format_gross_profit(scope_start, scope_end)
62
66
  end
63
67
  end
64
68
  end
@@ -1,9 +1,11 @@
1
- require "memoist"
2
- require "roi/financial_result"
3
- require "roi/rentability_periods"
4
- require "math_util"
5
- require "active_support"
6
- require "active_support/core_ext"
1
+ # frozen_string_literal: true
2
+
3
+ require 'memoist'
4
+ require 'roi/gross_profit'
5
+ require 'roi/rentability_periods'
6
+ require 'math_util'
7
+ require 'active_support'
8
+ require 'active_support/core_ext'
7
9
 
8
10
  module ROI
9
11
  class Rentability
@@ -20,20 +22,20 @@ module ROI
20
22
  post_initialize(options)
21
23
  end
22
24
 
23
- def post_initialize(options)
24
- end
25
+ def post_initialize(options); end
25
26
 
26
27
  def calculate
27
28
  parse_rentabilities
28
- if @rentabilities.count > 0
29
+ if @rentabilities.count.positive?
29
30
  dates = @rentabilities.keys
30
- @start_date, @end_date = [dates[0], dates[-1]]
31
+ @start_date = dates[0]
32
+ @end_date = dates[-1]
31
33
  end
32
34
  self
33
35
  end
34
36
 
35
- def financial
36
- FinancialResult.new(rentabilities, start_date, end_date)
37
+ def gross_profit
38
+ GrossProfit.new(rentabilities, start_date, end_date)
37
39
  end
38
40
 
39
41
  def dates_with_position
@@ -45,15 +47,14 @@ module ROI
45
47
  end_date ||= @end_date
46
48
 
47
49
  filtered = @rentabilities.values.select do |val|
48
- val.date.between?(start_date, end_date)
50
+ val.reference_date.between?(start_date, end_date)
49
51
  end
50
52
  filtered.map(&:rentability).compact
51
53
  end
52
54
 
53
55
  def volatility(months_ago = nil)
54
- _start = months_ago ?
55
- (end_date - months_ago.months + 1.month).beginning_of_month : nil
56
- (volatility_in_window(nil, _start).first || [])[1]
56
+ start = (end_date - months_ago.months + 1.month).beginning_of_month if months_ago
57
+ (volatility_in_window(nil, start).first || [])[1]
57
58
  end
58
59
 
59
60
  def volatility_in_window(days = nil, start_date = nil)
@@ -62,23 +63,21 @@ module ROI
62
63
 
63
64
  0.upto(filtered.size - days).map do |low|
64
65
  series = filtered.slice(low, days + 1)
65
- vol = MathUtil.volatility(series)
66
- date = dates_with_position.fetch(low + days) { dates_with_position.last }
67
- [date, vol] if date
66
+ date =
67
+ dates_with_position.fetch(low + days) { dates_with_position.last }
68
+ [date, MathUtil.volatility(series)] if date
68
69
  end
69
70
  end
70
71
 
71
72
  def to_a
72
73
  dates_with_position.map do |date|
73
- if @rentabilities[date]
74
- [date.to_time.to_i, @rentabilities[date].share]
75
- end
74
+ [date.strftime('%Y-%m-%d'), @rentabilities[date].quota - 1] if @rentabilities[date]
76
75
  end.compact
77
76
  end
78
77
 
79
78
  protected
80
- def before_parse_rentabilities
81
- end
79
+
80
+ def before_parse_rentabilities; end
82
81
 
83
82
  def work_days
84
83
  start_date && end_date ? WorkDay.between(start_date, end_date) : []
@@ -86,6 +85,7 @@ module ROI
86
85
  memoize :work_days
87
86
 
88
87
  private
88
+
89
89
  def parse_rentabilities
90
90
  @rentabilities = {}
91
91
  before_parse_rentabilities
@@ -99,10 +99,10 @@ module ROI
99
99
  last_value = rentabilities_source(last_date)
100
100
  return rentabilities unless this_value && last_value
101
101
 
102
- last_share = rentabilities[last_date].try(:share) || 1
102
+ last_quota = rentabilities[last_date].try(:quota) || 1
103
103
  rentability = (this_value / last_value - 1).round(8)
104
- new_share = (last_share * (1 + rentability)).round(8)
105
- line = RentabilityLine.new(this_date, rentability, nil, new_share, true)
104
+ new_quota = (last_quota * (1 + rentability)).round(8)
105
+ line = RentabilityLine.new(this_date, rentability, new_quota, true)
106
106
  after_parse(this_date, last_date, rentabilities, line)
107
107
  end
108
108
  end
@@ -1,21 +1,15 @@
1
- module ROI
2
- class RentabilityLine < Struct.new(
3
- :date, :rentability, :daily_result, :share, :have_position, :total_balance)
1
+ # frozen_string_literal: true
4
2
 
5
- def self.build(date: nil, share: 1, have_position: false)
6
- self.new(date, nil, nil, share, have_position, nil)
7
- end
3
+ module ROI
4
+ class RentabilityLine
5
+ attr_reader :reference_date, :rentability,
6
+ :gross_profit, :quota, :have_position
8
7
 
9
- def self.create(date, assets, last_balance, last_share)
10
- line = build(date: date, share: last_share || 1)
11
- line.total_balance = assets.map(&:value).inject(:+)
12
- if last_balance.to_f > 0
13
- line.daily_result = assets.map(&:daily_result).inject(:+)
14
- line.rentability = line.daily_result / last_balance
15
- line.share = (last_share * (1 + line.rentability)).round(8)
16
- line.have_position = true
17
- end
18
- line
8
+ def initialize(reference_date, rentability, quota, have_position)
9
+ @reference_date = reference_date
10
+ @rentability = rentability
11
+ @quota = quota
12
+ @have_position = have_position
19
13
  end
20
14
  end
21
15
  end
@@ -1,4 +1,6 @@
1
- require "work_day"
1
+ # frozen_string_literal: true
2
+
3
+ require 'work_day'
2
4
 
3
5
  module ROI
4
6
  module RentabilityPeriods
@@ -13,8 +15,9 @@ module ROI
13
15
  end
14
16
 
15
17
  def months(amount, date = end_date)
16
- scoped_start = WorkDay.last_until((date - amount.month).end_of_month)
17
- scoped_end = adjust_end_date(date)
18
+ scoped_start =
19
+ WorkDay.last_until((date - (amount + 1).month).end_of_month)
20
+ scoped_end = adjust_end_date((date - 1.month).end_of_month)
18
21
  check_gaps_and_format(scoped_start, scoped_end)
19
22
  end
20
23
 
@@ -34,32 +37,41 @@ module ROI
34
37
  end
35
38
 
36
39
  private
40
+
37
41
  def adjust_start_date(date)
38
42
  [start_date, date].compact.max
39
43
  end
40
44
 
41
45
  def adjust_end_date(date)
42
- WorkDay.last_until(date.strftime("%Y-%m") == end_date.strftime("%Y-%m") ?
43
- end_date : date.end_of_month)
46
+ scoped_end =
47
+ if date.strftime('%Y-%m') == end_date.strftime('%Y-%m')
48
+ end_date
49
+ else
50
+ date.end_of_month
51
+ end
52
+ WorkDay.last_until(scoped_end)
44
53
  end
45
54
 
46
55
  def format(start_date, end_date)
47
56
  scoped_start, scoped_end = rentabilities.values_at(start_date, end_date)
48
- if scoped_start && scoped_end
49
- ((scoped_end.share / scoped_start.share - 1) * 100).round(8)
50
- end
57
+ ((scoped_end.quota / scoped_start.quota - 1) * 100).round(8) if scoped_start && scoped_end
51
58
  end
52
59
 
53
60
  def check_gaps_and_format(scoped_start, scoped_end)
54
- _start, _end = rentabilities.values_at(scoped_start, scoped_end)
55
- return unless _start && _end
56
- if skip_on_gap
57
- rentabilities.each_value do |line|
58
- return if line.date.between?(_start.date, _end.date) &&
59
- !line.have_position
60
- end
61
- end
61
+ local_start, local_end = rentabilities.values_at(scoped_start, scoped_end)
62
+ return unless local_start && local_end
63
+ return if skip_on_gap && gap?(local_start, local_end)
64
+
62
65
  format(scoped_start, scoped_end)
63
66
  end
67
+
68
+ def gap?(start_date, end_date)
69
+ gap = rentabilities.values.detect do |line|
70
+ line.reference_date.between?(
71
+ start_date.reference_date, end_date.reference_date
72
+ ) && !line.have_position
73
+ end
74
+ !gap.nil?
75
+ end
64
76
  end
65
77
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROI
2
- VERSION = "0.1.6"
4
+ VERSION = '2.2.0'
3
5
  end
@@ -1,25 +1,27 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'roi/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = "roi_calculator"
8
- spec.version = ROI::VERSION
9
- spec.authors = ["Adriano Bacha"]
10
- spec.email = ["abacha@gmail.com"]
8
+ spec.name = 'roi_calculator'
9
+ spec.version = ROI::VERSION
10
+ spec.authors = ['Adriano Bacha']
11
+ spec.email = ['abacha@gmail.com']
11
12
 
12
- spec.summary = %q{Rentability and financial calculations}
13
- spec.license = "MIT"
13
+ spec.summary = 'Rentability and Gross Profit Calculations'
14
+ spec.license = 'MIT'
14
15
 
15
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
17
  f.match(%r{^(test|spec|features)/})
17
18
  end
18
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
+ spec.required_ruby_version = '>= 2.5.0'
19
21
 
20
- spec.add_development_dependency "bundler", "~> 1.13"
21
- spec.add_development_dependency "rspec", "~> 3.0"
22
- spec.add_runtime_dependency "memoist", "~> 0.15"
23
- spec.add_runtime_dependency "math_util", "~> 0.1.0"
24
- spec.add_runtime_dependency "work_day", "~> 0.3.0"
22
+ spec.add_development_dependency 'bundler', '~> 1.13'
23
+ spec.add_development_dependency 'rspec', '~> 3.0'
24
+ spec.add_runtime_dependency 'math_util', '~> 0.1.0'
25
+ spec.add_runtime_dependency 'memoist', '~> 0.15'
26
+ spec.add_runtime_dependency 'work_day', '~> 1.0.0'
25
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roi_calculator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adriano Bacha
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-29 00:00:00.000000000 Z
11
+ date: 2020-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -39,47 +39,47 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: memoist
42
+ name: math_util
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.15'
47
+ version: 0.1.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.15'
54
+ version: 0.1.0
55
55
  - !ruby/object:Gem::Dependency
56
- name: math_util
56
+ name: memoist
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.1.0
61
+ version: '0.15'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.1.0
68
+ version: '0.15'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: work_day
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.3.0
75
+ version: 1.0.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.3.0
82
+ version: 1.0.0
83
83
  description:
84
84
  email:
85
85
  - abacha@gmail.com
@@ -89,16 +89,15 @@ extra_rdoc_files: []
89
89
  files:
90
90
  - ".gitignore"
91
91
  - ".rspec"
92
- - ".ruby-gemset"
93
92
  - ".ruby-version"
94
93
  - ".travis.yml"
95
94
  - Gemfile
96
95
  - Gemfile.lock
97
96
  - LICENSE.txt
98
97
  - README.md
99
- - circle.yml
98
+ - bitbucket-pipelines.yml
100
99
  - lib/roi.rb
101
- - lib/roi/financial_result.rb
100
+ - lib/roi/gross_profit.rb
102
101
  - lib/roi/rentability.rb
103
102
  - lib/roi/rentability_line.rb
104
103
  - lib/roi/rentability_periods.rb
@@ -116,7 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
115
  requirements:
117
116
  - - ">="
118
117
  - !ruby/object:Gem::Version
119
- version: '0'
118
+ version: 2.5.0
120
119
  required_rubygems_version: !ruby/object:Gem::Requirement
121
120
  requirements:
122
121
  - - ">="
@@ -124,8 +123,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
123
  version: '0'
125
124
  requirements: []
126
125
  rubyforge_project:
127
- rubygems_version: 2.4.8
126
+ rubygems_version: 2.7.6
128
127
  signing_key:
129
128
  specification_version: 4
130
- summary: Rentability and financial calculations
129
+ summary: Rentability and Gross Profit Calculations
131
130
  test_files: []
@@ -1 +0,0 @@
1
- bigbang_services
data/circle.yml DELETED
@@ -1,3 +0,0 @@
1
- dependencies:
2
- pre:
3
- - gem install bundler