2:1
kitco: Precious Metals Market Info. Access🔗ℹ
The
kitco package provides a Racket interface for accessing the precious
metal market spot prices published on the Web by Kitco Metals, Inc. The
information is represented in Racket as either Racket objects (structs), or
as
SXML.
This is useful for research, educational exercises, hobby
experimentation, and prototyping Web apps. Please note that this is not for mission-critical use; once your app is advancing from
prototype to production use, you normally will want to have a contract with a
data service that can offer guarantees about reliability and correctness.
For example, here is a use of this package to fetch the information
and return it in SXML format (using dummy information, and with some parts
elided):
> (current-kitco-user-agent "Mozilla (my app) Firefox/NOT")
> (get-kitco-market-sxml)
(market (spot (@ (name "newyork") |
(timestamp "2000-12-25T12:34:56") |
(status "open")) |
(pm (@ (name "gold") |
(bid "900.0") |
(ask "909.09") |
(change "10.0") |
(change-percent "1.0") |
(low "888.88") |
(high "999.99"))) |
(pm (@ (name "silver") |
(bid "50.0") |
(ask "50.01") |
(change "-5.5") |
(change-percent "-10.10") |
(low "49.49") |
(high "51.50"))) |
(pm (@ (name "platinum") |
...attributes...)) |
(pm (@ (name "palladium") |
...attributes...))) |
(spot (@ (name "eurasia") |
(timestamp "2000-12-25T12:34:56") |
(status "closed")) |
(pm (@ (name "gold") |
(bid "901.0") |
(ask "902.0") |
(ny-change "1.0") |
(ny-change-percent "0.5"))) |
...pms...)) |
(See the documentation for current-kitco-user-agent, for why we say “Mozilla” and “Firefox” here.)
For another example, here is getting the information into a graph
of objects and navigating the graph to get the New York Gold bid and ask
prices:
> (current-kitco-user-agent "Mozilla (my app) Firefox/NOT")
> (define km (get-kitco-market))
> (define spot (kitco-market-newyork-spot km))
> (define pms (kitco-spot-pm-hash spot))
> (define gold (hash-ref pms 'gold))
> (kitco-pm-bid gold) |
900.05 |
> (kitco-pm-ask gold) |
900.1 |
Please note that you should not rely on this package, nor on this
data feed. If someday it says silver is back up to 50, double-check with
authoritative sources before you quit your job. And don’t assume that this
data feed won’t suddenly stop working without warning. And under no
circumstances should you even think of suing the author of this package.
This package is independent of Kitco Metals, Inc., and they are not
responsible in any way for this package, nor are we aware that they offer any
guarantees about the data that this package accesses.
(struct | | kitco-pm | ( | name | | | | | bid | | | | | ask | | | | | change | | | | | change-percent | | | | | low | | | | | high | | | | | ny-change | | | | | ny-change-percent)) |
|
name : symbol? |
bid : number? |
ask : number? |
change : (or/c #f number?) |
change-percent : (or/c #f number?) |
low : (or/c #f number?) |
high : (or/c #f number?) |
ny-change : (or/c #f number?) |
ny-change-percent : (or/c #f number?) |
This struct represents information about a single precious metal, and is associated with a single kitco-spot. The name field value is a symbol such as 'gold. Note that New York data will not use the ny-change and ny-change-percent fields, but Europe/Asia data currently does.
(struct kitco-spot (name timestamp-string status pm-hash))
|
name : symbol? |
timestamp-string : string? |
status : (or/c 'open 'closed) |
pm-hash : (hash/c symbol? kitco-pm?) |
This struct represents spot prices on a particular region’s exchange(s). The name field is a symbol – either 'newyork or 'eurasia. timestamp-string is in human-readable ISO 8601 format. pm-hash is a hash of symbols (e.g., 'gold, like the name field of kitco-pm) to kitco-pm objects.
(struct kitco-market (newyork-spot eurasia-spot))
|
newyork-spot : (or/c #f kitco-spot?) |
eurasia-spot : (or/c #f kitco-spot?) |
This struct represents the entirety of the market data received
from a request, such as by get-kitco-market.
(kitco-pm->sxml x) → sxml?
|
x : kitco-pm? |
(kitco-spot->sxml x) → sxml? |
x : kitco-spot? |
(kitco-market->sxml x) → sxml? |
x : kitco-market? |
Convert the object to SXML format.
Note that the ordering of the XML pm elements within a spot element is undefined.
(parse-kitco-market-html in) → kitco-market?
|
in : input-port? |
Parses HTML from the Kitco Market Web page, from input port in. Note that usually you will call get-kitco-market or get-kitco-market-sxml rather than calling this parsing procedure directly.
(parse-kitco-market-html-string str) → kitco-market?
|
str : string? |
Like parse-kitco-market-html but takes a string rather than an input port.
(current-kitco-market-url) → url?
|
(current-kitco-market-url url) → void? |
url : url? |
A URL used internally by get-kitco-market and get-kitco-market-sxml. You should not normally change this except for testing or
simulation.
(current-kitco-user-agent) → string?
|
(current-kitco-user-agent str) → void? |
str : string? |
String for the default value of HTTP header User-Agent.
In general, you should use a different user agent string for each
app that you make. For example, if your app is named NW-O-Matic, do something
like:
(define km |
(parameterize ((current-kitco-user-agent |
"Mozilla (NW-O-Matic) Firefox/NOT")) |
(get-kitco-market))) |
or:
(current-kitco-user-agent "Mozilla (NW-O-Matic) Firefox/NOT") |
(define km (get-kitco-market)) |
or use a "#:user-agent" command-line argument instead of the parameter:
(define km |
(get-kitco-market #:user-agent "Mozilla (NW-O-Matic) Firefox/NOT")) |
The reason for including keywords like “Mozilla” and
“Firefox” is historical: in the early days of Web browsers, a very small
number of Web sites used the user agent string to detect Netscape (nee Mosaic
Communications) Navigator (based on “Mozilla”, the publicly-known internal
name for Navigator, in the user agent string) and send different HTML to it
than for other browsers; browsers like Microsoft Internet Explorer began
sending user agent strings that also included the string “Mozilla”. This
remains a convention, even after a well-known Netscape spinoff eventually
adopted the internal “Mozilla” name as its corporate name.
(get-kitco-market [#:user-agent user-agent]) → kitco-market?
|
user-agent : string? = #f |
Get a kitco-market object by making an HTTP request and parsing the result.
If user-agent is #f, the value of the current-kitco-user-agent parameter is used. See the documentation for that parameter for
why you should specify a user agent specific to your app.
Please note that, since this procedure makes HTTP requests of an
external server operated by someone else, it is important not to abuse the
server with requests that are too frequent.
(get-kitco-market-sxml [#:user-agent user-agent]) → sxml?
|
user-agent : string? = #f |
Like get-kitco-market, but returns SXML rather than a kitco-market object. See the documentation for get-kitco-market.
Find out for-pay sources of same information, with some service
guarantees, and perhaps offer an interface to those, too.
Parse London Fix section, and add it to market struct.
Pull timestamp out of any “File created on” towards bottom of page, and add it to the market struct.
Add custom-writers for structs.
In SXML format, sort the PMs, either alphabetically, or in the default Kitco order.
Version 2:1 — 2016-03-01
For get-kitco-market-sxml, the ordering of pm elements is now deterministic, for a given version of
this package, simplifying automated test suites.
Fixed intermittently failing test.
Version 2:0 — 2016-02-27
Version 1:1 — 2013-09-30
Version 1:0 — 2013-09-30
Copyright 2013, 2016 Neil Van Dyke. This program is Free Software; you can
redistribute it and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version. This program is distributed in
the hope that it will be useful, but without any warranty; without even the
implied warranty of merchantability or fitness for a particular purpose. See
http://www.gnu.org/licenses/ for details. For other licenses and consulting,
please contact the author.