]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front.git/blame - markets/poloniex.go
poloniex balance draft
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front.git] / markets / poloniex.go
CommitLineData
6c5c1403
J
1package markets
2
3import (
4 "fmt"
5
6 "github.com/jloup/poloniex"
7 "github.com/shopspring/decimal"
8)
9
10type CurrencyPair struct {
11 Name string
12 Rate decimal.Decimal
13}
14
15type Poloniex struct {
16 TickerCache map[string]CurrencyPair
17
18 publicClient *poloniex.Poloniex
19 updateTickerChan chan CurrencyPair
20}
21
22func NewPoloniex() *Poloniex {
23 client, _ := poloniex.NewClient("", "")
24
25 return &Poloniex{
26 TickerCache: make(map[string]CurrencyPair),
27 updateTickerChan: nil,
28 publicClient: client,
29 }
30}
31
32func (p *Poloniex) GetBalance(apiKey, apiSecret, base_currency string) (decimal.Decimal, error) {
33 client, _ := poloniex.NewClient(apiKey, apiSecret)
34
35 accounts, err := client.TradeReturnAvailableAccountBalances()
36 if err != nil {
37 return decimal.Zero, err
38 }
39
40 marginBalance, err := p.computeAccountBalance(accounts.Margin, base_currency)
41 if err != nil {
42 return decimal.Zero, err
43 }
44
45 exchangeBalance, err := p.computeAccountBalance(accounts.Exchange, base_currency)
46 if err != nil {
47 return decimal.Zero, err
48 }
49
50 return decimal.Sum(marginBalance, exchangeBalance), nil
51}
52
53func (p *Poloniex) computeAccountBalance(account map[string]decimal.Decimal, base_currency string) (decimal.Decimal, error) {
54 var total decimal.Decimal
55
56 for currency, amount := range account {
57 pair, err := p.GetCurrencyPair(base_currency, currency)
58 if err != nil {
59 return decimal.Zero, err
60 }
61
62 total = total.Add(amount.Mul(pair.Rate))
63 }
64
65 return total, nil
66}
67
68func (p *Poloniex) GetCurrencyPair(curr1, curr2 string) (CurrencyPair, error) {
69 pairName := fmt.Sprintf("%s_%s", curr1, curr2)
70
71 fmt.Println(pairName)
72 if curr1 == curr2 {
73 return CurrencyPair{pairName, decimal.NewFromFloat(1.0)}, nil
74 }
75
76 pair, ok := p.TickerCache[pairName]
77 if !ok {
78 pair, err := p.fetchTicker(pairName)
79 if err != nil {
80 return CurrencyPair{}, err
81 }
82
83 return pair, nil
84 }
85
86 return pair, nil
87}
88
89func (p *Poloniex) fetchTicker(pair string) (CurrencyPair, error) {
90 tickers, err := p.publicClient.PubReturnTickers()
91 if err != nil {
92 return CurrencyPair{}, err
93 }
94
95 if ticker, ok := tickers[pair]; ok {
96 pair := CurrencyPair{Name: pair, Rate: ticker.Last}
97
98 if p.updateTickerChan != nil {
99 p.updateTickerChan <- pair
100 }
101
102 return pair, nil
103 } else {
104 return CurrencyPair{}, fmt.Errorf("pair '%v' not in tickers", pair)
105 }
106}
107
108func (p *Poloniex) StartTicker() error {
109 stream, err := poloniex.NewWSClient()
110 if err != nil {
111 return err
112 }
113
114 err = stream.SubscribeTicker()
115 if err != nil {
116 return err
117 }
118
119 p.updateTickerChan = make(chan CurrencyPair)
120
121 go func() {
122 for {
123 quit := false
124 select {
125 case data, ok := <-stream.Subs["ticker"]:
126 if !ok {
127 quit = true
128 } else {
129 ticker := data.(poloniex.WSTicker)
130 p.TickerCache[ticker.CurrencyPair] = CurrencyPair{Name: ticker.CurrencyPair, Rate: decimal.NewFromFloat(ticker.Last)}
131 }
132
133 case pair, ok := <-p.updateTickerChan:
134 if !ok {
135 quit = true
136 } else {
137 p.TickerCache[pair.Name] = pair
138 }
139 }
140 if quit {
141 //TODO: logit
142 p.updateTickerChan = nil
143 break
144 }
145 }
146 }()
147
148 return nil
149}