Files
gocryptotrader/bitfinexhttp.go
GloriousCode 7223875230 Now adds a universal way to retrieve all enabled currencies
New endpoint to retrieve values for all enabled currency data for all enabled exchanges and return it as JSON object for front end
2016-07-13 21:43:48 +10:00

959 lines
26 KiB
Go

package main
import (
"errors"
"fmt"
"log"
"net/url"
"strconv"
"strings"
"time"
"github.com/gorilla/websocket"
)
const (
BITFINEX_API_URL = "https://api.bitfinex.com/v1/"
BITFINEX_API_VERSION = "1"
BITFINEX_TICKER = "pubticker/"
BITFINEX_STATS = "stats/"
BITFINEX_LENDBOOK = "lendbook/"
BITFINEX_ORDERBOOK = "book/"
BITFINEX_TRADES = "trades/"
BITFINEX_LENDS = "lends/"
BITFINEX_SYMBOLS = "symbols/"
BITFINEX_SYMBOLS_DETAILS = "symbols_details/"
BITFINEX_ACCOUNT_INFO = "account_infos"
BITFINEX_DEPOSIT = "deposit/new"
BITFINEX_ORDER_NEW = "order/new"
BITFINEX_ORDER_NEW_MULTI = "order/new/multi"
BITFINEX_ORDER_CANCEL = "order/cancel"
BITFINEX_ORDER_CANCEL_MULTI = "order/cancel/multi"
BITFINEX_ORDER_CANCEL_ALL = "order/cancel/all"
BITFINEX_ORDER_CANCEL_REPLACE = "order/cancel/replace"
BITFINEX_ORDER_STATUS = "order/status"
BITFINEX_ORDERS = "orders"
BITFINEX_POSITIONS = "positions"
BITFINEX_CLAIM_POSITION = "position/claim"
BITFINEX_HISTORY = "history"
BITFINEX_HISTORY_MOVEMENTS = "history/movements"
BITFINEX_TRADE_HISTORY = "mytrades"
BITFINEX_OFFER_NEW = "offer/new"
BITFINEX_OFFER_CANCEL = "offer/cancel"
BITFINEX_OFFER_STATUS = "offer/status"
BITFINEX_OFFERS = "offers"
BITFINEX_MARGIN_ACTIVE_FUNDS = "taken_funds"
BITFINEX_MARGIN_TOTAL_FUNDS = "total_taken_funds"
BITFINEX_MARGIN_CLOSE = "funding/close"
BITFINEX_BALANCES = "balances"
BITFINEX_MARGIN_INFO = "margin_infos"
BITFINEX_TRANSFER = "transfer"
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 {
Name string
Enabled bool
Verbose bool
Websocket bool
RESTPollingDelay time.Duration
AuthenticatedAPISupport bool
APIKey, APISecret string
ActiveOrders []BitfinexOrder
BaseCurrencies []string
AvailablePairs []string
EnabledPairs []string
WebsocketConn *websocket.Conn
WebsocketSubdChannels map[int]BitfinexWebsocketChanInfo
}
func (b *Bitfinex) SetDefaults() {
b.Name = "Bitfinex"
b.Enabled = false
b.Verbose = false
b.Websocket = false
b.RESTPollingDelay = 10
b.WebsocketSubdChannels = make(map[int]BitfinexWebsocketChanInfo)
}
func (b *Bitfinex) GetName() string {
return b.Name
}
func (b *Bitfinex) Setup(exch Exchanges) {
if !exch.Enabled {
b.SetEnabled(false)
} else {
b.Enabled = true
b.AuthenticatedAPISupport = exch.AuthenticatedAPISupport
b.SetAPIKeys(exch.APIKey, exch.APISecret)
b.RESTPollingDelay = exch.RESTPollingDelay
b.Verbose = exch.Verbose
b.Websocket = exch.Websocket
b.BaseCurrencies = SplitStrings(exch.BaseCurrencies, ",")
b.AvailablePairs = SplitStrings(exch.AvailablePairs, ",")
b.EnabledPairs = SplitStrings(exch.EnabledPairs, ",")
}
}
func (k *Bitfinex) GetEnabledCurrencies() []string {
return k.EnabledPairs
}
func (b *Bitfinex) Start() {
go b.Run()
}
func (b *Bitfinex) SetEnabled(enabled bool) {
b.Enabled = enabled
}
func (b *Bitfinex) IsEnabled() bool {
return b.Enabled
}
func (b *Bitfinex) SetAPIKeys(apiKey, apiSecret string) {
b.APIKey = apiKey
b.APISecret = apiSecret
}
func (b *Bitfinex) Run() {
if b.Verbose {
log.Printf("%s Websocket: %s.", b.GetName(), 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 = SplitStrings(StringToUpper(JoinStrings(exchangeProducts, ",")), ",")
diff := StringSliceDifference(b.AvailablePairs, exchangeProducts)
if len(diff) > 0 {
exch, err := GetExchangeConfig(b.Name)
if err != nil {
log.Println(err)
} else {
log.Printf("%s Updating available pairs. Difference: %s.\n", b.Name, diff)
exch.AvailablePairs = JoinStrings(exchangeProducts, ",")
UpdateExchangeConfig(exch)
}
}
}
for b.Enabled {
for _, x := range b.EnabledPairs {
currency := x
go func() {
ticker, err := b.GetTicker(currency, nil)
if err != nil {
log.Println(err)
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 := EncodeURLValues(BITFINEX_API_URL+BITFINEX_TICKER+symbol, values)
response := BitfinexTicker{}
err := SendHTTPGetRequest(path, true, &response)
if err != nil {
return response, err
}
return response, nil
}
func (b *Bitfinex) GetTickerPrice(currency string) TickerPrice {
var tickerPrice TickerPrice
ticker, err := b.GetTicker(currency, nil)
if err != nil {
log.Println(err)
return tickerPrice
}
tickerPrice.Ask = ticker.Ask
tickerPrice.Bid = ticker.Bid
tickerPrice.CryptoCurrency = currency
tickerPrice.Low = ticker.Low
tickerPrice.Last = ticker.Last
tickerPrice.Volume = ticker.Volume
tickerPrice.High = ticker.High
return tickerPrice
}
type BitfinexLendbookBidAsk struct {
Rate float64 `json:"rate,string"`
Amount float64 `json:"amount,string"`
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 := SendHTTPGetRequest(BITFINEX_API_URL+BITFINEX_STATS+symbol, true, &response)
if err != nil {
return response, err
}
return response, nil
}
func (b *Bitfinex) GetLendbook(symbol string, values url.Values) (BitfinexLendbook, error) {
path := EncodeURLValues(BITFINEX_API_URL+BITFINEX_LENDBOOK+symbol, values)
response := BitfinexLendbook{}
err := SendHTTPGetRequest(path, true, &response)
if err != nil {
return response, err
}
return response, nil
}
func (b *Bitfinex) GetOrderbook(symbol string, values url.Values) (BitfinexOrderbook, error) {
path := EncodeURLValues(BITFINEX_API_URL+BITFINEX_ORDERBOOK+symbol, values)
response := BitfinexOrderbook{}
err := SendHTTPGetRequest(path, true, &response)
if err != nil {
return response, err
}
return response, nil
}
func (b *Bitfinex) GetTrades(symbol string, values url.Values) ([]BitfinexTradeStructure, error) {
path := EncodeURLValues(BITFINEX_API_URL+BITFINEX_TRADES+symbol, values)
response := []BitfinexTradeStructure{}
err := SendHTTPGetRequest(path, true, &response)
if err != nil {
return nil, err
}
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 := EncodeURLValues(BITFINEX_API_URL+BITFINEX_LENDS+symbol, values)
response := []BitfinexLends{}
err := SendHTTPGetRequest(path, true, &response)
if err != nil {
return nil, err
}
return response, nil
}
func (b *Bitfinex) GetSymbols() ([]string, error) {
products := []string{}
err := SendHTTPGetRequest(BITFINEX_API_URL+BITFINEX_SYMBOLS, true, &products)
if err != nil {
return nil, err
}
return products, nil
}
func (b *Bitfinex) GetSymbolsDetails() ([]BitfinexSymbolDetails, error) {
response := []BitfinexSymbolDetails{}
err := SendHTTPGetRequest(BITFINEX_API_URL+BITFINEX_SYMBOLS_DETAILS, true, &response)
if err != nil {
return nil, err
}
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)
if err != nil {
log.Println(err)
}
log.Println(response)
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
request["wallet_name"] = walletName
request["renew"] = renew
response := BitfinexDepositResponse{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_DEPOSIT, request, &response)
if err != nil {
return response, err
}
return response, nil
}
func (b *Bitfinex) NewOrder(Symbol string, Amount float64, Price float64, Buy bool, Type string, Hidden bool) (BitfinexOrder, error) {
request := make(map[string]interface{})
request["symbol"] = Symbol
request["amount"] = strconv.FormatFloat(Amount, 'f', -1, 64)
request["price"] = strconv.FormatFloat(Price, 'f', -1, 64)
request["exchange"] = "bitfinex"
if Buy {
request["side"] = "buy"
} else {
request["side"] = "sell"
}
request["type"] = Type
//request["is_hidden"] = Hidden
response := BitfinexOrder{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_NEW, request, &response)
if err != nil {
return response, err
}
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
response := BitfinexOrderMultiResponse{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_NEW_MULTI, request, &response)
if err != nil {
return response, err
}
return response, nil
}
func (b *Bitfinex) CancelOrder(OrderID int64) (BitfinexOrder, error) {
request := make(map[string]interface{})
request["order_id"] = OrderID
response := BitfinexOrder{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_CANCEL, request, &response)
if err != nil {
return response, err
}
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
response := BitfinexGenericResponse{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_CANCEL_MULTI, request, nil)
if err != nil {
return "", err
}
return response.Result, nil
}
func (b *Bitfinex) CancelAllOrders() (string, error) {
response := BitfinexGenericResponse{}
err := b.SendAuthenticatedHTTPRequest("GET", BITFINEX_ORDER_CANCEL_ALL, nil, nil)
if err != nil {
return "", err
}
return response.Result, nil
}
func (b *Bitfinex) ReplaceOrder(OrderID int64, Symbol string, Amount float64, Price float64, Buy bool, Type string, Hidden bool) (BitfinexOrder, error) {
request := make(map[string]interface{})
request["order_id"] = OrderID
request["symbol"] = Symbol
request["amount"] = strconv.FormatFloat(Amount, 'f', -1, 64)
request["price"] = strconv.FormatFloat(Price, 'f', -1, 64)
request["exchange"] = "bitfinex"
if Buy {
request["side"] = "buy"
} else {
request["side"] = "sell"
}
request["type"] = Type
//request["is_hidden"] = Hidden
response := BitfinexOrder{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_CANCEL_REPLACE, request, &response)
if err != nil {
return response, err
}
return response, nil
}
func (b *Bitfinex) GetOrderStatus(OrderID int64) (BitfinexOrder, error) {
request := make(map[string]interface{})
request["order_id"] = OrderID
orderStatus := BitfinexOrder{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_STATUS, request, &orderStatus)
if err != nil {
return orderStatus, err
}
return orderStatus, err
}
func (b *Bitfinex) GetActiveOrders() ([]BitfinexOrder, error) {
response := []BitfinexOrder{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDERS, nil, &response)
if err != nil {
return nil, err
}
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)
if err != nil {
return nil, err
}
return response, nil
}
func (b *Bitfinex) ClaimPosition(PositionID int) (BitfinexPosition, error) {
request := make(map[string]interface{})
request["position_id"] = PositionID
response := BitfinexPosition{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_CLAIM_POSITION, nil, nil)
if err != nil {
return BitfinexPosition{}, err
}
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
if !timeSince.IsZero() {
request["since"] = timeSince
}
if !timeUntil.IsZero() {
request["until"] = timeUntil
}
if limit > 0 {
request["limit"] = limit
}
if len(wallet) > 0 {
request["wallet"] = wallet
}
response := []BitfinexBalanceHistory{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_HISTORY, request, &response)
if err != nil {
return nil, err
}
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
if len(method) > 0 {
request["method"] = method
}
if !timeSince.IsZero() {
request["since"] = timeSince
}
if !timeUntil.IsZero() {
request["until"] = timeUntil
}
if limit > 0 {
request["limit"] = limit
}
response := []BitfinexMovementHistory{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_HISTORY_MOVEMENTS, request, &response)
if err != nil {
return nil, err
}
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
request["timestamp"] = timestamp
if !until.IsZero() {
request["until"] = until
}
if limit > 0 {
request["limit"] = limit
}
if reverse > 0 {
request["reverse"] = reverse
}
response := []BitfinexTradeHistory{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_TRADE_HISTORY, request, &response)
if err != nil {
return nil, err
}
return response, nil
}
func (b *Bitfinex) NewOffer(symbol string, amount, rate float64, period int64, direction string) int64 {
request := make(map[string]interface{})
request["currency"] = symbol
request["amount"] = amount
request["rate"] = rate
request["period"] = period
request["direction"] = direction
type OfferResponse struct {
Offer_Id int64
}
response := OfferResponse{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_OFFER_NEW, request, &response)
if err != nil {
log.Println(err)
return 0
}
return response.Offer_Id
}
func (b *Bitfinex) CancelOffer(OfferID int64) (BitfinexOffer, error) {
request := make(map[string]interface{})
request["offer_id"] = OfferID
response := BitfinexOffer{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_OFFER_CANCEL, request, &response)
if err != nil {
return response, err
}
return response, nil
}
func (b *Bitfinex) GetOfferStatus(OfferID int64) (BitfinexOffer, error) {
request := make(map[string]interface{})
request["offer_id"] = OfferID
response := BitfinexOffer{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_STATUS, request, &response)
if err != nil {
return response, err
}
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)
if err != nil {
return nil, err
}
return response, nil
}
func (b *Bitfinex) GetActiveMarginFunding() ([]BitfinexMarginFunds, error) {
response := []BitfinexMarginFunds{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_MARGIN_ACTIVE_FUNDS, nil, &response)
if err != nil {
return nil, err
}
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)
if err != nil {
return nil, err
}
return response, nil
}
func (b *Bitfinex) CloseMarginFunding(SwapID int64) (BitfinexOffer, error) {
request := make(map[string]interface{})
request["swap_id"] = SwapID
response := BitfinexOffer{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_MARGIN_CLOSE, request, &response)
if err != nil {
return response, err
}
return response, nil
}
func (b *Bitfinex) GetAccountBalance() ([]BitfinexBalance, error) {
response := []BitfinexBalance{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_BALANCES, nil, &response)
if err != nil {
return nil, err
}
return response, nil
}
func (b *Bitfinex) GetMarginInfo() ([]BitfinexMarginInfo, error) {
response := []BitfinexMarginInfo{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_MARGIN_INFO, nil, &response)
if err != nil {
return nil, err
}
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
request["currency"] = currency
request["walletfrom"] = walletFrom
request["walletTo"] = walletTo
response := []BitfinexWalletTransfer{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_TRANSFER, request, &response)
if err != nil {
return nil, err
}
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
request["walletselected"] = wallet
request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64)
request["address"] = address
response := []BitfinexWithdrawal{}
err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_WITHDRAWAL, request, &response)
if err != nil {
return nil, err
}
return response, nil
}
func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[string]interface{}, result interface{}) (err error) {
request := make(map[string]interface{})
request["request"] = fmt.Sprintf("/v%s/%s", BITFINEX_API_VERSION, path)
request["nonce"] = strconv.FormatInt(time.Now().UnixNano(), 10)
if params != nil {
for key, value := range params {
request[key] = value
}
}
PayloadJson, err := JSONEncode(request)
if err != nil {
return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request")
}
if b.Verbose {
log.Printf("Request JSON: %s\n", PayloadJson)
}
PayloadBase64 := Base64Encode(PayloadJson)
hmac := GetHMAC(HASH_SHA512_384, []byte(PayloadBase64), []byte(b.APISecret))
headers := make(map[string]string)
headers["X-BFX-APIKEY"] = b.APIKey
headers["X-BFX-PAYLOAD"] = PayloadBase64
headers["X-BFX-SIGNATURE"] = HexEncodeToString(hmac)
resp, err := SendHTTPRequest(method, BITFINEX_API_URL+path, headers, strings.NewReader(""))
if b.Verbose {
log.Printf("Recieved raw: \n%s\n", resp)
}
err = JSONDecode([]byte(resp), &result)
if err != nil {
return errors.New("Unable to JSON Unmarshal response.")
}
return nil
}