-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ac1a45d
Showing
11 changed files
with
479 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
*.gem | ||
.bundle | ||
Gemfile.lock | ||
pkg/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
require "bundler/gem_tasks" | ||
# require 'rake' | ||
require 'rake/testtask' | ||
|
||
# Host or location to copy gem to. At the moment this is only a local copy | ||
# operation | ||
GEM_LOCAL = "/Users/scott/.gems-repository" | ||
|
||
# Details of theremote server to upload the gem to | ||
GEM_HOST = "gems.signalvsnoise.com" | ||
GEM_HOST_USER = "root" | ||
SSH_KEY = "#{ENV['HOME']}/.ssh/scott-signalvsnoise.key" | ||
|
||
Rake::TestTask.new("test:units") { |test| | ||
%w{. lib test}.each { |dir| test.libs << dir } | ||
test.test_files = FileList["test/unit/*_test.rb"].exclude("test/test_helper.rb", "test/vendor") | ||
test.verbose = false | ||
# test.warning = true | ||
} | ||
|
||
Rake::TestTask.new("test:functionals") { |test| | ||
%w{. lib test}.each { |dir| test.libs << dir } | ||
test.test_files = FileList["test/functional/*_test.rb"].exclude("test/test_helper.rb", "test/vendor") | ||
test.verbose = false | ||
# test.warning = true | ||
} | ||
|
||
task :test => ["test:units", "test:functionals"] | ||
|
||
def get_version | ||
DividendPredictor::VERSION | ||
end | ||
|
||
task :upload_local do | ||
# place the gem in the local repository | ||
gem_file = "pkg/#{APP_NAME}-#{get_version}.gem" | ||
system "cp #{gem_file} #{GEM_LOCAL}/gems/" | ||
|
||
# update the gem index | ||
system "cd #{GEM_LOCAL} && gem generate_index -d ." | ||
end | ||
|
||
task :sync_remote do | ||
system "cd #{GEM_LOCAL} && rsync -auvz -e 'ssh -i #{SSH_KEY}' . #{GEM_HOST_USER}@#{GEM_HOST}:/var/www/gems/" | ||
end | ||
|
||
task :publish => [ :test, :build, :upload_local, :sync_remote ] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
= How to query the nasdaq.com for prices | ||
|
||
Let's check the price for Altria (MO) because everyone loves smoking, right? | ||
|
||
== Query | ||
|
||
$ curl -i "http://www.nasdaq.com/quote.dll?page=dynamic&mode=data&symbol=MO&random=0.7634591432288283" | ||
|
||
== Response | ||
|
||
HTTP/1.1 200 ok | ||
Content-Length: 113 | ||
Content-Type: text/plain | ||
Server: Microsoft-IIS/7.5 | ||
Date: Thu, 18 Aug 2011 06:01:43 GMT | ||
Connection: close | ||
|
||
*MO|26|0.32|1.25%|13,603,764|up|Y|$ 26.17|$ 25.79|MO|Dec. 31, 1969|N/A|N/A|N|NYSE|N|Altria Group| | ||
|
||
What fields are returned in the data? | ||
|
||
*MO - Symbol | ||
26 - Price in $US. The price here is $26.00 even | ||
0.32 - Change in $US, from | ||
1.25% - Change in % | ||
13,603,764 - Volume of shares traded | ||
up - Direction of movement. Values (up, down) | ||
Y - Unknown. Values (Y, A, N) | ||
$ 26.17 - Day high. Unescaped value would be "$ 26.17" | ||
$ 25.79 - Day low. Unescaped value would be "$ 25.79" | ||
MO - Symbol | ||
Dec. 31, 1969 - Unknown | ||
N/A - Unknown | ||
N/A - Unknown | ||
N - Unknown | ||
NYSE - Stock exchange | ||
N - Unknown | ||
Altria Group - Company name | ||
|
||
OK, so after we smoke that tasty (oh so tasty!) tobacco, it's time for a Coke :) | ||
|
||
$ curl -i "http://www.nasdaq.com/quote.dll?page=dynamic&mode=data&symbol=KO&random=0.7634591432288283" | ||
HTTP/1.1 200 ok | ||
Content-Length: 127 | ||
Content-Type: text/plain | ||
Server: Microsoft-IIS/7.5 | ||
Date: Thu, 18 Aug 2011 06:01:57 GMT | ||
Connection: close | ||
|
||
*KO|69.28|1.11|1.63%|11,587,911|up|Y|$ 69.35|$ 68.16|KO|Dec. 31, 1969|N/A|N/A|N|NYSE|N|Coca-Cola Company (The)| | ||
|
||
= Price History | ||
|
||
Lets find the price history for KO. | ||
|
||
See the "5120" in the URL? The "5" means nothing to us, but the 120 is the | ||
number of months of data to return. 120 months is 10 years. But you can | ||
specify longer in the URL. Nasdaq only makes prices back to 2 Jan 1990 | ||
though. | ||
|
||
http://charting.nasdaq.com/ext/charts.dll?2-1-14-0-0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0-5120-03NA000000KO-&SF:4|5-WD=539-HT=395--XXCL- | ||
|
||
All of the pipe delimited "0,0,0,0,0" sets can be eliminated with no change | ||
to the output. Sweet. | ||
|
||
Here is 3 months of Altria price data | ||
|
||
http://charting.nasdaq.com/ext/charts.dll?2-1-14-0-0,0,0,0,00,0,0,0,0-5003-03NA000000MO-&SF:4|5-WD=539-HT=395--XCL- | ||
|
||
= Realtime Quotes | ||
|
||
Quote for KO | ||
|
||
== Request | ||
|
||
GET http://www.nasdaq.com/aspx/NLS/NLSHandler.ashx?msg=Last&Symbol=KO&QESymbol=KO | ||
|
||
== Response | ||
|
||
<DocumentElement> | ||
<Last> | ||
<totVol>1711</totVol> | ||
<high>67.8200</high> | ||
<low>67.2800</low> | ||
<Price>67.8200</Price> | ||
<ConsolidatedShares>2715</ConsolidatedShares> | ||
<ServerTime>9/23/2011 8:06:41 AM</ServerTime> | ||
<RefreshTime>35000</RefreshTime> | ||
<MarketStatus>C</MarketStatus> | ||
<MarketCloseTime>16:0</MarketCloseTime> | ||
<previousclose>67.82</previousclose> | ||
<tradedate>9/23/2011 8:06:41 AM</tradedate> | ||
</Last> | ||
</DocumentElement> | ||
|
||
|
||
= Charts | ||
|
||
The charts are rendered by URL's like this... | ||
|
||
http://charting.nasdaq.com/ext/charts.dll?2-1-14-0-0-51-03NA000000KO-&SF:1|8|5-SH:8=20-WD=539-HT=395- | ||
|
||
The SF:X parameter changes the type of chart. | ||
|
||
SF:1 | Mountain | ||
SF:4 | OHLC | ||
SF:6 | Candlestick | ||
SF:7 | Line | ||
SF:43 | Bar | ||
|
||
Other parameters | ||
|
||
WD | Width | ||
HT | Height | ||
|
||
Lower Studies | ||
|
||
The "5-SH" means that volume is rendered in the "lower studies" section at | ||
the bottom of the chart. | ||
|
||
"8=20" | Render the 20 day moving average | ||
"8=50" | Render the 50 day moving average | ||
|
||
50 day moving average | ||
|
||
http://charting.nasdaq.com/ext/charts.dll?2-1-14-0-0-51-03NA000000KO-&SF:1|8|5-SH:8=50-WD=539-HT=395- | ||
|
||
MACD | ||
|
||
The parameters "15=12,26,9" causes the lower studies section to show | ||
the MACD. | ||
|
||
Note that parameters are pipe delimited in the url in some places. | ||
|
||
http://charting.nasdaq.com/ext/charts.dll?2-1-14-0-0-51-03NA000000KO-&SF:1|8|15-SH:8=20|15=12,26,9-WD=539-HT=395- | ||
|
||
The "27=10" causes the rendering of the RSI (Relative Strength Index) | ||
|
||
http://charting.nasdaq.com/ext/charts.dll?2-1-14-0-0-51-03NA000000KO-&SF:1|8|27-SH:8=20|27=10-WD=539-HT=395- | ||
|
||
== Examples | ||
|
||
Mountain | ||
|
||
curl "http://charting.nasdaq.com/ext/charts.dll?2-1-14-0-0-51-03NA000000KO-&SF:1|8|5-SH:8=20-WD=539-HT=395-" > ko-mountain-1.gif | ||
|
||
OHLC | ||
|
||
curl "http://charting.nasdaq.com/ext/charts.dll?2-1-14-0-0-51-03NA000000KO-&SF:4|8|5-SH:8=20-WD=539-HT=395-" > ko-ohlc-1.gif | ||
|
||
Candlestick | ||
|
||
curl "http://charting.nasdaq.com/ext/charts.dll?2-1-14-0-0-51-03NA000000KO-&SF:6|8|5-SH:8=20-WD=539-HT=395-" > ko-candlestick-1.gif | ||
|
||
Line | ||
|
||
curl "http://charting.nasdaq.com/ext/charts.dll?2-1-14-0-0-51-03NA000000KO-&SF:7|8|5-SH:8=20-WD=539-HT=395-" > ko-line-1.gif | ||
|
||
Bar | ||
|
||
curl "http://charting.nasdaq.com/ext/charts.dll?2-1-14-0-0-51-03NA000000KO-&SF:43|8|5-SH:8=20-WD=539-HT=395-" > ko-bar-1.gif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
require "bundler/gem_tasks" | ||
require 'rake/testtask' | ||
|
||
# Host or location to copy gem to. At the moment this is only a local copy | ||
# operation | ||
GEM_LOCAL = "/Users/scott/.gems-repository" | ||
|
||
# Details of theremote server to upload the gem to | ||
GEM_HOST = "gems.signalvsnoise.com" | ||
GEM_HOST_USER = "root" | ||
SSH_KEY = "#{ENV['HOME']}/.ssh/scott-signalvsnoise.key" | ||
|
||
Rake::TestTask.new("test:units") { |test| | ||
%w{. lib test}.each { |dir| test.libs << dir } | ||
test.test_files = FileList["test/test_*.rb"].exclude("test/test_helper.rb", "test/vendor") | ||
test.verbose = false | ||
# test.warning = true | ||
} | ||
|
||
|
||
task :test => ["test:units"] | ||
|
||
def get_version | ||
Scottjbarr::Nasdaq::VERSION | ||
end | ||
|
||
task :upload_local do | ||
# place the gem in the local repository | ||
gem_file = "pkg/#{APP_NAME}-#{get_version}.gem" | ||
system "cp #{gem_file} #{GEM_LOCAL}/gems/" | ||
|
||
# update the gem index | ||
system "cd #{GEM_LOCAL} && gem generate_index -d ." | ||
end | ||
|
||
task :sync_remote do | ||
system "cd #{GEM_LOCAL} && rsync -auvz -e 'ssh -i #{SSH_KEY}' . #{GEM_HOST_USER}@#{GEM_HOST}:/var/www/gems/" | ||
end | ||
|
||
task :publish => [ :test, :build, :upload_local, :sync_remote ] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
require "scottjbarr-nasdaq/version" | ||
|
||
Dir.glob(File.dirname(__FILE__) + '/scottjbarr-nasdaq/*') { |file| require file } | ||
|
||
module Nasdaq | ||
SERVER = "www.nasdaq.com" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
require 'net/http' | ||
require 'cgi' | ||
require 'uri' | ||
require 'nokogiri' | ||
require 'hashie' | ||
require 'active_support/core_ext/string/inflections' | ||
|
||
module Nasdaq | ||
|
||
class Quote < Hashie::Dash | ||
|
||
property :symbol | ||
property :tot_vol | ||
property :high | ||
property :low | ||
property :price | ||
property :consolidated_shares | ||
property :server_time | ||
property :refresh_time | ||
property :market_status | ||
property :market_close_time | ||
property :previous_close | ||
property :trade_date | ||
|
||
INTEGER_FIELDS = %w(consolidated_shares refresh_time tot_vol) | ||
DECIMAL_FIELDS = %w(high low previous_close price) | ||
# DATE_FIELDS = %w(server_time trade_date) | ||
|
||
def market_open? | ||
market_status == "O" | ||
end | ||
|
||
def self.path(symbol) | ||
data = { | ||
:msg => "Last", | ||
:Symbol => symbol.upcase, | ||
:QESymbol => symbol.upcase | ||
} | ||
path = "/aspx/NLS/NLSHandler.ashx?#{get_form_data(data)}" | ||
end | ||
|
||
def self.uri(symbol) | ||
URI.parse("http://#{SERVER}#{path(symbol)}") | ||
end | ||
|
||
def self.for(symbol) | ||
uri = uri(symbol) | ||
http = Net::HTTP.new(uri.host, uri.port) | ||
response = http.get(uri.to_s) | ||
|
||
# p resp.status | ||
hash = parse(response.body) | ||
hash[:symbol] = symbol | ||
|
||
hash = cast_values(hash) | ||
Quote.new(hash) | ||
end | ||
|
||
def self.cast_values(hash) | ||
hash.each_pair do |k, v| | ||
if INTEGER_FIELDS.include?(k) | ||
hash[k] = v.to_i | ||
elsif DECIMAL_FIELDS.include?(k) | ||
hash[k] = v.to_f | ||
end | ||
end | ||
|
||
hash | ||
end | ||
|
||
# Convert a hash to an escaped query string | ||
def self.get_form_data(params) | ||
params.reduce("") { |m, v| m += "#{v[0]}=#{CGI.escape(v[1].to_s)}&" }.chop | ||
end | ||
|
||
def self.parse(body) | ||
xml = Nokogiri::XML(body) do |config| | ||
config.options = Nokogiri::XML::ParseOptions::STRICT | Nokogiri::XML::ParseOptions::NOENT | Nokogiri::XML::ParseOptions::NOBLANKS | ||
end | ||
|
||
hash = {} | ||
|
||
xml.xpath('//DocumentElement/Last').children.each do |node| | ||
hash[convert_name(node.name)] = node.text | ||
end | ||
|
||
hash | ||
end | ||
|
||
def self.convert_name(name) | ||
name = name.underscore | ||
|
||
if name == "previousclose" | ||
name = "previous_close" | ||
elsif name == "tradedate" | ||
name = "trade_date" | ||
end | ||
|
||
name | ||
end | ||
|
||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module Nasdaq | ||
VERSION = "0.0.1" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# -*- encoding: utf-8 -*- | ||
$:.push File.expand_path("../lib", __FILE__) | ||
require "scottjbarr-nasdaq/version" | ||
|
||
Gem::Specification.new do |s| | ||
s.name = "scottjbarr-nasdaq" | ||
s.version = Nasdaq::VERSION | ||
s.authors = ["Scott Barr"] | ||
s.email = ["[email protected]"] | ||
s.homepage = "" | ||
s.summary = %q{Scrape quotes from NASDAQ} | ||
s.description = %q{Scrape quotes from NASDAQ} | ||
|
||
s.rubyforge_project = "scottjbarr-nasdaq" | ||
|
||
s.files = `git ls-files`.split("\n") | ||
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") | ||
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } | ||
s.require_paths = ["lib"] | ||
|
||
# specify any dependencies here; for example: | ||
# s.add_development_dependency "rspec" | ||
# s.add_runtime_dependency "rest-client" | ||
end |
Oops, something went wrong.