roi_calculator 0.2.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 16bd4ca3ba06d4e40dae6588b1cf9af5aaef6b8d
4
- data.tar.gz: 44bf9cd2cad6675cd2e8c018bde42d89ea321668
2
+ SHA256:
3
+ metadata.gz: 2292a5e2fdd3376f2b491c52ffda763d7477650a6357609010fa974394438aef
4
+ data.tar.gz: 23586cca38d104c7c148b2af1e6560e79a329cd0d7f8d5c4d4963d626c4099c1
5
5
  SHA512:
6
- metadata.gz: b6b3a1624bf312a509c342496cdf5b1c39aa7abf3f2271d1b16c720c8260174dc02c39e5b78cadc3e1d442e4b7606f731515f4b4c9758e74f0988da942d138a1
7
- data.tar.gz: a823c2daa89b7d1ca93070ec6a3d5b7ace8949027d2873b68ad4ec6206a7c5adb4edf54f715d7f857fdf851747ee82c0634cc4bf7279e1ca1f73f2eb371338fb
6
+ metadata.gz: d172202068e4dd338e81912e5f861377a2db2ac06225c9a838945e118ef3b24c690ab8c4863d6e7279553e5633767dce7bc0f3b5b4d4c244d507f4dd2cb7601c
7
+ data.tar.gz: c7fc4b68c3a4d30c5593f0009e3405d7386c98183afe1732acb0426a9c9eb3370a9b98444ebec20b234d28e3ea58f10fce7deeb361955ca5f7c6d88c4a1dee56
@@ -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.strftime("%Y-%m-%d"), @rentabilities[date].share - 1]
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.2.0"
4
+ VERSION = '2.2.1'
3
5
  end
@@ -1,25 +1,29 @@
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
+ # rubocop:disable Gemspec/RequiredRubyVersion
21
+ spec.required_ruby_version = '>= 2.2.5'
22
+ # rubocop:enable Gemspec/RequiredRubyVersion
19
23
 
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"
24
+ spec.add_development_dependency 'bundler', '~> 1.13'
25
+ spec.add_development_dependency 'rspec', '~> 3.0'
26
+ spec.add_runtime_dependency 'math_util', '~> 0.1.0'
27
+ spec.add_runtime_dependency 'memoist', '~> 0.15'
28
+ spec.add_runtime_dependency 'work_day', '~> 1.0.0'
25
29
  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.2.0
4
+ version: 2.2.1
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-30 00:00:00.000000000 Z
11
+ date: 2020-12-21 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.2.5
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