Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Untitled #1

Merged
1 commit merged into from over 3 years ago

2 participants

maia David N. Welton
maia

refactored initialize and fetch methods, added public methods for pagination of results, and the returned object now isn't an array with results but a GoogleScreener object with the results array and also the total count of all results.

maia maia refactored initialize and fetch methods, added public methods for pag…
…ination of results, and the returned object now isn't an array with results but a GoogleScreener object with the results array and also the total count of all results
27fd528
David N. Welton
Owner

Ok, I have accepted this and put it on my branch.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Feb 22, 2011
maia maia refactored initialize and fetch methods, added public methods for pag…
…ination of results, and the returned object now isn't an array with results but a GoogleScreener object with the results array and also the total count of all results
27fd528
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 55 additions and 40 deletions. Show diff stats Hide diff stats

  1. +55 40 lib/google_screener.rb
95 lib/google_screener.rb
@@ -10,6 +10,8 @@
10 10 class GoogleScreener
11 11
12 12 BASE_URI = "http://www.google.com/finance?"
  13 +
  14 + # We don't yet know what :desc and :noIL do, also other :restype options are unknown.
13 15 BASE_PARAMS = {
14 16 :gl => "us",
15 17 :hl => "en",
@@ -23,7 +25,6 @@ class GoogleScreener
23 25 }
24 26
25 27 # Known options in the screener.
26   -
27 28 KNOWN_OPTIONS = [
28 29 :MarketCap,
29 30 :PE,
@@ -33,52 +34,44 @@ class GoogleScreener
33 34 :NetIncomeGrowthRate5Years,
34 35 :QuoteLast
35 36 ]
36   -
37   - SCREENER_MIN = {
38   - :MarketCap => 10_000_000,
39   - :PE => 0,
40   - :DividendYield => 0.01,
41   - :Price52WeekPercChange => -100.00,
42   - :NetIncomeGrowthRate5Years => -100.00,
43   - :QuoteLast => 0.00
44   - }
45   - SCREENER_MAX = {
46   - :MarketCap => 1_500_000_000_000,
47   - :PE => 100,
48   - :DividendYield => 38.03,
49   - :Price52WeekPercChange => -5,
50   - :NetIncomeGrowthRate5Years => 500,
51   - :QuoteLast => 150000
  37 +
  38 + # Defaults for the query. Probably these values are too specific?
  39 + DEFAULTS = {
  40 + :max => {
  41 + :MarketCap => 1_500_000_000_000,
  42 + :PE => 100,
  43 + :DividendYield => 50,
  44 + :Price52WeekPercChange => -5,
  45 + :NetIncomeGrowthRate5Years => 500,
  46 + :QuoteLast => 150000
  47 + },
  48 + :min => {
  49 + :MarketCap => 10_000_000,
  50 + :PE => 0,
  51 + :DividendYield => 0,
  52 + :Price52WeekPercChange => -100,
  53 + :NetIncomeGrowthRate5Years => -100,
  54 + :QuoteLast => 0
  55 + }
52 56 }
  57 +
  58 + EXCHANGES = "(exchange:NYSE OR exchange:NASDAQ OR exchange:AMEX)"
53 59
54 60 class Result
55 61 attr_reader :name, :symbol, :values
56 62 def initialize(result)
57   - @name = result['title']
58   - @symbol = result['ticker']
59   - @values = Hash[result['columns'].map { |c| [c['field'], c['value']] }]
  63 + @name = result['title']
  64 + @symbol = result['ticker']
  65 + @exchange = result['exchange']
  66 + @values = Hash[result['columns'].map { |c| [c['field'], c['value']] }]
60 67 end
61 68 end
62 69
63   - attr_reader :results
  70 + attr_reader :results, :count
64 71
65 72 def initialize(options = {})
66   - merged_minimums = SCREENER_MIN.merge(options[:min] || {})
67   - merged_maximums = SCREENER_MAX.merge(options[:max] || {})
68   - option_string = merged_minimums.map do |key, value|
69   - if !KNOWN_OPTIONS.include?(key)
70   - raise "Unknown 'min' option: #{key}"
71   - end
72   - "(#{CGI.escape(key.to_s)} > #{value.to_f})"
73   - end.join(" & ")
74   - option_string += " & "
75   - option_string += merged_maximums.map do |key, value|
76   - if !KNOWN_OPTIONS.include?(key)
77   - raise "Unknown 'max' option: #{key}"
78   - end
79   - "(#{CGI.escape(key.to_s)} < #{value.to_f})"
80   - end.join(" & ")
81   - query = "((exchange:NYSE) OR (exchange:NASDAQ) OR (exchange:AMEX)) [#{option_string}]"
  73 + string = screen(:min, options[:min] || {}) + "&" + screen(:max, options[:max] || {})
  74 + query = "#{EXCHANGES} [#{string}]"
82 75 @params = BASE_PARAMS.merge(:q => query)
83 76 end
84 77
@@ -86,15 +79,37 @@ def sort_as(how)
86 79 @params.merge!(:sortas => how)
87 80 self
88 81 end
  82 +
  83 + def start(n)
  84 + @params.merge!(:start => n)
  85 + self
  86 + end
  87 +
  88 + def limit(n)
  89 + @params.merge!(:num => n)
  90 + self
  91 + end
89 92
90 93 def fetch
91   - @results = get_data.map { |res| Result.new(res) }
  94 + @count = response['num_company_results']
  95 + @results = response['searchresults'].map { |stock| Result.new(stock) }
  96 + remove_instance_variable(:@params)
  97 + remove_instance_variable(:@response)
  98 + self
92 99 end
93 100
94 101 private
  102 +
  103 + def screen(type, options)
  104 + comparator = (type == :min ? ">" : "<")
  105 + DEFAULTS[type].merge(options)
  106 + .keep_if {|k, v| KNOWN_OPTIONS.include?(k) }
  107 + .map { |k, v| "#{CGI.escape(k.to_s)}#{comparator}#{v.to_f}" }
  108 + .join("&")
  109 + end
95 110
96   - def get_data
97   - JSON.parse(open(uri).read)['searchresults']
  111 + def response
  112 + @response ||= JSON.parse(open(uri).read)
98 113 end
99 114
100 115 def uri

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.