mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-16 23:16:48 +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
1031 lines
26 KiB
Go
1031 lines
26 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"net/url"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
POLONIEX_API_URL = "https://poloniex.com"
|
|
POLONIEX_API_TRADING_ENDPOINT = "tradingApi"
|
|
POLONIEX_API_VERSION = "1"
|
|
POLONIEX_BALANCES = "returnBalances"
|
|
POLONIEX_BALANCES_COMPLETE = "returnCompleteBalances"
|
|
POLONIEX_DEPOSIT_ADDRESSES = "returnDepositAddresses"
|
|
POLONIEX_GENERATE_NEW_ADDRESS = "generateNewAddress"
|
|
POLONIEX_DEPOSITS_WITHDRAWALS = "returnDepositsWithdrawals"
|
|
POLONIEX_ORDERS = "returnOpenOrders"
|
|
POLONIEX_TRADE_HISTORY = "returnTradeHistory"
|
|
POLONIEX_ORDER_BUY = "buy"
|
|
POLONIEX_ORDER_SELL = "sell"
|
|
POLONIEX_ORDER_CANCEL = "cancelOrder"
|
|
POLONIEX_ORDER_MOVE = "moveOrder"
|
|
POLONIEX_WITHDRAW = "withdraw"
|
|
POLONIEX_FEE_INFO = "returnFeeInfo"
|
|
POLONIEX_AVAILABLE_BALANCES = "returnAvailableAccountBalances"
|
|
POLONIEX_TRADABLE_BALANCES = "returnTradableBalances"
|
|
POLONIEX_TRANSFER_BALANCE = "transferBalance"
|
|
POLONIEX_MARGIN_ACCOUNT_SUMMARY = "returnMarginAccountSummary"
|
|
POLONIEX_MARGIN_BUY = "marginBuy"
|
|
POLONIEX_MARGIN_SELL = "marginSell"
|
|
POLONIEX_MARGIN_POSITION = "getMarginPosition"
|
|
POLONIEX_MARGIN_POSITION_CLOSE = "closeMarginPosition"
|
|
POLONIEX_CREATE_LOAN_OFFER = "createLoanOffer"
|
|
POLONIEX_CANCEL_LOAN_OFFER = "cancelLoanOffer"
|
|
POLONIEX_OPEN_LOAN_OFFERS = "returnOpenLoanOffers"
|
|
POLONIEX_ACTIVE_LOANS = "returnActiveLoans"
|
|
POLONIEX_AUTO_RENEW = "toggleAutoRenew"
|
|
)
|
|
|
|
type Poloniex struct {
|
|
Name string
|
|
Enabled bool
|
|
Verbose bool
|
|
Websocket bool
|
|
RESTPollingDelay time.Duration
|
|
AuthenticatedAPISupport bool
|
|
AccessKey, SecretKey string
|
|
Fee float64
|
|
BaseCurrencies []string
|
|
AvailablePairs []string
|
|
EnabledPairs []string
|
|
}
|
|
|
|
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
|
|
p.Fee = 0
|
|
p.Verbose = false
|
|
p.Websocket = false
|
|
p.RESTPollingDelay = 10
|
|
}
|
|
|
|
func (p *Poloniex) GetName() string {
|
|
return p.Name
|
|
}
|
|
|
|
func (p *Poloniex) SetEnabled(enabled bool) {
|
|
p.Enabled = enabled
|
|
}
|
|
|
|
func (p *Poloniex) IsEnabled() bool {
|
|
return p.Enabled
|
|
}
|
|
|
|
func (p *Poloniex) Setup(exch Exchanges) {
|
|
if !exch.Enabled {
|
|
p.SetEnabled(false)
|
|
} else {
|
|
p.Enabled = true
|
|
p.AuthenticatedAPISupport = exch.AuthenticatedAPISupport
|
|
p.SetAPIKeys(exch.APIKey, exch.APISecret)
|
|
p.RESTPollingDelay = exch.RESTPollingDelay
|
|
p.Verbose = exch.Verbose
|
|
p.Websocket = exch.Websocket
|
|
p.BaseCurrencies = SplitStrings(exch.BaseCurrencies, ",")
|
|
p.AvailablePairs = SplitStrings(exch.AvailablePairs, ",")
|
|
p.EnabledPairs = SplitStrings(exch.EnabledPairs, ",")
|
|
}
|
|
}
|
|
|
|
func (k *Poloniex) GetEnabledCurrencies() []string {
|
|
return k.EnabledPairs
|
|
}
|
|
|
|
func (p *Poloniex) Start() {
|
|
go p.Run()
|
|
}
|
|
|
|
func (p *Poloniex) SetAPIKeys(apiKey, apiSecret string) {
|
|
p.AccessKey = apiKey
|
|
p.SecretKey = apiSecret
|
|
}
|
|
|
|
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(), 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.GetTicker()
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
log.Printf("Poloniex %s Last %f High %f Low %f Volume %f\n", currency, ticker[currency].Last, ticker[currency].High24Hr, ticker[currency].Low24Hr, ticker[currency].QuoteVolume)
|
|
//AddExchangeInfo(p.GetName(), currency[0:3], currency[3:], 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
|
|
}
|
|
|
|
resp := response{}
|
|
path := fmt.Sprintf("%s/public?command=returnTicker", POLONIEX_API_URL)
|
|
err := SendHTTPGetRequest(path, true, &resp.Data)
|
|
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
return resp.Data, nil
|
|
}
|
|
|
|
func (p *Poloniex) GetTickerPrice(currency string) TickerPrice {
|
|
var tickerPrice TickerPrice
|
|
ticker, err := p.GetTicker()
|
|
if err != nil {
|
|
log.Println(err)
|
|
return tickerPrice
|
|
}
|
|
tickerPrice.CryptoCurrency = currency
|
|
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
|
|
|
|
return tickerPrice
|
|
}
|
|
|
|
func (p *Poloniex) GetVolume() (interface{}, error) {
|
|
var resp interface{}
|
|
path := fmt.Sprintf("%s/public?command=return24hVolume", POLONIEX_API_URL)
|
|
err := SendHTTPGetRequest(path, true, &resp)
|
|
|
|
if err != nil {
|
|
return resp, err
|
|
}
|
|
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 {
|
|
Data map[string]PoloniexOrderbook
|
|
}
|
|
|
|
vals := url.Values{}
|
|
vals.Set("currencyPair", currencyPair)
|
|
|
|
if depth != 0 {
|
|
vals.Set("depth", strconv.Itoa(depth))
|
|
}
|
|
|
|
resp := Response{}
|
|
path := fmt.Sprintf("%s/public?command=returnOrderBook&%s", POLONIEX_API_URL, vals.Encode())
|
|
err := SendHTTPGetRequest(path, true, &resp.Data)
|
|
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
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)
|
|
|
|
if start != "" {
|
|
vals.Set("start", start)
|
|
}
|
|
|
|
if end != "" {
|
|
vals.Set("end", end)
|
|
}
|
|
|
|
resp := []PoloniexTradeHistory{}
|
|
path := fmt.Sprintf("%s/public?command=returnTradeHistory&%s", POLONIEX_API_URL, vals.Encode())
|
|
err := SendHTTPGetRequest(path, true, &resp)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
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)
|
|
|
|
if start != "" {
|
|
vals.Set("start", start)
|
|
}
|
|
|
|
if end != "" {
|
|
vals.Set("end", end)
|
|
}
|
|
|
|
if period != "" {
|
|
vals.Set("period", period)
|
|
}
|
|
|
|
resp := []PoloniexChartData{}
|
|
path := fmt.Sprintf("%s/public?command=returnChartData&%s", POLONIEX_API_URL, vals.Encode())
|
|
err := SendHTTPGetRequest(path, true, &resp)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
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
|
|
}
|
|
resp := Response{}
|
|
path := fmt.Sprintf("%s/public?command=returnCurrencies", POLONIEX_API_URL)
|
|
err := SendHTTPGetRequest(path, true, &resp.Data)
|
|
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
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)
|
|
err := SendHTTPGetRequest(path, true, &resp)
|
|
|
|
if err != nil {
|
|
return resp, err
|
|
}
|
|
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)
|
|
|
|
if err != nil {
|
|
return PoloniexBalance{}, err
|
|
}
|
|
|
|
data := result.(map[string]interface{})
|
|
balance := PoloniexBalance{}
|
|
balance.Currency = make(map[string]float64)
|
|
|
|
for x, y := range data {
|
|
balance.Currency[x], _ = strconv.ParseFloat(y.(string), 64)
|
|
}
|
|
|
|
return balance, nil
|
|
}
|
|
|
|
type PoloniexCompleteBalance struct {
|
|
Available float64
|
|
OnOrders float64
|
|
BTCValue float64
|
|
}
|
|
|
|
type PoloniexCompleteBalances struct {
|
|
Currency map[string]PoloniexCompleteBalance
|
|
}
|
|
|
|
func (p *Poloniex) GetCompleteBalances() (PoloniexCompleteBalances, error) {
|
|
var result interface{}
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_BALANCES_COMPLETE, url.Values{}, &result)
|
|
|
|
if err != nil {
|
|
return PoloniexCompleteBalances{}, err
|
|
}
|
|
|
|
data := result.(map[string]interface{})
|
|
balance := PoloniexCompleteBalances{}
|
|
balance.Currency = make(map[string]PoloniexCompleteBalance)
|
|
|
|
for x, y := range data {
|
|
dataVals := y.(map[string]interface{})
|
|
balancesData := PoloniexCompleteBalance{}
|
|
balancesData.Available, _ = strconv.ParseFloat(dataVals["available"].(string), 64)
|
|
balancesData.OnOrders, _ = strconv.ParseFloat(dataVals["onOrders"].(string), 64)
|
|
balancesData.BTCValue, _ = strconv.ParseFloat(dataVals["btcValue"].(string), 64)
|
|
balance.Currency[x] = balancesData
|
|
}
|
|
|
|
return balance, nil
|
|
}
|
|
|
|
type PoloniexDepositAddresses struct {
|
|
Addresses map[string]string
|
|
}
|
|
|
|
func (p *Poloniex) GetDepositAddresses() (PoloniexDepositAddresses, error) {
|
|
var result interface{}
|
|
addresses := PoloniexDepositAddresses{}
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_DEPOSIT_ADDRESSES, url.Values{}, &result)
|
|
|
|
if err != nil {
|
|
return addresses, err
|
|
}
|
|
|
|
addresses.Addresses = make(map[string]string)
|
|
data := result.(map[string]interface{})
|
|
for x, y := range data {
|
|
addresses.Addresses[x] = y.(string)
|
|
}
|
|
|
|
return addresses, nil
|
|
}
|
|
|
|
func (p *Poloniex) GenerateNewAddress(currency string) (string, error) {
|
|
type Response struct {
|
|
Success int
|
|
Error string
|
|
Response string
|
|
}
|
|
resp := Response{}
|
|
values := url.Values{}
|
|
values.Set("currency", currency)
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_GENERATE_NEW_ADDRESS, values, &resp)
|
|
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if resp.Error != "" {
|
|
return "", errors.New(resp.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{}
|
|
|
|
if start != "" {
|
|
values.Set("start", start)
|
|
} else {
|
|
values.Set("start", "0")
|
|
}
|
|
|
|
if end != "" {
|
|
values.Set("end", end)
|
|
} else {
|
|
values.Set("end", strconv.FormatInt(time.Now().Unix(), 10))
|
|
}
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_DEPOSITS_WITHDRAWALS, values, &resp)
|
|
|
|
if err != nil {
|
|
return resp, err
|
|
}
|
|
|
|
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{}
|
|
|
|
if currency != "" {
|
|
values.Set("currencyPair", currency)
|
|
result := PoloniexOpenOrdersResponse{}
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_ORDERS, values, &result.Data)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
return result, nil
|
|
} else {
|
|
values.Set("currencyPair", "all")
|
|
result := PoloniexOpenOrdersResponseAll{}
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_ORDERS, values, &result.Data)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
}
|
|
|
|
type PoloniexAuthentictedTradeHistory struct {
|
|
GlobalTradeID int64 `json:"globalTradeID"`
|
|
TradeID int64 `json:"tradeID,string"`
|
|
Date string `json:"data,string"`
|
|
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][]PoloniexOrder
|
|
}
|
|
|
|
type PoloniexAuthenticatedTradeHistoryResponse struct {
|
|
Data []PoloniexOrder
|
|
}
|
|
|
|
func (p *Poloniex) GetAuthenticatedTradeHistory(currency, start, end string) (interface{}, error) {
|
|
values := url.Values{}
|
|
|
|
if start != "" {
|
|
values.Set("start", start)
|
|
}
|
|
|
|
if end != "" {
|
|
values.Set("end", end)
|
|
}
|
|
|
|
if currency != "" {
|
|
values.Set("currencyPair", currency)
|
|
result := PoloniexAuthenticatedTradeHistoryResponse{}
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_TRADE_HISTORY, values, &result.Data)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
return result, nil
|
|
} else {
|
|
values.Set("currencyPair", "all")
|
|
result := PoloniexAuthenticatedTradeHistoryAll{}
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_TRADE_HISTORY, values, &result.Data)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
}
|
|
|
|
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,string"`
|
|
}
|
|
|
|
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{}
|
|
|
|
var orderType string
|
|
if buy {
|
|
orderType = POLONIEX_ORDER_BUY
|
|
} else {
|
|
orderType = POLONIEX_ORDER_SELL
|
|
}
|
|
|
|
values.Set("currencyPair", currency)
|
|
values.Set("rate", strconv.FormatFloat(rate, 'f', -1, 64))
|
|
values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
|
|
|
if immediate {
|
|
values.Set("immediateOrCancel", "1")
|
|
}
|
|
|
|
if fillOrKill {
|
|
values.Set("fillOrKill", "1")
|
|
}
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", orderType, values, &result)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
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{}
|
|
values.Set("orderNumber", strconv.FormatInt(orderID, 10))
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_ORDER_CANCEL, values, &result)
|
|
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
if result.Success != 1 {
|
|
return false, errors.New(result.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{}
|
|
values.Set("orderNumber", strconv.FormatInt(orderID, 10))
|
|
values.Set("rate", strconv.FormatFloat(rate, 'f', -1, 64))
|
|
|
|
if amount != 0 {
|
|
values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
|
}
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_ORDER_MOVE, values, &result)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
if result.Success != 1 {
|
|
return result, errors.New(result.Error)
|
|
}
|
|
|
|
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{}
|
|
|
|
values.Set("currency", currency)
|
|
values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
|
values.Set("address", address)
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_WITHDRAW, values, &result)
|
|
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
if result.Error != "" {
|
|
return false, errors.New(result.Error)
|
|
}
|
|
|
|
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)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (p *Poloniex) GetTradableBalances() (map[string]map[string]float64, error) {
|
|
type Response struct {
|
|
Data map[string]map[string]interface{}
|
|
}
|
|
result := Response{}
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_TRADABLE_BALANCES, url.Values{}, &result.Data)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
balances := make(map[string]map[string]float64)
|
|
|
|
for x, y := range result.Data {
|
|
balances[x] = make(map[string]float64)
|
|
for z, w := range y {
|
|
balances[x][z], _ = strconv.ParseFloat(w.(string), 64)
|
|
}
|
|
}
|
|
|
|
return balances, nil
|
|
}
|
|
|
|
func (p *Poloniex) TransferBalance(currency, from, to string, amount float64) (bool, error) {
|
|
values := url.Values{}
|
|
result := PoloniexGenericResponse{}
|
|
|
|
values.Set("currency", currency)
|
|
values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
|
values.Set("fromAccount", from)
|
|
values.Set("toAccount", to)
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_TRANSFER_BALANCE, values, &result)
|
|
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
if result.Error != "" && result.Success != 1 {
|
|
return false, errors.New(result.Error)
|
|
}
|
|
|
|
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)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (p *Poloniex) PlaceMarginOrder(currency string, rate, amount, lendingRate float64, buy bool) (PoloniexOrderResponse, error) {
|
|
result := PoloniexOrderResponse{}
|
|
values := url.Values{}
|
|
|
|
var orderType string
|
|
if buy {
|
|
orderType = POLONIEX_MARGIN_BUY
|
|
} else {
|
|
orderType = POLONIEX_MARGIN_SELL
|
|
}
|
|
|
|
values.Set("currencyPair", currency)
|
|
values.Set("rate", strconv.FormatFloat(rate, 'f', -1, 64))
|
|
values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
|
|
|
if lendingRate != 0 {
|
|
values.Set("lendingRate", strconv.FormatFloat(lendingRate, 'f', -1, 64))
|
|
}
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", orderType, values, &result)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
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{}
|
|
|
|
if currency != "" && currency != "all" {
|
|
values.Set("currencyPair", currency)
|
|
result := PoloniexMarginPosition{}
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_MARGIN_POSITION, values, &result)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
return result, nil
|
|
} else {
|
|
values.Set("currencyPair", "all")
|
|
|
|
type Response struct {
|
|
Data map[string]PoloniexMarginPosition
|
|
}
|
|
|
|
result := Response{}
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_MARGIN_POSITION, values, &result.Data)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
}
|
|
|
|
func (p *Poloniex) CloseMarginPosition(currency string) (bool, error) {
|
|
values := url.Values{}
|
|
values.Set("currencyPair", currency)
|
|
result := PoloniexGenericResponse{}
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_MARGIN_POSITION_CLOSE, values, &result)
|
|
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
if result.Success == 0 {
|
|
return false, errors.New(result.Error)
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
func (p *Poloniex) CreateLoanOffer(currency string, amount, rate float64, duration int, autoRenew bool) (int64, error) {
|
|
values := url.Values{}
|
|
values.Set("currency", currency)
|
|
values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
|
values.Set("duration", strconv.Itoa(duration))
|
|
|
|
if autoRenew {
|
|
values.Set("autoRenew", "1")
|
|
} else {
|
|
values.Set("autoRenew", "0")
|
|
}
|
|
|
|
values.Set("lendingRate", strconv.FormatFloat(rate, 'f', -1, 64))
|
|
|
|
type Response struct {
|
|
Success int `json:"success"`
|
|
Error string `json:"error"`
|
|
OrderID int64 `json:"orderID"`
|
|
}
|
|
|
|
result := Response{}
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_CREATE_LOAN_OFFER, values, &result)
|
|
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
if result.Success == 0 {
|
|
return 0, errors.New(result.Error)
|
|
}
|
|
|
|
return result.OrderID, nil
|
|
}
|
|
|
|
func (p *Poloniex) CancelLoanOffer(orderNumber int64) (bool, error) {
|
|
result := PoloniexGenericResponse{}
|
|
values := url.Values{}
|
|
values.Set("orderID", strconv.FormatInt(orderNumber, 10))
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_CANCEL_LOAN_OFFER, values, &result)
|
|
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
if result.Success == 0 {
|
|
return false, errors.New(result.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
|
|
}
|
|
result := Response{}
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_OPEN_LOAN_OFFERS, url.Values{}, &result.Data)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if result.Data == nil {
|
|
return nil, errors.New("There are no open loan offers.")
|
|
}
|
|
|
|
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)
|
|
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (p *Poloniex) ToggleAutoRenew(orderNumber int64) (bool, error) {
|
|
values := url.Values{}
|
|
values.Set("orderNumber", strconv.FormatInt(orderNumber, 10))
|
|
result := PoloniexGenericResponse{}
|
|
|
|
err := p.SendAuthenticatedHTTPRequest("POST", POLONIEX_AUTO_RENEW, values, &result)
|
|
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
if result.Success == 0 {
|
|
return false, errors.New(result.Error)
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
func (p *Poloniex) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Values, result interface{}) error {
|
|
headers := make(map[string]string)
|
|
headers["Content-Type"] = "application/x-www-form-urlencoded"
|
|
headers["Key"] = p.AccessKey
|
|
|
|
nonce := time.Now().UnixNano()
|
|
nonceStr := strconv.FormatInt(nonce, 10)
|
|
|
|
values.Set("nonce", nonceStr)
|
|
values.Set("command", endpoint)
|
|
|
|
hmac := GetHMAC(HASH_SHA512, []byte(values.Encode()), []byte(p.SecretKey))
|
|
headers["Sign"] = HexEncodeToString(hmac)
|
|
|
|
path := fmt.Sprintf("%s/%s", POLONIEX_API_URL, POLONIEX_API_TRADING_ENDPOINT)
|
|
resp, err := SendHTTPRequest(method, path, headers, bytes.NewBufferString(values.Encode()))
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = JSONDecode([]byte(resp), &result)
|
|
|
|
if err != nil {
|
|
return errors.New("Unable to JSON Unmarshal response.")
|
|
}
|
|
return nil
|
|
}
|