yahoo_stock 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +61 -0
- data/Manifest.txt +29 -0
- data/README.rdoc +142 -0
- data/Rakefile +22 -0
- data/lib/yahoo_stock.rb +19 -0
- data/lib/yahoo_stock/base.rb +37 -0
- data/lib/yahoo_stock/history.rb +32 -0
- data/lib/yahoo_stock/interface.rb +71 -0
- data/lib/yahoo_stock/interface/history.rb +186 -0
- data/lib/yahoo_stock/interface/quote.rb +287 -0
- data/lib/yahoo_stock/interface/scrip_symbol.rb +74 -0
- data/lib/yahoo_stock/quote.rb +158 -0
- data/lib/yahoo_stock/result.rb +21 -0
- data/lib/yahoo_stock/result/array_format.rb +27 -0
- data/lib/yahoo_stock/result/hash_format.rb +37 -0
- data/lib/yahoo_stock/scrip_symbol.rb +61 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/yahoo_stock/base_spec.rb +48 -0
- data/spec/yahoo_stock/history_spec.rb +75 -0
- data/spec/yahoo_stock/interface/history_spec.rb +317 -0
- data/spec/yahoo_stock/interface/quote_spec.rb +414 -0
- data/spec/yahoo_stock/interface/scrip_symbol_spec.rb +120 -0
- data/spec/yahoo_stock/interface_spec.rb +104 -0
- data/spec/yahoo_stock/quote_spec.rb +258 -0
- data/spec/yahoo_stock/result/array_format_spec.rb +38 -0
- data/spec/yahoo_stock/result/hash_format_spec.rb +68 -0
- data/spec/yahoo_stock/result_spec.rb +33 -0
- data/spec/yahoo_stock/scrip_symbol_spec.rb +46 -0
- metadata +81 -0
data/History.txt
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
=== 0.1.1 2009-08-31
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
* Initial release
|
5
|
+
|
6
|
+
=== 0.1.2 2009-09-01
|
7
|
+
|
8
|
+
* 1 minor change:
|
9
|
+
* changed method name YahooStock::Quote#get_data to get
|
10
|
+
|
11
|
+
=== 0.1.3 2009-09-05
|
12
|
+
|
13
|
+
* 3 additions:
|
14
|
+
* adds a new class called YahooStock::ScripSymbol that allows to
|
15
|
+
find out the stock symbol for a company
|
16
|
+
* adds specs for previous and new code
|
17
|
+
* adds
|
18
|
+
|
19
|
+
=== 0.1.4 2009-09-05
|
20
|
+
|
21
|
+
* 2 changes related with ruby 1.9:
|
22
|
+
* modifies quote class to be compatible with ruby 1.9
|
23
|
+
* modifies interface class to be compatible with 1.9
|
24
|
+
|
25
|
+
=== 0.1.5 2009-09-06
|
26
|
+
|
27
|
+
* 1 changes related with ruby 1.9:
|
28
|
+
* modifies ScripSymbol class to be compatible with ruby 1.9
|
29
|
+
|
30
|
+
=== 0.1.6 2009-09-07
|
31
|
+
|
32
|
+
* 1 addition:
|
33
|
+
* adds convenience methods Quote#realtime, standard and extended to
|
34
|
+
fetch relevant stock values
|
35
|
+
|
36
|
+
=== 1.0.1 2009-09-10
|
37
|
+
|
38
|
+
* 1 addition:
|
39
|
+
* adds feature to retreive historical stock data
|
40
|
+
|
41
|
+
=== 1.0.2 2009-10-04
|
42
|
+
Major changes in the public API. Check the README.rdoc file and individual classes for more information
|
43
|
+
|
44
|
+
* 8 addition:
|
45
|
+
* adds YahooStock::Interface::History
|
46
|
+
* adds YahooStock::Interface::Quote
|
47
|
+
* adds YahooStock::Interface::ScripSymbol
|
48
|
+
* adds YahooStock::Result as a superclass for all formatter classes
|
49
|
+
* adds array format, Result::ArrayFormat, to generate results as an array
|
50
|
+
* adds hash format, Result::ArrayFormat, to generate results as key value pairs
|
51
|
+
* adds base class as parent for public facing classes
|
52
|
+
* adds observers to check when it is required to send request to yahoo again to get fresh data
|
53
|
+
|
54
|
+
* 7 changes:
|
55
|
+
* changes YahooStock::Interface to be the main interface class. Other interface classes will inherit from this
|
56
|
+
* changes YahooStock::ScripSymbol to use YahooStock::Interface::ScripSymbol
|
57
|
+
* removes all history interface logic from YahooStock::History and uses YahooStock::Interface::History
|
58
|
+
* changes YahooStock::Quote, YahooStock::History, YahooStock::ScripSymbol to extend from YahooStock::Base
|
59
|
+
* sorts url parameters before sending request to yahoo
|
60
|
+
* YahooInterface::Quote#realtime, extended, and standard methods should return self to allow calling different format output method calls
|
61
|
+
* do not discard any empty values when finding scrip symbol options for a company as this interferes with different format options
|
data/Manifest.txt
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.rdoc
|
4
|
+
Rakefile
|
5
|
+
lib/yahoo_stock/base.rb
|
6
|
+
lib/yahoo_stock/history.rb
|
7
|
+
lib/yahoo_stock/interface.rb
|
8
|
+
lib/yahoo_stock/interface/history.rb
|
9
|
+
lib/yahoo_stock/interface/quote.rb
|
10
|
+
lib/yahoo_stock/interface/scrip_symbol.rb
|
11
|
+
lib/yahoo_stock/quote.rb
|
12
|
+
lib/yahoo_stock/result.rb
|
13
|
+
lib/yahoo_stock/result/array_format.rb
|
14
|
+
lib/yahoo_stock/result/hash_format.rb
|
15
|
+
lib/yahoo_stock/scrip_symbol.rb
|
16
|
+
lib/yahoo_stock.rb
|
17
|
+
spec/spec_helper.rb
|
18
|
+
spec/yahoo_stock/base_spec.rb
|
19
|
+
spec/yahoo_stock/interface_spec.rb
|
20
|
+
spec/yahoo_stock/interface/history_spec.rb
|
21
|
+
spec/yahoo_stock/interface/quote_spec.rb
|
22
|
+
spec/yahoo_stock/interface/scrip_symbol_spec.rb
|
23
|
+
spec/yahoo_stock/quote_spec.rb
|
24
|
+
spec/yahoo_stock/history_spec.rb
|
25
|
+
spec/yahoo_stock/result_spec.rb
|
26
|
+
spec/yahoo_stock/result/array_format_spec.rb
|
27
|
+
spec/yahoo_stock/result/hash_format_spec.rb
|
28
|
+
spec/yahoo_stock/scrip_symbol_spec.rb
|
29
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
= yahoo_stock
|
2
|
+
|
3
|
+
* http://github.com/nas/yahoo_stock
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Provides an interface to yahoo finance to get stock related data. For instance, latest trade related data, volume, 50 day moving average, market cap, etc, virtually any thing that yahoo finance provides.
|
8
|
+
|
9
|
+
If you don't know the stock / scrip symbol of the company then you can find that out by using the YahooStock::ScripSymbol class. The methods are mentioned in the Usage section below. For instance, YHOO for yahoo, GOOG for google, etc.
|
10
|
+
The kind of parameters to be passed can be found after initializing the
|
11
|
+
YahooStock::Quote object and passing valid_parameters message, example is given below in the USAGE section.
|
12
|
+
|
13
|
+
== USAGE:
|
14
|
+
|
15
|
+
require 'rubygems'
|
16
|
+
|
17
|
+
require 'yahoo_stock'
|
18
|
+
|
19
|
+
* Initialize quote object
|
20
|
+
|
21
|
+
quote = YahooStock::Quote.new(:stock_symbols => ['YHOO', 'GOOG'])
|
22
|
+
|
23
|
+
* To view the valid parameters that can be passed
|
24
|
+
|
25
|
+
quote.valid_parameters
|
26
|
+
|
27
|
+
* To view the current parameters used
|
28
|
+
|
29
|
+
quote.current_parameters
|
30
|
+
|
31
|
+
* To view the current stock symbols used
|
32
|
+
|
33
|
+
quote.current_symbols
|
34
|
+
|
35
|
+
* To add more stocks to the list
|
36
|
+
|
37
|
+
quote.add_symbols('MSFT', 'AAPL')
|
38
|
+
|
39
|
+
* To remove stocks from list
|
40
|
+
|
41
|
+
quote.remove_symbols('MSFT', 'AAPL')
|
42
|
+
|
43
|
+
* To find data for all stocks, this will give a string containing all values
|
44
|
+
|
45
|
+
quote.results
|
46
|
+
|
47
|
+
to return an array instead of a string use:
|
48
|
+
|
49
|
+
quote.results(:to_array).output
|
50
|
+
|
51
|
+
to return a hash, use:
|
52
|
+
|
53
|
+
quote.results(:to_hash).output
|
54
|
+
|
55
|
+
to store results in a file, use:
|
56
|
+
|
57
|
+
quote.results.store('filename')
|
58
|
+
|
59
|
+
* To find out the stock symbol for a company
|
60
|
+
|
61
|
+
symbol = YahooStock::ScripSymbol.new('Yahoo')
|
62
|
+
|
63
|
+
* To find all symbols for that company, this will give a string containing all values
|
64
|
+
|
65
|
+
symbol.results
|
66
|
+
|
67
|
+
to return an array instead of a string use:
|
68
|
+
|
69
|
+
symbol.results(:to_array).output
|
70
|
+
|
71
|
+
to return a hash, use:
|
72
|
+
|
73
|
+
symbol.results(:to_hash).output
|
74
|
+
|
75
|
+
to store results in a file, use:
|
76
|
+
|
77
|
+
symbol.results.store('filename')
|
78
|
+
|
79
|
+
* To find symbols for multiple companies
|
80
|
+
|
81
|
+
symbols = YahooStock::ScripSymbol.results('Yahoo', 'Company1', 'Company3')
|
82
|
+
|
83
|
+
* to get the result in a string
|
84
|
+
|
85
|
+
symbols.output
|
86
|
+
|
87
|
+
* to store output in a file
|
88
|
+
|
89
|
+
symbols.store('filename')
|
90
|
+
|
91
|
+
* To find historical data for a stock
|
92
|
+
|
93
|
+
history = YahooStock::History.new(:stock_symbols => 'yhoo', :start_date => Date.today-20, end_date => Date.today -2)
|
94
|
+
|
95
|
+
to return an array instead of a string use:
|
96
|
+
|
97
|
+
history.results(:to_array).output
|
98
|
+
|
99
|
+
to return a hash, use:
|
100
|
+
|
101
|
+
history.results(:to_hash).output
|
102
|
+
|
103
|
+
to store results in a file, use:
|
104
|
+
|
105
|
+
history.results.store('filename')
|
106
|
+
|
107
|
+
== INSTALL:
|
108
|
+
|
109
|
+
gem sources -a http://gems.github.com
|
110
|
+
|
111
|
+
sudo gem install nas-yahoo_stock
|
112
|
+
|
113
|
+
== TESTS:
|
114
|
+
|
115
|
+
Tests are written using Rspec 1.2.2
|
116
|
+
|
117
|
+
To run all tests 'rake spec' from the root directory
|
118
|
+
|
119
|
+
== LICENSE:
|
120
|
+
|
121
|
+
(The MIT License)
|
122
|
+
|
123
|
+
Copyright (c) 2009 Nasir Jamal
|
124
|
+
|
125
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
126
|
+
a copy of this software and associated documentation files (the
|
127
|
+
'Software'), to deal in the Software without restriction, including
|
128
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
129
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
130
|
+
permit persons to whom the Software is furnished to do so, subject to
|
131
|
+
the following conditions:
|
132
|
+
|
133
|
+
The above copyright notice and this permission notice shall be
|
134
|
+
included in all copies or substantial portions of the Software.
|
135
|
+
|
136
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
137
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
138
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
139
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
140
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
141
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
142
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'hoe', '>= 2.1.0'
|
3
|
+
require 'hoe'
|
4
|
+
require 'fileutils'
|
5
|
+
require './lib/yahoo_stock'
|
6
|
+
|
7
|
+
Hoe.plugin :newgem
|
8
|
+
# Hoe.plugin :website
|
9
|
+
# Hoe.plugin :cucumberfeatures
|
10
|
+
|
11
|
+
# Generate all the Rake tasks
|
12
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
13
|
+
$hoe = Hoe.spec 'yahoo_stock' do
|
14
|
+
self.developer 'Nasir Jamal', 'nas35_in@yahoo.com'
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'newgem/tasks'
|
18
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
19
|
+
|
20
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
21
|
+
# remove_task :default
|
22
|
+
# task :default => [:spec, :features]
|
data/lib/yahoo_stock.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'date'
|
5
|
+
require 'yahoo_stock/base.rb'
|
6
|
+
require 'yahoo_stock/interface.rb'
|
7
|
+
require 'yahoo_stock/history.rb'
|
8
|
+
require 'yahoo_stock/scrip_symbol.rb'
|
9
|
+
require 'yahoo_stock/quote.rb'
|
10
|
+
require 'yahoo_stock/interface/quote.rb'
|
11
|
+
require 'yahoo_stock/interface/history.rb'
|
12
|
+
require 'yahoo_stock/interface/scrip_symbol.rb'
|
13
|
+
require 'yahoo_stock/result.rb'
|
14
|
+
require 'yahoo_stock/result/array_format.rb'
|
15
|
+
require 'yahoo_stock/result/hash_format.rb'
|
16
|
+
|
17
|
+
module YahooStock
|
18
|
+
VERSION = '1.0.2'
|
19
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# YahooStock::Base class to find and output results.
|
2
|
+
module YahooStock
|
3
|
+
|
4
|
+
class Base
|
5
|
+
|
6
|
+
def initialize(interface)
|
7
|
+
@interface = interface
|
8
|
+
end
|
9
|
+
|
10
|
+
# Uses the values method of the interface used to show results .
|
11
|
+
def find
|
12
|
+
@interface.values
|
13
|
+
end
|
14
|
+
|
15
|
+
# Method takes one parameter type or a block
|
16
|
+
# type uses the existing format classes namespaced in Result::ClassName.output
|
17
|
+
# e.g. * results :to_array
|
18
|
+
# * results {YourSpecialFormat.method_name}
|
19
|
+
# to store
|
20
|
+
def results(type=nil, &block)
|
21
|
+
if block_given?
|
22
|
+
yield
|
23
|
+
else
|
24
|
+
return YahooStock::Result.new(find) if !type || type.to_s.empty?
|
25
|
+
format_type = type.to_s.sub(/^to_/,'').strip
|
26
|
+
return YahooStock::Result.const_get("#{format_type.capitalize}Format").new(find){data_attributes}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Abstract method
|
31
|
+
def data_attributes
|
32
|
+
raise 'Abstract method called. Use the subclass data_attributes method'
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module YahooStock
|
2
|
+
class History < Base
|
3
|
+
|
4
|
+
class HistoryError < RuntimeError; end
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
unless options.is_a?(Hash)
|
8
|
+
raise HistoryError, 'A hash of start_date, end_date and stock_symbol is expected as parameters'
|
9
|
+
end
|
10
|
+
@interface = YahooStock::Interface::History.new(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def find
|
14
|
+
@find_values = super()
|
15
|
+
@find_values.sub(/Date.*\s/,'') if @find_values
|
16
|
+
end
|
17
|
+
|
18
|
+
def values_with_header
|
19
|
+
@interface.values
|
20
|
+
end
|
21
|
+
|
22
|
+
def data_attributes
|
23
|
+
return unless values_with_header
|
24
|
+
data_attributes = /Date.*\s/.match(values_with_header)
|
25
|
+
unless data_attributes.nil?
|
26
|
+
@data_attributes = data_attributes[0].sub(/\s*$/,'').split(',')
|
27
|
+
@data_attributes.map &:strip
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
=begin
|
2
|
+
Main class to interface with Yahoo
|
3
|
+
=end
|
4
|
+
|
5
|
+
require 'net/http'
|
6
|
+
require 'observer'
|
7
|
+
module YahooStock
|
8
|
+
# ==DESCRIPTION:
|
9
|
+
#
|
10
|
+
# Class to generate the right url and interface with yahoo
|
11
|
+
#
|
12
|
+
class Interface
|
13
|
+
include Observable
|
14
|
+
class InterfaceError < RuntimeError ; end
|
15
|
+
|
16
|
+
BASE_URLS = {
|
17
|
+
:quote => "http://download.finance.yahoo.com/d/quotes.csv",
|
18
|
+
:history => "http://ichart.finance.yahoo.com/table.csv",
|
19
|
+
:scrip_symbol => "http://finance.yahoo.com/lookup/all"
|
20
|
+
} unless defined?(BASE_URLS)
|
21
|
+
|
22
|
+
attr_accessor :base_url, :uri_parameters
|
23
|
+
|
24
|
+
# Send request to the uri and get results
|
25
|
+
def get
|
26
|
+
begin
|
27
|
+
response = Net::HTTP.get_response(URI.parse(uri))
|
28
|
+
rescue => e
|
29
|
+
raise InterfaceError, "#{e.message}\n\n#{e.backtrace}"
|
30
|
+
end
|
31
|
+
response.code == '200' ? response.body : response_error(response)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Generates full url to connect to yahoo
|
35
|
+
def uri
|
36
|
+
raise InterfaceError, 'Base url is require to generate full uri.' unless @base_url
|
37
|
+
return @base_url if @uri_parameters.nil? || @uri_parameters.empty?
|
38
|
+
params_with_values = []
|
39
|
+
@uri_parameters.each {|k,v| params_with_values << "#{k}=#{v}"}
|
40
|
+
@base_url+'?'+params_with_values.join('&')
|
41
|
+
end
|
42
|
+
|
43
|
+
# Get result string
|
44
|
+
def values
|
45
|
+
@values ||= get
|
46
|
+
end
|
47
|
+
|
48
|
+
def update
|
49
|
+
@values = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Generate error for debugging when something goes wrong while sending
|
55
|
+
# request to yahoo
|
56
|
+
def response_error(response)
|
57
|
+
trace = "Response \n\nbody : #{response.body}\n\ncode: #{response.code}\n\nmessage: #{response.message}"
|
58
|
+
case @base_url
|
59
|
+
when BASE_URLS[:quote]
|
60
|
+
raise InterfaceError, "Error :: Could not get stock data \n\n#{trace}"
|
61
|
+
when BASE_URLS[:history]
|
62
|
+
raise InterfaceError, "Error :: Could not get historical data \n\n#{trace}"
|
63
|
+
when BASE_URLS[:scrip_symbol]
|
64
|
+
raise InterfaceError, "Error :: Could not get stock symbol \n\n#{trace}"
|
65
|
+
else
|
66
|
+
raise InterfaceError, "Error connecting to #{@base_url} \n\n#{trace}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
=begin
|
2
|
+
params:
|
3
|
+
s=stock symbol
|
4
|
+
a=month-1
|
5
|
+
b=date
|
6
|
+
c=year
|
7
|
+
d=month-1
|
8
|
+
e=date
|
9
|
+
f=year
|
10
|
+
g=d or w or m
|
11
|
+
ignore=.csv
|
12
|
+
|
13
|
+
=end
|
14
|
+
|
15
|
+
module YahooStock
|
16
|
+
# ==DESCRIPTION:
|
17
|
+
#
|
18
|
+
# Class to generate the right url and interface with yahoo to get history of a stock
|
19
|
+
#
|
20
|
+
class Interface::History < Interface
|
21
|
+
|
22
|
+
class HistoryError < RuntimeError ; end
|
23
|
+
|
24
|
+
attr_reader :stock_symbol, :start_date, :end_date, :interval
|
25
|
+
|
26
|
+
# The options parameter expects a hash with 4 key value pairs
|
27
|
+
#
|
28
|
+
# :stock_symbol => 'goog', :start_date => Date.today-30,
|
29
|
+
# :end_date => Date.today-10, :interval => :weekly
|
30
|
+
#
|
31
|
+
# The interval option accepts :daily, :monthly and :weekly values
|
32
|
+
#
|
33
|
+
# The interval key is optional, if not used then by default uses :daily
|
34
|
+
#
|
35
|
+
# and provides daily history for the specified date range
|
36
|
+
#
|
37
|
+
def initialize(options)
|
38
|
+
@base_url = BASE_URLS[:history]
|
39
|
+
validate_keys(options)
|
40
|
+
|
41
|
+
@stock_symbol = options[:stock_symbol]
|
42
|
+
@start_date = options[:start_date]
|
43
|
+
@end_date = options[:end_date]
|
44
|
+
@interval = options[:interval].nil? ? :daily : options[:interval].to_sym
|
45
|
+
|
46
|
+
validate_interval_values(options[:interval]) if options[:interval]
|
47
|
+
validate_stock_symbol(options)
|
48
|
+
validate_start_date(options)
|
49
|
+
validate_end_date(options)
|
50
|
+
validate_history_range
|
51
|
+
end
|
52
|
+
|
53
|
+
# Make sure that stock symbol is not nil or an empty string before setting it
|
54
|
+
def stock_symbol=(stock_symbol)
|
55
|
+
validate_stock_symbol_attribute(stock_symbol)
|
56
|
+
@stock_symbol = stock_symbol
|
57
|
+
end
|
58
|
+
|
59
|
+
# Before setting start date
|
60
|
+
# - Make sure that it is of type date
|
61
|
+
# - Make sure that it is before the end date
|
62
|
+
def start_date=(start_date)
|
63
|
+
validate_start_date_type(start_date)
|
64
|
+
validate_history_range(start_date)
|
65
|
+
@start_date = start_date
|
66
|
+
end
|
67
|
+
|
68
|
+
# Before setting end date
|
69
|
+
# - Make sure that it is of type date
|
70
|
+
# - Make sure that it is after the start date
|
71
|
+
def end_date=(end_date)
|
72
|
+
validate_end_date_type(end_date)
|
73
|
+
validate_history_range(start_date, end_date)
|
74
|
+
@end_date = end_date
|
75
|
+
end
|
76
|
+
|
77
|
+
# Set interval to specify whether daily, weekly or monthly histroy required
|
78
|
+
def interval=(interval)
|
79
|
+
validate_interval_values(interval)
|
80
|
+
@interval = interval
|
81
|
+
end
|
82
|
+
|
83
|
+
# Generate full uri with the help of uri method of the superclass
|
84
|
+
def uri
|
85
|
+
frequency = case interval
|
86
|
+
when :daily : 'd'
|
87
|
+
when :weekly : 'w'
|
88
|
+
when :monthly : 'm'
|
89
|
+
end
|
90
|
+
@uri_parameters = {:a => sprintf("%02d", start_date.month-1), :b => start_date.day,
|
91
|
+
:c => start_date.year, :d => sprintf("%02d", end_date.month-1),
|
92
|
+
:e => end_date.day, :f => end_date.year, :s => stock_symbol,
|
93
|
+
:g => frequency, :ignore => '.csv'}
|
94
|
+
super()
|
95
|
+
end
|
96
|
+
|
97
|
+
# Get uri content with the help of get method of the super class
|
98
|
+
def get
|
99
|
+
if stock_symbol.nil? || start_date.nil? || end_date.nil?
|
100
|
+
raise HistoryError, 'Cannot send request unless all parameters, ie stock_symbol, start and end date are present'
|
101
|
+
end
|
102
|
+
if !(start_date.is_a?(Date) || end_date.is_a?(Date))
|
103
|
+
raise HistoryError, 'Start and end date should be of type Date'
|
104
|
+
end
|
105
|
+
uri
|
106
|
+
super()
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def validate_interval_values(interval_value=interval)
|
112
|
+
valid_values = [:daily, :weekly, :monthly]
|
113
|
+
unless valid_values.include?(interval_value)
|
114
|
+
raise HistoryError, "Allowed values for interval are #{valid_values.join(', ')}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def validate_stock_symbol(options)
|
119
|
+
unless options.keys.include?(:stock_symbol)
|
120
|
+
raise HistoryError, ':stock_symbol key is not present in the parameter hash'
|
121
|
+
end
|
122
|
+
validate_stock_symbol_attribute
|
123
|
+
end
|
124
|
+
|
125
|
+
def validate_stock_symbol_attribute(symbol=stock_symbol)
|
126
|
+
if symbol.nil? || symbol.empty?
|
127
|
+
raise HistoryError, ':stock_symbol value cannot be nil or blank'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def validate_start_date(options)
|
132
|
+
validate_date_options(:start_date, options)
|
133
|
+
validate_start_date_type
|
134
|
+
end
|
135
|
+
|
136
|
+
def validate_end_date(options)
|
137
|
+
validate_date_options(:end_date, options)
|
138
|
+
validate_end_date_type
|
139
|
+
end
|
140
|
+
|
141
|
+
def validate_history_range(s_date = start_date, e_date = end_date)
|
142
|
+
if s_date >= Date.today
|
143
|
+
raise HistoryError, "Start date must be in the past"
|
144
|
+
end
|
145
|
+
if e_date >= Date.today
|
146
|
+
raise HistoryError, "End date must be in the past"
|
147
|
+
end
|
148
|
+
if e_date < s_date
|
149
|
+
raise HistoryError, "End date must be greater than the start date"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def validate_end_date_type(e_date=end_date)
|
154
|
+
unless e_date.is_a?(Date)
|
155
|
+
raise HistoryError, "End date must be of type Date"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def validate_start_date_type(s_date=start_date)
|
160
|
+
unless s_date.is_a?(Date)
|
161
|
+
raise HistoryError, "Start date must be of type Date"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def validate_date_options(date_type, options)
|
166
|
+
unless options.keys.include?(date_type)
|
167
|
+
raise HistoryError, ":#{date_type} key is not present in the parameter hash"
|
168
|
+
end
|
169
|
+
|
170
|
+
if options[date_type].nil? || options[date_type].to_s.empty?
|
171
|
+
raise HistoryError, ":#{date_type} value cannot be blank"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def validate_keys(options)
|
176
|
+
valid_keys = [:stock_symbol, :start_date, :end_date, :interval]
|
177
|
+
invalid_keys = []
|
178
|
+
options.keys.each{|key| invalid_keys << key unless valid_keys.include?(key) }
|
179
|
+
unless invalid_keys.length.zero?
|
180
|
+
raise HistoryError, "An invalid key '#{invalid_keys.join(',')}' is passed in the parameters. Allowed keys are #{valid_keys.join(', ')}"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|