-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit fe0a675
Showing
33 changed files
with
2,426 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
hs_err_pid*.log | ||
pom.xml | ||
pom.xml.asc | ||
**/gen | ||
**/target | ||
.* | ||
!.gitignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
BOOT_CLOJURE_VERSION=1.9.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
@ECHO OFF | ||
IF EXIST ".\build\" rd /q /s ".\build" | ||
MKDIR build\db | ||
MKDIR build\target\public | ||
.\boot.exe build-cljs | ||
MOVE .\target\public\main.js .\build\target\public\ | ||
MOVE .\target\public\index.html .\build\target\public\ | ||
.\boot.exe build-server | ||
MOVE .\target\* .\build\ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
(set-env! | ||
:resource-paths #{"resources"} | ||
:source-paths #{"src/clj" "src/cljs"} | ||
:dependencies '[[adzerk/boot-cljs "2.1.4" :scope "test"] | ||
[adzerk/boot-reload "0.5.2" :scope "test"] | ||
[javax.xml.bind/jaxb-api "2.3.0"] ; necessary for Java 9 compatibility | ||
; Clojure dependencies. (server) | ||
[org.clojure/clojure "1.9.0"] | ||
[clj-http "3.9.0"] | ||
[clj-time "0.14.3"] | ||
[com.draines/postal "2.0.2"] | ||
[org.clojure/data.json "0.2.6"] | ||
[org.clojure/java.jdbc "0.7.6"] | ||
[org.xerial/sqlite-jdbc "3.20.1"] | ||
[ring "1.6.3"] | ||
[compojure "1.6.1"] | ||
[http-kit "2.2.0"] | ||
[crypto-random "1.2.0"] | ||
[org.clojure/data.codec "0.1.1"] | ||
[org.clojure/tools.nrepl "0.2.12"] | ||
[samestep/boot-refresh "0.1.0" :scope "test"] | ||
; ClojureScript dependencies. (client) | ||
[org.clojure/clojurescript "1.10.238" :scope "test"] | ||
[cljs-ajax "0.7.3" :scope "test"] | ||
[reagent "0.7.0" :scope "test"] | ||
[cljsjs/react-dom "16.3.2-0" :scope "test"] | ||
[cljsjs/react "16.3.2-0" :scope "test"] | ||
[soda-ash "0.79.1" :scope "test"]]) | ||
(task-options! | ||
pom {:project 'trexd | ||
:version "1.0.0-SNAPSHOT" | ||
:description "BitTrex Daemon"} | ||
aot {:namespace #{'trexd.core}} | ||
jar {:main 'trexd.core}) | ||
|
||
(require | ||
'[adzerk.boot-cljs :refer [cljs]] | ||
'[adzerk.boot-reload :refer [reload]] | ||
'[samestep.boot-refresh :refer [refresh]] | ||
'trexd.core) | ||
|
||
(deftask run [] | ||
(comp | ||
(watch) | ||
(reload :asset-path "public") | ||
(cljs | ||
:source-map true | ||
:optimizations :none | ||
:compiler-options {:asset-path "main.out"}) | ||
(target) | ||
(with-pass-thru _ | ||
(trexd.core/-main)))) | ||
|
||
(deftask build-server [] | ||
(comp | ||
(aot) | ||
(pom) | ||
(uber) | ||
(jar) | ||
(sift :include #{#"\.jar$"}) | ||
(target))) | ||
|
||
(deftask build-cljs [] | ||
(comp | ||
(cljs | ||
:optimizations :advanced | ||
:compiler-options {:asset-path "main.out"} | ||
:pretty-print true | ||
:pseudo-names true) | ||
(target))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
rm -rf ./build | ||
mkdir build/db | ||
mkdir build/target/public | ||
boot build-cljs | ||
mv ./target/public/main.js ./build/target/public/ | ||
mv ./target/public/index.html ./build/target/public/ | ||
boot build-server | ||
mv ./target/* ./build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
## Bittrex Trading Daemon (trexd) | ||
|
||
### Features: | ||
|
||
- Setup email alert for: | ||
- When price reaches ? rate. | ||
- When limit buy/sell order is completed. | ||
- View, create and cancel orders. | ||
- Simple web based interface. | ||
- Fully scriptable (Uses clojure REPL) | ||
- All services run on your machine, no hidden third party. | ||
- And more to come..? | ||
|
||
|
||
|
||
### Setup: | ||
|
||
Download then extract latest release. | ||
|
||
In cmd / shell: | ||
|
||
cd trexd | ||
|
||
java -jar trexd-*.jar | ||
|
||
Follow setup steps given by the program and it should setup a working webserver in no time. | ||
|
||
GUI is hosted locally on localhost:8080 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"/> | ||
<! Choose between local or remote copy. Must be 2.2.x, 2.3.x has bug in modal screen display./> | ||
<! link rel="stylesheet" href="./semantic.min.css"/> | ||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.14/semantic.min.css"> | ||
</head> | ||
|
||
<body> | ||
<! Style makes div display full whitespace instead of default collapsed whitespace. /> | ||
<style>div {white-space: pre; font-family: "Courier New", monospace;}</style> | ||
<div id="menu"></div> | ||
<div id="content"></div> | ||
<div id="repl"></div> | ||
<script src="main.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{:require [trexd.core] | ||
:init-fns [] | ||
:compiler-options {}} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
(ns trexd.aes | ||
(:refer-clojure :exclude [bytes]) | ||
(:gen-class)) | ||
|
||
;; Source: https://stackoverflow.com/questions/10221257/is-there-an-aes-library-for-clojure | ||
;; Adapted to convert all input to string. | ||
(import (javax.crypto Cipher KeyGenerator SecretKey) | ||
(javax.crypto.spec SecretKeySpec) | ||
(java.security SecureRandom) | ||
(org.apache.commons.codec.binary Base64)) | ||
|
||
(defn bytes [s] | ||
(.getBytes s "UTF-8")) | ||
|
||
(defn base64 [b] | ||
(Base64/encodeBase64String b)) | ||
|
||
(defn debase64 [s] | ||
(Base64/decodeBase64 (bytes s))) | ||
|
||
(defn get-raw-key [seed] | ||
(let [keygen (KeyGenerator/getInstance "AES") | ||
sr (SecureRandom/getInstance "SHA1PRNG")] | ||
(.setSeed sr (bytes seed)) | ||
(.init keygen 128 sr) | ||
(.. keygen generateKey getEncoded))) | ||
|
||
(defn get-cipher [mode seed] | ||
(let [key-spec (SecretKeySpec. (get-raw-key seed) "AES") | ||
cipher (Cipher/getInstance "AES")] | ||
(.init cipher mode key-spec) | ||
cipher)) | ||
|
||
(defn encrypt [text key] | ||
(let [text-str (str text) | ||
key-str (str key)] | ||
(let [bytes (bytes text-str) | ||
cipher (get-cipher Cipher/ENCRYPT_MODE key-str)] | ||
(base64 (.doFinal cipher bytes))))) | ||
|
||
(defn decrypt [text key] | ||
(let [text-str (str text) | ||
key-str (str key)] | ||
(let [cipher (get-cipher Cipher/DECRYPT_MODE key-str)] | ||
(String. (.doFinal cipher (debase64 text-str)))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
(ns trexd.bittrex-api | ||
(:require [trexd.util :as u]) | ||
(:gen-class)) | ||
|
||
;; Final Format: {:success true, :msg "oh cow", :command "get-market", :result data} | ||
(defn r-template | ||
"Bittrex result map template. All exchanges share the same output format." | ||
[original-map command result] | ||
{:success (:success original-map) | ||
:msg (if (nil? (:msg original-map))(:message original-map)(:msg original-map)) | ||
:command command | ||
:result result}) | ||
|
||
;; Bittrex Wrapper. | ||
;; Converts to predefined clojure map template before returning. (json -> map -> templated map format) | ||
;; Some of the result fields are not recorded or renamed. eg timestamp, null fields. | ||
;; https://support.bittrex.com/hc/en-us/articles/115003723911-Developer-s-Guide-API | ||
;; Public API | ||
(defn getmarkets [] | ||
(u/post->map "https://bittrex.com/api/v1.1/public/getmarkets")) | ||
(defn getcurrencies [] | ||
(u/post->map "https://bittrex.com/api/v1.1/public/getcurrencies")) | ||
(defn getticker [market] | ||
(let [r (u/post->map "https://bittrex.com/api/v1.1/public/getticker" {:query-params {"market" market}}) | ||
rr (:result r)] | ||
(r-template r "get-ticker" {:bid (rr :Bid) | ||
:ask (rr :Ask) | ||
:last (rr :Last)}))) | ||
(defn getmarketsummaries [] | ||
(let [r (u/post->map "https://bittrex.com/api/v1.1/public/getmarketsummaries")] | ||
(r-template r "get-market-summaries" (for [rr (:result r)] | ||
{:pair (rr :MarketName) | ||
:high (rr :High) | ||
:low (rr :Low) | ||
:last (rr :Last) | ||
:volume (rr :Volume) | ||
:base (rr :BaseVolume) | ||
:bid (rr :Bid) | ||
:ask (rr :Ask)})))) | ||
(defn getmarketsummary [market] | ||
(u/post->map "https://bittrex.com/api/v1.1/public/getmarketsummary" {:query-params {"market" market}})) | ||
(defn getorderbook | ||
([market] | ||
(let [r (u/post->map "https://bittrex.com/api/v1.1/public/getorderbook" {:query-params {"market" market "type" "both"}}) | ||
rr (:result r)] | ||
(r-template r "get-orderbook" {:buy (for [rrb (:buy rr)] | ||
{:size (rrb :Quantity) | ||
:rate (rrb :Rate)}) | ||
:sell (for [rrs (:sell rr)] | ||
{:size (rrs :Quantity) | ||
:rate (rrs :Rate)})}))) | ||
([market type] | ||
(u/post->map "https://bittrex.com/api/v1.1/public/getorderbook" {:query-params {"market" market "type" type}}))) | ||
|
||
(defn getmarkethistory [market] | ||
(let [r (u/post->map "https://bittrex.com/api/v1.1/public/getmarkethistory" {:query-params {"market" market}})] | ||
(r-template r "get-market-history") (for [rr (:result r)] | ||
{:id (rr :Id) | ||
:size (rr :Quantity) | ||
:rate (rr :Price) | ||
:total (rr :Total) | ||
:type (rr :OrderType) | ||
:timestamp (u/date->epoch (rr :TimeStamp))}))) | ||
|
||
;; Market API | ||
(defn buylimit [market quantity rate] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/market/buylimit" {:query-params {"market" market "quantity" quantity "rate" rate}}) | ||
rr (:result r)] | ||
(r-template r "create-limit-buy" {:uuid (rr :uuid)}))) | ||
|
||
(defn selllimit [market quantity rate] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/market/selllimit" {:query-params {"market" market "quantity" quantity "rate" rate}}) | ||
rr (:result r)] | ||
(r-template r "create-limit-sell" {:uuid (rr :uuid)}))) | ||
|
||
(defn cancel [uuid] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/market/cancel" {:query-params {"uuid" uuid}})] | ||
(r-template r "cancel-order" {}))) | ||
|
||
(defn getopenorders | ||
([] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/market/getopenorders")] | ||
(r-template r "get-open-orders" (for [rr (:result r)] | ||
{:uuid (rr :OrderUuid) | ||
:pair (rr :Exchange) | ||
:type (rr :OrderType) | ||
:size (rr :Quantity) | ||
:left (rr :QuantityRemaining) | ||
:rate (rr :Limit) | ||
:timestamp (u/date->epoch (rr :Opened))})))) | ||
([market] | ||
(u/post->map-signed "https://bittrex.com/api/v1.1/market/getopenorders" {:query-params {"market" market}}))) | ||
|
||
;; Account API | ||
(defn getbalances [] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/account/getbalances")] | ||
(r-template r "get-balances" (for [rr (:result r)] | ||
{:pair (rr :Currency) | ||
:balance (rr :Balance) | ||
:available (rr :Available) | ||
:pending (rr :Pending)})))) | ||
|
||
(defn getbalance [currency] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/account/getbalance" {:query-params {"currency" currency}}) | ||
rr (:result r)] | ||
(r-template r "get-balances" {:pair (rr :Currency) | ||
:balance (rr :Balance) | ||
:available (rr :Available) | ||
:pending (rr :Pending)}))) | ||
|
||
(defn getdepositaddress [currency] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/account/getdepositaddress" {:query-params {"currency" currency}}) | ||
rr (:result r)] | ||
(r-template r "get-deposit-address" {:pair (rr :Currency) | ||
:address (rr :Address)}))) | ||
|
||
(defn withdraw | ||
([currency quantity address] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/account/withdraw" {:query-params {"currency" currency "quantity" quantity "address" address}}) | ||
rr (:result r)] | ||
(r-template r "withdraw" {:uuid (rr :uuid)}))) | ||
([currency quantity address paymentid] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/account/withdraw" {:query-params {"currency" currency "quantity" quantity "address" address "paymentid" paymentid}}) | ||
rr (:result r)] | ||
(r-template r "withdraw" {:uuid (rr :uuid)})))) | ||
|
||
(defn getorder [uuid] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/account/getorder" {:query-params {"uuid" uuid}}) | ||
rr (:result r)] | ||
(r-template r "get-order" {:uuid (rr :OrderUuid) | ||
:pair (rr :Exchange) | ||
:type (rr :Type) | ||
:size (rr :Quantity) | ||
:left (rr :QuantityRemaining) | ||
:rate (rr :Limit) | ||
:timestamp (u/date->epoch (rr :Opened)) | ||
:isopen (rr :IsOpen)}))) | ||
|
||
(defn getorderhistory | ||
([] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/account/getorderhistory")] | ||
(r-template r "get-order-history" (for [rr (:result r)] | ||
{:uuid (rr :uuid) | ||
:pair (rr :Exchange) | ||
:type (rr :Type) | ||
:rate (rr :Limit) | ||
:size (rr :Quantity) | ||
:left (rr :QuantityRemaining) | ||
:timestamp (u/date->epoch (rr :TimeStamp))})))) | ||
([market] | ||
(u/post->map-signed "https://bittrex.com/api/v1.1/account/getorderhistory" {:query-params {"market" market}}))) | ||
|
||
(defn getwithdrawalhistory | ||
([] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/account/getwithdrawalhistory")] | ||
(r-template r "get-withdrawal-history" (for [rr (:result r)] | ||
{:uuid (rr :uuid) | ||
:pair (rr :Currency) | ||
:size (rr :Amount) | ||
:address (rr :Address) | ||
:txcost (rr :TxCost) | ||
:timestamp (u/date->epoch (rr :TimeStamp))})))) | ||
([currency] | ||
(u/post->map-signed "https://bittrex.com/api/v1.1/account/getwithdrawalhistory" {:query-params {"currency" currency}}))) | ||
|
||
(defn getdeposithistory | ||
([] | ||
(let [r (u/post->map-signed "https://bittrex.com/api/v1.1/account/getdeposithistory")] | ||
(r-template r "get-deposit-history" (for [rr (:result r)] | ||
{:uuid (rr :uuid) | ||
:pair (rr :Currency) | ||
:size (rr :Amount) | ||
:address (rr :Address) | ||
:txcost (rr :TxCost) | ||
:timestamp (u/date->epoch (rr :TimeStamp))})))) | ||
([currency] | ||
(u/post->map-signed "https://bittrex.com/api/v1.1/account/getdeposithistory" {:query-params {"currency" currency}}))) |
Oops, something went wrong.