Browse Source

Brent futures

Innokenty Enikeev 10 years ago
parent
commit
30443cdfe2
3 changed files with 37 additions and 8 deletions
  1. 16 6
      chatikbot.lisp
  2. 18 1
      finance.lisp
  3. 3 1
      utils.lisp

+ 16 - 6
chatikbot.lisp

@@ -179,7 +179,9 @@
 (defun process-rates ()
   (handler-case
       (push-circular (cons (local-time:timestamp-to-unix (local-time:now))
-                           (get-rates))
+                           (list* (cons "Brent"
+                                        (get-brent))
+                                  (get-rates)))
                      *per-minute-rates*)
     (error (e) (log:error e))))
 
@@ -187,8 +189,11 @@
   (log:info "handle-cmd-rates" chat-id message-id args)
   (let ((rates (rest (peek-circular *per-minute-rates*))))
     (telegram-send-message chat-id
-                           (format nil "Зеленый ~A, гейро ~A, британец ~A"
-                                   (cdar rates) (cdadr rates) (cdaddr rates)))))
+                           (format nil "Зеленый ~A, гейро ~A, британец ~A, чёрная ~A"
+                                   (aget "USD/RUB" rates)
+                                   (aget "EUR/RUB" rates)
+                                   (aget "GBP/RUB" rates)
+                                   (aget "Brent" rates)))))
 
 (defun handle-cmd-charts (chat-id message-id args)
   (log:info "handle-cmd-charts" chat-id message-id args)
@@ -197,13 +202,18 @@
       (let* ((usd (or (null args) (find "usd" args :test #'equal)))
              (eur (or (null args) (find "eur" args :test #'equal)))
              (gbp (or (null args) (find "gbp" args :test #'equal)))
+             (brent (or (null args) (find "brent" args :test #'equal)))
              (rates (rest (peek-circular *per-minute-rates*))))
         (if (or usd eur gbp)
           (telegram-send-photo chat-id
                                (make-chart *per-minute-rates*
-                                           :usd usd :eur eur :gbp gbp)
-                               :caption (format nil "Зеленый ~A, гейро ~A, британец ~A"
-                                                (cdar rates) (cdadr rates) (cdaddr rates)))
+                                           :usd usd :eur eur
+                                           :gbp gbp :brent brent)
+                               :caption (format nil "Зеленый ~A, гейро ~A, британец ~A, чёрная ~A"
+                                                (aget "USD/RUB" rates)
+                                                (aget "EUR/RUB" rates)
+                                                (aget "GBP/RUB" rates)
+                                                (aget "Brent" rates)))
           (telegram-send-message chat-id "Хуй тебе")))
     (error (e)
       (log:error e)

+ 18 - 1
finance.lisp

@@ -3,6 +3,8 @@
 (defparameter +yahoo-url+ "https://query.yahooapis.com/v1/public/yql" "Yahoo Finance API endpoint")
 (defparameter +yahoo-query+ "select Name,Rate from yahoo.finance.xchange where pair in (~{\"~A\"~^,~})")
 
+(defparameter +brent-url+ "http://www.cmegroup.com/CmeWS/mvc/Quotes/Future/424/G")
+
 (defvar *rate-pairs* '("USDRUB" "EURRUB" "GBPRUB"))
 
 (defun get-rates (&optional (pairs *rate-pairs*))
@@ -20,12 +22,25 @@
        collect (cons (aget "Name" rate)
                      (read-from-string (aget "Rate" rate))))))
 
+(defun get-brent ()
+  (handler-case
+      (read-from-string
+       (aget "last" (first (aget "quotes"
+                                 (yason:parse
+                                  (flexi-streams:octets-to-string
+                                   (drakma:http-request +brent-url+
+                                                        :force-binary t
+                                                        :decode-content t)
+                                   :external-format :utf-8)
+                                  :object-as :alist)))))
+    (error (e) (log:error e))))
+
 (defun get-serie (series name)
   (loop for (time . rates) in series
      when (aget name rates)
      collect (list time (aget name rates))))
 
-(defun make-chart (series &key (usd t) (eur t) (gbp t))
+(defun make-chart (series &key (usd t) (eur t) (gbp t) (brent t))
   (let ((flat (remove-if #'null (if (alexandria:circular-list-p series)
                                      (flat-circular series)
                                      series))))
@@ -33,6 +48,8 @@
       (when usd (adw-charting:add-series "USD/RUB" (get-serie flat "USD/RUB")))
       (when eur (adw-charting:add-series "EUR/RUB" (get-serie flat "EUR/RUB")))
       (when gbp (adw-charting:add-series "GBP/RUB" (get-serie flat "GBP/RUB")))
+      (when brent (adw-charting:add-series "Brent last day futures"
+                                           (get-serie flat "Brent")))
       (adw-charting:set-axis
        :x "Time" :draw-gridlines-p t
        :label-formatter #'(lambda (v) (local-time:format-timestring nil (local-time:unix-to-timestamp v)

+ 3 - 1
utils.lisp

@@ -114,4 +114,6 @@ is replaced with replacement."
                                      (not (find "Etc" (pathname-directory file) :test #'string=))))
       (cl-fad:walk-directory (merge-pathnames "Etc/" root-directory) #'visitor :directories nil))))
 
-(local-time:reread-timezone-repository :timezone-repository "/usr/share/zoneinfo/")
+(let ((zonepath "/usr/share/zoneinfo/"))
+  (when (directory zonepath)
+    (local-time:reread-timezone-repository :timezone-repository zonepath)))