From 50c6eea630c5bf6d1513d093125f11ce30deaff5 Mon Sep 17 00:00:00 2001 From: jloup Date: Mon, 26 Mar 2018 10:55:17 +0200 Subject: [PATCH] Display short positions. --- Gopkg.lock | 24 ++++++++-------- api/market_config.go | 19 ++++++++----- cmd/web/js/poloniex.jsx | 12 ++++++-- markets/balance.go | 15 ++++++++++ markets/poloniex.go | 61 ++++++++++++++++++++++++++++++++--------- 5 files changed, 96 insertions(+), 35 deletions(-) create mode 100644 markets/balance.go diff --git a/Gopkg.lock b/Gopkg.lock index 20a4d7e..1e1aad8 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -10,8 +10,8 @@ [[projects]] name = "github.com/Sirupsen/logrus" packages = ["."] - revision = "d682213848ed68c0a260ca37d6dd5ace8423f5ba" - version = "v1.0.4" + revision = "c155da19408a8799da419ed3eeb0cb5db0ad5dbc" + version = "v1.0.5" [[projects]] name = "github.com/boombuler/barcode" @@ -26,8 +26,8 @@ [[projects]] name = "github.com/dgrijalva/jwt-go" packages = ["."] - revision = "dbeaa9332f19a944acb5736b4456cfcc02140e29" - version = "v3.1.0" + revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e" + version = "v3.2.0" [[projects]] name = "github.com/gin-contrib/cors" @@ -61,8 +61,8 @@ "orm", "types" ] - revision = "62ce1a18dd39eab82c8a3fc1a5b076e59c0a284f" - version = "v6.9.6" + revision = "24dfe0572921e42ffe1035f7afbd40f9d97cb8c8" + version = "v6.10.0" [[projects]] name = "github.com/golang/protobuf" @@ -74,13 +74,13 @@ branch = "master" name = "github.com/jinzhu/inflection" packages = ["."] - revision = "1c35d901db3da928c72a72d8458480cc9ade058f" + revision = "04140366298a54a039076d798123ffa108fff46c" [[projects]] branch = "master" name = "github.com/jloup/poloniex" packages = ["."] - revision = "e75e6fd7991c1d71576ad97de73fc922f24a5fd2" + revision = "72d53259a0b28f1778281d7a9f7b20469d8c0171" [[projects]] branch = "master" @@ -108,7 +108,7 @@ branch = "master" name = "github.com/shopspring/decimal" packages = ["."] - revision = "e3482495ff4cba75613e4177ed79825c890058a9" + revision = "2df3e6ddaf6e9531dd02d7b6337f2d310f5e4f22" [[projects]] name = "github.com/ugorji/go" @@ -124,13 +124,13 @@ "blowfish", "ssh/terminal" ] - revision = "91a49db82a88618983a78a06c1cbd4e00ab749ab" + revision = "88942b9c40a4c9d203b82b3731787b672d6e809b" [[projects]] branch = "master" name = "golang.org/x/net" packages = ["websocket"] - revision = "cbe0f9307d0156177f9dd5dc85da1a31abc5f2fb" + revision = "6078986fec03a1dcc236c34816c71b0e05018fda" [[projects]] branch = "master" @@ -139,7 +139,7 @@ "unix", "windows" ] - revision = "f6cff0780e542efa0c8e864dc8fa522808f6a598" + revision = "91ee8cde435411ca3f1cd365e8f20131aed4d0a1" [[projects]] name = "gopkg.in/go-playground/validator.v8" diff --git a/api/market_config.go b/api/market_config.go index d85af4d..25e390d 100644 --- a/api/market_config.go +++ b/api/market_config.go @@ -82,7 +82,7 @@ func (q MarketBalanceQuery) Run() (interface{}, *Error) { result := struct { Value decimal.Decimal `json:"value"` ValueCurrency string `json:"valueCurrency"` - Balance map[string]decimal.Decimal `json:"balance"` + Balance map[string]markets.Balance `json:"balance"` }{} resultErr := CallExternalService(fmt.Sprintf("'%s' GetBalanceValue", q.In.Market), EXTERNAL_SERVICE_TIMEOUT_SECONDS*time.Second, func() *Error { @@ -92,18 +92,23 @@ func (q MarketBalanceQuery) Run() (interface{}, *Error) { return &Error{InvalidMarketCredentials, "wrong market credentials", fmt.Errorf("wrong '%v' market credentials", q.In.Market)} } - if err != nil { - return NewInternalError(err) + if utils.ErrIs(err, markets.IPRestricted) { + return &Error{IPRestrictedApiKey, "ip restricted api key", fmt.Errorf("'%v' ip restricted", q.In.Market)} } - value, err := Poloniex.ComputeAccountBalanceValue(balance, q.In.Currency) if err != nil { return NewInternalError(err) } - result.Balance = balance - result.ValueCurrency = q.In.Currency - result.Value = value.Round(8) + for currency, value := range balance.Balances { + if value.BTCValue.Abs().LessThan(decimal.NewFromFloat(0.0001)) { + delete(balance.Balances, currency) + } + } + + result.Balance = balance.Balances + result.ValueCurrency = "BTC" + result.Value = balance.BTCValue.Round(8) return nil }) diff --git a/cmd/web/js/poloniex.jsx b/cmd/web/js/poloniex.jsx index 813a506..db6b1c4 100644 --- a/cmd/web/js/poloniex.jsx +++ b/cmd/web/js/poloniex.jsx @@ -113,6 +113,10 @@ class PoloniexBalance extends React.Component { this.state = {'hideMsg': true, 'msg': '', 'msgOk': false}; } + computeCurrencyRatio = (currency) => { + return (parseFloat(this.props.balance[currency].btcValue) / parseFloat(this.props.balanceValue) * 100.0).toFixed(1); + } + render = () => { var dashboard = null; @@ -120,16 +124,18 @@ class PoloniexBalance extends React.Component { var balance = Object.keys(this.props.balance).map(function(currency) { return
- {this.props.balance[currency]} +
+ {this.props.balance[currency].amount} {currency} ({this.computeCurrencyRatio(currency)}%) +
; }.bind(this)); dashboard =
-
+
{balance}
-
+
Balance ({this.props.balanceCurrency}): {this.props.balanceValue}
diff --git a/markets/balance.go b/markets/balance.go new file mode 100644 index 0000000..cd46ac9 --- /dev/null +++ b/markets/balance.go @@ -0,0 +1,15 @@ +package markets + +import ( + "github.com/shopspring/decimal" +) + +type Balance struct { + Amount decimal.Decimal `json:"amount"` + BTCValue decimal.Decimal `json:"btcValue"` +} + +type Summary struct { + Balances map[string]Balance + BTCValue decimal.Decimal +} diff --git a/markets/poloniex.go b/markets/poloniex.go index 34ebb7e..9aaeafb 100644 --- a/markets/poloniex.go +++ b/markets/poloniex.go @@ -52,40 +52,75 @@ func NewPoloniex() *Poloniex { } } -func (p *Poloniex) GetBalance(apiKey, apiSecret string) (map[string]decimal.Decimal, error) { +func (p *Poloniex) GetBalance(apiKey, apiSecret string) (Summary, error) { client, _ := poloniex.NewClient(apiKey, apiSecret) + var summary Summary accounts, err := client.TradeReturnAvailableAccountBalances() if poloniexInvalidCredentialsError(err) { - return nil, utils.Error{InvalidCredentials, "invalid poloniex credentials"} + return Summary{}, utils.Error{InvalidCredentials, "invalid poloniex credentials"} } + if poloniexRestrictedIPError(err) { + return Summary{}, utils.Error{IPRestricted, "IP restricted api key"} + } + + if err != nil { + return Summary{}, err + } + + positions, err := client.TradeGetMarginPosition() if err != nil { - return nil, err + return Summary{}, err } - balances := make(map[string]decimal.Decimal) - for currency, balance := range accounts.Margin { - balances[currency] = balances[currency].Add(balance) + marginAccount, err := client.TradeReturnMarginAccountSummary() + if err != nil { + return Summary{}, err } - for currency, balance := range accounts.Exchange { - balances[currency] = balances[currency].Add(balance) + summary.Balances = make(map[string]Balance) + for currency, amount := range accounts.Exchange { + balance := summary.Balances[currency] + balance.Amount = balance.Amount.Add(amount) + + summary.Balances[currency] = balance } - return balances, nil + summary.BTCValue, err = p.ComputeAccountBalanceValue(summary.Balances) + if err != nil { + return Summary{}, err + } + + for currencyPair, position := range positions { + if position.Type == "none" { + continue + } + currency := currencyPair[4:] + balance := summary.Balances[currency] + balance.Amount = balance.Amount.Add(position.Amount) + balance.BTCValue = balance.BTCValue.Add(position.Total.Add(position.PlusValue)) + + summary.Balances[currency] = balance + } + + summary.BTCValue = summary.BTCValue.Add(marginAccount.NetValue) + + return summary, nil } -func (p *Poloniex) ComputeAccountBalanceValue(account map[string]decimal.Decimal, baseCurrency string) (decimal.Decimal, error) { +func (p *Poloniex) ComputeAccountBalanceValue(account map[string]Balance) (decimal.Decimal, error) { var total decimal.Decimal - for currency, amount := range account { - pair, err := p.GetCurrencyPair(baseCurrency, currency) + for currency, balance := range account { + pair, err := p.GetCurrencyPair("BTC", currency) if err != nil { return decimal.Zero, err } - total = total.Add(amount.Mul(pair.Rate)) + total = total.Add(balance.Amount.Mul(pair.Rate)) + balance.BTCValue = balance.BTCValue.Add(balance.Amount.Mul(pair.Rate)) + account[currency] = balance } return total, nil -- 2.41.0