mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-14 15:09:51 +00:00
New endpoint to retrieve values for all enabled currency data for all enabled exchanges and return it as JSON object for front end
959 lines
26 KiB
Go
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
|
|
}
|