cotcube-bardata 0.1.8 → 0.1.11

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
2
  SHA256:
3
- metadata.gz: a701303a258aaaf6050922e35eaacf53ce09fc43fc25778492ebb0b11fb9890c
4
- data.tar.gz: 389709153f639e14638832e701f19a295181e1b81e26a8aa2ba2baf5c0587ee9
3
+ metadata.gz: dc417f9b8b33204bbc1b345ec28e2c5604b2a5f59c183a6a0a1ad15a6cf223b1
4
+ data.tar.gz: f631c5507dff588e4f2e19209aca5d135514e450ddc9b311e407b9733f539191
5
5
  SHA512:
6
- metadata.gz: ee32360405d9597e82c6eb9d7678895ecd1c7db9872ed2ecdd8efbd4fc0cd2ec4cea21d2546e867a45af3655ab251a34d39855d7b7d7865458ea60ff8ba65811
7
- data.tar.gz: 7a4387b1834d811a61e9bd04fbe0a263f7f4a730b2a15cb928fb956929acefa5097a502fa548c26356f5ccac051d7f037344c42e320400a8a5eab55266119b81
6
+ metadata.gz: f5276bd185a561658226f65b92ce696774f1da7442bf0c10704925e4afd295566844d02bf866921575bf60cea6944555c7dd6abc28214ed5852ca8228553d2f3
7
+ data.tar.gz: c73f923b1bf4399bf6a9cea56e4adf2acc3aaeab770d4b56cc1daae7d5a4f7c4617f30baff58b03f9ced45a9987a4bf8106c709f12a1cfb17f0021cfe36a6d71
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## 0.1.11 (March 07, 2021)
2
+ - daily.rb: added new technique 'caching in constants' to accelerate computation, also referring to continuous
3
+ - provide.rb: minor change, so disregarded contracts can be used in swapproximate
4
+
5
+ ## 0.1.10 (February 11, 2021)
6
+ - Daily.rb: Added measure parameters to continous_suite
7
+ - cached.rb: Minor fix in comparison
8
+
9
+ ## 0.1.9.3 (February 08, 2021)
10
+ - cached: minor change fixing problem to get yesterday in rth subsets
11
+
12
+ ## 0.1.9.2 (February 07, 2021)
13
+ - minor changes
14
+ - daily#continuous_table: introducing debuglevel
15
+
16
+ ## 0.1.9.1 (January 29, 2021)
17
+ - provide: added new interval 'synth', mixing available dailies with synthetic days based on quarters
18
+ - minor change / cleanup
19
+ - setting gemspec to use rake 13 and changing version spec to overcome warnings
20
+
1
21
  ## 0.1.8 (January 27, 2021)
2
22
  - in helpers, #extended_range_for_date: fixed comparison signs
3
23
  - range_matrix: applied cops, noted appearance of Cotcube::Helpers.simple_series_stats
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.8
1
+ 0.1.11
@@ -52,6 +52,8 @@ module Cotcube
52
52
  :continuous_actual_ml,
53
53
  # based on continuous, create list of when which contract was most liquid
54
54
  :continuous_overview,
55
+ # provider estimation of current ML usability
56
+ :continuous_table,
55
57
  # provide the list of quarters, possibly as hours or days.
56
58
  :provide_quarters,
57
59
  # some statistics to estimate daily volatility of specific contract
@@ -8,6 +8,7 @@ module Cotcube
8
8
  symbol: nil, id: nil,
9
9
  range: nil,
10
10
  config: init,
11
+ debug: false,
11
12
  timezone: Time.find_zone('America/Chicago'),
12
13
  filter: :full, # most probably either :full or :rth
13
14
  force_update: false, # force reloading via provide_quarters
@@ -59,9 +60,9 @@ module Cotcube
59
60
  end
60
61
  end
61
62
  return result
62
- elsif File.mtime(file) + 1.day > File.mtime(quarters_file)
63
- puts "CACHE #{File.mtime(file)}\t#{file}"
64
- puts "QUART #{File.mtime(quarters_file)}\t#{quarters_file}"
63
+ elsif File.mtime(file) - Time.now.beginning_of_day >= 0
64
+ puts "CACHE #{File.mtime(file)}\t#{file}" if debug
65
+ puts "QUART #{File.mtime(quarters_file)}\t#{quarters_file}" if debug
65
66
  result = if range.nil?
66
67
  base
67
68
  else
@@ -97,17 +98,17 @@ module Cotcube
97
98
  base = Cotcube::Helpers.reduce(bars: data, to: :days)
98
99
 
99
100
  # remove last day of result unless marked
