1
0
Преглед на файлове

[finance] hodl sell and del

Innocenty Enikeew преди 8 години
родител
ревизия
d59b179941
променени са 1 файла, в които са добавени 61 реда и са изтрити 3 реда
  1. 61 3
      plugins/finance.lisp

+ 61 - 3
plugins/finance.lisp

@@ -167,8 +167,15 @@
   (db-execute "update finance_orders set amount = ?, close = ?, close_at = ? WHERE rowid = ?"
               amount close close-at row-id))
 
-(defun db/orders-get (chat-id)
-  (db-select "select rowid, user_id, user_name, symbol, amount, open, open_at, close, close_at from finance_orders where chat_id = ? order by open_at, close_at" chat-id))
+(defun db/order-del (row-id)
+  (db-execute "delete from finance_orders WHERE rowid = ?" row-id))
+
+(defun db/orders-get (chat-id &optional user-id symbol opened)
+  (db-select "select rowid, user_id, user_name, symbol, amount, open, open_at, close, close_at from finance_orders where chat_id = ? and (user_id = ? or ?) and (symbol = ? or ?) and (close is null or ?) order by open_at, close_at"
+             chat-id
+             user-id (if (or (null user-id) (member user-id *admins*)) 1 0)
+             symbol (if (null symbol) 1 0)
+             (if opened 0 1)))
 
 ;; Cron
 (defcron process-rates ()
@@ -246,7 +253,9 @@
           (get-symbol-label (agets info :symbol))
           (format-ts (local-time:unix-to-timestamp (agets info :open-at)))
           (agets info :open)
-          (if (> (or (agets info :income) 0) 0) "📈" "📉")
+          (if (agets info :open-p)
+              (if (> (or (agets info :income) 0) 0) "📈" "📉")
+              (if (> (or (agets info :income) 0) 0) "🏆" "🐟"))
           (if (agets info :open-p) "now"
               (format-ts (local-time:unix-to-timestamp (agets info :close-at))))
           (or (agets info :close) 0)
@@ -276,9 +285,58 @@
       (log:error "~A" e)
       (bot-send-message chat-id "/hodl buy <SYM> <AMT> <PRICE> [YYYY-MM-DD]"))))
 
+(defun handle-hodl-sell (chat-id from args)
+  (handler-case
+      (let* ((symbol (get-label-symbol (nth 1 args)))
+             (amount (parse-float (nth 2 args)))
+             (close (parse-float (nth 3 args)))
+             (close-at (if (nth 4 args) (local-time:parse-timestring (nth 4 args)) (local-time:now)))
+             (user-id (agets from "id"))
+             (orders (db/orders-get chat-id user-id symbol t))
+             (total-amount (apply #'+ (mapcar #'(lambda (o) (parse-float (nth 4 o))) orders))))
+        (if (> amount total-amount)
+            (bot-send-message chat-id (format nil "Нет у тебя столько ~A! (не хватает ~A)"
+                                              (nth 1 args)
+                                              (- amount total-amount)))
+            (progn
+              (loop for order in orders
+                 for order-amount = (parse-float (nth 4 order))
+                 while (> amount 0)
+                 when (> order-amount amount)
+                 do (db/order-buy chat-id (nth 1 order) (nth 2 order) (nth 3 order)
+                                  (princ-to-string (- order-amount amount))
+                                  (nth 5 order) (nth 6 order))
+                 do (progn
+                      (db/order-sell (nth 0 order)
+                                          (princ-to-string (min amount order-amount))
+                                          (princ-to-string close)
+                                          (local-time:timestamp-to-unix close-at))
+                      (decf amount order-amount)))
+              (handle-hodl-show chat-id))))
+    (error (e)
+      (log:error "~A" e)
+      (bot-send-message chat-id "/hodl sell <SYM> <AMT> <PRICE> [YYYY-MM-DD]"))))
+
+(defun handle-hodl-del (chat-id from args)
+  (handler-case
+      (let* ((symbol (get-label-symbol (nth 1 args)))
+             (amount (or (nth 2 args) (error "no amount")))
+             (order (find amount (db/orders-get chat-id (agets from "id") symbol)
+                          :key #'(lambda (r) (nth 4 r)) :test #'equal)))
+        (if order
+            (progn
+              (db/order-del (car order))
+              (handle-hodl-show chat-id))
+            (bot-send-message chat-id (format nil "Не нашёл ~A ~A :(" amount (nth 1 args)))))
+    (error (e)
+      (log:error "~A" e)
+      (bot-send-message chat-id "/hodl del <SYM> <AMT>"))))
+
 (def-message-cmd-handler handle-hodl (:hodl :hodlers)
   (cond
     ((equal (car args) "buy") (handle-hodl-buy chat-id (agets message "from") args))
+    ((equal (car args) "sell") (handle-hodl-sell chat-id (agets message "from") args))
+    ((equal (car args) "del") (handle-hodl-del chat-id (agets message "from") args))
     (:otherwise (handle-hodl-show chat-id))))