cotcube-bardata 0.1.2 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.irbrc.rb +3 -1
- data/CHANGELOG.md +38 -0
- data/Gemfile +3 -2
- data/README.md +61 -28
- data/Rakefile +5 -3
- data/VERSION +1 -1
- data/cotcube-bardata.gemspec +10 -11
- data/lib/cotcube-bardata.rb +47 -17
- data/lib/cotcube-bardata/cached.rb +120 -0
- data/lib/cotcube-bardata/constants.rb +8 -8
- data/lib/cotcube-bardata/daily.rb +120 -58
- data/lib/cotcube-bardata/eods.rb +93 -50
- data/lib/cotcube-bardata/helpers.rb +107 -0
- data/lib/cotcube-bardata/init.rb +23 -26
- data/lib/cotcube-bardata/provide.rb +38 -13
- data/lib/cotcube-bardata/quarters.rb +28 -65
- data/lib/cotcube-bardata/range_matrix.rb +117 -0
- data/lib/cotcube-bardata/trade_dates.rb +19 -6
- data/lib/cotcube-bardata/trading_hours.rb +47 -0
- metadata +43 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7db21286fcb1a011326db3d27333b3417ec497db6c5b005250e0dcc11d355839
|
4
|
+
data.tar.gz: 1eca29b839ae84d43c601f793501237cabc5de25363ea1bd55f6c707393d98ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b46cbfbd3bf8117a5076691d9eaa8985ea551d822838e69cf4336a97161e77d3c0ab5b9427f957a08a219a19290d76832527cadbf2956d16053762443e8f25b
|
7
|
+
data.tar.gz: b082544cd2ac1c4a36a5e23a7ce2da9764fd9ce4fa7f09a72b28a579301eb007fda3ea8c8856cb5f9a9fea6756d2c6ee2a4d84224195840793ff49d1c7985855
|
data/.irbrc.rb
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,41 @@
|
|
1
|
+
## 0.1.7 (January 14, 2021)
|
2
|
+
- added :range parameter to :provide, hence to :provide_cached, :provide_daily
|
3
|
+
- added forgotten module_functions
|
4
|
+
|
5
|
+
## 0.1.6 (January 07, 2021)
|
6
|
+
- prefering datetime instead date (in helpers and daily)
|
7
|
+
- changed keyword :set to :filter in cached, provide and trading_hours
|
8
|
+
|
9
|
+
## 0.1.5 (January 02, 2021)
|
10
|
+
- applied some still missing cops
|
11
|
+
|
12
|
+
## 0.1.4 (January 02, 2021)
|
13
|
+
- two minor fixes (cached.rb, daily.rb)
|
14
|
+
- adding first (shy) specs ... to be continued
|
15
|
+
- cotcube-bardata.rb: added dependency parallel, added new module files and functions
|
16
|
+
- provide.rb: writing provide, the central accessor to actual bardata
|
17
|
+
- cached.rb: implementing 'provide_cached', which manages reduced and dimished subsets of 'quarters'
|
18
|
+
- helpers.rb: added get_id_set
|
19
|
+
- daily.rb: applied cops
|
20
|
+
- quarters.rb: applied cops, used new get_id_set, slimmed down content in favor of 'provide'
|
21
|
+
- eods.rb: renamed get_id_from to get_id_set
|
22
|
+
- added explanation to range_matrix.rb
|
23
|
+
- added 'holidays' to trade_dates.csv, depending on according CSV
|
24
|
+
- applied cops to init.rb
|
25
|
+
- changed name from get_range to trading_hours
|
26
|
+
- minor change in gemspec
|
27
|
+
- fixed typos in README
|
28
|
+
- added bounded versions to gemspec
|
29
|
+
- applied cops
|
30
|
+
- new file trading_hours.rb providing get_range(). Based on CSV data it provides a list of ranges depicting seconds since Sunday 0:00am, which in turn can be used with the helper Array.new.to_time_interval.
|
31
|
+
- new file and method 'range_matrix', investigating high-low ranges of entire daily
|
32
|
+
- Too bad, found copied README...fixing something quite embarassing.
|
33
|
+
|
34
|
+
## 0.1.3 (December 23, 2020)
|
35
|
+
- added .provide_most_liquids_by_eod which supports :age, filtering out files that have been updated more recently
|
36
|
+
- added 'type' to symbols to filter for e.g. currencies
|
37
|
+
- changed .provide_eods not to raise on missing eod-file but just to WARN
|
38
|
+
|
1
39
|
## 0.1.2 (December 22, 2020)
|
2
40
|
- created and added .provide_quarters
|
3
41
|
- added cotcube-helpers as new dependency to gempsec
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,36 +1,19 @@
|
|
1
|
-
#
|
1
|
+
# cotcube-bardata
|
2
2
|
|
3
|
-
This gem
|
4
|
-
time series data into bitangents.
|
3
|
+
This gem is a versatile provider of bardata. It relies on a directory structure most probably saved to `/var/cotcube/bardata/`. The following directories and files contain data others might expect to be delivered by a database:
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
the bitangent in regard to the :fuzziness, which is at least 1 'tick'.
|
12
|
-
- Ocassionally a bitangent becomes an N-tangent, when multiple findings or clusters are
|
13
|
-
in one line resp. the fuzzied ranged on the sheared graph.
|
14
|
-
- Shearing is limited by reaching 0 degrees, so everything below the horizont (or above resp.)
|
15
|
-
is discarded.
|
16
|
-
|
17
|
-
After identifiying the angle of Z degress delivering N findings( actually N - 1, as the
|
18
|
-
last finding always is the last member of the series), the entire time series then is split
|
19
|
-
into N subranges, where each subrange is processed again until it reaches minimum size
|
20
|
-
(which defaults to 3 items).
|
21
|
-
|
22
|
-
Except for the very first range the challenge is to trim away the beginning of each sub
|
23
|
-
range.
|
24
|
-
|
25
|
-
The result of such a search is a tree, where it might be considerable to walk and change
|
26
|
-
this tree by adding elements to the time series instead of recalculating it completely.
|
5
|
+
1. `eods`: within *eods/<id or symbol>/<date>.csv*, for each date a list of contracts is located, to be applied with the list of headers `%i[ contract date open high low close volume oi ]`.
|
6
|
+
2. `daily`: within *daily/<id or symbol>/<contract>.csv*, for each contract all eods are provided. The list of headers is expected as `%i[ contract date open high low close volume oi ]`. Please note that it is not obvious whether `close` contains settlement or actual closing price, depending on the exchange and the broker providing the source data.
|
7
|
+
3. `quarters`: within *quarters/<id or symbol>/<contract>.csv*, for each contract a list of quarters (15 minute intervals) is provided, depending on the first occurrence of the contract within the topN volume segment. Note the different headers here: `%i[ contract date_alike day open high low close volume ]`.
|
8
|
+
4. `trading_hours`: within *trading_hours/<symbol or type>_<set>.csv* a list of intervals is provided, with the headers `%i[ interval_start interval_end ]` for each interval described by seconds since Sunday 0:00p.m. (as defaulted by Ruby's *DateTime.new.wday)*.
|
9
|
+
5. `trade_dates.csv`: A growing list of trade\_dates as provided by the CME.
|
27
10
|
|
28
11
|
## Installation
|
29
12
|
|
30
13
|
Add this line to your application's Gemfile:
|
31
14
|
|
32
15
|
```ruby
|
33
|
-
gem '
|
16
|
+
gem 'cotcube-bardata'
|
34
17
|
```
|
35
18
|
|
36
19
|
And then execute:
|
@@ -39,11 +22,60 @@ And then execute:
|
|
39
22
|
|
40
23
|
Or install it yourself as:
|
41
24
|
|
42
|
-
$ gem install
|
25
|
+
$ gem install cotcube-bardata
|
43
26
|
|
44
27
|
## Usage
|
45
28
|
|
46
|
-
|
29
|
+
### Configuration
|
30
|
+
|
31
|
+
The gem expects a configfile 'bardata.yml', located in '/etc/cotcube/' on linux platform and '/usr/local/etc/cotcube/' on FreeBSD. The location of the configfile can be overwritten by passing the according parameter to `init`.
|
32
|
+
|
33
|
+
### daily.rb
|
34
|
+
|
35
|
+
Provides
|
36
|
+
|
37
|
+
* `provide_daily(symbol: nil, id: nil, contract:, timezone: Time.find_zone('America/Chicago'), config: init)`
|
38
|
+
* `continuous(symbol: nil, id: nil, config: init, date: nil)`: Loads all dailies for given *id* and groups by date, hence providing a list of eods.
|
39
|
+
* `continuous_ml(symbol: nil, id: nil, base: nil)`: Provides a list of contracts, containing a list of most liquid by volume contracts as `{ date: , ml: }`
|
40
|
+
* `continuous_actual_ml(symbol: nil, id: nil)`: Same as above, but providing the succeeding trading day (as the signaled 'ML' is yet one day old before it can be used).
|
41
|
+
* `continuous_overview(symbol: nil, id: nil, config: init, selector: :volume, human: false, filter: nil)`: Several purposes, but most noticeable providing the range of first and last occurrence within the top N% by volume within eods.
|
42
|
+
|
43
|
+
### eods.rb
|
44
|
+
|
45
|
+
Provides
|
46
|
+
|
47
|
+
* `most_liquid_for(symbol: nil, id: nil, date: last_trade_date, config: init, quiet: false)`
|
48
|
+
* `provide_most_liquids_by_eod(config: init, date: last_trade_date, filter: :volume_part, age: 1.hour)`
|
49
|
+
* `provide_eods(**args)`
|
50
|
+
* `provide_quarters(**args)`
|
51
|
+
|
52
|
+
### quarters.rb
|
53
|
+
|
54
|
+
Provides `provide_quarters(**args)`.
|
55
|
+
|
56
|
+
### provide.rb
|
57
|
+
|
58
|
+
Provides `provide(**args)`.
|
59
|
+
|
60
|
+
### range\_matrix.rb
|
61
|
+
|
62
|
+
Provides `range_matrix`, a simple method processing data based on `Bardata.continuous_actual_ml` to return a statistical overview of daily high-low ranges (not True Ranges). It contains sets for
|
63
|
+
|
64
|
+
* all available data,
|
65
|
+
* a data subset containing the recent 12 months
|
66
|
+
* data diminished by `:dim` (top and bottom) based on all available data
|
67
|
+
|
68
|
+
and contains *max*, *avg*, *lower*, *median*, *upper* and *max* (where 'upper' and 'lower' are like the median but at the 25percentile and 75percentile resp.).
|
69
|
+
|
70
|
+
As a third dimension (sorry!) all of the above is applied to days, weeks as well as months.
|
71
|
+
|
72
|
+
### trade\_dates.rb
|
73
|
+
|
74
|
+
Provides `last_trade_date`, simple fetches the current 5 trade dates from CME and returns the very last.
|
75
|
+
|
76
|
+
### trading\_hours.rb
|
77
|
+
|
78
|
+
Provides `get_range(symbol: nil, set: :full, force_set: false, config: init, debug: false)`, loading a set of intervals. The sets are defaulting to :full when the requested set is not found--unless :force\_set is enabled. Furthermore, if symbol is not found, the type-based version is returned. Eventually, if neither could be returned, the 24x7 interval is returned.
|
47
79
|
|
48
80
|
## Development
|
49
81
|
|
@@ -53,9 +85,10 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
53
85
|
|
54
86
|
## Contributing
|
55
87
|
|
56
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
88
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/donkeybridge/bitangent.
|
57
89
|
|
58
90
|
|
59
91
|
## License
|
60
92
|
|
61
93
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
94
|
+
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.7
|
data/cotcube-bardata.gemspec
CHANGED
@@ -9,13 +9,13 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.summary = 'Functions to provide bardata; and some simple time series aggregations'
|
10
10
|
spec.description = 'Functions to provide bardata; and some simple time series aggregations '
|
11
11
|
|
12
|
-
spec.homepage =
|
12
|
+
spec.homepage = "https://github.com/donkeybridge/#{spec.name}"
|
13
13
|
spec.license = 'BSD-4-Clause'
|
14
14
|
spec.required_ruby_version = Gem::Requirement.new('~> 2.7')
|
15
15
|
|
16
16
|
spec.metadata['homepage_uri'] = spec.homepage
|
17
17
|
spec.metadata['source_code_uri'] = spec.homepage
|
18
|
-
spec.metadata['changelog_uri'] = spec.homepage
|
18
|
+
spec.metadata['changelog_uri'] = "#{spec.homepage}/CHANGELOG.md"
|
19
19
|
|
20
20
|
# Specify which files should be added to the gem when it is released.
|
21
21
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -26,16 +26,15 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
27
|
spec.require_paths = ['lib']
|
28
28
|
|
29
|
-
spec.add_dependency '
|
30
|
-
spec.add_dependency '
|
31
|
-
spec.add_dependency '
|
32
|
-
spec.add_dependency '
|
33
|
-
spec.add_dependency '
|
34
|
-
spec.add_dependency '
|
35
|
-
spec.add_dependency '
|
29
|
+
spec.add_dependency 'activesupport', '~> 6'
|
30
|
+
spec.add_dependency 'colorize', '~> 0.8'
|
31
|
+
spec.add_dependency 'cotcube-helpers', '~> 0.1'
|
32
|
+
spec.add_dependency 'cotcube-indicators', '~> 0.1'
|
33
|
+
spec.add_dependency 'httparty', '~> 0.18'
|
34
|
+
spec.add_dependency 'parallel', '~> 1'
|
35
|
+
spec.add_dependency 'yaml', '~> 0.1'
|
36
36
|
|
37
|
-
|
38
|
-
spec.add_development_dependency 'rake'
|
37
|
+
spec.add_development_dependency 'rake', '>= 12'
|
39
38
|
spec.add_development_dependency 'rspec', '~>3.6'
|
40
39
|
spec.add_development_dependency 'yard', '~>0.9'
|
41
40
|
end
|
data/lib/cotcube-bardata.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# rubocop:disable Naming/FileName
|
2
|
+
# rubocop:enable Naming/FileName
|
1
3
|
# frozen_string_literal: true
|
2
4
|
|
3
5
|
require 'active_support'
|
@@ -9,34 +11,62 @@ require 'date' unless defined?(DateTime)
|
|
9
11
|
require 'csv' unless defined?(CSV)
|
10
12
|
require 'yaml' unless defined?(YAML)
|
11
13
|
require 'cotcube-helpers'
|
12
|
-
|
13
|
-
|
14
|
+
require 'parallel'
|
14
15
|
|
15
16
|
require_relative 'cotcube-bardata/constants'
|
17
|
+
require_relative 'cotcube-bardata/helpers'
|
16
18
|
require_relative 'cotcube-bardata/init'
|
17
19
|
require_relative 'cotcube-bardata/trade_dates'
|
18
20
|
require_relative 'cotcube-bardata/daily'
|
19
21
|
require_relative 'cotcube-bardata/quarters'
|
20
22
|
require_relative 'cotcube-bardata/eods'
|
23
|
+
require_relative 'cotcube-bardata/cached'
|
21
24
|
require_relative 'cotcube-bardata/provide'
|
25
|
+
require_relative 'cotcube-bardata/range_matrix'
|
26
|
+
require_relative 'cotcube-bardata/trading_hours'
|
22
27
|
|
23
28
|
module Cotcube
|
24
29
|
module Bardata
|
25
|
-
|
26
30
|
module_function :config_path, # provides the path of configuration directory
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
# provides the prefix of the configuration directory according to OS-specific FSH
|
32
|
+
:config_prefix,
|
33
|
+
# checks whether environment is prepared and returns the config hash
|
34
|
+
:init,
|
35
|
+
# Provides the most recent trade date (today or maybe last friday before weekend)
|
36
|
+
:last_trade_date,
|
37
|
+
:provide,
|
38
|
+
# the most_liquid contract for a given symbol or id, based on date or last_trade_date
|
39
|
+
:most_liquid_for,
|
40
|
+
# provides the list of eods, either with data or just the contracts,
|
41
|
+
# filtered for liquidity threshold
|
42
|
+
:provide_eods,
|
43
|
+
:provide_most_liquids_by_eod,
|
44
|
+
# provides the list of dailies for a given symbol, which include OI.
|
45
|
+
# Note that the close is most probably settlement price.
|
46
|
+
:provide_daily,
|
47
|
+
# for a given date or range, provide all contracts that exceed a given threshold of volume share
|
48
|
+
:continuous,
|
49
|
+
# the list of most liquid contracts (by each days volume share)
|
50
|
+
:continuous_ml,
|
51
|
+
# same list but riped one day each
|
52
|
+
:continuous_actual_ml,
|
53
|
+
# based on continuous, create list of when which contract was most liquid
|
54
|
+
:continuous_overview,
|
55
|
+
# provide the list of quarters, possibly as hours or days.
|
56
|
+
:provide_quarters,
|
57
|
+
# some statistics to estimate daily volatility of specific contract
|
58
|
+
:range_matrix,
|
59
|
+
# create an array of ranges based on specified source data
|
60
|
+
:trading_hours,
|
61
|
+
# receive id / symbol information on an uncertain set of parameters
|
62
|
+
:get_id_set,
|
63
|
+
:select_specific_date,
|
64
|
+
:extended_select_for_range,
|
65
|
+
:provide_cached,
|
66
|
+
:compare,
|
67
|
+
:holidays,
|
68
|
+
:symbols # reads and provides the symbols file
|
69
|
+
|
70
|
+
# please note that module_functions of source provided in private files must be published there
|
40
71
|
end
|
41
72
|
end
|
42
|
-
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cotcube
|
4
|
+
# missing top level documentation
|
5
|
+
module Bardata
|
6
|
+
# send pre-created days based on quarters
|
7
|
+
def provide_cached(contract:, # rubocop:disable Metrics/ParameterLists
|
8
|
+
symbol: nil, id: nil,
|
9
|
+
range: nil,
|
10
|
+
config: init,
|
11
|
+
timezone: Time.find_zone('America/Chicago'),
|
12
|
+
filter: :full, # most probably either :full or :rth
|
13
|
+
force_update: false, # force reloading via provide_quarters
|
14
|
+
force_recent: false) #
|
15
|
+
|
16
|
+
unless range.nil? ||
|
17
|
+
range.is_a?(Range) &&
|
18
|
+
[Date, DateTime, ActiveSupport::TimeWithZone].map do |cl|
|
19
|
+
(range.begin.nil? || range.begin.is_a?(cl)) &&
|
20
|
+
(range.end.nil? || range.end.is_a?(cl))
|
21
|
+
end.reduce(:|)
|
22
|
+
raise ArgumentError, 'Range, if given, must be either (Integer..Integer) or (Timelike..Timelike)'
|
23
|
+
end
|
24
|
+
|
25
|
+
unless range.nil?
|
26
|
+
range_begin = range.begin.nil? ? nil : timezone.parse(range.begin.to_s)
|
27
|
+
range_end = range.end.nil? ? nil : timezone.parse(range.end.to_s)
|
28
|
+
range = (range_begin..range_end)
|
29
|
+
end
|
30
|
+
|
31
|
+
headers = %i[contract datetime open high low close volume]
|
32
|
+
sym = get_id_set(symbol: symbol, id: id, contract: contract)
|
33
|
+
contract = contract[-3..]
|
34
|
+
dir = "#{config[:data_path]}/cached/#{sym[:id]}_#{filter.to_s.downcase}"
|
35
|
+
symlink = "#{config[:data_path]}/cached/#{sym[:symbol]}_#{filter.to_s.downcase}"
|
36
|
+
`mkdir -p #{dir}` unless Dir.exist? dir
|
37
|
+
`ln -s #{dir} #{symlink}` unless File.exist? symlink
|
38
|
+
file = "#{dir}/#{contract}.csv"
|
39
|
+
quarters_file = "#{config[:data_path]}/quarters/#{sym[:id]}/#{contract[-3..]}.csv"
|
40
|
+
if File.exist?(file) && (not force_update)
|
41
|
+
base = CSV.read(file, headers: headers).map do |x|
|
42
|
+
x = x.to_h
|
43
|
+
x[:datetime] = timezone.parse(x[:datetime])
|
44
|
+
%i[open high low close].each { |z| x[z] = x[z].to_f.round(9) }
|
45
|
+
x[:volume] = x[:volume].to_i
|
46
|
+
x[:type] = "#{filter.to_s.downcase}_day".to_sym
|
47
|
+
x
|
48
|
+
end
|
49
|
+
if base.last[:high].zero?
|
50
|
+
# contract exists but is closed (has the CLOSED marker)
|
51
|
+
base.pop
|
52
|
+
# rubocop:disable Metrics/BlockNesting
|
53
|
+
result = if range.nil?
|
54
|
+
base
|
55
|
+
else
|
56
|
+
base.select do |x|
|
57
|
+
(range.begin.nil? ? true : x[:datetime] >= range.begin) and
|
58
|
+
(range.end.nil? ? true : x[:datetime] <= range.end)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
return result
|
62
|
+
elsif File.mtime(file) < File.mtime(quarters_file)
|
63
|
+
result = if range.nil?
|
64
|
+
base
|
65
|
+
else
|
66
|
+
base.select do |x|
|
67
|
+
(range.begin.nil? ? true : x[:datetime] >= range.begin) and
|
68
|
+
(range.end.nil? ? true : x[:datetime] <= range.end)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
# rubocop:enable Metrics/BlockNesting
|
72
|
+
return result
|
73
|
+
else
|
74
|
+
puts "File #{file} exists, but is neither closed nor current. Running update.".colorize(:light_green)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
begin
|
78
|
+
data = provide_quarters(contract: contract, id: sym[:id], keep_marker: true)
|
79
|
+
rescue StandardError
|
80
|
+
puts "Cannot provide quarters for requested contract #{sym[:symbol]}:#{contract},"\
|
81
|
+
"returning '[ ]'".colorize(:light_red)
|
82
|
+
return []
|
83
|
+
end
|
84
|
+
|
85
|
+
# removing marker if existing
|
86
|
+
contract_is_marked = data.last[:high].zero?
|
87
|
+
data.pop if contract_is_marked
|
88
|
+
unless (filter == :full) || (data.size < 3)
|
89
|
+
requested_set = trading_hours(symbol: sym[:symbol], filter: filter)
|
90
|
+
data = data.select_within(ranges: requested_set, attr: :datetime) { |x| x.to_datetime.to_sssm }
|
91
|
+
end
|
92
|
+
|
93
|
+
base = Cotcube::Helpers.reduce(bars: data, to: :days)
|
94
|
+
|
95
|
+
# remove last day of result unless marked
|
96
|
+
base.pop unless contract_is_marked || force_recent
|
97
|
+
|
98
|
+
base.map do |x|
|
99
|
+
x[:datetime] = x[:datetime].to_date
|
100
|
+
x[:type] = "#{filter}_day".to_sym
|
101
|
+
x.delete(:day)
|
102
|
+
end
|
103
|
+
CSV.open(file, 'w') do |csv|
|
104
|
+
base.each { |b| csv << b.values_at(*headers) }
|
105
|
+
if contract_is_marked
|
106
|
+
marker = ["#{sym[:symbol]}#{contract}", base.last[:datetime] + 1.day, 0, 0, 0, 0, 0]
|
107
|
+
csv << marker
|
108
|
+
end
|
109
|
+
end
|
110
|
+
if range.nil?
|
111
|
+
base
|
112
|
+
else
|
113
|
+
base.select do |x|
|
114
|
+
(range.begin.nil? ? true : x[:date] >= range.begin) and
|
115
|
+
(range.end.nil? ? true : x[:date] <= range.end)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|