100
- base.pop unless contract_is_marked || force_recent
101
+ base.pop if base.last[:datetime].to_date == timezone.now.to_date and not force_recent
101
102
 
102
103
  base.map do |x|
103
- x[:datetime] = x[:datetime].to_date
104
+ x[:date] = x[:datetime].to_date
104
105
  x[:type] = "#{filter}_day".to_sym
105
106
  x.delete(:day)
106
107
  end
107
108
  CSV.open(file, 'w') do |csv|
108
109
  base.each { |b| csv << b.values_at(*headers) }
109
110
  if contract_is_marked
110
- marker = ["#{sym[:symbol]}#{contract}", base.last[:datetime] + 1.day, 0, 0, 0, 0, 0]
111
+ marker = ["#{sym[:symbol]}#{contract}", base.last[:date] + 1.day, 0, 0, 0, 0, 0]
111
112
  csv << marker
112
113
  end
113
114
  end
@@ -61,29 +61,50 @@ module Cotcube
61
61
 
62
62
  # reads all files in bardata/daily/<id> and aggregates by date
63
63
  # (what is a pre-stage of a continuous based on daily bars)
64
- def continuous(symbol: nil, id: nil, config: init, date: nil)
64
+ def continuous(symbol: nil, id: nil, config: init, date: nil, measure: nil, force_rewrite: false)
65
+ raise ArgumentError, ':measure, if given, must be a Time object (e.g. Time.now)' unless [NilClass, Time].include? measure.class
66
+ measuring = lambda {|c| puts "[continuous] Time measured until '#{c}': #{(Time.now.to_f - measure.to_f).round(2)}sec" unless measure.nil? }
67
+
68
+ measuring.call("Starting")
65
69
  sym = get_id_set(symbol: symbol, id: id)
66
70
  id = sym[:id]
67
71
  id_path = "#{config[:data_path]}/daily/#{id}"
68
- available_contracts = Dir["#{id_path}/*.csv"].map { |x| x.split('/').last.split('.').first }
69
- available_contracts.sort_by! { |x| x[-7] }.sort_by! { |x| x[-6..-5] }
70
- data = []
71
- available_contracts.each do |c|
72
- provide_daily(id: id, config: config, contract: c).each do |x|
73
- data << x
72
+ c_file = "#{id_path}/continuous.csv"
73
+
74
+ # instead of using the provide_daily methods above, for this bulk operation a 'continuous.csv' is created
75
+ # this boosts from 4.5sec to 0.3sec
76
+ rewriting = force_rewrite or not(File.exist?(c_file)) or (Time.now - File.mtime(c_file) > 8.days)
77
+ if rewriting
78
+ puts "In daily+continuous: Rewriting #{c_file} #{force_rewrite ? "forcibly" : "due to fileage"}.".light_yellow
79
+ `rm #{c_file}; find #{id_path} | xargs cat 2>/dev/null | grep -v '0,0,0,0' | sort -t, -k2 | cut -d, -f1,2,7,8 > #{c_file}`
80
+ end
81
+ loading = lambda do
82
+ data = CSV.read(c_file).map do |row|
83
+ r = { contract: row[0],
84
+ date: row[1],
85
+ volume: row[2].to_i,
86
+ oi: row[3].to_i
87
+ }
88
+ end
89
+
90
+ measuring.call("Finished retrieving dailies.")
91
+ result = []
92
+ data.group_by { |x| x[:date] }.map do |k, v|
93
+ v.map { |x| x.delete(:date) }
94
+ result << {
95
+ date: k,
96
+ volume: v.map { |x| x[:volume] }.reduce(:+),
97
+ oi: v.map { |x| x[:oi] }.reduce(:+)
98
+ }
99
+ result.last[:contracts] = v
74
100
  end
75
101
  end
76
- result = []
77
- data.sort_by { |x| x[:date] }.group_by { |x| x[:date] }.map do |k, v|
78
- v.map { |x| x.delete(:date) }
79
- result << {
80
- date: k,
81
- volume: v.map { |x| x[:volume] }.reduce(:+),
82
- oi: v.map { |x| x[:oi] }.reduce(:+)
83
- }
84
- result.last[:contracts] = v
102
+ constname = "CONTINUOUS_#{symbol}".to_sym
103
+ if rewriting or not Cotcube::Bardata.const_defined?( constname)
104
+ Cotcube::Bardata.const_set constname, loading.call
85
105
  end
