From aeb327c80cb59821331b42fc6e41f7d483900a42 Mon Sep 17 00:00:00 2001 From: Adrian Gallagher Date: Tue, 21 Mar 2017 01:50:07 +1100 Subject: [PATCH] Package exchanges --- events.go | 3 +- exchanges/alphapoint/alphapoint_types.go | 159 +++++++ exchanges/alphapoint/alphapoint_wrapper.go | 20 + .../alphapoint/alphapointhttp.go | 163 +------- .../alphapoint/alphapointwebsocket.go | 20 +- exchanges/anx/anx_types.go | 54 +++ exchanges/anx/anx_wrapper.go | 67 +++ anxhttp.go => exchanges/anx/anxhttp.go | 119 +----- exchanges/bitfinex/bitfinex_types.go | 298 +++++++++++++ exchanges/bitfinex/bitfinex_wrapper.go | 108 +++++ .../bitfinex/bitfinexhttp.go | 329 +-------------- .../bitfinex/bitfinexwebsocket.go | 69 +--- exchanges/bitstamp/bitstamp_types.go | 109 +++++ exchanges/bitstamp/bitstamp_wrapper.go | 90 ++++ .../bitstamp/bitstamphttp.go | 191 +-------- .../bitstamp/bitstampwebsocket.go | 2 +- exchanges/btcc/btcc_types.go | 156 +++++++ exchanges/btcc/btcc_wrapper.go | 70 ++++ btcchttp.go => exchanges/btcc/btcchttp.go | 183 +------- .../btcc/btccwebsocket.go | 37 +- exchanges/btce/btce_types.go | 126 ++++++ exchanges/btce/btce_wrapper.go | 85 ++++ btcehttp.go => exchanges/btce/btcehttp.go | 202 +-------- .../btcmarkets/btcmarkets.go | 127 +----- exchanges/btcmarkets/btcmarkets_types.go | 56 +++ exchanges/btcmarkets/btcmarkets_wrapper.go | 79 ++++ exchanges/exchange.go | 27 ++ exchanges/gdax/gdax_types.go | 219 ++++++++++ exchanges/gdax/gdax_wrapper.go | 116 ++++++ gdaxhttp.go => exchanges/gdax/gdaxhttp.go | 265 +----------- .../gdax/gdaxwebsocket.go | 61 +-- exchanges/gemini/gemini_types.go | 94 +++++ exchanges/gemini/gemini_wrapper.go | 97 +++++ .../gemini/geminihttp.go | 184 +-------- exchanges/huobi/huobi_types.go | 15 + exchanges/huobi/huobi_wrapper.go | 80 ++++ huobihttp.go => exchanges/huobi/huobihttp.go | 84 +--- .../huobi/huobiwebsocket.go | 2 +- exchanges/itbit/itbit_types.go | 34 ++ exchanges/itbit/itbit_wrapper.go | 67 +++ itbithttp.go => exchanges/itbit/itbithttp.go | 95 +---- kraken.go => exchanges/kraken/kraken.go | 114 +---- exchanges/kraken/kraken_types.go | 44 ++ exchanges/kraken/kraken_wrapper.go | 82 ++++ exchanges/lakebtc/lakebtc_types.go | 100 +++++ exchanges/lakebtc/lakebtc_wrapper.go | 85 ++++ .../lakebtc/lakebtchttp.go | 178 +------- exchanges/liqui/liqui_types.go | 105 +++++ exchanges/liqui/liqui_wrapper.go | 109 +++++ liquihttp.go => exchanges/liqui/liquihttp.go | 202 +-------- .../localbitcoins/localbitcoins_types.go | 84 ++++ .../localbitcoins/localbitcoins_wrapper.go | 74 ++++ .../localbitcoins/localbitcoinshttp.go | 147 +------ exchanges/okcoin/okcoin_types.go | 391 ++++++++++++++++++ exchanges/okcoin/okcoin_wrapper.go | 102 +++++ .../okcoin/okcoinhttp.go | 312 +------------- .../okcoin/okcoinwebsocket.go | 175 +------- exchanges/poloniex/poloniex_types.go | 214 ++++++++++ exchanges/poloniex/poloniex_wrapper.go | 86 ++++ .../poloniex/poloniexhttp.go | 289 +------------ .../poloniex/poloniexwebsocket.go | 2 +- ticker.go => exchanges/ticker/ticker.go | 27 +- interfaces.go | 17 - main.go | 101 +++-- restfulRouter.go | 3 +- tickerRoutes.go | 7 +- wallet.go | 13 - walletRoutes.go | 4 +- 68 files changed, 3808 insertions(+), 3621 deletions(-) create mode 100644 exchanges/alphapoint/alphapoint_types.go create mode 100644 exchanges/alphapoint/alphapoint_wrapper.go rename alphapointhttp.go => exchanges/alphapoint/alphapointhttp.go (70%) rename alphapointwebsocket.go => exchanges/alphapoint/alphapointwebsocket.go (63%) create mode 100644 exchanges/anx/anx_types.go create mode 100644 exchanges/anx/anx_wrapper.go rename anxhttp.go => exchanges/anx/anxhttp.go (65%) create mode 100644 exchanges/bitfinex/bitfinex_types.go create mode 100644 exchanges/bitfinex/bitfinex_wrapper.go rename bitfinexhttp.go => exchanges/bitfinex/bitfinexhttp.go (62%) rename bitfinexwebsocket.go => exchanges/bitfinex/bitfinexwebsocket.go (88%) create mode 100644 exchanges/bitstamp/bitstamp_types.go create mode 100644 exchanges/bitstamp/bitstamp_wrapper.go rename bitstamphttp.go => exchanges/bitstamp/bitstamphttp.go (69%) rename bitstampwebsocket.go => exchanges/bitstamp/bitstampwebsocket.go (99%) create mode 100644 exchanges/btcc/btcc_types.go create mode 100644 exchanges/btcc/btcc_wrapper.go rename btcchttp.go => exchanges/btcc/btcchttp.go (73%) rename btccwebsocket.go => exchanges/btcc/btccwebsocket.go (74%) create mode 100644 exchanges/btce/btce_types.go create mode 100644 exchanges/btce/btce_wrapper.go rename btcehttp.go => exchanges/btce/btcehttp.go (59%) rename btcmarkets.go => exchanges/btcmarkets/btcmarkets.go (69%) create mode 100644 exchanges/btcmarkets/btcmarkets_types.go create mode 100644 exchanges/btcmarkets/btcmarkets_wrapper.go create mode 100644 exchanges/gdax/gdax_types.go create mode 100644 exchanges/gdax/gdax_wrapper.go rename gdaxhttp.go => exchanges/gdax/gdaxhttp.go (59%) rename gdaxwebsocket.go => exchanges/gdax/gdaxwebsocket.go (59%) create mode 100644 exchanges/gemini/gemini_types.go create mode 100644 exchanges/gemini/gemini_wrapper.go rename geminihttp.go => exchanges/gemini/geminihttp.go (57%) create mode 100644 exchanges/huobi/huobi_types.go create mode 100644 exchanges/huobi/huobi_wrapper.go rename huobihttp.go => exchanges/huobi/huobihttp.go (65%) rename huobiwebsocket.go => exchanges/huobi/huobiwebsocket.go (99%) create mode 100644 exchanges/itbit/itbit_types.go create mode 100644 exchanges/itbit/itbit_wrapper.go rename itbithttp.go => exchanges/itbit/itbithttp.go (70%) rename kraken.go => exchanges/kraken/kraken.go (78%) create mode 100644 exchanges/kraken/kraken_types.go create mode 100644 exchanges/kraken/kraken_wrapper.go create mode 100644 exchanges/lakebtc/lakebtc_types.go create mode 100644 exchanges/lakebtc/lakebtc_wrapper.go rename lakebtchttp.go => exchanges/lakebtc/lakebtchttp.go (63%) create mode 100644 exchanges/liqui/liqui_types.go create mode 100644 exchanges/liqui/liqui_wrapper.go rename liquihttp.go => exchanges/liqui/liquihttp.go (55%) create mode 100644 exchanges/localbitcoins/localbitcoins_types.go create mode 100644 exchanges/localbitcoins/localbitcoins_wrapper.go rename localbitcoinshttp.go => exchanges/localbitcoins/localbitcoinshttp.go (60%) create mode 100644 exchanges/okcoin/okcoin_types.go create mode 100644 exchanges/okcoin/okcoin_wrapper.go rename okcoinhttp.go => exchanges/okcoin/okcoinhttp.go (74%) rename okcoinwebsocket.go => exchanges/okcoin/okcoinwebsocket.go (75%) create mode 100644 exchanges/poloniex/poloniex_types.go create mode 100644 exchanges/poloniex/poloniex_wrapper.go rename poloniexhttp.go => exchanges/poloniex/poloniexhttp.go (66%) rename poloniexwebsocket.go => exchanges/poloniex/poloniexwebsocket.go (99%) rename ticker.go => exchanges/ticker/ticker.go (90%) delete mode 100644 interfaces.go diff --git a/events.go b/events.go index 99f2196f..4fb96593 100644 --- a/events.go +++ b/events.go @@ -7,6 +7,7 @@ import ( "strconv" "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" ) const ( @@ -116,7 +117,7 @@ func (e *Event) CheckCondition() bool { condition := common.SplitStrings(e.Condition, ",") targetPrice, _ := strconv.ParseFloat(condition[1], 64) - ticker, err := GetTickerByExchange(e.Exchange) + ticker, err := ticker.GetTickerByExchange(e.Exchange) if err != nil { return false } diff --git a/exchanges/alphapoint/alphapoint_types.go b/exchanges/alphapoint/alphapoint_types.go new file mode 100644 index 00000000..353b8ea4 --- /dev/null +++ b/exchanges/alphapoint/alphapoint_types.go @@ -0,0 +1,159 @@ +package alphapoint + +type AlphapointTrade struct { + TID int64 `json:"tid"` + Price float64 `json:"px"` + Quantity float64 `json:"qty"` + Unixtime int `json:"unixtime"` + UTCTicks int64 `json:"utcticks"` + IncomingOrderSide int `json:"incomingOrderSide"` + IncomingServerOrderID int `json:"incomingServerOrderId"` + BookServerOrderID int `json:"bookServerOrderId"` +} + +type AlphapointTrades struct { + IsAccepted bool `json:"isAccepted"` + RejectReason string `json:"rejectReason"` + DateTimeUTC int64 `json:"dateTimeUtc"` + Instrument string `json:"ins"` + StartIndex int `json:"startIndex"` + Count int `json:"count"` + Trades []AlphapointTrade `json:"trades"` +} + +type AlphapointTradesByDate struct { + IsAccepted bool `json:"isAccepted"` + RejectReason string `json:"rejectReason"` + DateTimeUTC int64 `json:"dateTimeUtc"` + Instrument string `json:"ins"` + StartDate int64 `json:"startDate"` + EndDate int64 `json:"endDate"` + Trades []AlphapointTrade `json:"trades"` +} + +type AlphapointTicker struct { + High float64 `json:"high"` + Last float64 `json:"last"` + Bid float64 `json:"bid"` + Volume float64 `json:"volume"` + Low float64 `json:"low"` + Ask float64 `json:"ask"` + Total24HrQtyTraded float64 `json:"Total24HrQtyTraded"` + Total24HrNumTrades float64 `json:"Total24HrNumTrades"` + SellOrderCount float64 `json:"sellOrderCount"` + BuyOrderCount float64 `json:"buyOrderCount"` + NumOfCreateOrders float64 `json:"numOfCreateOrders"` + IsAccepted bool `json:"isAccepted"` + RejectReason string `json:"rejectReason"` +} + +type AlphapointOrderbookEntry struct { + Quantity float64 `json:"qty"` + Price float64 `json:"px"` +} + +type AlphapointOrderbook struct { + Bids []AlphapointOrderbookEntry `json:"bids"` + Asks []AlphapointOrderbookEntry `json:"asks"` + IsAccepted bool `json:"isAccepted"` + RejectReason string `json:"rejectReason"` +} + +type AlphapointProductPair struct { + Name string `json:"name"` + Productpaircode int `json:"productPairCode"` + Product1Label string `json:"product1Label"` + Product1Decimalplaces int `json:"product1DecimalPlaces"` + Product2Label string `json:"product2Label"` + Product2Decimalplaces int `json:"product2DecimalPlaces"` +} + +type AlphapointProductPairs struct { + ProductPairs []AlphapointProductPair `json:"productPairs"` + IsAccepted bool `json:"isAccepted"` + RejectReason string `json:"rejectReason"` +} + +type AlphapointProduct struct { + Name string `json:"name"` + IsDigital bool `json:"isDigital"` + ProductCode int `json:"productCode"` + DecimalPlaces int `json:"decimalPlaces"` + FullName string `json:"fullName"` +} + +type AlphapointProducts struct { + Products []AlphapointProduct `json:"products"` + IsAccepted bool `json:"isAccepted"` + RejectReason string `json:"rejectReason"` +} + +type AlphapointUserInfo struct { + UserInfoKVP []struct { + Key string `json:"key"` + Value string `json:"value"` + } `json:"userInfoKVP"` + IsAccepted bool `json:"isAccepted"` + RejectReason string `json:"rejectReason"` +} + +type AlphapointAccountInfo struct { + Currencies []struct { + Name string `json:"name"` + Balance int `json:"balance"` + Hold int `json:"hold"` + } `json:"currencies"` + ProductPairs []struct { + ProductPairName string `json:"productPairName"` + ProductPairCode int `json:"productPairCode"` + TradeCount int `json:"tradeCount"` + TradeVolume int `json:"tradeVolume"` + } `json:"productPairs"` + IsAccepted bool `json:"isAccepted"` + RejectReason string `json:"rejectReason"` +} + +type AlphapointOrder struct { + Serverorderid int `json:"ServerOrderId"` + AccountID int `json:"AccountId"` + Price int `json:"Price"` + QtyTotal int `json:"QtyTotal"` + QtyRemaining int `json:"QtyRemaining"` + ReceiveTime int64 `json:"ReceiveTime"` + Side int `json:"Side"` +} + +type AlphapointOpenOrders struct { + Instrument string `json:"ins"` + Openorders []AlphapointOrder `json:"openOrders"` +} + +type AlphapointOrderInfo struct { + OpenOrders []AlphapointOpenOrders `json:"openOrdersInfo"` + IsAccepted bool `json:"isAccepted"` + DateTimeUTC int64 `json:"dateTimeUtc"` + RejectReason string `json:"rejectReason"` +} + +type AlphapointDepositAddresses struct { + Name string `json:"name"` + DepositAddress string `json:"depositAddress"` +} + +type AlphapointWebsocketTicker struct { + MessageType string `json:"messageType"` + ProductPair string `json:"prodPair"` + High float64 `json:"high"` + Low float64 `json:"low"` + Last float64 `json:"last"` + Volume float64 `json:"volume"` + Volume24Hrs float64 `json:"volume24hrs"` + Volume24HrsProduct2 float64 `json:"volume24hrsProduct2"` + Total24HrQtyTraded float64 `json:"Total24HrQtyTraded"` + Total24HrProduct2Traded float64 `json:"Total24HrProduct2Traded"` + Total24HrNumTrades float64 `json:"Total24HrNumTrades"` + Bid float64 `json:"bid"` + Ask float64 `json:"ask"` + BuyOrderCount int `json:"buyOrderCount"` + SellOrderCount int `json:"sellOrderCount"` +} diff --git a/exchanges/alphapoint/alphapoint_wrapper.go b/exchanges/alphapoint/alphapoint_wrapper.go new file mode 100644 index 00000000..6ac6e1e3 --- /dev/null +++ b/exchanges/alphapoint/alphapoint_wrapper.go @@ -0,0 +1,20 @@ +package alphapoint + +import ( + "log" + + "github.com/thraser-/gocryptotrader/exchanges/ticker" +) + +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 +} diff --git a/alphapointhttp.go b/exchanges/alphapoint/alphapointhttp.go similarity index 70% rename from alphapointhttp.go rename to exchanges/alphapoint/alphapointhttp.go index 0eaaeae6..c691ab3f 100644 --- a/alphapointhttp.go +++ b/exchanges/alphapoint/alphapointhttp.go @@ -1,4 +1,4 @@ -package main +package alphapoint import ( "bytes" @@ -36,153 +36,7 @@ const ( ) type Alphapoint struct { - WebsocketConn *websocket.Conn - WebsocketURL string - ExchangeName string - ExchangeEnabled bool - WebsocketEnabled bool - Verbose bool - APIUrl, APIKey, UserID, APISecret string -} - -type AlphapointTrade struct { - TID int64 `json:"tid"` - Price float64 `json:"px"` - Quantity float64 `json:"qty"` - Unixtime int `json:"unixtime"` - UTCTicks int64 `json:"utcticks"` - IncomingOrderSide int `json:"incomingOrderSide"` - IncomingServerOrderID int `json:"incomingServerOrderId"` - BookServerOrderID int `json:"bookServerOrderId"` -} - -type AlphapointTrades struct { - IsAccepted bool `json:"isAccepted"` - RejectReason string `json:"rejectReason"` - DateTimeUTC int64 `json:"dateTimeUtc"` - Instrument string `json:"ins"` - StartIndex int `json:"startIndex"` - Count int `json:"count"` - Trades []AlphapointTrade `json:"trades"` -} - -type AlphapointTradesByDate struct { - IsAccepted bool `json:"isAccepted"` - RejectReason string `json:"rejectReason"` - DateTimeUTC int64 `json:"dateTimeUtc"` - Instrument string `json:"ins"` - StartDate int64 `json:"startDate"` - EndDate int64 `json:"endDate"` - Trades []AlphapointTrade `json:"trades"` -} - -type AlphapointTicker struct { - High float64 `json:"high"` - Last float64 `json:"last"` - Bid float64 `json:"bid"` - Volume float64 `json:"volume"` - Low float64 `json:"low"` - Ask float64 `json:"ask"` - Total24HrQtyTraded float64 `json:"Total24HrQtyTraded"` - Total24HrNumTrades float64 `json:"Total24HrNumTrades"` - SellOrderCount float64 `json:"sellOrderCount"` - BuyOrderCount float64 `json:"buyOrderCount"` - NumOfCreateOrders float64 `json:"numOfCreateOrders"` - IsAccepted bool `json:"isAccepted"` - RejectReason string `json:"rejectReason"` -} - -type AlphapointOrderbookEntry struct { - Quantity float64 `json:"qty"` - Price float64 `json:"px"` -} - -type AlphapointOrderbook struct { - Bids []AlphapointOrderbookEntry `json:"bids"` - Asks []AlphapointOrderbookEntry `json:"asks"` - IsAccepted bool `json:"isAccepted"` - RejectReason string `json:"rejectReason"` -} - -type AlphapointProductPair struct { - Name string `json:"name"` - Productpaircode int `json:"productPairCode"` - Product1Label string `json:"product1Label"` - Product1Decimalplaces int `json:"product1DecimalPlaces"` - Product2Label string `json:"product2Label"` - Product2Decimalplaces int `json:"product2DecimalPlaces"` -} - -type AlphapointProductPairs struct { - ProductPairs []AlphapointProductPair `json:"productPairs"` - IsAccepted bool `json:"isAccepted"` - RejectReason string `json:"rejectReason"` -} - -type AlphapointProduct struct { - Name string `json:"name"` - IsDigital bool `json:"isDigital"` - ProductCode int `json:"productCode"` - DecimalPlaces int `json:"decimalPlaces"` - FullName string `json:"fullName"` -} - -type AlphapointProducts struct { - Products []AlphapointProduct `json:"products"` - IsAccepted bool `json:"isAccepted"` - RejectReason string `json:"rejectReason"` -} - -type AlphapointUserInfo struct { - UserInfoKVP []struct { - Key string `json:"key"` - Value string `json:"value"` - } `json:"userInfoKVP"` - IsAccepted bool `json:"isAccepted"` - RejectReason string `json:"rejectReason"` -} - -type AlphapointAccountInfo struct { - Currencies []struct { - Name string `json:"name"` - Balance int `json:"balance"` - Hold int `json:"hold"` - } `json:"currencies"` - ProductPairs []struct { - ProductPairName string `json:"productPairName"` - ProductPairCode int `json:"productPairCode"` - TradeCount int `json:"tradeCount"` - TradeVolume int `json:"tradeVolume"` - } `json:"productPairs"` - IsAccepted bool `json:"isAccepted"` - RejectReason string `json:"rejectReason"` -} - -type AlphapointOrder struct { - Serverorderid int `json:"ServerOrderId"` - AccountID int `json:"AccountId"` - Price int `json:"Price"` - QtyTotal int `json:"QtyTotal"` - QtyRemaining int `json:"QtyRemaining"` - ReceiveTime int64 `json:"ReceiveTime"` - Side int `json:"Side"` -} - -type AlphapointOpenOrders struct { - Instrument string `json:"ins"` - Openorders []AlphapointOrder `json:"openOrders"` -} - -type AlphapointOrderInfo struct { - OpenOrders []AlphapointOpenOrders `json:"openOrdersInfo"` - IsAccepted bool `json:"isAccepted"` - DateTimeUTC int64 `json:"dateTimeUtc"` - RejectReason string `json:"rejectReason"` -} - -type AlphapointDepositAddresses struct { - Name string `json:"name"` - DepositAddress string `json:"depositAddress"` + WebsocketConn *websocket.Conn } func (a *Alphapoint) SetDefaults() { @@ -205,19 +59,6 @@ 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/alphapointwebsocket.go b/exchanges/alphapoint/alphapointwebsocket.go similarity index 63% rename from alphapointwebsocket.go rename to exchanges/alphapoint/alphapointwebsocket.go index ba6dc4e4..38bd851c 100644 --- a/alphapointwebsocket.go +++ b/exchanges/alphapoint/alphapointwebsocket.go @@ -1,4 +1,4 @@ -package main +package alphapoint import ( "log" @@ -12,24 +12,6 @@ const ( ALPHAPOINT_DEFAULT_WEBSOCKET_URL = "wss://sim3.alphapoint.com:8401/v1/GetTicker/" ) -type AlphapointWebsocketTicker struct { - MessageType string `json:"messageType"` - ProductPair string `json:"prodPair"` - High float64 `json:"high"` - Low float64 `json:"low"` - Last float64 `json:"last"` - Volume float64 `json:"volume"` - Volume24Hrs float64 `json:"volume24hrs"` - Volume24HrsProduct2 float64 `json:"volume24hrsProduct2"` - Total24HrQtyTraded float64 `json:"Total24HrQtyTraded"` - Total24HrProduct2Traded float64 `json:"Total24HrProduct2Traded"` - Total24HrNumTrades float64 `json:"Total24HrNumTrades"` - Bid float64 `json:"bid"` - Ask float64 `json:"ask"` - BuyOrderCount int `json:"buyOrderCount"` - SellOrderCount int `json:"sellOrderCount"` -} - func (a *Alphapoint) WebsocketClient() { for a.ExchangeEnabled && a.WebsocketEnabled { var Dialer websocket.Dialer diff --git a/exchanges/anx/anx_types.go b/exchanges/anx/anx_types.go new file mode 100644 index 00000000..49b6956f --- /dev/null +++ b/exchanges/anx/anx_types.go @@ -0,0 +1,54 @@ +package anx + +type ANXOrder struct { + OrderType string `json:"orderType"` + BuyTradedCurrency bool `json:"buyTradedCurrency"` + TradedCurrency string `json:"tradedCurrency"` + SettlementCurrency string `json:"settlementCurrency"` + TradedCurrencyAmount string `json:"tradedCurrencyAmount"` + SettlementCurrencyAmount string `json:"settlementCurrencyAmount"` + LimitPriceInSettlementCurrency string `json:"limitPriceInSettlementCurrency"` + ReplaceExistingOrderUUID string `json:"replaceExistingOrderUuid"` + ReplaceOnlyIfActive bool `json:"replaceOnlyIfActive"` +} + +type ANXOrderResponse struct { + BuyTradedCurrency bool `json:"buyTradedCurrency"` + ExecutedAverageRate string `json:"executedAverageRate"` + LimitPriceInSettlementCurrency string `json:"limitPriceInSettlementCurrency"` + OrderID string `json:"orderId"` + OrderStatus string `json:"orderStatus"` + OrderType string `json:"orderType"` + ReplaceExistingOrderUUID string `json:"replaceExistingOrderId"` + SettlementCurrency string `json:"settlementCurrency"` + SettlementCurrencyAmount string `json:"settlementCurrencyAmount"` + SettlementCurrencyOutstanding string `json:"settlementCurrencyOutstanding"` + Timestamp int64 `json:"timestamp"` + TradedCurrency string `json:"tradedCurrency"` + TradedCurrencyAmount string `json:"tradedCurrencyAmount"` + TradedCurrencyOutstanding string `json:"tradedCurrencyOutstanding"` +} + +type ANXTickerComponent struct { + Currency string `json:"currency"` + Display string `json:"display"` + DisplayShort string `json:"display_short"` + Value float64 `json:"value,string"` + ValueInt int64 `json:"value_int,string"` +} + +type ANXTicker struct { + Result string `json:"result"` + Data struct { + High ANXTickerComponent `json:"high"` + Low ANXTickerComponent `json:"low"` + Avg ANXTickerComponent `json:"avg"` + Vwap ANXTickerComponent `json:"vwap"` + Vol ANXTickerComponent `json:"vol"` + Last ANXTickerComponent `json:"last"` + Buy ANXTickerComponent `json:"buy"` + Sell ANXTickerComponent `json:"sell"` + Now string `json:"now"` + UpdateTime string `json:"dataUpdateTime"` + } `json:"data"` +} diff --git a/exchanges/anx/anx_wrapper.go b/exchanges/anx/anx_wrapper.go new file mode 100644 index 00000000..13f597f1 --- /dev/null +++ b/exchanges/anx/anx_wrapper.go @@ -0,0 +1,67 @@ +package anx + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (a *ANX) Start() { + go a.Run() +} + +func (a *ANX) Run() { + if a.Verbose { + log.Printf("%s polling delay: %ds.\n", a.GetName(), a.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", a.GetName(), len(a.EnabledPairs), a.EnabledPairs) + } + + for a.Enabled { + for _, x := range a.EnabledPairs { + currency := x + go func() { + ticker, err := a.GetTickerPrice(currency) + if err != nil { + log.Println(err) + return + } + log.Printf("ANX %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) + //AddExchangeInfo(a.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) + }() + } + time.Sleep(time.Second * a.RESTPollingDelay) + } +} + +func (a *ANX) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(a.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tickerNew, nil + } + + var tickerPrice ticker.TickerPrice + tick, err := a.GetTicker(currency) + if err != nil { + return tickerPrice, err + } + + tickerPrice.Ask = tick.Data.Buy.Value + tickerPrice.Bid = tick.Data.Sell.Value + tickerPrice.FirstCurrency = currency[0:3] + tickerPrice.SecondCurrency = currency[3:] + tickerPrice.Low = tick.Data.Low.Value + tickerPrice.Last = tick.Data.Last.Value + tickerPrice.Volume = tick.Data.Vol.Value + tickerPrice.High = tick.Data.High.Value + ticker.ProcessTicker(a.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the ANX exchange +func (e *ANX) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + return response, nil +} diff --git a/anxhttp.go b/exchanges/anx/anxhttp.go similarity index 65% rename from anxhttp.go rename to exchanges/anx/anxhttp.go index 6706c283..4b355f9c 100644 --- a/anxhttp.go +++ b/exchanges/anx/anxhttp.go @@ -1,4 +1,4 @@ -package main +package anx import ( "bytes" @@ -31,59 +31,6 @@ type ANX struct { exchange.ExchangeBase } -type ANXOrder struct { - OrderType string `json:"orderType"` - BuyTradedCurrency bool `json:"buyTradedCurrency"` - TradedCurrency string `json:"tradedCurrency"` - SettlementCurrency string `json:"settlementCurrency"` - TradedCurrencyAmount string `json:"tradedCurrencyAmount"` - SettlementCurrencyAmount string `json:"settlementCurrencyAmount"` - LimitPriceInSettlementCurrency string `json:"limitPriceInSettlementCurrency"` - ReplaceExistingOrderUUID string `json:"replaceExistingOrderUuid"` - ReplaceOnlyIfActive bool `json:"replaceOnlyIfActive"` -} - -type ANXOrderResponse struct { - BuyTradedCurrency bool `json:"buyTradedCurrency"` - ExecutedAverageRate string `json:"executedAverageRate"` - LimitPriceInSettlementCurrency string `json:"limitPriceInSettlementCurrency"` - OrderID string `json:"orderId"` - OrderStatus string `json:"orderStatus"` - OrderType string `json:"orderType"` - ReplaceExistingOrderUUID string `json:"replaceExistingOrderId"` - SettlementCurrency string `json:"settlementCurrency"` - SettlementCurrencyAmount string `json:"settlementCurrencyAmount"` - SettlementCurrencyOutstanding string `json:"settlementCurrencyOutstanding"` - Timestamp int64 `json:"timestamp"` - TradedCurrency string `json:"tradedCurrency"` - TradedCurrencyAmount string `json:"tradedCurrencyAmount"` - TradedCurrencyOutstanding string `json:"tradedCurrencyOutstanding"` -} - -type ANXTickerComponent struct { - Currency string `json:"currency"` - Display string `json:"display"` - DisplayShort string `json:"display_short"` - Value float64 `json:"value,string"` - ValueInt int64 `json:"value_int,string"` -} - -type ANXTicker struct { - Result string `json:"result"` - Data struct { - High ANXTickerComponent `json:"high"` - Low ANXTickerComponent `json:"low"` - Avg ANXTickerComponent `json:"avg"` - Vwap ANXTickerComponent `json:"vwap"` - Vol ANXTickerComponent `json:"vol"` - Last ANXTickerComponent `json:"last"` - Buy ANXTickerComponent `json:"buy"` - Sell ANXTickerComponent `json:"sell"` - Now string `json:"now"` - UpdateTime string `json:"dataUpdateTime"` - } `json:"data"` -} - func (a *ANX) SetDefaults() { a.Name = "ANX" a.Enabled = false @@ -111,11 +58,6 @@ func (a *ANX) Setup(exch config.ExchangeConfig) { } } -//Start is run if exchange is enabled, after Setup -func (a *ANX) Start() { - go a.Run() -} - func (a *ANX) GetFee(maker bool) float64 { if maker { return a.MakerFee @@ -124,29 +66,6 @@ func (a *ANX) GetFee(maker bool) float64 { } } -func (a *ANX) Run() { - if a.Verbose { - log.Printf("%s polling delay: %ds.\n", a.GetName(), a.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", a.GetName(), len(a.EnabledPairs), a.EnabledPairs) - } - - for a.Enabled { - for _, x := range a.EnabledPairs { - currency := x - go func() { - ticker, err := a.GetTickerPrice(currency) - if err != nil { - log.Println(err) - return - } - log.Printf("ANX %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) - AddExchangeInfo(a.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) - }() - } - time.Sleep(time.Second * a.RESTPollingDelay) - } -} - func (a *ANX) GetTicker(currency string) (ANXTicker, error) { var ticker ANXTicker err := common.SendHTTPGetRequest(fmt.Sprintf("%sapi/2/%s/%s", ANX_API_URL, currency, ANX_TICKER), true, &ticker) @@ -156,35 +75,6 @@ func (a *ANX) GetTicker(currency string) (ANXTicker, error) { return ticker, nil } -func (a *ANX) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(a.GetName(), currency[0:3], currency[3:]) - if err == nil { - return tickerNew, nil - } - - var tickerPrice TickerPrice - ticker, err := a.GetTicker(currency) - if err != nil { - return tickerPrice, err - } - - tickerPrice.Ask = ticker.Data.Buy.Value - tickerPrice.Bid = ticker.Data.Sell.Value - tickerPrice.FirstCurrency = currency[0:3] - tickerPrice.SecondCurrency = currency[3:] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Low = ticker.Data.Low.Value - tickerPrice.Last = ticker.Data.Last.Value - tickerPrice.Volume = ticker.Data.Vol.Value - tickerPrice.High = ticker.Data.High.Value - ProcessTicker(a.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - -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] @@ -405,13 +295,6 @@ func (a *ANX) GetDepositAddress(currency, name string, new bool) (string, error) return response.Address, nil } -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the ANX exchange -func (e *ANX) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - return response, nil -} - func (a *ANX) SendAuthenticatedHTTPRequest(path string, params map[string]interface{}, result interface{}) (err error) { request := make(map[string]interface{}) request["nonce"] = strconv.FormatInt(time.Now().UnixNano(), 10)[0:13] diff --git a/exchanges/bitfinex/bitfinex_types.go b/exchanges/bitfinex/bitfinex_types.go new file mode 100644 index 00000000..4dbb53be --- /dev/null +++ b/exchanges/bitfinex/bitfinex_types.go @@ -0,0 +1,298 @@ +package bitfinex + +type BitfinexStats struct { + Period int64 + Volume float64 `json:",string"` +} + +type BitfinexTicker struct { + Mid float64 `json:",string"` + Bid float64 `json:",string"` + Ask float64 `json:",string"` + Last float64 `json:"Last_price,string"` + Low float64 `json:",string"` + High float64 `json:",string"` + Volume float64 `json:",string"` + Timestamp string +} + +type BitfinexMarginLimits struct { + On_Pair string + InitialMargin float64 `json:"initial_margin,string"` + MarginRequirement float64 `json:"margin_requirement,string"` + TradableBalance float64 `json:"tradable_balance,string"` +} + +type BitfinexMarginInfo struct { + MarginBalance float64 `json:"margin_balance,string"` + TradableBalance float64 `json:"tradable_balance,string"` + UnrealizedPL int64 `json:"unrealized_pl"` + UnrealizedSwap int64 `json:"unrealized_swap"` + NetValue float64 `json:"net_value,string"` + RequiredMargin int64 `json:"required_margin"` + Leverage float64 `json:"leverage,string"` + MarginRequirement float64 `json:"margin_requirement,string"` + MarginLimits []BitfinexMarginLimits `json:"margin_limits"` + Message string +} + +type BitfinexOrder struct { + ID int64 + Symbol string + Exchange string + Price float64 `json:"price,string"` + AverageExecutionPrice float64 `json:"avg_execution_price,string"` + Side string + Type string + Timestamp string + IsLive bool `json:"is_live"` + IsCancelled bool `json:"is_cancelled"` + IsHidden bool `json:"is_hidden"` + WasForced bool `json:"was_forced"` + OriginalAmount float64 `json:"original_amount,string"` + RemainingAmount float64 `json:"remaining_amount,string"` + ExecutedAmount float64 `json:"executed_amount,string"` + OrderID int64 `json:"order_id"` +} + +type BitfinexPlaceOrder struct { + Symbol string `json:"symbol"` + Amount float64 `json:"amount,string"` + Price float64 `json:"price,string"` + Exchange string `json:"exchange"` + Side string `json:"side"` + Type string `json:"type"` +} + +type BitfinexBalance struct { + Type string + Currency string + Amount float64 `json:"amount,string"` + Available float64 `json:"available,string"` +} + +type BitfinexOffer struct { + ID int64 + Currency string + Rate float64 `json:"rate,string"` + Period int64 + Direction string + Timestamp string + Type string + IsLive bool `json:"is_live"` + IsCancelled bool `json:"is_cancelled"` + OriginalAmount float64 `json:"original_amount,string"` + RemainingAmount float64 `json:"remaining_amount,string"` + ExecutedAmount float64 `json:"remaining_amount,string"` +} + +type BitfinexBookStructure struct { + Price, Amount, Timestamp string +} + +type BitfinexFee struct { + Currency string + TakerFees float64 + MakerFees float64 +} + +type BitfinexOrderbook struct { + Bids []BitfinexBookStructure + Asks []BitfinexBookStructure +} + +type BitfinexTradeStructure struct { + Timestamp, Tid int64 + Price, Amount, Exchange, Type string +} + +type BitfinexSymbolDetails struct { + Pair string `json:"pair"` + PricePrecision int `json:"price_precision"` + InitialMargin float64 `json:"initial_margin,string"` + MinimumMargin float64 `json:"minimum_margin,string"` + MaximumOrderSize float64 `json:"maximum_order_size,string"` + MinimumOrderSize float64 `json:"minimum_order_size,string"` + Expiration string `json:"expiration"` +} + +type BitfinexLends struct { + Rate float64 `json:"rate,string"` + AmountLent float64 `json:"amount_lent,string"` + AmountUsed float64 `json:"amount_used,string"` + Timestamp int64 `json:"timestamp"` +} + +type BitfinexAccountInfo struct { + MakerFees string `json:"maker_fees"` + TakerFees string `json:"taker_fees"` + Fees []struct { + Pairs string `json:"pairs"` + MakerFees string `json:"maker_fees"` + TakerFees string `json:"taker_fees"` + } `json:"fees"` +} + +type BitfinexDepositResponse struct { + Result string `json:"string"` + Method string `json:"method"` + Currency string `json:"currency"` + Address string `json:"address"` +} + +type BitfinexOrderMultiResponse struct { + Orders []BitfinexOrder `json:"order_ids"` + Status string `json:"status"` +} + +type BitfinexLendbookBidAsk struct { + Rate float64 `json:"rate,string"` + Amount float64 `json:"amount,string"` + Period int `json:"period"` + Timestamp string `json:"timestamp"` + FlashReturnRate string `json:"frr"` +} + +type BitfinexLendbook struct { + Bids []BitfinexLendbookBidAsk `json:"bids"` + Asks []BitfinexLendbookBidAsk `json:"asks"` +} + +type BitfinexPosition struct { + ID int64 `json:"id"` + Symbol string `json:"string"` + Status string `json:"active"` + Base float64 `json:"base,string"` + Amount float64 `json:"amount,string"` + Timestamp string `json:"timestamp"` + Swap float64 `json:"swap,string"` + PL float64 `json:"pl,string"` +} + +type BitfinexBalanceHistory struct { + Currency string `json:"currency"` + Amount float64 `json:"amount,string"` + Balance float64 `json:"balance,string"` + Description string `json:"description"` + Timestamp string `json:"timestamp"` +} + +type BitfinexMovementHistory struct { + ID int64 `json:"id"` + Currency string `json:"currency"` + Method string `json:"method"` + Type string `json:"withdrawal"` + Amount float64 `json:"amount,string"` + Description string `json:"description"` + Status string `json:"status"` + Timestamp string `json:"timestamp"` +} + +type BitfinexTradeHistory struct { + Price float64 `json:"price,string"` + Amount float64 `json:"amount,string"` + Timestamp string `json:"timestamp"` + Exchange string `json:"exchange"` + Type string `json:"type"` + FeeCurrency string `json:"fee_currency"` + FeeAmount float64 `json:"fee_amount,string"` + TID int64 `json:"tid"` + OrderID int64 `json:"order_id"` +} + +type BitfinexMarginFunds struct { + ID int64 `json:"id"` + PositionID int64 `json:"position_id"` + Currency string `json:"currency"` + Rate float64 `json:"rate,string"` + Period int `json:"period"` + Amount float64 `json:"amount,string"` + Timestamp string `json:"timestamp"` +} + +type BitfinexMarginTotalTakenFunds struct { + PositionPair string `json:"position_pair"` + TotalSwaps float64 `json:"total_swaps,string"` +} + +type BitfinexWalletTransfer struct { + Status string `json:"status"` + Message string `json:"message"` +} + +type BitfinexWithdrawal struct { + Status string `json:"status"` + Message string `json:"message"` + WithdrawalID int64 `json:"withdrawal_id"` +} + +type BitfinexGenericResponse struct { + Result string `json:"result"` +} + +type BitfinexWebsocketChanInfo struct { + Channel string + Pair string +} + +type BitfinexWebsocketBook struct { + Price float64 + Count int + Amount float64 +} + +type BitfinexWebsocketTrade struct { + ID int64 + Timestamp int64 + Price float64 + Amount float64 +} + +type BitfinexWebsocketTicker struct { + Bid float64 + BidSize float64 + Ask float64 + AskSize float64 + DailyChange float64 + DialyChangePerc float64 + LastPrice float64 + Volume float64 +} + +type BitfinexWebsocketPosition struct { + Pair string + Status string + Amount float64 + Price float64 + MarginFunding float64 + MarginFundingType int +} + +type BitfinexWebsocketWallet struct { + Name string + Currency string + Balance float64 + UnsettledInterest float64 +} + +type BitfinexWebsocketOrder struct { + OrderID int64 + Pair string + Amount float64 + OrigAmount float64 + OrderType string + Status string + Price float64 + PriceAvg float64 + Timestamp string + Notify int +} + +type BitfinexWebsocketTradeExecuted struct { + TradeID int64 + Pair string + Timestamp int64 + OrderID int64 + AmountExecuted float64 + PriceExecuted float64 +} diff --git a/exchanges/bitfinex/bitfinex_wrapper.go b/exchanges/bitfinex/bitfinex_wrapper.go new file mode 100644 index 00000000..1552347e --- /dev/null +++ b/exchanges/bitfinex/bitfinex_wrapper.go @@ -0,0 +1,108 @@ +package bitfinex + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (b *Bitfinex) Start() { + go b.Run() +} + +func (b *Bitfinex) Run() { + if b.Verbose { + log.Printf("%s Websocket: %s.", b.GetName(), common.IsEnabled(b.Websocket)) + log.Printf("%s polling delay: %ds.\n", b.GetName(), b.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) + } + + if b.Websocket { + go b.WebsocketClient() + } + + exchangeProducts, err := b.GetSymbols() + if err != nil { + log.Printf("%s Failed to get available symbols.\n", b.GetName()) + } else { + log.Println(exchangeProducts) + /* + exchangeProducts = common.SplitStrings(common.StringToUpper(common.JoinStrings(exchangeProducts, ",")), ",") + diff := common.StringSliceDifference(b.AvailablePairs, exchangeProducts) + if len(diff) > 0 { + exch, err := bot.config.GetExchangeConfig(b.Name) + if err != nil { + log.Println(err) + } else { + log.Printf("%s Updating available pairs. Difference: %s.\n", b.Name, diff) + exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",") + bot.config.UpdateExchangeConfig(exch) + } + } + */ + } + + for b.Enabled { + for _, x := range b.EnabledPairs { + currency := x + go func() { + ticker, err := b.GetTickerPrice(currency) + if err != nil { + return + } + log.Printf("Bitfinex %s Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) + //AddExchangeInfo(b.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) + }() + } + time.Sleep(time.Second * b.RESTPollingDelay) + } +} + +func (b *Bitfinex) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tick, err := ticker.GetTicker(b.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tick, nil + } + + var tickerPrice ticker.TickerPrice + tickerNew, err := b.GetTicker(currency, nil) + if err != nil { + return tickerPrice, err + } + tickerPrice.Ask = tickerNew.Ask + tickerPrice.Bid = tickerNew.Bid + tickerPrice.FirstCurrency = currency[0:3] + tickerPrice.SecondCurrency = currency[3:] + tickerPrice.Low = tickerNew.Low + tickerPrice.Last = tickerNew.Last + tickerPrice.Volume = tickerNew.Volume + tickerPrice.High = tickerNew.High + ticker.ProcessTicker(b.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Bitfinex exchange +func (e *Bitfinex) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + accountBalance, err := e.GetAccountBalance() + if err != nil { + return response, err + } + if !e.Enabled { + return response, nil + } + + for i := 0; i < len(accountBalance); i++ { + var exchangeCurrency exchange.ExchangeAccountCurrencyInfo + exchangeCurrency.CurrencyName = accountBalance[i].Currency + exchangeCurrency.TotalValue = accountBalance[i].Amount + exchangeCurrency.Hold = accountBalance[i].Available + + response.Currencies = append(response.Currencies, exchangeCurrency) + } + return response, nil +} diff --git a/bitfinexhttp.go b/exchanges/bitfinex/bitfinexhttp.go similarity index 62% rename from bitfinexhttp.go rename to exchanges/bitfinex/bitfinexhttp.go index bea065a2..05fb39c8 100644 --- a/bitfinexhttp.go +++ b/exchanges/bitfinex/bitfinexhttp.go @@ -1,4 +1,4 @@ -package main +package bitfinex import ( "errors" @@ -54,125 +54,8 @@ const ( BITFINEX_WITHDRAWAL = "withdrawal" ) -type BitfinexStats struct { - Period int64 - Volume float64 `json:",string"` -} - -type BitfinexTicker struct { - Mid float64 `json:",string"` - Bid float64 `json:",string"` - Ask float64 `json:",string"` - Last float64 `json:"Last_price,string"` - Low float64 `json:",string"` - High float64 `json:",string"` - Volume float64 `json:",string"` - Timestamp string -} - -type MarginLimits struct { - On_Pair string - InitialMargin float64 `json:"initial_margin,string"` - MarginRequirement float64 `json:"margin_requirement,string"` - TradableBalance float64 `json:"tradable_balance,string"` -} - -type BitfinexMarginInfo struct { - MarginBalance float64 `json:"margin_balance,string"` - TradableBalance float64 `json:"tradable_balance,string"` - UnrealizedPL int64 `json:"unrealized_pl"` - UnrealizedSwap int64 `json:"unrealized_swap"` - NetValue float64 `json:"net_value,string"` - RequiredMargin int64 `json:"required_margin"` - Leverage float64 `json:"leverage,string"` - MarginRequirement float64 `json:"margin_requirement,string"` - MarginLimits []MarginLimits `json:"margin_limits"` - Message string -} - -type BitfinexOrder struct { - ID int64 - Symbol string - Exchange string - Price float64 `json:"price,string"` - AverageExecutionPrice float64 `json:"avg_execution_price,string"` - Side string - Type string - Timestamp string - IsLive bool `json:"is_live"` - IsCancelled bool `json:"is_cancelled"` - IsHidden bool `json:"is_hidden"` - WasForced bool `json:"was_forced"` - OriginalAmount float64 `json:"original_amount,string"` - RemainingAmount float64 `json:"remaining_amount,string"` - ExecutedAmount float64 `json:"executed_amount,string"` - OrderID int64 `json:"order_id"` -} - -type BitfinexPlaceOrder struct { - Symbol string `json:"symbol"` - Amount float64 `json:"amount,string"` - Price float64 `json:"price,string"` - Exchange string `json:"exchange"` - Side string `json:"side"` - Type string `json:"type"` -} - -type BitfinexBalance struct { - Type string - Currency string - Amount float64 `json:"amount,string"` - Available float64 `json:"available,string"` -} - -type BitfinexOffer struct { - ID int64 - Currency string - Rate float64 `json:"rate,string"` - Period int64 - Direction string - Timestamp string - Type string - IsLive bool `json:"is_live"` - IsCancelled bool `json:"is_cancelled"` - OriginalAmount float64 `json:"original_amount,string"` - RemainingAmount float64 `json:"remaining_amount,string"` - ExecutedAmount float64 `json:"remaining_amount,string"` -} - -type BookStructure struct { - Price, Amount, Timestamp string -} - -type BitfinexFee struct { - Currency string - TakerFees float64 - MakerFees float64 -} - -type BitfinexOrderbook struct { - Bids []BookStructure - Asks []BookStructure -} - -type BitfinexTradeStructure struct { - Timestamp, Tid int64 - Price, Amount, Exchange, Type string -} - -type BitfinexSymbolDetails struct { - Pair string `json:"pair"` - PricePrecision int `json:"price_precision"` - InitialMargin float64 `json:"initial_margin,string"` - MinimumMargin float64 `json:"minimum_margin,string"` - MaximumOrderSize float64 `json:"maximum_order_size,string"` - MinimumOrderSize float64 `json:"minimum_order_size,string"` - Expiration string `json:"expiration"` -} - type Bitfinex struct { exchange.ExchangeBase - ActiveOrders []BitfinexOrder WebsocketConn *websocket.Conn WebsocketSubdChannels map[int]BitfinexWebsocketChanInfo } @@ -202,55 +85,6 @@ func (b *Bitfinex) Setup(exch config.ExchangeConfig) { } } -func (b *Bitfinex) Start() { - go b.Run() -} - -func (b *Bitfinex) Run() { - if b.Verbose { - log.Printf("%s Websocket: %s.", b.GetName(), common.IsEnabled(b.Websocket)) - log.Printf("%s polling delay: %ds.\n", b.GetName(), b.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) - } - - if b.Websocket { - go b.WebsocketClient() - } - - exchangeProducts, err := b.GetSymbols() - if err != nil { - log.Printf("%s Failed to get available symbols.\n", b.GetName()) - } else { - exchangeProducts = common.SplitStrings(common.StringToUpper(common.JoinStrings(exchangeProducts, ",")), ",") - diff := common.StringSliceDifference(b.AvailablePairs, exchangeProducts) - if len(diff) > 0 { - exch, err := bot.config.GetExchangeConfig(b.Name) - if err != nil { - log.Println(err) - } else { - log.Printf("%s Updating available pairs. Difference: %s.\n", b.Name, diff) - exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",") - bot.config.UpdateExchangeConfig(exch) - } - } - } - - for b.Enabled { - for _, x := range b.EnabledPairs { - currency := x - go func() { - ticker, err := b.GetTickerPrice(currency) - if err != nil { - return - } - log.Printf("Bitfinex %s Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) - AddExchangeInfo(b.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) - }() - } - time.Sleep(time.Second * b.RESTPollingDelay) - } -} - func (b *Bitfinex) GetTicker(symbol string, values url.Values) (BitfinexTicker, error) { path := common.EncodeURLValues(BITFINEX_API_URL+BITFINEX_TICKER+symbol, values) response := BitfinexTicker{} @@ -261,43 +95,6 @@ func (b *Bitfinex) GetTicker(symbol string, values url.Values) (BitfinexTicker, return response, nil } -func (b *Bitfinex) GetTickerPrice(currency string) (TickerPrice, error) { - ticker, err := GetTicker(b.GetName(), currency[0:3], currency[3:]) - if err == nil { - return ticker, nil - } - - var tickerPrice TickerPrice - tickerNew, err := b.GetTicker(currency, nil) - if err != nil { - return tickerPrice, err - } - tickerPrice.Ask = tickerNew.Ask - tickerPrice.Bid = tickerNew.Bid - tickerPrice.FirstCurrency = currency[0:3] - tickerPrice.SecondCurrency = currency[3:] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Low = tickerNew.Low - tickerPrice.Last = tickerNew.Last - tickerPrice.Volume = tickerNew.Volume - tickerPrice.High = tickerNew.High - ProcessTicker(b.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - -type BitfinexLendbookBidAsk struct { - Rate float64 `json:"rate,string"` - Amount float64 `json:"amount,string"` - Period int `json:"period"` - Timestamp string `json:"timestamp"` - FlashReturnRate string `json:"frr"` -} - -type BitfinexLendbook struct { - Bids []BitfinexLendbookBidAsk `json:"bids"` - Asks []BitfinexLendbookBidAsk `json:"asks"` -} - func (b *Bitfinex) GetStats(symbol string) (BitfinexStats, error) { response := BitfinexStats{} err := common.SendHTTPGetRequest(BITFINEX_API_URL+BITFINEX_STATS+symbol, true, &response) @@ -337,13 +134,6 @@ func (b *Bitfinex) GetTrades(symbol string, values url.Values) ([]BitfinexTradeS return response, nil } -type BitfinexLends struct { - Rate float64 `json:"rate,string"` - AmountLent float64 `json:"amount_lent,string"` - AmountUsed float64 `json:"amount_used,string"` - Timestamp int64 `json:"timestamp"` -} - func (b *Bitfinex) GetLends(symbol string, values url.Values) ([]BitfinexLends, error) { path := common.EncodeURLValues(BITFINEX_API_URL+BITFINEX_LENDS+symbol, values) response := []BitfinexLends{} @@ -372,16 +162,6 @@ func (b *Bitfinex) GetSymbolsDetails() ([]BitfinexSymbolDetails, error) { return response, nil } -type BitfinexAccountInfo struct { - MakerFees string `json:"maker_fees"` - TakerFees string `json:"taker_fees"` - Fees []struct { - Pairs string `json:"pairs"` - MakerFees string `json:"maker_fees"` - TakerFees string `json:"taker_fees"` - } `json:"fees"` -} - func (b *Bitfinex) GetAccountInfo() ([]BitfinexAccountInfo, error) { response := []BitfinexAccountInfo{} err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ACCOUNT_INFO, nil, &response) @@ -392,13 +172,6 @@ func (b *Bitfinex) GetAccountInfo() ([]BitfinexAccountInfo, error) { return response, nil } -type BitfinexDepositResponse struct { - Result string `json:"string"` - Method string `json:"method"` - Currency string `json:"currency"` - Address string `json:"address"` -} - func (b *Bitfinex) NewDeposit(method, walletName string, renew int) (BitfinexDepositResponse, error) { request := make(map[string]interface{}) request["method"] = method @@ -442,11 +215,6 @@ func (b *Bitfinex) NewOrder(Symbol string, Amount float64, Price float64, Buy bo return response, nil } -type BitfinexOrderMultiResponse struct { - Orders []BitfinexOrder `json:"order_ids"` - Status string `json:"status"` -} - func (b *Bitfinex) NewOrderMulti(orders []BitfinexPlaceOrder) (BitfinexOrderMultiResponse, error) { request := make(map[string]interface{}) request["orders"] = orders @@ -475,10 +243,6 @@ func (b *Bitfinex) CancelOrder(OrderID int64) (BitfinexOrder, error) { return response, nil } -type BitfinexGenericResponse struct { - Result string `json:"result"` -} - func (b *Bitfinex) CancelMultiplateOrders(OrderIDs []int64) (string, error) { request := make(map[string]interface{}) request["order_ids"] = OrderIDs @@ -557,17 +321,6 @@ func (b *Bitfinex) GetActiveOrders() ([]BitfinexOrder, error) { return response, nil } -type BitfinexPosition struct { - ID int64 `json:"id"` - Symbol string `json:"string"` - Status string `json:"active"` - Base float64 `json:"base,string"` - Amount float64 `json:"amount,string"` - Timestamp string `json:"timestamp"` - Swap float64 `json:"swap,string"` - PL float64 `json:"pl,string"` -} - func (b *Bitfinex) GetActivePositions() ([]BitfinexPosition, error) { response := []BitfinexPosition{} err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_POSITIONS, nil, &response) @@ -593,14 +346,6 @@ func (b *Bitfinex) ClaimPosition(PositionID int) (BitfinexPosition, error) { return response, nil } -type BitfinexBalanceHistory struct { - Currency string `json:"currency"` - Amount float64 `json:"amount,string"` - Balance float64 `json:"balance,string"` - Description string `json:"description"` - Timestamp string `json:"timestamp"` -} - func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince time.Time, timeUntil time.Time, limit int, wallet string) ([]BitfinexBalanceHistory, error) { request := make(map[string]interface{}) request["currency"] = symbol @@ -631,17 +376,6 @@ func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince time.Time, timeUnt return response, nil } -type BitfinexMovementHistory struct { - ID int64 `json:"id"` - Currency string `json:"currency"` - Method string `json:"method"` - Type string `json:"withdrawal"` - Amount float64 `json:"amount,string"` - Description string `json:"description"` - Status string `json:"status"` - Timestamp string `json:"timestamp"` -} - func (b *Bitfinex) GetMovementHistory(symbol, method string, timeSince, timeUntil time.Time, limit int) ([]BitfinexMovementHistory, error) { request := make(map[string]interface{}) request["currency"] = symbol @@ -672,18 +406,6 @@ func (b *Bitfinex) GetMovementHistory(symbol, method string, timeSince, timeUnti return response, nil } -type BitfinexTradeHistory struct { - Price float64 `json:"price,string"` - Amount float64 `json:"amount,string"` - Timestamp string `json:"timestamp"` - Exchange string `json:"exchange"` - Type string `json:"type"` - FeeCurrency string `json:"fee_currency"` - FeeAmount float64 `json:"fee_amount,string"` - TID int64 `json:"tid"` - OrderID int64 `json:"order_id"` -} - func (b *Bitfinex) GetTradeHistory(symbol string, timestamp, until time.Time, limit, reverse int) ([]BitfinexTradeHistory, error) { request := make(map[string]interface{}) request["currency"] = symbol @@ -762,16 +484,6 @@ func (b *Bitfinex) GetOfferStatus(OfferID int64) (BitfinexOffer, error) { return response, nil } -type BitfinexMarginFunds struct { - ID int64 `json:"id"` - PositionID int64 `json:"position_id"` - Currency string `json:"currency"` - Rate float64 `json:"rate,string"` - Period int `json:"period"` - Amount float64 `json:"amount,string"` - Timestamp string `json:"timestamp"` -} - func (b *Bitfinex) GetActiveOffers() ([]BitfinexOffer, error) { response := []BitfinexOffer{} err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_OFFERS, nil, &response) @@ -794,11 +506,6 @@ func (b *Bitfinex) GetActiveMarginFunding() ([]BitfinexMarginFunds, error) { return response, nil } -type BitfinexMarginTotalTakenFunds struct { - PositionPair string `json:"position_pair"` - TotalSwaps float64 `json:"total_swaps,string"` -} - func (b *Bitfinex) GetMarginTotalTakenFunds() ([]BitfinexMarginTotalTakenFunds, error) { response := []BitfinexMarginTotalTakenFunds{} err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_MARGIN_TOTAL_FUNDS, nil, &response) @@ -834,29 +541,6 @@ func (b *Bitfinex) GetAccountBalance() ([]BitfinexBalance, error) { return response, nil } -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Bitfinex exchange -func (e *Bitfinex) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - accountBalance, err := e.GetAccountBalance() - if err != nil { - return response, err - } - if !e.Enabled { - return response, nil - } - - for i := 0; i < len(accountBalance); i++ { - var exchangeCurrency ExchangeAccountCurrencyInfo - exchangeCurrency.CurrencyName = accountBalance[i].Currency - exchangeCurrency.TotalValue = accountBalance[i].Amount - exchangeCurrency.Hold = accountBalance[i].Available - - response.Currencies = append(response.Currencies, exchangeCurrency) - } - return response, nil -} - func (b *Bitfinex) GetMarginInfo() ([]BitfinexMarginInfo, error) { response := []BitfinexMarginInfo{} err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_MARGIN_INFO, nil, &response) @@ -868,11 +552,6 @@ func (b *Bitfinex) GetMarginInfo() ([]BitfinexMarginInfo, error) { return response, nil } -type BitfinexWalletTransfer struct { - Status string `json:"status"` - Message string `json:"message"` -} - func (b *Bitfinex) WalletTransfer(amount float64, currency, walletFrom, walletTo string) ([]BitfinexWalletTransfer, error) { request := make(map[string]interface{}) request["amount"] = amount @@ -890,12 +569,6 @@ func (b *Bitfinex) WalletTransfer(amount float64, currency, walletFrom, walletTo return response, nil } -type BitfinexWithdrawal struct { - Status string `json:"status"` - Message string `json:"message"` - WithdrawalID int64 `json:"withdrawal_id"` -} - func (b *Bitfinex) Withdrawal(withdrawType, wallet, address string, amount float64) ([]BitfinexWithdrawal, error) { request := make(map[string]interface{}) request["withdrawal_type"] = withdrawType diff --git a/bitfinexwebsocket.go b/exchanges/bitfinex/bitfinexwebsocket.go similarity index 88% rename from bitfinexwebsocket.go rename to exchanges/bitfinex/bitfinexwebsocket.go index 5a6c2ab4..1f8c0ab6 100644 --- a/bitfinexwebsocket.go +++ b/exchanges/bitfinex/bitfinexwebsocket.go @@ -1,4 +1,4 @@ -package main +package bitfinex import ( "log" @@ -28,73 +28,6 @@ const ( BITFINEX_WEBSOCKET_HEARTBEAT = "hb" ) -type BitfinexWebsocketChanInfo struct { - Channel string - Pair string -} - -type BitfinexWebsocketBook struct { - Price float64 - Count int - Amount float64 -} - -type BitfinexWebsocketTrade struct { - ID int64 - Timestamp int64 - Price float64 - Amount float64 -} - -type BitfinexWebsocketTicker struct { - Bid float64 - BidSize float64 - Ask float64 - AskSize float64 - DailyChange float64 - DialyChangePerc float64 - LastPrice float64 - Volume float64 -} - -type BitfinexWebsocketPosition struct { - Pair string - Status string - Amount float64 - Price float64 - MarginFunding float64 - MarginFundingType int -} - -type BitfinexWebsocketWallet struct { - Name string - Currency string - Balance float64 - UnsettledInterest float64 -} - -type BitfinexWebsocketOrder struct { - OrderID int64 - Pair string - Amount float64 - OrigAmount float64 - OrderType string - Status string - Price float64 - PriceAvg float64 - Timestamp string - Notify int -} - -type BitfinexWebsocketTradeExecuted struct { - TradeID int64 - Pair string - Timestamp int64 - OrderID int64 - AmountExecuted float64 - PriceExecuted float64 -} - func (b *Bitfinex) WebsocketPingHandler() error { request := make(map[string]string) request["event"] = "ping" diff --git a/exchanges/bitstamp/bitstamp_types.go b/exchanges/bitstamp/bitstamp_types.go new file mode 100644 index 00000000..bc90479d --- /dev/null +++ b/exchanges/bitstamp/bitstamp_types.go @@ -0,0 +1,109 @@ +package bitstamp + +type BitstampTicker struct { + Last float64 `json:"last,string"` + High float64 `json:"high,string"` + Low float64 `json:"low,string"` + Vwap float64 `json:"vwap,string"` + Volume float64 `json:"volume,string"` + Bid float64 `json:"bid,string"` + Ask float64 `json:"ask,string"` + Timestamp int64 `json:"timestamp,string"` + Open float64 `json:"open,string"` +} + +type BitstampBalances struct { + BTCReserved float64 `json:"btc_reserved,string"` + BTCEURFee float64 `json:"btceur_fee,string"` + BTCAvailable float64 `json:"btc_available,string"` + XRPAvailable float64 `json:"xrp_available,string"` + EURAvailable float64 `json:"eur_available,string"` + USDReserved float64 `json:"usd_reserved,string"` + EURReserved float64 `json:"eur_reserved,string"` + XRPEURFee float64 `json:"xrpeur_fee,string"` + XRPReserved float64 `json:"xrp_reserved,string"` + XRPBalance float64 `json:"xrp_balance,string"` + XRPUSDFee float64 `json:"xrpusd_fee,string"` + EURBalance float64 `json:"eur_balance,string"` + BTCBalance float64 `json:"btc_balance,string"` + BTCUSDFee float64 `json:"btcusd_fee,string"` + USDBalance float64 `json:"usd_balance,string"` + USDAvailable float64 `json:"usd_available,string"` + EURUSDFee float64 `json:"eurusd_fee,string"` +} + +type BitstampOrderbookBase struct { + Price float64 + Amount float64 +} + +type BitstampOrderbook struct { + Timestamp int64 `json:"timestamp,string"` + Bids []BitstampOrderbookBase + Asks []BitstampOrderbookBase +} + +type BitstampTransactions struct { + Date int64 `json:"date,string"` + TradeID int64 `json:"tid,string"` + Price float64 `json:"price,string"` + Type int `json:"type,string"` + Amount float64 `json:"amount,string"` +} + +type BitstampEURUSDConversionRate struct { + Buy float64 `json:"buy,string"` + Sell float64 `json:"sell,string"` +} + +type BitstampUserTransactions struct { + Date string `json:"datetime"` + TransID int64 `json:"id"` + Type int `json:"type,string"` + USD float64 `json:"usd"` + EUR float64 `json:"eur"` + BTC float64 `json:"btc"` + XRP float64 `json:"xrp"` + BTCUSD float64 `json:"btc_usd"` + Fee float64 `json:"fee,string"` + OrderID int64 `json:"order_id"` +} + +type BitstampOrder struct { + ID int64 `json:"id"` + Date string `json:"datetime"` + Type int `json:"type"` + Price float64 `json:"price"` + Amount float64 `json:"amount"` +} + +type BitstampOrderStatus struct { + Status string + Transactions []struct { + TradeID int64 `json:"tid"` + USD float64 `json:"usd,string"` + Price float64 `json:"price,string"` + Fee float64 `json:"fee,string"` + BTC float64 `json:"btc,string"` + } +} + +type BitstampWithdrawalRequests struct { + OrderID int64 `json:"id"` + Date string `json:"datetime"` + Type int `json:"type"` + Amount float64 `json:"amount,string"` + Status int `json:"status"` + Data interface{} +} + +type BitstampUnconfirmedBTCTransactions struct { + Amount float64 `json:"amount,string"` + Address string `json:"address"` + Confirmations int `json:"confirmations"` +} + +type BitstampXRPDepositResponse struct { + Address string `json:"address"` + DestinationTag int64 `json:"destination_tag"` +} diff --git a/exchanges/bitstamp/bitstamp_wrapper.go b/exchanges/bitstamp/bitstamp_wrapper.go new file mode 100644 index 00000000..d854eb9a --- /dev/null +++ b/exchanges/bitstamp/bitstamp_wrapper.go @@ -0,0 +1,90 @@ +package bitstamp + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (b *Bitstamp) Start() { + go b.Run() +} + +func (b *Bitstamp) Run() { + if b.Verbose { + log.Printf("%s Websocket: %s.", b.GetName(), common.IsEnabled(b.Websocket)) + log.Printf("%s polling delay: %ds.\n", b.GetName(), b.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) + } + + if b.Websocket { + go b.PusherClient() + } + + for b.Enabled { + for _, x := range b.EnabledPairs { + currency := x + go func() { + ticker, err := b.GetTickerPrice(currency) + if err != nil { + log.Println(err) + return + } + log.Printf("Bitstamp %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) + //AddExchangeInfo(b.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) + }() + } + time.Sleep(time.Second * b.RESTPollingDelay) + } +} + +func (b *Bitstamp) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(b.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tickerNew, nil + } + + var tickerPrice ticker.TickerPrice + tick, err := b.GetTicker(currency, false) + if err != nil { + return tickerPrice, err + + } + tickerPrice.Ask = tick.Ask + tickerPrice.Bid = tick.Bid + tickerPrice.FirstCurrency = currency[0:3] + tickerPrice.SecondCurrency = currency[3:] + tickerPrice.Low = tick.Low + tickerPrice.Last = tick.Last + tickerPrice.Volume = tick.Volume + tickerPrice.High = tick.High + ticker.ProcessTicker(b.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Bitstamp exchange +func (e *Bitstamp) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + accountBalance, err := e.GetBalance() + if err != nil { + return response, err + } + + var btcExchangeInfo exchange.ExchangeAccountCurrencyInfo + btcExchangeInfo.CurrencyName = "BTC" + btcExchangeInfo.TotalValue = accountBalance.BTCBalance + btcExchangeInfo.Hold = accountBalance.BTCReserved + response.Currencies = append(response.Currencies, btcExchangeInfo) + + var usdExchangeInfo exchange.ExchangeAccountCurrencyInfo + usdExchangeInfo.CurrencyName = "USD" + usdExchangeInfo.TotalValue = accountBalance.USDBalance + usdExchangeInfo.Hold = accountBalance.USDReserved + response.Currencies = append(response.Currencies, usdExchangeInfo) + + return response, nil +} diff --git a/bitstamphttp.go b/exchanges/bitstamp/bitstamphttp.go similarity index 69% rename from bitstamphttp.go rename to exchanges/bitstamp/bitstamphttp.go index ac27af95..3803a6d0 100644 --- a/bitstamphttp.go +++ b/exchanges/bitstamp/bitstamphttp.go @@ -1,4 +1,4 @@ -package main +package bitstamp import ( "errors" @@ -49,114 +49,6 @@ type Bitstamp struct { Balance BitstampBalances } -type BitstampTicker struct { - Last float64 `json:"last,string"` - High float64 `json:"high,string"` - Low float64 `json:"low,string"` - Vwap float64 `json:"vwap,string"` - Volume float64 `json:"volume,string"` - Bid float64 `json:"bid,string"` - Ask float64 `json:"ask,string"` - Timestamp int64 `json:"timestamp,string"` - Open float64 `json:"open,string"` -} - -type BitstampBalances struct { - BTCReserved float64 `json:"btc_reserved,string"` - BTCEURFee float64 `json:"btceur_fee,string"` - BTCAvailable float64 `json:"btc_available,string"` - XRPAvailable float64 `json:"xrp_available,string"` - EURAvailable float64 `json:"eur_available,string"` - USDReserved float64 `json:"usd_reserved,string"` - EURReserved float64 `json:"eur_reserved,string"` - XRPEURFee float64 `json:"xrpeur_fee,string"` - XRPReserved float64 `json:"xrp_reserved,string"` - XRPBalance float64 `json:"xrp_balance,string"` - XRPUSDFee float64 `json:"xrpusd_fee,string"` - EURBalance float64 `json:"eur_balance,string"` - BTCBalance float64 `json:"btc_balance,string"` - BTCUSDFee float64 `json:"btcusd_fee,string"` - USDBalance float64 `json:"usd_balance,string"` - USDAvailable float64 `json:"usd_available,string"` - EURUSDFee float64 `json:"eurusd_fee,string"` -} - -type BitstampOrderbookBase struct { - Price float64 - Amount float64 -} - -type BitstampOrderbook struct { - Timestamp int64 `json:"timestamp,string"` - Bids []BitstampOrderbookBase - Asks []BitstampOrderbookBase -} - -type BitstampTransactions struct { - Date int64 `json:"date,string"` - TradeID int64 `json:"tid,string"` - Price float64 `json:"price,string"` - Type int `json:"type,string"` - Amount float64 `json:"amount,string"` -} - -type BitstampEURUSDConversionRate struct { - Buy float64 `json:"buy,string"` - Sell float64 `json:"sell,string"` -} - -type BitstampUserTransactions struct { - Date string `json:"datetime"` - TransID int64 `json:"id"` - Type int `json:"type,string"` - USD float64 `json:"usd"` - EUR float64 `json:"eur"` - BTC float64 `json:"btc"` - XRP float64 `json:"xrp"` - BTCUSD float64 `json:"btc_usd"` - Fee float64 `json:"fee,string"` - OrderID int64 `json:"order_id"` -} - -type BitstampOrder struct { - ID int64 `json:"id"` - Date string `json:"datetime"` - Type int `json:"type"` - Price float64 `json:"price"` - Amount float64 `json:"amount"` -} - -type BitstampOrderStatus struct { - Status string - Transactions []struct { - TradeID int64 `json:"tid"` - USD float64 `json:"usd,string"` - Price float64 `json:"price,string"` - Fee float64 `json:"fee,string"` - BTC float64 `json:"btc,string"` - } -} - -type BitstampWithdrawalRequests struct { - OrderID int64 `json:"id"` - Date string `json:"datetime"` - Type int `json:"type"` - Amount float64 `json:"amount,string"` - Status int `json:"status"` - Data interface{} -} - -type BitstampUnconfirmedBTCTransactions struct { - Amount float64 `json:"amount,string"` - Address string `json:"address"` - Confirmations int `json:"confirmations"` -} - -type BitstampXRPDepositResponse struct { - Address string `json:"address"` - DestinationTag int64 `json:"destination_tag"` -} - func (b *Bitstamp) SetDefaults() { b.Name = "Bitstamp" b.Enabled = false @@ -165,10 +57,6 @@ func (b *Bitstamp) SetDefaults() { b.RESTPollingDelay = 10 } -func (b *Bitstamp) Start() { - go b.Run() -} - func (b *Bitstamp) Setup(exch config.ExchangeConfig) { if !exch.Enabled { b.SetEnabled(false) @@ -202,34 +90,6 @@ func (b *Bitstamp) GetFee(currency string) float64 { } } -func (b *Bitstamp) Run() { - if b.Verbose { - log.Printf("%s Websocket: %s.", b.GetName(), common.IsEnabled(b.Websocket)) - log.Printf("%s polling delay: %ds.\n", b.GetName(), b.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) - } - - if b.Websocket { - go b.PusherClient() - } - - for b.Enabled { - for _, x := range b.EnabledPairs { - currency := x - go func() { - ticker, err := b.GetTickerPrice(currency) - if err != nil { - log.Println(err) - return - } - log.Printf("Bitstamp %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) - AddExchangeInfo(b.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) - }() - } - time.Sleep(time.Second * b.RESTPollingDelay) - } -} - func (b *Bitstamp) GetTicker(currency string, hourly bool) (BitstampTicker, error) { tickerEndpoint := BITSTAMP_API_TICKER if hourly { @@ -248,31 +108,6 @@ func (b *Bitstamp) GetTicker(currency string, hourly bool) (BitstampTicker, erro return ticker, nil } -func (b *Bitstamp) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(b.GetName(), currency[0:3], currency[3:]) - if err == nil { - return tickerNew, nil - } - - var tickerPrice TickerPrice - ticker, err := b.GetTicker(currency, false) - if err != nil { - return tickerPrice, err - - } - tickerPrice.Ask = ticker.Ask - tickerPrice.Bid = ticker.Bid - tickerPrice.FirstCurrency = currency[0:3] - tickerPrice.SecondCurrency = currency[3:] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Low = ticker.Low - tickerPrice.Last = ticker.Last - tickerPrice.Volume = ticker.Volume - tickerPrice.High = ticker.High - ProcessTicker(b.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - func (b *Bitstamp) GetOrderbook(currency string) (BitstampOrderbook, error) { type response struct { Timestamp int64 `json:"timestamp,string"` @@ -352,30 +187,6 @@ func (b *Bitstamp) GetBalance() (BitstampBalances, error) { return balance, nil } -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Bitstamp exchange -func (e *Bitstamp) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - accountBalance, err := e.GetBalance() - if err != nil { - return response, err - } - - var btcExchangeInfo ExchangeAccountCurrencyInfo - btcExchangeInfo.CurrencyName = "BTC" - btcExchangeInfo.TotalValue = accountBalance.BTCBalance - btcExchangeInfo.Hold = accountBalance.BTCReserved - response.Currencies = append(response.Currencies, btcExchangeInfo) - - var usdExchangeInfo ExchangeAccountCurrencyInfo - usdExchangeInfo.CurrencyName = "USD" - usdExchangeInfo.TotalValue = accountBalance.USDBalance - usdExchangeInfo.Hold = accountBalance.USDReserved - response.Currencies = append(response.Currencies, usdExchangeInfo) - - return response, nil -} - func (b *Bitstamp) GetUserTransactions(values url.Values) ([]BitstampUserTransactions, error) { type Response struct { Date string `json:"datetime"` diff --git a/bitstampwebsocket.go b/exchanges/bitstamp/bitstampwebsocket.go similarity index 99% rename from bitstampwebsocket.go rename to exchanges/bitstamp/bitstampwebsocket.go index 5e073e3f..6958d1a0 100644 --- a/bitstampwebsocket.go +++ b/exchanges/bitstamp/bitstampwebsocket.go @@ -1,4 +1,4 @@ -package main +package bitstamp import ( "log" diff --git a/exchanges/btcc/btcc_types.go b/exchanges/btcc/btcc_types.go new file mode 100644 index 00000000..8f796eb3 --- /dev/null +++ b/exchanges/btcc/btcc_types.go @@ -0,0 +1,156 @@ +package btcc + +type BTCCTicker struct { + High float64 `json:",string"` + Low float64 `json:",string"` + Buy float64 `json:",string"` + Sell float64 `json:",string"` + Last float64 `json:",string"` + Vol float64 `json:",string"` + Date int64 + Vwap float64 `json:",string"` + Prev_close float64 `json:",string"` + Open float64 `json:",string"` +} + +type BTCCProfile struct { + Username string + TradePasswordEnabled bool `json:"trade_password_enabled,bool"` + OTPEnabled bool `json:"otp_enabled,bool"` + TradeFee float64 `json:"trade_fee"` + TradeFeeCNYLTC float64 `json:"trade_fee_cnyltc"` + TradeFeeBTCLTC float64 `json:"trade_fee_btcltc"` + DailyBTCLimit float64 `json:"daily_btc_limit"` + DailyLTCLimit float64 `json:"daily_ltc_limit"` + BTCDespoitAddress string `json:"btc_despoit_address"` + BTCWithdrawalAddress string `json:"btc_withdrawal_address"` + LTCDepositAddress string `json:"ltc_deposit_address"` + LTCWithdrawalAddress string `json:"ltc_withdrawal_request"` + APIKeyPermission int64 `json:"api_key_permission"` +} + +type BTCCCurrencyGeneric struct { + Currency string + Symbol string + Amount string + AmountInt int64 `json:"amount_integer"` + AmountDecimal float64 `json:"amount_decimal"` +} + +type BTCCOrder struct { + ID int64 + Type string + Price float64 + Currency string + Amount float64 + AmountOrig float64 `json:"amount_original"` + Date int64 + Status string + Detail BTCCOrderDetail +} + +type BTCCOrderDetail struct { + Dateline int64 + Price float64 + Amount float64 +} + +type BTCCWithdrawal struct { + ID int64 + Address string + Currency string + Amount float64 + Date int64 + Transaction string + Status string +} + +type BTCCDeposit struct { + ID int64 + Address string + Currency string + Amount float64 + Date int64 + Status string +} + +type BTCCBidAsk struct { + Price float64 + Amount float64 +} + +type BTCCDepth struct { + Bid []BTCCBidAsk + Ask []BTCCBidAsk +} + +type BTCCTransaction struct { + ID int64 + Type string + BTCAmount float64 `json:"btc_amount"` + LTCAmount float64 `json:"ltc_amount"` + CNYAmount float64 `json:"cny_amount"` + Date int64 +} + +type BTCCIcebergOrder struct { + ID int64 + Type string + Price float64 + Market string + Amount float64 + AmountOrig float64 `json:"amount_original"` + DisclosedAmount float64 `json:"disclosed_amount"` + Variance float64 + Date int64 + Status string +} + +type BTCCStopOrder struct { + ID int64 + Type string + StopPrice float64 `json:"stop_price"` + TrailingAmt float64 `json:"trailing_amount"` + TrailingPct float64 `json:"trailing_percentage"` + Price float64 + Market string + Amount float64 + Date int64 + Status string + OrderID int64 `json:"order_id"` +} + +type BTCCWebsocketOrder struct { + Price float64 `json:"price"` + TotalAmount float64 `json:"totalamount"` + Type string `json:"type"` +} + +type BTCCWebsocketGroupOrder struct { + Asks []BTCCWebsocketOrder `json:"ask"` + Bids []BTCCWebsocketOrder `json:"bid"` + Market string `json:"market"` +} + +type BTCCWebsocketTrade struct { + Amount float64 `json:"amount"` + Date float64 `json:"date"` + Market string `json:"market"` + Price float64 `json:"price"` + TradeID float64 `json:"trade_id"` + Type string `json:"type"` +} + +type BTCCWebsocketTicker struct { + Buy float64 `json:"buy"` + Date float64 `json:"date"` + High float64 `json:"high"` + Last float64 `json:"last"` + Low float64 `json:"low"` + Market string `json:"market"` + Open float64 `json:"open"` + PrevClose float64 `json:"prev_close"` + Sell float64 `json:"sell"` + Volume float64 `json:"vol"` + Vwap float64 `json:"vwap"` +} diff --git a/exchanges/btcc/btcc_wrapper.go b/exchanges/btcc/btcc_wrapper.go new file mode 100644 index 00000000..62f577ce --- /dev/null +++ b/exchanges/btcc/btcc_wrapper.go @@ -0,0 +1,70 @@ +package btcc + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (b *BTCC) Start() { + go b.Run() +} + +func (b *BTCC) Run() { + if b.Verbose { + log.Printf("%s Websocket: %s.", b.GetName(), common.IsEnabled(b.Websocket)) + log.Printf("%s polling delay: %ds.\n", b.GetName(), b.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) + } + + if b.Websocket { + go b.WebsocketClient() + } + + for b.Enabled { + for _, x := range b.EnabledPairs { + currency := x + go func() { + ticker, err := b.GetTickerPrice(common.StringToLower(currency)) + if err != nil { + log.Println(err) + return + } + log.Printf("BTCC %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) + //AddExchangeInfo(b.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) + }() + } + time.Sleep(time.Second * b.RESTPollingDelay) + } +} + +func (b *BTCC) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(b.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tickerNew, nil + } + + var tickerPrice ticker.TickerPrice + tick, err := b.GetTicker(currency) + tickerPrice.Ask = tick.Sell + tickerPrice.Bid = tick.Buy + tickerPrice.FirstCurrency = currency[0:3] + tickerPrice.SecondCurrency = currency[3:] + tickerPrice.Low = tick.Low + tickerPrice.Last = tick.Last + tickerPrice.Volume = tick.Vol + tickerPrice.High = tick.High + ticker.ProcessTicker(b.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +//TODO: Retrieve BTCC info +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Kraken exchange +func (e *BTCC) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + return response, nil +} diff --git a/btcchttp.go b/exchanges/btcc/btcchttp.go similarity index 73% rename from btcchttp.go rename to exchanges/btcc/btcchttp.go index 41e2da28..9ddce7b0 100644 --- a/btcchttp.go +++ b/exchanges/btcc/btcchttp.go @@ -1,4 +1,4 @@ -package main +package btcc import ( "errors" @@ -46,126 +46,6 @@ type BTCC struct { exchange.ExchangeBase } -type BTCCTicker struct { - High float64 `json:",string"` - Low float64 `json:",string"` - Buy float64 `json:",string"` - Sell float64 `json:",string"` - Last float64 `json:",string"` - Vol float64 `json:",string"` - Date int64 - Vwap float64 `json:",string"` - Prev_close float64 `json:",string"` - Open float64 `json:",string"` -} - -type BTCCProfile struct { - Username string - TradePasswordEnabled bool `json:"trade_password_enabled,bool"` - OTPEnabled bool `json:"otp_enabled,bool"` - TradeFee float64 `json:"trade_fee"` - TradeFeeCNYLTC float64 `json:"trade_fee_cnyltc"` - TradeFeeBTCLTC float64 `json:"trade_fee_btcltc"` - DailyBTCLimit float64 `json:"daily_btc_limit"` - DailyLTCLimit float64 `json:"daily_ltc_limit"` - BTCDespoitAddress string `json:"btc_despoit_address"` - BTCWithdrawalAddress string `json:"btc_withdrawal_address"` - LTCDepositAddress string `json:"ltc_deposit_address"` - LTCWithdrawalAddress string `json:"ltc_withdrawal_request"` - APIKeyPermission int64 `json:"api_key_permission"` -} - -type BTCCCurrencyGeneric struct { - Currency string - Symbol string - Amount string - AmountInt int64 `json:"amount_integer"` - AmountDecimal float64 `json:"amount_decimal"` -} - -type BTCCOrder struct { - ID int64 - Type string - Price float64 - Currency string - Amount float64 - AmountOrig float64 `json:"amount_original"` - Date int64 - Status string - Detail BTCCOrderDetail -} - -type BTCCOrderDetail struct { - Dateline int64 - Price float64 - Amount float64 -} - -type BTCCWithdrawal struct { - ID int64 - Address string - Currency string - Amount float64 - Date int64 - Transaction string - Status string -} - -type BTCCDeposit struct { - ID int64 - Address string - Currency string - Amount float64 - Date int64 - Status string -} - -type BTCCBidAsk struct { - Price float64 - Amount float64 -} - -type BTCCDepth struct { - Bid []BTCCBidAsk - Ask []BTCCBidAsk -} - -type BTCCTransaction struct { - ID int64 - Type string - BTCAmount float64 `json:"btc_amount"` - LTCAmount float64 `json:"ltc_amount"` - CNYAmount float64 `json:"cny_amount"` - Date int64 -} - -type BTCCIcebergOrder struct { - ID int64 - Type string - Price float64 - Market string - Amount float64 - AmountOrig float64 `json:"amount_original"` - DisclosedAmount float64 `json:"disclosed_amount"` - Variance float64 - Date int64 - Status string -} - -type BTCCStopOrder struct { - ID int64 - Type string - StopPrice float64 `json:"stop_price"` - TrailingAmt float64 `json:"trailing_amount"` - TrailingPct float64 `json:"trailing_percentage"` - Price float64 - Market string - Amount float64 - Date int64 - Status string - OrderID int64 `json:"order_id"` -} - func (b *BTCC) SetDefaults() { b.Name = "BTCC" b.Enabled = false @@ -192,42 +72,10 @@ func (b *BTCC) Setup(exch config.ExchangeConfig) { } } -func (b *BTCC) Start() { - go b.Run() -} - func (b *BTCC) GetFee() float64 { return b.Fee } -func (b *BTCC) Run() { - if b.Verbose { - log.Printf("%s Websocket: %s.", b.GetName(), common.IsEnabled(b.Websocket)) - log.Printf("%s polling delay: %ds.\n", b.GetName(), b.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) - } - - if b.Websocket { - go b.WebsocketClient() - } - - for b.Enabled { - for _, x := range b.EnabledPairs { - currency := x - go func() { - ticker, err := b.GetTickerPrice(common.StringToLower(currency)) - if err != nil { - log.Println(err) - return - } - log.Printf("BTCC %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) - AddExchangeInfo(b.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) - }() - } - time.Sleep(time.Second * b.RESTPollingDelay) - } -} - func (b *BTCC) GetTicker(symbol string) (BTCCTicker, error) { type Response struct { Ticker BTCCTicker @@ -242,27 +90,6 @@ func (b *BTCC) GetTicker(symbol string) (BTCCTicker, error) { return resp.Ticker, nil } -func (b *BTCC) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(b.GetName(), currency[0:3], currency[3:]) - if err == nil { - return tickerNew, nil - } - - var tickerPrice TickerPrice - ticker, err := b.GetTicker(currency) - tickerPrice.Ask = ticker.Sell - tickerPrice.Bid = ticker.Buy - tickerPrice.FirstCurrency = currency[0:3] - tickerPrice.SecondCurrency = currency[3:] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Low = ticker.Low - tickerPrice.Last = ticker.Last - tickerPrice.Volume = ticker.Vol - tickerPrice.High = ticker.High - ProcessTicker(b.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - func (b *BTCC) GetTradesLast24h(symbol string) bool { req := fmt.Sprintf("%sdata/trades?market=%s", BTCC_API_URL, symbol) err := common.SendHTTPGetRequest(req, true, nil) @@ -320,14 +147,6 @@ func (b *BTCC) GetAccountInfo(infoType string) { } } -//TODO: Retrieve BTCC info -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Kraken exchange -func (e *BTCC) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - return response, nil -} - func (b *BTCC) PlaceOrder(buyOrder bool, price, amount float64, market string) { params := make([]interface{}, 0) params = append(params, strconv.FormatFloat(price, 'f', -1, 64)) diff --git a/btccwebsocket.go b/exchanges/btcc/btccwebsocket.go similarity index 74% rename from btccwebsocket.go rename to exchanges/btcc/btccwebsocket.go index 8226ca83..029b8df5 100644 --- a/btccwebsocket.go +++ b/exchanges/btcc/btccwebsocket.go @@ -1,4 +1,4 @@ -package main +package btcc import ( "fmt" @@ -12,41 +12,6 @@ const ( BTCC_SOCKETIO_ADDRESS = "https://websocket.btcc.com" ) -type BTCCWebsocketOrder struct { - Price float64 `json:"price"` - TotalAmount float64 `json:"totalamount"` - Type string `json:"type"` -} - -type BTCCWebsocketGroupOrder struct { - Asks []BTCCWebsocketOrder `json:"ask"` - Bids []BTCCWebsocketOrder `json:"bid"` - Market string `json:"market"` -} - -type BTCCWebsocketTrade struct { - Amount float64 `json:"amount"` - Date float64 `json:"date"` - Market string `json:"market"` - Price float64 `json:"price"` - TradeID float64 `json:"trade_id"` - Type string `json:"type"` -} - -type BTCCWebsocketTicker struct { - Buy float64 `json:"buy"` - Date float64 `json:"date"` - High float64 `json:"high"` - Last float64 `json:"last"` - Low float64 `json:"low"` - Market string `json:"market"` - Open float64 `json:"open"` - PrevClose float64 `json:"prev_close"` - Sell float64 `json:"sell"` - Volume float64 `json:"vol"` - Vwap float64 `json:"vwap"` -} - var BTCCSocket *socketio.SocketIO func (b *BTCC) OnConnect(output chan socketio.Message) { diff --git a/exchanges/btce/btce_types.go b/exchanges/btce/btce_types.go new file mode 100644 index 00000000..a1f8b8e5 --- /dev/null +++ b/exchanges/btce/btce_types.go @@ -0,0 +1,126 @@ +package btce + +type BTCeTicker struct { + High float64 + Low float64 + Avg float64 + Vol float64 + Vol_cur float64 + Last float64 + Buy float64 + Sell float64 + Updated int64 +} + +type BTCEOrderbook struct { + Asks [][]float64 `json:"asks"` + Bids [][]float64 `json:"bids"` +} + +type BTCETrades struct { + Type string `json:"type"` + Price float64 `json:"bid"` + Amount float64 `json:"amount"` + TID int64 `json:"tid"` + Timestamp int64 `json:"timestamp"` +} + +type BTCEResponse struct { + Return interface{} `json:"return"` + Success int `json:"success"` + Error string `json:"error"` +} + +type BTCEPair struct { + DecimalPlaces int `json:"decimal_places"` + MinPrice float64 `json:"min_price"` + MaxPrice float64 `json:"max_price"` + MinAmount float64 `json:"min_amount"` + Hidden int `json:"hidden"` + Fee float64 `json:"fee"` +} + +type BTCEInfo struct { + ServerTime int64 `json:"server_time"` + Pairs map[string]BTCEPair `json:"pairs"` +} + +type BTCEAccountInfo struct { + Funds map[string]float64 `json:"funds"` + OpenOrders int `json:"open_orders"` + Rights struct { + Info int `json:"info"` + Trade int `json:"trade"` + Withdraw int `json:"withdraw"` + } `json:"rights"` + ServerTime float64 `json:"server_time"` + TransactionCount int `json:"transaction_count"` +} + +type BTCEActiveOrders struct { + Pair string `json:"pair"` + Type string `json:"sell"` + Amount float64 `json:"amount"` + Rate float64 `json:"rate"` + TimestampCreated float64 `json:"time_created"` + Status int `json:"status"` +} + +type BTCEOrderInfo struct { + Pair string `json:"pair"` + Type string `json:"sell"` + StartAmount float64 `json:"start_amount"` + Amount float64 `json:"amount"` + Rate float64 `json:"rate"` + TimestampCreated float64 `json:"time_created"` + Status int `json:"status"` +} + +type BTCECancelOrder struct { + OrderID float64 `json:"order_id"` + Funds map[string]float64 `json:"funds"` +} + +type BTCETrade struct { + Received float64 `json:"received"` + Remains float64 `json:"remains"` + OrderID float64 `json:"order_id"` + Funds map[string]float64 `json:"funds"` +} + +type BTCETransHistory struct { + Type int `json:"type"` + Amount float64 `json:"amount"` + Currency string `json:"currency"` + Description string `json:"desc"` + Status int `json:"status"` + Timestamp float64 `json:"timestamp"` +} + +type BTCETradeHistory struct { + Pair string `json:"pair"` + Type string `json:"type"` + Amount float64 `json:"amount"` + Rate float64 `json:"rate"` + OrderID float64 `json:"order_id"` + MyOrder int `json:"is_your_order"` + Timestamp float64 `json:"timestamp"` +} + +type BTCEWithdrawCoins struct { + TID int64 `json:"tId"` + AmountSent float64 `json:"amountSent"` + Funds map[string]float64 `json:"funds"` +} + +type BTCECreateCoupon struct { + Coupon string `json:"coupon"` + TransID int64 `json:"transID"` + Funds map[string]float64 `json:"funds"` +} + +type BTCERedeemCoupon struct { + CouponAmount float64 `json:"couponAmount,string"` + CouponCurrency string `json:"couponCurrency"` + TransID int64 `json:"transID"` +} diff --git a/exchanges/btce/btce_wrapper.go b/exchanges/btce/btce_wrapper.go new file mode 100644 index 00000000..bf400c2e --- /dev/null +++ b/exchanges/btce/btce_wrapper.go @@ -0,0 +1,85 @@ +package btce + +import ( + "errors" + "log" + "time" + + "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (b *BTCE) Start() { + go b.Run() +} + +func (b *BTCE) Run() { + if b.Verbose { + log.Printf("%s Websocket: %s.", b.GetName(), common.IsEnabled(b.Websocket)) + log.Printf("%s polling delay: %ds.\n", b.GetName(), b.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) + } + + pairs := []string{} + for _, x := range b.EnabledPairs { + x = common.StringToLower(x[0:3] + "_" + x[3:6]) + pairs = append(pairs, x) + } + pairsString := common.JoinStrings(pairs, "-") + + for b.Enabled { + go func() { + ticker, err := b.GetTicker(pairsString) + if err != nil { + log.Println(err) + return + } + for x, y := range ticker { + x = common.StringToUpper(x[0:3] + x[4:]) + log.Printf("BTC-e %s: Last %f High %f Low %f Volume %f\n", x, y.Last, y.High, y.Low, y.Vol_cur) + b.Ticker[x] = y + //AddExchangeInfo(b.GetName(), common.StringToUpper(x[0:3]), common.StringToUpper(x[4:]), y.Last, y.Vol_cur) + } + }() + time.Sleep(time.Second * b.RESTPollingDelay) + } +} + +func (b *BTCE) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + var tickerPrice ticker.TickerPrice + tick, ok := b.Ticker[currency] + if !ok { + return tickerPrice, errors.New("Unable to get currency.") + } + tickerPrice.Ask = tick.Buy + tickerPrice.Bid = tick.Sell + tickerPrice.FirstCurrency = currency[0:3] + tickerPrice.SecondCurrency = currency[3:] + tickerPrice.Low = tick.Low + tickerPrice.Last = tick.Last + tickerPrice.Volume = tick.Vol_cur + tickerPrice.High = tick.High + ticker.ProcessTicker(b.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the BTCE exchange +func (e *BTCE) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + accountBalance, err := e.GetAccountInfo() + if err != nil { + return response, err + } + + for x, y := range accountBalance.Funds { + var exchangeCurrency exchange.ExchangeAccountCurrencyInfo + exchangeCurrency.CurrencyName = common.StringToUpper(x) + exchangeCurrency.TotalValue = y + exchangeCurrency.Hold = 0 + response.Currencies = append(response.Currencies, exchangeCurrency) + } + + return response, nil +} diff --git a/btcehttp.go b/exchanges/btce/btcehttp.go similarity index 59% rename from btcehttp.go rename to exchanges/btce/btcehttp.go index 6b17a892..97e56118 100644 --- a/btcehttp.go +++ b/exchanges/btce/btcehttp.go @@ -1,4 +1,4 @@ -package main +package btce import ( "errors" @@ -40,37 +40,6 @@ type BTCE struct { Ticker map[string]BTCeTicker } -type BTCeTicker struct { - High float64 - Low float64 - Avg float64 - Vol float64 - Vol_cur float64 - Last float64 - Buy float64 - Sell float64 - Updated int64 -} - -type BTCEOrderbook struct { - Asks [][]float64 `json:"asks"` - Bids [][]float64 `json:"bids"` -} - -type BTCETrades struct { - Type string `json:"type"` - Price float64 `json:"bid"` - Amount float64 `json:"amount"` - TID int64 `json:"tid"` - Timestamp int64 `json:"timestamp"` -} - -type BTCEResponse struct { - Return interface{} `json:"return"` - Success int `json:"success"` - Error string `json:"error"` -} - func (b *BTCE) SetDefaults() { b.Name = "BTCE" b.Enabled = false @@ -98,60 +67,10 @@ func (b *BTCE) Setup(exch config.ExchangeConfig) { } } -func (b *BTCE) Start() { - go b.Run() -} - func (b *BTCE) GetFee() float64 { return b.Fee } -func (b *BTCE) Run() { - if b.Verbose { - log.Printf("%s Websocket: %s.", b.GetName(), common.IsEnabled(b.Websocket)) - log.Printf("%s polling delay: %ds.\n", b.GetName(), b.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) - } - - pairs := []string{} - for _, x := range b.EnabledPairs { - x = common.StringToLower(x[0:3] + "_" + x[3:6]) - pairs = append(pairs, x) - } - pairsString := common.JoinStrings(pairs, "-") - - for b.Enabled { - go func() { - ticker, err := b.GetTicker(pairsString) - if err != nil { - log.Println(err) - return - } - for x, y := range ticker { - x = common.StringToUpper(x[0:3] + x[4:]) - log.Printf("BTC-e %s: Last %f High %f Low %f Volume %f\n", x, y.Last, y.High, y.Low, y.Vol_cur) - b.Ticker[x] = y - AddExchangeInfo(b.GetName(), common.StringToUpper(x[0:3]), common.StringToUpper(x[4:]), y.Last, y.Vol_cur) - } - }() - time.Sleep(time.Second * b.RESTPollingDelay) - } -} - -type BTCEPair struct { - DecimalPlaces int `json:"decimal_places"` - MinPrice float64 `json:"min_price"` - MaxPrice float64 `json:"max_price"` - MinAmount float64 `json:"min_amount"` - Hidden int `json:"hidden"` - Fee float64 `json:"fee"` -} - -type BTCEInfo struct { - ServerTime int64 `json:"server_time"` - Pairs map[string]BTCEPair `json:"pairs"` -} - func (b *BTCE) GetInfo() (BTCEInfo, error) { req := fmt.Sprintf("%s/%s/%s/", BTCE_API_PUBLIC_URL, BTCE_API_PUBLIC_VERSION, BTCE_INFO) resp := BTCEInfo{} @@ -179,25 +98,6 @@ func (b *BTCE) GetTicker(symbol string) (map[string]BTCeTicker, error) { return response.Data, nil } -func (b *BTCE) GetTickerPrice(currency string) (TickerPrice, error) { - var tickerPrice TickerPrice - ticker, ok := b.Ticker[currency] - if !ok { - return tickerPrice, errors.New("Unable to get currency.") - } - tickerPrice.Ask = ticker.Buy - tickerPrice.Bid = ticker.Sell - tickerPrice.FirstCurrency = currency[0:3] - tickerPrice.SecondCurrency = currency[3:] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Low = ticker.Low - tickerPrice.Last = ticker.Last - tickerPrice.Volume = ticker.Vol_cur - tickerPrice.High = ticker.High - ProcessTicker(b.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - func (b *BTCE) GetDepth(symbol string) (BTCEOrderbook, error) { type Response struct { Data map[string]BTCEOrderbook @@ -232,18 +132,6 @@ func (b *BTCE) GetTrades(symbol string) ([]BTCETrades, error) { return trades, nil } -type BTCEAccountInfo struct { - Funds map[string]float64 `json:"funds"` - OpenOrders int `json:"open_orders"` - Rights struct { - Info int `json:"info"` - Trade int `json:"trade"` - Withdraw int `json:"withdraw"` - } `json:"rights"` - ServerTime float64 `json:"server_time"` - TransactionCount int `json:"transaction_count"` -} - func (b *BTCE) GetAccountInfo() (BTCEAccountInfo, error) { var result BTCEAccountInfo err := b.SendAuthenticatedHTTPRequest(BTCE_ACCOUNT_INFO, url.Values{}, &result) @@ -255,35 +143,6 @@ func (b *BTCE) GetAccountInfo() (BTCEAccountInfo, error) { return result, nil } -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the BTCE exchange -func (e *BTCE) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - accountBalance, err := e.GetAccountInfo() - if err != nil { - return response, err - } - - for x, y := range accountBalance.Funds { - var exchangeCurrency ExchangeAccountCurrencyInfo - exchangeCurrency.CurrencyName = common.StringToUpper(x) - exchangeCurrency.TotalValue = y - exchangeCurrency.Hold = 0 - response.Currencies = append(response.Currencies, exchangeCurrency) - } - - return response, nil -} - -type BTCEActiveOrders struct { - Pair string `json:"pair"` - Type string `json:"sell"` - Amount float64 `json:"amount"` - Rate float64 `json:"rate"` - TimestampCreated float64 `json:"time_created"` - Status int `json:"status"` -} - func (b *BTCE) GetActiveOrders(pair string) (map[string]BTCEActiveOrders, error) { req := url.Values{} req.Add("pair", pair) @@ -298,16 +157,6 @@ func (b *BTCE) GetActiveOrders(pair string) (map[string]BTCEActiveOrders, error) return result, nil } -type BTCEOrderInfo struct { - Pair string `json:"pair"` - Type string `json:"sell"` - StartAmount float64 `json:"start_amount"` - Amount float64 `json:"amount"` - Rate float64 `json:"rate"` - TimestampCreated float64 `json:"time_created"` - Status int `json:"status"` -} - func (b *BTCE) GetOrderInfo(OrderID int64) (map[string]BTCEOrderInfo, error) { req := url.Values{} req.Add("order_id", strconv.FormatInt(OrderID, 10)) @@ -322,11 +171,6 @@ func (b *BTCE) GetOrderInfo(OrderID int64) (map[string]BTCEOrderInfo, error) { return result, nil } -type BTCECancelOrder struct { - OrderID float64 `json:"order_id"` - Funds map[string]float64 `json:"funds"` -} - func (b *BTCE) CancelOrder(OrderID int64) (bool, error) { req := url.Values{} req.Add("order_id", strconv.FormatInt(OrderID, 10)) @@ -341,13 +185,6 @@ func (b *BTCE) CancelOrder(OrderID int64) (bool, error) { return true, nil } -type BTCETrade struct { - Received float64 `json:"received"` - Remains float64 `json:"remains"` - OrderID float64 `json:"order_id"` - Funds map[string]float64 `json:"funds"` -} - //to-do: convert orderid to int64 func (b *BTCE) Trade(pair, orderType string, amount, price float64) (float64, error) { req := url.Values{} @@ -366,15 +203,6 @@ func (b *BTCE) Trade(pair, orderType string, amount, price float64) (float64, er return result.OrderID, nil } -type BTCETransHistory struct { - Type int `json:"type"` - Amount float64 `json:"amount"` - Currency string `json:"currency"` - Description string `json:"desc"` - Status int `json:"status"` - Timestamp float64 `json:"timestamp"` -} - func (b *BTCE) GetTransactionHistory(TIDFrom, Count, TIDEnd int64, order, since, end string) (map[string]BTCETransHistory, error) { req := url.Values{} req.Add("from", strconv.FormatInt(TIDFrom, 10)) @@ -395,16 +223,6 @@ func (b *BTCE) GetTransactionHistory(TIDFrom, Count, TIDEnd int64, order, since, return result, nil } -type BTCETradeHistory struct { - Pair string `json:"pair"` - Type string `json:"type"` - Amount float64 `json:"amount"` - Rate float64 `json:"rate"` - OrderID float64 `json:"order_id"` - MyOrder int `json:"is_your_order"` - Timestamp float64 `json:"timestamp"` -} - func (b *BTCE) GetTradeHistory(TIDFrom, Count, TIDEnd int64, order, since, end, pair string) (map[string]BTCETradeHistory, error) { req := url.Values{} @@ -427,12 +245,6 @@ func (b *BTCE) GetTradeHistory(TIDFrom, Count, TIDEnd int64, order, since, end, return result, nil } -type BTCEWithdrawCoins struct { - TID int64 `json:"tId"` - AmountSent float64 `json:"amountSent"` - Funds map[string]float64 `json:"funds"` -} - func (b *BTCE) WithdrawCoins(coin string, amount float64, address string) (BTCEWithdrawCoins, error) { req := url.Values{} @@ -449,12 +261,6 @@ func (b *BTCE) WithdrawCoins(coin string, amount float64, address string) (BTCEW return result, nil } -type BTCECreateCoupon struct { - Coupon string `json:"coupon"` - TransID int64 `json:"transID"` - Funds map[string]float64 `json:"funds"` -} - func (b *BTCE) CreateCoupon(currency string, amount float64) (BTCECreateCoupon, error) { req := url.Values{} @@ -471,12 +277,6 @@ func (b *BTCE) CreateCoupon(currency string, amount float64) (BTCECreateCoupon, return result, nil } -type BTCERedeemCoupon struct { - CouponAmount float64 `json:"couponAmount,string"` - CouponCurrency string `json:"couponCurrency"` - TransID int64 `json:"transID"` -} - func (b *BTCE) RedeemCoupon(coupon string) (BTCERedeemCoupon, error) { req := url.Values{} diff --git a/btcmarkets.go b/exchanges/btcmarkets/btcmarkets.go similarity index 69% rename from btcmarkets.go rename to exchanges/btcmarkets/btcmarkets.go index e0ce840c..e59b6557 100644 --- a/btcmarkets.go +++ b/exchanges/btcmarkets/btcmarkets.go @@ -1,4 +1,4 @@ -package main +package btcmarkets import ( "bytes" @@ -31,55 +31,6 @@ type BTCMarkets struct { Ticker map[string]BTCMarketsTicker } -type BTCMarketsTicker struct { - BestBID float64 - BestAsk float64 - LastPrice float64 - Currency string - Instrument string - Timestamp int64 -} - -type BTCMarketsTrade struct { - TradeID int64 `json:"tid"` - Amount float64 `json:"amount"` - Price float64 `json:"price"` - Date int64 `json:"date"` -} - -type BTCMarketsOrderbook struct { - Currency string `json:"currency"` - Instrument string `json:"instrument"` - Timestamp int64 `json:"timestamp"` - Asks [][]float64 `json:"asks"` - Bids [][]float64 `json:"bids"` -} - -type BTCMarketsTradeResponse struct { - ID int64 `json:"id"` - CreationTime float64 `json:"creationTime"` - Description string `json:"description"` - Price float64 `json:"price"` - Volume float64 `json:"volume"` - Fee float64 `json:"fee"` -} - -type BTCMarketsOrder struct { - ID int64 `json:"id"` - Currency string `json:"currency"` - Instrument string `json:"instrument"` - OrderSide string `json:"orderSide"` - OrderType string `json:"ordertype"` - CreationTime float64 `json:"creationTime"` - Status string `json:"status"` - ErrorMessage string `json:"errorMessage"` - Price float64 `json:"price"` - Volume float64 `json:"volume"` - OpenVolume float64 `json:"openVolume"` - ClientRequestId string `json:"clientRequestId"` - Trades []BTCMarketsTradeResponse `json:"trades"` -} - func (b *BTCMarkets) SetDefaults() { b.Name = "BTC Markets" b.Enabled = false @@ -107,40 +58,10 @@ func (b *BTCMarkets) Setup(exch config.ExchangeConfig) { } } -func (b *BTCMarkets) Start() { - go b.Run() -} - func (b *BTCMarkets) GetFee() float64 { return b.Fee } -func (b *BTCMarkets) Run() { - if b.Verbose { - log.Printf("%s polling delay: %ds.\n", b.GetName(), b.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) - } - - for b.Enabled { - for _, x := range b.EnabledPairs { - currency := x - go func() { - ticker, err := b.GetTickerPrice(currency) - if err != nil { - return - } - BTCMarketsLastUSD, _ := ConvertCurrency(ticker.Last, "AUD", "USD") - BTCMarketsBestBidUSD, _ := ConvertCurrency(ticker.Bid, "AUD", "USD") - BTCMarketsBestAskUSD, _ := ConvertCurrency(ticker.Ask, "AUD", "USD") - log.Printf("BTC Markets %s: Last %f (%f) Bid %f (%f) Ask %f (%f)\n", currency, BTCMarketsLastUSD, ticker.Last, BTCMarketsBestBidUSD, ticker.Bid, BTCMarketsBestAskUSD, ticker.Ask) - AddExchangeInfo(b.GetName(), currency[0:3], currency[3:], ticker.Last, 0) - AddExchangeInfo(b.GetName(), currency[0:3], "USD", BTCMarketsLastUSD, 0) - }() - } - time.Sleep(time.Second * b.RESTPollingDelay) - } -} - func (b *BTCMarkets) GetTicker(symbol string) (BTCMarketsTicker, error) { ticker := BTCMarketsTicker{} path := fmt.Sprintf("/market/%s/AUD/tick", symbol) @@ -151,27 +72,6 @@ func (b *BTCMarkets) GetTicker(symbol string) (BTCMarketsTicker, error) { return ticker, nil } -func (b *BTCMarkets) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(b.GetName(), currency[0:3], currency[3:]) - if err == nil { - return tickerNew, nil - } - - var tickerPrice TickerPrice - ticker, err := b.GetTicker(currency) - if err != nil { - return tickerPrice, err - } - tickerPrice.Ask = ticker.BestAsk - tickerPrice.Bid = ticker.BestBID - tickerPrice.FirstCurrency = currency[0:3] - tickerPrice.SecondCurrency = currency[3:] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Last = ticker.LastPrice - ProcessTicker(b.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - func (b *BTCMarkets) GetOrderbook(symbol string) (BTCMarketsOrderbook, error) { orderbook := BTCMarketsOrderbook{} path := fmt.Sprintf("/market/%s/AUD/orderbook", symbol) @@ -364,12 +264,6 @@ func (b *BTCMarkets) GetOrderDetail(orderID []int64) ([]BTCMarketsOrder, error) return resp.Orders, nil } -type BTCMarketsAccountBalance struct { - Balance float64 `json:"balance"` - PendingFunds float64 `json:"pendingFunds"` - Currency string `json:"currency"` -} - func (b *BTCMarkets) GetAccountBalance() ([]BTCMarketsAccountBalance, error) { balance := []BTCMarketsAccountBalance{} err := b.SendAuthenticatedRequest("GET", BTCMARKETS_ACCOUNT_BALANCE, nil, &balance) @@ -387,25 +281,6 @@ func (b *BTCMarkets) GetAccountBalance() ([]BTCMarketsAccountBalance, error) { return balance, nil } -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the BTCMarkets exchange -func (e *BTCMarkets) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - accountBalance, err := e.GetAccountBalance() - if err != nil { - return response, err - } - for i := 0; i < len(accountBalance); i++ { - var exchangeCurrency ExchangeAccountCurrencyInfo - exchangeCurrency.CurrencyName = accountBalance[i].Currency - exchangeCurrency.TotalValue = accountBalance[i].Balance - exchangeCurrency.Hold = accountBalance[i].PendingFunds - - response.Currencies = append(response.Currencies, exchangeCurrency) - } - return response, nil -} - func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data interface{}, result interface{}) (err error) { nonce := strconv.FormatInt(time.Now().UnixNano(), 10)[0:13] request := "" diff --git a/exchanges/btcmarkets/btcmarkets_types.go b/exchanges/btcmarkets/btcmarkets_types.go new file mode 100644 index 00000000..45a2f8a9 --- /dev/null +++ b/exchanges/btcmarkets/btcmarkets_types.go @@ -0,0 +1,56 @@ +package btcmarkets + +type BTCMarketsTicker struct { + BestBID float64 + BestAsk float64 + LastPrice float64 + Currency string + Instrument string + Timestamp int64 +} + +type BTCMarketsTrade struct { + TradeID int64 `json:"tid"` + Amount float64 `json:"amount"` + Price float64 `json:"price"` + Date int64 `json:"date"` +} + +type BTCMarketsOrderbook struct { + Currency string `json:"currency"` + Instrument string `json:"instrument"` + Timestamp int64 `json:"timestamp"` + Asks [][]float64 `json:"asks"` + Bids [][]float64 `json:"bids"` +} + +type BTCMarketsTradeResponse struct { + ID int64 `json:"id"` + CreationTime float64 `json:"creationTime"` + Description string `json:"description"` + Price float64 `json:"price"` + Volume float64 `json:"volume"` + Fee float64 `json:"fee"` +} + +type BTCMarketsOrder struct { + ID int64 `json:"id"` + Currency string `json:"currency"` + Instrument string `json:"instrument"` + OrderSide string `json:"orderSide"` + OrderType string `json:"ordertype"` + CreationTime float64 `json:"creationTime"` + Status string `json:"status"` + ErrorMessage string `json:"errorMessage"` + Price float64 `json:"price"` + Volume float64 `json:"volume"` + OpenVolume float64 `json:"openVolume"` + ClientRequestId string `json:"clientRequestId"` + Trades []BTCMarketsTradeResponse `json:"trades"` +} + +type BTCMarketsAccountBalance struct { + Balance float64 `json:"balance"` + PendingFunds float64 `json:"pendingFunds"` + Currency string `json:"currency"` +} diff --git a/exchanges/btcmarkets/btcmarkets_wrapper.go b/exchanges/btcmarkets/btcmarkets_wrapper.go new file mode 100644 index 00000000..3289f973 --- /dev/null +++ b/exchanges/btcmarkets/btcmarkets_wrapper.go @@ -0,0 +1,79 @@ +package btcmarkets + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (b *BTCMarkets) Start() { + go b.Run() +} + +func (b *BTCMarkets) Run() { + if b.Verbose { + log.Printf("%s polling delay: %ds.\n", b.GetName(), b.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) + } + + for b.Enabled { + for _, x := range b.EnabledPairs { + currency := x + go func() { + ticker, err := b.GetTickerPrice(currency) + if err != nil { + return + } + //BTCMarketsLastUSD, _ := ConvertCurrency(ticker.Last, "AUD", "USD") + //BTCMarketsBestBidUSD, _ := ConvertCurrency(ticker.Bid, "AUD", "USD") + //BTCMarketsBestAskUSD, _ := ConvertCurrency(ticker.Ask, "AUD", "USD") + //log.Printf("BTC Markets %s: Last %f (%f) Bid %f (%f) Ask %f (%f)\n", currency, BTCMarketsLastUSD, ticker.Last, BTCMarketsBestBidUSD, ticker.Bid, BTCMarketsBestAskUSD, ticker.Ask) + log.Printf("BTC Markets %s: Last %f Bid %f Ask %f \n", currency, ticker.Last, ticker.Bid, ticker.Ask) + //AddExchangeInfo(b.GetName(), currency[0:3], currency[3:], ticker.Last, 0) + //AddExchangeInfo(b.GetName(), currency[0:3], "USD", BTCMarketsLastUSD, 0) + }() + } + time.Sleep(time.Second * b.RESTPollingDelay) + } +} + +func (b *BTCMarkets) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(b.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tickerNew, nil + } + + var tickerPrice ticker.TickerPrice + tick, err := b.GetTicker(currency) + if err != nil { + return tickerPrice, err + } + tickerPrice.Ask = tick.BestAsk + tickerPrice.Bid = tick.BestBID + tickerPrice.FirstCurrency = currency[0:3] + tickerPrice.SecondCurrency = currency[3:] + tickerPrice.Last = tick.LastPrice + ticker.ProcessTicker(b.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the BTCMarkets exchange +func (e *BTCMarkets) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + accountBalance, err := e.GetAccountBalance() + if err != nil { + return response, err + } + for i := 0; i < len(accountBalance); i++ { + var exchangeCurrency exchange.ExchangeAccountCurrencyInfo + exchangeCurrency.CurrencyName = accountBalance[i].Currency + exchangeCurrency.TotalValue = accountBalance[i].Balance + exchangeCurrency.Hold = accountBalance[i].PendingFunds + + response.Currencies = append(response.Currencies, exchangeCurrency) + } + return response, nil +} diff --git a/exchanges/exchange.go b/exchanges/exchange.go index cd44029d..ba3e1a4a 100644 --- a/exchanges/exchange.go +++ b/exchanges/exchange.go @@ -5,12 +5,27 @@ import ( "time" "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/config" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" ) const ( WarningBase64DecryptSecretKeyFailed = "WARNING -- Exchange %s unable to base64 decode secret key.. Disabling Authenticated API support." ) +//ExchangeAccountInfo : Generic type to hold each exchange's holdings in all enabled currencies +type ExchangeAccountInfo struct { + ExchangeName string + Currencies []ExchangeAccountCurrencyInfo +} + +//ExchangeAccountCurrencyInfo : Sub type to store currency name and value +type ExchangeAccountCurrencyInfo struct { + CurrencyName string + TotalValue float64 + Hold float64 +} + type ExchangeBase struct { Name string Enabled bool @@ -27,6 +42,18 @@ type ExchangeBase struct { APIUrl string } +//IBotExchange : Enforces standard functions for all exchanges supported in gocryptotrader +type IBotExchange interface { + Setup(exch config.ExchangeConfig) + Start() + SetDefaults() + GetName() string + IsEnabled() bool + GetTickerPrice(currency string) (ticker.TickerPrice, error) + GetEnabledCurrencies() []string + GetExchangeAccountInfo() (ExchangeAccountInfo, error) +} + func (e *ExchangeBase) GetName() string { return e.Name } diff --git a/exchanges/gdax/gdax_types.go b/exchanges/gdax/gdax_types.go new file mode 100644 index 00000000..857ab9f6 --- /dev/null +++ b/exchanges/gdax/gdax_types.go @@ -0,0 +1,219 @@ +package gdax + +type GDAXTicker struct { + TradeID int64 `json:"trade_id"` + Price float64 `json:"price,string"` + Size float64 `json:"size,string"` + Time string `json:"time"` +} + +type GDAXProduct struct { + ID string `json:"id"` + BaseCurrency string `json:"base_currency"` + QuoteCurrency string `json:"quote_currency"` + BaseMinSize float64 `json:"base_min_size,string"` + BaseMaxSize int64 `json:"base_max_size,string"` + QuoteIncrement float64 `json:"quote_increment,string"` + DisplayName string `json:"string"` +} + +type GDAXOrderL1L2 struct { + Price float64 + Amount float64 + NumOrders float64 +} + +type GDAXOrderL3 struct { + Price float64 + Amount float64 + OrderID string +} + +type GDAXOrderbookL1L2 struct { + Sequence int64 `json:"sequence"` + Bids [][]GDAXOrderL1L2 `json:"asks"` + Asks [][]GDAXOrderL1L2 `json:"asks"` +} + +type GDAXOrderbookL3 struct { + Sequence int64 `json:"sequence"` + Bids [][]GDAXOrderL3 `json:"asks"` + Asks [][]GDAXOrderL3 `json:"asks"` +} + +type GDAXOrderbookResponse struct { + Sequence int64 `json:"sequence"` + Bids [][]interface{} `json:"bids"` + Asks [][]interface{} `json:"asks"` +} + +type GDAXTrade struct { + TradeID int64 `json:"trade_id"` + Price float64 `json:"price,string"` + Size float64 `json:"size,string"` + Time string `json:"time"` + Side string `json:"side"` +} + +type GDAXStats struct { + Open float64 `json:"open,string"` + High float64 `json:"high,string"` + Low float64 `json:"low,string"` + Volume float64 `json:"volume,string"` +} + +type GDAXCurrency struct { + ID string + Name string + MinSize float64 `json:"min_size,string"` +} + +type GDAXHistory struct { + Time int64 + Low float64 + High float64 + Open float64 + Close float64 + Volume float64 +} + +type GDAXAccountResponse struct { + ID string `json:"id"` + Balance float64 `json:"balance,string"` + Hold float64 `json:"hold,string"` + Available float64 `json:"available,string"` + Currency string `json:"currency"` +} + +type GDAXAccountLedgerResponse struct { + ID string `json:"id"` + CreatedAt string `json:"created_at"` + Amount float64 `json:"amount,string"` + Balance float64 `json:"balance,string"` + Type string `json:"type"` + details interface{} `json:"details"` +} + +type GDAXAccountHolds struct { + ID string `json:"id"` + AccountID string `json:"account_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + Amount float64 `json:"amount,string"` + Type string `json:"type"` + Reference string `json:"ref"` +} + +type GDAXOrdersResponse struct { + ID string `json:"id"` + Size float64 `json:"size,string"` + Price float64 `json:"price,string"` + ProductID string `json:"product_id"` + Status string `json:"status"` + FilledSize float64 `json:"filled_size,string"` + FillFees float64 `json:"fill_fees,string"` + Settled bool `json:"settled"` + Side string `json:"side"` + CreatedAt string `json:"created_at"` +} + +type GDAXOrderResponse struct { + ID string `json:"id"` + Size float64 `json:"size,string"` + Price float64 `json:"price,string"` + DoneReason string `json:"done_reason"` + Status string `json:"status"` + Settled bool `json:"settled"` + FilledSize float64 `json:"filled_size,string"` + ProductID string `json:"product_id"` + FillFees float64 `json:"fill_fees,string"` + Side string `json:"side"` + CreatedAt string `json:"created_at"` + DoneAt string `json:"done_at"` +} + +type GDAXFillResponse struct { + TradeID int `json:"trade_id"` + ProductID string `json:"product_id"` + Price float64 `json:"price,string"` + Size float64 `json:"size,string"` + OrderID string `json:"order_id"` + CreatedAt string `json:"created_at"` + Liquidity string `json:"liquidity"` + Fee float64 `json:"fee,string"` + Settled bool `json:"settled"` + Side string `json:"side"` +} + +type GDAXReportResponse struct { + ID string `json:"id"` + Type string `json:"type"` + Status string `json:"status"` + CreatedAt string `json:"created_at"` + CompletedAt string `json:"completed_at"` + ExpiresAt string `json:"expires_at"` + FileURL string `json:"file_url"` + Params struct { + StartDate string `json:"start_date"` + EndDate string `json:"end_date"` + } `json:params"` +} + +type GDAXWebsocketSubscribe struct { + Type string `json:"type"` + ProductID string `json:"product_id"` +} + +type GDAXWebsocketReceived struct { + Type string `json:"type"` + Time string `json:"time"` + Sequence int `json:"sequence"` + OrderID string `json:"order_id"` + Size float64 `json:"size,string"` + Price float64 `json:"price,string"` + Side string `json:"side"` +} + +type GDAXWebsocketOpen struct { + Type string `json:"type"` + Time string `json:"time"` + Sequence int `json:"sequence"` + OrderID string `json:"order_id"` + Price float64 `json:"price,string"` + RemainingSize float64 `json:"remaining_size,string"` + Side string `json:"side"` +} + +type GDAXWebsocketDone struct { + Type string `json:"type"` + Time string `json:"time"` + Sequence int `json:"sequence"` + Price float64 `json:"price,string"` + OrderID string `json:"order_id"` + Reason string `json:"reason"` + Side string `json:"side"` + RemainingSize float64 `json:"remaining_size,string"` +} + +type GDAXWebsocketMatch struct { + Type string `json:"type"` + TradeID int `json:"trade_id"` + Sequence int `json:"sequence"` + MakerOrderID string `json:"maker_order_id"` + TakerOrderID string `json:"taker_order_id"` + Time string `json:"time"` + Size float64 `json:"size,string"` + Price float64 `json:"price,string"` + Side string `json:"side"` +} + +type GDAXWebsocketChange struct { + Type string `json:"type"` + Time string `json:"time"` + Sequence int `json:"sequence"` + OrderID string `json:"order_id"` + NewSize float64 `json:"new_size,string"` + OldSize float64 `json:"old_size,string"` + Price float64 `json:"price,string"` + Side string `json:"side"` +} diff --git a/exchanges/gdax/gdax_wrapper.go b/exchanges/gdax/gdax_wrapper.go new file mode 100644 index 00000000..6d8341e5 --- /dev/null +++ b/exchanges/gdax/gdax_wrapper.go @@ -0,0 +1,116 @@ +package gdax + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (g *GDAX) Start() { + go g.Run() +} + +func (g *GDAX) Run() { + if g.Verbose { + log.Printf("%s Websocket: %s. (url: %s).\n", g.GetName(), common.IsEnabled(g.Websocket), GDAX_WEBSOCKET_URL) + log.Printf("%s polling delay: %ds.\n", g.GetName(), g.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", g.GetName(), len(g.EnabledPairs), g.EnabledPairs) + } + + if g.Websocket { + go g.WebsocketClient() + } + + exchangeProducts, err := g.GetProducts() + if err != nil { + log.Printf("%s Failed to get available products.\n", g.GetName()) + } else { + log.Println(exchangeProducts) + /* + currencies := []string{} + for _, x := range exchangeProducts { + if x.ID != "BTC" && x.ID != "USD" && x.ID != "GBP" { + currencies = append(currencies, x.ID[0:3]+x.ID[4:]) + } + } + diff := common.StringSliceDifference(g.AvailablePairs, currencies) + if len(diff) > 0 { + exch, err := bot.config.GetExchangeConfig(g.Name) + if err != nil { + log.Println(err) + } else { + log.Printf("%s Updating available pairs. Difference: %s.\n", g.Name, diff) + exch.AvailablePairs = common.JoinStrings(currencies, ",") + bot.config.UpdateExchangeConfig(exch) + } + } + */ + } + + for g.Enabled { + for _, x := range g.EnabledPairs { + currency := x[0:3] + "-" + x[3:] + go func() { + ticker, err := g.GetTickerPrice(currency) + + if err != nil { + log.Println(err) + return + } + log.Printf("GDAX %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) + //AddExchangeInfo(g.GetName(), currency[0:3], currency[4:], ticker.Last, ticker.Volume) + }() + } + time.Sleep(time.Second * g.RESTPollingDelay) + } +} + +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the GDAX exchange +func (e *GDAX) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + accountBalance, err := e.GetAccounts() + if err != nil { + return response, err + } + for i := 0; i < len(accountBalance); i++ { + var exchangeCurrency exchange.ExchangeAccountCurrencyInfo + exchangeCurrency.CurrencyName = accountBalance[i].Currency + exchangeCurrency.TotalValue = accountBalance[i].Balance + exchangeCurrency.Hold = accountBalance[i].Hold + + response.Currencies = append(response.Currencies, exchangeCurrency) + } + return response, nil +} + +func (g *GDAX) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(g.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tickerNew, nil + } + + var tickerPrice ticker.TickerPrice + tick, err := g.GetTicker(currency) + if err != nil { + return ticker.TickerPrice{}, err + } + + stats, err := g.GetStats(currency) + + if err != nil { + return ticker.TickerPrice{}, err + } + + tickerPrice.FirstCurrency = currency[0:3] + tickerPrice.SecondCurrency = currency[4:] + tickerPrice.Volume = stats.Volume + tickerPrice.Last = tick.Price + tickerPrice.High = stats.High + tickerPrice.Low = stats.Low + ticker.ProcessTicker(g.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} diff --git a/gdaxhttp.go b/exchanges/gdax/gdaxhttp.go similarity index 59% rename from gdaxhttp.go rename to exchanges/gdax/gdaxhttp.go index 731e4c4a..9dc3aed7 100644 --- a/gdaxhttp.go +++ b/exchanges/gdax/gdaxhttp.go @@ -1,4 +1,4 @@ -package main +package gdax import ( "bytes" @@ -37,83 +37,6 @@ type GDAX struct { exchange.ExchangeBase } -type GDAXTicker struct { - TradeID int64 `json:"trade_id"` - Price float64 `json:"price,string"` - Size float64 `json:"size,string"` - Time string `json:"time"` -} - -type GDAXProduct struct { - ID string `json:"id"` - BaseCurrency string `json:"base_currency"` - QuoteCurrency string `json:"quote_currency"` - BaseMinSize float64 `json:"base_min_size,string"` - BaseMaxSize int64 `json:"base_max_size,string"` - QuoteIncrement float64 `json:"quote_increment,string"` - DisplayName string `json:"string"` -} - -type GDAXOrderL1L2 struct { - Price float64 - Amount float64 - NumOrders float64 -} - -type GDAXOrderL3 struct { - Price float64 - Amount float64 - OrderID string -} - -type GDAXOrderbookL1L2 struct { - Sequence int64 `json:"sequence"` - Bids [][]GDAXOrderL1L2 `json:"asks"` - Asks [][]GDAXOrderL1L2 `json:"asks"` -} - -type GDAXOrderbookL3 struct { - Sequence int64 `json:"sequence"` - Bids [][]GDAXOrderL3 `json:"asks"` - Asks [][]GDAXOrderL3 `json:"asks"` -} - -type GDAXOrderbookResponse struct { - Sequence int64 `json:"sequence"` - Bids [][]interface{} `json:"bids"` - Asks [][]interface{} `json:"asks"` -} - -type GDAXTrade struct { - TradeID int64 `json:"trade_id"` - Price float64 `json:"price,string"` - Size float64 `json:"size,string"` - Time string `json:"time"` - Side string `json:"side"` -} - -type GDAXStats struct { - Open float64 `json:"open,string"` - High float64 `json:"high,string"` - Low float64 `json:"low,string"` - Volume float64 `json:"volume,string"` -} - -type GDAXCurrency struct { - ID string - Name string - MinSize float64 `json:"min_size,string"` -} - -type GDAXHistory struct { - Time int64 - Low float64 - High float64 - Open float64 - Close float64 - Volume float64 -} - func (g *GDAX) SetDefaults() { g.Name = "GDAX" g.Enabled = false @@ -141,10 +64,6 @@ func (g *GDAX) Setup(exch config.ExchangeConfig) { } } -func (g *GDAX) Start() { - go g.Run() -} - func (g *GDAX) GetFee(maker bool) float64 { if maker { return g.MakerFee @@ -153,58 +72,6 @@ func (g *GDAX) GetFee(maker bool) float64 { } } -func (g *GDAX) Run() { - if g.Verbose { - log.Printf("%s Websocket: %s. (url: %s).\n", g.GetName(), common.IsEnabled(g.Websocket), GDAX_WEBSOCKET_URL) - log.Printf("%s polling delay: %ds.\n", g.GetName(), g.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", g.GetName(), len(g.EnabledPairs), g.EnabledPairs) - } - - if g.Websocket { - go g.WebsocketClient() - } - - exchangeProducts, err := g.GetProducts() - if err != nil { - log.Printf("%s Failed to get available products.\n", g.GetName()) - } else { - currencies := []string{} - for _, x := range exchangeProducts { - if x.ID != "BTC" && x.ID != "USD" && x.ID != "GBP" { - currencies = append(currencies, x.ID[0:3]+x.ID[4:]) - } - } - diff := common.StringSliceDifference(g.AvailablePairs, currencies) - if len(diff) > 0 { - exch, err := bot.config.GetExchangeConfig(g.Name) - if err != nil { - log.Println(err) - } else { - log.Printf("%s Updating available pairs. Difference: %s.\n", g.Name, diff) - exch.AvailablePairs = common.JoinStrings(currencies, ",") - bot.config.UpdateExchangeConfig(exch) - } - } - } - - for g.Enabled { - for _, x := range g.EnabledPairs { - currency := x[0:3] + "-" + x[3:] - go func() { - ticker, err := g.GetTickerPrice(currency) - - if err != nil { - log.Println(err) - return - } - log.Printf("GDAX %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) - AddExchangeInfo(g.GetName(), currency[0:3], currency[4:], ticker.Last, ticker.Volume) - }() - } - time.Sleep(time.Second * g.RESTPollingDelay) - } -} - func (g *GDAX) GetProducts() ([]GDAXProduct, error) { products := []GDAXProduct{} err := common.SendHTTPGetRequest(GDAX_API_URL+GDAX_PRODUCTS, true, &products) @@ -317,35 +184,6 @@ func (g *GDAX) GetTicker(symbol string) (GDAXTicker, error) { return ticker, nil } -func (g *GDAX) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(g.GetName(), currency[0:3], currency[3:]) - if err == nil { - return tickerNew, nil - } - - var tickerPrice TickerPrice - ticker, err := g.GetTicker(currency) - if err != nil { - return TickerPrice{}, err - } - - stats, err := g.GetStats(currency) - - if err != nil { - return TickerPrice{}, err - } - - tickerPrice.FirstCurrency = currency[0:3] - tickerPrice.SecondCurrency = currency[4:] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Volume = stats.Volume - tickerPrice.Last = ticker.Price - tickerPrice.High = stats.High - tickerPrice.Low = stats.Low - ProcessTicker(g.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - func (g *GDAX) GetTrades(symbol string) ([]GDAXTrade, error) { trades := []GDAXTrade{} path := fmt.Sprintf("%s/%s/%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_TRADES) @@ -403,14 +241,6 @@ func (g *GDAX) GetCurrencies() ([]GDAXCurrency, error) { return currencies, nil } -type GDAXAccountResponse struct { - ID string `json:"id"` - Balance float64 `json:"balance,string"` - Hold float64 `json:"hold,string"` - Available float64 `json:"available,string"` - Currency string `json:"currency"` -} - func (g *GDAX) GetAccounts() ([]GDAXAccountResponse, error) { resp := []GDAXAccountResponse{} err := g.SendAuthenticatedHTTPRequest("GET", GDAX_API_URL+GDAX_ACCOUNTS, nil, &resp) @@ -431,34 +261,6 @@ func (g *GDAX) GetAccount(account string) (GDAXAccountResponse, error) { return resp, nil } -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the GDAX exchange -func (e *GDAX) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - accountBalance, err := e.GetAccounts() - if err != nil { - return response, err - } - for i := 0; i < len(accountBalance); i++ { - var exchangeCurrency ExchangeAccountCurrencyInfo - exchangeCurrency.CurrencyName = accountBalance[i].Currency - exchangeCurrency.TotalValue = accountBalance[i].Balance - exchangeCurrency.Hold = accountBalance[i].Hold - - response.Currencies = append(response.Currencies, exchangeCurrency) - } - return response, nil -} - -type GDAXAccountLedgerResponse struct { - ID string `json:"id"` - CreatedAt string `json:"created_at"` - Amount float64 `json:"amount,string"` - Balance float64 `json:"balance,string"` - Type string `json:"type"` - details interface{} `json:"details"` -} - func (g *GDAX) GetAccountHistory(accountID string) ([]GDAXAccountLedgerResponse, error) { resp := []GDAXAccountLedgerResponse{} path := fmt.Sprintf("%s/%s/%s", GDAX_ACCOUNTS, accountID, GDAX_LEDGER) @@ -469,16 +271,6 @@ func (g *GDAX) GetAccountHistory(accountID string) ([]GDAXAccountLedgerResponse, return resp, nil } -type GDAXAccountHolds struct { - ID string `json:"id"` - AccountID string `json:"account_id"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` - Amount float64 `json:"amount,string"` - Type string `json:"type"` - Reference string `json:"ref"` -} - func (g *GDAX) GetHolds(accountID string) ([]GDAXAccountHolds, error) { resp := []GDAXAccountHolds{} path := fmt.Sprintf("%s/%s/%s", GDAX_ACCOUNTS, accountID, GDAX_HOLDS) @@ -527,19 +319,6 @@ func (g *GDAX) CancelOrder(orderID string) error { return nil } -type GDAXOrdersResponse struct { - ID string `json:"id"` - Size float64 `json:"size,string"` - Price float64 `json:"price,string"` - ProductID string `json:"product_id"` - Status string `json:"status"` - FilledSize float64 `json:"filled_size,string"` - FillFees float64 `json:"fill_fees,string"` - Settled bool `json:"settled"` - Side string `json:"side"` - CreatedAt string `json:"created_at"` -} - func (g *GDAX) GetOrders(params url.Values) ([]GDAXOrdersResponse, error) { path := common.EncodeURLValues(GDAX_API_URL+GDAX_ORDERS, params) resp := []GDAXOrdersResponse{} @@ -550,21 +329,6 @@ func (g *GDAX) GetOrders(params url.Values) ([]GDAXOrdersResponse, error) { return resp, nil } -type GDAXOrderResponse struct { - ID string `json:"id"` - Size float64 `json:"size,string"` - Price float64 `json:"price,string"` - DoneReason string `json:"done_reason"` - Status string `json:"status"` - Settled bool `json:"settled"` - FilledSize float64 `json:"filled_size,string"` - ProductID string `json:"product_id"` - FillFees float64 `json:"fill_fees,string"` - Side string `json:"side"` - CreatedAt string `json:"created_at"` - DoneAt string `json:"done_at"` -} - func (g *GDAX) GetOrder(orderID string) (GDAXOrderResponse, error) { path := fmt.Sprintf("%s/%s", GDAX_ORDERS, orderID) resp := GDAXOrderResponse{} @@ -575,19 +339,6 @@ func (g *GDAX) GetOrder(orderID string) (GDAXOrderResponse, error) { return resp, nil } -type GDAXFillResponse struct { - TradeID int `json:"trade_id"` - ProductID string `json:"product_id"` - Price float64 `json:"price,string"` - Size float64 `json:"size,string"` - OrderID string `json:"order_id"` - CreatedAt string `json:"created_at"` - Liquidity string `json:"liquidity"` - Fee float64 `json:"fee,string"` - Settled bool `json:"settled"` - Side string `json:"side"` -} - func (g *GDAX) GetFills(params url.Values) ([]GDAXFillResponse, error) { path := common.EncodeURLValues(GDAX_API_URL+GDAX_FILLS, params) resp := []GDAXFillResponse{} @@ -611,20 +362,6 @@ func (g *GDAX) Transfer(transferType string, amount float64, accountID string) e return nil } -type GDAXReportResponse struct { - ID string `json:"id"` - Type string `json:"type"` - Status string `json:"status"` - CreatedAt string `json:"created_at"` - CompletedAt string `json:"completed_at"` - ExpiresAt string `json:"expires_at"` - FileURL string `json:"file_url"` - Params struct { - StartDate string `json:"start_date"` - EndDate string `json:"end_date"` - } `json:params"` -} - func (g *GDAX) GetReport(reportType, startDate, endDate string) (GDAXReportResponse, error) { request := make(map[string]interface{}) request["type"] = reportType diff --git a/gdaxwebsocket.go b/exchanges/gdax/gdaxwebsocket.go similarity index 59% rename from gdaxwebsocket.go rename to exchanges/gdax/gdaxwebsocket.go index fc9fc33e..e83d8b34 100644 --- a/gdaxwebsocket.go +++ b/exchanges/gdax/gdaxwebsocket.go @@ -1,4 +1,4 @@ -package main +package gdax import ( "log" @@ -12,65 +12,6 @@ const ( GDAX_WEBSOCKET_URL = "wss://ws-feed.exchange.gdax.com" ) -type GDAXWebsocketSubscribe struct { - Type string `json:"type"` - ProductID string `json:"product_id"` -} - -type GDAXWebsocketReceived struct { - Type string `json:"type"` - Time string `json:"time"` - Sequence int `json:"sequence"` - OrderID string `json:"order_id"` - Size float64 `json:"size,string"` - Price float64 `json:"price,string"` - Side string `json:"side"` -} - -type GDAXWebsocketOpen struct { - Type string `json:"type"` - Time string `json:"time"` - Sequence int `json:"sequence"` - OrderID string `json:"order_id"` - Price float64 `json:"price,string"` - RemainingSize float64 `json:"remaining_size,string"` - Side string `json:"side"` -} - -type GDAXWebsocketDone struct { - Type string `json:"type"` - Time string `json:"time"` - Sequence int `json:"sequence"` - Price float64 `json:"price,string"` - OrderID string `json:"order_id"` - Reason string `json:"reason"` - Side string `json:"side"` - RemainingSize float64 `json:"remaining_size,string"` -} - -type GDAXWebsocketMatch struct { - Type string `json:"type"` - TradeID int `json:"trade_id"` - Sequence int `json:"sequence"` - MakerOrderID string `json:"maker_order_id"` - TakerOrderID string `json:"taker_order_id"` - Time string `json:"time"` - Size float64 `json:"size,string"` - Price float64 `json:"price,string"` - Side string `json:"side"` -} - -type GDAXWebsocketChange struct { - Type string `json:"type"` - Time string `json:"time"` - Sequence int `json:"sequence"` - OrderID string `json:"order_id"` - NewSize float64 `json:"new_size,string"` - OldSize float64 `json:"old_size,string"` - Price float64 `json:"price,string"` - Side string `json:"side"` -} - func (g *GDAX) WebsocketSubscribe(product string, conn *websocket.Conn) error { subscribe := GDAXWebsocketSubscribe{"subscribe", product} json, err := common.JSONEncode(subscribe) diff --git a/exchanges/gemini/gemini_types.go b/exchanges/gemini/gemini_types.go new file mode 100644 index 00000000..1e2ab074 --- /dev/null +++ b/exchanges/gemini/gemini_types.go @@ -0,0 +1,94 @@ +package gemini + +type GeminiOrderbookEntry struct { + Price float64 `json:"price,string"` + Quantity float64 `json:"quantity,string"` +} + +type GeminiOrderbook struct { + Bids []GeminiOrderbookEntry `json:"bids"` + Asks []GeminiOrderbookEntry `json:"asks"` +} + +type GeminiTrade struct { + Timestamp int64 `json:"timestamp"` + TID int64 `json:"tid"` + Price float64 `json:"price"` + Amount float64 `json:"amount"` + Side string `json:"taker"` +} + +type GeminiOrder struct { + OrderID int64 `json:"order_id"` + ClientOrderID string `json:"client_order_id"` + Symbol string `json:"symbol"` + Exchange string `json:"exchange"` + Price float64 `json:"price,string"` + AvgExecutionPrice float64 `json:"avg_execution_price,string"` + Side string `json:"side"` + Type string `json:"type"` + Timestamp int64 `json:"timestamp"` + TimestampMS int64 `json:"timestampms"` + IsLive bool `json:"is_live"` + IsCancelled bool `json:"is_cancelled"` + WasForced bool `json:"was_forced"` + ExecutedAmount float64 `json:"executed_amount,string"` + RemainingAmount float64 `json:"remaining_amount,string"` + OriginalAmount float64 `json:"original_amount,string"` +} + +type GeminiOrderResult struct { + Result bool `json:"result"` +} + +type GeminiTradeHistory struct { + Price float64 `json:"price"` + Amount float64 `json:"amount"` + Timestamp int64 `json:"timestamp"` + TimestampMS int64 `json:"timestampms"` + Type string `json:"type"` + FeeCurrency string `json:"fee_currency"` + FeeAmount float64 `json:"fee_amount"` + TID int64 `json:"tid"` + OrderID int64 `json:"order_id"` + ClientOrderID string `json:"client_order_id"` +} + +type GeminiBalance struct { + Currency string `json:"currency"` + Amount float64 `json:"amount"` + Available float64 `json:"available"` +} + +type GeminiTicker struct { + Ask float64 `json:"ask,string"` + Bid float64 `json:"bid,string"` + Last float64 `json:"last,string"` + Volume struct { + Currency float64 + USD float64 + Timestamp int64 + } +} + +type GeminiAuction struct { + LastAuctionPrice float64 `json:"last_auction_price,string"` + LastAuctionQuantity float64 `json:"last_auction_quantity,string"` + LastHighestBidPrice float64 `json:"last_highest_bid_price,string"` + LastLowestAskPrice float64 `json:"last_lowest_ask_price,string"` + NextUpdateMS int64 `json:"next_update_ms"` + NextAuctionMS int64 `json:"next_auction_ms"` + LastAuctionEID int64 `json:"last_auction_eid"` +} +type GeminiAuctionHistory struct { + AuctionID int64 `json:"auction_id"` + AuctionPrice float64 `json:"auction_price,string"` + AuctionQuantity float64 `json:"auction_quantity,string"` + EID int64 `json:"eid"` + HighestBidPrice float64 `json:"highest_bid_price,string"` + LowestAskPrice float64 `json:"lowest_ask_price,string"` + AuctionResult string `json:"auction_result"` + Timestamp int64 `json:"timestamp"` + TimestampMS int64 `json:"timestampms"` + EventType string `json:"event_type"` +} diff --git a/exchanges/gemini/gemini_wrapper.go b/exchanges/gemini/gemini_wrapper.go new file mode 100644 index 00000000..fbe1873f --- /dev/null +++ b/exchanges/gemini/gemini_wrapper.go @@ -0,0 +1,97 @@ +package gemini + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (g *Gemini) Start() { + go g.Run() +} + +func (g *Gemini) Run() { + if g.Verbose { + log.Printf("%s polling delay: %ds.\n", g.GetName(), g.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", g.GetName(), len(g.EnabledPairs), g.EnabledPairs) + } + + exchangeProducts, err := g.GetSymbols() + if err != nil { + log.Printf("%s Failed to get available symbols.\n", g.GetName()) + } else { + log.Println(exchangeProducts) + /* + exchangeProducts = common.SplitStrings(common.StringToUpper(common.JoinStrings(exchangeProducts, ",")), ",") + diff := common.StringSliceDifference(g.AvailablePairs, exchangeProducts) + if len(diff) > 0 { + exch, err := bot.config.GetExchangeConfig(g.Name) + if err != nil { + log.Println(err) + } else { + log.Printf("%s Updating available pairs. Difference: %s.\n", g.Name, diff) + exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",") + bot.config.UpdateExchangeConfig(exch) + } + } + */ + } + + for g.Enabled { + for _, x := range g.EnabledPairs { + currency := x + go func() { + ticker, err := g.GetTickerPrice(currency) + if err != nil { + log.Println(err) + return + } + log.Printf("Gemini %s Last %f Bid %f Ask %f Volume %f\n", currency, ticker.Last, ticker.Bid, ticker.Ask, ticker.Volume) + //AddExchangeInfo(g.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) + }() + } + time.Sleep(time.Second * g.RESTPollingDelay) + } +} + +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Gemini exchange +func (e *Gemini) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + accountBalance, err := e.GetBalances() + if err != nil { + return response, err + } + for i := 0; i < len(accountBalance); i++ { + var exchangeCurrency exchange.ExchangeAccountCurrencyInfo + exchangeCurrency.CurrencyName = accountBalance[i].Currency + exchangeCurrency.TotalValue = accountBalance[i].Amount + exchangeCurrency.Hold = accountBalance[i].Available + + response.Currencies = append(response.Currencies, exchangeCurrency) + } + return response, nil +} + +func (g *Gemini) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(g.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tickerNew, nil + } + + var tickerPrice ticker.TickerPrice + tick, err := g.GetTicker(currency) + if err != nil { + return tickerPrice, err + } + tickerPrice.Ask = tick.Ask + tickerPrice.Bid = tick.Bid + tickerPrice.FirstCurrency = currency[0:3] + tickerPrice.SecondCurrency = currency[3:] + tickerPrice.Last = tick.Last + tickerPrice.Volume = tick.Volume.USD + ticker.ProcessTicker(g.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} diff --git a/geminihttp.go b/exchanges/gemini/geminihttp.go similarity index 57% rename from geminihttp.go rename to exchanges/gemini/geminihttp.go index 5719ad61..e473bc7f 100644 --- a/geminihttp.go +++ b/exchanges/gemini/geminihttp.go @@ -1,4 +1,4 @@ -package main +package gemini import ( "errors" @@ -39,66 +39,6 @@ type Gemini struct { exchange.ExchangeBase } -type GeminiOrderbookEntry struct { - Price float64 `json:"price,string"` - Quantity float64 `json:"quantity,string"` -} - -type GeminiOrderbook struct { - Bids []GeminiOrderbookEntry `json:"bids"` - Asks []GeminiOrderbookEntry `json:"asks"` -} - -type GeminiTrade struct { - Timestamp int64 `json:"timestamp"` - TID int64 `json:"tid"` - Price float64 `json:"price"` - Amount float64 `json:"amount"` - Side string `json:"taker"` -} - -type GeminiOrder struct { - OrderID int64 `json:"order_id"` - ClientOrderID string `json:"client_order_id"` - Symbol string `json:"symbol"` - Exchange string `json:"exchange"` - Price float64 `json:"price,string"` - AvgExecutionPrice float64 `json:"avg_execution_price,string"` - Side string `json:"side"` - Type string `json:"type"` - Timestamp int64 `json:"timestamp"` - TimestampMS int64 `json:"timestampms"` - IsLive bool `json:"is_live"` - IsCancelled bool `json:"is_cancelled"` - WasForced bool `json:"was_forced"` - ExecutedAmount float64 `json:"executed_amount,string"` - RemainingAmount float64 `json:"remaining_amount,string"` - OriginalAmount float64 `json:"original_amount,string"` -} - -type GeminiOrderResult struct { - Result bool `json:"result"` -} - -type GeminiTradeHistory struct { - Price float64 `json:"price"` - Amount float64 `json:"amount"` - Timestamp int64 `json:"timestamp"` - TimestampMS int64 `json:"timestampms"` - Type string `json:"type"` - FeeCurrency string `json:"fee_currency"` - FeeAmount float64 `json:"fee_amount"` - TID int64 `json:"tid"` - OrderID int64 `json:"order_id"` - ClientOrderID string `json:"client_order_id"` -} - -type GeminiBalance struct { - Currency string `json:"currency"` - Amount float64 `json:"amount"` - Available float64 `json:"available"` -} - func (g *Gemini) SetDefaults() { g.Name = "Gemini" g.Enabled = false @@ -123,62 +63,6 @@ func (g *Gemini) Setup(exch config.ExchangeConfig) { } } -func (g *Gemini) Start() { - go g.Run() -} - -func (g *Gemini) Run() { - if g.Verbose { - log.Printf("%s polling delay: %ds.\n", g.GetName(), g.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", g.GetName(), len(g.EnabledPairs), g.EnabledPairs) - } - - exchangeProducts, err := g.GetSymbols() - if err != nil { - log.Printf("%s Failed to get available symbols.\n", g.GetName()) - } else { - exchangeProducts = common.SplitStrings(common.StringToUpper(common.JoinStrings(exchangeProducts, ",")), ",") - diff := common.StringSliceDifference(g.AvailablePairs, exchangeProducts) - if len(diff) > 0 { - exch, err := bot.config.GetExchangeConfig(g.Name) - if err != nil { - log.Println(err) - } else { - log.Printf("%s Updating available pairs. Difference: %s.\n", g.Name, diff) - exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",") - bot.config.UpdateExchangeConfig(exch) - } - } - } - - for g.Enabled { - for _, x := range g.EnabledPairs { - currency := x - go func() { - ticker, err := g.GetTickerPrice(currency) - if err != nil { - log.Println(err) - return - } - log.Printf("Gemini %s Last %f Bid %f Ask %f Volume %f\n", currency, ticker.Last, ticker.Bid, ticker.Ask, ticker.Volume) - AddExchangeInfo(g.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) - }() - } - time.Sleep(time.Second * g.RESTPollingDelay) - } -} - -type GeminiTicker struct { - Ask float64 `json:"ask,string"` - Bid float64 `json:"bid,string"` - Last float64 `json:"last,string"` - Volume struct { - Currency float64 - USD float64 - Timestamp int64 - } -} - func (g *Gemini) GetTicker(currency string) (GeminiTicker, error) { type TickerResponse struct { @@ -210,28 +94,6 @@ func (g *Gemini) GetTicker(currency string) (GeminiTicker, error) { return ticker, nil } -func (g *Gemini) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(g.GetName(), currency[0:3], currency[3:]) - if err == nil { - return tickerNew, nil - } - - var tickerPrice TickerPrice - ticker, err := g.GetTicker(currency) - if err != nil { - return tickerPrice, err - } - tickerPrice.Ask = ticker.Ask - tickerPrice.Bid = ticker.Bid - tickerPrice.FirstCurrency = currency[0:3] - tickerPrice.SecondCurrency = currency[3:] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Last = ticker.Last - tickerPrice.Volume = ticker.Volume.USD - ProcessTicker(g.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - func (g *Gemini) GetSymbols() ([]string, error) { symbols := []string{} path := fmt.Sprintf("%s/v%s/%s", GEMINI_API_URL, GEMINI_API_VERSION, GEMINI_SYMBOLS) @@ -242,16 +104,6 @@ func (g *Gemini) GetSymbols() ([]string, error) { return symbols, nil } -type GeminiAuction struct { - LastAuctionPrice float64 `json:"last_auction_price,string"` - LastAuctionQuantity float64 `json:"last_auction_quantity,string"` - LastHighestBidPrice float64 `json:"last_highest_bid_price,string"` - LastLowestAskPrice float64 `json:"last_lowest_ask_price,string"` - NextUpdateMS int64 `json:"next_update_ms"` - NextAuctionMS int64 `json:"next_auction_ms"` - LastAuctionEID int64 `json:"last_auction_eid"` -} - func (g *Gemini) GetAuction(currency string) (GeminiAuction, error) { path := fmt.Sprintf("%s/v%s/%s/%s", GEMINI_API_URL, GEMINI_API_VERSION, GEMINI_AUCTION, currency) auction := GeminiAuction{} @@ -262,19 +114,6 @@ func (g *Gemini) GetAuction(currency string) (GeminiAuction, error) { return auction, nil } -type GeminiAuctionHistory struct { - AuctionID int64 `json:"auction_id"` - AuctionPrice float64 `json:"auction_price,string"` - AuctionQuantity float64 `json:"auction_quantity,string"` - EID int64 `json:"eid"` - HighestBidPrice float64 `json:"highest_bid_price,string"` - LowestAskPrice float64 `json:"lowest_ask_price,string"` - AuctionResult string `json:"auction_result"` - Timestamp int64 `json:"timestamp"` - TimestampMS int64 `json:"timestampms"` - EventType string `json:"event_type"` -} - func (g *Gemini) GetAuctionHistory(currency string, params url.Values) ([]GeminiAuctionHistory, error) { path := common.EncodeURLValues(fmt.Sprintf("%s/v%s/%s/%s/%s", GEMINI_API_URL, GEMINI_API_VERSION, GEMINI_AUCTION, currency, GEMINI_AUCTION_HISTORY), params) auctionHist := []GeminiAuctionHistory{} @@ -391,25 +230,6 @@ func (g *Gemini) GetBalances() ([]GeminiBalance, error) { return response, nil } -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Gemini exchange -func (e *Gemini) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - accountBalance, err := e.GetBalances() - if err != nil { - return response, err - } - for i := 0; i < len(accountBalance); i++ { - var exchangeCurrency ExchangeAccountCurrencyInfo - exchangeCurrency.CurrencyName = accountBalance[i].Currency - exchangeCurrency.TotalValue = accountBalance[i].Amount - exchangeCurrency.Hold = accountBalance[i].Available - - response.Currencies = append(response.Currencies, exchangeCurrency) - } - return response, nil -} - func (g *Gemini) PostHeartbeat() (bool, error) { type Response struct { Result bool `json:"result"` @@ -452,7 +272,7 @@ func (g *Gemini) SendAuthenticatedHTTPRequest(method, path string, params map[st headers["X-GEMINI-PAYLOAD"] = PayloadBase64 headers["X-GEMINI-SIGNATURE"] = common.HexEncodeToString(hmac) - resp, err := common.SendHTTPRequest(method, BITFINEX_API_URL+path, headers, strings.NewReader("")) + resp, err := common.SendHTTPRequest(method, GEMINI_API_URL+path, headers, strings.NewReader("")) if g.Verbose { log.Printf("Recieved raw: \n%s\n", resp) diff --git a/exchanges/huobi/huobi_types.go b/exchanges/huobi/huobi_types.go new file mode 100644 index 00000000..1d3986aa --- /dev/null +++ b/exchanges/huobi/huobi_types.go @@ -0,0 +1,15 @@ +package huobi + +type HuobiTicker struct { + High float64 + Low float64 + Last float64 + Vol float64 + Buy float64 + Sell float64 +} + +type HuobiTickerResponse struct { + Time string + Ticker HuobiTicker +} diff --git a/exchanges/huobi/huobi_wrapper.go b/exchanges/huobi/huobi_wrapper.go new file mode 100644 index 00000000..bd7a8d5e --- /dev/null +++ b/exchanges/huobi/huobi_wrapper.go @@ -0,0 +1,80 @@ +package huobi + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (h *HUOBI) Start() { + go h.Run() +} + +func (h *HUOBI) Run() { + if h.Verbose { + log.Printf("%s Websocket: %s (url: %s).\n", h.GetName(), common.IsEnabled(h.Websocket), HUOBI_SOCKETIO_ADDRESS) + log.Printf("%s polling delay: %ds.\n", h.GetName(), h.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", h.GetName(), len(h.EnabledPairs), h.EnabledPairs) + } + + if h.Websocket { + go h.WebsocketClient() + } + + for h.Enabled { + for _, x := range h.EnabledPairs { + currency := common.StringToLower(x[0:3]) + go func() { + ticker, err := h.GetTickerPrice(currency) + if err != nil { + log.Println(err) + return + } + /* + HuobiLastUSD, _ := ConvertCurrency(ticker.Last, "CNY", "USD") + HuobiHighUSD, _ := ConvertCurrency(ticker.High, "CNY", "USD") + HuobiLowUSD, _ := ConvertCurrency(ticker.Low, "CNY", "USD") + log.Printf("Huobi %s: Last %f (%f) High %f (%f) Low %f (%f) Volume %f\n", currency, HuobiLastUSD, ticker.Last, HuobiHighUSD, ticker.High, HuobiLowUSD, ticker.Low, ticker.Volume) + AddExchangeInfo(h.GetName(), common.StringToUpper(currency[0:3]), common.StringToUpper(currency[3:]), ticker.Last, ticker.Volume) + AddExchangeInfo(h.GetName(), common.StringToUpper(currency[0:3]), "USD", HuobiLastUSD, ticker.Volume) + */ + log.Printf("Huobi %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) + }() + } + time.Sleep(time.Second * h.RESTPollingDelay) + } +} + +func (h *HUOBI) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(h.GetName(), common.StringToUpper(currency[0:3]), common.StringToUpper(currency[3:])) + if err == nil { + return tickerNew, nil + } + + var tickerPrice ticker.TickerPrice + tick, err := h.GetTicker(currency) + if err != nil { + return tickerPrice, err + } + tickerPrice.Ask = tick.Sell + tickerPrice.Bid = tick.Buy + tickerPrice.FirstCurrency = common.StringToUpper(currency[0:3]) + tickerPrice.SecondCurrency = common.StringToUpper(currency[3:]) + tickerPrice.Low = tick.Low + tickerPrice.Last = tick.Last + tickerPrice.Volume = tick.Vol + tickerPrice.High = tick.High + ticker.ProcessTicker(h.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +//TODO: retrieve HUOBI balance info +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the HUOBI exchange +func (e *HUOBI) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + return response, nil +} diff --git a/huobihttp.go b/exchanges/huobi/huobihttp.go similarity index 65% rename from huobihttp.go rename to exchanges/huobi/huobihttp.go index 1b2299f0..4387f8d8 100644 --- a/huobihttp.go +++ b/exchanges/huobi/huobihttp.go @@ -1,4 +1,4 @@ -package main +package huobi import ( "fmt" @@ -22,20 +22,6 @@ type HUOBI struct { exchange.ExchangeBase } -type HuobiTicker struct { - High float64 - Low float64 - Last float64 - Vol float64 - Buy float64 - Sell float64 -} - -type HuobiTickerResponse struct { - Time string - Ticker HuobiTicker -} - func (h *HUOBI) SetDefaults() { h.Name = "Huobi" h.Enabled = false @@ -61,46 +47,10 @@ func (h *HUOBI) Setup(exch config.ExchangeConfig) { } } -func (h *HUOBI) Start() { - go h.Run() -} - func (h *HUOBI) GetFee() float64 { return h.Fee } -func (h *HUOBI) Run() { - if h.Verbose { - log.Printf("%s Websocket: %s (url: %s).\n", h.GetName(), common.IsEnabled(h.Websocket), HUOBI_SOCKETIO_ADDRESS) - log.Printf("%s polling delay: %ds.\n", h.GetName(), h.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", h.GetName(), len(h.EnabledPairs), h.EnabledPairs) - } - - if h.Websocket { - go h.WebsocketClient() - } - - for h.Enabled { - for _, x := range h.EnabledPairs { - currency := common.StringToLower(x[0:3]) - go func() { - ticker, err := h.GetTickerPrice(currency) - if err != nil { - log.Println(err) - return - } - HuobiLastUSD, _ := ConvertCurrency(ticker.Last, "CNY", "USD") - HuobiHighUSD, _ := ConvertCurrency(ticker.High, "CNY", "USD") - HuobiLowUSD, _ := ConvertCurrency(ticker.Low, "CNY", "USD") - log.Printf("Huobi %s: Last %f (%f) High %f (%f) Low %f (%f) Volume %f\n", currency, HuobiLastUSD, ticker.Last, HuobiHighUSD, ticker.High, HuobiLowUSD, ticker.Low, ticker.Volume) - AddExchangeInfo(h.GetName(), common.StringToUpper(currency[0:3]), common.StringToUpper(currency[3:]), ticker.Last, ticker.Volume) - AddExchangeInfo(h.GetName(), common.StringToUpper(currency[0:3]), "USD", HuobiLastUSD, ticker.Volume) - }() - } - time.Sleep(time.Second * h.RESTPollingDelay) - } -} - func (h *HUOBI) GetTicker(symbol string) (HuobiTicker, error) { resp := HuobiTickerResponse{} path := fmt.Sprintf("http://api.huobi.com/staticmarket/ticker_%s_json.js", symbol) @@ -112,30 +62,6 @@ func (h *HUOBI) GetTicker(symbol string) (HuobiTicker, error) { return resp.Ticker, nil } -func (h *HUOBI) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(h.GetName(), common.StringToUpper(currency[0:3]), common.StringToUpper(currency[3:])) - if err == nil { - return tickerNew, nil - } - - var tickerPrice TickerPrice - ticker, err := h.GetTicker(currency) - if err != nil { - return tickerPrice, err - } - tickerPrice.Ask = ticker.Sell - tickerPrice.Bid = ticker.Buy - tickerPrice.FirstCurrency = common.StringToUpper(currency[0:3]) - tickerPrice.SecondCurrency = common.StringToUpper(currency[3:]) - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Low = ticker.Low - tickerPrice.Last = ticker.Last - tickerPrice.Volume = ticker.Vol - tickerPrice.High = ticker.High - ProcessTicker(h.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - func (h *HUOBI) GetOrderBook(symbol string) bool { path := fmt.Sprintf("http://api.huobi.com/staticmarket/depth_%s_json.js", symbol) err := common.SendHTTPGetRequest(path, true, nil) @@ -277,11 +203,3 @@ func (h *HUOBI) SendAuthenticatedRequest(method string, v url.Values) error { return nil } - -//TODO: retrieve HUOBI balance info -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the HUOBI exchange -func (e *HUOBI) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - return response, nil -} diff --git a/huobiwebsocket.go b/exchanges/huobi/huobiwebsocket.go similarity index 99% rename from huobiwebsocket.go rename to exchanges/huobi/huobiwebsocket.go index ef5e3bd4..1120afc8 100644 --- a/huobiwebsocket.go +++ b/exchanges/huobi/huobiwebsocket.go @@ -1,4 +1,4 @@ -package main +package huobi import ( "log" diff --git a/exchanges/itbit/itbit_types.go b/exchanges/itbit/itbit_types.go new file mode 100644 index 00000000..7814efa2 --- /dev/null +++ b/exchanges/itbit/itbit_types.go @@ -0,0 +1,34 @@ +package itbit + +type ItBitTicker struct { + Pair string + Bid float64 `json:",string"` + BidAmt float64 `json:",string"` + Ask float64 `json:",string"` + AskAmt float64 `json:",string"` + LastPrice float64 `json:",string"` + LastAmt float64 `json:",string"` + Volume24h float64 `json:",string"` + VolumeToday float64 `json:",string"` + High24h float64 `json:",string"` + Low24h float64 `json:",string"` + HighToday float64 `json:",string"` + LowToday float64 `json:",string"` + OpenToday float64 `json:",string"` + VwapToday float64 `json:",string"` + Vwap24h float64 `json:",string"` + ServertimeUTC string +} + +type ItbitOrderbookEntry struct { + Quantitiy float64 `json:"quantity,string"` + Price float64 `json:"price,string"` +} + +type ItBitOrderbookResponse struct { + ServerTimeUTC string `json:"serverTimeUTC"` + LastUpdatedTimeUTC string `json:"lastUpdatedTimeUTC"` + Ticker string `json:"ticker"` + Bids []ItbitOrderbookEntry `json:"bids"` + Asks []ItbitOrderbookEntry `json:"asks"` +} diff --git a/exchanges/itbit/itbit_wrapper.go b/exchanges/itbit/itbit_wrapper.go new file mode 100644 index 00000000..29a4400b --- /dev/null +++ b/exchanges/itbit/itbit_wrapper.go @@ -0,0 +1,67 @@ +package itbit + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (i *ItBit) Start() { + go i.Run() +} +func (i *ItBit) Run() { + if i.Verbose { + log.Printf("%s polling delay: %ds.\n", i.GetName(), i.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", i.GetName(), len(i.EnabledPairs), i.EnabledPairs) + } + + for i.Enabled { + for _, x := range i.EnabledPairs { + currency := x + go func() { + ticker, err := i.GetTickerPrice(currency) + if err != nil { + log.Println(err) + return + } + log.Printf("ItBit %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) + //AddExchangeInfo(i.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) + }() + } + time.Sleep(time.Second * i.RESTPollingDelay) + } +} + +func (i *ItBit) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(i.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tickerNew, nil + } + + var tickerPrice ticker.TickerPrice + tick, err := i.GetTicker(currency) + if err != nil { + return tickerPrice, err + } + + tickerPrice.Ask = tick.Ask + tickerPrice.Bid = tick.Bid + tickerPrice.FirstCurrency = currency[0:3] + tickerPrice.SecondCurrency = currency[3:] + tickerPrice.Last = tick.LastPrice + tickerPrice.High = tick.High24h + tickerPrice.Low = tick.Low24h + tickerPrice.Volume = tick.Volume24h + ticker.ProcessTicker(i.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +//TODO Get current holdings from ItBit +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the ItBit exchange +func (e *ItBit) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + return response, nil +} diff --git a/itbithttp.go b/exchanges/itbit/itbithttp.go similarity index 70% rename from itbithttp.go rename to exchanges/itbit/itbithttp.go index b502be01..2351b562 100644 --- a/itbithttp.go +++ b/exchanges/itbit/itbithttp.go @@ -1,4 +1,4 @@ -package main +package itbit import ( "bytes" @@ -22,26 +22,6 @@ type ItBit struct { exchange.ExchangeBase } -type ItBitTicker struct { - Pair string - Bid float64 `json:",string"` - BidAmt float64 `json:",string"` - Ask float64 `json:",string"` - AskAmt float64 `json:",string"` - LastPrice float64 `json:",string"` - LastAmt float64 `json:",string"` - Volume24h float64 `json:",string"` - VolumeToday float64 `json:",string"` - High24h float64 `json:",string"` - Low24h float64 `json:",string"` - HighToday float64 `json:",string"` - LowToday float64 `json:",string"` - OpenToday float64 `json:",string"` - VwapToday float64 `json:",string"` - Vwap24h float64 `json:",string"` - ServertimeUTC string -} - func (i *ItBit) SetDefaults() { i.Name = "ITBIT" i.Enabled = false @@ -68,10 +48,6 @@ func (i *ItBit) Setup(exch config.ExchangeConfig) { } } -func (i *ItBit) Start() { - go i.Run() -} - func (i *ItBit) GetFee(maker bool) float64 { if maker { return i.MakerFee @@ -80,29 +56,6 @@ func (i *ItBit) GetFee(maker bool) float64 { } } -func (i *ItBit) Run() { - if i.Verbose { - log.Printf("%s polling delay: %ds.\n", i.GetName(), i.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", i.GetName(), len(i.EnabledPairs), i.EnabledPairs) - } - - for i.Enabled { - for _, x := range i.EnabledPairs { - currency := x - go func() { - ticker, err := i.GetTickerPrice(currency) - if err != nil { - log.Println(err) - return - } - log.Printf("ItBit %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) - AddExchangeInfo(i.GetName(), currency[0:3], currency[3:], ticker.Last, ticker.Volume) - }() - } - time.Sleep(time.Second * i.RESTPollingDelay) - } -} - func (i *ItBit) GetTicker(currency string) (ItBitTicker, error) { path := ITBIT_API_URL + "/markets/" + currency + "/ticker" var itbitTicker ItBitTicker @@ -113,44 +66,6 @@ func (i *ItBit) GetTicker(currency string) (ItBitTicker, error) { return itbitTicker, nil } -func (i *ItBit) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(i.GetName(), currency[0:3], currency[3:]) - if err == nil { - return tickerNew, nil - } - - var tickerPrice TickerPrice - ticker, err := i.GetTicker(currency) - if err != nil { - return tickerPrice, err - } - - tickerPrice.Ask = ticker.Ask - tickerPrice.Bid = ticker.Bid - tickerPrice.FirstCurrency = currency[0:3] - tickerPrice.SecondCurrency = currency[3:] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Last = ticker.LastPrice - tickerPrice.High = ticker.High24h - tickerPrice.Low = ticker.Low24h - tickerPrice.Volume = ticker.Volume24h - ProcessTicker(i.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - -type ItbitOrderbookEntry struct { - Quantitiy float64 `json:"quantity,string"` - Price float64 `json:"price,string"` -} - -type ItBitOrderbookResponse struct { - ServerTimeUTC string `json:"serverTimeUTC"` - LastUpdatedTimeUTC string `json:"lastUpdatedTimeUTC"` - Ticker string `json:"ticker"` - Bids []ItbitOrderbookEntry `json:"bids"` - Asks []ItbitOrderbookEntry `json:"asks"` -} - func (i *ItBit) GetOrderbook(currency string) (ItBitOrderbookResponse, error) { response := ItBitOrderbookResponse{} path := ITBIT_API_URL + "/markets/" + currency + "/order_book" @@ -182,14 +97,6 @@ func (i *ItBit) GetWallets(params url.Values) { } } -//TODO Get current holdings from ItBit -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the ItBit exchange -func (e *ItBit) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - return response, nil -} - func (i *ItBit) CreateWallet(walletName string) { path := "/wallets" params := make(map[string]interface{}) diff --git a/kraken.go b/exchanges/kraken/kraken.go similarity index 78% rename from kraken.go rename to exchanges/kraken/kraken.go index 7cb18aa6..56f6d4a7 100644 --- a/kraken.go +++ b/exchanges/kraken/kraken.go @@ -1,4 +1,4 @@ -package main +package kraken import ( "errors" @@ -73,10 +73,6 @@ func (k *Kraken) Setup(exch config.ExchangeConfig) { } } -func (k *Kraken) Start() { - go k.Run() -} - func (k *Kraken) GetFee(cryptoTrade bool) float64 { if cryptoTrade { return k.CryptoFee @@ -85,48 +81,6 @@ func (k *Kraken) GetFee(cryptoTrade bool) float64 { } } -func (k *Kraken) Run() { - if k.Verbose { - log.Printf("%s polling delay: %ds.\n", k.GetName(), k.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", k.GetName(), len(k.EnabledPairs), k.EnabledPairs) - } - - assetPairs, err := k.GetAssetPairs() - if err != nil { - log.Printf("%s Failed to get available symbols.\n", k.GetName()) - } else { - var exchangeProducts []string - for _, v := range assetPairs { - exchangeProducts = append(exchangeProducts, v.Altname) - } - diff := common.StringSliceDifference(k.AvailablePairs, exchangeProducts) - if len(diff) > 0 { - exch, err := bot.config.GetExchangeConfig(k.Name) - if err != nil { - log.Println(err) - } else { - log.Printf("%s Updating available pairs. Difference: %s.\n", k.Name, diff) - exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",") - bot.config.UpdateExchangeConfig(exch) - } - } - } - - for k.Enabled { - err := k.GetTicker(common.JoinStrings(k.EnabledPairs, ",")) - if err != nil { - log.Println(err) - } else { - for _, x := range k.EnabledPairs { - ticker := k.Ticker[x] - log.Printf("Kraken %s Last %f High %f Low %f Volume %f\n", x, ticker.Last, ticker.High, ticker.Low, ticker.Volume) - AddExchangeInfo(k.GetName(), x[0:3], x[3:], ticker.Last, ticker.Volume) - } - } - time.Sleep(time.Second * k.RESTPollingDelay) - } -} - func (k *Kraken) GetServerTime() error { var result interface{} path := fmt.Sprintf("%s/%s/public/%s", KRAKEN_API_URL, KRAKEN_API_VERSION, KRAKEN_SERVER_TIME) @@ -153,25 +107,6 @@ func (k *Kraken) GetAssets() error { return nil } -type KrakenAssetPairs struct { - Altname string `json:"altname"` - AclassBase string `json:"aclass_base"` - Base string `json:"base"` - AclassQuote string `json:"aclass_quote"` - Quote string `json:"quote"` - Lot string `json:"lot"` - PairDecimals int `json:"pair_decimals"` - LotDecimals int `json:"lot_decimals"` - LotMultiplier int `json:"lot_multiplier"` - LeverageBuy []int `json:"leverage_buy"` - LeverageSell []int `json:"leverage_sell"` - Fees [][]float64 `json:"fees"` - FeesMaker [][]float64 `json:"fees_maker"` - FeeVolumeCurrency string `json:"fee_volume_currency"` - MarginCall int `json:"margin_call"` - MarginStop int `json:"margin_stop"` -} - func (k *Kraken) GetAssetPairs() (map[string]KrakenAssetPairs, error) { type Response struct { Result map[string]KrakenAssetPairs `json:"result"` @@ -189,30 +124,6 @@ func (k *Kraken) GetAssetPairs() (map[string]KrakenAssetPairs, error) { return response.Result, nil } -type KrakenTicker struct { - Ask float64 - Bid float64 - Last float64 - Volume float64 - VWAP float64 - Trades int64 - Low float64 - High float64 - Open float64 -} - -type KrakenTickerResponse struct { - Ask []string `json:"a"` - Bid []string `json:"b"` - Last []string `json:"c"` - Volume []string `json:"v"` - VWAP []string `json:"p"` - Trades []int64 `json:"t"` - Low []string `json:"l"` - High []string `json:"h"` - Open string `json:"o"` -} - func (k *Kraken) GetTicker(symbol string) error { values := url.Values{} values.Set("pair", symbol) @@ -251,21 +162,6 @@ 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, error) { - 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, nil -} - func (k *Kraken) GetOHLC(symbol string) error { values := url.Values{} values.Set("pair", symbol) @@ -339,14 +235,6 @@ func (k *Kraken) GetBalance() { log.Println(result) } -//TODO: Retrieve Kraken info -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Kraken exchange -func (e *Kraken) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - return response, nil -} - func (k *Kraken) GetTradeBalance(symbol, asset string) { values := url.Values{} diff --git a/exchanges/kraken/kraken_types.go b/exchanges/kraken/kraken_types.go new file mode 100644 index 00000000..f1ec460d --- /dev/null +++ b/exchanges/kraken/kraken_types.go @@ -0,0 +1,44 @@ +package kraken + +type KrakenAssetPairs struct { + Altname string `json:"altname"` + AclassBase string `json:"aclass_base"` + Base string `json:"base"` + AclassQuote string `json:"aclass_quote"` + Quote string `json:"quote"` + Lot string `json:"lot"` + PairDecimals int `json:"pair_decimals"` + LotDecimals int `json:"lot_decimals"` + LotMultiplier int `json:"lot_multiplier"` + LeverageBuy []int `json:"leverage_buy"` + LeverageSell []int `json:"leverage_sell"` + Fees [][]float64 `json:"fees"` + FeesMaker [][]float64 `json:"fees_maker"` + FeeVolumeCurrency string `json:"fee_volume_currency"` + MarginCall int `json:"margin_call"` + MarginStop int `json:"margin_stop"` +} + +type KrakenTicker struct { + Ask float64 + Bid float64 + Last float64 + Volume float64 + VWAP float64 + Trades int64 + Low float64 + High float64 + Open float64 +} + +type KrakenTickerResponse struct { + Ask []string `json:"a"` + Bid []string `json:"b"` + Last []string `json:"c"` + Volume []string `json:"v"` + VWAP []string `json:"p"` + Trades []int64 `json:"t"` + Low []string `json:"l"` + High []string `json:"h"` + Open string `json:"o"` +} diff --git a/exchanges/kraken/kraken_wrapper.go b/exchanges/kraken/kraken_wrapper.go new file mode 100644 index 00000000..776698f2 --- /dev/null +++ b/exchanges/kraken/kraken_wrapper.go @@ -0,0 +1,82 @@ +package kraken + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (k *Kraken) Start() { + go k.Run() +} + +func (k *Kraken) Run() { + if k.Verbose { + log.Printf("%s polling delay: %ds.\n", k.GetName(), k.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", k.GetName(), len(k.EnabledPairs), k.EnabledPairs) + } + + assetPairs, err := k.GetAssetPairs() + if err != nil { + log.Printf("%s Failed to get available symbols.\n", k.GetName()) + } else { + log.Println(assetPairs) + /* + var exchangeProducts []string + for _, v := range assetPairs { + exchangeProducts = append(exchangeProducts, v.Altname) + } + diff := common.StringSliceDifference(k.AvailablePairs, exchangeProducts) + if len(diff) > 0 { + exch, err := bot.config.GetExchangeConfig(k.Name) + if err != nil { + log.Println(err) + } else { + log.Printf("%s Updating available pairs. Difference: %s.\n", k.Name, diff) + exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",") + bot.config.UpdateExchangeConfig(exch) + } + } + */ + } + + for k.Enabled { + err := k.GetTicker(common.JoinStrings(k.EnabledPairs, ",")) + if err != nil { + log.Println(err) + } else { + for _, x := range k.EnabledPairs { + ticker := k.Ticker[x] + log.Printf("Kraken %s Last %f High %f Low %f Volume %f\n", x, ticker.Last, ticker.High, ticker.Low, ticker.Volume) + //AddExchangeInfo(k.GetName(), x[0:3], x[3:], ticker.Last, ticker.Volume) + } + } + time.Sleep(time.Second * k.RESTPollingDelay) + } +} + +//This will return the TickerPrice struct when tickers are completed here.. +func (k *Kraken) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + var tickerPrice ticker.TickerPrice + /* + ticker, err := i.GetTicker(currency) + if err != nil { + log.Println(err) + return tickerPrice + } + tickerPrice.Ask = ticker.Ask + tickerPrice.Bid = ticker.Bid + */ + return tickerPrice, nil +} + +//TODO: Retrieve Kraken info +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Kraken exchange +func (e *Kraken) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + return response, nil +} diff --git a/exchanges/lakebtc/lakebtc_types.go b/exchanges/lakebtc/lakebtc_types.go new file mode 100644 index 00000000..ea8a7455 --- /dev/null +++ b/exchanges/lakebtc/lakebtc_types.go @@ -0,0 +1,100 @@ +package lakebtc + +type LakeBTCTicker struct { + Last float64 + Bid float64 + Ask float64 + High float64 + Low float64 + Volume float64 +} + +type LakeBTCOrderbookStructure struct { + Price float64 + Amount float64 +} + +type LakeBTCOrderbook struct { + Bids []LakeBTCOrderbookStructure `json:"bids"` + Asks []LakeBTCOrderbookStructure `json:"asks"` +} + +/* Silly hack due to API returning null instead of strings */ +type LakeBTCTickerResponse struct { + Last interface{} + Bid interface{} + Ask interface{} + High interface{} + Low interface{} + Volume interface{} +} + +type LakeBTCTradeHistory struct { + Date int64 `json:"data"` + Price float64 `json:"price,string"` + Amount float64 `json:"amount,string"` + TID int64 `json:"tid"` +} + +type LakeBTCAccountInfo struct { + Balance map[string]string `json:"balance"` + Locked map[string]string `json:"locked"` + Profile struct { + Email string `json:"email"` + UID string `json:"uid"` + BTCDepositAddress string `json:"btc_deposit_addres"` + } `json:"profile"` +} + +type LakeBTCTrade struct { + ID int64 `json:"id"` + Result string `json:"result"` +} + +type LakeBTCOpenOrders struct { + ID int64 `json:"id"` + Amount float64 `json:"amount,string"` + Price float64 `json:"price,string"` + Symbol string `json:"symbol"` + Type string `json:"type"` + At int64 `json:"at"` +} + +type LakeBTCOrders struct { + ID int64 `json:"id"` + OriginalAmount float64 `json:"original_amount,string"` + Amount float64 `json:"amount,string"` + Price float64 `json:"price,string"` + Symbol string `json:"symbol"` + Type string `json:"type"` + State string `json:"state"` + At int64 `json:"at"` +} + +type LakeBTCAuthenticaltedTradeHistory struct { + Type string `json:"type"` + Symbol string `json:"symbol"` + Amount float64 `json:"amount,string"` + Total float64 `json:"total,string"` + At int64 `json:"at"` +} +type LakeBTCExternalAccounts struct { + ID int64 `json:"id,string"` + Type string `json:"type"` + Address string `json:"address"` + Alias interface{} `json:"alias"` + Currencies string `json:"currencies"` + State string `json:"state"` + UpdatedAt int64 `json:"updated_at,string"` +} + +type LakeBTCWithdraw struct { + ID int64 `json:"id,string"` + Amount float64 `json:"amount,string"` + Currency string `json:"currency"` + Fee float64 `json:"fee,string"` + State string `json:"state"` + Source string `json:"source"` + ExternalAccountID int64 `json:"external_account_id,string"` + At int64 `json:"at"` +} diff --git a/exchanges/lakebtc/lakebtc_wrapper.go b/exchanges/lakebtc/lakebtc_wrapper.go new file mode 100644 index 00000000..4119135e --- /dev/null +++ b/exchanges/lakebtc/lakebtc_wrapper.go @@ -0,0 +1,85 @@ +package lakebtc + +import ( + "log" + "strconv" + "time" + + "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (l *LakeBTC) Start() { + go l.Run() +} +func (l *LakeBTC) Run() { + if l.Verbose { + log.Printf("%s polling delay: %ds.\n", l.GetName(), l.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", l.GetName(), len(l.EnabledPairs), l.EnabledPairs) + } + + for l.Enabled { + for _, x := range l.EnabledPairs { + ticker, err := l.GetTickerPrice(x) + if err != nil { + log.Println(err) + continue + } + log.Printf("LakeBTC BTC %s: Last %f High %f Low %f Volume %f\n", x[3:], ticker.Last, ticker.High, ticker.Low, ticker.Volume) + //AddExchangeInfo(l.GetName(), x[0:3], x[3:], ticker.Last, ticker.Volume) + } + time.Sleep(time.Second * l.RESTPollingDelay) + } +} + +func (l *LakeBTC) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(l.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tickerNew, nil + } + + tick, err := l.GetTicker() + if err != nil { + return ticker.TickerPrice{}, err + } + + result, ok := tick[currency] + if !ok { + return ticker.TickerPrice{}, err + } + + var tickerPrice ticker.TickerPrice + tickerPrice.Ask = result.Ask + tickerPrice.Bid = result.Bid + tickerPrice.Volume = result.Volume + tickerPrice.High = result.High + tickerPrice.Low = result.Low + tickerPrice.Last = result.Last + tickerPrice.FirstCurrency = currency[0:3] + tickerPrice.SecondCurrency = currency[3:] + ticker.ProcessTicker(l.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +func (l *LakeBTC) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = l.GetName() + accountInfo, err := l.GetAccountInfo() + if err != nil { + return response, err + } + + for x, y := range accountInfo.Balance { + for z, w := range accountInfo.Locked { + if z == x { + var exchangeCurrency exchange.ExchangeAccountCurrencyInfo + exchangeCurrency.CurrencyName = common.StringToUpper(x) + exchangeCurrency.TotalValue, _ = strconv.ParseFloat(y, 64) + exchangeCurrency.Hold, _ = strconv.ParseFloat(w, 64) + response.Currencies = append(response.Currencies, exchangeCurrency) + } + } + } + return response, nil +} diff --git a/lakebtchttp.go b/exchanges/lakebtc/lakebtchttp.go similarity index 63% rename from lakebtchttp.go rename to exchanges/lakebtc/lakebtchttp.go index b8a9c955..0559c7e7 100644 --- a/lakebtchttp.go +++ b/exchanges/lakebtc/lakebtchttp.go @@ -1,4 +1,4 @@ -package main +package lakebtc import ( "errors" @@ -34,25 +34,6 @@ type LakeBTC struct { exchange.ExchangeBase } -type LakeBTCTicker struct { - Last float64 - Bid float64 - Ask float64 - High float64 - Low float64 - Volume float64 -} - -type LakeBTCOrderbookStructure struct { - Price float64 - Amount float64 -} - -type LakeBTCOrderbook struct { - Bids []LakeBTCOrderbookStructure `json:"bids"` - Asks []LakeBTCOrderbookStructure `json:"asks"` -} - func (l *LakeBTC) SetDefaults() { l.Name = "LakeBTC" l.Enabled = false @@ -79,10 +60,6 @@ func (l *LakeBTC) Setup(exch config.ExchangeConfig) { } } -func (l *LakeBTC) Start() { - go l.Run() -} - func (l *LakeBTC) GetFee(maker bool) float64 { if maker { return l.MakerFee @@ -91,36 +68,6 @@ func (l *LakeBTC) GetFee(maker bool) float64 { } } -func (l *LakeBTC) Run() { - if l.Verbose { - log.Printf("%s polling delay: %ds.\n", l.GetName(), l.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", l.GetName(), len(l.EnabledPairs), l.EnabledPairs) - } - - for l.Enabled { - for _, x := range l.EnabledPairs { - ticker, err := l.GetTickerPrice(x) - if err != nil { - log.Println(err) - continue - } - log.Printf("LakeBTC BTC %s: Last %f High %f Low %f Volume %f\n", x[3:], ticker.Last, ticker.High, ticker.Low, ticker.Volume) - AddExchangeInfo(l.GetName(), x[0:3], x[3:], ticker.Last, ticker.Volume) - } - time.Sleep(time.Second * l.RESTPollingDelay) - } -} - -/* Silly hack due to API returning null instead of strings */ -type LakeBTCTickerResponse struct { - Last interface{} - Bid interface{} - Ask interface{} - High interface{} - Low interface{} - Volume interface{} -} - func (l *LakeBTC) GetTicker() (map[string]LakeBTCTicker, error) { response := make(map[string]LakeBTCTickerResponse) path := fmt.Sprintf("%s/%s", LAKEBTC_API_URL, LAKEBTC_TICKER) @@ -158,36 +105,6 @@ func (l *LakeBTC) GetTicker() (map[string]LakeBTCTicker, error) { return result, nil } -func (l *LakeBTC) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(l.GetName(), currency[0:3], currency[3:]) - if err == nil { - return tickerNew, nil - } - - ticker, err := l.GetTicker() - if err != nil { - return TickerPrice{}, err - } - - result, ok := ticker[currency] - if !ok { - return TickerPrice{}, err - } - - var tickerPrice TickerPrice - tickerPrice.Ask = result.Ask - tickerPrice.Bid = result.Bid - tickerPrice.Volume = result.Volume - tickerPrice.High = result.High - tickerPrice.Low = result.Low - tickerPrice.Last = result.Last - tickerPrice.FirstCurrency = currency[0:3] - tickerPrice.SecondCurrency = currency[3:] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - ProcessTicker(l.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - func (l *LakeBTC) GetOrderBook(currency string) (LakeBTCOrderbook, error) { type Response struct { Bids [][]string `json:"bids"` @@ -231,13 +148,6 @@ func (l *LakeBTC) GetOrderBook(currency string) (LakeBTCOrderbook, error) { return orderbook, nil } -type LakeBTCTradeHistory struct { - Date int64 `json:"data"` - Price float64 `json:"price,string"` - Amount float64 `json:"amount,string"` - TID int64 `json:"tid"` -} - func (l *LakeBTC) GetTradeHistory(currency string) ([]LakeBTCTradeHistory, error) { path := fmt.Sprintf("%s/%s?symbol=%s", LAKEBTC_API_URL, LAKEBTC_TRADES, common.StringToLower(currency)) resp := []LakeBTCTradeHistory{} @@ -248,16 +158,6 @@ func (l *LakeBTC) GetTradeHistory(currency string) ([]LakeBTCTradeHistory, error return resp, nil } -type LakeBTCAccountInfo struct { - Balance map[string]string `json:"balance"` - Locked map[string]string `json:"locked"` - Profile struct { - Email string `json:"email"` - UID string `json:"uid"` - BTCDepositAddress string `json:"btc_deposit_addres"` - } `json:"profile"` -} - func (l *LakeBTC) GetAccountInfo() (LakeBTCAccountInfo, error) { resp := LakeBTCAccountInfo{} err := l.SendAuthenticatedHTTPRequest(LAKEBTC_GET_ACCOUNT_INFO, "", &resp) @@ -269,33 +169,6 @@ func (l *LakeBTC) GetAccountInfo() (LakeBTCAccountInfo, error) { return resp, nil } -func (l *LakeBTC) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = l.GetName() - accountInfo, err := l.GetAccountInfo() - if err != nil { - return response, err - } - - for x, y := range accountInfo.Balance { - for z, w := range accountInfo.Locked { - if z == x { - var exchangeCurrency ExchangeAccountCurrencyInfo - exchangeCurrency.CurrencyName = common.StringToUpper(x) - exchangeCurrency.TotalValue, _ = strconv.ParseFloat(y, 64) - exchangeCurrency.Hold, _ = strconv.ParseFloat(w, 64) - response.Currencies = append(response.Currencies, exchangeCurrency) - } - } - } - return response, nil -} - -type LakeBTCTrade struct { - ID int64 `json:"id"` - Result string `json:"result"` -} - func (l *LakeBTC) Trade(orderType int, amount, price float64, currency string) (LakeBTCTrade, error) { resp := LakeBTCTrade{} params := strconv.FormatFloat(price, 'f', -1, 64) + "," + strconv.FormatFloat(amount, 'f', -1, 64) + "," + currency @@ -318,15 +191,6 @@ func (l *LakeBTC) Trade(orderType int, amount, price float64, currency string) ( return resp, nil } -type LakeBTCOpenOrders struct { - ID int64 `json:"id"` - Amount float64 `json:"amount,string"` - Price float64 `json:"price,string"` - Symbol string `json:"symbol"` - Type string `json:"type"` - At int64 `json:"at"` -} - func (l *LakeBTC) GetOpenOrders() ([]LakeBTCOpenOrders, error) { orders := []LakeBTCOpenOrders{} err := l.SendAuthenticatedHTTPRequest(LAKEBTC_OPEN_ORDERS, "", &orders) @@ -337,17 +201,6 @@ func (l *LakeBTC) GetOpenOrders() ([]LakeBTCOpenOrders, error) { return orders, nil } -type LakeBTCOrders struct { - ID int64 `json:"id"` - OriginalAmount float64 `json:"original_amount,string"` - Amount float64 `json:"amount,string"` - Price float64 `json:"price,string"` - Symbol string `json:"symbol"` - Type string `json:"type"` - State string `json:"state"` - At int64 `json:"at"` -} - func (l *LakeBTC) GetOrders(orders []int64) ([]LakeBTCOrders, error) { var ordersStr []string for _, x := range orders { @@ -382,14 +235,6 @@ func (l *LakeBTC) CancelOrder(orderID int64) error { return nil } -type LakeBTCAuthenticaltedTradeHistory struct { - Type string `json:"type"` - Symbol string `json:"symbol"` - Amount float64 `json:"amount,string"` - Total float64 `json:"total,string"` - At int64 `json:"at"` -} - func (l *LakeBTC) GetTrades(timestamp int64) ([]LakeBTCAuthenticaltedTradeHistory, error) { params := "" if timestamp != 0 { @@ -405,16 +250,6 @@ func (l *LakeBTC) GetTrades(timestamp int64) ([]LakeBTCAuthenticaltedTradeHistor return trades, nil } -type LakeBTCExternalAccounts struct { - ID int64 `json:"id,string"` - Type string `json:"type"` - Address string `json:"address"` - Alias interface{} `json:"alias"` - Currencies string `json:"currencies"` - State string `json:"state"` - UpdatedAt int64 `json:"updated_at,string"` -} - /* Only for BTC */ func (l *LakeBTC) GetExternalAccounts() ([]LakeBTCExternalAccounts, error) { resp := []LakeBTCExternalAccounts{} @@ -425,17 +260,6 @@ func (l *LakeBTC) GetExternalAccounts() ([]LakeBTCExternalAccounts, error) { return resp, nil } -type LakeBTCWithdraw struct { - ID int64 `json:"id,string"` - Amount float64 `json:"amount,string"` - Currency string `json:"currency"` - Fee float64 `json:"fee,string"` - State string `json:"state"` - Source string `json:"source"` - ExternalAccountID int64 `json:"external_account_id,string"` - At int64 `json:"at"` -} - /* Only for BTC */ func (l *LakeBTC) CreateWithdraw(amount float64, accountID int64) (LakeBTCWithdraw, error) { resp := LakeBTCWithdraw{} diff --git a/exchanges/liqui/liqui_types.go b/exchanges/liqui/liqui_types.go new file mode 100644 index 00000000..bf25573d --- /dev/null +++ b/exchanges/liqui/liqui_types.go @@ -0,0 +1,105 @@ +package liqui + +type LiquiTicker struct { + High float64 + Low float64 + Avg float64 + Vol float64 + Vol_cur float64 + Last float64 + Buy float64 + Sell float64 + Updated int64 +} + +type LiquiOrderbook struct { + Asks [][]float64 `json:"asks"` + Bids [][]float64 `json:"bids"` +} + +type LiquiTrades struct { + Type string `json:"type"` + Price float64 `json:"bid"` + Amount float64 `json:"amount"` + TID int64 `json:"tid"` + Timestamp int64 `json:"timestamp"` +} + +type LiquiResponse struct { + Return interface{} `json:"return"` + Success int `json:"success"` + Error string `json:"error"` +} + +type LiquiPair struct { + DecimalPlaces int `json:"decimal_places"` + MinPrice float64 `json:"min_price"` + MaxPrice float64 `json:"max_price"` + MinAmount float64 `json:"min_amount"` + Hidden int `json:"hidden"` + Fee float64 `json:"fee"` +} + +type LiquiInfo struct { + ServerTime int64 `json:"server_time"` + Pairs map[string]LiquiPair `json:"pairs"` +} + +type LiquiAccountInfo struct { + Funds map[string]float64 `json:"funds"` + Rights struct { + Info bool `json:"info"` + Trade bool `json:"trade"` + Withdraw bool `json:"withdraw"` + } `json:"rights"` + ServerTime float64 `json:"server_time"` + TransactionCount int `json:"transaction_count"` + OpenOrders int `json:"open_orders"` +} + +type LiquiTrade struct { + Received float64 `json:"received"` + Remains float64 `json:"remains"` + OrderID float64 `json:"order_id"` + Funds map[string]float64 `json:"funds"` +} + +type LiquiActiveOrders struct { + Pair string `json:"pair"` + Type string `json:"sell"` + Amount float64 `json:"amount"` + Rate float64 `json:"rate"` + TimestampCreated float64 `json:"time_created"` + Status int `json:"status"` +} + +type LiquiOrderInfo struct { + Pair string `json:"pair"` + Type string `json:"sell"` + StartAmount float64 `json:"start_amount"` + Amount float64 `json:"amount"` + Rate float64 `json:"rate"` + TimestampCreated float64 `json:"time_created"` + Status int `json:"status"` +} + +type LiquiCancelOrder struct { + OrderID float64 `json:"order_id"` + Funds map[string]float64 `json:"funds"` +} + +type LiquiTradeHistory struct { + Pair string `json:"pair"` + Type string `json:"type"` + Amount float64 `json:"amount"` + Rate float64 `json:"rate"` + OrderID float64 `json:"order_id"` + MyOrder int `json:"is_your_order"` + Timestamp float64 `json:"timestamp"` +} + +type LiquiWithdrawCoins struct { + TID int64 `json:"tId"` + AmountSent float64 `json:"amountSent"` + Funds map[string]float64 `json:"funds"` +} diff --git a/exchanges/liqui/liqui_wrapper.go b/exchanges/liqui/liqui_wrapper.go new file mode 100644 index 00000000..5659db24 --- /dev/null +++ b/exchanges/liqui/liqui_wrapper.go @@ -0,0 +1,109 @@ +package liqui + +import ( + "errors" + "log" + "time" + + "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (l *Liqui) Start() { + go l.Run() +} + +func (l *Liqui) Run() { + if l.Verbose { + log.Printf("%s polling delay: %ds.\n", l.GetName(), l.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", l.GetName(), len(l.EnabledPairs), l.EnabledPairs) + } + + var err error + l.Info, err = l.GetInfo() + if err != nil { + log.Printf("%s Unable to fetch info.\n", l.GetName()) + } else { + exchangeProducts := l.GetAvailablePairs(true) + log.Println(exchangeProducts) + /* + diff := common.StringSliceDifference(l.AvailablePairs, exchangeProducts) + if len(diff) > 0 { + exch, err := bot.config.GetExchangeConfig(l.Name) + if err != nil { + log.Println(err) + } else { + log.Printf("%s Updating available pairs. Difference: %s.\n", l.Name, diff) + exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",") + bot.config.UpdateExchangeConfig(exch) + } + } + */ + } + + pairs := []string{} + for _, x := range l.EnabledPairs { + currencies := common.SplitStrings(x, "_") + x = common.StringToLower(currencies[0]) + "_" + common.StringToLower(currencies[1]) + pairs = append(pairs, x) + } + pairsString := common.JoinStrings(pairs, "-") + + for l.Enabled { + go func() { + ticker, err := l.GetTicker(pairsString) + if err != nil { + log.Println(err) + return + } + for x, y := range ticker { + //currencies := common.SplitStrings(x, "_") + x = common.StringToUpper(x) + log.Printf("Liqui %s: Last %f High %f Low %f Volume %f\n", x, y.Last, y.High, y.Low, y.Vol_cur) + l.Ticker[x] = y + //AddExchangeInfo(l.GetName(), common.StringToUpper(currencies[0]), common.StringToUpper(currencies[1]), y.Last, y.Vol_cur) + } + }() + time.Sleep(time.Second * l.RESTPollingDelay) + } +} + +func (l *Liqui) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + var tickerPrice ticker.TickerPrice + tick, ok := l.Ticker[currency] + if !ok { + return tickerPrice, errors.New("Unable to get currency.") + } + tickerPrice.Ask = tick.Buy + tickerPrice.Bid = tick.Sell + currencies := common.SplitStrings(currency, "_") + tickerPrice.FirstCurrency = currencies[0] + tickerPrice.SecondCurrency = currencies[1] + tickerPrice.Low = tick.Low + tickerPrice.Last = tick.Last + tickerPrice.Volume = tick.Vol_cur + tickerPrice.High = tick.High + ticker.ProcessTicker(l.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Liqui exchange +func (e *Liqui) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + accountBalance, err := e.GetAccountInfo() + if err != nil { + return response, err + } + + for x, y := range accountBalance.Funds { + var exchangeCurrency exchange.ExchangeAccountCurrencyInfo + exchangeCurrency.CurrencyName = common.StringToUpper(x) + exchangeCurrency.TotalValue = y + exchangeCurrency.Hold = 0 + response.Currencies = append(response.Currencies, exchangeCurrency) + } + + return response, nil +} diff --git a/liquihttp.go b/exchanges/liqui/liquihttp.go similarity index 55% rename from liquihttp.go rename to exchanges/liqui/liquihttp.go index 2c2ceae6..e0e7e8ab 100644 --- a/liquihttp.go +++ b/exchanges/liqui/liquihttp.go @@ -1,4 +1,4 @@ -package main +package liqui import ( "errors" @@ -38,37 +38,6 @@ type Liqui struct { Info LiquiInfo } -type LiquiTicker struct { - High float64 - Low float64 - Avg float64 - Vol float64 - Vol_cur float64 - Last float64 - Buy float64 - Sell float64 - Updated int64 -} - -type LiquiOrderbook struct { - Asks [][]float64 `json:"asks"` - Bids [][]float64 `json:"bids"` -} - -type LiquiTrades struct { - Type string `json:"type"` - Price float64 `json:"bid"` - Amount float64 `json:"amount"` - TID int64 `json:"tid"` - Timestamp int64 `json:"timestamp"` -} - -type LiquiResponse struct { - Return interface{} `json:"return"` - Success int `json:"success"` - Error string `json:"error"` -} - func (l *Liqui) SetDefaults() { l.Name = "Liqui" l.Enabled = false @@ -95,76 +64,6 @@ func (l *Liqui) Setup(exch config.ExchangeConfig) { } } -func (l *Liqui) Start() { - go l.Run() -} - -func (l *Liqui) Run() { - if l.Verbose { - log.Printf("%s polling delay: %ds.\n", l.GetName(), l.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", l.GetName(), len(l.EnabledPairs), l.EnabledPairs) - } - - var err error - l.Info, err = l.GetInfo() - if err != nil { - log.Printf("%s Unable to fetch info.\n", l.GetName()) - } else { - exchangeProducts := l.GetAvailablePairs(true) - diff := common.StringSliceDifference(l.AvailablePairs, exchangeProducts) - if len(diff) > 0 { - exch, err := bot.config.GetExchangeConfig(l.Name) - if err != nil { - log.Println(err) - } else { - log.Printf("%s Updating available pairs. Difference: %s.\n", l.Name, diff) - exch.AvailablePairs = common.JoinStrings(exchangeProducts, ",") - bot.config.UpdateExchangeConfig(exch) - } - } - } - - pairs := []string{} - for _, x := range l.EnabledPairs { - currencies := common.SplitStrings(x, "_") - x = common.StringToLower(currencies[0]) + "_" + common.StringToLower(currencies[1]) - pairs = append(pairs, x) - } - pairsString := common.JoinStrings(pairs, "-") - - for l.Enabled { - go func() { - ticker, err := l.GetTicker(pairsString) - if err != nil { - log.Println(err) - return - } - for x, y := range ticker { - currencies := common.SplitStrings(x, "_") - x = common.StringToUpper(x) - log.Printf("Liqui %s: Last %f High %f Low %f Volume %f\n", x, y.Last, y.High, y.Low, y.Vol_cur) - l.Ticker[x] = y - AddExchangeInfo(l.GetName(), common.StringToUpper(currencies[0]), common.StringToUpper(currencies[1]), y.Last, y.Vol_cur) - } - }() - time.Sleep(time.Second * l.RESTPollingDelay) - } -} - -type LiquiPair struct { - DecimalPlaces int `json:"decimal_places"` - MinPrice float64 `json:"min_price"` - MaxPrice float64 `json:"max_price"` - MinAmount float64 `json:"min_amount"` - Hidden int `json:"hidden"` - Fee float64 `json:"fee"` -} - -type LiquiInfo struct { - ServerTime int64 `json:"server_time"` - Pairs map[string]LiquiPair `json:"pairs"` -} - func (l *Liqui) GetFee(currency string) (float64, error) { val, ok := l.Info.Pairs[common.StringToLower(currency)] if !ok { @@ -212,26 +111,6 @@ func (l *Liqui) GetTicker(symbol string) (map[string]LiquiTicker, error) { return response.Data, nil } -func (l *Liqui) GetTickerPrice(currency string) (TickerPrice, error) { - var tickerPrice TickerPrice - ticker, ok := l.Ticker[currency] - if !ok { - return tickerPrice, errors.New("Unable to get currency.") - } - tickerPrice.Ask = ticker.Buy - tickerPrice.Bid = ticker.Sell - currencies := common.SplitStrings(currency, "_") - tickerPrice.FirstCurrency = currencies[0] - tickerPrice.SecondCurrency = currencies[1] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Low = ticker.Low - tickerPrice.Last = ticker.Last - tickerPrice.Volume = ticker.Vol_cur - tickerPrice.High = ticker.High - ProcessTicker(l.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - func (l *Liqui) GetDepth(symbol string) (LiquiOrderbook, error) { type Response struct { Data map[string]LiquiOrderbook @@ -266,18 +145,6 @@ func (l *Liqui) GetTrades(symbol string) ([]LiquiTrades, error) { return trades, nil } -type LiquiAccountInfo struct { - Funds map[string]float64 `json:"funds"` - Rights struct { - Info bool `json:"info"` - Trade bool `json:"trade"` - Withdraw bool `json:"withdraw"` - } `json:"rights"` - ServerTime float64 `json:"server_time"` - TransactionCount int `json:"transaction_count"` - OpenOrders int `json:"open_orders"` -} - func (l *Liqui) GetAccountInfo() (LiquiAccountInfo, error) { var result LiquiAccountInfo err := l.SendAuthenticatedHTTPRequest(LIQUI_ACCOUNT_INFO, url.Values{}, &result) @@ -289,33 +156,6 @@ func (l *Liqui) GetAccountInfo() (LiquiAccountInfo, error) { return result, nil } -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Liqui exchange -func (e *Liqui) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - accountBalance, err := e.GetAccountInfo() - if err != nil { - return response, err - } - - for x, y := range accountBalance.Funds { - var exchangeCurrency ExchangeAccountCurrencyInfo - exchangeCurrency.CurrencyName = common.StringToUpper(x) - exchangeCurrency.TotalValue = y - exchangeCurrency.Hold = 0 - response.Currencies = append(response.Currencies, exchangeCurrency) - } - - return response, nil -} - -type LiquiTrade struct { - Received float64 `json:"received"` - Remains float64 `json:"remains"` - OrderID float64 `json:"order_id"` - Funds map[string]float64 `json:"funds"` -} - //to-do: convert orderid to int64 func (l *Liqui) Trade(pair, orderType string, amount, price float64) (float64, error) { req := url.Values{} @@ -334,15 +174,6 @@ func (l *Liqui) Trade(pair, orderType string, amount, price float64) (float64, e return result.OrderID, nil } -type LiquiActiveOrders struct { - Pair string `json:"pair"` - Type string `json:"sell"` - Amount float64 `json:"amount"` - Rate float64 `json:"rate"` - TimestampCreated float64 `json:"time_created"` - Status int `json:"status"` -} - func (l *Liqui) GetActiveOrders(pair string) (map[string]LiquiActiveOrders, error) { req := url.Values{} req.Add("pair", pair) @@ -357,16 +188,6 @@ func (l *Liqui) GetActiveOrders(pair string) (map[string]LiquiActiveOrders, erro return result, nil } -type LiquiOrderInfo struct { - Pair string `json:"pair"` - Type string `json:"sell"` - StartAmount float64 `json:"start_amount"` - Amount float64 `json:"amount"` - Rate float64 `json:"rate"` - TimestampCreated float64 `json:"time_created"` - Status int `json:"status"` -} - func (l *Liqui) GetOrderInfo(OrderID int64) (map[string]LiquiOrderInfo, error) { req := url.Values{} req.Add("order_id", strconv.FormatInt(OrderID, 10)) @@ -381,11 +202,6 @@ func (l *Liqui) GetOrderInfo(OrderID int64) (map[string]LiquiOrderInfo, error) { return result, nil } -type LiquiCancelOrder struct { - OrderID float64 `json:"order_id"` - Funds map[string]float64 `json:"funds"` -} - func (l *Liqui) CancelOrder(OrderID int64) (bool, error) { req := url.Values{} req.Add("order_id", strconv.FormatInt(OrderID, 10)) @@ -400,16 +216,6 @@ func (l *Liqui) CancelOrder(OrderID int64) (bool, error) { return true, nil } -type LiquiTradeHistory struct { - Pair string `json:"pair"` - Type string `json:"type"` - Amount float64 `json:"amount"` - Rate float64 `json:"rate"` - OrderID float64 `json:"order_id"` - MyOrder int `json:"is_your_order"` - Timestamp float64 `json:"timestamp"` -} - func (l *Liqui) GetTradeHistory(vals url.Values, pair string) (map[string]LiquiTradeHistory, error) { if pair != "" { vals.Add("pair", pair) @@ -425,12 +231,6 @@ func (l *Liqui) GetTradeHistory(vals url.Values, pair string) (map[string]LiquiT return result, nil } -type LiquiWithdrawCoins struct { - TID int64 `json:"tId"` - AmountSent float64 `json:"amountSent"` - Funds map[string]float64 `json:"funds"` -} - // API mentions that this isn't active now, but will be soon - you must provide the first 8 characters of the key // in your ticket to support. func (l *Liqui) WithdrawCoins(coin string, amount float64, address string) (LiquiWithdrawCoins, error) { diff --git a/exchanges/localbitcoins/localbitcoins_types.go b/exchanges/localbitcoins/localbitcoins_types.go new file mode 100644 index 00000000..337c2e00 --- /dev/null +++ b/exchanges/localbitcoins/localbitcoins_types.go @@ -0,0 +1,84 @@ +package localbitcoins + +import ( + "time" +) + +type LocalBitcoinsTicker struct { + Avg12h float64 `json:"avg_12h,string"` + Avg1h float64 `json:"avg_1h,string"` + Avg24h float64 `json:"avg_24h,string"` + Rates struct { + Last float64 `json:"last,string"` + } `json:"rates"` + VolumeBTC float64 `json:"volume_btc,string"` +} + +type LocalBitcoinsTrade struct { + TID int64 `json:"tid"` + Date int64 `json:"date"` + Amount float64 `json:"amount,string"` + Price float64 `json:"price,string"` +} + +type LocalBitcoinsOrderbookStructure struct { + Price float64 + Amount float64 +} + +type LocalBitcoinsOrderbook struct { + Bids []LocalBitcoinsOrderbookStructure `json:"bids"` + Asks []LocalBitcoinsOrderbookStructure `json:"asks"` +} + +type LocalBitcoinsAccountInfo struct { + Username string `json:"username"` + CreatedAt time.Time `json:"created_at"` + AgeText string `json:"age_text"` + TradingPartners int `json:"trading_partners_count"` + FeedbacksUnconfirmed int `json:"feedbacks_unconfirmed_count"` + TradeVolumeText string `json:"trade_volume_text"` + HasCommonTrades bool `json:"has_common_trades"` + HasFeedback bool `json:"has_feedback"` + ConfirmedTradesText string `json:"confirmed_trade_count_text"` + BlockedCount int `json:"blocked_count"` + FeedbackScore int `json:"feedback_score"` + FeedbackCount int `json:"feedback_count"` + URL string `json:"url"` + TrustedCount int `json:"trusted_count"` + IdentityVerifiedAt time.Time `json:"identify_verified_at"` +} + +type LocalBitcoinsBalance struct { + Balance float64 `json:"balance,string"` + Sendable float64 `json:"Sendable,string"` +} + +type LocalBitcoinsWalletTransaction struct { + TXID string `json:"txid"` + Amount float64 `json:"amount,string"` + Description string `json:"description"` + TXType int `json:"tx_type"` + CreatedAt time.Time `json:"created_at"` +} + +type LocalBitcoinsWalletAddressList struct { + Address string `json:"address"` + Received float64 `json:"received,string"` +} + +type LocalBitcoinsWalletInfo struct { + Message string `json:"message"` + Total LocalBitcoinsBalance `json:"total"` + SentTransactions30d []LocalBitcoinsWalletTransaction `json:"sent_transactions_30d"` + ReceivedTransactions30d []LocalBitcoinsWalletTransaction `json:"received_transactions_30d"` + ReceivingAddressCount int `json:"receiving_address_count"` + ReceivingAddressList []LocalBitcoinsWalletAddressList `json:"receiving_address_list"` +} + +type LocalBitcoinsWalletBalanceInfo struct { + Message string `json:"message"` + Total LocalBitcoinsBalance `json:"total"` + ReceivingAddressCount int `json:"receiving_address_count"` // always 1 + ReceivingAddressList []LocalBitcoinsWalletAddressList `json:"receiving_address_list"` +} diff --git a/exchanges/localbitcoins/localbitcoins_wrapper.go b/exchanges/localbitcoins/localbitcoins_wrapper.go new file mode 100644 index 00000000..0fd80b21 --- /dev/null +++ b/exchanges/localbitcoins/localbitcoins_wrapper.go @@ -0,0 +1,74 @@ +package localbitcoins + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (l *LocalBitcoins) Start() { + go l.Run() +} + +func (l *LocalBitcoins) Run() { + if l.Verbose { + log.Printf("%s polling delay: %ds.\n", l.GetName(), l.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", l.GetName(), len(l.EnabledPairs), l.EnabledPairs) + } + + for l.Enabled { + for _, x := range l.EnabledPairs { + currency := x[3:] + ticker, err := l.GetTickerPrice("BTC" + currency) + + if err != nil { + log.Println(err) + return + } + + log.Printf("LocalBitcoins BTC %s: Last %f Volume %f\n", currency, ticker.Last, ticker.Volume) + //AddExchangeInfo(l.GetName(), x[0:3], x[3:], ticker.Last, ticker.Volume) + } + time.Sleep(time.Second * l.RESTPollingDelay) + } +} + +func (l *LocalBitcoins) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(l.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tickerNew, nil + } + + tick, err := l.GetTicker() + if err != nil { + return ticker.TickerPrice{}, err + } + + var tickerPrice ticker.TickerPrice + for key, value := range tick { + tickerPrice.Last = value.Rates.Last + tickerPrice.FirstCurrency = currency[0:3] + tickerPrice.SecondCurrency = key + tickerPrice.Volume = value.VolumeBTC + ticker.ProcessTicker(l.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + } + return tickerPrice, nil +} + +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the LocalBitcoins exchange +func (e *LocalBitcoins) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + accountBalance, err := e.GetWalletBalance() + if err != nil { + return response, err + } + var exchangeCurrency exchange.ExchangeAccountCurrencyInfo + exchangeCurrency.CurrencyName = "BTC" + exchangeCurrency.TotalValue = accountBalance.Total.Balance + + response.Currencies = append(response.Currencies, exchangeCurrency) + return response, nil +} diff --git a/localbitcoinshttp.go b/exchanges/localbitcoins/localbitcoinshttp.go similarity index 60% rename from localbitcoinshttp.go rename to exchanges/localbitcoins/localbitcoinshttp.go index efb77276..337290c2 100644 --- a/localbitcoinshttp.go +++ b/exchanges/localbitcoins/localbitcoinshttp.go @@ -1,4 +1,4 @@ -package main +package localbitcoins import ( "bytes" @@ -56,10 +56,6 @@ func (l *LocalBitcoins) Setup(exch config.ExchangeConfig) { } } -func (l *LocalBitcoins) Start() { - go l.Run() -} - func (l *LocalBitcoins) GetFee(maker bool) float64 { if maker { return l.MakerFee @@ -68,39 +64,6 @@ func (l *LocalBitcoins) GetFee(maker bool) float64 { } } -func (l *LocalBitcoins) Run() { - if l.Verbose { - log.Printf("%s polling delay: %ds.\n", l.GetName(), l.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", l.GetName(), len(l.EnabledPairs), l.EnabledPairs) - } - - for l.Enabled { - for _, x := range l.EnabledPairs { - currency := x[3:] - ticker, err := l.GetTickerPrice("BTC" + currency) - - if err != nil { - log.Println(err) - return - } - - log.Printf("LocalBitcoins BTC %s: Last %f Volume %f\n", currency, ticker.Last, ticker.Volume) - AddExchangeInfo(l.GetName(), x[0:3], x[3:], ticker.Last, ticker.Volume) - } - time.Sleep(time.Second * l.RESTPollingDelay) - } -} - -type LocalBitcoinsTicker struct { - Avg12h float64 `json:"avg_12h,string"` - Avg1h float64 `json:"avg_1h,string"` - Avg24h float64 `json:"avg_24h,string"` - Rates struct { - Last float64 `json:"last,string"` - } `json:"rates"` - VolumeBTC float64 `json:"volume_btc,string"` -} - func (l *LocalBitcoins) GetTicker() (map[string]LocalBitcoinsTicker, error) { result := make(map[string]LocalBitcoinsTicker) err := common.SendHTTPGetRequest(LOCALBITCOINS_API_URL+LOCALBITCOINS_API_TICKER, true, &result) @@ -112,36 +75,6 @@ func (l *LocalBitcoins) GetTicker() (map[string]LocalBitcoinsTicker, error) { return result, nil } -func (l *LocalBitcoins) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(l.GetName(), currency[0:3], currency[3:]) - if err == nil { - return tickerNew, nil - } - - ticker, err := l.GetTicker() - if err != nil { - return TickerPrice{}, err - } - - var tickerPrice TickerPrice - for key, value := range ticker { - tickerPrice.Last = value.Rates.Last - tickerPrice.FirstCurrency = currency[0:3] - tickerPrice.SecondCurrency = key - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Volume = value.VolumeBTC - ProcessTicker(l.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - } - return tickerPrice, nil -} - -type LocalBitcoinsTrade struct { - TID int64 `json:"tid"` - Date int64 `json:"date"` - Amount float64 `json:"amount,string"` - Price float64 `json:"price,string"` -} - func (l *LocalBitcoins) GetTrades(currency string, values url.Values) ([]LocalBitcoinsTrade, error) { path := common.EncodeURLValues(fmt.Sprintf("%s/%s/trades.json", LOCALBITCOINS_API_URL+LOCALBITCOINS_API_BITCOINCHARTS, currency), values) result := []LocalBitcoinsTrade{} @@ -154,16 +87,6 @@ func (l *LocalBitcoins) GetTrades(currency string, values url.Values) ([]LocalBi return result, nil } -type LocalBitcoinsOrderbookStructure struct { - Price float64 - Amount float64 -} - -type LocalBitcoinsOrderbook struct { - Bids []LocalBitcoinsOrderbookStructure `json:"bids"` - Asks []LocalBitcoinsOrderbookStructure `json:"asks"` -} - func (l *LocalBitcoins) GetOrderbook(currency string) (LocalBitcoinsOrderbook, error) { type response struct { Bids [][]string `json:"bids"` @@ -211,24 +134,6 @@ func (l *LocalBitcoins) GetOrderbook(currency string) (LocalBitcoinsOrderbook, e return orderbook, nil } -type LocalBitcoinsAccountInfo struct { - Username string `json:"username"` - CreatedAt time.Time `json:"created_at"` - AgeText string `json:"age_text"` - TradingPartners int `json:"trading_partners_count"` - FeedbacksUnconfirmed int `json:"feedbacks_unconfirmed_count"` - TradeVolumeText string `json:"trade_volume_text"` - HasCommonTrades bool `json:"has_common_trades"` - HasFeedback bool `json:"has_feedback"` - ConfirmedTradesText string `json:"confirmed_trade_count_text"` - BlockedCount int `json:"blocked_count"` - FeedbackScore int `json:"feedback_score"` - FeedbackCount int `json:"feedback_count"` - URL string `json:"url"` - TrustedCount int `json:"trusted_count"` - IdentityVerifiedAt time.Time `json:"identify_verified_at"` -} - func (l *LocalBitcoins) GetAccountInfo(username string, self bool) (LocalBitcoinsAccountInfo, error) { type response struct { Data LocalBitcoinsAccountInfo `json:"data"` @@ -275,33 +180,6 @@ func (l *LocalBitcoins) CheckPincode(pin int) (bool, error) { return true, nil } -type LocalBitcoinsBalance struct { - Balance float64 `json:"balance,string"` - Sendable float64 `json:"Sendable,string"` -} - -type LocalBitcoinsWalletTransaction struct { - TXID string `json:"txid"` - Amount float64 `json:"amount,string"` - Description string `json:"description"` - TXType int `json:"tx_type"` - CreatedAt time.Time `json:"created_at"` -} - -type LocalBitcoinsWalletAddressList struct { - Address string `json:"address"` - Received float64 `json:"received,string"` -} - -type LocalBitcoinsWalletInfo struct { - Message string `json:"message"` - Total LocalBitcoinsBalance `json:"total"` - SentTransactions30d []LocalBitcoinsWalletTransaction `json:"sent_transactions_30d"` - ReceivedTransactions30d []LocalBitcoinsWalletTransaction `json:"received_transactions_30d"` - ReceivingAddressCount int `json:"receiving_address_count"` - ReceivingAddressList []LocalBitcoinsWalletAddressList `json:"receiving_address_list"` -} - func (l *LocalBitcoins) GetWalletInfo() (LocalBitcoinsWalletInfo, error) { type response struct { Data LocalBitcoinsWalletInfo `json:"data"` @@ -320,13 +198,6 @@ func (l *LocalBitcoins) GetWalletInfo() (LocalBitcoinsWalletInfo, error) { return resp.Data, nil } -type LocalBitcoinsWalletBalanceInfo struct { - Message string `json:"message"` - Total LocalBitcoinsBalance `json:"total"` - ReceivingAddressCount int `json:"receiving_address_count"` // always 1 - ReceivingAddressList []LocalBitcoinsWalletAddressList `json:"receiving_address_list"` -} - func (l *LocalBitcoins) GetWalletBalance() (LocalBitcoinsWalletBalanceInfo, error) { type response struct { Data LocalBitcoinsWalletBalanceInfo `json:"data"` @@ -426,19 +297,3 @@ func (l *LocalBitcoins) SendAuthenticatedHTTPRequest(method, path string, values return nil } - -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the LocalBitcoins exchange -func (e *LocalBitcoins) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - accountBalance, err := e.GetWalletBalance() - if err != nil { - return response, err - } - var exchangeCurrency ExchangeAccountCurrencyInfo - exchangeCurrency.CurrencyName = "BTC" - exchangeCurrency.TotalValue = accountBalance.Total.Balance - - response.Currencies = append(response.Currencies, exchangeCurrency) - return response, nil -} diff --git a/exchanges/okcoin/okcoin_types.go b/exchanges/okcoin/okcoin_types.go new file mode 100644 index 00000000..0d279a01 --- /dev/null +++ b/exchanges/okcoin/okcoin_types.go @@ -0,0 +1,391 @@ +package okcoin + +type OKCoinTicker struct { + Buy float64 `json:",string"` + High float64 `json:",string"` + Last float64 `json:",string"` + Low float64 `json:",string"` + Sell float64 `json:",string"` + Vol float64 `json:",string"` +} + +type OKCoinTickerResponse struct { + Date string + Ticker OKCoinTicker +} +type OKCoinFuturesTicker struct { + Last float64 + Buy float64 + Sell float64 + High float64 + Low float64 + Vol float64 + Contract_ID int64 + Unit_Amount float64 +} + +type OKCoinOrderbook struct { + Asks [][]float64 `json:"asks"` + Bids [][]float64 `json:"bids"` +} + +type OKCoinFuturesTickerResponse struct { + Date string + Ticker OKCoinFuturesTicker +} + +type OKCoinBorrowInfo struct { + BorrowBTC float64 `json:"borrow_btc"` + BorrowLTC float64 `json:"borrow_ltc"` + BorrowCNY float64 `json:"borrow_cny"` + CanBorrow float64 `json:"can_borrow"` + InterestBTC float64 `json:"interest_btc"` + InterestLTC float64 `json:"interest_ltc"` + Result bool `json:"result"` + DailyInterestBTC float64 `json:"today_interest_btc"` + DailyInterestLTC float64 `json:"today_interest_ltc"` + DailyInterestCNY float64 `json:"today_interest_cny"` +} + +type OKCoinBorrowOrder struct { + Amount float64 `json:"amount"` + BorrowDate int64 `json:"borrow_date"` + BorrowID int64 `json:"borrow_id"` + Days int64 `json:"days"` + TradeAmount float64 `json:"deal_amount"` + Rate float64 `json:"rate"` + Status int64 `json:"status"` + Symbol string `json:"symbol"` +} + +type OKCoinRecord struct { + Address string `json:"addr"` + Account int64 `json:"account,string"` + Amount float64 `json:"amount"` + Bank string `json:"bank"` + BenificiaryAddress string `json:"benificiary_addr"` + TransactionValue float64 `json:"transaction_value"` + Fee float64 `json:"fee"` + Date float64 `json:"date"` +} + +type OKCoinAccountRecords struct { + Records []OKCoinRecord `json:"records"` + Symbol string `json:"symbol"` +} + +type OKCoinFuturesOrder struct { + Amount float64 `json:"amount"` + ContractName string `json:"contract_name"` + DateCreated float64 `json:"create_date"` + TradeAmount float64 `json:"deal_amount"` + Fee float64 `json:"fee"` + LeverageRate float64 `json:"lever_rate"` + OrderID int64 `json:"order_id"` + Price float64 `json:"price"` + AvgPrice float64 `json:"avg_price"` + Status float64 `json:"status"` + Symbol string `json:"symbol"` + Type int64 `json:"type"` + UnitAmount int64 `json:"unit_amount"` +} + +type OKCoinFuturesHoldAmount struct { + Amount float64 `json:"amount"` + ContractName string `json:"contract_name"` +} + +type OKCoinFuturesExplosive struct { + Amount float64 `json:"amount,string"` + DateCreated string `json:"create_date"` + Loss float64 `json:"loss,string"` + Type int64 `json:"type"` +} + +type OKCoinTrades struct { + Amount float64 `json:"amount,string"` + Date int64 `json:"date` + DateMS int64 `json:"date_ms"` + Price float64 `json:"price,string"` + TradeID int64 `json:"tid"` + Type string `json:"type"` +} + +type OKCoinFuturesTrades struct { + Amount float64 `json:"amount"` + Date int64 `json:"date"` + DateMS int64 `json:"date_ms"` + Price float64 `json:"price"` + TradeID int64 `json:"tid"` + Type string `json:"type"` +} + +type OKCoinUserInfo struct { + Info struct { + Funds struct { + Asset struct { + Net float64 `json:"net,string"` + Total float64 `json:"total,string"` + } `json:"asset"` + Borrow struct { + BTC float64 `json:"btc,string"` + LTC float64 `json:"ltc,string"` + USD float64 `json:"usd,string"` + } `json:"borrow"` + Free struct { + BTC float64 `json:"btc,string"` + LTC float64 `json:"ltc,string"` + USD float64 `json:"usd,string"` + } `json:"free"` + Freezed struct { + BTC float64 `json:"btc,string"` + LTC float64 `json:"ltc,string"` + USD float64 `json:"usd,string"` + } `json:"freezed"` + UnionFund struct { + BTC float64 `json:"btc,string"` + LTC float64 `json:"ltc,string"` + } `json:"union_fund"` + } `json:"funds"` + } `json:"info"` + Result bool `json:"result"` +} + +type OKCoinBatchTrade struct { + OrderInfo []struct { + OrderID int64 `json:"order_id"` + ErrorCode int64 `json:"error_code"` + } `json:"order_info"` + Result bool `json:"result"` +} + +type OKCoinCancelOrderResponse struct { + Success string + Error string +} + +type OKCoinOrderInfo struct { + Amount float64 `json:"amount"` + AvgPrice float64 `json:"avg_price"` + Created int64 `json:"create_date"` + DealAmount float64 `json:"deal_amount"` + OrderID int64 `json:"order_id"` + OrdersID int64 `json:"orders_id"` + Price float64 `json:"price"` + Status int `json:"status"` + Symbol string `json:"symbol"` + Type string `json:"type"` +} + +type OKCoinOrderHistory struct { + CurrentPage int `json:"current_page"` + Orders []OKCoinOrderInfo `json:"orders"` + PageLength int `json:"page_length"` + Result bool `json:"result"` + Total int `json:"total"` +} + +type OKCoinWithdrawalResponse struct { + WithdrawID int `json:"withdraw_id"` + Result bool `json:"result"` +} + +type OKCoinWithdrawInfo struct { + Address string `json:"address"` + Amount float64 `json:"amount"` + Created int64 `json:"created_date"` + ChargeFee float64 `json:"chargefee"` + Status int `json:"status"` + WithdrawID int64 `json:"withdraw_id"` +} + +type OKCoinOrderFeeInfo struct { + Fee float64 `json:"fee,string"` + OrderID int64 `json:"order_id"` + Type string `json:"type"` +} + +type OKCoinLendDepth struct { + Amount float64 `json:"amount"` + Days string `json:"days"` + Num int64 `json:"num"` + Rate float64 `json:"rate,string"` +} + +type OKCoinBorrowResponse struct { + Result bool `json:"result"` + BorrowID int `json:"borrow_id"` +} + +type OKCoinWebsocketFutureIndex struct { + FutureIndex float64 `json:"futureIndex"` + Timestamp int64 `json:"timestamp,string"` +} + +type OKCoinWebsocketTicker struct { + Timestamp float64 + Vol string + Buy float64 + High float64 + Last float64 + Low float64 + Sell float64 +} + +type OKCoinWebsocketFuturesTicker struct { + Buy float64 `json:"buy"` + ContractID string `json:"contractId"` + High float64 `json:"high"` + HoldAmount float64 `json:"hold_amount"` + Last float64 `json:"last,string"` + Low float64 `json:"low"` + Sell float64 `json:"sell"` + UnitAmount float64 `json:"unitAmount"` + Volume float64 `json:"vol,string"` +} + +type OKCoinWebsocketOrderbook struct { + Asks [][]float64 `json:"asks"` + Bids [][]float64 `json:"bids"` + Timestamp int64 `json:"timestamp,string"` +} + +type OKCoinWebsocketUserinfo struct { + Info struct { + Funds struct { + Asset struct { + Net float64 `json:"net,string"` + Total float64 `json:"total,string"` + } `json:"asset"` + Free struct { + BTC float64 `json:"btc,string"` + LTC float64 `json:"ltc,string"` + USD float64 `json:"usd,string"` + CNY float64 `json:"cny,string"` + } `json:"free"` + Frozen struct { + BTC float64 `json:"btc,string"` + LTC float64 `json:"ltc,string"` + USD float64 `json:"usd,string"` + CNY float64 `json:"cny,string"` + } `json:"freezed"` + } `json:"funds"` + } `json:"info"` + Result bool `json:"result"` +} + +type OKCoinWebsocketFuturesContract struct { + Available float64 `json:"available"` + Balance float64 `json:"balance"` + Bond float64 `json:"bond"` + ContractID float64 `json:"contract_id"` + ContractType string `json:"contract_type"` + Frozen float64 `json:"freeze"` + Profit float64 `json:"profit"` + Loss float64 `json:"unprofit"` +} + +type OKCoinWebsocketFuturesUserInfo struct { + Info struct { + BTC struct { + Balance float64 `json:"balance"` + Contracts []OKCoinWebsocketFuturesContract `json:"contracts"` + Rights float64 `json:"rights"` + } `json:"btc"` + LTC struct { + Balance float64 `json:"balance"` + Contracts []OKCoinWebsocketFuturesContract `json:"contracts"` + Rights float64 `json:"rights"` + } `json:"ltc"` + } `json:"info"` + Result bool `json:"result"` +} + +type OKCoinWebsocketOrder struct { + Amount float64 `json:"amount"` + AvgPrice float64 `json:"avg_price"` + DateCreated float64 `json:"create_date"` + TradeAmount float64 `json:"deal_amount"` + OrderID float64 `json:"order_id"` + OrdersID float64 `json:"orders_id"` + Price float64 `json:"price"` + Status int64 `json:"status"` + Symbol string `json:"symbol"` + OrderType string `json:"type"` +} + +type OKCoinWebsocketFuturesOrder struct { + Amount float64 `json:"amount"` + ContractName string `json:"contract_name"` + DateCreated float64 `json:"createdDate"` + TradeAmount float64 `json:"deal_amount"` + Fee float64 `json:"fee"` + LeverageAmount int `json:"lever_rate"` + OrderID float64 `json:"order_id"` + Price float64 `json:"price"` + AvgPrice float64 `json:"avg_price"` + Status int `json:"status"` + Symbol string `json:"symbol"` + TradeType int `json:"type"` + UnitAmount float64 `json:"unit_amount"` +} + +type OKCoinWebsocketRealtrades struct { + AveragePrice float64 `json:"averagePrice,string"` + CompletedTradeAmount float64 `json:"completedTradeAmount,string"` + DateCreated float64 `json:"createdDate"` + ID float64 `json:"id"` + OrderID float64 `json:"orderId"` + SigTradeAmount float64 `json:"sigTradeAmount,string"` + SigTradePrice float64 `json:"sigTradePrice,string"` + Status int64 `json:"status"` + Symbol string `json:"symbol"` + TradeAmount float64 `json:"tradeAmount,string"` + TradePrice float64 `json:"buy,string"` + TradeType string `json:"tradeType"` + TradeUnitPrice float64 `json:"tradeUnitPrice,string"` + UnTrade float64 `json:"unTrade,string"` +} + +type OKCoinWebsocketFuturesRealtrades struct { + Amount float64 `json:"amount,string"` + ContractID float64 `json:"contract_id,string"` + ContractName string `json:"contract_name"` + ContractType string `json:"contract_type"` + TradeAmount float64 `json:"deal_amount,string"` + Fee float64 `json:"fee,string"` + OrderID float64 `json:"orderid"` + Price float64 `json:"price,string"` + AvgPrice float64 `json:"price_avg,string"` + Status int `json:"status,string"` + TradeType int `json:"type,string"` + UnitAmount float64 `json:"unit_amount,string"` + LeverageAmount int `json:"lever_rate,string"` +} + +type OKCoinWebsocketEvent struct { + Event string `json:"event"` + Channel string `json:"channel"` +} + +type OKCoinWebsocketResponse struct { + Channel string `json:"channel"` + Data interface{} `json:"data"` +} + +type OKCoinWebsocketEventAuth struct { + Event string `json:"event"` + Channel string `json:"channel"` + Parameters map[string]string `json:"parameters"` +} + +type OKCoinWebsocketEventAuthRemove struct { + Event string `json:"event"` + Channel string `json:"channel"` + Parameters map[string]string `json:"parameters"` +} + +type OKCoinWebsocketTradeOrderResponse struct { + OrderID int64 `json:"order_id,string"` + Result bool `json:"result,string"` +} diff --git a/exchanges/okcoin/okcoin_wrapper.go b/exchanges/okcoin/okcoin_wrapper.go new file mode 100644 index 00000000..71c4f268 --- /dev/null +++ b/exchanges/okcoin/okcoin_wrapper.go @@ -0,0 +1,102 @@ +package okcoin + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (o *OKCoin) Start() { + go o.Run() +} + +func (o *OKCoin) Run() { + if o.Verbose { + log.Printf("%s Websocket: %s. (url: %s).\n", o.GetName(), common.IsEnabled(o.Websocket), o.WebsocketURL) + log.Printf("%s polling delay: %ds.\n", o.GetName(), o.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", o.GetName(), len(o.EnabledPairs), o.EnabledPairs) + } + + if o.Websocket { + go o.WebsocketClient() + } + + for o.Enabled { + for _, x := range o.EnabledPairs { + currency := common.StringToLower(x[0:3] + "_" + x[3:]) + if o.APIUrl == OKCOIN_API_URL { + for _, y := range o.FuturesValues { + futuresValue := y + go func() { + ticker, err := o.GetFuturesTicker(currency, futuresValue) + if err != nil { + log.Println(err) + return + } + log.Printf("OKCoin Intl Futures %s (%s): Last %f High %f Low %f Volume %f\n", currency, futuresValue, ticker.Last, ticker.High, ticker.Low, ticker.Vol) + //AddExchangeInfo(o.GetName(), common.StringToUpper(currency[0:3]), common.StringToUpper(currency[4:]), ticker.Last, ticker.Vol) + }() + } + go func() { + ticker, err := o.GetTickerPrice(currency) + if err != nil { + log.Println(err) + return + } + log.Printf("OKCoin Intl Spot %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) + //AddExchangeInfo(o.GetName(), common.StringToUpper(currency[0:3]), common.StringToUpper(currency[4:]), ticker.Last, ticker.Volume) + }() + } else { + go func() { + ticker, err := o.GetTickerPrice(currency) + if err != nil { + log.Println(err) + return + } + //tickerLastUSD, _ := ConvertCurrency(ticker.Last, "CNY", "USD") + //tickerHighUSD, _ := ConvertCurrency(ticker.High, "CNY", "USD") + //tickerLowUSD, _ := ConvertCurrency(ticker.Low, "CNY", "USD") + //log.Printf("OKCoin China %s: Last %f (%f) High %f (%f) Low %f (%f) Volume %f\n", currency, tickerLastUSD, ticker.Last, tickerHighUSD, ticker.High, tickerLowUSD, ticker.Low, ticker.Volume) + log.Printf("OKCoin China %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) + //AddExchangeInfo(o.GetName(), common.StringToUpper(currency[0:3]), common.StringToUpper(currency[4:]), ticker.Last, ticker.Volume) + //AddExchangeInfo(o.GetName(), common.StringToUpper(currency[0:3]), "USD", tickerLastUSD, ticker.Volume) + }() + } + } + time.Sleep(time.Second * o.RESTPollingDelay) + } +} + +func (o *OKCoin) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(o.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tickerNew, nil + } + + var tickerPrice ticker.TickerPrice + tick, err := o.GetTicker(currency) + if err != nil { + return tickerPrice, err + } + tickerPrice.Ask = tick.Sell + tickerPrice.Bid = tick.Buy + tickerPrice.FirstCurrency = common.StringToUpper(currency[0:3]) + tickerPrice.SecondCurrency = common.StringToUpper(currency[4:]) + tickerPrice.Low = tick.Low + tickerPrice.Last = tick.Last + tickerPrice.Volume = tick.Vol + tickerPrice.High = tick.High + ticker.ProcessTicker(o.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +//TODO support for retrieving holdings from OKCOIN +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the OKCoin exchange +func (e *OKCoin) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + return response, nil +} diff --git a/okcoinhttp.go b/exchanges/okcoin/okcoinhttp.go similarity index 74% rename from okcoinhttp.go rename to exchanges/okcoin/okcoinhttp.go index da186afe..56145305 100644 --- a/okcoinhttp.go +++ b/exchanges/okcoin/okcoinhttp.go @@ -1,4 +1,4 @@ -package main +package okcoin import ( "errors" @@ -6,7 +6,6 @@ import ( "net/url" "strconv" "strings" - "time" "github.com/gorilla/websocket" "github.com/thrasher-/gocryptotrader/common" @@ -78,108 +77,6 @@ type OKCoin struct { WebsocketConn *websocket.Conn } -type OKCoinTicker struct { - Buy float64 `json:",string"` - High float64 `json:",string"` - Last float64 `json:",string"` - Low float64 `json:",string"` - Sell float64 `json:",string"` - Vol float64 `json:",string"` -} - -type OKCoinTickerResponse struct { - Date string - Ticker OKCoinTicker -} -type OKCoinFuturesTicker struct { - Last float64 - Buy float64 - Sell float64 - High float64 - Low float64 - Vol float64 - Contract_ID int64 - Unit_Amount float64 -} - -type OKCoinOrderbook struct { - Asks [][]float64 `json:"asks"` - Bids [][]float64 `json:"bids"` -} - -type OKCoinFuturesTickerResponse struct { - Date string - Ticker OKCoinFuturesTicker -} - -type OKCoinBorrowInfo struct { - BorrowBTC float64 `json:"borrow_btc"` - BorrowLTC float64 `json:"borrow_ltc"` - BorrowCNY float64 `json:"borrow_cny"` - CanBorrow float64 `json:"can_borrow"` - InterestBTC float64 `json:"interest_btc"` - InterestLTC float64 `json:"interest_ltc"` - Result bool `json:"result"` - DailyInterestBTC float64 `json:"today_interest_btc"` - DailyInterestLTC float64 `json:"today_interest_ltc"` - DailyInterestCNY float64 `json:"today_interest_cny"` -} - -type OKCoinBorrowOrder struct { - Amount float64 `json:"amount"` - BorrowDate int64 `json:"borrow_date"` - BorrowID int64 `json:"borrow_id"` - Days int64 `json:"days"` - TradeAmount float64 `json:"deal_amount"` - Rate float64 `json:"rate"` - Status int64 `json:"status"` - Symbol string `json:"symbol"` -} - -type OKCoinRecord struct { - Address string `json:"addr"` - Account int64 `json:"account,string"` - Amount float64 `json:"amount"` - Bank string `json:"bank"` - BenificiaryAddress string `json:"benificiary_addr"` - TransactionValue float64 `json:"transaction_value"` - Fee float64 `json:"fee"` - Date float64 `json:"date"` -} - -type OKCoinAccountRecords struct { - Records []OKCoinRecord `json:"records"` - Symbol string `json:"symbol"` -} - -type OKCoinFuturesOrder struct { - Amount float64 `json:"amount"` - ContractName string `json:"contract_name"` - DateCreated float64 `json:"create_date"` - TradeAmount float64 `json:"deal_amount"` - Fee float64 `json:"fee"` - LeverageRate float64 `json:"lever_rate"` - OrderID int64 `json:"order_id"` - Price float64 `json:"price"` - AvgPrice float64 `json:"avg_price"` - Status float64 `json:"status"` - Symbol string `json:"symbol"` - Type int64 `json:"type"` - UnitAmount int64 `json:"unit_amount"` -} - -type OKCoinFuturesHoldAmount struct { - Amount float64 `json:"amount"` - ContractName string `json:"contract_name"` -} - -type OKCoinFuturesExplosive struct { - Amount float64 `json:"amount,string"` - DateCreated string `json:"create_date"` - Loss float64 `json:"loss,string"` - Type int64 `json:"type"` -} - func (o *OKCoin) SetDefaults() { o.SetErrorDefaults() o.SetWebsocketErrorDefaults() @@ -217,10 +114,6 @@ func (o *OKCoin) Setup(exch config.ExchangeConfig) { } } -func (o *OKCoin) Start() { - go o.Run() -} - func (o *OKCoin) GetFee(maker bool) float64 { if o.APIUrl == OKCOIN_API_URL { if maker { @@ -233,62 +126,6 @@ func (o *OKCoin) GetFee(maker bool) float64 { return 0 } -func (o *OKCoin) Run() { - if o.Verbose { - log.Printf("%s Websocket: %s. (url: %s).\n", o.GetName(), common.IsEnabled(o.Websocket), o.WebsocketURL) - log.Printf("%s polling delay: %ds.\n", o.GetName(), o.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", o.GetName(), len(o.EnabledPairs), o.EnabledPairs) - } - - if o.Websocket { - go o.WebsocketClient() - } - - for o.Enabled { - for _, x := range o.EnabledPairs { - currency := common.StringToLower(x[0:3] + "_" + x[3:]) - if o.APIUrl == OKCOIN_API_URL { - for _, y := range o.FuturesValues { - futuresValue := y - go func() { - ticker, err := o.GetFuturesTicker(currency, futuresValue) - if err != nil { - log.Println(err) - return - } - log.Printf("OKCoin Intl Futures %s (%s): Last %f High %f Low %f Volume %f\n", currency, futuresValue, ticker.Last, ticker.High, ticker.Low, ticker.Vol) - AddExchangeInfo(o.GetName(), common.StringToUpper(currency[0:3]), common.StringToUpper(currency[4:]), ticker.Last, ticker.Vol) - }() - } - go func() { - ticker, err := o.GetTickerPrice(currency) - if err != nil { - log.Println(err) - return - } - log.Printf("OKCoin Intl Spot %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) - AddExchangeInfo(o.GetName(), common.StringToUpper(currency[0:3]), common.StringToUpper(currency[4:]), ticker.Last, ticker.Volume) - }() - } else { - go func() { - ticker, err := o.GetTickerPrice(currency) - if err != nil { - log.Println(err) - return - } - tickerLastUSD, _ := ConvertCurrency(ticker.Last, "CNY", "USD") - tickerHighUSD, _ := ConvertCurrency(ticker.High, "CNY", "USD") - tickerLowUSD, _ := ConvertCurrency(ticker.Low, "CNY", "USD") - log.Printf("OKCoin China %s: Last %f (%f) High %f (%f) Low %f (%f) Volume %f\n", currency, tickerLastUSD, ticker.Last, tickerHighUSD, ticker.High, tickerLowUSD, ticker.Low, ticker.Volume) - AddExchangeInfo(o.GetName(), common.StringToUpper(currency[0:3]), common.StringToUpper(currency[4:]), ticker.Last, ticker.Volume) - AddExchangeInfo(o.GetName(), common.StringToUpper(currency[0:3]), "USD", tickerLastUSD, ticker.Volume) - }() - } - } - time.Sleep(time.Second * o.RESTPollingDelay) - } -} - func (o *OKCoin) GetTicker(symbol string) (OKCoinTicker, error) { resp := OKCoinTickerResponse{} vals := url.Values{} @@ -301,30 +138,6 @@ func (o *OKCoin) GetTicker(symbol string) (OKCoinTicker, error) { return resp.Ticker, nil } -func (o *OKCoin) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(o.GetName(), currency[0:3], currency[3:]) - if err == nil { - return tickerNew, nil - } - - var tickerPrice TickerPrice - ticker, err := o.GetTicker(currency) - if err != nil { - return tickerPrice, err - } - tickerPrice.Ask = ticker.Sell - tickerPrice.Bid = ticker.Buy - tickerPrice.FirstCurrency = common.StringToUpper(currency[0:3]) - tickerPrice.SecondCurrency = common.StringToUpper(currency[4:]) - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - tickerPrice.Low = ticker.Low - tickerPrice.Last = ticker.Last - tickerPrice.Volume = ticker.Vol - tickerPrice.High = ticker.High - ProcessTicker(o.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - func (o *OKCoin) GetOrderBook(symbol string, size int64, merge bool) (OKCoinOrderbook, error) { resp := OKCoinOrderbook{} vals := url.Values{} @@ -344,15 +157,6 @@ func (o *OKCoin) GetOrderBook(symbol string, size int64, merge bool) (OKCoinOrde return resp, nil } -type OKCoinTrades struct { - Amount float64 `json:"amount,string"` - Date int64 `json:"date` - DateMS int64 `json:"date_ms"` - Price float64 `json:"price,string"` - TradeID int64 `json:"tid"` - Type string `json:"type"` -} - func (o *OKCoin) GetTrades(symbol string, since int64) ([]OKCoinTrades, error) { result := []OKCoinTrades{} vals := url.Values{} @@ -426,15 +230,6 @@ func (o *OKCoin) GetFuturesDepth(symbol, contractType string, size int64, merge return result, nil } -type OKCoinFuturesTrades struct { - Amount float64 `json:"amount"` - Date int64 `json:"date"` - DateMS int64 `json:"date_ms"` - Price float64 `json:"price"` - TradeID int64 `json:"tid"` - Type string `json:"type"` -} - func (o *OKCoin) GetFuturesTrades(symbol, contractType string) ([]OKCoinFuturesTrades, error) { result := []OKCoinFuturesTrades{} vals := url.Values{} @@ -555,37 +350,6 @@ func (o *OKCoin) GetFuturesExplosive(symbol, contractType string, status, curren return resp.Data, nil } -type OKCoinUserInfo struct { - Info struct { - Funds struct { - Asset struct { - Net float64 `json:"net,string"` - Total float64 `json:"total,string"` - } `json:"asset"` - Borrow struct { - BTC float64 `json:"btc,string"` - LTC float64 `json:"ltc,string"` - USD float64 `json:"usd,string"` - } `json:"borrow"` - Free struct { - BTC float64 `json:"btc,string"` - LTC float64 `json:"ltc,string"` - USD float64 `json:"usd,string"` - } `json:"free"` - Freezed struct { - BTC float64 `json:"btc,string"` - LTC float64 `json:"ltc,string"` - USD float64 `json:"usd,string"` - } `json:"freezed"` - UnionFund struct { - BTC float64 `json:"btc,string"` - LTC float64 `json:"ltc,string"` - } `json:"union_fund"` - } `json:"funds"` - } `json:"info"` - Result bool `json:"result"` -} - func (o *OKCoin) GetUserInfo() (OKCoinUserInfo, error) { result := OKCoinUserInfo{} err := o.SendAuthenticatedHTTPRequest(OKCOIN_USERINFO, url.Values{}, &result) @@ -638,14 +402,6 @@ func (o *OKCoin) GetTradeHistory(symbol string, TradeID int64) ([]OKCoinTrades, return result, nil } -type OKCoinBatchTrade struct { - OrderInfo []struct { - OrderID int64 `json:"order_id"` - ErrorCode int64 `json:"error_code"` - } `json:"order_info"` - Result bool `json:"result"` -} - func (o *OKCoin) BatchTrade(orderData string, symbol, orderType string) (OKCoinBatchTrade, error) { v := url.Values{} v.Set("orders_data", orderData) @@ -662,11 +418,6 @@ func (o *OKCoin) BatchTrade(orderData string, symbol, orderType string) (OKCoinB return result, nil } -type OKCoinCancelOrderResponse struct { - Success string - Error string -} - func (o *OKCoin) CancelOrder(orderID []int64, symbol string) (OKCoinCancelOrderResponse, error) { v := url.Values{} orders := []string{} @@ -694,19 +445,6 @@ func (o *OKCoin) CancelOrder(orderID []int64, symbol string) (OKCoinCancelOrderR return result, nil } -type OKCoinOrderInfo struct { - Amount float64 `json:"amount"` - AvgPrice float64 `json:"avg_price"` - Created int64 `json:"create_date"` - DealAmount float64 `json:"deal_amount"` - OrderID int64 `json:"order_id"` - OrdersID int64 `json:"orders_id"` - Price float64 `json:"price"` - Status int `json:"status"` - Symbol string `json:"symbol"` - Type string `json:"type"` -} - func (o *OKCoin) GetOrderInfo(orderID int64, symbol string) ([]OKCoinOrderInfo, error) { type Response struct { Result bool `json:"result"` @@ -759,14 +497,6 @@ func (o *OKCoin) GetOrderInfoBatch(orderID []int64, symbol string) ([]OKCoinOrde return result.Orders, nil } -type OKCoinOrderHistory struct { - CurrentPage int `json:"current_page"` - Orders []OKCoinOrderInfo `json:"orders"` - PageLength int `json:"page_length"` - Result bool `json:"result"` - Total int `json:"total"` -} - func (o *OKCoin) GetOrderHistory(pageLength, currentPage int64, status, symbol string) (OKCoinOrderHistory, error) { v := url.Values{} v.Set("symbol", symbol) @@ -784,11 +514,6 @@ func (o *OKCoin) GetOrderHistory(pageLength, currentPage int64, status, symbol s return result, nil } -type OKCoinWithdrawalResponse struct { - WithdrawID int `json:"withdraw_id"` - Result bool `json:"result"` -} - func (o *OKCoin) Withdrawal(symbol string, fee float64, tradePWD, address string, amount float64) (int, error) { v := url.Values{} v.Set("symbol", symbol) @@ -833,15 +558,6 @@ func (o *OKCoin) CancelWithdrawal(symbol string, withdrawalID int64) (int, error return result.WithdrawID, nil } -type OKCoinWithdrawInfo struct { - Address string `json:"address"` - Amount float64 `json:"amount"` - Created int64 `json:"created_date"` - ChargeFee float64 `json:"chargefee"` - Status int `json:"status"` - WithdrawID int64 `json:"withdraw_id"` -} - func (o *OKCoin) GetWithdrawalInfo(symbol string, withdrawalID int64) ([]OKCoinWithdrawInfo, error) { type Response struct { Result bool @@ -865,12 +581,6 @@ func (o *OKCoin) GetWithdrawalInfo(symbol string, withdrawalID int64) ([]OKCoinW return result.Withdraw, nil } -type OKCoinOrderFeeInfo struct { - Fee float64 `json:"fee,string"` - OrderID int64 `json:"order_id"` - Type string `json:"type"` -} - func (o *OKCoin) GetOrderFeeInfo(symbol string, orderID int64) (OKCoinOrderFeeInfo, error) { type Response struct { Data OKCoinOrderFeeInfo `json:"data"` @@ -895,13 +605,6 @@ func (o *OKCoin) GetOrderFeeInfo(symbol string, orderID int64) (OKCoinOrderFeeIn return result.Data, nil } -type OKCoinLendDepth struct { - Amount float64 `json:"amount"` - Days string `json:"days"` - Num int64 `json:"num"` - Rate float64 `json:"rate,string"` -} - func (o *OKCoin) GetLendDepth(symbol string) ([]OKCoinLendDepth, error) { type Response struct { LendDepth []OKCoinLendDepth `json:"lend_depth"` @@ -934,11 +637,6 @@ func (o *OKCoin) GetBorrowInfo(symbol string) (OKCoinBorrowInfo, error) { return result, nil } -type OKCoinBorrowResponse struct { - Result bool `json:"result"` - BorrowID int `json:"borrow_id"` -} - func (o *OKCoin) Borrow(symbol, days string, amount, rate float64) (int, error) { v := url.Values{} v.Set("symbol", symbol) @@ -1063,14 +761,6 @@ func (o *OKCoin) GetAccountRecords(symbol string, recType, currentPage, pageLeng return result.Records, nil } -//TODO support for retrieving holdings from OKCOIN -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the OKCoin exchange -func (e *OKCoin) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - return response, nil -} - func (o *OKCoin) GetFuturesUserInfo() { err := o.SendAuthenticatedHTTPRequest(OKCOIN_FUTURES_USERINFO, url.Values{}, nil) diff --git a/okcoinwebsocket.go b/exchanges/okcoin/okcoinwebsocket.go similarity index 75% rename from okcoinwebsocket.go rename to exchanges/okcoin/okcoinwebsocket.go index fac2d58c..3a81a2f4 100644 --- a/okcoinwebsocket.go +++ b/exchanges/okcoin/okcoinwebsocket.go @@ -1,4 +1,4 @@ -package main +package okcoin import ( "fmt" @@ -32,179 +32,6 @@ const ( OKCOIN_WEBSOCKET_FUTURES_ORDER_INFO = "ok_futureusd_order_info" ) -type OKCoinWebsocketFutureIndex struct { - FutureIndex float64 `json:"futureIndex"` - Timestamp int64 `json:"timestamp,string"` -} - -type OKCoinWebsocketTicker struct { - Timestamp float64 - Vol string - Buy float64 - High float64 - Last float64 - Low float64 - Sell float64 -} - -type OKCoinWebsocketFuturesTicker struct { - Buy float64 `json:"buy"` - ContractID string `json:"contractId"` - High float64 `json:"high"` - HoldAmount float64 `json:"hold_amount"` - Last float64 `json:"last,string"` - Low float64 `json:"low"` - Sell float64 `json:"sell"` - UnitAmount float64 `json:"unitAmount"` - Volume float64 `json:"vol,string"` -} - -type OKCoinWebsocketOrderbook struct { - Asks [][]float64 `json:"asks"` - Bids [][]float64 `json:"bids"` - Timestamp int64 `json:"timestamp,string"` -} - -type OKCoinWebsocketUserinfo struct { - Info struct { - Funds struct { - Asset struct { - Net float64 `json:"net,string"` - Total float64 `json:"total,string"` - } `json:"asset"` - Free struct { - BTC float64 `json:"btc,string"` - LTC float64 `json:"ltc,string"` - USD float64 `json:"usd,string"` - CNY float64 `json:"cny,string"` - } `json:"free"` - Frozen struct { - BTC float64 `json:"btc,string"` - LTC float64 `json:"ltc,string"` - USD float64 `json:"usd,string"` - CNY float64 `json:"cny,string"` - } `json:"freezed"` - } `json:"funds"` - } `json:"info"` - Result bool `json:"result"` -} - -type OKCoinWebsocketFuturesContract struct { - Available float64 `json:"available"` - Balance float64 `json:"balance"` - Bond float64 `json:"bond"` - ContractID float64 `json:"contract_id"` - ContractType string `json:"contract_type"` - Frozen float64 `json:"freeze"` - Profit float64 `json:"profit"` - Loss float64 `json:"unprofit"` -} - -type OKCoinWebsocketFuturesUserInfo struct { - Info struct { - BTC struct { - Balance float64 `json:"balance"` - Contracts []OKCoinWebsocketFuturesContract `json:"contracts"` - Rights float64 `json:"rights"` - } `json:"btc"` - LTC struct { - Balance float64 `json:"balance"` - Contracts []OKCoinWebsocketFuturesContract `json:"contracts"` - Rights float64 `json:"rights"` - } `json:"ltc"` - } `json:"info"` - Result bool `json:"result"` -} - -type OKCoinWebsocketOrder struct { - Amount float64 `json:"amount"` - AvgPrice float64 `json:"avg_price"` - DateCreated float64 `json:"create_date"` - TradeAmount float64 `json:"deal_amount"` - OrderID float64 `json:"order_id"` - OrdersID float64 `json:"orders_id"` - Price float64 `json:"price"` - Status int64 `json:"status"` - Symbol string `json:"symbol"` - OrderType string `json:"type"` -} - -type OKCoinWebsocketFuturesOrder struct { - Amount float64 `json:"amount"` - ContractName string `json:"contract_name"` - DateCreated float64 `json:"createdDate"` - TradeAmount float64 `json:"deal_amount"` - Fee float64 `json:"fee"` - LeverageAmount int `json:"lever_rate"` - OrderID float64 `json:"order_id"` - Price float64 `json:"price"` - AvgPrice float64 `json:"avg_price"` - Status int `json:"status"` - Symbol string `json:"symbol"` - TradeType int `json:"type"` - UnitAmount float64 `json:"unit_amount"` -} - -type OKCoinWebsocketRealtrades struct { - AveragePrice float64 `json:"averagePrice,string"` - CompletedTradeAmount float64 `json:"completedTradeAmount,string"` - DateCreated float64 `json:"createdDate"` - ID float64 `json:"id"` - OrderID float64 `json:"orderId"` - SigTradeAmount float64 `json:"sigTradeAmount,string"` - SigTradePrice float64 `json:"sigTradePrice,string"` - Status int64 `json:"status"` - Symbol string `json:"symbol"` - TradeAmount float64 `json:"tradeAmount,string"` - TradePrice float64 `json:"buy,string"` - TradeType string `json:"tradeType"` - TradeUnitPrice float64 `json:"tradeUnitPrice,string"` - UnTrade float64 `json:"unTrade,string"` -} - -type OKCoinWebsocketFuturesRealtrades struct { - Amount float64 `json:"amount,string"` - ContractID float64 `json:"contract_id,string"` - ContractName string `json:"contract_name"` - ContractType string `json:"contract_type"` - TradeAmount float64 `json:"deal_amount,string"` - Fee float64 `json:"fee,string"` - OrderID float64 `json:"orderid"` - Price float64 `json:"price,string"` - AvgPrice float64 `json:"price_avg,string"` - Status int `json:"status,string"` - TradeType int `json:"type,string"` - UnitAmount float64 `json:"unit_amount,string"` - LeverageAmount int `json:"lever_rate,string"` -} - -type OKCoinWebsocketEvent struct { - Event string `json:"event"` - Channel string `json:"channel"` -} - -type OKCoinWebsocketResponse struct { - Channel string `json:"channel"` - Data interface{} `json:"data"` -} - -type OKCoinWebsocketEventAuth struct { - Event string `json:"event"` - Channel string `json:"channel"` - Parameters map[string]string `json:"parameters"` -} - -type OKCoinWebsocketEventAuthRemove struct { - Event string `json:"event"` - Channel string `json:"channel"` - Parameters map[string]string `json:"parameters"` -} - -type OKCoinWebsocketTradeOrderResponse struct { - OrderID int64 `json:"order_id,string"` - Result bool `json:"result,string"` -} - func (o *OKCoin) PingHandler(message string) error { err := o.WebsocketConn.WriteControl(websocket.PingMessage, []byte("{'event':'ping'}"), time.Now().Add(time.Second)) diff --git a/exchanges/poloniex/poloniex_types.go b/exchanges/poloniex/poloniex_types.go new file mode 100644 index 00000000..cb11d039 --- /dev/null +++ b/exchanges/poloniex/poloniex_types.go @@ -0,0 +1,214 @@ +package poloniex + +import ( + "time" +) + +type PoloniexTicker struct { + Last float64 `json:"last,string"` + LowestAsk float64 `json:"lowestAsk,string"` + HighestBid float64 `json:"highestBid,string"` + PercentChange float64 `json:"percentChange,string"` + BaseVolume float64 `json:"baseVolume,string"` + QuoteVolume float64 `json:"quoteVolume,string"` + IsFrozen int `json:"isFrozen,string"` + High24Hr float64 `json:"high24hr,string"` + Low24Hr float64 `json:"low24hr,string"` +} + +type PoloniexOrderbook struct { + Asks [][]interface{} `json:"asks"` + Bids [][]interface{} `json:"bids"` + IsFrozen string `json:"isFrozen"` +} + +type PoloniexTradeHistory struct { + GlobalTradeID int64 `json:"globalTradeID"` + TradeID int64 `json:"tradeID"` + Date string `json:"date"` + Type string `json:"type"` + Rate float64 `json:"rate,string"` + Amount float64 `json:"amount,string"` + Total float64 `json:"total,string"` +} + +type PoloniexChartData struct { + Date int `json:"date"` + High float64 `json:"high"` + Low float64 `json:"low"` + Open float64 `json:"open"` + Close float64 `json:"close"` + Volume float64 `json:"volume"` + QuoteVolume float64 `json:"quoteVolume"` + WeightedAverage float64 `json:"weightedAverage"` +} + +type PoloniexCurrencies struct { + Name string `json:"name"` + MaxDailyWithdrawal string `json:"maxDailyWithdrawal"` + TxFee float64 `json:"txFee,string"` + MinConfirmations int `json:"minConf"` + DepositAddresses interface{} `json:"depositAddress"` + Disabled int `json:"disabled"` + Delisted int `json:"delisted"` + Frozen int `json:"frozen"` +} + +type PoloniexLoanOrder struct { + Rate float64 `json:"rate,string"` + Amount float64 `json:"amount,string"` + RangeMin int `json:"rangeMin"` + RangeMax int `json:"rangeMax"` +} + +type PoloniexLoanOrders struct { + Offers []PoloniexLoanOrder `json:"offers"` + Demands []PoloniexLoanOrder `json:"demands"` +} + +type PoloniexBalance struct { + Currency map[string]float64 +} + +type PoloniexCompleteBalance struct { + Available float64 + OnOrders float64 + BTCValue float64 +} + +type PoloniexDepositAddresses struct { + Addresses map[string]string +} + +type PoloniexDepositsWithdrawals struct { + Deposits []struct { + Currency string `json:"currency"` + Address string `json:"address"` + Amount float64 `json:"amount,string"` + Confirmations int `json:"confirmations"` + TransactionID string `json:"txid"` + Timestamp time.Time `json:"timestamp"` + Status string `json:"string"` + } `json:"deposits"` + Withdrawals []struct { + WithdrawalNumber int64 `json:"withdrawalNumber"` + Currency string `json:"currency"` + Address string `json:"address"` + Amount float64 `json:"amount,string"` + Confirmations int `json:"confirmations"` + TransactionID string `json:"txid"` + Timestamp time.Time `json:"timestamp"` + Status string `json:"string"` + IPAddress string `json:"ipAddress"` + } `json:"withdrawals"` +} + +type PoloniexOrder struct { + OrderNumber int64 `json:"orderNumber,string"` + Type string `json:"type"` + Rate float64 `json:"rate,string"` + Amount float64 `json:"amount,string"` + Total float64 `json:"total,string"` + Date string `json:"date"` + Margin float64 `json:"margin"` +} + +type PoloniexOpenOrdersResponseAll struct { + Data map[string][]PoloniexOrder +} + +type PoloniexOpenOrdersResponse struct { + Data []PoloniexOrder +} + +type PoloniexAuthentictedTradeHistory struct { + GlobalTradeID int64 `json:"globalTradeID"` + TradeID int64 `json:"tradeID,string"` + Date string `json:"date"` + Rate float64 `json:"rate,string"` + Amount float64 `json:"amount,string"` + Total float64 `json:"total,string"` + Fee float64 `json:"fee,string"` + OrderNumber int64 `json:"orderNumber,string"` + Type string `json:"type"` + Category string `json:"category"` +} + +type PoloniexAuthenticatedTradeHistoryAll struct { + Data map[string][]PoloniexAuthentictedTradeHistory +} + +type PoloniexAuthenticatedTradeHistoryResponse struct { + Data []PoloniexAuthentictedTradeHistory +} + +type PoloniexResultingTrades struct { + Amount float64 `json:"amount,string"` + Date string `json:"date"` + Rate float64 `json:"rate,string"` + Total float64 `json:"total,string"` + TradeID int64 `json:"tradeID,string"` + Type string `json:"type"` +} + +type PoloniexOrderResponse struct { + OrderNumber int64 `json:"orderNumber,string"` + Trades []PoloniexResultingTrades `json:"resultingTrades"` +} + +type PoloniexGenericResponse struct { + Success int `json:"success"` + Error string `json:"error"` +} + +type PoloniexMoveOrderResponse struct { + Success int `json:"success"` + Error string `json:"error"` + OrderNumber int64 `json:"orderNumber,string"` + Trades map[string][]PoloniexResultingTrades `json:"resultingTrades"` +} + +type PoloniexWithdraw struct { + Response string `json:"response"` + Error string `json:"error"` +} + +type PoloniexFee struct { + MakerFee float64 `json:"makerFee,string"` + TakerFee float64 `json:"takerFee,string"` + ThirtyDayVolume float64 `json:"thirtyDayVolume,string"` + NextTier float64 `json:"nextTier,string"` +} + +type PoloniexMargin struct { + TotalValue float64 `json:"totalValue,string"` + ProfitLoss float64 `json:"pl,string"` + LendingFees float64 `json:"lendingFees,string"` + NetValue float64 `json:"netValue,string"` + BorrowedValue float64 `json:"totalBorrowedValue,string"` + CurrentMargin float64 `json:"currentMargin,string"` +} + +type PoloniexMarginPosition struct { + Amount float64 `json:"amount,string"` + Total float64 `json:"total,string"` + BasePrice float64 `json:"basePrice,string"` + LiquidiationPrice float64 `json:"liquidiationPrice"` + ProfitLoss float64 `json:"pl,string"` + LendingFees float64 `json:"lendingFees,string"` + Type string `json:"type"` +} + +type PoloniexLoanOffer struct { + ID int64 `json:"id"` + Rate float64 `json:"rate,string"` + Amount float64 `json:"amount,string"` + Duration int `json:"duration"` + AutoRenew bool `json:"autoRenew,int"` + Date string `json:"date"` +} + +type PoloniexActiveLoans struct { + Provided []PoloniexLoanOffer `json:"provided"` + Used []PoloniexLoanOffer `json:"used"` +} diff --git a/exchanges/poloniex/poloniex_wrapper.go b/exchanges/poloniex/poloniex_wrapper.go new file mode 100644 index 00000000..e6d8a39b --- /dev/null +++ b/exchanges/poloniex/poloniex_wrapper.go @@ -0,0 +1,86 @@ +package poloniex + +import ( + "log" + "time" + + "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" +) + +func (p *Poloniex) Start() { + go p.Run() +} + +func (p *Poloniex) Run() { + if p.Verbose { + log.Printf("%s Websocket: %s (url: %s).\n", p.GetName(), common.IsEnabled(p.Websocket), POLONIEX_WEBSOCKET_ADDRESS) + log.Printf("%s polling delay: %ds.\n", p.GetName(), p.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", p.GetName(), len(p.EnabledPairs), p.EnabledPairs) + } + + if p.Websocket { + go p.WebsocketClient() + } + + for p.Enabled { + for _, x := range p.EnabledPairs { + currency := x + go func() { + ticker, err := p.GetTickerPrice(currency) + if err != nil { + log.Println(err) + return + } + log.Printf("Poloniex %s Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) + //currencyPair := common.SplitStrings(currency, "_") + //AddExchangeInfo(p.GetName(), currencyPair[0], currencyPair[1], ticker.Last, ticker.Volume) + }() + } + time.Sleep(time.Second * p.RESTPollingDelay) + } +} + +func (p *Poloniex) GetTickerPrice(currency string) (ticker.TickerPrice, error) { + tickerNew, err := ticker.GetTicker(p.GetName(), currency[0:3], currency[3:]) + if err == nil { + return tickerNew, nil + } + + var tickerPrice ticker.TickerPrice + tick, err := p.GetTicker() + if err != nil { + return tickerPrice, err + } + + currencyPair := common.SplitStrings(currency, "_") + tickerPrice.FirstCurrency = currencyPair[0] + tickerPrice.SecondCurrency = currencyPair[1] + tickerPrice.Ask = tick[currency].Last + tickerPrice.Bid = tick[currency].HighestBid + tickerPrice.High = tick[currency].HighestBid + tickerPrice.Last = tick[currency].Last + tickerPrice.Low = tick[currency].LowestAsk + tickerPrice.Volume = tick[currency].BaseVolume + ticker.ProcessTicker(p.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) + return tickerPrice, nil +} + +//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Poloniex exchange +func (e *Poloniex) GetExchangeAccountInfo() (exchange.ExchangeAccountInfo, error) { + var response exchange.ExchangeAccountInfo + response.ExchangeName = e.GetName() + accountBalance, err := e.GetBalances() + if err != nil { + return response, err + } + currencies := e.AvailablePairs + for i := 0; i < len(currencies); i++ { + var exchangeCurrency exchange.ExchangeAccountCurrencyInfo + exchangeCurrency.CurrencyName = currencies[i] + exchangeCurrency.TotalValue = accountBalance.Currency[currencies[i]] + response.Currencies = append(response.Currencies, exchangeCurrency) + } + return response, nil +} diff --git a/poloniexhttp.go b/exchanges/poloniex/poloniexhttp.go similarity index 66% rename from poloniexhttp.go rename to exchanges/poloniex/poloniexhttp.go index 90f39898..9aa90e13 100644 --- a/poloniexhttp.go +++ b/exchanges/poloniex/poloniexhttp.go @@ -1,10 +1,9 @@ -package main +package poloniex import ( "bytes" "errors" "fmt" - "log" "net/url" "strconv" "time" @@ -50,18 +49,6 @@ type Poloniex struct { exchange.ExchangeBase } -type PoloniexTicker struct { - Last float64 `json:"last,string"` - LowestAsk float64 `json:"lowestAsk,string"` - HighestBid float64 `json:"highestBid,string"` - PercentChange float64 `json:"percentChange,string"` - BaseVolume float64 `json:"baseVolume,string"` - QuoteVolume float64 `json:"quoteVolume,string"` - IsFrozen int `json:"isFrozen,string"` - High24Hr float64 `json:"high24hr,string"` - Low24Hr float64 `json:"low24hr,string"` -} - func (p *Poloniex) SetDefaults() { p.Name = "Poloniex" p.Enabled = false @@ -87,43 +74,10 @@ func (p *Poloniex) Setup(exch config.ExchangeConfig) { } } -func (p *Poloniex) Start() { - go p.Run() -} - func (p *Poloniex) GetFee() float64 { return p.Fee } -func (p *Poloniex) Run() { - if p.Verbose { - log.Printf("%s Websocket: %s (url: %s).\n", p.GetName(), common.IsEnabled(p.Websocket), POLONIEX_WEBSOCKET_ADDRESS) - log.Printf("%s polling delay: %ds.\n", p.GetName(), p.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", p.GetName(), len(p.EnabledPairs), p.EnabledPairs) - } - - if p.Websocket { - go p.WebsocketClient() - } - - for p.Enabled { - for _, x := range p.EnabledPairs { - currency := x - go func() { - ticker, err := p.GetTickerPrice(currency) - if err != nil { - log.Println(err) - return - } - log.Printf("Poloniex %s Last %f High %f Low %f Volume %f\n", currency, ticker.Last, ticker.High, ticker.Low, ticker.Volume) - currencyPair := common.SplitStrings(currency, "_") - AddExchangeInfo(p.GetName(), currencyPair[0], currencyPair[1], ticker.Last, ticker.Volume) - }() - } - time.Sleep(time.Second * p.RESTPollingDelay) - } -} - func (p *Poloniex) GetTicker() (map[string]PoloniexTicker, error) { type response struct { Data map[string]PoloniexTicker @@ -139,32 +93,6 @@ func (p *Poloniex) GetTicker() (map[string]PoloniexTicker, error) { return resp.Data, nil } -func (p *Poloniex) GetTickerPrice(currency string) (TickerPrice, error) { - tickerNew, err := GetTicker(p.GetName(), currency[0:3], currency[3:]) - if err == nil { - return tickerNew, nil - } - - var tickerPrice TickerPrice - ticker, err := p.GetTicker() - if err != nil { - return tickerPrice, err - } - - currencyPair := common.SplitStrings(currency, "_") - tickerPrice.FirstCurrency = currencyPair[0] - tickerPrice.SecondCurrency = currencyPair[1] - tickerPrice.CurrencyPair = tickerPrice.FirstCurrency + "_" + tickerPrice.SecondCurrency - 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 - ProcessTicker(p.GetName(), tickerPrice.FirstCurrency, tickerPrice.SecondCurrency, tickerPrice) - return tickerPrice, nil -} - func (p *Poloniex) GetVolume() (interface{}, error) { var resp interface{} path := fmt.Sprintf("%s/public?command=return24hVolume", POLONIEX_API_URL) @@ -176,12 +104,6 @@ func (p *Poloniex) GetVolume() (interface{}, error) { return resp, nil } -type PoloniexOrderbook struct { - Asks [][]interface{} `json:"asks"` - Bids [][]interface{} `json:"bids"` - IsFrozen string `json:"isFrozen"` -} - //TO-DO: add support for individual pair depth fetching func (p *Poloniex) GetOrderbook(currencyPair string, depth int) (map[string]PoloniexOrderbook, error) { type Response struct { @@ -205,16 +127,6 @@ func (p *Poloniex) GetOrderbook(currencyPair string, depth int) (map[string]Polo return resp.Data, nil } -type PoloniexTradeHistory struct { - GlobalTradeID int64 `json:"globalTradeID"` - TradeID int64 `json:"tradeID"` - Date string `json:"date"` - Type string `json:"type"` - Rate float64 `json:"rate,string"` - Amount float64 `json:"amount,string"` - Total float64 `json:"total,string"` -} - func (p *Poloniex) GetTradeHistory(currencyPair, start, end string) ([]PoloniexTradeHistory, error) { vals := url.Values{} vals.Set("currencyPair", currencyPair) @@ -237,17 +149,6 @@ func (p *Poloniex) GetTradeHistory(currencyPair, start, end string) ([]PoloniexT return resp, nil } -type PoloniexChartData struct { - Date int `json:"date"` - High float64 `json:"high"` - Low float64 `json:"low"` - Open float64 `json:"open"` - Close float64 `json:"close"` - Volume float64 `json:"volume"` - QuoteVolume float64 `json:"quoteVolume"` - WeightedAverage float64 `json:"weightedAverage"` -} - func (p *Poloniex) GetChartData(currencyPair, start, end, period string) ([]PoloniexChartData, error) { vals := url.Values{} vals.Set("currencyPair", currencyPair) @@ -274,17 +175,6 @@ func (p *Poloniex) GetChartData(currencyPair, start, end, period string) ([]Polo return resp, nil } -type PoloniexCurrencies struct { - Name string `json:"name"` - MaxDailyWithdrawal string `json:"maxDailyWithdrawal"` - TxFee float64 `json:"txFee,string"` - MinConfirmations int `json:"minConf"` - DepositAddresses interface{} `json:"depositAddress"` - Disabled int `json:"disabled"` - Delisted int `json:"delisted"` - Frozen int `json:"frozen"` -} - func (p *Poloniex) GetCurrencies() (map[string]PoloniexCurrencies, error) { type Response struct { Data map[string]PoloniexCurrencies @@ -299,18 +189,6 @@ func (p *Poloniex) GetCurrencies() (map[string]PoloniexCurrencies, error) { return resp.Data, nil } -type PoloniexLoanOrder struct { - Rate float64 `json:"rate,string"` - Amount float64 `json:"amount,string"` - RangeMin int `json:"rangeMin"` - RangeMax int `json:"rangeMax"` -} - -type PoloniexLoanOrders struct { - Offers []PoloniexLoanOrder `json:"offers"` - Demands []PoloniexLoanOrder `json:"demands"` -} - func (p *Poloniex) GetLoanOrders(currency string) (PoloniexLoanOrders, error) { resp := PoloniexLoanOrders{} path := fmt.Sprintf("%s/public?command=returnLoanOrders¤cy=%s", POLONIEX_API_URL, currency) @@ -322,10 +200,6 @@ func (p *Poloniex) GetLoanOrders(currency string) (PoloniexLoanOrders, error) { return resp, nil } -type PoloniexBalance struct { - Currency map[string]float64 -} - func (p *Poloniex) GetBalances() (PoloniexBalance, error) { var result interface{} err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_BALANCES, url.Values{}, &result) @@ -345,12 +219,6 @@ func (p *Poloniex) GetBalances() (PoloniexBalance, error) { return balance, nil } -type PoloniexCompleteBalance struct { - Available float64 - OnOrders float64 - BTCValue float64 -} - type PoloniexCompleteBalances struct { Currency map[string]PoloniexCompleteBalance } @@ -379,10 +247,6 @@ func (p *Poloniex) GetCompleteBalances() (PoloniexCompleteBalances, error) { return balance, nil } -type PoloniexDepositAddresses struct { - Addresses map[string]string -} - func (p *Poloniex) GetDepositAddresses() (PoloniexDepositAddresses, error) { var result interface{} addresses := PoloniexDepositAddresses{} @@ -424,29 +288,6 @@ func (p *Poloniex) GenerateNewAddress(currency string) (string, error) { return resp.Response, nil } -type PoloniexDepositsWithdrawals struct { - Deposits []struct { - Currency string `json:"currency"` - Address string `json:"address"` - Amount float64 `json:"amount,string"` - Confirmations int `json:"confirmations"` - TransactionID string `json:"txid"` - Timestamp time.Time `json:"timestamp"` - Status string `json:"string"` - } `json:"deposits"` - Withdrawals []struct { - WithdrawalNumber int64 `json:"withdrawalNumber"` - Currency string `json:"currency"` - Address string `json:"address"` - Amount float64 `json:"amount,string"` - Confirmations int `json:"confirmations"` - TransactionID string `json:"txid"` - Timestamp time.Time `json:"timestamp"` - Status string `json:"string"` - IPAddress string `json:"ipAddress"` - } `json:"withdrawals"` -} - func (p *Poloniex) GetDepositsWithdrawals(start, end string) (PoloniexDepositsWithdrawals, error) { resp := PoloniexDepositsWithdrawals{} values := url.Values{} @@ -472,24 +313,6 @@ func (p *Poloniex) GetDepositsWithdrawals(start, end string) (PoloniexDepositsWi return resp, nil } -type PoloniexOrder struct { - OrderNumber int64 `json:"orderNumber,string"` - Type string `json:"type"` - Rate float64 `json:"rate,string"` - Amount float64 `json:"amount,string"` - Total float64 `json:"total,string"` - Date string `json:"date"` - Margin float64 `json:"margin"` -} - -type PoloniexOpenOrdersResponseAll struct { - Data map[string][]PoloniexOrder -} - -type PoloniexOpenOrdersResponse struct { - Data []PoloniexOrder -} - func (p *Poloniex) GetOpenOrders(currency string) (interface{}, error) { values := url.Values{} @@ -516,27 +339,6 @@ func (p *Poloniex) GetOpenOrders(currency string) (interface{}, error) { } } -type PoloniexAuthentictedTradeHistory struct { - GlobalTradeID int64 `json:"globalTradeID"` - TradeID int64 `json:"tradeID,string"` - Date string `json:"date"` - Rate float64 `json:"rate,string"` - Amount float64 `json:"amount,string"` - Total float64 `json:"total,string"` - Fee float64 `json:"fee,string"` - OrderNumber int64 `json:"orderNumber,string"` - Type string `json:"type"` - Category string `json:"category"` -} - -type PoloniexAuthenticatedTradeHistoryAll struct { - Data map[string][]PoloniexAuthentictedTradeHistory -} - -type PoloniexAuthenticatedTradeHistoryResponse struct { - Data []PoloniexAuthentictedTradeHistory -} - func (p *Poloniex) GetAuthenticatedTradeHistory(currency, start, end string) (interface{}, error) { values := url.Values{} @@ -571,20 +373,6 @@ func (p *Poloniex) GetAuthenticatedTradeHistory(currency, start, end string) (in } } -type PoloniexResultingTrades struct { - Amount float64 `json:"amount,string"` - Date string `json:"date"` - Rate float64 `json:"rate,string"` - Total float64 `json:"total,string"` - TradeID int64 `json:"tradeID,string"` - Type string `json:"type"` -} - -type PoloniexOrderResponse struct { - OrderNumber int64 `json:"orderNumber,string"` - Trades []PoloniexResultingTrades `json:"resultingTrades"` -} - func (p *Poloniex) PlaceOrder(currency string, rate, amount float64, immediate, fillOrKill, buy bool) (PoloniexOrderResponse, error) { result := PoloniexOrderResponse{} values := url.Values{} @@ -617,11 +405,6 @@ func (p *Poloniex) PlaceOrder(currency string, rate, amount float64, immediate, return result, nil } -type PoloniexGenericResponse struct { - Success int `json:"success"` - Error string `json:"error"` -} - func (p *Poloniex) CancelOrder(orderID int64) (bool, error) { result := PoloniexGenericResponse{} values := url.Values{} @@ -640,13 +423,6 @@ func (p *Poloniex) CancelOrder(orderID int64) (bool, error) { return true, nil } -type PoloniexMoveOrderResponse struct { - Success int `json:"success"` - Error string `json:"error"` - OrderNumber int64 `json:"orderNumber,string"` - Trades map[string][]PoloniexResultingTrades `json:"resultingTrades"` -} - func (p *Poloniex) MoveOrder(orderID int64, rate, amount float64) (PoloniexMoveOrderResponse, error) { result := PoloniexMoveOrderResponse{} values := url.Values{} @@ -670,11 +446,6 @@ func (p *Poloniex) MoveOrder(orderID int64, rate, amount float64) (PoloniexMoveO return result, nil } -type PoloniexWithdraw struct { - Response string `json:"response"` - Error string `json:"error"` -} - func (p *Poloniex) Withdraw(currency, address string, amount float64) (bool, error) { result := PoloniexWithdraw{} values := url.Values{} @@ -696,13 +467,6 @@ func (p *Poloniex) Withdraw(currency, address string, amount float64) (bool, err return true, nil } -type PoloniexFee struct { - MakerFee float64 `json:"makerFee,string"` - TakerFee float64 `json:"takerFee,string"` - ThirtyDayVolume float64 `json:"thirtyDayVolume,string"` - NextTier float64 `json:"nextTier,string"` -} - func (p *Poloniex) GetFeeInfo() (PoloniexFee, error) { result := PoloniexFee{} err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_FEE_INFO, url.Values{}, &result) @@ -760,15 +524,6 @@ func (p *Poloniex) TransferBalance(currency, from, to string, amount float64) (b return true, nil } -type PoloniexMargin struct { - TotalValue float64 `json:"totalValue,string"` - ProfitLoss float64 `json:"pl,string"` - LendingFees float64 `json:"lendingFees,string"` - NetValue float64 `json:"netValue,string"` - BorrowedValue float64 `json:"totalBorrowedValue,string"` - CurrentMargin float64 `json:"currentMargin,string"` -} - func (p *Poloniex) GetMarginAccountSummary() (PoloniexMargin, error) { result := PoloniexMargin{} err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_MARGIN_ACCOUNT_SUMMARY, url.Values{}, &result) @@ -808,16 +563,6 @@ func (p *Poloniex) PlaceMarginOrder(currency string, rate, amount, lendingRate f return result, nil } -type PoloniexMarginPosition struct { - Amount float64 `json:"amount,string"` - Total float64 `json:"total,string"` - BasePrice float64 `json:"basePrice,string"` - LiquidiationPrice float64 `json:"liquidiationPrice"` - ProfitLoss float64 `json:"pl,string"` - LendingFees float64 `json:"lendingFees,string"` - Type string `json:"type"` -} - func (p *Poloniex) GetMarginPosition(currency string) (interface{}, error) { values := url.Values{} @@ -920,15 +665,6 @@ func (p *Poloniex) CancelLoanOffer(orderNumber int64) (bool, error) { return true, nil } -type PoloniexLoanOffer struct { - ID int64 `json:"id"` - Rate float64 `json:"rate,string"` - Amount float64 `json:"amount,string"` - Duration int `json:"duration"` - AutoRenew bool `json:"autoRenew,int"` - Date string `json:"date"` -} - func (p *Poloniex) GetOpenLoanOffers() (map[string][]PoloniexLoanOffer, error) { type Response struct { Data map[string][]PoloniexLoanOffer @@ -948,11 +684,6 @@ func (p *Poloniex) GetOpenLoanOffers() (map[string][]PoloniexLoanOffer, error) { return result.Data, nil } -type PoloniexActiveLoans struct { - Provided []PoloniexLoanOffer `json:"provided"` - Used []PoloniexLoanOffer `json:"used"` -} - func (p *Poloniex) GetActiveLoans() (PoloniexActiveLoans, error) { result := PoloniexActiveLoans{} err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_ACTIVE_LOANS, url.Values{}, &result) @@ -1010,21 +741,3 @@ func (p *Poloniex) SendAuthenticatedHTTPRequest(method, endpoint string, values } return nil } - -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Poloniex exchange -func (e *Poloniex) GetExchangeAccountInfo() (ExchangeAccountInfo, error) { - var response ExchangeAccountInfo - response.ExchangeName = e.GetName() - accountBalance, err := e.GetBalances() - if err != nil { - return response, err - } - currencies := e.AvailablePairs - for i := 0; i < len(currencies); i++ { - var exchangeCurrency ExchangeAccountCurrencyInfo - exchangeCurrency.CurrencyName = currencies[i] - exchangeCurrency.TotalValue = accountBalance.Currency[currencies[i]] - response.Currencies = append(response.Currencies, exchangeCurrency) - } - return response, nil -} diff --git a/poloniexwebsocket.go b/exchanges/poloniex/poloniexwebsocket.go similarity index 99% rename from poloniexwebsocket.go rename to exchanges/poloniex/poloniexwebsocket.go index 55cc6793..4c2291e7 100644 --- a/poloniexwebsocket.go +++ b/exchanges/poloniex/poloniexwebsocket.go @@ -1,4 +1,4 @@ -package main +package poloniex import ( "log" diff --git a/ticker.go b/exchanges/ticker/ticker.go similarity index 90% rename from ticker.go rename to exchanges/ticker/ticker.go index 14be0ece..f2cd99e8 100644 --- a/ticker.go +++ b/exchanges/ticker/ticker.go @@ -1,8 +1,7 @@ -package main +package ticker import ( "errors" - "log" "strconv" ) @@ -10,6 +9,8 @@ var ( ErrTickerForExchangeNotFound = "Ticker for exchange does not exist." ErrPrimaryCurrencyNotFound = "Error primary currency for ticker not found." ErrSecondaryCurrencyNotFound = "Error secondary currency for ticker not found." + + Tickers []Ticker ) type TickerPrice struct { @@ -69,7 +70,7 @@ func GetTicker(exchange, firstCurrency, secondCurrency string) (TickerPrice, err } func GetTickerByExchange(exchange string) (*Ticker, error) { - for _, y := range bot.tickers { + for _, y := range Tickers { if y.ExchangeName == exchange { return &y, nil } @@ -78,7 +79,7 @@ func GetTickerByExchange(exchange string) (*Ticker, error) { } func FirstCurrencyExists(exchange, currency string) bool { - for _, y := range bot.tickers { + for _, y := range Tickers { if y.ExchangeName == exchange { if _, ok := y.Price[currency]; ok { return true @@ -89,7 +90,7 @@ func FirstCurrencyExists(exchange, currency string) bool { } func SecondCurrencyExists(exchange, primary, secondary string) bool { - for _, y := range bot.tickers { + for _, y := range Tickers { if y.ExchangeName == exchange { if _, ok := y.Price[primary]; ok { if _, ok := y.Price[primary][secondary]; ok { @@ -101,20 +102,20 @@ func SecondCurrencyExists(exchange, primary, secondary string) bool { return false } -func CreateNewTicker(exchangeName string, firstCurrency, secondCurrency string, tickerNew TickerPrice) { +func CreateNewTicker(exchangeName string, firstCurrency, secondCurrency string, tickerNew TickerPrice) Ticker { ticker := Ticker{} ticker.ExchangeName = exchangeName ticker.Price = make(map[string]map[string]TickerPrice) sMap := make(map[string]TickerPrice) sMap[secondCurrency] = tickerNew ticker.Price[firstCurrency] = sMap - bot.tickers = append(bot.tickers, ticker) + return ticker } func ProcessTicker(exchangeName string, firstCurrency, secondCurrency string, tickerNew TickerPrice) { tickerNew.CurrencyPair = tickerNew.FirstCurrency + tickerNew.SecondCurrency - if len(bot.tickers) == 0 { + if len(Tickers) == 0 { CreateNewTicker(exchangeName, firstCurrency, secondCurrency, tickerNew) return } else { @@ -137,13 +138,3 @@ func ProcessTicker(exchangeName string, firstCurrency, secondCurrency string, ti ticker.Price[firstCurrency] = sMap } } - -func HandleTickerEvents() { - bot.tickerChan = make(chan Ticker) - for { - select { - case ticker := <-bot.tickerChan: - log.Printf("Ticker update recv %v..\n", ticker) - } - } -} diff --git a/interfaces.go b/interfaces.go deleted file mode 100644 index da0f2c57..00000000 --- a/interfaces.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "github.com/thrasher-/gocryptotrader/config" -) - -//IBotExchange : Enforces standard functions for all exchanges supported in gocryptotrader -type IBotExchange interface { - Setup(exch config.ExchangeConfig) - Start() - SetDefaults() - GetName() string - IsEnabled() bool - GetTickerPrice(currency string) (TickerPrice, error) - GetEnabledCurrencies() []string - GetExchangeAccountInfo() (ExchangeAccountInfo, error) -} diff --git a/main.go b/main.go index e2572f77..d58cedbb 100644 --- a/main.go +++ b/main.go @@ -11,35 +11,52 @@ import ( "github.com/thrasher-/gocryptotrader/common" "github.com/thrasher-/gocryptotrader/config" + "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges/anx" + "github.com/thrasher-/gocryptotrader/exchanges/bitfinex" + "github.com/thrasher-/gocryptotrader/exchanges/bitstamp" + "github.com/thrasher-/gocryptotrader/exchanges/btcc" + "github.com/thrasher-/gocryptotrader/exchanges/btce" + "github.com/thrasher-/gocryptotrader/exchanges/btcmarkets" + "github.com/thrasher-/gocryptotrader/exchanges/gdax" + "github.com/thrasher-/gocryptotrader/exchanges/gemini" + "github.com/thrasher-/gocryptotrader/exchanges/huobi" + "github.com/thrasher-/gocryptotrader/exchanges/itbit" + "github.com/thrasher-/gocryptotrader/exchanges/kraken" + "github.com/thrasher-/gocryptotrader/exchanges/lakebtc" + "github.com/thrasher-/gocryptotrader/exchanges/liqui" + "github.com/thrasher-/gocryptotrader/exchanges/localbitcoins" + "github.com/thrasher-/gocryptotrader/exchanges/okcoin" + "github.com/thrasher-/gocryptotrader/exchanges/poloniex" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" ) -type Exchange struct { - anx ANX - btcc BTCC - bitstamp Bitstamp - bitfinex Bitfinex - btce BTCE - btcmarkets BTCMarkets - gdax GDAX - gemini Gemini - okcoinChina OKCoin - okcoinIntl OKCoin - itbit ItBit - lakebtc LakeBTC - liqui Liqui - localbitcoins LocalBitcoins - poloniex Poloniex - huobi HUOBI - kraken Kraken +type ExchangeMain struct { + anx anx.ANX + btcc btcc.BTCC + bitstamp bitstamp.Bitstamp + bitfinex bitfinex.Bitfinex + btce btce.BTCE + btcmarkets btcmarkets.BTCMarkets + gdax gdax.GDAX + gemini gemini.Gemini + okcoinChina okcoin.OKCoin + okcoinIntl okcoin.OKCoin + itbit itbit.ItBit + lakebtc lakebtc.LakeBTC + liqui liqui.Liqui + localbitcoins localbitcoins.LocalBitcoins + poloniex poloniex.Poloniex + huobi huobi.HUOBI + kraken kraken.Kraken } type Bot struct { - config config.Config - exchange Exchange - exchanges []IBotExchange - tickers []Ticker - tickerChan chan Ticker - shutdown chan bool + config config.Config + exchange ExchangeMain + exchanges []exchange.IBotExchange + tickers []ticker.Ticker + shutdown chan bool } var bot Bot @@ -89,24 +106,24 @@ func main() { log.Printf("Available Exchanges: %d. Enabled Exchanges: %d.\n", len(bot.config.Exchanges), bot.config.GetConfigEnabledExchanges()) log.Println("Bot Exchange support:") - bot.exchanges = []IBotExchange{ - new(ANX), - new(Kraken), - new(BTCC), - new(Bitstamp), - new(Bitfinex), - new(BTCE), - new(BTCMarkets), - new(GDAX), - new(Gemini), - new(OKCoin), - new(OKCoin), - new(ItBit), - new(LakeBTC), - new(Liqui), - new(LocalBitcoins), - new(Poloniex), - new(HUOBI), + bot.exchanges = []exchange.IBotExchange{ + new(anx.ANX), + new(kraken.Kraken), + new(btcc.BTCC), + new(bitstamp.Bitstamp), + new(bitfinex.Bitfinex), + new(btce.BTCE), + new(btcmarkets.BTCMarkets), + new(gdax.GDAX), + new(gemini.Gemini), + new(okcoin.OKCoin), + new(okcoin.OKCoin), + new(itbit.ItBit), + new(lakebtc.LakeBTC), + new(liqui.Liqui), + new(localbitcoins.LocalBitcoins), + new(poloniex.Poloniex), + new(huobi.HUOBI), } for i := 0; i < len(bot.exchanges); i++ { diff --git a/restfulRouter.go b/restfulRouter.go index c8037e68..e675e8f5 100644 --- a/restfulRouter.go +++ b/restfulRouter.go @@ -4,9 +4,10 @@ import ( "net/http" "github.com/gorilla/mux" + "github.com/thrasher-/gocryptotrader/exchanges" ) -func NewRouter(exchanges []IBotExchange) *mux.Router { +func NewRouter(exchanges []exchange.IBotExchange) *mux.Router { router := mux.NewRouter().StrictSlash(true) allRoutes := append(routes, ExchangeRoutes...) allRoutes = append(allRoutes, ConfigRoutes...) diff --git a/tickerRoutes.go b/tickerRoutes.go index 7a4713e6..38c63faa 100644 --- a/tickerRoutes.go +++ b/tickerRoutes.go @@ -6,13 +6,14 @@ import ( "net/http" "github.com/gorilla/mux" + "github.com/thrasher-/gocryptotrader/exchanges/ticker" ) func jsonTickerResponse(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) currency := vars["currency"] exchangeName := vars["exchangeName"] - var response TickerPrice + var response ticker.TickerPrice var err error for i := 0; i < len(bot.exchanges); i++ { if bot.exchanges[i] != nil { @@ -40,8 +41,8 @@ type AllEnabledExchangeCurrencies struct { } type EnabledExchangeCurrencies struct { - ExchangeName string `json:"exchangeName"` - ExchangeValues []TickerPrice `json:"exchangeValues"` + ExchangeName string `json:"exchangeName"` + ExchangeValues []ticker.TickerPrice `json:"exchangeValues"` } func getAllActiveTickersResponse(w http.ResponseWriter, r *http.Request) { diff --git a/wallet.go b/wallet.go index f886e3f2..06ab7d0f 100644 --- a/wallet.go +++ b/wallet.go @@ -1,14 +1 @@ package main - -//ExchangeAccountInfo : Generic type to hold each exchange's holdings in all enabled currencies -type ExchangeAccountInfo struct { - ExchangeName string - Currencies []ExchangeAccountCurrencyInfo -} - -//ExchangeAccountCurrencyInfo : Sub type to store currency name and value -type ExchangeAccountCurrencyInfo struct { - CurrencyName string - TotalValue float64 - Hold float64 -} diff --git a/walletRoutes.go b/walletRoutes.go index 7fcefc5c..9937e90b 100644 --- a/walletRoutes.go +++ b/walletRoutes.go @@ -4,10 +4,12 @@ import ( "encoding/json" "log" "net/http" + + "github.com/thrasher-/gocryptotrader/exchanges" ) type AllEnabledExchangeAccounts struct { - Data []ExchangeAccountInfo `json:"data"` + Data []exchange.ExchangeAccountInfo `json:"data"` } func GetAllEnabledAccountInfo(w http.ResponseWriter, r *http.Request) {