6 "github.com/jloup/poloniex"
7 "github.com/shopspring/decimal"
10 type CurrencyPair struct {
15 type Poloniex struct {
16 TickerCache map[string]CurrencyPair
18 publicClient *poloniex.Poloniex
19 updateTickerChan chan CurrencyPair
22 func NewPoloniex() *Poloniex {
23 client, _ := poloniex.NewClient("", "")
26 TickerCache: make(map[string]CurrencyPair),
27 updateTickerChan: nil,
32 func (p *Poloniex) GetBalance(apiKey, apiSecret, base_currency string) (decimal.Decimal, error) {
33 client, _ := poloniex.NewClient(apiKey, apiSecret)
35 accounts, err := client.TradeReturnAvailableAccountBalances()
37 return decimal.Zero, err
40 marginBalance, err := p.computeAccountBalance(accounts.Margin, base_currency)
42 return decimal.Zero, err
45 exchangeBalance, err := p.computeAccountBalance(accounts.Exchange, base_currency)
47 return decimal.Zero, err
50 return decimal.Sum(marginBalance, exchangeBalance), nil
53 func (p *Poloniex) computeAccountBalance(account map[string]decimal.Decimal, base_currency string) (decimal.Decimal, error) {
54 var total decimal.Decimal
56 for currency, amount := range account {
57 pair, err := p.GetCurrencyPair(base_currency, currency)
59 return decimal.Zero, err
62 total = total.Add(amount.Mul(pair.Rate))
68 func (p *Poloniex) GetCurrencyPair(curr1, curr2 string) (CurrencyPair, error) {
69 pairName := fmt.Sprintf("%s_%s", curr1, curr2)
73 return CurrencyPair{pairName, decimal.NewFromFloat(1.0)}, nil
76 pair, ok := p.TickerCache[pairName]
78 pair, err := p.fetchTicker(pairName)
80 return CurrencyPair{}, err
89 func (p *Poloniex) fetchTicker(pair string) (CurrencyPair, error) {
90 tickers, err := p.publicClient.PubReturnTickers()
92 return CurrencyPair{}, err
95 if ticker, ok := tickers[pair]; ok {
96 pair := CurrencyPair{Name: pair, Rate: ticker.Last}
98 if p.updateTickerChan != nil {
99 p.updateTickerChan <- pair
104 return CurrencyPair{}, fmt.Errorf("pair '%v' not in tickers", pair)
108 func (p *Poloniex) StartTicker() error {
109 stream, err := poloniex.NewWSClient()
114 err = stream.SubscribeTicker()
119 p.updateTickerChan = make(chan CurrencyPair)
125 case data, ok := <-stream.Subs["ticker"]:
129 ticker := data.(poloniex.WSTicker)
130 p.TickerCache[ticker.CurrencyPair] = CurrencyPair{Name: ticker.CurrencyPair, Rate: decimal.NewFromFloat(ticker.Last)}
133 case pair, ok := <-p.updateTickerChan:
137 p.TickerCache[pair.Name] = pair
142 p.updateTickerChan = nil