2 # This file is part of SMR.
4 # SMR is free software: you can redistribute it and/or modify it under the
5 # terms of the GNU General Public License as published by the Free Software
6 # Foundation, either version 3 of the License, or (at your option) any later
9 # SMR is distributed in the hope that it will be useful, but WITHOUT ANY
10 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License along with
14 # SMR. If not, see <http://www.gnu.org/licenses/>.
16 require 'asset_position'
20 # Total assets of current user at some point in time.
22 # Use #open_positions to access Smr::AssetPosition objects of all positions
23 # held. Then each knows more details about itself.
25 # collection of Smr::AssetPosition objects of currently open positions
26 attr_reader :open_positions
28 # currently invested amount of money
31 # current market value of all assets
32 attr_reader :market_value
34 # current profit/loss on all assets
35 attr_reader :profit_loss
37 # current collateral_coverage_value of all assets
38 attr_reader :collateral_coverage_value
41 # age of +Quote+ data before its considered old
42 QUOTE_OUTDATED_DAYS = 4
45 # date defines the point of Time this object sits at
46 def initialize(id_user, date, options={:id_portfolio=>false, :skip_cash_positions=>false})
47 raise 'date must be of Time' unless date.is_a?(Time)
53 limit_portfolio = if options[:id_portfolio] then 'AND po.id=%i' % options[:id_portfolio] else '' end
54 skip_cash_positions = if options[:skip_cash_positions] then 'AND s.id != %i' % Smr::ID_CASH_SECURITY else '' end
59 @collateral_coverage_value = 0.0
61 @_have_old_quotes = false
62 @_have_missing_quotes = false
64 @open_positions = Array.new
66 # ATTENTION: not portable!
67 # - thats not the preferred way to do a query.
68 # - this one is just too complex for ActiveRecord at the moment
69 open_positions = Smr::AssetPositions.new(@date, '
73 p.id_portfolio, # if those values could be used
74 pr.id_order, # things would be much faster since
75 pr.id_position, # subsequent SmrPosition objects query
76 pr.date, # these again... too many queries...
85 MAX(pr1.date) AS LASTDATE,
86 pr1.id_position AS LASTPOSITION
91 GROUP BY pr1.id_position
97 AND p.id_portfolio=po.id
98 AND s.id=p.id_security
100 AND (p.closed=0 OR p.closed>%i)
102 AND pr.id_position=LASTPOSITION
103 AND po.name NOT LIKE "watchlist:%%" /* HACK for speed on old DBs */
105 ORDER BY pr.date' % [@date, limit_portfolio, skip_cash_positions, @id_user, @date]).get_all
107 # turn Position objects into SmrPosition
108 # - for the sake of performance we calculate totals right here
109 open_positions.each do |p|
110 sp = Smr::AssetPosition.new(p.id, id_user, @date)
111 @open_positions << sp
113 @invested += sp.invested
114 @market_value += sp.market_value if sp.market_value
115 @profit_loss += sp.profit_loss if sp.profit_loss
116 @collateral_coverage_value += sp.collateral_coverage_value
118 if not sp.market_value then @_have_missing_quotes = true end
119 if sp.quote_time and sp.quote_time < QUOTE_OUTDATED_DAYS.days.ago then
120 @_have_old_quotes = true
127 # tell whether this Asset report includes outdated quotes
132 # tell whether this Asset report is lacking quote data
133 def have_missing_quotes?
134 @_have_missing_quotes