1 Introduction
2 Objects
4 Parsing
5 Network
6 Known Issues
7 History
8 Legal

kitco: Kitco Precious Metals Market Info. Access from Racket

Neil Van Dyke

 (require (planet neil/kitco:1:1))

1 Introduction

This 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 (for writing as XML).
This is useful for research, for hobby experimentation, and for 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")
                (pm (@ (name "palladium")
          (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")))
(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)
> (kitco-pm-ask gold)
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.

2 Objects


(struct kitco-pm (name
  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.

4 Parsing


(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.

5 Network


(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"))
(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.

6 Known Issues

7 History

8 Legal

Copyright 2013 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.