App-Chart
view release on metacpan or search on metacpan
lib/App/Chart/Suffix/LME.pm view on Meta::CPAN
(chart-symbol-mdate symbol))
(lat (string-append commodity ".LME")))
# all rows with month in symbol
(lat symbol))))
commodity-list buyer-row seller-row))
row-list)))
(and-let* ((m (string-match "LMEX Index value [^0-9\n]*([0-9]+ [A-Za-z]+ [0-9][0-9][0-9][0-9])[^0-9.\n]+([0-9.]+)" body)))
(set! ret (cons (list "LMEX.LME"
#f
(d/m/y-str->tdate (match:substring m 1))
#f # no separate buy price
(match:substring m 2)
#f)
ret)))
ret)
(define (daily-latest-parse body)
(list
(cons 'form (html-form-parse body))
(cons 'prices (daily-html-parse body))))
(define (daily-latest-info type)
(lme-ensure-login)
(pagebits-read #:filename (case type
((metals) "lme-latest-metals")
((plastics) "lme-latest-plastics"))
#:status (list (_ "LME")
(case type
((metals) (_ "metals latest"))
((plastics) (_ "plastics latest"))))
#:url (list (case type
((metals)
((plastics) "https://secure.lme.com/Data/community/Dataprices_daily_prices_plastics.aspx"))
#:cookiejar lme-cookiejar-filename
#:follow #f)
#:timezone (timezone-london)
#:parse daily-latest-parse))
#-----------------------------------------------------------------------------
# latest
#
# This uses the daily prices in the login "free data service", login
# required, at
#
# https://secure.lme.com/Data/community/Dataprices_daily_metals.aspx
#
# This plain url gives the most recent prices, which we take as a quote for
# the indicated day then work back with form-data fetching previous days to
# find price change amounts. Or the database is used if it covers the
# desired symbol(s).
#
# Unfortunately there's no Last-Modified or ETag to save refetching if the
# latest GET contents have not yet updated. (???)
(define (lme-latest-update-database type newest-data prev-data)
(let* ((end-tdate (data-tdate newest-data))
(start-tdate (if prev-data
(data-tdate prev-data)
end-tdate))
(db-list (download-also '() #:selector (lme-type->selector type)
#:start-tdate start-tdate
#:end-tdate end-tdate)))
(if prev-data
(daily-process db-list prev-data))
(daily-process db-list newest-data)))
(define (lme-latest-process newest-data prev-data proc)
(define lst '())
(for-each
(lambda (elem)
(receive-list (symbol name tdate buy sell mdate)
elem
(and-let* ((prev-elem (assoc symbol prev-data))) # match car
(let ((prev-sell (fifth prev-elem)))
(receive-list (decimals buy sell prev-sell)
(strings->numbers+decimals buy sell prev-sell)
# need both buy and sell to show as quote
(define bid buy)
(define offer (and buy sell))
(define quote-tdate (and buy sell tdate))
# sell is normally always present, but have seen entire page
# blank (empty fields "" which become #f) 31aug05 after
# 29aug05 bank holiday
(set! lst
(cons (latest-new #:symbol symbol
#:name name
#:quote-tdate quote-tdate
#:bid bid
#:offer offer
#:last-tdate tdate
#:last sell
#:prev prev-sell
#:decimals decimals
#:contract-mdate mdate
#:source 'lme)
lst)))))))
newest-data)
(proc lst))
(define (lme-latest-type symbol-list type proc)
(and-let* ((newest-data (assq-ref (daily-latest-info type) 'prices)))
# COVERED-TDATE is the data we already have for all of SYMBOL-LIST (or
# rather for the worst among that list), default to a dummy 100 days
( run in 2.137 seconds using v1.01-cache-2.11-cpan-483215c6ad5 )