ns watcher core require postal core as postal postal sendmail as local

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
(ns watcher.core
(:require [postal.core :as postal]
[postal.sendmail :as local]
[postal.smtp :as smtp]
[clj-http.client :as client]
[clojure.data.json :as json]
[clj-time.local :as l]
(:require [watcher.log :as log])
(:gen-class))
;;;;;; constants ;;;;;;
(def zoho (read-string (slurp "zoho.edn"))) ; mail config
(def tr 0.001)
(def trminus (* tr -1))
(def sec 1000)
(def minute (* 60 sec))
(def waitp minute)
(def totalwait (* 3 60)) ; 3hours. totalwait * waitp
(def intervalstep 30) ; every 30 minutes notify
(def title "btcusd notify")
(def titleshutdown "btcusd watch")
(def titlestartup "startup btcusd watch")
(def recp "ben@gmail.com")
(def frommail "ben@metaexchange.io")
(def btcusd-price (atom -1))
(def btcusd-prev (atom -1))
(def delta (atom -1))
(def maxd (atom -1))
(def mind (atom 1))
(def nfirst (atom false))
(def ptimestamp (atom nil))
(def ptimestamp-prev (atom nil))
(defn sendmailinfo
"send signup via email"
[info subj]
(log/info "sending mail " info)
(postal/send-message
zoho {:from frommail :to [recp] :subject subj :body (str info)}))
;;;;;; functions ;;;;;;
(defn formatDouble [t]
(format "%.3f" (double (* t 100))))
(defn mailstr [t]
(str (formatDouble t) " % in the last " (/ waitp 1000)
" seconds. \n" "btcusd: " @btcusd-price "\nlast " @btcusd-prev)
"\n" (l/local-now))
(defn sendmailtresh []
(sendmailinfo (str (mailstr @delta)
"\nbids " @polobids "\nasks: " @poloasks) title))
(defn btce []
(json/read-str (get (client/get "https://btc-e.com/api/3/ticker/btc_usd" {:query-params {}}) :body)))
(defn roc [cur prev]
"rate of change"
(let [d (- cur prev)]
(/ d cur)))
(defn currentROC []
"current rate of change"
(roc @btcusd-price @btcusd-prev))
;;;;;; updates ;;;;;;
(defn parse-number
"Reads a number from a string. Returns nil if not a number."
[s]
(if (re-find #"^-?\d+\.?\d*$" s)
(read-string s)))
(defn logcurrent []
(def sttr (atom ""))
(reset! sttr (str @sttr "delta: " (formatDouble (currentROC)) "%" " btc: " @btcusd-price
" last: " @btcusd-prev " timestamp: " @ptimestamp "\n"))
(reset! sttr (str @sttr "bids\n" (prettyob @polobids) "\n"))
(reset! sttr (str @sttr "asks\n" (prettyob @poloasks) "\n"))
(log/info @sttr)
(if @nfirst
(sendmailinfo @sttr "watch")))
(defn updates [new-price]
(log/info "updates")
(reset! delta (currentROC))
(reset! btcusd-prev @btcusd-price)
(reset! btcusd-price new-price)
(if (> @delta @maxd)
(reset! maxd @delta))
(if (< @delta @mind)
(reset! mind @delta))
(updateob)
(logcurrent)
(if (not @nfirst)
(reset! nfirst true)))
(defn updateaction []
;lost more than tr
(if (and (< @delta trminus)) ; (> @delta -0.5) (< @delta 0.5))
(sendmailtresh)
(log/debug "no significant change" (formatDouble @delta))))
(defn update-timestamp [new-ts]
(reset! ptimestamp-prev @ptimestamp)
(reset! ptimestamp new-ts))
(defn pricewatch []
(let [v (btce)]
(updates (get-in v ["btc_usd" "last"]))
(update-timestamp (get-in v ["btc_usd" "updated"])))
(updateaction))
(defn send-interval [i]
(log/info "interval function")
(sendmailinfo (str "price: " @btcusd-price ". previous: " @btcusd-prev
". ROC: " (format "%.3f" (currentROC)) ". min ROC: " @mind) "btcusd interval"))
(defn doseq-interval
"a function to do things in a thread in steps. no threadpool"
[f coll interval]
(doseq [i coll]
(f)
(Thread/sleep interval)))
;;;;;; main thread ;;;;;;
(defn startup []
;(sendmailinfo "startup btcusd watcher" titlestartup)
(log/info "starting watcher app"))
(defn shutdown []
(log/info "shutdown watcher app")
(sendmailinfo "shutdown" titleshutdown))
(defn -main
"main"
[& args]
(log/info "startup")
(startup)
(doseq-interval pricewatch (range totalwait) waitp)
(shutdown))