-
Notifications
You must be signed in to change notification settings - Fork 0
/
orderflow.go
121 lines (104 loc) · 3.07 KB
/
orderflow.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
package malgova
import (
"fmt"
"github.com/sivamgr/kstreamdb"
)
// PriceCell struct
type PriceCell struct {
BidQuantityTaken uint32
AskQuantityTaken uint32
VolumeTraded uint32
}
// OrderFlowMonitor struct
type OrderFlowMonitor struct {
LastTick kstreamdb.TickData
TotalBidsQuantityTaken uint32
TotalAsksQuantityTaken uint32
TicksUpdated uint32
Prices map[uint32]*PriceCell
Bids [5]kstreamdb.DepthItem
Asks [5]kstreamdb.DepthItem
}
// NewOrderFlowMonitor creates a new orderflow monitor
func NewOrderFlowMonitor() *OrderFlowMonitor {
pNew := new(OrderFlowMonitor)
pNew.Prices = make(map[uint32]*PriceCell)
return pNew
}
// GetPriceCell returns the price cell
func (r *OrderFlowMonitor) GetPriceCell(p float32) *PriceCell {
k := uint32(p * 100)
if _, ok := r.Prices[k]; !ok {
r.Prices[k] = new(PriceCell)
}
return r.Prices[k]
}
// Update processes the tick
func (r *OrderFlowMonitor) Update(t kstreamdb.TickData) {
if t.VolumeTraded > r.LastTick.VolumeTraded {
r.TicksUpdated++
ltq := t.LastTradedQuantity
pCell := r.GetPriceCell(t.LastPrice)
if (len(r.Bids) > 0) && (t.LastPrice <= r.Bids[0].Price) {
pCell.BidQuantityTaken += ltq
r.TotalBidsQuantityTaken += ltq
} else if (len(r.Asks) > 0) && (t.LastPrice >= r.Bids[0].Price) {
pCell.AskQuantityTaken += ltq
r.TotalAsksQuantityTaken += ltq
}
pCell.VolumeTraded += ltq
// Update with latest depth
r.Bids = t.Bid
r.Asks = t.Ask
}
r.LastTick = t
}
func (v *PriceCell) resetCounters() {
v.AskQuantityTaken = 0
v.BidQuantityTaken = 0
}
// Reset resets Bids/Asks
func (r *OrderFlowMonitor) Reset() {
r.TotalAsksQuantityTaken = 0
r.TotalBidsQuantityTaken = 0
r.TicksUpdated = 0
for _, v := range r.Prices {
v.resetCounters()
}
r.LastTick = kstreamdb.TickData{}
}
// StringifyPriceCell Stringify the Price Bucket
func (r *OrderFlowMonitor) StringifyPriceCell(p float32) string {
pCell := r.GetPriceCell(p)
if pCell == nil {
return ""
}
bidsQty := " "
bidsCount := " "
asksQty := " "
asksCount := " "
if (len(r.Bids) > 0) && (p <= r.Bids[0].Price) && (p >= r.Bids[len(r.Bids)-1].Price) {
for _, bid := range r.Bids {
if bid.Price == p {
bidsCount = fmt.Sprintf("%8d", bid.Orders)
bidsQty = fmt.Sprintf("%8d", bid.Quantity)
break
}
}
} else if (len(r.Asks) > 0) && (p >= r.Asks[0].Price) && (p <= r.Asks[len(r.Asks)-1].Price) {
for _, ask := range r.Asks {
if ask.Price == p {
asksCount = fmt.Sprintf("%8d", ask.Orders)
asksQty = fmt.Sprintf("%8d", ask.Quantity)
break
}
}
}
out := fmt.Sprintf("%8d|%8.2f|%s|%s|%8d|%8d|%s|%s", pCell.VolumeTraded, p, bidsCount, bidsQty, pCell.BidQuantityTaken, pCell.AskQuantityTaken, asksQty, asksCount)
return out
}
// StringifyTotals stringyfies total
func (r *OrderFlowMonitor) StringifyTotals() string {
out := fmt.Sprintf("%8d %8d %8d %8d %8d ", r.LastTick.VolumeTraded, r.LastTick.TotalBuyQuantity, r.TotalBidsQuantityTaken, r.TotalAsksQuantityTaken, r.LastTick.TotalSellQuantity)
return out
}