Engine changes

This commit is contained in:
Adrian Gallagher
2018-10-30 16:19:59 +11:00
parent 53964aadf5
commit f5914e8c10
310 changed files with 23570 additions and 9155 deletions

View File

@@ -10,5 +10,5 @@ FROM alpine:latest
RUN apk update && apk add --no-cache ca-certificates
COPY --from=build /go/bin/gocryptotrader /app/
COPY --from=build /go/src/github.com/thrasher-/gocryptotrader/config.json /app/
EXPOSE 9050
EXPOSE 9050-9053
CMD ["/app/gocryptotrader"]

View File

@@ -0,0 +1,51 @@
package main
import (
"encoding/json"
"log"
"sync"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/engine"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
)
func main() {
var err error
engine.Bot, err = engine.New()
if err != nil {
log.Fatalf("Failed to initialise engine. Err: %s", err)
}
log.Printf("Loading exchanges..")
var wg sync.WaitGroup
for x := range exchange.Exchanges {
name := exchange.Exchanges[x]
err = engine.LoadExchange(name, true, &wg)
if err != nil {
log.Printf("Failed to load exchange %s. Err: %s", name, err)
continue
}
}
wg.Wait()
log.Println("Done.")
var cfgs []config.ExchangeConfig
for x := range engine.Bot.Exchanges {
var cfg *config.ExchangeConfig
cfg, err = engine.Bot.Exchanges[x].GetDefaultConfig()
if err != nil {
log.Printf("Failed to get exchanges default config. Err: %s", err)
continue
}
log.Printf("Adding %s", engine.Bot.Exchanges[x].GetName())
cfgs = append(cfgs, *cfg)
}
data, err := json.MarshalIndent(cfgs, "", " ")
if err != nil {
log.Fatalf("Unable to marshal cfgs. Err: %s", err)
}
log.Println(string(data))
}

View File

