-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
252 lines (221 loc) · 7.24 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/*
CryptoGo
Universidade de Brasília
Departamento de Ciência da Computação
Linguagens de Programação - CIC0093 - 2020/2 B
Prof. Dr. Marcelo Ladeira
Desenvolvido por
Bruno Sanguinetti Regadas de Barros - 18/0046063
Caio Bernardon N. K. Massucato - 16/0115001
Gabriel Nardelli Aprá - 18/0046322
Gabriel Rodrigues Pacheco - 17/0058280
João Marcos Melo Monteiro -13/0143031
*/
package main
import (
"context"
"fmt"
"strconv"
"github.com/adshao/go-binance/v2"
)
var (
apiKey string = "123"
secretKey string = "123"
)
var keepAlive bool = true
func main() {
//client := binance.NewClient(apiKey, secretKey)
//ticker(client, "ETHUSDT")
//go streamTicker("ETHUSDT")
go streamCandle("BTCUSDT", "5m")
go streamCandle("ETHUSDT", "1m")
commSwitch()
}
//Inicializa os objetos (scructs) de cada moeda
func setCoins() CryptoArray {
fmt.Println("Coin struct configurado e alocado!")
coin := CryptoArray{}
return coin
}
// Abre um canal de comunicação (channel) para que go routines
// tenham acesso simultaneo aos objetos (sctructs) das moedas
// retornando um canal com tipos CryptoArray (chan CryptoArray)
func chanCoins() chan CryptoArray {
fmt.Println("Abrindo canal para coin.")
coin := make(chan CryptoArray)
go func() {
coin <- setCoins()
}()
fmt.Println("Canal aberto com sucesso!")
return coin
}
// Retorna o objeto que esta no canal (channel) como um
// objeto propriamente do tipo CryptoArray.
func returnCoins() CryptoArray {
fmt.Println("Sinalizando abertura de canal...")
return <-chanCoins()
}
func priceMean(actualPrice [18]Price, pastPrice [18]Price, meanChannel chan [2]float64) {
var (
actualMean float64 = 0
actualSum float64 = 0
pastMean float64 = 0
pastSum float64 = 0
)
for i := 0; i < len(actualPrice); i++ {
actualSum += actualPrice[i].open
}
for i := 0; i < len(pastPrice); i++ {
pastSum += pastPrice[i].open
}
actualMean = actualSum / float64(len(actualPrice))
actualPrice[0].open = actualMean
pastMean = pastSum / float64(len(pastPrice))
pastPrice[0].open = pastMean
var means = [2]float64{actualMean, pastMean}
meanChannel <- means
}
func printActual(symbol string, actualPriceCounter int, actualPrice [18]Price) {
fmt.Println("_______________________________________________________________")
fmt.Println(symbol)
fmt.Printf("%d - ", actualPriceCounter)
fmt.Print("Preço Atual: ")
fmt.Println(actualPrice[actualPriceCounter])
}
func printPast(pastPriceCounter int, pastPrice [18]Price) {
fmt.Printf("%d - ", pastPriceCounter)
fmt.Print("Preço Passado: ")
fmt.Println(pastPrice[pastPriceCounter])
}
func assembleKline(event chan *binance.WsKlineEvent, symbol string) {
var (
//pastMean float64 = 0
actualPriceCounter int = 0
pastPriceCounter int = 0
firstIteration bool = true
means = [2]float64{0.0, 0.0}
)
var streamedCoin CryptoArray
meanChannel := make(chan [2]float64)
var coinChannel = chanCoins()
streamedCoin = <-coinChannel
streamedCoin.symbol = symbol
for keepAlive {
var streamedEvent *binance.WsKlineEvent
streamedEvent = <-event
a, err := strconv.ParseFloat(streamedEvent.Kline.Open, 64)
if err != nil {
fmt.Println(err)
return
} else {
streamedPrice := Price{open: a}
if streamedPrice != streamedCoin.ActualMeter.actual1m[actualPriceCounter] {
if actualPriceCounter == 17 {
firstIteration = false
actualPriceCounter = 0
}
actualPriceCounter++
if firstIteration {
streamedCoin.ActualMeter.actual1m[actualPriceCounter] = streamedPrice
printActual(symbol, actualPriceCounter, streamedCoin.ActualMeter.actual1m)
fmt.Printf("Local de Memória do Objeto: %p\n", &streamedCoin)
} else {
pastPriceCounter++
if pastPriceCounter <= 17 {
streamedCoin.PastMeter.past1m[pastPriceCounter] = streamedCoin.ActualMeter.actual1m[pastPriceCounter]
streamedCoin.ActualMeter.actual1m[actualPriceCounter] = streamedPrice
printActual(symbol, actualPriceCounter, streamedCoin.ActualMeter.actual1m)
printPast(actualPriceCounter, streamedCoin.PastMeter.past1m)
fmt.Printf("Local de Memória do Objeto: %p\n", &streamedCoin)
if pastPriceCounter == 17 {
pastPriceCounter = 0
go priceMean(streamedCoin.ActualMeter.actual1m, streamedCoin.PastMeter.past1m, meanChannel)
means = <-meanChannel
streamedCoin.ActualMeter.actual1m[0].open = means[0]
streamedCoin.PastMeter.past1m[0].open = means[1]
}
}
}
} else {
streamedCoin.ActualMeter.actual1m[actualPriceCounter] = streamedPrice
}
}
}
}
// streamCandle(symbol, time) Recebe como argumento um simbolo de tipo string
// e um tempo de tipo string no formato 1m , 5m , 15m, 30m, 1h, 2h, 4h...
// e inicia uma conexão webSocket com o servidor HTTP da Binance, recebendo
// WsKlineEvent struct em formato json por 2000ms
func streamCandle(symbol string, time string) {
streamedEvent := make(chan *binance.WsKlineEvent)
go assembleKline(streamedEvent, symbol)
// Handler de sucesso, receberá o stream do servidor em json
wsKlineHandler := func(event *binance.WsKlineEvent) {
streamedEvent <- event
}
errHandler := func(err error) {
fmt.Println(err)
}
// Inicia a conexão webSocket com o servidor HTTP da Binance,
// chamando a função da biblioteca que conecta ao endPoint de Candle.
doneC, _, err := binance.WsKlineServe(symbol, time, wsKlineHandler, errHandler)
if err != nil {
fmt.Println(err)
return
}
<-doneC
}
// ticker(client, symbol) Recebe como argumento um cliente autenticado e simbolo de tipo string
// e um tempo de tipo string no formato 1m , 5m , 15m, 30m, 1h, 2h, 4h...
// e inicia uma conexão webSocket com o servidor HTTP da Binance, recebendo
// WsKlineEvent struct em formato json por 2000ms
func ticker(client *binance.Client, symbol string) {
prices, err := client.NewListPricesService().Symbol(symbol).Do(context.Background())
if err != nil {
fmt.Println(err)
return
}
for _, p := range prices {
fmt.Println(p)
}
}
// streamTicker(symbol) Recebe como argumento um simbolo de tipo string
// e inicia uma conexão webSocket com o servidor HTTP da Binance,
// recebendo WsMarketStatEvent struct em formato json por 1000ms
func streamTicker(symbol string) {
streamedCoin := returnCoins()
streamedCoin.symbol = symbol
// Handler de sucesso, receberá o stream do servidor em json
wsMarketStatEvent := func(event *binance.WsMarketStatEvent) {
a, err := strconv.ParseFloat(event.OpenPrice, 64)
if err != nil {
fmt.Println(err)
return
} else {
fmt.Println("_______________________________________________________________")
fmt.Println(streamedCoin.symbol)
streamedPrice := Price{open: a}
streamedCoin.ActualMeter.actual1m[0] = streamedPrice
fmt.Println(streamedCoin.ActualMeter.actual1m[0])
fmt.Printf("Local de Memória do Objeto: %p\n", &streamedCoin)
}
}
// Handler de erro, receberá o stream do servidor com json
errHandler := func(err error) {
fmt.Println(err)
}
// Inicia a conexão webSocket com o servidor HTTP da Binance,
// chamando a função da biblioteca que conecta ao endPoint de ticker.
doneC, _, err := binance.WsMarketStatServe(symbol, wsMarketStatEvent, errHandler)
if err != nil {
fmt.Println(err)
return
}
<-doneC
}
// Mantem a procedure principal viva.
func commSwitch() {
for keepAlive {
continue
}
}