securities 0.0.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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 1.9.2
4
+ - jruby
5
+ - rbx
6
+ script: "bundle exec rake"
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in securities.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Nedomas
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # Securities
2
+
3
+ [![Build Status](https://secure.travis-ci.org/Nedomas/securities.png)](http://travis-ci.org/Nedomas/securities)
4
+
5
+ Financial information scraper gem.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'securities'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install securities
20
+
21
+ ## Usage
22
+
23
+ You can get stock information with commands:
24
+
25
+ my_stocks = Securities::Stock.new('aapl', 'yhoo').history(:start_date => '2012-01-01', :end_date => '2012-02-01', :periods => :weekly)
26
+ Optional parameter :periods accepts :daily, :weekly, :monthly, :dividend. If not specified, it defaults to :daily.
27
+
28
+ You can access hash for a single stock with:
29
+
30
+ my_stocks.results["yhoo"]
31
+
32
+ Results are returned in a hash:
33
+
34
+ {"aapl"=>[{:date=>"2012-01-04", :open=>"410.00", :high=>"414.68", :low=>"409.28", :close=>"413.44", :volume=>"9286500", :adj_close=>"411.67"}, {:date=>"2012-01-03", :open=>"409.40", :high=>"412.50", :low=>"409.00", :close=>"411.23", :volume=>"10793600", :adj_close=>"409.47"}],
35
+ "yhoo"=>[{:date=>"2012-01-04", :open=>"16.12", :high=>"16.16", :low=>"15.74", :close=>"15.78", :volume=>"35655300", :adj_close=>"15.78"}, {:date=>"2012-01-03", :open=>"16.27", :high=>"16.39", :low=>"16.20", :close=>"16.29", :volume=>"19708600", :adj_close=>"16.29"}]}
36
+
37
+ ## To do:
38
+
39
+ * Write specs.
40
+ * Add quote info (P/E, P/S, etc.)
41
+ * Add symbol from name lookup.
42
+ * Add options support.
43
+ * Add technical analysis module (or a seperate gem which works in synergy with this).
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new
6
+ task :default => :spec
@@ -0,0 +1,52 @@
1
+ require 'active_support/core_ext'
2
+ require 'uri'
3
+ require 'net/http'
4
+ require 'csv'
5
+
6
+ module Securities
7
+ #
8
+ # Main class to communicate with Yahoo! Finance
9
+ #
10
+ class Scraper
11
+
12
+ attr_reader :results
13
+ # Error handling
14
+ class ScraperException < StandardError
15
+ end
16
+
17
+ def initialize type, parameters
18
+ @results = Hash.new
19
+
20
+ # Manage different type requests.
21
+ case type
22
+ when :history then @results = scrape_history(parameters)
23
+ else raise ScraperException, 'Cannot determine request type.'
24
+ end
25
+ end
26
+
27
+ def scrape_history parameters
28
+ parameters.each do |symbol, url|
29
+
30
+ uri = URI.parse(url)
31
+
32
+ # Check connection
33
+ begin
34
+ get = Net::HTTP.get(uri)
35
+ rescue => error
36
+ raise ScraperException, "Connection error: #{error.message}"
37
+ end
38
+
39
+ # Skip first line because it contains headers with Date,Open,High,Low,Close,Volume,Adj Close
40
+ csv = CSV.parse(get, :headers => true)
41
+
42
+ data = Array.new
43
+ csv.each_with_index {|row, index|
44
+ data[index] = {:date => row[0], :open => row[1], :high => row[2], :low => row[3], :close => row[4], :volume => row[5], :adj_close => row[6]}
45
+ }
46
+ @results[symbol] = data
47
+ end
48
+ return @results
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,147 @@
1
+ module Securities
2
+
3
+ # Usage: my_stocks = Securities::Stock.new('aapl', 'yhoo').history(:start_date => '2012-01-01', :end_date => '2012-02-01', :periods => :weekly)
4
+ # :periods accepts :daily, :weekly, :monthly, :dividend. If not specified, it defaults to :daily.
5
+ #
6
+ # You can access hash for a single stock with:
7
+ # my_stocks.results["yhoo"]
8
+
9
+ class Stock
10
+
11
+ attr_reader :symbols
12
+ # REGEX for YYYY-MM-DD
13
+ DATE_REGEX = /^[0-9]{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])/
14
+ PERIODS_ARRAY = [:daily, :weekly, :montly, :dividends]
15
+
16
+ # Error handling
17
+ class StockException < StandardError
18
+ end
19
+
20
+ def initialize *parameters
21
+ validate_symbols(parameters)
22
+ end
23
+
24
+ def history parameters
25
+ type = :history
26
+ parameters[:symbols] = @symbols
27
+ validate_history(parameters)
28
+ urls = generate_history_url(parameters)
29
+ Securities::Scraper.new(type, urls)
30
+ end
31
+
32
+ private
33
+
34
+ # History URL generator
35
+ #
36
+ # Generating URL for various types of requests within stocks.
37
+ #
38
+ # Using Yahoo Finance
39
+ # http://ichart.finance.yahoo.com/table.csv?s=%s&a=%s&b=%s&c=%s&d=%s&e=%s&f=%s&g=%s&ignore=.csv
40
+ #
41
+ # s = ticker symbol.
42
+ #
43
+ # Start date
44
+ # a = start_month
45
+ # b = start_day
46
+ # c = start_year
47
+ #
48
+ # End date
49
+ # d = end_month
50
+ # e = end_day
51
+ # f = end_year
52
+ #
53
+ # g = :periods
54
+ # Possible values are 'd' for daily (the default), 'w' for weekly, 'm' for monthly and 'v' for dividends.
55
+
56
+ def generate_history_url parameters
57
+
58
+ start_date = parameters[:start_date].to_date
59
+ end_date = parameters[:end_date].to_date
60
+
61
+ periods = case parameters[:periods]
62
+ when :daily then 'd'
63
+ when :weekly then 'w'
64
+ when :monthly then 'm'
65
+ when :dividends then 'v'
66
+ end
67
+
68
+ results = Hash.new
69
+ @symbols.each do |symbol|
70
+ url = 'http://ichart.finance.yahoo.com/table.csv?s=%s&a=%s&b=%s&c=%s&d=%s&e=%s&f=%s&g=%s&ignore=.csv' % [
71
+ symbol,
72
+ start_date.month - 1,
73
+ start_date.day,
74
+ start_date.year,
75
+ end_date.month - 1,
76
+ end_date.day,
77
+ end_date.year,
78
+ periods
79
+ ]
80
+ results[symbol] = url
81
+ end
82
+
83
+ # Returns a hash {'symbol' => 'url'}
84
+ return results
85
+ end
86
+
87
+ #
88
+ # Input parameters validation
89
+ #
90
+ def validate_symbols parameters
91
+ # Reject empty symbol hashes.
92
+ @symbols = parameters.reject(&:empty?)
93
+
94
+ unless !@symbols.empty?
95
+ raise StockException, 'You must specify stock symbols.'
96
+ end
97
+
98
+ unless @symbols.uniq.length == @symbols.length
99
+ raise StockException, 'Duplicate symbols given.'
100
+ end
101
+ end
102
+
103
+ def validate_history parameters
104
+ unless parameters.is_a?(Hash)
105
+ raise StockException, 'Given parameters have to be a hash.'
106
+ end
107
+
108
+ unless parameters.has_keys?(:start_date, :end_date)
109
+ raise StockException, 'You must specify :start_date and :end_date.'
110
+ end
111
+
112
+ unless DATE_REGEX.match(parameters[:start_date])
113
+ raise StockException, 'Invalid :start_date specified. Format YYYY-MM-DD.'
114
+ end
115
+
116
+ unless DATE_REGEX.match(parameters[:end_date])
117
+ raise StockException, 'Invalid :end_date specified. Format YYYY-MM-DD.'
118
+ end
119
+
120
+ unless parameters[:start_date].to_date < parameters[:end_date].to_date
121
+ raise StockException, ':end_date must be greater than the :start_date.'
122
+ end
123
+
124
+ unless parameters[:start_date].to_date < Date.today
125
+ raise StockException, ':start_date must not be in the future.'
126
+ end
127
+
128
+ # Set to default :periods if key isn't specified.
129
+ parameters[:periods] = :daily if !parameters.has_key?(:periods)
130
+
131
+ unless PERIODS_ARRAY.include?(parameters[:periods])
132
+ raise StockException, 'Invalid :periods value specified.'
133
+ end
134
+ end
135
+
136
+ end
137
+ end
138
+
139
+ #
140
+ # The missing hash function
141
+ # Returns true if all keys are present in hash.
142
+ #
143
+ class Hash
144
+ def has_keys?(*_keys)
145
+ (_keys - self.keys).empty?
146
+ end
147
+ end
@@ -0,0 +1,3 @@
1
+ module Securities
2
+ VERSION = "0.0.1"
3
+ end
data/lib/securities.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "securities/version"
2
+ require "securities/scraper"
3
+ require "securities/stock"
4
+
5
+ module Securities
6
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/securities/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Nedomas"]
6
+ gem.email = ["domas.bitvinskas@me.com"]
7
+ gem.description = %q{Financial information scraper and a technical analysis tool.}
8
+ gem.summary = %q{Financial information scraper and a technical analysis tool.}
9
+ gem.homepage = "https://github.com/Nedomas/securities"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "securities"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Securities::VERSION
17
+
18
+ gem.add_dependency 'rails'
19
+ gem.add_development_dependency 'rspec'
20
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Securities do
4
+ it 'requires tests'
5
+ end
@@ -0,0 +1,20 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ $:.unshift File.dirname(__FILE__) + '/../lib'
8
+ require 'securities'
9
+
10
+ RSpec.configure do |config|
11
+ config.treat_symbols_as_metadata_keys_with_true_values = true
12
+ config.run_all_when_everything_filtered = true
13
+ config.filter_run :focus
14
+
15
+ # Run specs in random order to surface order dependencies. If you find an
16
+ # order dependency and want to debug it, you can fix the order by providing
17
+ # the seed, which is printed after each run.
18
+ # --seed 1234
19
+ config.order = 'random'
20
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: securities
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nedomas
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Financial information scraper and a technical analysis tool.
47
+ email:
48
+ - domas.bitvinskas@me.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - .rspec
55
+ - .travis.yml
56
+ - Gemfile
57
+ - LICENSE
58
+ - README.md
59
+ - Rakefile
60
+ - lib/securities.rb
61
+ - lib/securities/scraper.rb
62
+ - lib/securities/stock.rb
63
+ - lib/securities/version.rb
64
+ - securities.gemspec
65
+ - spec/securities_spec.rb
66
+ - spec/spec_helper.rb
67
+ homepage: https://github.com/Nedomas/securities
68
+ licenses: []
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ segments:
80
+ - 0
81
+ hash: -407219618759612130
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ segments:
89
+ - 0
90
+ hash: -407219618759612130
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 1.8.23
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Financial information scraper and a technical analysis tool.
97
+ test_files:
98
+ - spec/securities_spec.rb
99
+ - spec/spec_helper.rb