ytterb 0.2.152.223223 → 0.2.154.000903

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4de92e40383cd2fc47c6dd00857bc62ea366000e
4
- data.tar.gz: cf77d498119558b2cb956adde78d8e0a5541a7d4
3
+ metadata.gz: 9d578badfc1091885c94aba70d1b629e33f7e5cb
4
+ data.tar.gz: 795be1dc6adc612d9c850c17d7246359ffbf002e
5
5
  SHA512:
6
- metadata.gz: 850e40a9c4b39e5147bd9c985c29203818b2590d207c8cfa3de1ce363b905eb237f52503dcceb8b78259e5db9937255c7c711e0097ed18bbd2bd4d133105b298
7
- data.tar.gz: 61ca6fd0035c30f4e9ab1b54574527422b19e19c70782d4d7237887770da122fb25ad0dbc7a391d8e9b3a3f7e0e73f38de8ef75f6f2353038f371e6fc4441511
6
+ metadata.gz: 62932e40ab5dc287dd10a521e6bd2315b3b944fe1479c68c26af61fea210f951b516f4477c7e89dea2761c691928f66bd5b6372f983c32818bcfebc726a4524d
7
+ data.tar.gz: e10472592351bca656d6cf3f9666b2b0546c01dcd48a6ac261567fdc71726759c2ee6f1d936241b3891e328b40f0f26dca9ed28215ae832377307ae6452a519e
@@ -0,0 +1,4 @@
1
+ ---
2
+ :sync_from: '2013-06-02'
3
+ :sync_increment: 120
4
+ :api_calls_per_hour: 1900
@@ -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.symbol
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
- puts "#{@stock_sync_queue.length} symbols in the queue"
40
- puts "Processing Symbol: #{curr}"
41
- curr_file = @local_settings.get_symbol_store_file(curr)
42
- curr_stock_info = Util::DataPersistHelper.load(curr_file) rescue nil
43
- curr_stock_info ||= {}
44
- curr_stock_info[:sync_to] ||= @local_settings[:sync_from]
45
- date_start = Date.parse(curr_stock_info[:sync_to])
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 "error in stock processor run: #{e.message} : #{e.backtrace.join(" | ")}"
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 attributes
18
- return @options.keys
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
- def self.builder_from_csv(stock_symbol_file, exchange)
35
- CSV.foreach(stock_symbol_file, :headers => true) do |obj|
36
- yield Stock.new(obj.to_hash.merge("Exchange" => exchange))
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
@@ -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 JSON.parse(response)
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}'")["query"]["results"]
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,6 @@
1
+ module Ytterb
2
+ module Yql
3
+ class InvalidYqlResponse < StandardError; end
4
+ class ClientYqlError < StandardError; end
5
+ end
6
+ 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.152.223223
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-02 00:00:00.000000000 Z
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