1
0

finance.lisp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. (in-package #:chatikbot)
  2. (defparameter +yahoo-url+ "https://query.yahooapis.com/v1/public/yql" "Yahoo Finance API endpoint")
  3. (defparameter +yahoo-query+ "select Name,Rate from yahoo.finance.xchange where pair in (~{\"~A\"~^,~})")
  4. (defparameter +brent-url+ "http://www.cmegroup.com/CmeWS/mvc/Quotes/Future/424/G")
  5. (defvar *rate-pairs* '("USDRUB" "EURRUB" "GBPRUB"))
  6. (defun get-rates (&optional (pairs *rate-pairs*))
  7. (let ((response (json-request
  8. +yahoo-url+
  9. :parameters (append '(("format" . "json")
  10. ("env" . "store://datatables.org/alltableswithkeys"))
  11. (list (cons "q" (format nil +yahoo-query+ pairs)))))))
  12. (when (aget "error" response)
  13. (error "Error in rates request"))
  14. (loop for rate in (aget "rate" (aget "results" (aget "query" response)))
  15. collect (cons (aget "Name" rate)
  16. (read-from-string (aget "Rate" rate))))))
  17. (defun get-brent ()
  18. (handler-case
  19. (let ((last (read-from-string
  20. (aget "last" (first (aget "quotes" (json-request +brent-url+)))))))
  21. (when (numberp last)
  22. last))
  23. (error (e) (log:error e))))
  24. (defparameter +btc-e-usd-url+ "https://btc-e.com/api/2/btc_usd/ticker" "BTC-e BTC/USD ticker url")
  25. (defun get-btc-e ()
  26. (handler-case
  27. (aget "last" (aget "ticker" (json-request +btc-e-usd-url+)))
  28. (error (e) (log:error e))))
  29. (defun get-serie (series idx)
  30. (loop for row in series
  31. when (elt row idx)
  32. collect (list (first row) (elt row idx))))
  33. (defun range (seq &key (key 'identity))
  34. (loop
  35. for item in seq
  36. for value = (funcall key item)
  37. minimizing value into min
  38. maximizing value into max
  39. finally (return (values min max))))
  40. (defvar *chart-points* 800 "Data points in chart")
  41. (defun make-chart (series names)
  42. (let* ((r (multiple-value-list (range series :key #'car)))
  43. (fmt (if (<= (- (second r) (first r))
  44. (* 60 60 36))
  45. '((:hour 2) ":" (:min 2))
  46. '((:day 2) "." (:month 2) " " (:hour 2) ":" (:min 2)))))
  47. (adw-charting:with-line-chart ((+ 90 *chart-points*)
  48. (floor (* 3 *chart-points*) 4))
  49. (loop for serie in names
  50. for idx from 1
  51. do (adw-charting:add-series serie (get-serie series idx)))
  52. (adw-charting:set-axis
  53. :x "Time" :draw-gridlines-p t
  54. :label-formatter #'(lambda (v)
  55. (local-time:format-timestring
  56. nil
  57. (local-time:unix-to-timestamp v)
  58. :format fmt)))
  59. (adw-charting:set-axis :y "RUB" :draw-gridlines-p t :label-formatter "~,2F")
  60. (adw-charting:save-file "chart.png"))))