86
- date.nil? ? result : result.select { |x| x[:date] == date }.first
106
+ measuring.call("Finished processing")
107
+ date.nil? ? Cotcube::Bardata.const_get(constname) : Cotcube::Bardata.const_get(constname).find { |x| x[:date] == date }
87
108
  end
88
109
 
89
110
  def continuous_ml(symbol: nil, id: nil, base: nil)
@@ -116,20 +137,27 @@ module Cotcube
116
137
  config: init,
117
138
  selector: :volume,
118
139
  human: false,
140
+ measure: nil,
119
141
  filter: nil)
142
+
143
+ raise ArgumentError, ':measure, if given, must be a Time object (e.g. Time.now)' unless [NilClass, Time].include? measure.class
144
+ measuring = lambda {|c| puts "[continuous_overview] Time measured until '#{c}': #{(Time.now.to_f - measure.to_f).round(2)}sec" unless measure.nil? }
145
+
120
146
  raise ArgumentError, 'Selector must be either :volume or :oi' unless selector.is_a?(Symbol) &&
121
- %i[volume oi].include?(selector)
147
+ %i[volume oi].include?(selector)
122
148
 
149
+ measuring.call("Starting")
123
150
  sym = get_id_set(symbol: symbol, id: id)
124
151
  id = sym[:id]
125
152
  # noinspection RubyNilAnalysis
126
- data = continuous(id: id, config: config).map do |x|
153
+ data = continuous(id: id, config: config, measure: measure).map do |x|
127
154
  {
128
155
  date: x[:date],
129
156
  volume: x[:contracts].sort_by { |z| - z[:volume] }[0..4].compact.reject { |z| z[:volume].zero? },
130
157
  oi: x[:contracts].sort_by { |z| - z[:oi] }[0..4].compact.reject { |z| z[:oi].zero? }
131
158
  }
132
159
  end
160
+ measuring.call("Retrieved continuous")
133
161
  data.reject! { |x| x[selector].empty? }
134
162
  result = data.group_by { |x| x[selector].first[:contract] }
135
163
  result.each_key do |key|
@@ -149,31 +177,44 @@ module Cotcube
149
177
  }\t#{v.last[:date]
150
178
  }\t#{format('%4d', (Date.parse(v.last[:date]) - Date.parse(v.first[:date])))
151
179
  }\t#{result[k].map do |x|
152
- x[:volume].select do
153
- x[:contract] == k
154
- end
155
- end.size
180
+ x[:volume].select do
181
+ x[:contract] == k
182
+ end
183
+ end.size
156
184
  }"
157
185
  # rubocop:enable Layout/ClosingParenthesisIndentation
158
186
  end
159
187
  end
188
+ measuring.call("Finished processing")
160
189
  result
161
190
  end
162
191
 
163
192
  def continuous_table(symbol: nil, id: nil,
164
193
  selector: :volume,
165
194
  filter: nil,
195
+ date: Date.today,
196
+ measure: nil,
197
+ debuglevel: 1,
166
198
  debug: false)
199
+ if debug.is_a?(Integer)
200
+ debuglevel = debug
201
+ debug = debuglevel > 0 ? true : false
202
+ end
203
+
204
+ raise ArgumentError, ':measure, if given, must be a Time object (e.g. Time.now)' unless [NilClass, Time].include? measure.class
205
+ measuring = lambda {|c| puts "[continuous_table] Time measured until '#{c}': #{(Time.now.to_f - measure.to_f).round(2)}sec" unless measure.nil? }
206
+
167
207
  raise ArgumentError, 'Selector must be either :volume or :oi' unless selector.is_a?(Symbol) &&
168
- %i[volume oi].include?(selector)
208
+ %i[volume oi].include?(selector)
169
209
 
210
+ measuring.call("Entering function")
170
211
  sym = get_id_set(symbol: symbol, id: id)
171
212
  if %w[R6 BJ GE].include? sym[:symbol]
172
- puts "Rejecting to process symbol '#{sym[:symbol]}'."
173
- return
213
+ puts "Rejecting to process symbol '#{sym[:symbol]}'.".light_red
214
+ return []
174
215
  end
175
216
  id = sym[:id]
176
- dfm = lambda do |x, y = Date.today.year|
217
+ dfm = lambda do |x, y = date.year|
177
218
  k = Date.strptime("#{y} #{x.negative? ? x + 366 : x}", '%Y %j')
178
219
  k -= 1 while [0, 6].include?(k.wday)
179
220
  k.strftime('%a, %Y-%m-%d')
@@ -181,13 +222,15 @@ module Cotcube
181
222
  puts "#{sym[:symbol]}\t#{x}\t#{y}"
182
223
  end
183
224
 
