cotcube-cftcsource 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 75a8631a91ea90a9fdf4505c9265508cfac8b06d385ab1b41f2e5683876e8617
4
+ data.tar.gz: db8caed963d6dcd7dc13d29faac945965bf1b55dfbeb36ce51a89ace235c149a
5
+ SHA512:
6
+ metadata.gz: 38aa716749ec46151657f0e503019ba05de75b3f26e461a7df850ba3b3580f7ece53b00ed9bc9fde3f667200dd74972060fdf7f71f8a1d13403b6238943fa060
7
+ data.tar.gz: d53d40b0b11e515b8cc405e915aca658e1fbafeb5a8b9cd6dc495bfb338bcd76daff3934a9c1e4674e3b147c28e74652cc733dd11914984a8534862e4a361d75
@@ -0,0 +1,12 @@
1
+ def verbose_toggle
2
+ irb_context.echo ? irb_context.echo = false : irb_context.echo = true
3
+ end
4
+
5
+ alias vt verbose_toggle
6
+
7
+ $debug = true
8
+ IRB.conf[:USE_MULTILINE] = false
9
+ # require 'bundler'
10
+ # Bundler.require
11
+
12
+ require_relative 'lib/cotcube-cftcsource'
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,3 @@
1
+ ## 0.1.1 (December 12, 2020)
2
+
3
+
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in bitangent.gemspec
4
+ gemspec
5
+
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Benjamin L. Tischendorf
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,86 @@
1
+ # cotcube-cftcsource
2
+
3
+ This gem provides a module containing a set of methods to download, maintain, provide and
4
+ analyze the COT data issued by the CFTC. It is part of the Cotcube suite.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'cotcube-cftcsource'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle install
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install cotcube-cftcsource
21
+
22
+ ## Usage
23
+
24
+ ### Configuration
25
+
26
+ The gem expects a configfile 'cftcsource.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`.
27
+
28
+ Following parameters are currently supported (please let me know if something is missing):
29
+
30
+ ```yaml
31
+ data_path: 'path where the raw downloaded data is saved and other data is cached'
32
+ symbols_file: 'A file containing a CSV with supported symbols--if ommited, an example set from constants.rb is used'
33
+ headers_path: 'Where the CSV headers for cot data and signal sets are cached.'
34
+ default_lookback: 'the amount of weeks to be used for indicators in signal processing'
35
+ default_set: 'the name of the indicator set to be used (as saved in etc/cotcube/indicators-<default_set>.rb)
36
+ ```
37
+
38
+ ### constants.rb
39
+
40
+ Basically sets up 3 constants:
41
+
42
+ 1. CFTC\_LINKS contains all URLs to download all zipped COT reports from cftc.gov
43
+ 2. CFTC\_HEADERS provides lists of symbols serving as headers for the CSV-saved COT data.
44
+ 3. CFTC\_SYMBOL\_EXAMPLES contains 2 sets of configuration data. Each set has the following structure:
45
+ * id: The CFTC id of the future.
46
+ * symbol: Some verbal, unambiguous short identifier for this future.
47
+ * ticksize:
48
+ * power: The leverage per tick.
49
+ * months: The set of trading months.
50
+ * bcf: A legacy constant, it is '1.0' in almost most cases.
51
+ * reports: uppercase letters, signaling which reports are available for the futures (Legacy, Financial, Disaggregated and Cit)
52
+ * name:
53
+
54
+ ### init.rb
55
+ ### fetch and distribute
56
+
57
+ `CftcSource.fetch` downloads and unzips all COT-packages from CFTC.gov matching the :year parameter, defaulting to the current year.
58
+ Please see https://cftc.gov/MarketReports/CommitmentsofTraders/HistoricalCompressed/index.htm for which year parameters are available.
59
+
60
+ `CftcSource.distribute` breaks down the packages into the separated ID based directory tree.
61
+
62
+ NOTE: When building from scratch you should fetch and distribute all packages in proper annual order, as each run just updates data after the last available record.
63
+
64
+ ### provide.rb
65
+
66
+ Returns the requested series of raw COT data for given either :symbol or :id. The parameter :subset currently filters for 'std\_count', a further implementation is pending. If :subset is set to false, the complete series is returned.
67
+
68
+ ### series.rb
69
+
70
+ Based on the data returned by CftcSource.provide and the given indicator set, a series is created, cached and returned.
71
+
72
+ The default indicator simply calculates the net positions for pairs of `_long` and `_short`. Other indicator sets can be created. A simple example is in `etc/cotcube/indicators-example.rb`.
73
+ ## Development
74
+
75
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
76
+
77
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
78
+
79
+ ## Contributing
80
+
81
+ Bug reports and pull requests are welcome on GitHub at https://github.com/donkeybridge/bitangent.
82
+
83
+
84
+ ## License
85
+
86
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require __dir__ + '/../lib/cotcube-cftcsource.rb'
5
+
6
+ require 'irb'
7
+ require 'irb/completion'
8
+ require 'irb/ext/save-history'
9
+
10
+
11
+ # You can add fixtures and/or initialization code here to make experimenting
12
+ # with your gem easier. You can also use a different console, if you like.
13
+
14
+ # (If you use this, don't forget to add pry to your Gemfile!)
15
+ # require "pry"
16
+ # Pry.start
17
+
18
+ $debug = true
19
+
20
+ IRB.conf[:SAVE_HISTORY] = 1500
21
+ IRB.conf[:HISTORY_FILE] = '~/.irb-history'
22
+ IRB.conf[:ECHO] = false
23
+
24
+
25
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/cotcube-cftcsource.rb'
4
+
5
+ s = Cotcube::CftcSource.signals symbol: ARGV[0], report: ARGV[1].downcase.to_sym, human: false, count: 800, quiet: true
6
+ s.each {|x| puts x}
7
+
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'cotcube-cftcsource'
5
+ spec.version = File.read("#{__dir__}/VERSION")
6
+ spec.authors = ['Benjamin L. Tischendorf']
7
+ spec.email = ['donkeybridge@jtown.eu']
8
+
9
+ spec.summary = 'Functions to download and process COT data, aggregated into a module'
10
+ spec.description = 'Functions to download and process COT data, aggregated into a module'
11
+
12
+ spec.homepage = 'https://github.com/donkeybridge/'+ spec.name
13
+ spec.license = 'BSD-4-Clause'
14
+ spec.required_ruby_version = Gem::Requirement.new('~> 2.7')
15
+
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = spec.homepage
18
+ spec.metadata['changelog_uri'] = spec.homepage + '/CHANGELOG.md'
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+ spec.bindir = 'bin'
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_dependency 'cotcube-indicators'
30
+ spec.add_dependency 'yaml'
31
+ spec.add_dependency 'activesupport'
32
+ spec.add_dependency 'colorize'
33
+ spec.add_dependency 'httparty'
34
+ spec.add_dependency 'rubyzip'
35
+
36
+
37
+ spec.add_development_dependency 'rake'
38
+ spec.add_development_dependency 'rspec', '~>3.6'
39
+ spec.add_development_dependency 'yard', '~>0.9'
40
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # require 'bundler/setup'
4
+ # require 'rubygems/package'
5
+ require 'active_support'
6
+ require '../ci-dev/lib/cotcube-indicators'
7
+ require 'colorize'
8
+ require 'date' unless defined?(DateTime)
9
+ require 'csv' unless defined?(CSV)
10
+ require 'yaml' unless defined?(YAML)
11
+ require 'httparty'
12
+ require 'zip'
13
+
14
+
15
+ require_relative 'cotcube-cftcsource/init'
16
+ require_relative 'cotcube-cftcsource/constants'
17
+ require_relative 'cotcube-cftcsource/dates'
18
+ require_relative 'cotcube-cftcsource/fetch'
19
+ require_relative 'cotcube-cftcsource/distribute'
20
+ require_relative 'cotcube-cftcsource/provide'
21
+ require_relative 'cotcube-cftcsource/series'
22
+
23
+ private_files = Dir[__dir__ + '/cotcube-cftcsource/private/*.rb']
24
+ private_files.each do |file|
25
+ # puts 'Loading private module extension ' + file.chomp
26
+ require file.chomp
27
+ end
28
+
29
+ module Cotcube
30
+ module CftcSource
31
+ module_function :config_path, # provides the path of configuration directory
32
+ :config_prefix, # provides the prefix of the configuration directory according to OS-specific FSH
33
+ :init, # checks whether environment is prepared and returns the config hash
34
+ :symbols, # reads and provides the symbols file
35
+ :date_of_last_report, # returns the date of the currently last locally available report
36
+ :current_cot_date_on_website, # returns the date of the current report officially available on cftc.gov
37
+ :fetch, # downloads all (annual) reports, based on given year
38
+ :distribute, # distributes currently downloaded ('fetch'ed) reports to id_based directories
39
+ :available_cftc_ids, # returns a list of locally available cftc ids
40
+ :provide, # returns a series based on id (or symbol) and report / combined
41
+ :series # returns a series based on provide, after application of indicator set
42
+
43
+ # please not that module_functions of source provided in private files must be published there
44
+ end
45
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cotcube
4
+ module CftcSource
5
+
6
+ CFTC_LINKS = {
7
+ disagg: {
8
+ fut: {
9
+ current: 'https://www.cftc.gov/dea/newcot/f_disagg.txt',
10
+ hist: 'https://www.cftc.gov/files/dea/history/fut_disagg_txt_'
11
+ },
12
+ com: {
13
+ current: 'https://www.cftc.gov/dea/newcot/c_disagg.txt',
14
+ hist: 'https://www.cftc.gov/files/dea/history/com_disagg_txt_'
15
+ }
16
+ },
17
+ legacy: {
18
+ fut: {
19
+ current: 'https://www.cftc.gov/dea/newcot/deafut.txt',
20
+ hist: 'https://www.cftc.gov/files/dea/history/deacot'
21
+ },
22
+ com: {
23
+ current: 'https://www.cftc.gov/dea/newcot/deacom.txt',
24
+ hist: 'https://www.cftc.gov/files/dea/history/deahistfo'
25
+ }
26
+ },
27
+ financial: {
28
+ fut: {
29
+ current: 'https://www.cftc.gov/dea/newcot/FinFutWk.txt',
30
+ hist: 'https://www.cftc.gov/files/dea/history/fut_fin_txt_'
31
+ },
32
+ com: {
33
+ current: 'https://www.cftc.gov/dea/newcot/FinComWk.txt',
34
+ hist: 'https://www.cftc.gov/files/dea/history/com_fin_txt_'
35
+ }
36
+ },
37
+ cit: {
38
+ com: {
39
+ current: 'https://www.cftc.gov/dea/newcot/deacit.txt',
40
+ hist: 'https://www.cftc.gov/files/dea/history/dea_cit_txt_'
41
+ }
42
+ }
43
+ }.freeze
44
+
45
+ CFTC_HEADERS = {
46
+ legacy: %i[ name date date2 cftcid cftcid2 cftcid3 cftcid3] +
47
+ %i[ std_count_oi_all std_count_ncom_long std_count_ncom_short std_count_ncom_spread std_count_com_long std_count_com_short] +
48
+ %i[ std_count_rept_long std_count_rept_short std_count_nrept_long std_count_nrept_short] +
49
+ %i[ old_count_oi_all old_count_ncom_long old_count_ncom_short old_count_ncom_spread old_count_com_long old_count_com_short] +
50
+ %i[ old_count_rept_long old_count_rept_short old_count_nrept_long old_count_nrept_short] +
51
+ %i[ other_count_oi_all other_count_ncom_long other_count_ncom_short other_count_ncom_spread other_count_com_long other_count_com_short] +
52
+ %i[ other_count_rept_long other_count_rept_short other_count_nrept_long other_count_nrept_short] +
53
+ %i[ std_change_oi_all std_change_ncom_long std_change_ncom_short std_change_ncom_spread std_change_com_long std_change_com_short] +
54
+ %i[ std_change_rept_long std_change_rept_short std_change_nrept_long std_change_nrept_short] +
55
+ %i[ std_pct_oi_all std_pct_ncom_long std_pct_ncom_short std_pct_ncom_spread std_pct_com_long std_pct_com_short] +
56
+ %i[ std_pct_rept_long std_pct_rept_short std_pct_nrept_long std_pct_nrept_short] +
57
+ %i[ old_pct_oi_all old_pct_ncom_long old_pct_ncom_short old_pct_ncom_spread old_pct_com_long old_pct_com_short] +
58
+ %i[ old_pct_rept_long old_pct_rept_short old_pct_nrept_long old_pct_nrept_short] +
59
+ %i[ other_pct_oi_all other_pct_ncom_long other_pct_ncom_short other_pct_ncom_spread other_pct_com_long other_pct_com_short] +
60
+ %i[ other_pct_rept_long other_pct_rept_short other_pct_nrept_long other_pct_nrept_short] +
61
+ %i[ std_traders_oi_all std_traders_ncom_long std_traders_ncom_short std_traders_ncom_spread std_traders_com_long std_traders_com_short] +
62
+ %i[ std_traders_rept_long std_traders_rept_short] +
63
+ %i[ old_traders_oi_all old_traders_ncom_long old_traders_ncom_short old_traders_ncom_spread old_traders_com_long old_traders_com_short] +
64
+ %i[ old_traders_rept_long old_traders_rept_short] +
65
+ %i[ other_traders_oi_all other_traders_ncom_long other_traders_ncom_short other_traders_ncom_spread other_traders_com_long] +
66
+ %i[ other_traders_com_short other_traders_rept_long other_traders_rept_short] +
67
+ %i[ std_conc_gross4_long std_conc_gross4_short std_conc_gross8_long std_conc_gross8_short std_conc_net4_long std_conc_net4_short] +
68
+ %i[ std_conc_net8_long std_conc_net8_short old_conc_gross4_long old_conc_gross4_short old_conc_gross8_long old_conc_gross8_short] +
69
+ %i[ old_conc_net4_long old_conc_net4_short old_conc_net8_long old_conc_net8_short other_conc_gross4_long other_conc_gross4_short] +
70
+ %i[ other_conc_gross8_long other_conc_gross8_short other_conc_net4_long other_conc_net4_short other_conc_net8_long other_conc_net8_short] +
71
+ %i[ units CFTCContractMarketCode(Quotes) CFTCMarketCodeinInitials(Quotes) CFTCCommodityCode(Quotes) supplement],
72
+
73
+ disagg: %i[name date date2 cftcid cftcid2 cftcid3 cftcid3] +
74
+ %i[ std_count_oi_all std_count_prod_long std_count_prod_short std_count_swap_long std_count_swap_short std_count_swap_spread] +
75
+ %i[ std_count_money_long std_count_money_short std_count_money_spread std_count_other_long std_count_other_short std_count_other_spread] +
76
+ %i[ std_count_rept_long std_count_rept_short std_count_nrept_long std_count_nrept_short] +
77
+ %i[ old_count_oi_all old_count_prod_long old_count_prod_short old_count_swap_long old_count_swap_short old_count_swap_spread] +
78
+ %i[ old_count_money_long old_count_money_short old_count_money_spread old_count_other_long old_count_other_short old_count_other_spread] +
79
+ %i[ old_count_rept_long old_count_rept_short old_count_nrept_long old_count_nrept_short] +
80
+ %i[ other_count_oi_all other_count_prod_long other_count_prod_short other_count_swap_long other_count_swap_short other_count_swap_spread] +
81
+ %i[ other_count_money_long other_count_money_short other_count_money_spread other_count_other_long other_count_other_short other_count_other_spread] +
82
+ %i[ other_count_rept_long other_count_rept_short other_count_nrept_long other_count_nrept_short] +
83
+ %i[ std_change_oi_all std_change_prod_long std_change_prod_short std_change_swap_long std_change_swap_short std_change_swap_spread] +
84
+ %i[ std_change_money_long std_change_money_short std_change_money_spread std_change_other_long std_change_other_short std_change_other_spread] +
85
+ %i[ std_change_rept_long std_change_rept_short std_change_nrept_long std_change_nrept_short] +
86
+ %i[ std_pct_oi_all std_pct_prod_long std_pct_prod_short std_pct_swap_long std_pct_swap_short std_pct_swap_spread] +
87
+ %i[ std_pct_money_long std_pct_money_short std_pct_money_spread std_pct_other_long std_pct_other_short std_pct_other_spread] +
88
+ %i[ std_pct_rept_long std_pct_rept_short std_pct_nrept_long std_pct_nrept_short] +
89
+ %i[ old_pct_oi_all old_pct_prod_long old_pct_prod_short old_pct_swap_long old_pct_swap_short old_pct_swap_spread old_pct_money_long] +
90
+ %i[ old_pct_money_short old_pct_money_spread old_pct_other_long old_pct_other_short old_pct_other_spread] +
91
+ %i[ old_pct_rept_long old_pct_rept_short old_pct_nrept_long old_pct_nrept_short] +
92
+ %i[ other_pct_oi_all other_pct_prod_long other_pct_prod_short other_pct_swap_long other_pct_swap_short other_pct_swap_spread] +
93
+ %i[ other_pct_money_long other_pct_money_short other_pct_money_spread other_pct_other_long other_pct_other_short other_pct_other_spread] +
94
+ %i[ other_pct_rept_long other_pct_rept_short other_pct_nrept_long other_pct_nrept_short] +
95
+ %i[ std_traders_oi_all std_traders_prod_long std_traders_prod_short std_traders_swap_long std_traders_swap_short std_traders_swap_spread] +
96
+ %i[ std_traders_money_long std_traders_money_short std_traders_money_spread std_traders_other_long std_traders_other_short std_traders_other_spread] +
97
+ %i[ std_traders_rept_long std_traders_rept_short] +
98
+ %i[ old_traders_oi_all old_traders_prod_long old_traders_prod_short old_traders_swap_long old_traders_swap_short old_traders_swap_spread] +
99
+ %i[ old_traders_money_long old_traders_money_short old_traders_money_spread old_traders_other_long old_traders_other_short old_traders_other_spread] +
100
+ %i[ old_traders_rept_long old_traders_rept_short] +
101
+ %i[ other_traders_oi_all other_traders_prod_long other_traders_prod_short other_traders_swap_long other_traders_swap_short] +
102
+ %i[ other_traders_swap_spread other_traders_money_long other_traders_money_short other_traders_money_spread other_traders_other_long] +
103
+ %i[ other_traders_other_short other_traders_other_spread other_traders_rept_long other_traders_rept_short] +
104
+ %i[ std_conc_gross4_long std_conc_gross4_short std_conc_gross8_long std_conc_gross8_short std_conc_net4_long std_conc_net4_short std_conc_net8_long] +
105
+ %i[ std_conc_net8_short old_conc_gross4_long old_conc_gross4_short old_conc_gross8_long old_conc_gross8_short old_conc_net4_long old_conc_net4_short] +
106
+ %i[ old_conc_net8_long old_conc_net8_short other_conc_gross4_long other_conc_gross4_short other_conc_gross8_long other_conc_gross8_short] +
107
+ %i[ other_conc_net4_long other_conc_net4_short other_conc_net8_long other_conc_net8_short] +
108
+ %i[ units CFTC_Contract_Market_Code_Quotes CFTC_Market_Code_Quotes CFTC_Commodity_Code_Quotes CFTC_SubGroup_Code Fut_Combined supplement],
109
+
110
+ financial: %i[ name date date2 cftcid cftcid2 cftcid3 cftcid3] +
111
+ %i[ std_count_oi_all std_count_dealers_long std_count_dealers_short std_count_dealers_spread std_count_asset_long std_count_asset_short] +
112
+ %i[ std_count_asset_spread std_count_lev_long std_count_lev_short std_count_lev_spread std_count_other_long std_count_other_short] +
113
+ %i[ std_count_other_spread std_count_rept_long std_count_rept_short std_count_nrept_long std_count_nrept_short] +
114
+ %i[ std_change_oi_all std_change_dealers_long std_change_dealers_short std_change_dealers_spread std_change_asset_long std_change_asset_short] +
115
+ %i[ std_change_asset_spread std_change_lev_long std_change_lev_short std_change_lev_spread std_change_other_long std_change_other_short] +
116
+ %i[ std_change_other_spread std_change_rept_long std_change_rept_short std_change_nrept_long std_change_nrept_short] +
117
+ %i[ std_pct_oi_all std_pct_dealers_long std_pct_dealers_short std_pct_dealers_spread std_pct_asset_long std_pct_asset_short] +
118
+ %i[ std_pct_asset_spread std_pct_lev_long std_pct_lev_short std_pct_lev_spread std_pct_other_long std_pct_other_short] +
119
+ %i[ std_pct_other_spread std_pct_rept_long std_pct_rept_short std_pct_nrept_long std_pct_nrept_short] +
120
+ %i[ std_traders_oi_all std_traders_dealers_long std_traders_dealers_short std_traders_dealers_spread std_traders_asset_long std_traders_asset_short] +
121
+ %i[ std_traders_asset_spread std_traders_lev_long std_traders_lev_short std_traders_lev_spread std_traders_other_long std_traders_other_short std] +
122
+ %i[_traders_other_spread std_traders_rept_long std_traders_rept_short] +
123
+ %i[ std_conc_gross4_long std_conc_gross4_short std_conc_gross8_long std_conc_gross8_short std_conc_net4_long std_conc_net4_short] +
124
+ %i[ std_conc_net8_long std_conc_net8_short] +
125
+ %i[ units CFTC_Contract_Market_Code_Quotes CFTC_Market_Code_Quotes CFTC_Commodity_Code_Quotes CFTC_SubGroup_Code type supplement],
126
+
127
+
128
+ cit: %i[name date date2 cftcid cftcid2 cftcid3 cftcid3] +
129
+ %i[std_count_oi_all std_count_ncom_long std_count_ncom_short std_count_ncom_spread std_count_com_long std_count_com_short] +
130
+ %i[std_count_rept_long std_count_rept_short std_count_nrept_long std_count_nrept_short std_count_cit_long std_count_cit_short] +
131
+ %i[std_change_oi_all std_change_ncom_long std_change_ncom_short std_change_ncom_spread std_change_com_long std_change_com_short] +
132
+ %i[std_change_rept_long std_change_rept_short std_change_nrept_long std_change_nrept_short std_change_cit_long std_change_cit_short] +
133
+ %i[std_pct_oi_all std_pct_ncom_long std_pct_ncom_short std_pct_ncom_spread std_pct_com_long std_pct_com_short] +
134
+ %i[std_pct_rept_long std_pct_rept_short std_pct_nrept_long std_pct_nrept_short std_pct_cit_long std_pct_cit_short] +
135
+ %i[std_traders_oi_all std_traders_ncom_long std_traders_ncom_short std_traders_ncom_spread std_traders_com_long std_traders_com_short] +
136
+ %i[std_traders_rept_long std_traders_rept_short std_traders_cit_long std_traders_cit_short] +
137
+ %i[units supplement]
138
+ }.freeze
139
+
140
+ CFTC_SYMBOL_EXAMPLES = [
141
+ { id: "13874U", symbol: "ET", ticksize: 0.25, power: 1.25, months: "HMUZ", bcf: 1.0, reports: "LF", name: "S&P 500 MICRO" },
142
+ { id: "209747", symbol: "NM", ticksize: 0.25, power: 0.5, monhts: "HMUZ", bcf: 1.0, reports: "LF", name: "NASDAQ 100 MICRO" }
143
+ ].freeze
144
+
145
+
146
+ end
147
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cotcube
4
+ module CftcSource
5
+
6
+ # method to parse current years raw CFTC cot_files and return the latest available date
7
+ #
8
+ # @return [DateTime] DateTime object containing the date found
9
+ def date_of_last_report(config: init_config)
10
+ files = Dir["#{config[:data_path]}/raw/*#{Time.now.strftime('%Y')}.csv"]
11
+ DateTime.strptime(CSV.read(files[0]).tap { |x| x.shift if x[0][0] =~ /Market/ }.map { |x| x[2] }.max, '%Y-%m-%d') rescue nil
12
+ end
13
+
14
+ # method to extract the currently available most recent COT report from the according CFTC website
15
+ #
16
+ # @return [DateTime] a DateTime object containing the extracted date
17
+ def current_cot_date_on_website
18
+ uri = 'https://www.cftc.gov/MarketReports/CommitmentsofTraders/index.htm'
19
+ raw = HTTParty.get(uri).to_s
20
+ encoding_options = {
21
+ :invalid => :replace, # Replace invalid byte sequences
22
+ :undef => :replace, # Replace anything not defined in ASCII
23
+ :replace => '', # Use a blank for those replacements
24
+ :universal_newline => true # Always break lines with \n
25
+ }
26
+ line = raw.each_line.select{|x| x if x =~ /Reports Dated/ }[0].encode(Encoding.find('ASCII'), encoding_options)
27
+ date_string = line.split('Dated ').last.split('- Current').first
28
+ DateTime.strptime(date_string, '%B %d,%Y')
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cotcube
4
+ module CftcSource
5
+ # move expired
6
+
7
+ def move_expired_reports
8
+ Dir['/var/cotcube/cftc/cot/*'].each do |dir|
9
+ target = "/var/cotcube/cftc/expired/#{dir.split('/').last}/"
10
+ Dir["#{dir}/*.csv"].each do |file|
11
+ next unless CSV.read(file, converters: :all).last[2] < Date.today - 30
12
+
13
+ xdebug "Moving #{file} to #{target}"
14
+ `mkdir -p #{target}` unless File.exist? target
15
+ `mv #{file} #{target}`
16
+ end
17
+ if Dir["#{dir}/*"].empty?
18
+ xdebug "Removing #{dir}"
19
+ `rm -rf #{dir}`
20
+ end
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cotcube
4
+ module CftcSource
5
+
6
+ # Goes through CFTCLINKS to iterate over all types of reports
7
+ #
8
+ # @param [Hash] opts
9
+ # @option [Integer, String] Year to be processed, defaults to current year
10
+
11
+ def distribute(year: Time.now.year, debug: false, config: init)
12
+ raw_path = "#{config[:data_path]}/raw"
13
+ cot_path = "#{config[:data_path]}/cot"
14
+ CFTC_LINKS.each do |report, a|
15
+ a.each do |combined, _b|
16
+ puts ("Processing #{report}\t#{combined}\t#{year}") if debug
17
+
18
+ infile = "#{raw_path}/#{report}_#{combined}_#{year}.csv"
19
+ outfile = ->(symbol) { "#{cot_path}/#{symbol}/#{report}_#{combined}.csv" }
20
+
21
+ last_report = lambda do |symbol|
22
+ CSV.read("#{cot_path}/#{symbol}/#{report}_#{combined}.csv").last[1]
23
+ rescue StandardError
24
+ '1900-01-01'
25
+ end
26
+
27
+ cache = {}
28
+ csv_data = CSV.read(infile).tap { |lines| lines.shift if lines[0][0] =~ /Market/ }
29
+ csv_data.sort_by { |x| x[2] }.each do |line|
30
+ next if line[3].length != 6
31
+
32
+ sym = line[3]
33
+ cache[sym] ||= last_report.call(sym)
34
+ next if cache[sym] >= line[2]
35
+
36
+ line << "#{report} #{combined}"
37
+ line.map! { |x| x&.strip }
38
+ begin
39
+ CSV.open(outfile.call(sym), 'a+') { |f| f << line }
40
+ rescue StandardError
41
+ puts ("Found new id: #{sym}").colorize(:light_green)
42
+ `mkdir #{cot_path}/#{sym}`
43
+ CSV.open(outfile.call(sym), 'a+') { |f| f << line }
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ # print list
51
+
52
+ def available_cftc_ids(config: init, print: true, sort: :exchange)
53
+ result = CSV.parse(`find #{init[:data_path]}/cot/* | grep legacy | xargs head -n1 | grep , | awk -v FS=, -v OFS=, '{print $5,$4,$1}' | sed 's/"//g' | sort | uniq`.chomp, headers: %i{ exchange id name }).map{|x| x.to_h}
54
+ result = result.uniq{|row| row[:id] }
55
+ if print
56
+ result.sort_by{|x| x[sort]}.each {|row| puts "#{row[:exchange]}\t#{row[:id]}\t#{row[:name]}" }
57
+ end
58
+ result
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cotcube
4
+ module CftcSource
5
+
6
+
7
+ # method to download all available historical cot report files
8
+ #
9
+ # @param [Integer, String] year
10
+ # @param [Boolean] debug
11
+ # @param [Hash] config
12
+ def fetch(year: Time.now.year, debug: false, silent: false, config: init)
13
+
14
+ CFTC_LINKS.each do |report, a|
15
+ a.each do |combined, _b|
16
+ puts ("====> working on #{report}\t#{combined}") if debug
17
+ raw_dir = "#{config[:data_path]}/raw"
18
+
19
+ uri = "#{CFTC_LINKS[report][combined][:hist]}#{year}.zip"
20
+ file_data = nil
21
+ input = HTTParty.get(uri).body
22
+ Zip::InputStream.open(StringIO.new(input)) do |io|
23
+ while entry = io.get_next_entry
24
+ file_data = io.read
25
+ end
26
+ end
27
+ file = "#{raw_dir}/#{report}_#{combined}_#{year}.csv"
28
+ File.write(file, file_data)
29
+
30
+ puts "Contents have been written to '#{file}'." if debug
31
+ print "Check whether current date for #{report}_#{combined}_#{year} makes sense: " unless silent
32
+ puts `head -n2 #{file} | tail -n1 | cut -d, -f1,3`.chomp.light_white unless silent
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cotcube
4
+ module CftcSource
5
+
6
+
7
+ def symbols(config: init)
8
+ if config[:symbols_file].nil?
9
+ CFTC_SYMBOL_EXAMPLES
10
+ else
11
+ CSV
12
+ .read(config[:symbols_file], headers: %i{ id symbol ticksize power months type bcf reports name})
13
+ .map{|row| row.to_h }
14
+ .map{|row| [ :ticksize, :power, :bcf ].each {|z| row[z] = row[z].to_f}; row }
15
+ .reject{|row| row[:id].nil? }
16
+ end
17
+ end
18
+
19
+ def config_prefix
20
+ os = Gem::Platform.local.os
21
+ case os
22
+ when 'linux'
23
+ ''
24
+ when 'freebsd'
25
+ '/usr/local'
26
+ else
27
+ raise RuntimeError, 'unknown architecture'
28
+ end
29
+ end
30
+
31
+ def config_path
32
+ config_prefix + '/etc/cotcube'
33
+ end
34
+
35
+ def init(config_file_name: 'cftcsource.yml', debug: false)
36
+ name = 'cftcsource'
37
+ config_file = config_path + "/#{config_file_name}"
38
+
39
+ if File.exist?(config_file)
40
+ config = YAML.load(File.read config_file).transform_keys(&:to_sym)
41
+ else
42
+ config = {}
43
+ end
44
+
45
+ defaults = {
46
+ data_path: config_prefix + '/var/cotcube/' + name,
47
+ }
48
+
49
+
50
+ config = defaults.merge(config)
51
+
52
+
53
+ # part 2 of init process: Prepare directories
54
+
55
+ save_create_directory = lambda do |directory_name|
56
+ unless Dir.exist?(directory_name)
57
+ begin
58
+ `mkdir -p #{directory_name}`
59
+ unless $?.exitstatus.zero?
60
+ puts "Missing permissions to create or access '#{directory_name}', please clarify manually"
61
+ exit 1 unless defined?(IRB)
62
+ end
63
+ rescue
64
+ puts "Missing permissions to create or access '#{directory_name}', please clarify manually"
65
+ exit 1 unless defined?(IRB)
66
+ end
67
+ end
68
+ end
69
+ ['','raw','cot','series'].each do |path|
70
+ dir = "#{config[:data_path]}#{path == '' ? '' : '/'}#{path}"
71
+ save_create_directory.call(dir)
72
+ end
73
+
74
+ # eventually return config
75
+ config
76
+ end
77
+
78
+ end
79
+ end
80
+
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cotcube
4
+ module CftcSource
5
+ def provide(symbol: nil, # The barchart symbol of the contract
6
+ id: nil, # The CFTC ID of the contract
7
+ report: :legacy, # report type (legacy, disagg, financial, cit)
8
+ combined: :com, # combined of fut_only
9
+ after: '1900-01-01', # start at given date
10
+ subset: true, # set to false to return full data
11
+ measure: false,
12
+ config: init, #
13
+ debug: false) #
14
+
15
+ after = DateTime.strptime(after, '%Y-%m-%d') if after.is_a? String
16
+
17
+ unless symbol.nil?
18
+ symbol_id = symbols.select{|s| s[:symbol] == symbol.to_s.upcase}.first[:id]
19
+ raise ArgumentError, "Could not find match in #{config[:symbols_file]} for given symbol #{symbol}" if symbol_id.nil?
20
+ raise ArgumentError, "Mismatching symbol #{symbol} and given id #{id}" if not id.nil? and symbol_id != id
21
+ id = symbol_id
22
+ end
23
+ raise ArgumentError, "Need either :symbol or :id as parameter" if id.nil?
24
+
25
+ id_path = "#{config[:data_path]}/cot/#{id}"
26
+ data_file = "#{id_path}/#{report}_#{combined}.csv"
27
+
28
+ raise RuntimeError, "No data found for requested :id (#{id_path} does not exist)" unless Dir.exist?(id_path)
29
+ raise RuntimeError, "No data found for requested :report (#{report} #{combined} in #{id_path}" unless File.exist?(data_file)
30
+
31
+ puts "#{Time.now - measure}: PROVIDE: before CSV parse" if measure
32
+ raw = `cat #{data_file} | sed -e 's/\r//'`
33
+ data = CSV.parse(raw, row_sep: :auto, converters: :all, headers: CFTC_HEADERS[report]).map do |row|
34
+ d = row.to_h
35
+ d[:date] = d[:date2].strftime('%Y-%m-%d')
36
+ d
37
+ end
38
+ puts "#{Time.now - measure}: PROVIDE: after CSV parse" if measure
39
+ data.select! { |x| x[:date2] > after } if after
40
+ data.sort! { |x| x[:date2] }.uniq!{ |x| x[:date2] }
41
+ data.reverse!
42
+
43
+ if subset
44
+ data.map do |dataset|
45
+ dataset.map do |key,value|
46
+ dataset.delete(key) if key.to_s =~ (/_traders_/) ||
47
+ key.to_s =~ (/_pct_/) || key.to_s =~ (/_conc_/) ||
48
+ key.to_s =~ (/^other_/) || key.to_s =~ (/^old_/) || key.to_s =~ (/_change_/) ||
49
+ [ :units, :"CFTCContractMarketCode(Quotes)", :"CFTCMarketCodeinInitials(Quotes)",
50
+ :"CFTCCommodityCode(Quotes)", :name, :cftcid3, :date2 ].include?(key)
51
+ end
52
+ end
53
+ end
54
+ puts "#{Time.now - measure}: PROVIDE: after subset application, returning " if measure
55
+
56
+ data
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cotcube
4
+ module CftcSource
5
+
6
+ # - there will be configfile, containing the indicators
7
+ # a call hence
8
+ # 1. will try to load from the series directory
9
+ # 2. will try to update the series already loaded (or starting from empty)
10
+ # 3. provides the series (containing only the lookback period requested)\q
11
+ #
12
+ def series(symbol: nil,
13
+ report: :legacy,
14
+ combined: :com,
15
+ config: init,
16
+ after: '1900-01-01',
17
+ lookback: nil,
18
+ set: nil,
19
+ force: false,
20
+ measure: false,
21
+ debug: false
22
+ )
23
+ raise ArgumentError, "Can only build series with given symbol" if symbol.nil?
24
+ symbol_config = symbols.select{|s| s[:symbol] == symbol.to_s.upcase }.first
25
+ raise ArgumentError, "Can only build series with known symbol, '#{symbol}' is unknown." if symbol_config.nil?
26
+ puts "Using symbol_config '#{symbol_config}'" if debug
27
+
28
+ lookback = config[:default_lookback] if lookback.nil?
29
+ raise ArgumentError, "Lookback may not be nil, either provide option or set :default_lookback in configfile" if lookback.nil?
30
+
31
+ set = config[:default_set] if set.nil?
32
+ set = 'default' if set.nil?
33
+
34
+ series_dir = "#{config[:data_path]}/series/#{symbol}"
35
+ series_file = "#{series_dir}/#{report}_#{combined}_#{set}_#{lookback}.csv"
36
+ puts "Guessing series_file '#{series_file}'" if debug
37
+
38
+ `mkdir -p #{series_dir}` unless Dir.exist?(series_dir)
39
+
40
+ header_keys = CFTC_HEADERS[report]
41
+ .select { |key| key.to_s =~ /std_count/ }
42
+ .group_by { |key| key.to_s.split('_')[2] }
43
+ .keys
44
+ .tap { |k| k.delete('oi') }
45
+
46
+ puts "Using header_keys '#{header_keys}'" if debug
47
+
48
+
49
+ if set == 'default' or set.nil?
50
+ # load default indicatorset
51
+ indicators = {}
52
+ prefix = "std_count"
53
+ header_keys.map do |key|
54
+ indicators["#{prefix}_#{key}_net"] = Cotcube::Indicators.calc(a: "#{prefix}_#{key}_long", b: "#{prefix}_#{key}_short"){|a,b| a - b }
55
+ end
56
+ else
57
+ # load custom indicatorset
58
+ indicators_file = "#{config_path}/indicators-#{set}.rb"
59
+ raise ArgumentError, "Indicatorsfile #{indicators_file} does not exist" unless File.exist? indicators_file
60
+ load indicators_file
61
+ indicators = Cotcube::Indicators.build(lookback: lookback, keys: header_keys)
62
+ end
63
+
64
+ if File.exist?(series_file) and (Time.now - File.stat(series_file).mtime).to_i / 86400.0 < 5.0 and not force and not config[:always_force]
65
+ headers_file = "#{config[:headers_path]}/#{report}_#{combined}.json"
66
+ if File.exist? headers_file
67
+ provide_headers = JSON.parse(File.read(headers_file)).map{|x| x.to_sym}
68
+ else
69
+ provide_headers = (Cotcube::CftcSource.provide symbol: symbol, report: report, combined: combined, after: (Time.now - 20 * 86000).strftime("%Y-%m-%d")).first.keys
70
+ File.open(headers_file, 'w'){|f| f << provide_headers.to_json }
71
+ end
72
+ headers = provide_headers + indicators.keys
73
+ puts 'Returning saved data' if debug
74
+ puts "#{Time.now - measure}: SERIES: returning series from file" if measure
75
+
76
+ return CSV.read(series_file, headers: headers, converters: :all).map(&:to_h)
77
+ end
78
+
79
+ puts "#{Time.now - measure}: SERIES: before source" if measure
80
+
81
+ source = provide(symbol: symbol, report: report, combined: combined, config: config, after: after, measure: measure)
82
+
83
+ puts "#{Time.now - measure}: SERIES: after source" if measure
84
+
85
+ puts "First source: #{source.first}" if debug
86
+ puts "#{config}" if debug
87
+
88
+ source.each do |dataset|
89
+ indicators.each do |key, lambada|
90
+ dataset[key] = lambada.call(dataset)
91
+ end
92
+ end
93
+ CSV.open(series_file, 'w') { |csv| source.map{|x| csv << x.values } }
94
+
95
+ puts "#{Time.now - measure}: SERIES: returning series from source" if measure
96
+ source
97
+
98
+ end
99
+ end
100
+ end
metadata ADDED
@@ -0,0 +1,193 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cotcube-cftcsource
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Benjamin L. Tischendorf
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-12-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cotcube-indicators
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: yaml
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: colorize
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: httparty
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubyzip
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.6'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.6'
125
+ - !ruby/object:Gem::Dependency
126
+ name: yard
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.9'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.9'
139
+ description: Functions to download and process COT data, aggregated into a module
140
+ email:
141
+ - donkeybridge@jtown.eu
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".irbrc.rb"
147
+ - ".rspec"
148
+ - CHANGELOG.md
149
+ - Gemfile
150
+ - LICENSE.txt
151
+ - README.md
152
+ - Rakefile
153
+ - VERSION
154
+ - bin/console
155
+ - bin/setup
156
+ - bin/signals.rb
157
+ - cotcube-cftcsource.gemspec
158
+ - lib/cotcube-cftcsource.rb
159
+ - lib/cotcube-cftcsource/constants.rb
160
+ - lib/cotcube-cftcsource/dates.rb
161
+ - lib/cotcube-cftcsource/decommission.rb
162
+ - lib/cotcube-cftcsource/distribute.rb
163
+ - lib/cotcube-cftcsource/fetch.rb
164
+ - lib/cotcube-cftcsource/init.rb
165
+ - lib/cotcube-cftcsource/provide.rb
166
+ - lib/cotcube-cftcsource/series.rb
167
+ homepage: https://github.com/donkeybridge/cotcube-cftcsource
168
+ licenses:
169
+ - BSD-4-Clause
170
+ metadata:
171
+ homepage_uri: https://github.com/donkeybridge/cotcube-cftcsource
172
+ source_code_uri: https://github.com/donkeybridge/cotcube-cftcsource
173
+ changelog_uri: https://github.com/donkeybridge/cotcube-cftcsource/CHANGELOG.md
174
+ post_install_message:
175
+ rdoc_options: []
176
+ require_paths:
177
+ - lib
178
+ required_ruby_version: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - "~>"
181
+ - !ruby/object:Gem::Version
182
+ version: '2.7'
183
+ required_rubygems_version: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ requirements: []
189
+ rubygems_version: 3.1.2
190
+ signing_key:
191
+ specification_version: 4
192
+ summary: Functions to download and process COT data, aggregated into a module
193
+ test_files: []