@@ -33,22 +33,22 @@ main.go
```go
var a exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "ANX" {
a = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "ANX" {
a = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := a.GetTickerPrice()
tick, err := a.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := a.GetOrderbookEx()
ob, err := a.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -30,22 +30,22 @@ main.go
```go
var b exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Binance" {
b = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Binance" {
b = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := b.GetTickerPrice()
tick, err := b.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := b.GetOrderbookEx()
ob, err := b.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -30,22 +30,22 @@ main.go
```go
var b exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Bitfinex" {
b = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Bitfinex" {
b = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := b.GetTickerPrice()
tick, err := b.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := b.GetOrderbookEx()
ob, err := b.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var b exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Bitflyer" {
b = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Bitflyer" {
b = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := b.GetTickerPrice()
tick, err := b.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := b.GetOrderbookEx()
ob, err := b.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var b exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Bithumb" {
b = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Bithumb" {
b = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := b.GetTickerPrice()
tick, err := b.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := b.GetOrderbookEx()
ob, err := b.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var b exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Bitmex" {
b = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Bitmex" {
b = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := b.GetTickerPrice()
tick, err := b.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := b.GetOrderbookEx()
ob, err := b.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -30,22 +30,22 @@ main.go
```go
var b exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Bitstamp" {
b = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Bitstamp" {
b = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := b.GetTickerPrice()
tick, err := b.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := b.GetOrderbookEx()
ob, err := b.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var b exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Bittrex" {
b = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Bittrex" {
b = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := b.GetTickerPrice()
tick, err := b.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := b.GetOrderbookEx()
ob, err := b.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -30,22 +30,22 @@ main.go
```go
var b exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "BTCC" {
b = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "BTCC" {
b = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := b.GetTickerPrice()
tick, err := b.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := b.GetOrderbookEx()
ob, err := b.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var b exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "BTCMarkets" {
b = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "BTCMarkets" {
b = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := b.GetTickerPrice()
tick, err := b.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := b.GetOrderbookEx()
ob, err := b.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -30,22 +30,22 @@ main.go
```go
var c exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "CoinbasePro" {
c = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "CoinbasePro" {
c = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := c.GetTickerPrice()
tick, err := c.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := c.GetOrderbookEx()
ob, err := c.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -30,22 +30,22 @@ main.go
```go
var c exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Coinut" {
c = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Coinut" {
c = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := c.GetTickerPrice()
tick, err := c.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := c.GetOrderbookEx()
ob, err := c.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -16,7 +16,7 @@ exchange interface system set by exchange wrapper orderbook functions in
Examples below:
```go
ob, err := yobitExchange.GetOrderbookEx()
ob, err := yobitExchange.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -17,7 +17,7 @@ exchange interface system set by exchange wrapper orderbook functions in
Examples below:
```go
tick, err := yobitExchange.GetTickerPrice()
tick, err := yobitExchange.FetchTicker()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var e exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Exmo" {
e = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Exmo" {
e = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := e.GetTickerPrice()
tick, err := e.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := e.GetOrderbookEx()
ob, err := e.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var g exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "GateIO" {
g = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "GateIO" {
g = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := g.GetTickerPrice()
tick, err := g.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := g.GetOrderbookEx()
ob, err := g.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var g exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Gemini" {
g = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Gemini" {
g = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := g.GetTickerPrice()
tick, err := g.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := g.GetOrderbookEx()
ob, err := g.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -30,22 +30,22 @@ main.go
```go
var h exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "HitBTC" {
h = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "HitBTC" {
h = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := h.GetTickerPrice()
tick, err := h.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := h.GetOrderbookEx()
ob, err := h.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var h exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Huobi" {
h = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Huobi" {
h = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := h.GetTickerPrice()
tick, err := h.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := h.GetOrderbookEx()
ob, err := h.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var h exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "HuobiHadax" {
h = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "HuobiHadax" {
h = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := h.GetTickerPrice()
tick, err := h.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := h.GetOrderbookEx()
ob, err := h.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var i exchange.IBotExchange
for x := range bot.exchanges {
if bot.exchanges[x].GetName() == "Itbit" {
i = bot.exchanges[x]
for x := range bot.Exchanges {
if bot.Exchanges[x].GetName() == "Itbit" {
i = bot.Exchanges[x]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := i.GetTickerPrice()
tick, err := i.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := i.GetOrderbookEx()
ob, err := i.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var k exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Kraken" {
k = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Kraken" {
k = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := k.GetTickerPrice()
tick, err := k.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := k.GetOrderbookEx()
ob, err := k.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var l exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "LakeBTC" {
l = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "LakeBTC" {
l = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := l.GetTickerPrice()
tick, err := l.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := l.GetOrderbookEx()
ob, err := l.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var l exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "LocalBitcoins" {
l = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "LocalBitcoins" {
l = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := l.GetTickerPrice()
tick, err := l.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := l.GetOrderbookEx()
ob, err := l.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -30,22 +30,22 @@ main.go
```go
var o exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "OKCoin" {
y = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "OKCoin" {
y = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := o.GetTickerPrice()
tick, err := o.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := o.GetOrderbookEx()
ob, err := o.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var o exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "OKex" {
y = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "OKex" {
y = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := o.GetTickerPrice()
tick, err := o.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := o.GetOrderbookEx()
ob, err := o.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -30,22 +30,22 @@ main.go
```go
var p exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Poloniex" {
y = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Poloniex" {
y = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := p.GetTickerPrice()
tick, err := p.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := p.GetOrderbookEx()
ob, err := p.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var y exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "Yobit" {
y = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "Yobit" {
y = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := y.GetTickerPrice()
tick, err := y.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := y.GetOrderbookEx()
ob, err := y.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -29,22 +29,22 @@ main.go
```go
var z exchange.IBotExchange
for i := range bot.exchanges {
if bot.exchanges[i].GetName() == "ZB" {
z = bot.exchanges[i]
for i := range bot.Exchanges {
if bot.Exchanges[i].GetName() == "ZB" {
z = bot.Exchanges[i]
}
}
// Public calls - wrapper functions
// Fetches current ticker information
tick, err := z.GetTickerPrice()
tick, err := z.FetchTicker()
if err != nil {
// Handle error
}
// Fetches current orderbook information
ob, err := z.GetOrderbookEx()
ob, err := z.FetchOrderbook()
if err != nil {
// Handle error
}

View File

@@ -8,6 +8,9 @@ import (
"os"
"os/exec"
"github.com/thrasher-/gocryptotrader/currency"
"github.com/thrasher-/gocryptotrader/exchanges/assets"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
)
@@ -117,10 +120,14 @@ func main() {
newExchConfig := config.ExchangeConfig{}
newExchConfig.Name = capName
newExchConfig.Enabled = true
newExchConfig.RESTPollingDelay = 10
newExchConfig.APIKey = "Key"
newExchConfig.APISecret = "Secret"
newExchConfig.AssetTypes = "SPOT"
newExchConfig.API.Credentials.Key = "Key"
newExchConfig.API.Credentials.Secret = "Secret"
newExchConfig.CurrencyPairs = &currency.PairsManager{
AssetTypes: assets.AssetTypes{
assets.AssetTypeSpot,
},
}
configTestFile.Exchanges = append(configTestFile.Exchanges, newExchConfig)
// TODO sorting function so exchanges are in alphabetical order - low priority

View File

@@ -32,36 +32,34 @@ func ({{.Variable}} *{{.CapitalName}}) SetDefaults() {
{{.Variable}}.Name = "{{.CapitalName}}"
{{.Variable}}.Enabled = false
{{.Variable}}.Verbose = false
{{.Variable}}.RESTPollingDelay = 10
{{.Variable}}.RequestCurrencyPairFormat.Delimiter = ""
{{.Variable}}.RequestCurrencyPairFormat.Uppercase = true
{{.Variable}}.ConfigCurrencyPairFormat.Delimiter = ""
{{.Variable}}.ConfigCurrencyPairFormat.Uppercase = true
{{.Variable}}.AssetTypes = []string{ticker.Spot}
{{.Variable}}.AssetTypes = assets.AssetTypes{assets.AssetTypeSpot}
{{.Variable}}.SupportsAutoPairUpdating = false
{{.Variable}}.SupportsRESTTickerBatching = false
{{.Variable}}.Requester = request.New({{.Variable}}.Name,
request.NewRateLimit(time.Second, 0),
request.NewRateLimit(time.Second, 0),
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout))
{{.Variable}}.APIUrlDefault = {{.Name}}APIURL
{{.Variable}}.APIUrl = {{.Variable}}.APIUrlDefault
{{.Variable}}.API.Endpoints.URLDefault = {{.Name}}APIURL
{{.Variable}}.API.Endpoints.URL = {{.Variable}}.API.Endpoints.URLDefault
{{.Variable}}.WebsocketInit()
}
// Setup takes in the supplied exchange configuration details and sets params
func ({{.Variable}} *{{.CapitalName}}) Setup(exch *config.ExchangeConfig) {
func ({{.Variable}} *{{.CapitalName}}) Setup(exch *config.ExchangeConfig) error {
if !exch.Enabled {
{{.Variable}}.SetEnabled(false)
} else {
{{.Variable}}.Enabled = true
{{.Variable}}.AuthenticatedAPISupport = exch.AuthenticatedAPISupport
{{.Variable}}.SetAPIKeys(exch.APIKey, exch.APISecret, "", false)
{{.Variable}}.API.AuthenticatedSupport = exch.API.AuthenticatedSupport
{{.Variable}}.SetAPIKeys(exch.API.Credentials.Key, exch.API.Credentials.Secret, "", false)
{{.Variable}}.SetHTTPClientTimeout(exch.HTTPTimeout)
{{.Variable}}.SetHTTPClientUserAgent(exch.HTTPUserAgent)
{{.Variable}}.RESTPollingDelay = exch.RESTPollingDelay
{{.Variable}}.Verbose = exch.Verbose
{{.Variable}}.Websocket.SetWsStatusAndConnection(exch.Websocket)
{{.Variable}}.Websocket.SetWsStatusAndConnection(exch.Features.Enabled.Websocket)
{{.Variable}}.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
{{.Variable}}.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
{{.Variable}}.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
@@ -73,7 +71,7 @@ func ({{.Variable}} *{{.CapitalName}}) Setup(exch *config.ExchangeConfig) {
if err != nil {
log.Fatal(err)
}
err = {{.Variable}}.SetAutoPairDefaults()
err = {{.Variable}}.SetFeatureDefaults()
if err != nil {
log.Fatal(err)
}
@@ -89,9 +87,9 @@ func ({{.Variable}} *{{.CapitalName}}) Setup(exch *config.ExchangeConfig) {
// If the exchange supports websocket, update the below block
// err = {{.Variable}}.WebsocketSetup({{.Variable}}.WsConnect,
// exch.Name,
// exch.Websocket,
// exch.Features.Enabled.Websocket,
// {{.Name}}Websocket,
// exch.WebsocketURL)
// exch.Features.Enabled.WebsocketURL)
// if err != nil {
// log.Fatal(err)
// }

View File

@@ -27,9 +27,9 @@ func TestSetup(t *testing.T) {
t.Error("Test Failed - {{.CapitalName}} Setup() init error")
}
{{.Name}}Config.AuthenticatedAPISupport = true
{{.Name}}Config.APIKey = testAPIKey
{{.Name}}Config.APISecret = testAPISecret
{{.Name}}Config.API.AuthenticatedSupport = true
{{.Name}}Config.API.Credentials.Key = testAPIKey
{{.Name}}Config.API.Credentials.Secret = testAPISecret
{{.Variable}}.Setup({{.Name}}Config)
}

View File

@@ -31,7 +31,7 @@ func ({{.Variable}} *{{.CapitalName}}) Run() {
}
// UpdateTicker updates and returns the ticker for a currency pair
func ({{.Variable}} *{{.CapitalName}}) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
func ({{.Variable}} *{{.CapitalName}}) UpdateTicker(p currency.Pair, assetType assets.AssetType) (ticker.Price, error) {
var tickerPrice ticker.Price
// NOTE EXAMPLE FOR GETTING TICKER PRICE
//tick, err := {{.Variable}}.GetTickers()
@@ -39,7 +39,7 @@ func ({{.Variable}} *{{.CapitalName}}) UpdateTicker(p currency.Pair, assetType s
// return tickerPrice, err
//}
//for _, x := range {{.Variable}}.GetEnabledCurrencies() {
//for _, x := range {{.Variable}}.GetEnabledPairs(assetType) {
//curr := exchange.FormatExchangeCurrency({{.Variable}}.Name, x)
//for y := range tick {
// if tick[y].Symbol == curr.String() {
@@ -58,8 +58,8 @@ func ({{.Variable}} *{{.CapitalName}}) UpdateTicker(p currency.Pair, assetType s
return tickerPrice, nil // NOTE DO NOT USE AS RETURN
}
// GetTickerPrice returns the ticker for a currency pair
func ({{.Variable}} *{{.CapitalName}}) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
// FetchTicker returns the ticker for a currency pair
func ({{.Variable}} *{{.CapitalName}}) FetchTicker(p currency.Pair, assetType assets.AssetType) (ticker.Price, error) {
tickerNew, err := ticker.GetTicker({{.Variable}}.GetName(), p, assetType)
if err != nil {
return {{.Variable}}.UpdateTicker(p, assetType)
@@ -67,8 +67,8 @@ func ({{.Variable}} *{{.CapitalName}}) GetTickerPrice(p currency.Pair, assetType
return tickerNew, nil
}
// GetOrderbookEx returns orderbook base on the currency pair
func ({{.Variable}} *{{.CapitalName}}) GetOrderbookEx(currency currency.Pair, assetType string) (orderbook.Base, error) {
// FetchOrderbook returns orderbook base on the currency pair
func ({{.Variable}} *{{.CapitalName}}) FetchOrderbook(currency currency.Pair, assetType assets.AssetType) (orderbook.Base, error) {
ob, err := orderbook.Get({{.Variable}}.GetName(), currency, assetType)
if err != nil {
return {{.Variable}}.UpdateOrderbook(currency, assetType)
@@ -77,7 +77,7 @@ func ({{.Variable}} *{{.CapitalName}}) GetOrderbookEx(currency currency.Pair, as
}
// UpdateOrderbook updates and returns the orderbook for a currency pair
func ({{.Variable}} *{{.CapitalName}}) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
func ({{.Variable}} *{{.CapitalName}}) UpdateOrderbook(p currency.Pair, assetType assets.AssetType) (orderbook.Base, error) {
var orderBook orderbook.Base
//NOTE UPDATE ORDERBOOK EXAMPLE
//orderbookNew, err := {{.Variable}}.GetOrderBook(exchange.FormatExchangeCurrency({{.Variable}}.Name, p).String(), 1000)
@@ -111,7 +111,7 @@ func ({{.Variable}} *{{.CapitalName}}) GetFundingHistory() ([]exchange.FundHisto
}
// GetExchangeHistory returns historic trade data since exchange opening.
func ({{.Variable}} *{{.CapitalName}}) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
func ({{.Variable}} *{{.CapitalName}}) GetExchangeHistory(p currency.Pair, assetType assets.AssetType) ([]exchange.TradeHistory, error) {
return nil, common.ErrNotYetImplemented
}

View File

@@ -0,0 +1,174 @@
package main
import (
"log"
"sync"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/currency"
"github.com/thrasher-/gocryptotrader/engine"
exchange "github.com/thrasher-/gocryptotrader/exchanges"
"github.com/thrasher-/gocryptotrader/exchanges/assets"
)
const (
totalWrappers = 20
)
func main() {
var err error
engine.Bot, err = engine.New()
if err != nil {
log.Fatalf("Failed to initialise engine. Err: %s", err)
}
engine.Bot.Settings = engine.Settings{
DisableExchangeAutoPairUpdates: true,
}
log.Printf("Loading exchanges..")
var wg sync.WaitGroup
for x := range exchange.Exchanges {
name := exchange.Exchanges[x]
err := engine.LoadExchange(name, true, &wg)
if err != nil {
log.Printf("Failed to load exchange %s. Err: %s", name, err)
continue
}
}
wg.Wait()
log.Println("Done.")
log.Printf("Testing exchange wrappers..")
results := make(map[string][]string)
wg = sync.WaitGroup{}
for x := range engine.Bot.Exchanges {
wg.Add(1)
go func(num int) {
name := engine.Bot.Exchanges[num].GetName()
results[name] = testWrappers(engine.Bot.Exchanges[num])
wg.Done()
}(x)
}
wg.Wait()
log.Println("Done.")
log.Println()
for name, funcs := range results {
pct := float64(totalWrappers-len(funcs)) / float64(totalWrappers) * 100
log.Printf("Exchange %s wrapper coverage [%d/%d - %.2f%%] | Total missing: %d", name, totalWrappers-len(funcs), totalWrappers, pct, len(funcs))
log.Printf("\t Wrappers not implemented:")
for x := range funcs {
log.Printf("\t - %s", funcs[x])
}
log.Println()
}
}
func testWrappers(e exchange.IBotExchange) []string {
p := currency.NewPair(currency.BTC, currency.USD)
assetType := assets.AssetTypeSpot
var funcs []string
_, err := e.FetchTicker(p, assetType)
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "FetchTicker")
}
_, err = e.UpdateTicker(p, assetType)
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "UpdateTicker")
}
_, err = e.FetchOrderbook(p, assetType)
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "FetchOrderbook")
}
_, err = e.UpdateOrderbook(p, assetType)
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "UpdateOrderbook")
}
_, err = e.FetchTradablePairs(assets.AssetTypeSpot)
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "FetchTradablePairs")
}
err = e.UpdateTradablePairs(false)
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "UpdateTradablePairs")
}
_, err = e.GetAccountInfo()
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "GetAccountInfo")
}
_, err = e.GetExchangeHistory(p, assetType)
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "GetExchangeHistory")
}
_, err = e.GetFundingHistory()
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "GetFundingHistory")
}
_, err = e.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1000000, 10000000000, "meow")
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "SubmitOrder")
}
_, err = e.ModifyOrder(&exchange.ModifyOrder{})
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "ModifyOrder")
}
err = e.CancelOrder(&exchange.OrderCancellation{})
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "CancelOrder")
}
_, err = e.CancelAllOrders(&exchange.OrderCancellation{})
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "CancelAllOrders")
}
_, err = e.GetOrderInfo("1")
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "GetOrderInfo")
}
_, err = e.GetOrderHistory(&exchange.GetOrdersRequest{})
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "GetOrderHistory")
}
_, err = e.GetActiveOrders(&exchange.GetOrdersRequest{})
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "GetActiveOrders")
}
_, err = e.GetDepositAddress(currency.BTC, "")
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "GetDepositAddress")
}
_, err = e.WithdrawCryptocurrencyFunds(&exchange.CryptoWithdrawRequest{})
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "WithdrawCryptocurrencyFunds")
}
_, err = e.WithdrawFiatFunds(&exchange.FiatWithdrawRequest{})
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "WithdrawFiatFunds")
}
_, err = e.WithdrawFiatFundsToInternationalBank(&exchange.FiatWithdrawRequest{})
if err == common.ErrNotYetImplemented {
funcs = append(funcs, "WithdrawFiatFundsToInternationalBank")
}
return funcs
}

1502
cmd/gctcli/commands.go Normal file

File diff suppressed because it is too large Load Diff

115
cmd/gctcli/main.go Normal file
View File

@@ -0,0 +1,115 @@
package main
import (
"encoding/json"
"fmt"
"log"
"os"
"path/filepath"
"runtime"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/core"
"github.com/thrasher-/gocryptotrader/gctrpc/auth"
"github.com/urfave/cli"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
var (
host string
username string
password string
)
func jsonOutput(in interface{}) {
j, err := json.MarshalIndent(in, "", " ")
if err != nil {
return
}
fmt.Print(string(j))
}
func setupClient() (*grpc.ClientConn, error) {
targetPath := filepath.Join(common.GetDefaultDataDir(runtime.GOOS), "tls", "cert.pem")
creds, err := credentials.NewClientTLSFromFile(targetPath, "")
if err != nil {
return nil, err
}
opts := []grpc.DialOption{grpc.WithTransportCredentials(creds),
grpc.WithPerRPCCredentials(auth.BasicAuth{
Username: username,
Password: password,
}),
}
conn, err := grpc.Dial(host, opts...)
if err != nil {
return nil, err
}
return conn, err
}
func main() {
app := cli.NewApp()
app.Name = "gctcli"
app.Version = core.Version(true)
app.Usage = "command line interface for managing the gocryptotrader daemon"
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "rpchost",
Value: "localhost:9052",
Usage: "the gRPC host to connect to",
Destination: &host,
},
cli.StringFlag{
Name: "rpcuser",
Value: "admin",
Usage: "the gRPC username",
Destination: &username,
},
cli.StringFlag{
Name: "rpcpassword",
Value: "Password",
Usage: "the gRPC password",
Destination: &password,
},
}
app.Commands = []cli.Command{
getInfoCommand,
getExchangesCommand,
enableExchangeCommand,
disableExchangeCommand,
getExchangeInfoCommand,
getTickerCommand,
getTickersCommand,
getOrderbookCommand,
getOrderbooksCommand,
getAccountInfoCommand,
getConfigCommand,
getPortfolioCommand,
getPortfolioSummaryCommand,
addPortfolioAddressCommand,
removePortfolioAddressCommand,
getForexProvidersCommand,
getForexRatesCommand,
getOrdersCommand,
getOrderCommand,
submitOrderCommand,
cancelOrderCommand,
cancelAllOrdersCommand,
getEventsCommand,
addEventCommand,
removeEventCommand,
getCryptocurrencyDepositAddressesCommand,
getCryptocurrencyDepositAddressCommand,
withdrawCryptocurrencyFundsCommand,
withdrawFiatFundsCommand,
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}

105
cmd/gen_cert/main.go Normal file
View File

@@ -0,0 +1,105 @@
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"log"
"math/big"
"net"
"os"
"time"
"github.com/thrasher-/gocryptotrader/common"
)
func main() {
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
log.Fatalf("failed to generate private key: %s", err)
}
notBefore := time.Now()
notAfter := notBefore.Add(time.Hour * 24 * 365)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("failed to generate serial number: %s", err)
}
host, err := os.Hostname()
if err != nil {
log.Fatalf("failed to get hostname: %s", err)
}
dnsNames := []string{host}
if host != "localhost" {
dnsNames = append(dnsNames, "localhost")
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"gocryptotrader"},
CommonName: host,
},
NotBefore: notBefore,
NotAfter: notAfter,
IsCA: true,
BasicConstraintsValid: true,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
IPAddresses: []net.IP{
net.ParseIP("127.0.0.1"),
net.ParseIP("::1"),
},
DNSNames: dnsNames,
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privKey.PublicKey, privKey)
if err != nil {
log.Fatalf("Failed to create certificate: %s", err)
}
certData := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
if certData == nil {
log.Fatalf("cert data is nil")
}
b, err := x509.MarshalECPrivateKey(privKey)
if err != nil {
log.Printf("failed to marshal ECDSA private key: %s", err)
}
keyData := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: b})
if keyData == nil {
log.Fatalf("key pem data is nil")
}
err = common.WriteFile("key.pem", keyData)
if err != nil {
log.Fatalf("failed to write key.pem file %s", err)
}
log.Printf("wrote key.pem file")
err = common.WriteFile("cert.pem", certData)
if err != nil {
log.Fatalf("failed to write cert.pem file %s", err)
}
log.Printf("wrote cert.pem file")
log.Printf("testing tls.LoadX509Keypair..")
_, err = tls.LoadX509KeyPair("cert.pem", "key.pem")
if err != nil {
log.Fatal(err)
}
log.Printf("ok!")
}

View File

@@ -6,6 +6,7 @@ import (
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
@@ -129,19 +130,21 @@ func main() {
fmt.Println(string(pubKey))
type JSONGeneration struct {
APIAuthPEMKey string
PEMKey string
PEMKeySupport bool
}
r := JSONGeneration{
APIAuthPEMKey: string(privKey),
PEMKey: string(privKey),
PEMKeySupport: true,
}
resultk, err := common.JSONEncode(r)
resultk, err := json.MarshalIndent(r, "", " ")
if err != nil {
log.Fatal(err)
}
log.Println("Please visit https://github.com/huobiapi/API_Docs_en/wiki/Signing_API_Requests and follow from step 2 onwards.")
log.Printf("After completing the above instructions, please copy and paste the below key (including the following ',') into your Huobi exchange config file:\n\n")
log.Printf("After completing the above instructions, please copy and paste the below key in the API section (including the following ',') into your Huobi exchange config file:\n\n")
fmt.Println(string(resultk[1:len(resultk)-1]) + ",")
}

57
cmd/otp_gen/otp_gen.go Normal file
View File

@@ -0,0 +1,57 @@
package main
import (
"flag"
"log"
"time"
"github.com/pquerna/otp/totp"
"github.com/thrasher-/gocryptotrader/config"
)
func containsOTP(cfg *config.Config) bool {
for x := range cfg.Exchanges {
if cfg.Exchanges[x].API.Credentials.OTPSecret != "" {
return true
}
}
return false
}
func main() {
var inFile string
defaultCfg, err := config.GetFilePath("")
if err != nil {
log.Fatal(err)
}
flag.StringVar(&inFile, "infile", defaultCfg, "The config input file to process.")
flag.Parse()
log.Println("GoCryptoTrader: OTP code generator tool.")
var cfg config.Config
err = cfg.LoadConfig(inFile)
if err != nil {
log.Fatal(err)
}
log.Println("Loaded config file.")
if !containsOTP(&cfg) {
log.Println("No exchanges with OTP code stored. Exiting.")
}
for {
for x := range cfg.Exchanges {
if cfg.Exchanges[x].API.Credentials.OTPSecret != "" {
code, err := totp.GenerateCode(cfg.Exchanges[x].API.Credentials.OTPSecret, time.Now())
if err != nil {
log.Printf("Exchange %s: Failed to generate OTP code. Err: %s", cfg.Exchanges[x].Name, err)
continue
}
log.Printf("%s: %s", cfg.Exchanges[x].Name, code)
}
time.Sleep(time.Second)
}
}
}

View File

@@ -80,9 +80,9 @@ func main() {
}
log.Println("Loaded config file.")
displayCurrency = cfg.FiatDisplayCurrency
displayCurrency = cfg.Currency.FiatDisplayCurrency
port := portfolio.Base{}
port.SeedPortfolio(cfg.Portfolio)
port.Seed(cfg.Portfolio)
result := port.GetPortfolioSummary()
log.Println("Fetched portfolio data.")
@@ -132,6 +132,8 @@ func main() {
}
} else {
bf := bitfinex.Bitfinex{}
bf.SetDefaults()
bf.Verbose = false
ticker, errf := bf.GetTicker(y.Coin.String() + currency.USD.String())
if errf != nil {
log.Println(errf)

View File

@@ -8,7 +8,9 @@ import (
"github.com/gorilla/websocket"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/common/crypto"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/exchanges/assets"
)
// Vars for the websocket client
@@ -40,9 +42,9 @@ type WebsocketEventResponse struct {
// WebsocketOrderbookTickerRequest is a struct used for ticker and orderbook
// requests
type WebsocketOrderbookTickerRequest struct {
Exchange string `json:"exchangeName"`
Currency string `json:"currency"`
AssetType string `json:"assetType"`
Exchange string `json:"exchangeName"`
Currency string `json:"currency"`
AssetType assets.AssetType `json:"assetType"`
}
// SendWebsocketEvent sends a websocket event message
@@ -79,7 +81,7 @@ func main() {
log.Fatalf("Failed to load config file: %s", err)
}
listenAddr := cfg.Webserver.ListenAddress
listenAddr := cfg.RemoteControl.WebsocketRPC.ListenAddress
wsHost := fmt.Sprintf("ws://%s:%d/ws", common.ExtractHost(listenAddr),
common.ExtractPort(listenAddr))
log.Printf("Connecting to websocket host: %s", wsHost)
@@ -95,8 +97,8 @@ func main() {
log.Println("Authenticating..")
var wsResp WebsocketEventResponse
reqData := WebsocketAuth{
Username: cfg.Webserver.AdminUsername,
Password: common.HexEncodeToString(common.GetSHA256([]byte(cfg.Webserver.AdminPassword))),
Username: cfg.RemoteControl.Username,
Password: crypto.HexEncodeToString(crypto.GetSHA256([]byte(cfg.RemoteControl.Password))),
}
err = SendWebsocketEvent("auth", reqData, &wsResp)
if err != nil {
@@ -155,7 +157,7 @@ func main() {
dataReq := WebsocketOrderbookTickerRequest{
Exchange: "Bitfinex",
Currency: "BTCUSD",
AssetType: "SPOT",
AssetType: assets.AssetTypeSpot,
}
err = SendWebsocketEvent("GetTicker", dataReq, &wsResp)

View File

@@ -1,22 +1,12 @@
package common
import (
"crypto/hmac"
"crypto/md5" // nolint:gosec
"crypto/rand"
"crypto/sha1" // nolint:gosec
"crypto/sha256"
"crypto/sha512"
"encoding/base64"
"encoding/csv"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"hash"
"io"
"io/ioutil"
"math"
"net/http"
"net/url"
"os"
@@ -34,7 +24,8 @@ import (
// Vars for common.go operations
var (
HTTPClient *http.Client
HTTPClient *http.Client
HTTPUserAgent string
// ErrNotYetImplemented defines a common error across the code base that
// alerts of a function that has not been completed or tied into main code
@@ -47,11 +38,6 @@ var (
// Const declarations for common.go operations
const (
HashSHA1 = iota
HashSHA256
HashSHA512
HashSHA512_384
HashMD5
SatoshisPerBTC = 100000000
SatoshisPerLTC = 100000000
WeiPerEther = 1000000000000000000
@@ -71,95 +57,6 @@ func NewHTTPClientWithTimeout(t time.Duration) *http.Client {
return h
}
// GetRandomSalt returns a random salt
func GetRandomSalt(input []byte, saltLen int) ([]byte, error) {
if saltLen <= 0 {
return nil, errors.New("salt length is too small")
}
salt := make([]byte, saltLen)
if _, err := io.ReadFull(rand.Reader, salt); err != nil {
return nil, err
}
var result []byte
if input != nil {
result = input
}
result = append(result, salt...)
return result, nil
}
// GetMD5 returns a MD5 hash of a byte array
func GetMD5(input []byte) []byte {
m := md5.New() // nolint:gosec
m.Write(input)
return m.Sum(nil)
}
// GetSHA512 returns a SHA512 hash of a byte array
func GetSHA512(input []byte) []byte {
sha := sha512.New()
sha.Write(input)
return sha.Sum(nil)
}
// GetSHA256 returns a SHA256 hash of a byte array
func GetSHA256(input []byte) []byte {
sha := sha256.New()
sha.Write(input)
return sha.Sum(nil)
}
// GetHMAC returns a keyed-hash message authentication code using the desired
// hashtype
func GetHMAC(hashType int, input, key []byte) []byte {
var hasher func() hash.Hash
switch hashType {
case HashSHA1:
hasher = sha1.New
case HashSHA256:
hasher = sha256.New
case HashSHA512:
hasher = sha512.New
case HashSHA512_384:
hasher = sha512.New384
case HashMD5:
hasher = md5.New
}
h := hmac.New(hasher, key)
h.Write(input)
return h.Sum(nil)
}
// Sha1ToHex takes a string, sha1 hashes it and return a hex string of the
// result
func Sha1ToHex(data string) string {
h := sha1.New() // nolint:gosec
h.Write([]byte(data))
return hex.EncodeToString(h.Sum(nil))
}
// HexEncodeToString takes in a hexadecimal byte array and returns a string
func HexEncodeToString(input []byte) string {
return hex.EncodeToString(input)
}
// Base64Decode takes in a Base64 string and returns a byte array and an error
func Base64Decode(input string) ([]byte, error) {
result, err := base64.StdEncoding.DecodeString(input)
if err != nil {
return nil, err
}
return result, nil
}
// Base64Encode takes in a byte array then returns an encoded base64 string
func Base64Encode(input []byte) string {
return base64.StdEncoding.EncodeToString(input)
}
// StringSliceDifference concatenates slices together based on its index and
// returns an individual string array
func StringSliceDifference(slice1, slice2 []string) []string {
@@ -260,27 +157,6 @@ func StringToLower(input string) string {
return strings.ToLower(input)
}
// RoundFloat rounds your floating point number to the desired decimal place
func RoundFloat(x float64, prec int) float64 {
var rounder float64
pow := math.Pow(10, float64(prec))
intermed := x * pow
_, frac := math.Modf(intermed)
intermed += .5
x = .5
if frac < 0.0 {
x = -.5
intermed--
}
if frac >= x {
rounder = math.Ceil(intermed)
} else {
rounder = math.Floor(intermed)
}
return rounder / pow
}
// IsEnabled takes in a boolean param and returns a string if it is enabled
// or disabled
func IsEnabled(isEnabled bool) string {
@@ -314,33 +190,6 @@ func YesOrNo(input string) bool {
return false
}
// CalculateAmountWithFee returns a calculated fee included amount on fee
func CalculateAmountWithFee(amount, fee float64) float64 {
return amount + CalculateFee(amount, fee)
}
// CalculateFee returns a simple fee on amount
func CalculateFee(amount, fee float64) float64 {
return amount * (fee / 100)
}
// CalculatePercentageGainOrLoss returns the percentage rise over a certain
// period
func CalculatePercentageGainOrLoss(priceNow, priceThen float64) float64 {
return (priceNow - priceThen) / priceThen * 100
}
// CalculatePercentageDifference returns the percentage of difference between
// multiple time periods
func CalculatePercentageDifference(amount, secondAmount float64) float64 {
return (amount - secondAmount) / ((amount + secondAmount) / 2) * 100
}
// CalculateNetProfit returns net profit
func CalculateNetProfit(amount, priceThen, priceNow, costs float64) float64 {
return (priceNow * amount) - (priceThen * amount) - costs
}
// SendHTTPRequest sends a request using the http package and returns a response
// as a string and an error
func SendHTTPRequest(method, urlPath string, headers map[string]string, body io.Reader) (string, error) {
@@ -361,6 +210,10 @@ func SendHTTPRequest(method, urlPath string, headers map[string]string, body io.
req.Header.Add(k, v)
}
if HTTPUserAgent != "" && req.Header.Get("User-Agent") == "" {
req.Header.Add("User-Agent", HTTPUserAgent)
}
resp, err := HTTPClient.Do(req)
if err != nil {
return "", err

View File

@@ -1,7 +1,6 @@
package common
import (
"bytes"
"net/url"
"os"
"os/user"
@@ -74,142 +73,6 @@ func TestIsValidCryptoAddress(t *testing.T) {
}
}
func TestGetRandomSalt(t *testing.T) {
t.Parallel()
_, err := GetRandomSalt(nil, -1)
if err == nil {
t.Fatal("Test failed. Expected err on negative salt length")
}
salt, err := GetRandomSalt(nil, 10)
if err != nil {
t.Fatal(err)
}
if len(salt) != 10 {
t.Fatal("Test failed. Expected salt of len=10")
}
salt, err = GetRandomSalt([]byte("RAWR"), 12)
if err != nil {
t.Fatal(err)
}
if len(salt) != 16 {
t.Fatal("Test failed. Expected salt of len=16")
}
}
func TestGetMD5(t *testing.T) {
t.Parallel()
var originalString = []byte("I am testing the MD5 function in common!")
var expectedOutput = []byte("18fddf4a41ba90a7352765e62e7a8744")
actualOutput := GetMD5(originalString)
actualStr := HexEncodeToString(actualOutput)
if !bytes.Equal(expectedOutput, []byte(actualStr)) {
t.Errorf("Test failed. Expected '%s'. Actual '%s'",
expectedOutput, []byte(actualStr))
}
}
func TestGetSHA512(t *testing.T) {
t.Parallel()
var originalString = []byte("I am testing the GetSHA512 function in common!")
var expectedOutput = []byte(
`a2273f492ea73fddc4f25c267b34b3b74998bd8a6301149e1e1c835678e3c0b90859fce22e4e7af33bde1711cbb924809aedf5d759d648d61774b7185c5dc02b`,
)
actualOutput := GetSHA512(originalString)
actualStr := HexEncodeToString(actualOutput)
if !bytes.Equal(expectedOutput, []byte(actualStr)) {
t.Errorf("Test failed. Expected '%x'. Actual '%x'",
expectedOutput, []byte(actualStr))
}
}
func TestGetSHA256(t *testing.T) {
t.Parallel()
var originalString = []byte("I am testing the GetSHA256 function in common!")
var expectedOutput = []byte(
"0962813d7a9f739cdcb7f0c0be0c2a13bd630167e6e54468266e4af6b1ad9303",
)
actualOutput := GetSHA256(originalString)
actualStr := HexEncodeToString(actualOutput)
if !bytes.Equal(expectedOutput, []byte(actualStr)) {
t.Errorf("Test failed. Expected '%x'. Actual '%x'", expectedOutput,
[]byte(actualStr))
}
}
func TestGetHMAC(t *testing.T) {
t.Parallel()
expectedSha1 := []byte{
74, 253, 245, 154, 87, 168, 110, 182, 172, 101, 177, 49, 142, 2, 253, 165,
100, 66, 86, 246,
}
expectedsha256 := []byte{
54, 68, 6, 12, 32, 158, 80, 22, 142, 8, 131, 111, 248, 145, 17, 202, 224,
59, 135, 206, 11, 170, 154, 197, 183, 28, 150, 79, 168, 105, 62, 102,
}
expectedsha512 := []byte{
249, 212, 31, 38, 23, 3, 93, 220, 81, 209, 214, 112, 92, 75, 126, 40, 109,
95, 247, 182, 210, 54, 217, 224, 199, 252, 129, 226, 97, 201, 245, 220, 37,
201, 240, 15, 137, 236, 75, 6, 97, 12, 190, 31, 53, 153, 223, 17, 214, 11,
153, 203, 49, 29, 158, 217, 204, 93, 179, 109, 140, 216, 202, 71,
}
expectedsha512384 := []byte{
121, 203, 109, 105, 178, 68, 179, 57, 21, 217, 76, 82, 94, 100, 210, 1, 55,
201, 8, 232, 194, 168, 165, 58, 192, 26, 193, 167, 254, 183, 172, 4, 189,
158, 158, 150, 173, 33, 119, 125, 94, 13, 125, 89, 241, 184, 166, 128,
}
expectedmd5 := []byte{
113, 64, 132, 129, 213, 68, 231, 99, 252, 15, 175, 109, 198, 132, 139, 39,
}
sha1 := GetHMAC(HashSHA1, []byte("Hello,World"), []byte("1234"))
if string(sha1) != string(expectedSha1) {
t.Errorf("Test failed. Common GetHMAC error: Expected '%x'. Actual '%x'",
expectedSha1, sha1,
)
}
sha256 := GetHMAC(HashSHA256, []byte("Hello,World"), []byte("1234"))
if string(sha256) != string(expectedsha256) {
t.Errorf("Test failed. Common GetHMAC error: Expected '%x'. Actual '%x'",
expectedsha256, sha256,
)
}
sha512 := GetHMAC(HashSHA512, []byte("Hello,World"), []byte("1234"))
if string(sha512) != string(expectedsha512) {
t.Errorf("Test failed. Common GetHMAC error: Expected '%x'. Actual '%x'",
expectedsha512, sha512,
)
}
sha512384 := GetHMAC(HashSHA512_384, []byte("Hello,World"), []byte("1234"))
if string(sha512384) != string(expectedsha512384) {
t.Errorf("Test failed. Common GetHMAC error: Expected '%x'. Actual '%x'",
expectedsha512384, sha512384,
)
}
md5 := GetHMAC(HashMD5, []byte("Hello World"), []byte("1234"))
if string(md5) != string(expectedmd5) {
t.Errorf("Test failed. Common GetHMAC error: Expected '%x'. Actual '%x'",
expectedmd5, md5,
)
}
}
func TestSha1Tohex(t *testing.T) {
t.Parallel()
expectedResult := "fcfbfcd7d31d994ef660f6972399ab5d7a890149"
actualResult := Sha1ToHex("Testing Sha1ToHex")
if actualResult != expectedResult {
t.Errorf("Test failed. Expected '%s'. Actual '%s'",
expectedResult, actualResult)
}
}
func TestStringToLower(t *testing.T) {
t.Parallel()
upperCaseString := "HEY MAN"
@@ -232,44 +95,6 @@ func TestStringToUpper(t *testing.T) {
}
}
func TestHexEncodeToString(t *testing.T) {
t.Parallel()
originalInput := []byte("string")
expectedOutput := "737472696e67"
actualResult := HexEncodeToString(originalInput)
if actualResult != expectedOutput {
t.Errorf("Test failed. Expected '%s'. Actual '%s'",
expectedOutput, actualResult)
}
}
func TestBase64Decode(t *testing.T) {
t.Parallel()
originalInput := "aGVsbG8="
expectedOutput := []byte("hello")
actualResult, err := Base64Decode(originalInput)
if !bytes.Equal(actualResult, expectedOutput) {
t.Errorf("Test failed. Expected '%s'. Actual '%s'. Error: %s",
expectedOutput, actualResult, err)
}
_, err = Base64Decode("-")
if err == nil {
t.Error("Test failed. Bad base64 string failed returned nil error")
}
}
func TestBase64Encode(t *testing.T) {
t.Parallel()
originalInput := []byte("hello")
expectedOutput := "aGVsbG8="
actualResult := Base64Encode(originalInput)
if actualResult != expectedOutput {
t.Errorf("Test failed. Expected '%s'. Actual '%s'",
expectedOutput, actualResult)
}
}
func TestStringSliceDifference(t *testing.T) {
t.Parallel()
originalInputOne := []string{"hello"}
@@ -429,22 +254,6 @@ func TestReplaceString(t *testing.T) {
}
}
func TestRoundFloat(t *testing.T) {
t.Parallel()
// mapping of input vs expected result
testTable := map[float64]float64{
2.3232323: 2.32,
-2.3232323: -2.32,
}
for testInput, expectedOutput := range testTable {
actualOutput := RoundFloat(testInput, 2)
if actualOutput != expectedOutput {
t.Errorf("Test failed. RoundFloat Expected '%f'. Actual '%f'.",
expectedOutput, actualOutput)
}
}
}
func TestYesOrNo(t *testing.T) {
t.Parallel()
if !YesOrNo("y") {
@@ -458,68 +267,6 @@ func TestYesOrNo(t *testing.T) {
}
}
func TestCalculateFee(t *testing.T) {
t.Parallel()
originalInput := float64(1)
fee := float64(1)
expectedOutput := float64(0.01)
actualResult := CalculateFee(originalInput, fee)
if expectedOutput != actualResult {
t.Errorf(
"Test failed. Expected '%f'. Actual '%f'.", expectedOutput, actualResult)
}
}
func TestCalculateAmountWithFee(t *testing.T) {
t.Parallel()
originalInput := float64(1)
fee := float64(1)
expectedOutput := float64(1.01)
actualResult := CalculateAmountWithFee(originalInput, fee)
if expectedOutput != actualResult {
t.Errorf(
"Test failed. Expected '%f'. Actual '%f'.", expectedOutput, actualResult)
}
}
func TestCalculatePercentageGainOrLoss(t *testing.T) {
t.Parallel()
originalInput := float64(9300)
secondInput := float64(9000)
expectedOutput := 3.3333333333333335
actualResult := CalculatePercentageGainOrLoss(originalInput, secondInput)
if expectedOutput != actualResult {
t.Errorf(
"Test failed. Expected '%f'. Actual '%f'.", expectedOutput, actualResult)
}
}
func TestCalculatePercentageDifference(t *testing.T) {
t.Parallel()
originalInput := float64(10)
secondAmount := float64(5)
expectedOutput := 66.66666666666666
actualResult := CalculatePercentageDifference(originalInput, secondAmount)
if expectedOutput != actualResult {
t.Errorf(
"Test failed. Expected '%f'. Actual '%f'.", expectedOutput, actualResult)
}
}
func TestCalculateNetProfit(t *testing.T) {
t.Parallel()
amount := float64(5)
priceThen := float64(1)
priceNow := float64(10)
costs := float64(1)
expectedOutput := float64(44)
actualResult := CalculateNetProfit(amount, priceThen, priceNow, costs)
if expectedOutput != actualResult {
t.Errorf(
"Test failed. Expected '%f'. Actual '%f'.", expectedOutput, actualResult)
}
}
func TestSendHTTPRequest(t *testing.T) {
methodPost := "pOst"
methodGet := "GeT"

113
common/crypto/crypto.go Normal file
View File

@@ -0,0 +1,113 @@
package crypto
import (
"crypto/hmac"
"crypto/md5" // nolint:gosec
"crypto/rand"
"crypto/sha1" // nolint:gosec
"crypto/sha256"
"crypto/sha512"
"encoding/base64"
"encoding/hex"
"errors"
"hash"
"io"
)
// Const declarations for common.go operations
const (
HashSHA1 = iota
HashSHA256
HashSHA512
HashSHA512_384
HashMD5
)
// HexEncodeToString takes in a hexadecimal byte array and returns a string
func HexEncodeToString(input []byte) string {
return hex.EncodeToString(input)
}
// Base64Decode takes in a Base64 string and returns a byte array and an error
func Base64Decode(input string) ([]byte, error) {
result, err := base64.StdEncoding.DecodeString(input)
if err != nil {
return nil, err
}
return result, nil
}
// Base64Encode takes in a byte array then returns an encoded base64 string
func Base64Encode(input []byte) string {
return base64.StdEncoding.EncodeToString(input)
}
// GetRandomSalt returns a random salt
func GetRandomSalt(input []byte, saltLen int) ([]byte, error) {
if saltLen <= 0 {
return nil, errors.New("salt length is too small")
}
salt := make([]byte, saltLen)
if _, err := io.ReadFull(rand.Reader, salt); err != nil {
return nil, err
}
var result []byte
if input != nil {
result = input
}
result = append(result, salt...)
return result, nil
}
// GetMD5 returns a MD5 hash of a byte array
func GetMD5(input []byte) []byte {
m := md5.New() // nolint:gosec
m.Write(input)
return m.Sum(nil)
}
// GetSHA512 returns a SHA512 hash of a byte array
func GetSHA512(input []byte) []byte {
sha := sha512.New()
sha.Write(input)
return sha.Sum(nil)
}
// GetSHA256 returns a SHA256 hash of a byte array
func GetSHA256(input []byte) []byte {
sha := sha256.New()
sha.Write(input)
return sha.Sum(nil)
}
// GetHMAC returns a keyed-hash message authentication code using the desired
// hashtype
func GetHMAC(hashType int, input, key []byte) []byte {
var hasher func() hash.Hash
switch hashType {
case HashSHA1:
hasher = sha1.New
case HashSHA256:
hasher = sha256.New
case HashSHA512:
hasher = sha512.New
case HashSHA512_384:
hasher = sha512.New384
case HashMD5:
hasher = md5.New
}
h := hmac.New(hasher, key)
h.Write(input)
return h.Sum(nil)
}
// Sha1ToHex takes a string, sha1 hashes it and return a hex string of the
// result
func Sha1ToHex(data string) string {
h := sha1.New() // nolint:gosec
h.Write([]byte(data))
return hex.EncodeToString(h.Sum(nil))
}

View File

@@ -0,0 +1,180 @@
package crypto
import (
"bytes"
"testing"
)
func TestHexEncodeToString(t *testing.T) {
t.Parallel()
originalInput := []byte("string")
expectedOutput := "737472696e67"
actualResult := HexEncodeToString(originalInput)
if actualResult != expectedOutput {
t.Errorf("Test failed. Expected '%s'. Actual '%s'",
expectedOutput, actualResult)
}
}
func TestBase64Decode(t *testing.T) {
t.Parallel()
originalInput := "aGVsbG8="
expectedOutput := []byte("hello")
actualResult, err := Base64Decode(originalInput)
if !bytes.Equal(actualResult, expectedOutput) {
t.Errorf("Test failed. Expected '%s'. Actual '%s'. Error: %s",
expectedOutput, actualResult, err)
}
_, err = Base64Decode("-")
if err == nil {
t.Error("Test failed. Bad base64 string failed returned nil error")
}
}
func TestBase64Encode(t *testing.T) {
t.Parallel()
originalInput := []byte("hello")
expectedOutput := "aGVsbG8="
actualResult := Base64Encode(originalInput)
if actualResult != expectedOutput {
t.Errorf("Test failed. Expected '%s'. Actual '%s'",
expectedOutput, actualResult)
}
}
func TestGetRandomSalt(t *testing.T) {
t.Parallel()
_, err := GetRandomSalt(nil, -1)
if err == nil {
t.Fatal("Test failed. Expected err on negative salt length")
}
salt, err := GetRandomSalt(nil, 10)
if err != nil {
t.Fatal(err)
}
if len(salt) != 10 {
t.Fatal("Test failed. Expected salt of len=10")
}
salt, err = GetRandomSalt([]byte("RAWR"), 12)
if err != nil {
t.Fatal(err)
}
if len(salt) != 16 {
t.Fatal("Test failed. Expected salt of len=16")
}
}
func TestGetMD5(t *testing.T) {
t.Parallel()
var originalString = []byte("I am testing the MD5 function in common!")
var expectedOutput = []byte("18fddf4a41ba90a7352765e62e7a8744")
actualOutput := GetMD5(originalString)
actualStr := HexEncodeToString(actualOutput)
if !bytes.Equal(expectedOutput, []byte(actualStr)) {
t.Errorf("Test failed. Expected '%s'. Actual '%s'",
expectedOutput, []byte(actualStr))
}
}
func TestGetSHA512(t *testing.T) {
t.Parallel()
var originalString = []byte("I am testing the GetSHA512 function in common!")
var expectedOutput = []byte(
`a2273f492ea73fddc4f25c267b34b3b74998bd8a6301149e1e1c835678e3c0b90859fce22e4e7af33bde1711cbb924809aedf5d759d648d61774b7185c5dc02b`,
)
actualOutput := GetSHA512(originalString)
actualStr := HexEncodeToString(actualOutput)
if !bytes.Equal(expectedOutput, []byte(actualStr)) {
t.Errorf("Test failed. Expected '%x'. Actual '%x'",
expectedOutput, []byte(actualStr))
}
}
func TestGetSHA256(t *testing.T) {
t.Parallel()
var originalString = []byte("I am testing the GetSHA256 function in common!")
var expectedOutput = []byte(
"0962813d7a9f739cdcb7f0c0be0c2a13bd630167e6e54468266e4af6b1ad9303",
)
actualOutput := GetSHA256(originalString)
actualStr := HexEncodeToString(actualOutput)
if !bytes.Equal(expectedOutput, []byte(actualStr)) {
t.Errorf("Test failed. Expected '%x'. Actual '%x'", expectedOutput,
[]byte(actualStr))
}
}
func TestGetHMAC(t *testing.T) {
t.Parallel()
expectedSha1 := []byte{
74, 253, 245, 154, 87, 168, 110, 182, 172, 101, 177, 49, 142, 2, 253, 165,
100, 66, 86, 246,
}
expectedsha256 := []byte{
54, 68, 6, 12, 32, 158, 80, 22, 142, 8, 131, 111, 248, 145, 17, 202, 224,
59, 135, 206, 11, 170, 154, 197, 183, 28, 150, 79, 168, 105, 62, 102,
}
expectedsha512 := []byte{
249, 212, 31, 38, 23, 3, 93, 220, 81, 209, 214, 112, 92, 75, 126, 40, 109,
95, 247, 182, 210, 54, 217, 224, 199, 252, 129, 226, 97, 201, 245, 220, 37,
201, 240, 15, 137, 236, 75, 6, 97, 12, 190, 31, 53, 153, 223, 17, 214, 11,
153, 203, 49, 29, 158, 217, 204, 93, 179, 109, 140, 216, 202, 71,
}
expectedsha512384 := []byte{
121, 203, 109, 105, 178, 68, 179, 57, 21, 217, 76, 82, 94, 100, 210, 1, 55,
201, 8, 232, 194, 168, 165, 58, 192, 26, 193, 167, 254, 183, 172, 4, 189,
158, 158, 150, 173, 33, 119, 125, 94, 13, 125, 89, 241, 184, 166, 128,
}
expectedmd5 := []byte{
113, 64, 132, 129, 213, 68, 231, 99, 252, 15, 175, 109, 198, 132, 139, 39,
}
sha1 := GetHMAC(HashSHA1, []byte("Hello,World"), []byte("1234"))
if string(sha1) != string(expectedSha1) {
t.Errorf("Test failed. Common GetHMAC error: Expected '%x'. Actual '%x'",
expectedSha1, sha1,
)
}
sha256 := GetHMAC(HashSHA256, []byte("Hello,World"), []byte("1234"))
if string(sha256) != string(expectedsha256) {
t.Errorf("Test failed. Common GetHMAC error: Expected '%x'. Actual '%x'",
expectedsha256, sha256,
)
}
sha512 := GetHMAC(HashSHA512, []byte("Hello,World"), []byte("1234"))
if string(sha512) != string(expectedsha512) {
t.Errorf("Test failed. Common GetHMAC error: Expected '%x'. Actual '%x'",
expectedsha512, sha512,
)
}
sha512384 := GetHMAC(HashSHA512_384, []byte("Hello,World"), []byte("1234"))
if string(sha512384) != string(expectedsha512384) {
t.Errorf("Test failed. Common GetHMAC error: Expected '%x'. Actual '%x'",
expectedsha512384, sha512384,
)
}
md5 := GetHMAC(HashMD5, []byte("Hello World"), []byte("1234"))
if string(md5) != string(expectedmd5) {
t.Errorf("Test failed. Common GetHMAC error: Expected '%x'. Actual '%x'",
expectedmd5, md5,
)
}
}
func TestSha1Tohex(t *testing.T) {
t.Parallel()
expectedResult := "fcfbfcd7d31d994ef660f6972399ab5d7a890149"
actualResult := Sha1ToHex("Testing Sha1ToHex")
if actualResult != expectedResult {
t.Errorf("Test failed. Expected '%s'. Actual '%s'",
expectedResult, actualResult)
}
}

51
common/math/math.go Normal file
View File

@@ -0,0 +1,51 @@
package math
import "math"
// CalculateAmountWithFee returns a calculated fee included amount on fee
func CalculateAmountWithFee(amount, fee float64) float64 {
return amount + CalculateFee(amount, fee)
}
// CalculateFee returns a simple fee on amount
func CalculateFee(amount, fee float64) float64 {
return amount * (fee / 100)
}
// CalculatePercentageGainOrLoss returns the percentage rise over a certain
// period
func CalculatePercentageGainOrLoss(priceNow, priceThen float64) float64 {
return (priceNow - priceThen) / priceThen * 100
}
// CalculatePercentageDifference returns the percentage of difference between
// multiple time periods
func CalculatePercentageDifference(amount, secondAmount float64) float64 {
return (amount - secondAmount) / ((amount + secondAmount) / 2) * 100
}
// CalculateNetProfit returns net profit
func CalculateNetProfit(amount, priceThen, priceNow, costs float64) float64 {
return (priceNow * amount) - (priceThen * amount) - costs
}
// RoundFloat rounds your floating point number to the desired decimal place
func RoundFloat(x float64, prec int) float64 {
var rounder float64
pow := math.Pow(10, float64(prec))
intermed := x * pow
_, frac := math.Modf(intermed)
intermed += .5
x = .5
if frac < 0.0 {
x = -.5
intermed--
}
if frac >= x {
rounder = math.Ceil(intermed)
} else {
rounder = math.Floor(intermed)
}
return rounder / pow
}

81
common/math/math_test.go Normal file
View File

@@ -0,0 +1,81 @@
package math
import "testing"
func TestCalculateFee(t *testing.T) {
t.Parallel()
originalInput := float64(1)
fee := float64(1)
expectedOutput := float64(0.01)
actualResult := CalculateFee(originalInput, fee)
if expectedOutput != actualResult {
t.Errorf(
"Test failed. Expected '%f'. Actual '%f'.", expectedOutput, actualResult)
}
}
func TestCalculateAmountWithFee(t *testing.T) {
t.Parallel()
originalInput := float64(1)
fee := float64(1)
expectedOutput := float64(1.01)
actualResult := CalculateAmountWithFee(originalInput, fee)
if expectedOutput != actualResult {
t.Errorf(
"Test failed. Expected '%f'. Actual '%f'.", expectedOutput, actualResult)
}
}
func TestCalculatePercentageGainOrLoss(t *testing.T) {
t.Parallel()
originalInput := float64(9300)
secondInput := float64(9000)
expectedOutput := 3.3333333333333335
actualResult := CalculatePercentageGainOrLoss(originalInput, secondInput)
if expectedOutput != actualResult {
t.Errorf(
"Test failed. Expected '%f'. Actual '%f'.", expectedOutput, actualResult)
}
}
func TestCalculatePercentageDifference(t *testing.T) {
t.Parallel()
originalInput := float64(10)
secondAmount := float64(5)
expectedOutput := 66.66666666666666
actualResult := CalculatePercentageDifference(originalInput, secondAmount)
if expectedOutput != actualResult {
t.Errorf(
"Test failed. Expected '%f'. Actual '%f'.", expectedOutput, actualResult)
}
}
func TestCalculateNetProfit(t *testing.T) {
t.Parallel()
amount := float64(5)
priceThen := float64(1)
priceNow := float64(10)
costs := float64(1)
expectedOutput := float64(44)
actualResult := CalculateNetProfit(amount, priceThen, priceNow, costs)
if expectedOutput != actualResult {
t.Errorf(
"Test failed. Expected '%f'. Actual '%f'.", expectedOutput, actualResult)
}
}
func TestRoundFloat(t *testing.T) {
t.Parallel()
// mapping of input vs expected result
testTable := map[float64]float64{
2.3232323: 2.32,
-2.3232323: -2.32,
}
for testInput, expectedOutput := range testTable {
actualOutput := RoundFloat(testInput, 2)
if actualOutput != expectedOutput {
t.Errorf("Test failed. RoundFloat Expected '%f'. Actual '%f'.",
expectedOutput, actualOutput)
}
}
}

View File

@@ -6,14 +6,15 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/exchanges/assets"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
)
// global vars contain staged update data that will be sent to the communication
// mediums
var (
TickerStaged map[string]map[string]map[string]ticker.Price
OrderbookStaged map[string]map[string]map[string]Orderbook
TickerStaged map[string]map[assets.AssetType]map[string]ticker.Price
OrderbookStaged map[string]map[assets.AssetType]map[string]Orderbook
PortfolioStaged Portfolio
SettingsStaged Settings
ServiceStarted time.Time

View File

@@ -4,6 +4,7 @@ import (
"time"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/exchanges/assets"
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
log "github.com/thrasher-/gocryptotrader/logger"
@@ -25,8 +26,8 @@ type ICommunicate interface {
// Setup sets up communication variables and intiates a connection to the
// communication mediums
func (c IComm) Setup() {
TickerStaged = make(map[string]map[string]map[string]ticker.Price)
OrderbookStaged = make(map[string]map[string]map[string]Orderbook)
TickerStaged = make(map[string]map[assets.AssetType]map[string]ticker.Price)
OrderbookStaged = make(map[string]map[assets.AssetType]map[string]Orderbook)
ServiceStarted = time.Now()
for i := range c {
@@ -68,12 +69,12 @@ func (c IComm) GetEnabledCommunicationMediums() {
}
// StageTickerData stages updated ticker data for the communications package
func (c IComm) StageTickerData(exchangeName, assetType string, tickerPrice *ticker.Price) {
func (c IComm) StageTickerData(exchangeName string, assetType assets.AssetType, tickerPrice *ticker.Price) {
m.Lock()
defer m.Unlock()
if _, ok := TickerStaged[exchangeName]; !ok {
TickerStaged[exchangeName] = make(map[string]map[string]ticker.Price)
TickerStaged[exchangeName] = make(map[assets.AssetType]map[string]ticker.Price)
}
if _, ok := TickerStaged[exchangeName][assetType]; !ok {
@@ -85,12 +86,12 @@ func (c IComm) StageTickerData(exchangeName, assetType string, tickerPrice *tick
// StageOrderbookData stages updated orderbook data for the communications
// package
func (c IComm) StageOrderbookData(exchangeName, assetType string, ob *orderbook.Base) {
func (c IComm) StageOrderbookData(exchangeName string, assetType assets.AssetType, ob *orderbook.Base) {
m.Lock()
defer m.Unlock()
if _, ok := OrderbookStaged[exchangeName]; !ok {
OrderbookStaged[exchangeName] = make(map[string]map[string]Orderbook)
OrderbookStaged[exchangeName] = make(map[assets.AssetType]map[string]Orderbook)
}
if _, ok := OrderbookStaged[exchangeName][assetType]; !ok {

Some files were not shown because too many files have changed in this diff Show More