fix: query price range from volume profile trades on every updates. will make it slower on updates

This commit is contained in:
zenix 2023-01-16 12:37:51 +09:00
parent 746279d0a7
commit 0b71f2f1d2
2 changed files with 48 additions and 8 deletions

View File

@ -27,12 +27,8 @@ type VolumeProfile struct {
} }
func (inc *VolumeProfile) Update(price, volume float64, timestamp types.Time) { func (inc *VolumeProfile) Update(price, volume float64, timestamp types.Time) {
if inc.minPrice == 0 {
inc.minPrice = math.Inf(1) inc.minPrice = math.Inf(1)
}
if inc.maxPrice == 0 {
inc.maxPrice = math.Inf(-1) inc.maxPrice = math.Inf(-1)
}
if inc.profile == nil { if inc.profile == nil {
inc.profile = make(map[float64]float64) inc.profile = make(map[float64]float64)
} }
@ -47,13 +43,14 @@ func (inc *VolumeProfile) Update(price, volume float64, timestamp types.Time) {
for i = 0; i < len(inc.trades); i++ { for i = 0; i < len(inc.trades); i++ {
td := inc.trades[i] td := inc.trades[i]
if td.timestamp.After(filter) { if td.timestamp.After(filter) {
inc.trades = inc.trades[i : len(inc.trades)-1] inc.trades = inc.trades[i:len(inc.trades)]
break break
} }
inc.profile[math.Round(td.price/inc.Delta)] -= td.volume inc.profile[math.Round(td.price/inc.Delta)] -= td.volume
} }
for k, _ := range inc.profile { for i = 0; i < len(inc.trades); i++ {
k := math.Round(inc.trades[i].price / inc.Delta)
if k < inc.minPrice { if k < inc.minPrice {
inc.minPrice = k inc.minPrice = k
} }
@ -74,8 +71,14 @@ func (inc *VolumeProfile) PointOfControlAboveEqual(price float64, limit ...float
if len(limit) > 0 { if len(limit) > 0 {
filter = limit[0] filter = limit[0]
} }
if inc.Delta == 0 {
panic("Delta for volumeprofile shouldn't be zero")
}
start := math.Round(price / inc.Delta) start := math.Round(price / inc.Delta)
vol = math.Inf(-1) vol = math.Inf(-1)
if start > filter {
return 0, 0
}
for ; start <= filter; start += inc.Delta { for ; start <= filter; start += inc.Delta {
abs := math.Abs(inc.profile[start]) abs := math.Abs(inc.profile[start])
if vol < abs { if vol < abs {
@ -93,8 +96,16 @@ func (inc *VolumeProfile) PointOfControlBelowEqual(price float64, limit ...float
if len(limit) > 0 { if len(limit) > 0 {
filter = limit[0] filter = limit[0]
} }
if inc.Delta == 0 {
panic("Delta for volumeprofile shouldn't be zero")
}
start := math.Round(price / inc.Delta) start := math.Round(price / inc.Delta)
vol = math.Inf(-1) vol = math.Inf(-1)
if start < filter {
return 0, 0
}
for ; start >= filter; start -= inc.Delta { for ; start >= filter; start -= inc.Delta {
abs := math.Abs(inc.profile[start]) abs := math.Abs(inc.profile[start])
if vol < abs { if vol < abs {

View File

@ -0,0 +1,29 @@
package indicator
import (
"testing"
"time"
"github.com/c9s/bbgo/pkg/types"
"github.com/stretchr/testify/assert"
)
func Test_DelVolumeProfile(t *testing.T) {
vp := VolumeProfile{IntervalWindow: types.IntervalWindow{Window: 1, Interval: types.Interval1s}, Delta: 1.0}
vp.Update(1., 100., types.Time(time.Now()))
r, v := vp.PointOfControlAboveEqual(1.)
assert.Equal(t, r, 1.)
assert.Equal(t, v, 100.)
vp.Update(2., 100., types.Time(time.Now().Add(time.Second*10)))
r, v = vp.PointOfControlAboveEqual(1.)
assert.Equal(t, r, 2.)
assert.Equal(t, v, 100.)
r, v = vp.PointOfControlBelowEqual(1.)
assert.Equal(t, r, 0.)
assert.Equal(t, v, 0.)
r, v = vp.PointOfControlBelowEqual(2.)
assert.Equal(t, r, 2.)
assert.Equal(t, v, 100.)
}