Added static/dynamic fee values/methods for all exchanges.

This commit is contained in:
Adrian Gallagher
2015-02-24 17:53:56 +11:00
parent 660dbb3337
commit 92abe3bd95
10 changed files with 169 additions and 26 deletions

View File

@@ -34,6 +34,7 @@ const (
BITFINEX_CLAIM_POSITION = "position/claim"
BITFINEX_HISTORY = "history"
BITFINEX_TRADE_HISTORY = "mytrades"
BITFINEX_ACCOUNT_INFO = "account_infos"
)
type BitfinexStats struct {
@@ -56,6 +57,12 @@ type BookStructure struct {
Price, Amount, Timestamp string
}
type BitfinexFee struct {
Currency string
TakerFees float64
MakerFees float64
}
type BitfinexOrderbook struct {
Bids []BookStructure
Asks []BookStructure
@@ -80,6 +87,7 @@ type Bitfinex struct {
Orderbook BitfinexOrderbook
Trades []TradeStructure
SymbolsDetails []SymbolsDetails
Fees []BitfinexFee
}
func (b *Bitfinex) SetDefaults() {
@@ -104,7 +112,52 @@ func (b *Bitfinex) SetAPIKeys(apiKey, apiSecret string) {
b.APISecret = apiSecret
}
func (b *Bitfinex) SendAuthenticatedHTTPRequest(path string, params map[string]interface{}) (err error) {
func (b *Bitfinex) GetFee(maker bool, symbol string) (float64, error) {
for _, i := range b.Fees {
if symbol == i.Currency {
if maker {
return i.MakerFees, nil
} else {
return i.TakerFees, nil
}
}
}
return 0, errors.New("Unable to find specified currency.")
}
func (b *Bitfinex) GetAccountFeeInfo() (bool, error) {
type Fee struct {
Pairs string `json:"pairs"`
MakerFees string `json:"maker_fees"`
TakerFees string `json:"taker_fees"`
}
type Response struct {
Data []map[string][]Fee
}
var resp Response
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ACCOUNT_INFO, nil, &resp.Data)
if err != nil {
return false, err
}
Fees := []BitfinexFee{}
for _, i := range resp.Data[0]["fees"] {
var bfxFee BitfinexFee
bfxFee.Currency = i.Pairs
bfxFee.MakerFees, _ = strconv.ParseFloat(i.MakerFees, 64)
bfxFee.TakerFees, _ = strconv.ParseFloat(i.TakerFees, 64)
Fees = append(Fees, bfxFee)
}
b.Fees = Fees
return true, nil
}
func (b *Bitfinex) SendAuthenticatedHTTPRequest(path string, params map[string]interface{}, result interface{}) (err error) {
request := make(map[string]interface{})
request["request"] = "/v1/" + path
request["nonce"] = strconv.FormatInt(time.Now().UnixNano(), 10)
@@ -147,7 +200,13 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(path string, params map[string]i
}
contents, _ := ioutil.ReadAll(resp.Body)
log.Printf("Recieved raw: %s\n", string(contents))
log.Printf("Recieved raw: \n%s\n", string(contents))
err = json.Unmarshal(contents, &result)
if err != nil {
return errors.New("Unable to JSON response.")
}
resp.Body.Close()
return nil
}
@@ -212,7 +271,7 @@ func (b *Bitfinex) NewDeposit(Symbol, Method, Wallet string) {
request["method"] = Method
request["wallet_name"] = Wallet
err := b.SendAuthenticatedHTTPRequest(BITFINEX_DEPOSIT, request)
err := b.SendAuthenticatedHTTPRequest(BITFINEX_DEPOSIT, request, nil)
if err != nil {
fmt.Println(err)
@@ -235,7 +294,7 @@ func (b *Bitfinex) NewOrder(Symbol string, Amount float64, Price float64, Buy bo
//request["is_hidden"] - currently not implemented
request["type"] = Type
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_NEW, request)
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_NEW, request, nil)
if err != nil {
fmt.Println(err)
@@ -246,7 +305,7 @@ func (b *Bitfinex) CancelOrder(OrderID int) {
request := make(map[string]interface{})
request["order_id"] = OrderID
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_CANCEL, request)
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_CANCEL, request, nil)
if err != nil {
fmt.Println(err)
@@ -257,7 +316,7 @@ func (b *Bitfinex) CancelMultiplateOrders(OrderIDs []int) {
request := make(map[string]interface{})
request["order_ids"] = OrderIDs
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_CANCEL, request)
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_CANCEL, request, nil)
if err != nil {
fmt.Println(err)
@@ -265,7 +324,7 @@ func (b *Bitfinex) CancelMultiplateOrders(OrderIDs []int) {
}
func (b *Bitfinex) CancelAllOrders() {
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_CANCEL_ALL, nil)
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_CANCEL_ALL, nil, nil)
if err != nil {
fmt.Println(err)
@@ -281,7 +340,7 @@ func (b *Bitfinex) GetOrderStatus(OrderID int) {
request := make(map[string]interface{})
request["order_id"] = OrderID
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_STATUS, request)
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDER_STATUS, request, nil)
if err != nil {
fmt.Println(err)
@@ -289,7 +348,7 @@ func (b *Bitfinex) GetOrderStatus(OrderID int) {
}
func (b *Bitfinex) GetActiveOrders() {
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDERS, nil)
err := b.SendAuthenticatedHTTPRequest(BITFINEX_ORDERS, nil, nil)
if err != nil {
fmt.Println(err)
@@ -297,7 +356,7 @@ func (b *Bitfinex) GetActiveOrders() {
}
func (b *Bitfinex) GetActivePositions() {
err := b.SendAuthenticatedHTTPRequest(BITFINEX_POSITIONS, nil)
err := b.SendAuthenticatedHTTPRequest(BITFINEX_POSITIONS, nil, nil)
if err != nil {
fmt.Println(err)
@@ -308,7 +367,7 @@ func (b *Bitfinex) ClaimPosition(PositionID int) {
request := make(map[string]interface{})
request["position_id"] = PositionID
err := b.SendAuthenticatedHTTPRequest(BITFINEX_CLAIM_POSITION, nil)
err := b.SendAuthenticatedHTTPRequest(BITFINEX_CLAIM_POSITION, nil, nil)
if err != nil {
fmt.Println(err)
@@ -329,7 +388,7 @@ func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince time.Time, timeUnt
request["wallet"] = wallet
}
err := b.SendAuthenticatedHTTPRequest(BITFINEX_HISTORY, request)
err := b.SendAuthenticatedHTTPRequest(BITFINEX_HISTORY, request, nil)
if err != nil {
fmt.Println(err)
@@ -345,7 +404,7 @@ func (b *Bitfinex) GetTradeHistory(symbol string, timestamp time.Time, limit int
request["limit_trades"] = limit
}
err := b.SendAuthenticatedHTTPRequest(BITFINEX_TRADE_HISTORY, nil)
err := b.SendAuthenticatedHTTPRequest(BITFINEX_TRADE_HISTORY, nil, nil)
if err != nil {
fmt.Println(err)

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"log"
"encoding/hex"
"encoding/json"
"crypto/hmac"
"crypto/sha256"
"strings"
@@ -43,6 +44,8 @@ type Bitstamp struct {
Orderbook Orderbook
ConversionRate ConversionRate
Transactions []Transactions
Balance BitstampAccountBalance
TakerFee, MakerFee float64
}
type BitstampTicker struct {
@@ -55,6 +58,16 @@ type BitstampTicker struct {
Ask float64 `json:",string"`
}
type BitstampAccountBalance struct {
BTCReserved float64 `json:"usd_balance,string"`
Fee float64 `json:",string"`
BTCAvailable float64 `json:"btc_balance,string"`
USDReserved float64 `json:"usd_reserved,string"`
BTCBalance float64 `json:"btc_balance,string"`
USDBalance float64 `json:"usd_balance,string"`
USDAvailable float64 `json:"usd_available,string"`
}
type Orderbook struct {
Timestamp string
Bids [][]string
@@ -88,6 +101,10 @@ func (b *Bitstamp) IsEnabled() (bool) {
return b.Enabled
}
func (b *Bitstamp) GetFee() (float64) {
return b.Balance.Fee
}
func (b *Bitstamp) SetAPIKeys(clientID, apiKey, apiSecret string) {
b.ClientID = clientID
b.APIKey = apiKey
@@ -133,7 +150,7 @@ func (b *Bitstamp) GetEURUSDConversionRate() {
}
func (b *Bitstamp) GetBalance() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BALANCE, url.Values{})
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BALANCE, url.Values{}, &b.Balance)
if err != nil {
fmt.Println(err)
@@ -147,7 +164,7 @@ func (b *Bitstamp) GetUserTransactions(offset, limit, sort int64) {
req.Add("limit", strconv.FormatInt(limit, 10))
req.Add("sort", strconv.FormatInt(sort, 10))
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_USER_TRANSACTIONS, req)
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_USER_TRANSACTIONS, req, nil)
if err != nil {
fmt.Println(err)
@@ -158,7 +175,7 @@ func (b *Bitstamp) CancelOrder(OrderID int64) {
var req = url.Values{}
req.Add("id", strconv.FormatInt(OrderID, 10))
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_CANCEL_ORDER, req)
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_CANCEL_ORDER, req, nil)
if err != nil {
fmt.Println(err)
@@ -166,7 +183,7 @@ func (b *Bitstamp) CancelOrder(OrderID int64) {
}
func (b *Bitstamp) GetOpenOrders() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_OPEN_ORDERS, url.Values{})
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_OPEN_ORDERS, url.Values{}, nil)
if err != nil {
fmt.Println(err)
@@ -185,7 +202,7 @@ func (b *Bitstamp) PlaceOrder(price float64, amount float64, Type int) {
log.Printf("Placing %s order at price %f for %f amount.\n", orderType, price, amount)
err := b.SendAuthenticatedHTTPRequest(orderType, req)
err := b.SendAuthenticatedHTTPRequest(orderType, req, nil)
if err != nil {
fmt.Println(err)
@@ -193,7 +210,7 @@ func (b *Bitstamp) PlaceOrder(price float64, amount float64, Type int) {
}
func (b *Bitstamp) GetWithdrawalRequests() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_WITHDRAWAL_REQUESTS, url.Values{})
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_WITHDRAWAL_REQUESTS, url.Values{}, nil)
if err != nil {
fmt.Println(err)
@@ -205,7 +222,7 @@ func (b *Bitstamp) BitcoinWithdrawal(amount float64, address string) {
req.Add("amount", strconv.FormatFloat(amount, 'f', 8, 64))
req.Add("address", address)
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BITCOIN_WITHDRAWAL, req)
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BITCOIN_WITHDRAWAL, req, nil)
if err != nil {
fmt.Println(err)
@@ -213,7 +230,7 @@ func (b *Bitstamp) BitcoinWithdrawal(amount float64, address string) {
}
func (b *Bitstamp) BitcoinDepositAddress() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BITCOIN_DEPOSIT, url.Values{})
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_BITCOIN_DEPOSIT, url.Values{}, nil)
if err != nil {
fmt.Println(err)
@@ -221,7 +238,7 @@ func (b *Bitstamp) BitcoinDepositAddress() {
}
func (b *Bitstamp) UnconfirmedBitcoin() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_UNCONFIRMED_BITCOIN, url.Values{})
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_UNCONFIRMED_BITCOIN, url.Values{}, nil)
if err != nil {
fmt.Println(err)
@@ -234,7 +251,7 @@ func (b *Bitstamp) RippleWithdrawal(amount float64, address, currency string) {
req.Add("address", address)
req.Add("currency", currency)
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_RIPPLE_WITHDRAWAL, req)
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_RIPPLE_WITHDRAWAL, req, nil)
if err != nil {
fmt.Println(err)
@@ -242,21 +259,20 @@ func (b *Bitstamp) RippleWithdrawal(amount float64, address, currency string) {
}
func (b *Bitstamp) RippleDepositAddress() {
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_RIPPLE_DESPOIT, url.Values{})
err := b.SendAuthenticatedHTTPRequest(BITSTAMP_API_RIPPLE_DESPOIT, url.Values{}, nil)
if err != nil {
fmt.Println(err)
}
}
func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, values url.Values) (err error) {
func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, values url.Values, result interface{}) (err error) {
nonce := strconv.FormatInt(time.Now().UnixNano(), 10)
values.Set("key", b.APIKey)
values.Set("nonce", nonce)
hmac := hmac.New(sha256.New, []byte(b.APISecret))
hmac.Write([]byte(nonce + b.ClientID + b.APIKey))
values.Set("signature", strings.ToUpper(hex.EncodeToString(hmac.Sum(nil))))
reqBody := strings.NewReader(values.Encode())
path = BITSTAMP_API_URL + path
@@ -278,6 +294,13 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, values url.Values)
contents, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Recieved raw: %s\n", string(contents))
err = json.Unmarshal(contents, &result)
if err != nil {
return errors.New("Unable to JSON response.")
}
resp.Body.Close()
return nil
}

View File

@@ -25,6 +25,7 @@ type BTCChina struct {
Name string
Enabled bool
APISecret, APIKey string
Fee float64
}
type BTCChinaTicker struct {
@@ -43,6 +44,7 @@ type BTCChinaTicker struct {
func (b *BTCChina) SetDefaults() {
b.Name = "BTC China"
b.Enabled = true
b.Fee = 0
}
func (b *BTCChina) GetName() (string) {
@@ -62,6 +64,10 @@ func (b *BTCChina) SetAPIKeys(apiKey, apiSecret string) {
b.APISecret = apiSecret
}
func (b *BTCChina) GetFee() (float64) {
return b.Fee
}
func (b *BTCChina) GetTicker(symbol string) (BTCChinaTicker) {
type Response struct {
Ticker BTCChinaTicker

View File

@@ -28,6 +28,7 @@ type BTCE struct {
Name string
Enabled bool
APIKey, APISecret string
Fee float64
}
type BTCeTicker struct {
@@ -46,6 +47,7 @@ type BTCeTicker struct {
func (b *BTCE) SetDefaults() {
b.Name = "BTCE"
b.Enabled = true
b.Fee = 0.2
}
func (b *BTCE) GetName() (string) {
@@ -65,6 +67,10 @@ func (b *BTCE) SetAPIKeys(apiKey, apiSecret string) {
b.APISecret = apiSecret
}
func (b *BTCE) GetFee() (float64) {
return b.Fee
}
func (b *BTCE) GetTicker(symbol string) (BTCeTicker) {
type Response struct {
Ticker BTCeTicker

View File

@@ -21,6 +21,7 @@ const (
type BTCMarkets struct {
Name string
Enabled bool
Fee float64
APIKey, APISecret string
}
@@ -36,6 +37,7 @@ type BTCMarketsTicker struct {
func (b *BTCMarkets) SetDefaults() {
b.Name = "BTC Markets"
b.Enabled = true
b.Fee = 0.85
}
func (b *BTCMarkets) GetName() (string) {
@@ -55,6 +57,10 @@ func (b *BTCMarkets) SetAPIKeys(apiKey, apiSecret string) {
b.APISecret = apiSecret
}
func (b *BTCMarkets) GetFee() (float64) {
return b.Fee
}
func (b *BTCMarkets) GetTicker(symbol string) (BTCMarketsTicker) {
ticker := BTCMarketsTicker{}
path := fmt.Sprintf("/market/%s/AUD/tick", symbol)

View File

@@ -21,6 +21,7 @@ type HUOBI struct {
Name string
Enabled bool
AccessKey, SecretKey string
Fee float64
}
type HuobiTicker struct {
@@ -40,6 +41,7 @@ type HuobiTickerResponse struct {
func (h *HUOBI) SetDefaults() {
h.Name = "Huobi"
h.Enabled = true
h.Fee = 0
}
func (h *HUOBI) GetName() (string) {
@@ -59,6 +61,10 @@ func (h *HUOBI) SetAPIKeys(apiKey, apiSecret string) {
h.SecretKey = apiSecret
}
func (h *HUOBI) GetFee() (float64) {
return h.Fee
}
func (h *HUOBI) GetTicker(symbol string) (HuobiTicker) {
resp := HuobiTickerResponse{}
path := fmt.Sprintf("http://market.huobi.com/staticmarket/ticker_%s_json.js", symbol)

View File

@@ -24,6 +24,7 @@ type ItBit struct {
Name string
Enabled bool
ClientKey, APISecret, UserID string
MakerFee, TakerFee float64
}
type ItBitTicker struct {
@@ -49,6 +50,8 @@ type ItBitTicker struct {
func (i *ItBit) SetDefaults() {
i.Name = "ITBIT"
i.Enabled = true
i.MakerFee = -0.10
i.TakerFee = 0.50
}
func (i *ItBit) GetName() (string) {
@@ -68,6 +71,14 @@ func (i *ItBit) SetAPIKeys(apiKey, apiSecret string) {
i.APISecret = apiSecret
}
func (i *ItBit) GetFee(maker bool) (float64) {
if maker {
return i.MakerFee
} else {
return i.TakerFee
}
}
func (i *ItBit) GetTicker(currency string) (ItBitTicker) {
path := ITBIT_API_URL + "/markets/" + currency + "/ticker"
var itbitTicker ItBitTicker

View File

@@ -33,6 +33,7 @@ type LakeBTC struct {
Name string
Enabled bool
Email, APISecret string
TakerFee, MakerFee float64
}
type LakeBTCTicker struct {
@@ -51,6 +52,8 @@ type LakeBTCTickerResponse struct {
func (l *LakeBTC) SetDefaults() {
l.Name = "LakeBTC"
l.Enabled = true
l.TakerFee = 0.2
l.MakerFee = 0.15
}
func (l *LakeBTC) GetName() (string) {
@@ -70,6 +73,14 @@ func (l *LakeBTC) SetAPIKeys(apiKey, apiSecret string) {
l.APISecret = apiSecret
}
func (l *LakeBTC) GetFee(maker bool) (float64) {
if (maker) {
return l.MakerFee
} else {
return l.TakerFee
}
}
func (l *LakeBTC) GetTicker() (LakeBTCTickerResponse) {
response := LakeBTCTickerResponse{}
err := SendHTTPRequest(LAKEBTC_API_URL + LAKEBTC_TICKER, true, &response)

View File

@@ -77,6 +77,7 @@ func main() {
} else {
log.Printf("%s enabled.\n", exch.Name)
exchange.bitstamp.SetAPIKeys(exch.ClientID, exch.APIKey, exch.APISecret)
exchange.bitstamp.GetBalance()
}
} else if exchange.bitfinex.GetName() == exch.Name {
if !exch.Enabled {
@@ -85,6 +86,7 @@ func main() {
} else {
log.Printf("%s enabled.\n", exch.Name)
exchange.bitfinex.SetAPIKeys(exch.APIKey, exch.APISecret)
exchange.bitfinex.GetAccountFeeInfo()
}
} else if exchange.btce.GetName() == exch.Name {
if !exch.Enabled {

View File

@@ -21,6 +21,7 @@ type OKCoin struct {
Name string
Enabled bool
APIUrl, PartnerID, SecretKey string
TakerFee, MakerFee float64
}
type OKCoinTicker struct {
@@ -82,6 +83,18 @@ func (o *OKCoin) SetAPIKeys(apiKey, apiSecret string) {
o.SecretKey = apiSecret
}
func (o *OKCoin) GetFee(maker bool) (float64) {
if (o.APIUrl == OKCOIN_API_URL) {
if maker {
return o.MakerFee
} else {
return o.TakerFee
}
}
// Chinese exchange does not have any trading fees
return 0
}
func (o *OKCoin) GetTicker(symbol string) (OKCoinTicker) {
resp := OKCoinTickerResponse{}
path := fmt.Sprintf("ticker.do?symbol=%s&ok=1", symbol)