Comments (2)
Hello!
Perhaps you should short your order book according to the depth of the request. Kraken does not send notifications of events deeper than you want to receive. Most likely what happens is that you have a level left in your order book that has gone beyond the top 10. Then it is deleted without notification, because you are subscribed to the top 10. Then, due to some changes, it becomes one of the 10, which are taken into account in your checkout calculation.
You should save only the top 10/100/1000 levels in IndexedBook
and remove all levels that exceed the specified depth.
Below I write my part of test code with your checksum implementation. Here is naive realization of dropping exceeded levels, but its work for me:
package main
import (
"fmt"
"hash/crc32"
"sort"
"strings"
ws "github.com/aopoltorzhicky/go_kraken/websocket"
"github.com/pkg/errors"
"github.com/shopspring/decimal"
)
// OrderBook -
type OrderBook struct {
Asks map[string]string
Bids map[string]string
sortedAsks []Level
sortedBids []Level
depth int
}
// NewOrderBook -
func NewOrderBook(depth int) *OrderBook {
return &OrderBook{
Asks: make(map[string]string),
Bids: make(map[string]string),
sortedAsks: make([]Level, 0),
sortedBids: make([]Level, 0),
depth: depth,
}
}
// String -
func (o *OrderBook) String() string {
var str strings.Builder
str.WriteString("asks:\r\n")
for price, vol := range o.Asks {
str.WriteString("\t" + price)
str.WriteByte('[')
str.WriteString(vol)
str.WriteString("]\r\n")
}
str.WriteString("bids:\r\n")
for price, vol := range o.Bids {
str.WriteString("\t" + price)
str.WriteByte('[')
str.WriteString(vol)
str.WriteString("]\r\n")
}
return str.String()
}
func (o *OrderBook) update(m map[string]string, upd ws.OrderBookItem) error {
flVolume, err := upd.Volume.Float64()
if err != nil {
return err
}
price := upd.Price.String()
if flVolume == 0 {
delete(m, price)
} else {
m[price] = upd.Volume.String()
}
return nil
}
// Update -
func (o *OrderBook) Update(upd ws.OrderBookUpdate, withCheckSum bool) error {
for i := range upd.Asks {
if err := o.update(o.Asks, upd.Asks[i]); err != nil {
return err
}
}
o.sortedAsks = orderMap(o.Asks, true)[:o.depth]
for price := range o.Asks {
var found bool
for i := range o.sortedAsks {
if o.sortedAsks[i].Price == price {
found = true
break
}
}
if !found {
delete(o.Asks, price)
}
}
for i := range upd.Bids {
if err := o.update(o.Bids, upd.Bids[i]); err != nil {
return err
}
}
o.sortedBids = orderMap(o.Bids, false)[:o.depth]
for price := range o.Bids {
var found bool
for i := range o.sortedBids {
if o.sortedBids[i].Price == price {
found = true
break
}
}
if !found {
delete(o.Bids, price)
}
}
if withCheckSum && !upd.IsSnapshot {
cs := o.CheckSum()
if cs != upd.CheckSum {
return errors.Errorf("invalid checksum: %s != %s", cs, upd.CheckSum)
}
}
return nil
}
// CheckSum -
func (o *OrderBook) CheckSum() string {
var str strings.Builder
for _, level := range o.sortedAsks {
price := decimal.RequireFromString(level.Price).StringFixed(5)
price = strings.Replace(price, ".", "", 1)
price = strings.TrimLeft(price, "0")
str.WriteString(price)
volume := decimal.RequireFromString(level.Volume).StringFixed(8)
volume = strings.Replace(volume, ".", "", 1)
volume = strings.TrimLeft(volume, "0")
str.WriteString(volume)
}
for _, level := range o.sortedBids {
price := decimal.RequireFromString(level.Price).StringFixed(5)
price = strings.Replace(price, ".", "", 1)
price = strings.TrimLeft(price, "0")
str.WriteString(price)
volume := decimal.RequireFromString(level.Volume).StringFixed(8)
volume = strings.Replace(volume, ".", "", 1)
volume = strings.TrimLeft(volume, "0")
str.WriteString(volume)
}
checksum := str.String()
checksumInt := crc32.ChecksumIEEE([]byte(checksum))
return fmt.Sprint(checksumInt)
}
type Level struct {
Price string
Volume string
}
type ByPrice []Level
func (a ByPrice) Len() int { return len(a) }
func (a ByPrice) Less(i, j int) bool { return a[i].Price < a[j].Price }
func (a ByPrice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func orderMap(m map[string]string, asc bool) []Level {
result := make([]Level, 0)
for key, value := range m {
result = append(result, Level{key, value})
}
if asc {
sort.Sort(ByPrice(result))
} else {
sort.Sort(sort.Reverse(ByPrice(result)))
}
return result
}
from go_kraken.
Wow thank you so much for taking the time 🙏🏻 I will try implement what you've done here and let you know. For now I've simply used the ticker... Not an ideal solution.
Thanks again
from go_kraken.
Related Issues (15)
- websocket orderbook panics after initial snapshot HOT 1
- websocket subscribing to open orders fails HOT 1
- 1 commit behind on latest tag/release HOT 5
- panic send to closed channel on example auth HOT 1
- Can't parse open order websocket messages HOT 1
- Expanding Requests for Websocket HOT 1
- Received error "websocket: close 1013: Market data unavailable" HOT 3
- Bid / Ask Ordering mixed up in Unmarshal function? HOT 1
- Resubscribe fails for private channels HOT 1
- Missing ReqID field in `AddOrderRequest` and `AddOrderResponse` HOT 1
- GHo kraken
- Just heard back from Kraken support and it appears the website was under maintenance
- WithdrawInfo endpoint HOT 1
- Great job! :) HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from go_kraken.