diff --git a/.gitignore b/.gitignore
index 0cffcb34..f2403fc4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
-config.json
\ No newline at end of file
+config.json
+node_modules
+lib
diff --git a/alphapointhttp.go b/alphapointhttp.go
index fef2333f..14628c81 100644
--- a/alphapointhttp.go
+++ b/alphapointhttp.go
@@ -203,6 +203,21 @@ func (a *Alphapoint) GetTicker(symbol string) (AlphapointTicker, error) {
return response, nil
}
+func (a *Alphapoint) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker, err := a.GetTicker(currency)
+ if err != nil {
+ log.Println(err)
+ return TickerPrice{}
+ }
+ tickerPrice.Ask = ticker.Ask
+ tickerPrice.Bid = ticker.Bid
+
+ return tickerPrice
+}
+
+
+
func (a *Alphapoint) GetTrades(symbol string, startIndex, count int) (AlphapointTrades, error) {
request := make(map[string]interface{})
request["ins"] = symbol
diff --git a/anxhttp.go b/anxhttp.go
index 8b130d16..f23e0e49 100644
--- a/anxhttp.go
+++ b/anxhttp.go
@@ -188,6 +188,24 @@ func (a *ANX) GetTicker(currency string) ANXTicker {
return ticker
}
+func (a *ANX) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker := a.GetTicker(currency)
+ tickerPrice.Ask = ticker.Data.Buy.Value
+ tickerPrice.Bid = ticker.Data.Sell.Value
+ tickerPrice.CryptoCurrency = currency
+ tickerPrice.Low = ticker.Data.Low.Value
+ tickerPrice.Last = ticker.Data.Last.Value
+ tickerPrice.Volume = ticker.Data.Vol.Value
+ tickerPrice.High = ticker.Data.High.Value
+
+ return tickerPrice
+}
+
+func (a *ANX) GetEnabledCurrencies() []string {
+ return a.EnabledPairs
+}
+
func (a *ANX) GetAPIKey(username, password, otp, deviceID string) (string, string) {
request := make(map[string]interface{})
request["nonce"] = strconv.FormatInt(time.Now().UnixNano(), 10)[0:13]
diff --git a/bitfinexhttp.go b/bitfinexhttp.go
index 3871f5c7..f3503482 100644
--- a/bitfinexhttp.go
+++ b/bitfinexhttp.go
@@ -3,12 +3,13 @@ package main
import (
"errors"
"fmt"
- "github.com/gorilla/websocket"
"log"
"net/url"
"strconv"
"strings"
"time"
+
+ "github.com/gorilla/websocket"
)
const (
@@ -211,6 +212,10 @@ func (b *Bitfinex) Setup(exch Exchanges) {
}
}
+func (k *Bitfinex) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (b *Bitfinex) Start() {
go b.Run()
}
@@ -284,6 +289,24 @@ func (b *Bitfinex) GetTicker(symbol string, values url.Values) (BitfinexTicker,
return response, nil
}
+func (b *Bitfinex) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker, err := b.GetTicker(currency, nil)
+ if err != nil {
+ log.Println(err)
+ return tickerPrice
+ }
+ tickerPrice.Ask = ticker.Ask
+ tickerPrice.Bid = ticker.Bid
+ tickerPrice.CryptoCurrency = currency
+ tickerPrice.Low = ticker.Low
+ tickerPrice.Last = ticker.Last
+ tickerPrice.Volume = ticker.Volume
+ tickerPrice.High = ticker.High
+
+ return tickerPrice
+}
+
type BitfinexLendbookBidAsk struct {
Rate float64 `json:"rate,string"`
Amount float64 `json:"amount,string"`
diff --git a/bitstamphttp.go b/bitstamphttp.go
index c30dc513..e2d35311 100644
--- a/bitstamphttp.go
+++ b/bitstamphttp.go
@@ -169,6 +169,10 @@ func (b *Bitstamp) Setup(exch Exchanges) {
}
}
+func (k *Bitstamp) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (b *Bitstamp) SetEnabled(enabled bool) {
b.Enabled = enabled
}
@@ -234,6 +238,24 @@ func (b *Bitstamp) GetTicker(hourly bool) (BitstampTicker, error) {
return ticker, nil
}
+func (b *Bitstamp) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker, err := b.GetTicker(true)
+ if err != nil {
+ log.Println(err)
+ return tickerPrice
+ }
+ tickerPrice.Ask = ticker.Ask
+ tickerPrice.Bid = ticker.Bid
+ tickerPrice.CryptoCurrency = currency
+ tickerPrice.Low = ticker.Low
+ tickerPrice.Last = ticker.Last
+ tickerPrice.Volume = ticker.Volume
+ tickerPrice.High = ticker.High
+
+ return tickerPrice
+}
+
func (b *Bitstamp) GetOrderbook() (BitstampOrderbook, error) {
type response struct {
Timestamp int64 `json:"timestamp,string"`
diff --git a/brightonpeakhttp.go b/brightonpeakhttp.go
index 2208f30a..8e80e14a 100644
--- a/brightonpeakhttp.go
+++ b/brightonpeakhttp.go
@@ -61,6 +61,10 @@ func (b *BrightonPeak) Setup(exch Exchanges) {
}
}
+func (k *BrightonPeak) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (b *BrightonPeak) Start() {
go b.Run()
}
@@ -134,6 +138,24 @@ func (b *BrightonPeak) GetTicker(symbol string) (AlphapointTicker, error) {
return b.API.GetTicker(symbol)
}
+func (b *BrightonPeak) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker, err := b.GetTicker(currency)
+ if err != nil {
+ log.Println(err)
+ return tickerPrice
+ }
+ tickerPrice.Ask = ticker.Ask
+ tickerPrice.Bid = ticker.Bid
+ tickerPrice.CryptoCurrency = currency
+ tickerPrice.Low = ticker.Low
+ tickerPrice.Last = ticker.Last
+ tickerPrice.Volume = ticker.Volume
+ tickerPrice.High = ticker.High
+
+ return tickerPrice
+}
+
func (b *BrightonPeak) GetTrades(symbol string, startIndex, count int) (AlphapointTrades, error) {
return b.API.GetTrades(symbol, startIndex, count)
}
diff --git a/btcchttp.go b/btcchttp.go
index e8cfddf1..13f042d1 100644
--- a/btcchttp.go
+++ b/btcchttp.go
@@ -198,6 +198,10 @@ func (b *BTCC) Setup(exch Exchanges) {
}
}
+func (k *BTCC) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
//Start is run if exchange is enabled, after Setup
func (b *BTCC) Start() {
go b.Run()
@@ -272,6 +276,20 @@ func (b *BTCC) GetTicker(symbol string) BTCCTicker {
return resp.Ticker
}
+func (b *BTCC) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker := b.GetTicker(currency)
+ tickerPrice.Ask = ticker.Sell
+ tickerPrice.Bid = ticker.Buy
+ tickerPrice.CryptoCurrency = currency
+ tickerPrice.Low = ticker.Low
+ tickerPrice.Last = ticker.Last
+ tickerPrice.Volume = ticker.Vol
+ tickerPrice.High = ticker.High
+
+ return tickerPrice
+}
+
func (b *BTCC) GetTradesLast24h(symbol string) bool {
req := fmt.Sprintf("%sdata/trades?market=%s", BTCC_API_URL, symbol)
err := SendHTTPGetRequest(req, true, nil)
diff --git a/btcehttp.go b/btcehttp.go
index 0367d047..a220ae9b 100644
--- a/btcehttp.go
+++ b/btcehttp.go
@@ -116,6 +116,10 @@ func (b *BTCE) Setup(exch Exchanges) {
}
}
+func (k *BTCE) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (b *BTCE) Start() {
go b.Run()
}
@@ -185,6 +189,21 @@ func (b *BTCE) GetTicker(symbol string) (map[string]BTCeTicker, error) {
return response.Data, nil
}
+/// This getticker is different, so I'll let someone else implement....
+/// Or I will, just later...
+func (b *BTCE) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ /*ticker, err:= b.GetTicker(currency)
+ if err != nil {
+ log.Println(err)
+ return tickerPrice
+ }
+ tickerPrice.Ask = ticker.Buy
+ tickerPrice.Bid = ticker.Sell
+ */
+ return tickerPrice
+}
+
func (b *BTCE) GetDepth(symbol string) {
type Response struct {
Data map[string]BTCEOrderbook
diff --git a/btcmarkets.go b/btcmarkets.go
index 5f82f9ab..cec733ee 100644
--- a/btcmarkets.go
+++ b/btcmarkets.go
@@ -125,6 +125,10 @@ func (b *BTCMarkets) Setup(exch Exchanges) {
}
}
+func (k *BTCMarkets) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (b *BTCMarkets) Start() {
go b.Run()
}
@@ -188,6 +192,21 @@ func (b *BTCMarkets) GetTicker(symbol string) (BTCMarketsTicker, error) {
return ticker, nil
}
+func (b *BTCMarkets) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker, err := b.GetTicker(currency)
+ if err != nil {
+ log.Println(err)
+ return tickerPrice
+ }
+ tickerPrice.Ask = ticker.BestAsk
+ tickerPrice.Bid = ticker.BestBID
+ tickerPrice.CryptoCurrency = currency
+ tickerPrice.Last = ticker.LastPrice
+
+ return tickerPrice
+}
+
func (b *BTCMarkets) GetOrderbook(symbol string) (BTCMarketsOrderbook, error) {
orderbook := BTCMarketsOrderbook{}
path := fmt.Sprintf("/market/%s/AUD/orderbook", symbol)
diff --git a/coinbasehttp.go b/coinbasehttp.go
index 7d98ee5b..fc0d916c 100644
--- a/coinbasehttp.go
+++ b/coinbasehttp.go
@@ -159,6 +159,10 @@ func (c *Coinbase) Setup(exch Exchanges) {
}
}
+func (k *Coinbase) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (c *Coinbase) Start() {
go c.Run()
}
@@ -359,6 +363,20 @@ func (c *Coinbase) GetTicker(symbol string) (CoinbaseTicker, error) {
return ticker, nil
}
+func (c *Coinbase) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker, err := c.GetTicker(currency)
+ if err != nil {
+ log.Println(err)
+ return TickerPrice{}
+ }
+ tickerPrice.Ask = ticker.Price
+ tickerPrice.CryptoCurrency = currency
+ tickerPrice.Volume = ticker.Size
+
+ return tickerPrice
+}
+
func (c *Coinbase) GetTrades(symbol string) ([]CoinbaseTrade, error) {
trades := []CoinbaseTrade{}
path := fmt.Sprintf("%s/%s/%s", COINBASE_API_URL+COINBASE_PRODUCTS, symbol, COINBASE_TRADES)
diff --git a/geminihttp.go b/geminihttp.go
index 8cdf1946..548d5ff6 100644
--- a/geminihttp.go
+++ b/geminihttp.go
@@ -137,6 +137,10 @@ func (g *Gemini) Setup(exch Exchanges) {
}
}
+func (k *Gemini) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (g *Gemini) Start() {
go g.Run()
}
@@ -186,6 +190,13 @@ func (g *Gemini) Run() {
}
}
+/// Once GetTicker is created, then add in GetTickerPrice code plz - Scott
+func (g *Gemini) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+
+ return tickerPrice
+}
+
func (g *Gemini) GetSymbols() ([]string, error) {
symbols := []string{}
path := fmt.Sprintf("%s/v%s/%s", GEMINI_API_URL, GEMINI_API_VERSION, GEMINI_SYMBOLS)
diff --git a/huobihttp.go b/huobihttp.go
index e77625f0..bed18289 100644
--- a/huobihttp.go
+++ b/huobihttp.go
@@ -79,6 +79,10 @@ func (h *HUOBI) Setup(exch Exchanges) {
}
}
+func (k *HUOBI) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (h *HUOBI) Start() {
go h.Run()
}
@@ -132,6 +136,20 @@ func (h *HUOBI) GetTicker(symbol string) HuobiTicker {
return resp.Ticker
}
+func (h *HUOBI) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker := h.GetTicker(currency)
+ tickerPrice.Ask = ticker.Sell
+ tickerPrice.Bid = ticker.Buy
+ tickerPrice.CryptoCurrency = currency
+ tickerPrice.Low = ticker.Low
+ tickerPrice.Last = ticker.Last
+ tickerPrice.Volume = ticker.Vol
+ tickerPrice.High = ticker.High
+
+ return tickerPrice
+}
+
func (h *HUOBI) GetOrderBook(symbol string) bool {
path := fmt.Sprintf("http://market.huobi.com/staticmarket/depth_%s_json.js", symbol)
err := SendHTTPGetRequest(path, true, nil)
diff --git a/interfaces.go b/interfaces.go
index 8fd4bfd2..f6d66d03 100644
--- a/interfaces.go
+++ b/interfaces.go
@@ -6,4 +6,6 @@ type IBotExchange interface {
SetDefaults()
GetName() string
IsEnabled() bool
+ GetTickerPrice(currency string) TickerPrice
+ GetEnabledCurrencies() []string
}
diff --git a/itbithttp.go b/itbithttp.go
index f7b4f300..253221c0 100644
--- a/itbithttp.go
+++ b/itbithttp.go
@@ -86,6 +86,10 @@ func (i *ItBit) Setup(exch Exchanges) {
}
}
+func (k *ItBit) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (i *ItBit) Start() {
go i.Run()
}
@@ -134,6 +138,16 @@ func (i *ItBit) GetTicker(currency string) ItBitTicker {
return itbitTicker
}
+func (i *ItBit) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker := i.GetTicker(currency)
+
+ tickerPrice.Ask = ticker.Ask
+ tickerPrice.Bid = ticker.Bid
+
+ return tickerPrice
+}
+
type ItbitOrderbookEntry struct {
Quantitiy float64 `json:"quantity,string"`
Price float64 `json:"price,string"`
diff --git a/kraken.go b/kraken.go
index e1e646cc..3bad879d 100644
--- a/kraken.go
+++ b/kraken.go
@@ -90,6 +90,10 @@ func (k *Kraken) Setup(exch Exchanges) {
}
}
+func (k *Kraken) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (k *Kraken) Start() {
go k.Run()
}
@@ -229,6 +233,21 @@ func (k *Kraken) GetTicker(symbol string) error {
return nil
}
+//This will return the TickerPrice struct when tickers are completed here..
+func (k *Kraken) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ /*
+ ticker, err := i.GetTicker(currency)
+ if err != nil {
+ log.Println(err)
+ return tickerPrice
+ }
+ tickerPrice.Ask = ticker.Ask
+ tickerPrice.Bid = ticker.Bid
+ */
+ return tickerPrice
+}
+
func (k *Kraken) GetOHLC(symbol string) error {
values := url.Values{}
values.Set("pair", symbol)
diff --git a/lakebtchttp.go b/lakebtchttp.go
index 8b6417f2..edea18fd 100644
--- a/lakebtchttp.go
+++ b/lakebtchttp.go
@@ -95,6 +95,10 @@ func (l *LakeBTC) Setup(exch Exchanges) {
}
}
+func (k *LakeBTC) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (l *LakeBTC) Start() {
go l.Run()
}
@@ -148,6 +152,23 @@ func (l *LakeBTC) GetTicker() LakeBTCTickerResponse {
return response
}
+func (l *LakeBTC) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker := l.GetTicker()
+
+ if currency == "USD" {
+ tickerPrice.Ask = ticker.USD.Ask
+ tickerPrice.Bid = ticker.USD.Bid
+ } else if currency == "CNY" {
+ tickerPrice.Ask = ticker.CNY.Ask
+ tickerPrice.Bid = ticker.CNY.Bid
+ }
+
+ tickerPrice.CryptoCurrency = currency
+
+ return tickerPrice
+}
+
func (l *LakeBTC) GetOrderBook(currency string) bool {
req := LAKEBTC_ORDERBOOK
if currency == "CNY" {
diff --git a/localbitcoinshttp.go b/localbitcoinshttp.go
index d6a8b977..fba44eaf 100644
--- a/localbitcoinshttp.go
+++ b/localbitcoinshttp.go
@@ -74,6 +74,10 @@ func (l *LocalBitcoins) Setup(exch Exchanges) {
}
}
+func (k *LocalBitcoins) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (l *LocalBitcoins) Start() {
go l.Run()
}
@@ -136,6 +140,19 @@ func (l *LocalBitcoins) GetTicker() (map[string]LocalBitcoinsTicker, error) {
return result, nil
}
+func (l *LocalBitcoins) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker, err := l.GetTicker()
+ if err != nil {
+ log.Println(err)
+ return tickerPrice
+ }
+ tickerPrice.Ask = ticker[currency].Rates.Last
+ tickerPrice.CryptoCurrency = currency
+
+ return tickerPrice
+}
+
type LocalBitcoinsTrade struct {
TID int64 `json:"tid"`
Date int64 `json:"date"`
diff --git a/main.go b/main.go
index 9ce75fc5..fa670b73 100644
--- a/main.go
+++ b/main.go
@@ -3,6 +3,7 @@ package main
import (
"errors"
"log"
+ "net/http"
"os"
"os/signal"
"runtime"
@@ -40,8 +41,9 @@ type Bot struct {
var bot Bot
func SetupBotConfiguration(s IBotExchange, exch Exchanges) {
- s.Setup(exch)
+ s.SetDefaults()
if s.GetName() == exch.Name {
+ s.Setup(exch)
if s.IsEnabled() {
log.Printf("%s: Exchange support: %s (Authenticated API support: %s - Verbose mode: %s).\n", exch.Name, IsEnabled(exch.Enabled), IsEnabled(exch.AuthenticatedAPISupport), IsEnabled(exch.Verbose))
s.Start()
@@ -80,30 +82,10 @@ func main() {
} else {
log.Printf("SMS support enabled. Number of SMS contacts %d.\n", GetEnabledSMSContacts())
}
- }
- if !bot.config.SMS.Enabled {
+ } else {
log.Println("SMS support disabled.")
}
- if bot.config.Webserver.Enabled {
- err := CheckWebserverValues()
- if err != nil {
- log.Println(err) // non fatal event
- bot.config.Webserver.Enabled = false
- } else {
- log.Println("HTTP Webserver support enabled.")
- err = StartWebserver()
- if err != nil {
- log.Println("Unable to start Webserver: ", err)
- } else {
- log.Printf("HTTP server enabled and running at http://%s:%d\n", GetWebserverHost(), GetWebserverPort())
- }
- }
- }
- if !bot.config.Webserver.Enabled {
- log.Println("HTTP Webserver support disabled.")
- }
-
log.Printf("Available Exchanges: %d. Enabled Exchanges: %d.\n", len(bot.config.Exchanges), GetEnabledExchanges())
log.Println("Bot Exchange support:")
@@ -111,25 +93,24 @@ func main() {
bot.exchange.okcoinChina.APIUrl = OKCOIN_API_URL_CHINA
bot.exchanges = []IBotExchange{
- &bot.exchange.anx,
- &bot.exchange.kraken,
- &bot.exchange.btcc,
- &bot.exchange.bitstamp,
- &bot.exchange.brightonpeak,
- &bot.exchange.bitfinex,
- &bot.exchange.btce,
- &bot.exchange.btcmarkets,
- &bot.exchange.coinbase,
- &bot.exchange.gemini,
- &bot.exchange.okcoinChina,
- &bot.exchange.okcoinIntl,
- &bot.exchange.itbit,
- &bot.exchange.lakebtc,
- &bot.exchange.localbitcoins,
- &bot.exchange.poloniex,
- &bot.exchange.huobi,
+ new(ANX),
+ new(Kraken),
+ new(BTCC),
+ new(Bitstamp),
+ new(BrightonPeak),
+ new(Bitfinex),
+ new(BTCE),
+ new(BTCMarkets),
+ new(Coinbase),
+ new(Gemini),
+ new(OKCoin),
+ new(OKCoin),
+ new(ItBit),
+ new(LakeBTC),
+ new(LocalBitcoins),
+ new(Poloniex),
+ new(HUOBI),
}
-
for i := 0; i < len(bot.exchanges); i++ {
if bot.exchanges[i] != nil {
bot.exchanges[i].SetDefaults()
@@ -150,6 +131,22 @@ func main() {
}
}
}
+
+ if bot.config.Webserver.Enabled {
+ err := CheckWebserverValues()
+ if err != nil {
+ log.Println(err) // non fatal event
+ //bot.config.Webserver.Enabled = false
+ } else {
+ log.Println("HTTP Webserver support enabled.")
+ router := NewRouter(bot.exchanges)
+ log.Fatal(http.ListenAndServe(bot.config.Webserver.ListenAddress, router))
+ }
+ }
+ if !bot.config.Webserver.Enabled {
+ log.Println("HTTP Webserver support disabled.")
+ }
+
<-bot.shutdown
Shutdown()
}
diff --git a/okcoinhttp.go b/okcoinhttp.go
index 79a47834..a1cb3343 100644
--- a/okcoinhttp.go
+++ b/okcoinhttp.go
@@ -2,12 +2,13 @@ package main
import (
"errors"
- "github.com/gorilla/websocket"
"log"
"net/url"
"strconv"
"strings"
"time"
+
+ "github.com/gorilla/websocket"
)
const (
@@ -229,6 +230,10 @@ func (o *OKCoin) Setup(exch Exchanges) {
}
}
+func (k *OKCoin) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (o *OKCoin) Start() {
go o.Run()
}
@@ -322,6 +327,24 @@ func (o *OKCoin) GetTicker(symbol string) (OKCoinTicker, error) {
return resp.Ticker, nil
}
+func (o *OKCoin) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker, err := o.GetTicker(currency)
+ if err != nil {
+ log.Println(err)
+ return tickerPrice
+ }
+ tickerPrice.Ask = ticker.Sell
+ tickerPrice.Bid = ticker.Buy
+ tickerPrice.CryptoCurrency = currency
+ tickerPrice.Low = ticker.Low
+ tickerPrice.Last = ticker.Last
+ tickerPrice.Volume = ticker.Vol
+ tickerPrice.High = ticker.High
+
+ return tickerPrice
+}
+
func (o *OKCoin) GetOrderBook(symbol string, size int64, merge bool) (OKCoinOrderbook, error) {
resp := OKCoinOrderbook{}
vals := url.Values{}
diff --git a/poloniexhttp.go b/poloniexhttp.go
index 1925c591..198c5ff0 100644
--- a/poloniexhttp.go
+++ b/poloniexhttp.go
@@ -105,6 +105,10 @@ func (p *Poloniex) Setup(exch Exchanges) {
}
}
+func (k *Poloniex) GetEnabledCurrencies() []string {
+ return k.EnabledPairs
+}
+
func (p *Poloniex) Start() {
go p.Run()
}
@@ -161,6 +165,24 @@ func (p *Poloniex) GetTicker() (map[string]PoloniexTicker, error) {
return resp.Data, nil
}
+func (p *Poloniex) GetTickerPrice(currency string) TickerPrice {
+ var tickerPrice TickerPrice
+ ticker, err := p.GetTicker()
+ if err != nil {
+ log.Println(err)
+ return tickerPrice
+ }
+ tickerPrice.CryptoCurrency = currency
+ tickerPrice.Ask = ticker[currency].Last
+ tickerPrice.Bid = ticker[currency].HighestBid
+ tickerPrice.High = ticker[currency].HighestBid
+ tickerPrice.Last = ticker[currency].Last
+ tickerPrice.Low = ticker[currency].LowestAsk
+ tickerPrice.Volume = ticker[currency].BaseVolume
+
+ return tickerPrice
+}
+
func (p *Poloniex) GetVolume() (interface{}, error) {
var resp interface{}
path := fmt.Sprintf("%s/public?command=return24hVolume", POLONIEX_API_URL)
diff --git a/poloniexwebsocket.go b/poloniexwebsocket.go
index 9cd00548..59e76f47 100644
--- a/poloniexwebsocket.go
+++ b/poloniexwebsocket.go
@@ -1,9 +1,10 @@
package main
import (
- "gopkg.in/jcelliott/turnpike.v2"
"log"
"strconv"
+
+ "gopkg.in/jcelliott/turnpike.v2"
)
const (
diff --git a/restfulHandlers.go b/restfulHandlers.go
new file mode 100644
index 00000000..bdc5c32c
--- /dev/null
+++ b/restfulHandlers.go
@@ -0,0 +1,11 @@
+package main
+
+import (
+ "fmt"
+ "net/http"
+)
+
+func Index(w http.ResponseWriter, r *http.Request) {
+ fmt.Fprintln(w, bot.exchanges[0].GetName())
+
+}
diff --git a/restfulLogger.go b/restfulLogger.go
new file mode 100644
index 00000000..a1f21d1b
--- /dev/null
+++ b/restfulLogger.go
@@ -0,0 +1,23 @@
+package main
+
+import (
+ "log"
+ "net/http"
+ "time"
+)
+
+func Logger(inner http.Handler, name string) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ start := time.Now()
+
+ inner.ServeHTTP(w, r)
+
+ log.Printf(
+ "%s\t%s\t%s\t%s",
+ r.Method,
+ r.RequestURI,
+ name,
+ time.Since(start),
+ )
+ })
+}
\ No newline at end of file
diff --git a/restfulRouter.go b/restfulRouter.go
new file mode 100644
index 00000000..0ed2d18b
--- /dev/null
+++ b/restfulRouter.go
@@ -0,0 +1,25 @@
+package main
+
+import (
+ "net/http"
+
+ "github.com/gorilla/mux"
+)
+
+func NewRouter(exchanges []IBotExchange) *mux.Router {
+ router := mux.NewRouter().StrictSlash(true)
+ allRoutes := append(routes, exchangeRoutes...)
+ for _, route := range allRoutes {
+ var handler http.Handler
+ handler = route.HandlerFunc
+ handler = Logger(handler, route.Name)
+
+ router.
+ Methods(route.Method).
+ Path(route.Pattern).
+ Name(route.Name).
+ Handler(handler)
+
+ }
+ return router
+}
diff --git a/restfulRoutes.go b/restfulRoutes.go
new file mode 100644
index 00000000..1941d55d
--- /dev/null
+++ b/restfulRoutes.go
@@ -0,0 +1,16 @@
+package main
+
+import "net/http"
+
+type Route struct {
+ Name string
+ Method string
+ Pattern string
+ HandlerFunc http.HandlerFunc
+}
+
+type Routes []Route
+
+var routes = Routes{
+
+}
\ No newline at end of file
diff --git a/ticker.go b/ticker.go
index c73dc505..3e36fe4a 100644
--- a/ticker.go
+++ b/ticker.go
@@ -5,14 +5,14 @@ import (
)
type TickerPrice struct {
- CryptoCurrency string
- FiatCurrency string
- Last float64
- High float64
- Low float64
- Bid float64
- Ask float64
- Volume float64
+ CryptoCurrency string `json:"CryptoCurrency"`
+ FiatCurrency string `json:"FiatCurrency"`
+ Last float64 `json:"Last"`
+ High float64 `json:"High"`
+ Low float64 `json:"Low"`
+ Bid float64 `json:"Bid"`
+ Ask float64 `json:"Ask"`
+ Volume float64 `json:"Volume"`
}
type Ticker struct {
diff --git a/tickerRoutes.go b/tickerRoutes.go
new file mode 100644
index 00000000..ccc81d23
--- /dev/null
+++ b/tickerRoutes.go
@@ -0,0 +1,84 @@
+package main
+
+import (
+ "encoding/json"
+ "log"
+ "net/http"
+
+ "github.com/gorilla/mux"
+)
+
+func jsonTickerResponse(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ currency := vars["currency"]
+ exchangeName := vars["exchangeName"]
+ var response TickerPrice
+ for i := 0; i < len(bot.exchanges); i++ {
+ if bot.exchanges[i] != nil {
+ if bot.exchanges[i].IsEnabled() && bot.exchanges[i].GetName() == exchangeName {
+ response = bot.exchanges[i].GetTickerPrice(currency)
+ }
+ }
+ }
+
+ w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+ w.WriteHeader(http.StatusOK)
+ encoder := json.NewEncoder(w)
+
+ if err := encoder.Encode(response); err != nil {
+ panic(err)
+ }
+}
+
+type AllEnabledExchangeCurrencies struct {
+ Data []EnabledExchangeCurrencies `json:"data"`
+}
+
+type EnabledExchangeCurrencies struct {
+ ExchangeName string `json:"exchangeName"`
+ ExchangeValues []TickerPrice `json:"exchangeValues"`
+}
+
+func getAllActiveTickersResponse(w http.ResponseWriter, r *http.Request) {
+ var response AllEnabledExchangeCurrencies
+ log.Println(bot.exchanges[15])
+
+ for _, individualBot := range bot.exchanges {
+ if individualBot != nil && individualBot.IsEnabled() {
+ var individualExchange EnabledExchangeCurrencies
+ individualExchange.ExchangeName = individualBot.GetName()
+ log.Println("Getting enabled currencies for '" + individualBot.GetName() + "'")
+ currencies := individualBot.GetEnabledCurrencies()
+ log.Println(currencies)
+ for _, currency := range currencies {
+ tickerPrice := individualBot.GetTickerPrice(currency)
+ log.Println(tickerPrice)
+
+ individualExchange.ExchangeValues = append(individualExchange.ExchangeValues, tickerPrice)
+ }
+ response.Data = append(response.Data, individualExchange)
+ }
+ }
+
+ log.Println(response)
+ w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+ w.WriteHeader(http.StatusOK)
+ if err := json.NewEncoder(w).Encode(response); err != nil {
+ panic(err)
+ }
+}
+
+var exchangeRoutes = Routes{
+ Route{
+ "AllActiveExchangesAndCurrencies",
+ "GET",
+ "/exchanges/enabled/latest/all",
+ getAllActiveTickersResponse,
+ },
+ Route{
+ "IndividualExchangeAndCurrency",
+ "GET",
+ "/exchanges/{exchangeName}/latest/{currency}",
+ jsonTickerResponse,
+ },
+}
diff --git a/web/.bowerrc b/web/.bowerrc
new file mode 100644
index 00000000..8c58c8ef
--- /dev/null
+++ b/web/.bowerrc
@@ -0,0 +1,3 @@
+{
+ "directory": "app/bower_components"
+}
\ No newline at end of file
diff --git a/web/.gitignore b/web/.gitignore
new file mode 100644
index 00000000..b702acc6
--- /dev/null
+++ b/web/.gitignore
@@ -0,0 +1,7 @@
+logs/*
+!.gitkeep
+node_modules/
+bower_components/
+tmp
+.DS_Store
+.idea
\ No newline at end of file
diff --git a/web/.jshintrc b/web/.jshintrc
new file mode 100644
index 00000000..60f49fd3
--- /dev/null
+++ b/web/.jshintrc
@@ -0,0 +1,24 @@
+{
+ "strict": "global",
+ "globals": {
+ // Angular
+ "angular": false,
+
+ // Angular mocks
+ "module": false,
+ "inject": false,
+
+ // Jasmine
+ "jasmine": false,
+ "describe": false,
+ "beforeEach": false,
+ "afterEach": false,
+ "it": false,
+ "expect": false,
+
+ // Protractor
+ "browser": false,
+ "element": false,
+ "by": false
+ }
+}
diff --git a/web/.travis.yml b/web/.travis.yml
new file mode 100644
index 00000000..a549d113
--- /dev/null
+++ b/web/.travis.yml
@@ -0,0 +1,14 @@
+language: node_js
+node_js:
+ - '4.4'
+
+before_script:
+ - export DISPLAY=:99.0
+ - sh -e /etc/init.d/xvfb start
+ - npm start > /dev/null &
+ - npm run update-webdriver
+ - sleep 1 # give server time to start
+
+script:
+ - node_modules/.bin/karma start karma.conf.js --no-auto-watch --single-run --reporters=dots --browsers=Firefox
+ - node_modules/.bin/protractor e2e-tests/protractor.conf.js --browser=firefox
diff --git a/web/LICENSE b/web/LICENSE
new file mode 100644
index 00000000..b8de5aae
--- /dev/null
+++ b/web/LICENSE
@@ -0,0 +1,22 @@
+The MIT License
+
+Copyright (c) 2010-2016 Google, Inc. http://angularjs.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/web/README.md b/web/README.md
new file mode 100644
index 00000000..aa5ae109
--- /dev/null
+++ b/web/README.md
@@ -0,0 +1,24 @@
+### Prerequisites
+
+You need git to clone the angular-seed repository. You can get git from
+[http://git-scm.com/](http://git-scm.com/).
+
+We also use a number of node.js tools to initialize and test angular-seed. You must have node.js and
+its package manager (npm) installed. You can get them from [http://nodejs.org/](http://nodejs.org/).
+### Install Dependencies
+
+```
+npm install
+```
+
+
+### Run the Application
+
+The simplest way to start this server is:
+
+```
+npm start
+```
+
+Now browse to the app at `http://localhost/`.
+
diff --git a/web/app/app.css b/web/app/app.css
new file mode 100644
index 00000000..c9252407
--- /dev/null
+++ b/web/app/app.css
@@ -0,0 +1,30 @@
+/* app css stylesheet */
+
+.menu {
+ list-style: none;
+ border-bottom: 0.1em solid black;
+ margin-bottom: 2em;
+ padding: 0 0 0.5em;
+}
+
+.menu:before {
+ content: "[";
+}
+
+.menu:after {
+ content: "]";
+}
+
+.menu > li {
+ display: inline;
+}
+
+.menu > li:before {
+ content: "|";
+ padding-right: 0.3em;
+}
+
+.menu > li:nth-child(1):before {
+ content: "";
+ padding: 0;
+}
diff --git a/web/app/app.js b/web/app/app.js
new file mode 100644
index 00000000..fcbf7640
--- /dev/null
+++ b/web/app/app.js
@@ -0,0 +1,14 @@
+'use strict';
+
+// Declare app level module which depends on views, and components
+angular.module('myApp', [
+ 'ngRoute',
+ 'myApp.home',
+ 'myApp.about',
+ 'myApp.version'
+]).
+config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) {
+ $locationProvider.hashPrefix('!');
+
+ $routeProvider.otherwise({redirectTo: '/'});
+}]);
diff --git a/web/app/components/version/interpolate-filter.js b/web/app/components/version/interpolate-filter.js
new file mode 100644
index 00000000..03bb1987
--- /dev/null
+++ b/web/app/components/version/interpolate-filter.js
@@ -0,0 +1,9 @@
+'use strict';
+
+angular.module('myApp.version.interpolate-filter', [])
+
+.filter('interpolate', ['version', function(version) {
+ return function(text) {
+ return String(text).replace(/\%VERSION\%/mg, version);
+ };
+}]);
diff --git a/web/app/components/version/interpolate-filter_test.js b/web/app/components/version/interpolate-filter_test.js
new file mode 100644
index 00000000..ff56c529
--- /dev/null
+++ b/web/app/components/version/interpolate-filter_test.js
@@ -0,0 +1,15 @@
+'use strict';
+
+describe('myApp.version module', function() {
+ beforeEach(module('myApp.version'));
+
+ describe('interpolate filter', function() {
+ beforeEach(module(function($provide) {
+ $provide.value('version', 'TEST_VER');
+ }));
+
+ it('should replace VERSION', inject(function(interpolateFilter) {
+ expect(interpolateFilter('before %VERSION% after')).toEqual('before TEST_VER after');
+ }));
+ });
+});
diff --git a/web/app/components/version/version-directive.js b/web/app/components/version/version-directive.js
new file mode 100644
index 00000000..74088f8a
--- /dev/null
+++ b/web/app/components/version/version-directive.js
@@ -0,0 +1,9 @@
+'use strict';
+
+angular.module('myApp.version.version-directive', [])
+
+.directive('appVersion', ['version', function(version) {
+ return function(scope, elm, attrs) {
+ elm.text(version);
+ };
+}]);
diff --git a/web/app/components/version/version-directive_test.js b/web/app/components/version/version-directive_test.js
new file mode 100644
index 00000000..4a59e119
--- /dev/null
+++ b/web/app/components/version/version-directive_test.js
@@ -0,0 +1,17 @@
+'use strict';
+
+describe('myApp.version module', function() {
+ beforeEach(module('myApp.version'));
+
+ describe('app-version directive', function() {
+ it('should print current version', function() {
+ module(function($provide) {
+ $provide.value('version', 'TEST_VER');
+ });
+ inject(function($compile, $rootScope) {
+ var element = $compile(' ')($rootScope);
+ expect(element.text()).toEqual('TEST_VER');
+ });
+ });
+ });
+});
diff --git a/web/app/components/version/version.js b/web/app/components/version/version.js
new file mode 100644
index 00000000..cb7a10f9
--- /dev/null
+++ b/web/app/components/version/version.js
@@ -0,0 +1,8 @@
+'use strict';
+
+angular.module('myApp.version', [
+ 'myApp.version.interpolate-filter',
+ 'myApp.version.version-directive'
+])
+
+.value('version', '0.1');
diff --git a/web/app/components/version/version_test.js b/web/app/components/version/version_test.js
new file mode 100644
index 00000000..4ca6880d
--- /dev/null
+++ b/web/app/components/version/version_test.js
@@ -0,0 +1,11 @@
+'use strict';
+
+describe('myApp.version module', function() {
+ beforeEach(module('myApp.version'));
+
+ describe('version service', function() {
+ it('should return current version', inject(function(version) {
+ expect(version).toEqual('0.1');
+ }));
+ });
+});
diff --git a/web/app/index-async.html b/web/app/index-async.html
new file mode 100644
index 00000000..39a592fb
--- /dev/null
+++ b/web/app/index-async.html
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+ My AngularJS App
+
+
+
+
+
+
+
+ Angular seed app: v
+
+
+
diff --git a/web/app/index.html b/web/app/index.html
new file mode 100644
index 00000000..66d52107
--- /dev/null
+++ b/web/app/index.html
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+ GoCrpto Trader
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright 2016 GoCrypto Trader
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/app/views/about/about.html b/web/app/views/about/about.html
new file mode 100644
index 00000000..d5c01f4c
--- /dev/null
+++ b/web/app/views/about/about.html
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
+ README.md
+
+
+
Cryptocurrency trading bot written in Golang
+
+
+
+
+A cryptocurrency trading bot supporting multiple exchanges written in Golang.
+
+Please note that this bot is under development and is not ready for production!
+
+ Exchange Support Table
+
+
+
+Exchange
+REST API
+Streaming API
+FIX API
+
+
+
+Alphapoint
+Yes
+Yes
+NA
+
+
+ANXPRO
+Yes
+No
+NA
+
+
+Bitfinex
+Yes
+Yes
+NA
+
+
+Bitstamp
+Yes
+Yes
+NA
+
+
+BTCC
+Yes
+Yes
+No
+
+
+BTCE
+Yes
+NA
+NA
+
+
+BTCMarkets
+Yes
+NA
+NA
+
+
+Coinbase
+Yes
+Yes
+No
+
+
+Gemini
+Yes
+NA
+NA
+
+
+Huobi
+Yes
+Yes
+No
+
+
+ItBit
+Yes
+NA
+NA
+
+
+Kraken
+Yes
+NA
+NA
+
+
+LakeBTC
+Yes
+Yes
+NA
+
+
+LocalBitcoins
+Yes
+NA
+NA
+
+
+OKCoin (both)
+Yes
+Yes
+No
+
+
+Poloniex
+Yes
+Yes
+NA
+
+
+
+** NA means not applicable as the Exchange does not support the feature.
+
+ Current Features
+
+
+Support for all Exchange fiat and digital currencies, with the ability to individually toggle them on/off.
+REST API support for all exchanges.
+Websocket support for applicable exchanges.
+Ability to turn off/on certain exchanges.
+Ability to adjust manual polling timer for exchanges.
+SMS notification support via SMS Gateway.
+Basic event trigger system.
+
+
+ Planned Features
+
+
+WebGUI.
+FIX support.
+Expanding event trigger system.
+TALib.
+Trade history summary generation for tax purposes.
+
+
+Please feel free to submit any pull requests or suggest any desired features to be added.
+
+ Compiling instructions
+
+Download Go from https://golang.org/dl/
+Using a terminal, type go get github.com/thrasher-/gocryptotrader
+Change directory to the package directory, then type go install.
+Copy config_example.json to config.json.
+Make any neccessary changes to the config file.
+Run the application!
+
+ Binaries
+
+Binaries will be published once the codebase reaches a stable condition.
+
+
+
+
+
+
+
+
+
Look I'm A Sidebar!
+
+
+
+
+
\ No newline at end of file
diff --git a/web/app/views/about/about.js b/web/app/views/about/about.js
new file mode 100644
index 00000000..88de9479
--- /dev/null
+++ b/web/app/views/about/about.js
@@ -0,0 +1,14 @@
+'use strict';
+
+angular.module('myApp.about', ['ngRoute'])
+
+.config(['$routeProvider', function($routeProvider) {
+ $routeProvider.when('/about', {
+ templateUrl: '/views/about/about.html',
+ controller: 'AboutController'
+ });
+}])
+
+.controller('AboutController', [function() {
+
+}]);
\ No newline at end of file
diff --git a/web/app/views/about/about_test.js b/web/app/views/about/about_test.js
new file mode 100644
index 00000000..07b34d6b
--- /dev/null
+++ b/web/app/views/about/about_test.js
@@ -0,0 +1,16 @@
+'use strict';
+
+describe('myApp.view2 module', function() {
+
+ beforeEach(module('myApp.view2'));
+
+ describe('view2 controller', function(){
+
+ it('should ....', inject(function($controller) {
+ //spec body
+ var view2Ctrl = $controller('View2Ctrl');
+ expect(view2Ctrl).toBeDefined();
+ }));
+
+ });
+});
\ No newline at end of file
diff --git a/web/app/views/home/home.html b/web/app/views/home/home.html
new file mode 100644
index 00000000..0eddc317
--- /dev/null
+++ b/web/app/views/home/home.html
@@ -0,0 +1,28 @@
+Dashboard
+All enabled currencies
+
+
{{exchange.exchangeName}}
+
+
+ Currency
+ Last
+ High
+ Low
+ Volume
+ Bid
+ Ask
+
+
+ {{value.CryptoCurrency}}
+ {{value.Last}}
+ {{value.High}}
+ {{value.Low}}
+ {{value.Volume}}
+ {{value.Bid}}
+ {{value.Ask}}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web/app/views/home/home.js b/web/app/views/home/home.js
new file mode 100644
index 00000000..d2412903
--- /dev/null
+++ b/web/app/views/home/home.js
@@ -0,0 +1,28 @@
+'use strict';
+
+angular.module('myApp.home', ['ngRoute'])
+
+.config(['$routeProvider', function($routeProvider) {
+ $routeProvider.when('/', {
+ templateUrl: '/views/home/home.html',
+ controller: 'HomeController'
+ });
+}])
+
+.controller('HomeController', function ($scope, $http) {
+ $scope.getDashboardData = function() {
+ $http({
+ method: 'GET',
+ url: '/data/all-enabled-currencies'
+ }).
+ success(function (data, status, headers, config) {
+ $scope.exchanges = data.data;
+ }).
+ error(function (data, status, headers, config) {
+ console.log('error');
+ });
+ };
+
+ $scope.getDashboardData();
+
+});
\ No newline at end of file
diff --git a/web/app/views/home/home_test.js b/web/app/views/home/home_test.js
new file mode 100644
index 00000000..14ba79b4
--- /dev/null
+++ b/web/app/views/home/home_test.js
@@ -0,0 +1,16 @@
+'use strict';
+
+describe('myApp.view1 module', function() {
+
+ beforeEach(module('myApp.view1'));
+
+ describe('view1 controller', function(){
+
+ it('should ....', inject(function($controller) {
+ //spec body
+ var view1Ctrl = $controller('View1Ctrl');
+ expect(view1Ctrl).toBeDefined();
+ }));
+
+ });
+});
\ No newline at end of file
diff --git a/web/bower.json b/web/bower.json
new file mode 100644
index 00000000..66d9d74e
--- /dev/null
+++ b/web/bower.json
@@ -0,0 +1,15 @@
+{
+ "name": "angular-seed",
+ "description": "A starter project for AngularJS",
+ "version": "0.0.0",
+ "homepage": "https://github.com/angular/angular-seed",
+ "license": "MIT",
+ "private": true,
+ "dependencies": {
+ "angular": "~1.5.0",
+ "angular-route": "~1.5.0",
+ "angular-loader": "~1.5.0",
+ "angular-mocks": "~1.5.0",
+ "html5-boilerplate": "^5.3.0"
+ }
+}
diff --git a/web/e2e-tests/protractor.conf.js b/web/e2e-tests/protractor.conf.js
new file mode 100644
index 00000000..13c5cb62
--- /dev/null
+++ b/web/e2e-tests/protractor.conf.js
@@ -0,0 +1,22 @@
+//jshint strict: false
+exports.config = {
+
+ allScriptsTimeout: 11000,
+
+ specs: [
+ '*.js'
+ ],
+
+ capabilities: {
+ 'browserName': 'chrome'
+ },
+
+ baseUrl: 'http://localhost:8000/',
+
+ framework: 'jasmine',
+
+ jasmineNodeOpts: {
+ defaultTimeoutInterval: 30000
+ }
+
+};
diff --git a/web/e2e-tests/scenarios.js b/web/e2e-tests/scenarios.js
new file mode 100644
index 00000000..240d5f61
--- /dev/null
+++ b/web/e2e-tests/scenarios.js
@@ -0,0 +1,42 @@
+'use strict';
+
+/* https://github.com/angular/protractor/blob/master/docs/toc.md */
+
+describe('my app', function() {
+
+
+ it('should automatically redirect to /view1 when location hash/fragment is empty', function() {
+ browser.get('index.html');
+ expect(browser.getLocationAbsUrl()).toMatch("/view1");
+ });
+
+
+ describe('view1', function() {
+
+ beforeEach(function() {
+ browser.get('index.html#!/view1');
+ });
+
+
+ it('should render view1 when user navigates to /view1', function() {
+ expect(element.all(by.css('[ng-view] p')).first().getText()).
+ toMatch(/partial for view 1/);
+ });
+
+ });
+
+
+ describe('view2', function() {
+
+ beforeEach(function() {
+ browser.get('index.html#!/view2');
+ });
+
+
+ it('should render view2 when user navigates to /view2', function() {
+ expect(element.all(by.css('[ng-view] p')).first().getText()).
+ toMatch(/partial for view 2/);
+ });
+
+ });
+});
diff --git a/web/footer.html b/web/footer.html
deleted file mode 100644
index 37bdaade..00000000
--- a/web/footer.html
+++ /dev/null
@@ -1,4 +0,0 @@
-{{define "footer"}}
-