thirteen_f 0.2.1 → 0.2.2
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +15 -3
- data/README.md +4 -2
- data/lib/thirteen_f/company.rb +11 -0
- data/lib/thirteen_f/cusip_securities.rb +96 -0
- data/lib/thirteen_f/position.rb +12 -2
- data/lib/thirteen_f/version.rb +1 -1
- data/lib/thirteen_f.rb +1 -0
- data/thirteen_f.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2055d576a8a4c7d6328c15325eb1a34b02c7c390346ef9111b6aa82387f88a37
|
4
|
+
data.tar.gz: 60571d9e9ca221b80596453fab70fa284e841cc9e64e516bb616503c484c182d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5944c92f5e8ed3e0daa1cacd1089774f7eb5b26d134de33ae17f1e3b6a006d06ae616209d3c91b92ddc7d3789e5ed85d18382ae3765bc186ae6d41c3a7637fe
|
7
|
+
data.tar.gz: c4c9ebf3bfc18ef017004c286ff2b99e013f448873e4bd10ba60082a7911d737ca4a8cad267b2ebab0dfb575cde3de0c500038e277f24022012e05ba81301134
|
data/Gemfile.lock
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
thirteen_f (0.
|
4
|
+
thirteen_f (0.2.2)
|
5
5
|
http (>= 4.4)
|
6
6
|
nokogiri
|
7
|
+
pdf-reader
|
7
8
|
|
8
9
|
GEM
|
9
10
|
remote: https://rubygems.org/
|
10
11
|
specs:
|
12
|
+
Ascii85 (1.0.3)
|
11
13
|
addressable (2.7.0)
|
12
14
|
public_suffix (>= 2.0.2, < 5.0)
|
15
|
+
afm (0.2.2)
|
13
16
|
coderay (1.1.2)
|
14
17
|
domain_name (0.5.20190701)
|
15
18
|
unf (>= 0.0.5, < 1.0.0)
|
@@ -17,7 +20,8 @@ GEM
|
|
17
20
|
ffi-compiler (1.0.1)
|
18
21
|
ffi (>= 1.0.0)
|
19
22
|
rake
|
20
|
-
|
23
|
+
hashery (2.1.2)
|
24
|
+
http (4.4.1)
|
21
25
|
addressable (~> 2.3)
|
22
26
|
http-cookie (~> 1.0)
|
23
27
|
http-form_data (~> 2.2)
|
@@ -32,14 +36,22 @@ GEM
|
|
32
36
|
minitest (5.14.0)
|
33
37
|
nokogiri (1.10.9)
|
34
38
|
mini_portile2 (~> 2.4.0)
|
39
|
+
pdf-reader (2.4.0)
|
40
|
+
Ascii85 (~> 1.0.0)
|
41
|
+
afm (~> 0.2.1)
|
42
|
+
hashery (~> 2.0)
|
43
|
+
ruby-rc4
|
44
|
+
ttfunk
|
35
45
|
pry (0.13.0)
|
36
46
|
coderay (~> 1.1)
|
37
47
|
method_source (~> 1.0)
|
38
48
|
public_suffix (4.0.3)
|
39
49
|
rake (12.3.3)
|
50
|
+
ruby-rc4 (0.1.5)
|
51
|
+
ttfunk (1.6.2.1)
|
40
52
|
unf (0.1.4)
|
41
53
|
unf_ext
|
42
|
-
unf_ext (0.0.7.
|
54
|
+
unf_ext (0.0.7.7)
|
43
55
|
|
44
56
|
PLATFORMS
|
45
57
|
ruby
|
data/README.md
CHANGED
@@ -39,7 +39,6 @@ Or install it yourself as:
|
|
39
39
|
|
40
40
|
```ruby
|
41
41
|
search = ThirteenF::Search.new('Berkshire Hathaway')
|
42
|
-
search = ThirteenF::Search.new('BERKSHIRE HATHAWAY INC')
|
43
42
|
search.get_companies
|
44
43
|
search.companies
|
45
44
|
```
|
@@ -51,7 +50,7 @@ company = search.companies.first
|
|
51
50
|
company.get_filings # grabs 10 13F filings by default which is the minimum
|
52
51
|
company.get_filings(count: 20) # can supply an optional count keyword arg to get more filings
|
53
52
|
company.get_most_recent_holdings
|
54
|
-
company.most_recent_holdings # returns positions from
|
53
|
+
company.most_recent_holdings # returns positions from the most recent 13F filing
|
55
54
|
|
56
55
|
company.cik # type: String | ex: "0001067983"
|
57
56
|
company.name # type: String | ex: "BERKSHIRE HATHAWAY INC"
|
@@ -80,6 +79,9 @@ filing.cover_page_html_url # String or nil
|
|
80
79
|
### Positions
|
81
80
|
|
82
81
|
```ruby
|
82
|
+
xml_url = 'https://www.sec.gov/Archives/edgar/data/1061768/000156761920003359/form13fInfoTable.xml'
|
83
|
+
positions = Position.from_xml_url(xml_url)
|
84
|
+
|
83
85
|
position = filing.positions.first
|
84
86
|
position.filing
|
85
87
|
|
data/lib/thirteen_f/company.rb
CHANGED
@@ -27,6 +27,13 @@ class ThirteenF
|
|
27
27
|
Array.new 1, new(cik, name, state_or_country)
|
28
28
|
end
|
29
29
|
|
30
|
+
def self.from_cik(cik)
|
31
|
+
response = HTTP.get sec_url_from_cik(cik)
|
32
|
+
return false unless response.status == 200
|
33
|
+
page = Nokogiri::HTML response.to_s
|
34
|
+
from_company_page page
|
35
|
+
end
|
36
|
+
|
30
37
|
def initialize(cik, name, state_or_country)
|
31
38
|
@cik = cik
|
32
39
|
@name = name
|
@@ -55,6 +62,10 @@ class ThirteenF
|
|
55
62
|
"#{sec_filings_page_url}&type=13f&count=#{count}"
|
56
63
|
end
|
57
64
|
|
65
|
+
def self.sec_url_from_cik(cik)
|
66
|
+
"#{BASE_URL}/cgi-bin/browse-edgar?CIK=#{cik}"
|
67
|
+
end
|
68
|
+
|
58
69
|
private
|
59
70
|
def self.parse_name(name_cell)
|
60
71
|
name_cell.text.split("\n").first
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'http'
|
4
|
+
require 'date'
|
5
|
+
require 'open-uri'
|
6
|
+
require 'pdf-reader'
|
7
|
+
|
8
|
+
class ThirteenF
|
9
|
+
class CusipSecurities
|
10
|
+
attr_reader :file_name, :file_location, :quarter, :period_end, :list_entries
|
11
|
+
BASE_URL = 'https://www.sec.gov'
|
12
|
+
|
13
|
+
def self.all_file_locations
|
14
|
+
index_url = "#{BASE_URL}/divisions/investment/13flists.htm"
|
15
|
+
response = HTTP.get index_url
|
16
|
+
return false unless response.status == 200
|
17
|
+
page = Nokogiri::HTML response.to_s
|
18
|
+
a_tags = page.search('a').select do |a_tag|
|
19
|
+
href = a_tag.attributes['href']&.value.to_s
|
20
|
+
href.include?('13flist') && href.include?('.pdf')
|
21
|
+
end
|
22
|
+
a_tags.map { |a_tag|"#{BASE_URL + a_tag.attributes['href'].value}" }
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.most_recent_list
|
26
|
+
index_url = "#{BASE_URL}/divisions/investment/13flists.htm"
|
27
|
+
response = HTTP.get index_url
|
28
|
+
return false unless response.status == 200
|
29
|
+
page = Nokogiri::HTML response.to_s
|
30
|
+
a_tag = page.search('a').find { |a| a.text.include?('Current List') }
|
31
|
+
file_location = "#{BASE_URL + a_tag.attributes['href'].value}"
|
32
|
+
new file_location
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(file_location)
|
36
|
+
@file_location = file_location
|
37
|
+
@file_name = file_location.split('/').last
|
38
|
+
@quarter = set_quarter_string file_name
|
39
|
+
@period_end = set_period_end file_name
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_list_entries
|
44
|
+
return false unless file_location
|
45
|
+
io = URI.open file_location
|
46
|
+
reader = PDF::Reader.new io
|
47
|
+
valid_entries = []
|
48
|
+
reader.pages[2..-1].each do |page|
|
49
|
+
lines = page.text.split("\n").reject(&:empty?)[3..-1]
|
50
|
+
line_arrs = lines.map do |line|
|
51
|
+
next nil if line.include?('Total Count')
|
52
|
+
line.split(' ').reject(&:empty?).map(&:strip).reject { |text| text == '*' }
|
53
|
+
end
|
54
|
+
line_arrs.compact.each do |line_arr|
|
55
|
+
valid_entries.push ListEntry.new(line_arr)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
@list_entries = valid_entries
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
class ListEntry
|
63
|
+
attr_reader :cusip_number, :issuer_name, :issuer_description, :status
|
64
|
+
|
65
|
+
def initialize(line_arr)
|
66
|
+
@cusip_number = line_arr[0].delete(' ')
|
67
|
+
@issuer_name = line_arr[1].delete('*').strip
|
68
|
+
@issuer_description = line_arr[2]
|
69
|
+
@status = line_arr[3] || 'N/A'
|
70
|
+
true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
def set_quarter_string(file_name)
|
76
|
+
arr = file_name.sub('13flist', '').delete('.pdf').split('q')
|
77
|
+
case arr[1].to_i
|
78
|
+
when 1 then "1st Quarter #{arr[0]}"
|
79
|
+
when 2 then "2nd Quarter #{arr[0]}"
|
80
|
+
when 3 then "3rd Quarter #{arr[0]}"
|
81
|
+
when 4 then "4th Quarter #{arr[0]}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def set_period_end(file_name)
|
86
|
+
arr = file_name.sub('13flist', '').delete('.pdf').split('q')
|
87
|
+
case arr[1].to_i
|
88
|
+
when 1 then Date.parse("#{arr[0]}-03-31")
|
89
|
+
when 2 then Date.parse("#{arr[0]}-06-30")
|
90
|
+
when 3 then Date.parse("#{arr[0]}-09-30")
|
91
|
+
when 4 then Date.parse("#{arr[0]}-12-31")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
data/lib/thirteen_f/position.rb
CHANGED
@@ -13,13 +13,23 @@ class ThirteenF
|
|
13
13
|
response = HTTP.get filing.table_xml_url
|
14
14
|
xml_doc = Nokogiri::XML response.to_s
|
15
15
|
xml_doc.search('infoTable').map do |info_table|
|
16
|
-
position = new filing
|
16
|
+
position = new filing: filing
|
17
17
|
position.attributes_from_info_table(info_table)
|
18
18
|
position
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
22
|
+
def self.from_xml_url(table_xml_url)
|
23
|
+
response = HTTP.get table_xml_url
|
24
|
+
xml_doc = Nokogiri::XML response.to_s
|
25
|
+
xml_doc.search('infoTable').map do |info_table|
|
26
|
+
position = new
|
27
|
+
position.attributes_from_info_table(info_table)
|
28
|
+
position
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(filing: nil)
|
23
33
|
@filing = filing
|
24
34
|
end
|
25
35
|
|
data/lib/thirteen_f/version.rb
CHANGED
data/lib/thirteen_f.rb
CHANGED
data/thirteen_f.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thirteen_f
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fordfischer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pdf-reader
|
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'
|
69
83
|
description: |-
|
70
84
|
thirteen_f lets you easily search and retrieve SEC 13F
|
71
85
|
filing data. The SEC is the U.S. Securities and Exchange Commission. 13F
|
@@ -90,6 +104,7 @@ files:
|
|
90
104
|
- bin/setup
|
91
105
|
- lib/thirteen_f.rb
|
92
106
|
- lib/thirteen_f/company.rb
|
107
|
+
- lib/thirteen_f/cusip_securities.rb
|
93
108
|
- lib/thirteen_f/filing.rb
|
94
109
|
- lib/thirteen_f/position.rb
|
95
110
|
- lib/thirteen_f/search.rb
|