Class: HC::Portfolio

Inherits:
Object
  • Object
show all
Defined in:
lib/models/hc/portfolio.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.bakeObject

describes the snapshot of positions and account-values is stored on a daily base

bake generates portfolio-entries for each detected IB::Account,

stores converted account-values in the portfolio-record,
assigns Portfolio-positions to the time-grid and
connects the record to the referenced IB::Account.

returns an array with rid’s of successfully allocated portfolio-datasets



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/models/hc/portfolio.rb', line 14

def self.bake  

	gateway= IB::OrientGateway.current
    gateway.
	gateway.clients.map do | the_client |

		p = self.new
		p. from: the_client						 # implies update of p, assigns a rid
		p.import_positions    from: the_client             # assigns portfolio-values to the grid
		HC::MY_USER.create    from: p, to: the_client      # bidirectional link to account
		Date.today.to_tg.assign vertex: p, via: HC::D2F    # bidirectional link to the time-grid
		p.rid                                              # return_value
	end
end

.positionsObject



139
140
141
# File 'lib/models/hc/portfolio.rb', line 139

def self.positions
		query.nodes :out, via: HC::HAS_POSITION, expand: false  # returns a query-object
end

Instance Method Details

#accountObject



151
152
153
# File 'lib/models/hc/portfolio.rb', line 151

def 
	out( /user/ ).in.first
end

#account_data_scan(search_key, search_currency = nil) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/models/hc/portfolio.rb', line 61

def  search_key, search_currency=nil
	return if values.nil? or values.empty?
   values.keys.match(/Ac/).compact.string
	if .is_a? Array
		if search_currency.present? 
			.find_all{|x| x.key.match( search_key )  && x.currency == search_currency.upcase }
		else
			.find_all{|x| x.key.match( search_key ) }
		end
	end
end

#account_data_scan_projection(search_key) ⇒ Object

returns the projection for usage in OrientQuery It filters specific account-values

To execute a query, inject the from-parameter via a block



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/models/hc/portfolio.rb', line 34

def  search_key
	# values.keys.match(/Ac/).compact.string => ["AccruedCash", "AccruedDividend"]
	fields = values.keys.match(search_key).compact.string 
    p = fields.map{|y| "values[\"#{y}\"] as #{y} "}.join(", ")
    if block_given?
		 q =  OrientSupport::OrientQuery  
		 o.from( yield )
		  .projection( p )
			.execute     # return result
       else
			 p  #  return projection string
	end


end

#import_account_data(from:) ⇒ Object

Utility function to transform IB:AccountValues into a hash

which is stored in the property »value«

from is either a IB::Account or an array of IB::AccountValues



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/models/hc/portfolio.rb', line 78

def   from:
	from = from. if from.is_a? IB::Account
	 =  Hash.new
	currencies = from.find_all{|x| x.key == :Currency }.map &:value  # => ["BASE", "EUR", "SEK", "USD"]
	from.map{|y| y.key.to_s.split('-').first.to_sym}.uniq.each{|x| [ x ] = {} }
	subaccounts = [:C, :F, :S]
	
	from.each do |a|
		next if a.currency.empty? || a.value.to_i.zero? || a.value == "1.7976931348623157E308"
		id, subaccount =  a.key.to_s.split('-')
#				a.value =  a.value[-3] =='.' ?  a.value.to_f : a.value.to_i  if a.value.is_a?(String)
		a.value =  a.value.to_f
		subaccount = 'ALL' if subaccount.nil? 
		if [id.to_sym][subaccount.to_sym].present? 
			[id.to_sym][subaccount.to_sym].merge!  a.currency => a.value  
		else
			[id.to_sym][subaccount.to_sym] = { a.currency => a.value } 
		end
	end
	.delete_if{|_,l| l.empty?}  # return only elements with valid data, ie.non empty values

	update  values: 
end

#import_positions(from:) ⇒ Object

Utility function to add IB::PortfolioValues to the TimeGrid

from is either a IB::Account or an array of IB::PortfolioValues



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/models/hc/portfolio.rb', line 107

def import_positions from: 
	from = from.portfolio_values if from.is_a? IB::Account

	# delete possibly previous entries
	out_hc_has_position &.in &.map &:delete
#			out_hc_has_position &.map &:delete			#  edge is automatically removed by delete(vertex)

	from.each do | portfolio_position |

		portfolio_position.save
		# build link to portfolio-position
		assign via: HC::HAS_POSITION, vertex: portfolio_position
		# connect with previous entry
		previous = prev_portfolio_position(portfolio_position.contract)
#				puts "previous: #{previous}"
		previous &.assign via: HC::GRID, vertex: pp
	end
end

#position(*contract) ⇒ Object

get selected portfolio-value positions



144
145
146
147
148
149
# File 'lib/models/hc/portfolio.rb', line 144

def position *contract 
    
	# generated query: INFO->select  outE('hc_has_position').in[ contract=208:0 ]  from #249:0 
  nodes :out, via: HC::HAS_POSITION , where: { contract: contract }  # database-query solution
	#positions &.detect{|x| x.contract == contract }   # ruby solution
end

#positionsObject

shortcut for the portfolio-positions-array



132
133
134
# File 'lib/models/hc/portfolio.rb', line 132

def positions
	out( HC::HAS_POSITION ).in  #  ruby solution, without inheritance
end

#prev_portfolio_position(contract) ⇒ Object

go back one step in history, traverse to the portfolio_position where the contract matches



127
128
129
# File 'lib/models/hc/portfolio.rb', line 127

def prev_portfolio_position(contract)
		prev &.position( contract )
end

#to_humanObject



156
157
158
# File 'lib/models/hc/portfolio.rb', line 156

def to_human
			"<#{self.class.to_s.split(':').last}[#{rid}]: account:#{.to_human}, #{values.size} AccountValues; #{out_hc_has_position.size} Positions >"
end