Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ autodoc/**
/lib/
/classes/
.lein-deps-sum

.lein-failures
9 changes: 5 additions & 4 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
(defproject com.fxtlabs/stockings "1.1.0-SNAPSHOT"
(defproject com.fxtlabs/stockings "1.2.0-SNAPSHOT"
:description "Easy access to financial data: stock quotes, exchange rates, industry sectors, companies, and more."
:url "https://github.com/fxtlabs/stockings"
:dependencies [[org.clojure/clojure "1.2.1"]
:dependencies [[org.clojure/clojure "1.4.0"]
[joda-time "1.6"]
[clojure-csv "1.2.4"]
[clj-http "0.1.3"]]
[clj-http "0.1.3"]
[org.clojure/data.csv "0.1.2"]
[org.clojure/data.json "0.1.3"]]
:dev-dependencies
[[com.fxtlabs/autodoc "0.8.0-SNAPSHOT"
:exclusions [org.clojure/clojure org.clojure/clojure-contrib]]]
Expand Down
7 changes: 3 additions & 4 deletions src/stockings/alt.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from Google Finance."
{:author "Filippo Tampieri <[email protected]>"}
(:use [clojure.string :only (join split-lines)]
[clojure.contrib.def :only (defvar-)]
[stockings.utils :only (parse-double parse-int parse-long parse-keyword)]
[stockings.core :only (bare-stock-symbol)])
(:require [clojure.xml :as xml]
Expand All @@ -18,7 +17,7 @@
;;; Get current quotes
;;;

(defvar- date-time-parser
(def date-time-parser
(.withZone (DateTimeFormat/forPattern "yyyyMMddHHmmss") DateTimeZone/UTC))

(defn- parse-date-time
Expand Down Expand Up @@ -92,14 +91,14 @@
;;; Get historical quotes
;;;

(defvar- date-parser (DateTimeFormat/forPattern "dd-MMM-yy"))
(def date-parser (DateTimeFormat/forPattern "dd-MMM-yy"))

(defn- parse-date
"Parse a string representing a date into a `org.joda.time.LocalDate` object."
[^String s]
(.toLocalDate (.parseDateTime date-parser s)))

(defvar- re-line
(def re-line
#"((?:[0-9]|[123][0-9])-\w{3}-[0-9]{2}),([0-9]+(?:\.[0-9]*)?),([0-9]+(?:\.[0-9]*)?),([0-9]+(?:\.[0-9]*)?),([0-9]+(?:\.[0-9]*)?),([0-9]+(?:\.[0-9]*)?)"
"The regular expression used to match one line in the CSV-encoded quotes.
It matches a line in the form `Date,Open,High,Low,Close,Volume`
Expand Down
24 changes: 12 additions & 12 deletions src/stockings/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
from Yahoo! Finance."
{:author "Filippo Tampieri <[email protected]>"}
(:use [clojure.string :only (split join lower-case)]
[clojure.contrib.def :only (defvar defvar-)]
[clojure.contrib.json :only (read-json)])
[clojure.data.json :only (read-json)])
(:require [clj-http.client :as client]
[stockings.utils :as yql])
(:import (org.joda.time LocalDate LocalTime DateTimeZone)
Expand Down Expand Up @@ -78,7 +77,7 @@
;;; WARNING: use it only for data retrieved from the quotes.csv
;;; service above!

(defvar- nyc-date-time-zone
(def nyc-date-time-zone
(DateTimeZone/forTimeZone (TimeZone/getTimeZone "America/New_York")))

(defn get-correct-date-time [^LocalDate date ^LocalTime time]
Expand All @@ -90,7 +89,10 @@
;;; Get current quotes
;;;

(defvar- quote-parse-map
(def quote-parse-map
"A map from the keys of a raw stock quote to the parsers used to parse
the corresponding value strings of the raw stock quote into useful
typed values (ints, doubles, dates, etc.)."
{:symbol identity
:Name identity
:PERatio yql/parse-double
Expand Down Expand Up @@ -143,17 +145,15 @@
:PERatioRealtime yql/parse-double
:PriceEPSEstimateNextYear yql/parse-double
:EPSEstimateNextQuarter yql/parse-double
:PriceEPSEstimateCurrentYear yql/parse-double}
"A map from the keys of a raw stock quote to the parsers used to parse
the corresponding value strings of the raw stock quote into useful
typed values (ints, doubles, dates, etc.).")
:PriceEPSEstimateCurrentYear yql/parse-double})

(defvar raw-quote-keys (keys quote-parse-map)
(def raw-quote-keys
"A list of all the keys available in a raw stock quote. A custom stock
quote can be created by supplying `get-quote` with a parser capable of
extracting the value corresponding to a chosen subset of these keys
from a raw stock quote and packaging them into the desired result
structure.")
structure."
(keys quote-parse-map))

(defn parse-quote-item
"Looks up the value of a supplied key into a raw stock quote and
Expand Down Expand Up @@ -187,7 +187,7 @@
(apply hash-map
(mapcat (fn [[k v]] [k (parse-quote-item raw-quote v)]) key-map))))

(defvar- default-key-map
(def default-key-map
{:symbol :symbol
:name :Name
:last :LastTradePriceOnly
Expand All @@ -197,7 +197,7 @@
:low :DaysLow
:volume :Volume})

(defvar- default-quote-parser* (build-quote-parser default-key-map))
(def default-quote-parser* (build-quote-parser default-key-map))

(defn default-quote-parser
"The quote parser used by `get-quote` and `get-quotes` when a custom quote
Expand Down
39 changes: 19 additions & 20 deletions src/stockings/exchanges.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,38 @@
by the NASDAQ at <http://www.nasdaq.com/screening/company-list.aspx>."
{:author "Filippo Tampieri <[email protected]>"}
(:use [clojure.string :only (split lower-case upper-case)]
[clojure.contrib.def :only (defvar defvar-)]
[clojure-csv.core :only (parse-csv)]
[clojure.data.csv :as csv]
[stockings.core :only (explode-stock-symbol)])
(:require [clj-http.client :as client]))

;;;
;;; Stock Exchanges
;;;

(defvar nasdaq
{:name "NASDAQ Stock Market", :symbol "NASDAQ"}
"A map describing the NASDAQ Stock Market (NASDAQ).")
(def nasdaq
"A map describing the NASDAQ Stock Market (NASDAQ)."
{:name "NASDAQ Stock Market", :symbol "NASDAQ"})

(defvar nyse
{:name "New York Stock Exchange", :symbol "NYSE"}
"A map describing the New York Stock Exchange (NYSE).")
(def nyse
"A map describing the New York Stock Exchange (NYSE)."
{:name "New York Stock Exchange", :symbol "NYSE"})

(defvar amex
{:name "NYSE Amex Equities", :symbol "AMEX"}
"A map describing the NYSE Amex Equities (AMEX).")
(def amex
"A map describing the NYSE Amex Equities (AMEX)."
{:name "NYSE Amex Equities", :symbol "AMEX"})

(defvar exchanges
(def exchanges
"A map from stock exchange keywords to stock exchange info maps."
{:amex amex,
:nasdaq nasdaq
:nyse nyse}
"A map from stock exchange keywords to stock exchange info maps.")
:nyse nyse})

;;;
;;; Industry Sectors
;;;

(defvar industry-sectors
(def industry-sectors
"A list of the major industry sectors as classified by the NASDAQ."
["Basic Industries"
"Capital Goods"
"Consumer Durables"
Expand All @@ -47,14 +47,13 @@
"Miscellaneous"
"Public Utilities"
"Technology"
"Transportation"]
"A list of the major industry sectors as classified by the NASDAQ.")
"Transportation"])

;;;
;;; Companies
;;;

(defvar- source-url "http://www.nasdaq.com/screening/companies-by-name.aspx")
(def source-url "http://www.nasdaq.com/screening/companies-by-name.aspx")

;; Use a record instead of a map for efficiency since the lists of
;; companies are pretty long.
Expand All @@ -68,7 +67,7 @@
[r]
(and
(vector? r)
(= 9 (count r))
(= 10 (count r))
(< 0 (count (first r)))))

(defn- convert-record
Expand Down Expand Up @@ -99,7 +98,7 @@
industry for each company."
[exchange-key ^String s]
(->> s
parse-csv
csv/read-csv
rest
(filter valid-record?)
(map (partial convert-record exchange-key))))
Expand Down
12 changes: 6 additions & 6 deletions src/stockings/utils.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
(Yahoo! Query Language) and parse a variety of value types."
{:author "Filippo Tampieri <[email protected]>"}
(:use [clojure.string :only (join lower-case)]
[clojure.contrib.def :only (defvar defvar-)]
[clojure.contrib.json :only (read-json)])
[clojure.data.json :only (read-json)])
(:require [clj-http.client :as client])
(:import (org.joda.time DateTime LocalDate)
(org.joda.time.format DateTimeFormat)))

(defvar- yql-base-url "http://query.yahooapis.com/v1/public/yql")
(def yql-base-url "http://query.yahooapis.com/v1/public/yql")

(defn yql-string
"String values in a YQL query must be enclosed in double quotes.
Expand Down Expand Up @@ -51,6 +50,7 @@
(let [payload (-> response :body strip-wrapper read-json)]
(if-let [error (:error payload)]
(throw (Exception. (:description error))))
; (print (:quote (:results (:query payload))))
(:results (:query payload)))))

(defn map-parser
Expand Down Expand Up @@ -91,7 +91,7 @@
(if-let [m (re-matches #"(?:\+|\-)?\d+" s)]
(Long/parseLong m 10))))

(defvar- multipliers
(def multipliers
{"B" 1.0e9
"M" 1.0e6
"K" 1.0e3})
Expand All @@ -117,7 +117,7 @@
(if-let [m (re-matches #"((?:\+|\-)?\d+(?:\.\d*)?)%" s)]
(/ (Double/parseDouble (second m)) 100.0))))

(defvar- date-parsers
(def date-parsers
[(DateTimeFormat/forPattern "yyyy-MM-dd")
(DateTimeFormat/forPattern "M/dd/yyyy")])

Expand All @@ -133,7 +133,7 @@
:when d]
(.toLocalDate d)))))

(defvar- time-parser (DateTimeFormat/forPattern "hh:mmaa"))
(def time-parser (DateTimeFormat/forPattern "hh:mmaa"))

(defn parse-time
"If the supplied string represents a valid time in the hh:mmaa format
Expand Down