ytterb 0.2.152.223223 → 0.2.154.000903
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/lib/ytterb/.cache/local_settings/settings/.yaml +4 -0
- data/lib/ytterb/stock_symbol/cache_builder.rb +12 -37
- data/lib/ytterb/stock_symbol/stock.rb +42 -6
- data/lib/ytterb/yql/client.rb +6 -9
- data/lib/ytterb/yql/exceptions.rb +6 -0
- data/lib/ytterb/yql/response.rb +49 -0
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d578badfc1091885c94aba70d1b629e33f7e5cb
|
|
4
|
+
data.tar.gz: 795be1dc6adc612d9c850c17d7246359ffbf002e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 62932e40ab5dc287dd10a521e6bd2315b3b944fe1479c68c26af61fea210f951b516f4477c7e89dea2761c691928f66bd5b6372f983c32818bcfebc726a4524d
|
|
7
|
+
data.tar.gz: e10472592351bca656d6cf3f9666b2b0546c01dcd48a6ac261567fdc71726759c2ee6f1d936241b3891e328b40f0f26dca9ed28215ae832377307ae6452a519e
|
|
@@ -10,7 +10,6 @@ module Ytterb
|
|
|
10
10
|
class CacheBuilder
|
|
11
11
|
|
|
12
12
|
def initialize
|
|
13
|
-
@yql = Yql::Client.new
|
|
14
13
|
@sml = MarketLoader.new
|
|
15
14
|
@local_settings = Util::Settings.new
|
|
16
15
|
|
|
@@ -26,57 +25,33 @@ module Ytterb
|
|
|
26
25
|
def build_stock_sync_queue
|
|
27
26
|
@stock_sync_queue = Queue.new
|
|
28
27
|
@sml.stock_symbols.shuffle.each do |stock|
|
|
29
|
-
@stock_sync_queue << stock
|
|
28
|
+
@stock_sync_queue << stock
|
|
30
29
|
end
|
|
31
30
|
end
|
|
32
31
|
|
|
33
32
|
def stock_processor_run
|
|
33
|
+
initial_queue_size = @stock_sync_queue.length
|
|
34
|
+
prev_done = 0
|
|
35
|
+
puts "Initial queue size is #{initial_queue_size}"
|
|
34
36
|
while true
|
|
35
37
|
begin
|
|
36
38
|
curr = @stock_sync_queue.pop(true) rescue nil
|
|
37
39
|
break unless curr # queue is empty
|
|
38
40
|
sleep(3600.0/@local_settings[:api_calls_per_hour])
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (date_start < Date.today)
|
|
47
|
-
date_end = date_start + @local_settings[:sync_increment]
|
|
48
|
-
date_end = Date.today if date_end > Date.today
|
|
49
|
-
result = @yql.get_symbol_historical(curr,date_start.to_s, date_end.to_s)
|
|
50
|
-
max_end_date = Date.parse(curr_stock_info[:sync_to])
|
|
51
|
-
symbol_updated = false
|
|
52
|
-
if result and result.has_key?("quote") and result["quote"].kind_of?(Array)
|
|
53
|
-
# TODO: need to pull all this logic into the yql client
|
|
54
|
-
# TODO: this needs some tests!
|
|
55
|
-
result["quote"].each do |item|
|
|
56
|
-
if item["Date"]
|
|
57
|
-
curr_stock_info[:data]||={}
|
|
58
|
-
curr_stock_info[:data][item["Date"]] = item
|
|
59
|
-
if Date.parse(item["Date"]) > max_end_date
|
|
60
|
-
max_end_date = Date.parse(item["Date"])
|
|
61
|
-
curr_stock_info[:sync_to] = max_end_date.to_s
|
|
62
|
-
symbol_updated = true
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
@stock_sync_queue << curr if symbol_updated
|
|
67
|
-
puts curr_stock_info[:sync_to]
|
|
68
|
-
Util::DataPersistHelper.save(curr_file,curr_stock_info)
|
|
69
|
-
else
|
|
70
|
-
puts "Debug result: #{result}"
|
|
71
|
-
end
|
|
41
|
+
curr.fetch_history
|
|
42
|
+
curr_done = (initial_queue_size - @stock_sync_queue.length) * 100 / initial_queue_size
|
|
43
|
+
if curr_done > prev_done
|
|
44
|
+
puts "#{curr_done} %"
|
|
45
|
+
prev_done = curr_done
|
|
46
|
+
else
|
|
47
|
+
print "#{curr.symbol}."
|
|
72
48
|
end
|
|
73
49
|
rescue StandardError => e
|
|
74
|
-
puts "
|
|
50
|
+
puts "#{e.message} : #{e.backtrace.join("|")}"
|
|
75
51
|
end
|
|
76
52
|
end
|
|
77
53
|
end
|
|
78
54
|
|
|
79
|
-
|
|
80
55
|
end # CacheBuilder
|
|
81
56
|
end
|
|
82
57
|
end
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
require 'csv'
|
|
2
2
|
|
|
3
|
+
require_relative '../util'
|
|
4
|
+
require_relative '../yql'
|
|
5
|
+
|
|
3
6
|
module Ytterb
|
|
4
7
|
module StockSymbol
|
|
5
8
|
class Stock
|
|
@@ -12,10 +15,15 @@ module Ytterb
|
|
|
12
15
|
val.gsub!(/\^/,"-") if sym_k == :symbol
|
|
13
16
|
@options[sym_k] = val
|
|
14
17
|
end
|
|
18
|
+
# not interested in variable data which was captured in the stock list
|
|
19
|
+
@options.reject! {|k,v| [:lastsale, :marketcap, :adr_tso].include?(k) }
|
|
20
|
+
load
|
|
15
21
|
end
|
|
16
22
|
|
|
17
|
-
def
|
|
18
|
-
|
|
23
|
+
def self.builder_from_csv(stock_symbol_file, exchange)
|
|
24
|
+
CSV.foreach(stock_symbol_file, :headers => true) do |obj|
|
|
25
|
+
yield Stock.new(obj.to_hash.merge("Exchange" => exchange))
|
|
26
|
+
end
|
|
19
27
|
end
|
|
20
28
|
|
|
21
29
|
def method_missing(meth, *args, &block)
|
|
@@ -31,12 +39,40 @@ module Ytterb
|
|
|
31
39
|
@options.to_s
|
|
32
40
|
end
|
|
33
41
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
## load/save operations
|
|
43
|
+
def self.get_settings
|
|
44
|
+
@settings ||= Util::Settings.new
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def load
|
|
48
|
+
symbol_history_file = self.class.get_settings.get_symbol_store_file(self.symbol)
|
|
49
|
+
@history = Util::DataPersistHelper.load(curr_file) rescue nil
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def save
|
|
53
|
+
return unless @history
|
|
54
|
+
symbol_history_file = self.class.get_settings.get_symbol_store_file(self.symbol)
|
|
55
|
+
Util::DataPersistHelper.save(symbol_history_file,@history)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# history via yql operation
|
|
59
|
+
def self.get_yql_client
|
|
60
|
+
@yql_client ||= Yql::Client.new
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def fetch_history(start_date = nil, end_date = nil)
|
|
64
|
+
start_date ||= self.class.get_settings[:sync_from]
|
|
65
|
+
@history||={}
|
|
66
|
+
@history["items"]||={}
|
|
67
|
+
start_date = @history[:max_sync_date] if @history and @history[:max_sync_date]
|
|
68
|
+
@history[:max_sync_date] = Date.parse(Time.at(0).to_s).to_s
|
|
69
|
+
|
|
70
|
+
self.class.get_yql_client.get_symbol_historical(@options[:symbol], start_date, end_date).each do |line|
|
|
71
|
+
@history["items"][line["Date"]] = line
|
|
72
|
+
@history[:max_sync_date] = line["Date"] if Date.parse(line["Date"]) > Date.parse(@history[:max_sync_date])
|
|
37
73
|
end
|
|
74
|
+
save
|
|
38
75
|
end
|
|
39
|
-
|
|
40
76
|
end
|
|
41
77
|
end
|
|
42
78
|
end # Ytterb
|
data/lib/ytterb/yql/client.rb
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
require 'rest-client'
|
|
2
2
|
require 'cgi'
|
|
3
|
-
require 'json'
|
|
4
3
|
require 'date'
|
|
5
4
|
|
|
5
|
+
require_relative 'exceptions'
|
|
6
|
+
require_relative 'response'
|
|
7
|
+
|
|
6
8
|
module Ytterb
|
|
7
9
|
module Yql
|
|
8
10
|
class Client
|
|
9
11
|
def initialize
|
|
10
12
|
@endpoint = "http://query.yahooapis.com/v1/public/yql"
|
|
11
|
-
puts "YQL Client is using endpoint @ #{@endpoint}"
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
def get_yql_endpoint
|
|
@@ -17,22 +18,18 @@ module Ytterb
|
|
|
17
18
|
|
|
18
19
|
def run_select_query(query)
|
|
19
20
|
RestClient.get("#{get_yql_endpoint}?q=#{CGI::escape(query)}&format=json&env=store://datatables.org/alltableswithkeys") do |response, request, result|
|
|
20
|
-
raise "Failed performing YQLQuery\n Request: #{request.inspect}\n Response #{response.inspect}" unless response.code == 200
|
|
21
|
-
return
|
|
21
|
+
raise ClientYqlError, "Failed performing YQLQuery\n Request: #{request.inspect}\n Response #{response.inspect}" unless response.code == 200
|
|
22
|
+
return Response.new(response).lines
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
|
|
25
|
-
def get_symbol_current(my_symbol)
|
|
26
|
-
run_select_query("select * from yahoo.finance.quotes where symbol in (\"#{my_symbol}\")")["query"]["results"]
|
|
27
|
-
end
|
|
28
|
-
|
|
29
26
|
def get_symbol_historical(my_symbol, start_date = nil, end_date = nil)
|
|
30
27
|
requested_end = Date.parse(end_date) if end_date
|
|
31
28
|
requested_end = Date.today unless requested_end
|
|
32
29
|
|
|
33
30
|
requested_start = Date.parse(start_date) if start_date
|
|
34
31
|
requested_start = requested_end - 30 unless requested_start
|
|
35
|
-
run_select_query("select * from yahoo.finance.historicaldata where symbol in (\"#{my_symbol}\") and startDate='#{requested_start}' and endDate='#{requested_end}'")
|
|
32
|
+
run_select_query("select * from yahoo.finance.historicaldata where symbol in (\"#{my_symbol}\") and startDate='#{requested_start}' and endDate='#{requested_end}'")
|
|
36
33
|
end
|
|
37
34
|
|
|
38
35
|
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
require_relative 'exceptions'
|
|
4
|
+
|
|
5
|
+
module Ytterb
|
|
6
|
+
module Yql
|
|
7
|
+
class Response
|
|
8
|
+
def initialize(raw)
|
|
9
|
+
begin
|
|
10
|
+
@response = JSON.parse(raw)
|
|
11
|
+
rescue
|
|
12
|
+
raise InvalidYqlResponse, "failed parsing yql response"
|
|
13
|
+
end
|
|
14
|
+
build_response_lines
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def validate_response_line(line)
|
|
18
|
+
raise InvalidYqlResponse, "response line needs to be a hash. found a #{line.class}" unless line.kind_of?(Hash)
|
|
19
|
+
line.select! do |k,v|
|
|
20
|
+
["Symbol", "Date", "Open", "High", "Low", "Close", "Volume", "Adj_Close"].include?(k)
|
|
21
|
+
end
|
|
22
|
+
line
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def build_response_lines
|
|
26
|
+
@response_lines = []
|
|
27
|
+
return unless @response.has_key?("query")
|
|
28
|
+
return unless @response["query"].has_key?("count")
|
|
29
|
+
return unless @response["query"]["count"].to_i > 0
|
|
30
|
+
return unless @response["query"].has_key?("results")
|
|
31
|
+
return unless @response["query"]["results"].has_key?("quote")
|
|
32
|
+
if @response["query"]["results"]["quote"].kind_of?(Hash)
|
|
33
|
+
@response_lines << validate_response_line(@response["query"]["results"]["quote"])
|
|
34
|
+
elsif @response["query"]["results"]["quote"].kind_of?(Array)
|
|
35
|
+
@response["query"]["results"]["quote"].each do |line|
|
|
36
|
+
@response_lines << validate_response_line(line)
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
raise InvalidYqlResponse, "response/query/results/quote needs to be an Array or a Hash. Found a #{@response["query"]["results"]["quote"].class}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def lines
|
|
44
|
+
@response_lines
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ytterb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.154.000903
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- thext
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-06-
|
|
11
|
+
date: 2014-06-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -97,6 +97,7 @@ files:
|
|
|
97
97
|
- lib/ytterb/.cache/cached_symbol_data/.keepme
|
|
98
98
|
- lib/ytterb/.cache/cached_symbol_data/clean.sh
|
|
99
99
|
- lib/ytterb/.cache/local_settings/settings.yaml
|
|
100
|
+
- lib/ytterb/.cache/local_settings/settings/.yaml
|
|
100
101
|
- lib/ytterb/.cache/raw_symbol_data/companylist_amex.csv
|
|
101
102
|
- lib/ytterb/.cache/raw_symbol_data/companylist_nasdaq.csv
|
|
102
103
|
- lib/ytterb/.cache/raw_symbol_data/companylist_nyse.csv
|
|
@@ -113,6 +114,8 @@ files:
|
|
|
113
114
|
- lib/ytterb/yql.rb
|
|
114
115
|
- lib/ytterb/yql/_req.rb
|
|
115
116
|
- lib/ytterb/yql/client.rb
|
|
117
|
+
- lib/ytterb/yql/exceptions.rb
|
|
118
|
+
- lib/ytterb/yql/response.rb
|
|
116
119
|
- spec/spec_helper.rb
|
|
117
120
|
- spec/ytterb_spec.rb
|
|
118
121
|
- ytterb.gemspec
|