184
- ytoday = Date.today.yday
185
- data = continuous_overview(id: id, selector: selector, filter: filter, human: false, config: init)
186
- .reject { |k, _| k[-2..].to_i == Date.today.year % 2000 }
187
- .group_by { |k, _| k[2] }
188
- output_sent = 0
225
+ ytoday = date.yday
226
+ data = continuous_overview(id: id, selector: selector, filter: filter, human: false, config: init, measure: measure)
227
+ .reject { |k, _| k[-2..].to_i == date.year % 2000 }
228
+ .group_by { |k, _| k[2] }
229
+ measuring.call("Retrieved continous_overview")
230
+ output_sent = []
231
+ early_year=nil
189
232
  data.keys.sort.each do |month|
190
- puts "Processing #{sym[:symbol]}#{month}" if debug
233
+ puts "Processing #{sym[:symbol]}#{month}" if debuglevel > 1
191
234
  v0 = data[month]
192
235
  ydays = v0.map { |_, v1| Date.parse(v1.last[:date]).yday }
193
236
  fdays = v0.map { |_, v1| Date.parse(v1.first[:date]).yday }.sort
@@ -207,10 +250,9 @@ module Cotcube
207
250
  else
208
251
  :white
209
252
  end
210
- if debug || (color != :white)
211
- # rubocop:disable Layout/ClosingParenthesisIndentation
212
- puts "#{sym[:symbol]
213
- }#{month
253
+ # rubocop:disable Layout/ClosingParenthesisIndentation
254
+ output = "#{sym[:symbol]
255
+ }#{month
214
256
  }\t#{format '%12s', sym[:type]
215
257
  }\t#{ytoday
216
258
  }/#{fday
@@ -220,22 +262,27 @@ module Cotcube
220
262
  }: #{dfm.call(yavg)
221
263
  }\t#{format '%5d', ydays.max
222
264
  }: #{dfm.call(ydays.max)}".colorize(color)
223
- output_sent += 1
224
- end
225
- next unless debug
265
+ if debug || (color != :white)
266
+ puts output
267
+ output_sent << "#{sym[:symbol]}#{month}" unless color == :white
268
+ end
269
+ early_year ||= output
270
+ next unless (debug and debuglevel >= 2)
226
271
 
227
- v0.each do |contract, v1|
228
- puts "\t#{contract
272
+ v0.each do |contract, v1|
273
+ puts "\t#{contract
229
274
  }\t#{v1.first[:date]
230
275
  }\t#{Date.parse(v1.last[:date]).strftime('%a')
231
276
  }, #{v1.last[:date]
232
277
  } (#{Date.parse(v1.last[:date]).yday}"
233
- # rubocop:enable Layout/ClosingParenthesisIndentation
234
- end
278
+ # rubocop:enable Layout/ClosingParenthesisIndentation
279
+ end
235
280
  end
236
- case output_sent
281
+ case output_sent.size
237
282
  when 0
238
283
  puts "WARNING: No output was sent for symbol '#{sym[:symbol]}'.".colorize(:light_yellow)
284
+ puts " Assuming late-year-processing.".light_yellow
285
+ puts early_year.light_green
239
286
  when 1
240
287
  # all ok
241
288
  true
@@ -243,7 +290,8 @@ module Cotcube
243
290
  puts "---- #{output_sent} for #{sym[:symbol]} ---------------"
244
291
 
245
292
  end
246
- nil
293
+ measuring.call("Finished processing")
294
+ output_sent
247
295
  end
248
296
  end
249
297
  end
@@ -40,6 +40,15 @@ module Cotcube
40
40
  raise 'Missing implementation to reduce cached days to weeks or months'
41
41
  when :dailies, :daily
42
42
  provide_daily contract: contract, symbol: symbol, id: id, config: config, range: range
43
+ when :synth, :synthetic, :synthetic_days
44
+ days = provide_cached contract: contract, symbol: symbol, id: id, config: config, filter: filter,
45
+ range: range, force_recent: force_recent
46
+ dailies = provide_daily contract: contract, symbol: symbol, id: id, config: config, range: range
47
+ if ((days.last[:datetime] > dailies.last[:datetime]) rescue false)
48
+ dailies[..-2] + days.select { |d| d[:datetime] > dailies[-2][:datetime] }
49
+ else
50
+ dailies
51
+ end
43
52
  else
44
53
  raise ArgumentError, "Unsupported or unknown interval '#{interval}' in Bardata.provide"
45
54
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cotcube-bardata
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin L. Tischendorf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-27 00:00:00.000000000 Z
11
+ date: 2021-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport