mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
Merge pull request #1665 from c9s/c9s/improve-pv-slice-parsing
IMPROVE: improve price volume slice parsing
This commit is contained in:
commit
e293ec5c70
|
@ -1,6 +1,7 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -180,15 +181,40 @@ func (slice *PriceVolumeSlice) UnmarshalJSON(b []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParsePriceVolumeKvSliceJSON parses a JSON array of objects into PriceVolumeSlice
|
||||||
|
// [{"Price":...,"Volume":...}, ...]
|
||||||
|
func ParsePriceVolumeKvSliceJSON(b []byte) (PriceVolumeSlice, error) {
|
||||||
|
type S PriceVolumeSlice
|
||||||
|
var ts S
|
||||||
|
|
||||||
|
err := json.Unmarshal(b, &ts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ts) > 0 && ts[0].Price.IsZero() {
|
||||||
|
return nil, fmt.Errorf("unable to parse price volume slice correctly, input given: %s", string(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
return PriceVolumeSlice(ts), nil
|
||||||
|
}
|
||||||
|
|
||||||
// ParsePriceVolumeSliceJSON tries to parse a 2 dimensional string array into a PriceVolumeSlice
|
// ParsePriceVolumeSliceJSON tries to parse a 2 dimensional string array into a PriceVolumeSlice
|
||||||
//
|
//
|
||||||
// [["9000", "10"], ["9900", "10"], ... ]
|
// [["9000", "10"], ["9900", "10"], ... ]
|
||||||
|
//
|
||||||
|
// if parse failed, then it will try to parse the JSON array of objects, function ParsePriceVolumeKvSliceJSON will be called.
|
||||||
func ParsePriceVolumeSliceJSON(b []byte) (slice PriceVolumeSlice, err error) {
|
func ParsePriceVolumeSliceJSON(b []byte) (slice PriceVolumeSlice, err error) {
|
||||||
var as [][]fixedpoint.Value
|
var as [][]fixedpoint.Value
|
||||||
|
|
||||||
err = json.Unmarshal(b, &as)
|
err = json.Unmarshal(b, &as)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return slice, err
|
// fallback unmarshalling: if the prefix looks like an object array
|
||||||
|
if bytes.HasPrefix(b, []byte(`[{`)) {
|
||||||
|
return ParsePriceVolumeKvSliceJSON(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, a := range as {
|
for _, a := range as {
|
||||||
|
|
|
@ -3,10 +3,33 @@ package types
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestPriceVolumeSlice_UnmarshalJSON(t *testing.T) {
|
||||||
|
t.Run("array of array", func(t *testing.T) {
|
||||||
|
input := []byte(`[["19000.0","3.0"],["19111.0","2.0"]]`)
|
||||||
|
slice, err := ParsePriceVolumeSliceJSON(input)
|
||||||
|
if assert.NoError(t, err) {
|
||||||
|
assert.Len(t, slice, 2)
|
||||||
|
assert.Equal(t, "19000", slice[0].Price.String())
|
||||||
|
assert.Equal(t, "3", slice[0].Volume.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("array of object", func(t *testing.T) {
|
||||||
|
input := []byte(`[{ "Price": "19000.0", "Volume":"3.0"},{"Price": "19111.0","Volume": "2.0" }]`)
|
||||||
|
slice, err := ParsePriceVolumeSliceJSON(input)
|
||||||
|
if assert.NoError(t, err) {
|
||||||
|
assert.Len(t, slice, 2)
|
||||||
|
assert.Equal(t, "19000", slice[0].Price.String())
|
||||||
|
assert.Equal(t, "3", slice[0].Volume.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestPriceVolumeSlice_Remove(t *testing.T) {
|
func TestPriceVolumeSlice_Remove(t *testing.T) {
|
||||||
for _, descending := range []bool{true, false} {
|
for _, descending := range []bool{true, false} {
|
||||||
slice := PriceVolumeSlice{}
|
slice := PriceVolumeSlice{}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user