pivotshort: improve price grouping

This commit is contained in:
c9s 2022-07-02 18:51:17 +08:00
parent f940bb8e0a
commit 1e8ac0d08a
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
4 changed files with 94 additions and 45 deletions

View File

@ -54,6 +54,7 @@ exchangeStrategies:
# minDistance is used to ignore the place that is too near to the current price # minDistance is used to ignore the place that is too near to the current price
minDistance: 3% minDistance: 3%
groupDistance: 1%
# ratio is the ratio of the resistance price, # ratio is the ratio of the resistance price,
# higher the ratio, lower the price # higher the ratio, lower the price

View File

@ -106,7 +106,6 @@ func (s *BreakLow) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
// we need the price cross the break line or we do nothing // we need the price cross the break line or we do nothing
if !(openPrice.Compare(breakPrice) > 0 && closePrice.Compare(breakPrice) < 0) { if !(openPrice.Compare(breakPrice) > 0 && closePrice.Compare(breakPrice) < 0) {
log.Infof("%s kline is not between the break low price %f", kline.Symbol, breakPrice.Float64())
return return
} }

View File

@ -18,6 +18,7 @@ type ResistanceShort struct {
types.IntervalWindow types.IntervalWindow
MinDistance fixedpoint.Value `json:"minDistance"` MinDistance fixedpoint.Value `json:"minDistance"`
GroupDistance fixedpoint.Value `json:"groupDistance"`
NumLayers int `json:"numLayers"` NumLayers int `json:"numLayers"`
LayerSpread fixedpoint.Value `json:"layerSpread"` LayerSpread fixedpoint.Value `json:"layerSpread"`
Quantity fixedpoint.Value `json:"quantity"` Quantity fixedpoint.Value `json:"quantity"`
@ -39,6 +40,10 @@ func (s *ResistanceShort) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg
s.activeOrders = bbgo.NewActiveOrderBook(s.Symbol) s.activeOrders = bbgo.NewActiveOrderBook(s.Symbol)
s.activeOrders.BindStream(session.UserDataStream) s.activeOrders.BindStream(session.UserDataStream)
if s.GroupDistance.IsZero() {
s.GroupDistance = fixedpoint.NewFromFloat(0.01)
}
store, _ := session.MarketDataStore(s.Symbol) store, _ := session.MarketDataStore(s.Symbol)
s.resistancePivot = &indicator.Pivot{IntervalWindow: s.IntervalWindow} s.resistancePivot = &indicator.Pivot{IntervalWindow: s.IntervalWindow}
@ -65,13 +70,12 @@ func (s *ResistanceShort) Bind(session *bbgo.ExchangeSession, orderExecutor *bbg
func (s *ResistanceShort) findNextResistancePriceAndPlaceOrders(closePrice fixedpoint.Value) { func (s *ResistanceShort) findNextResistancePriceAndPlaceOrders(closePrice fixedpoint.Value) {
// if the close price is still lower than the resistance price, then we don't have to update // if the close price is still lower than the resistance price, then we don't have to update
if closePrice.Compare(s.nextResistancePrice) <= 0 { if closePrice.Compare(s.nextResistancePrice.Mul(one.Add(s.Ratio))) <= 0 {
return return
} }
minDistance := s.MinDistance.Float64() minDistance := s.MinDistance.Float64()
lows := s.resistancePivot.Lows resistancePrices := findPossibleResistancePrices(closePrice.Float64()*(1.0+minDistance), s.GroupDistance.Float64(), s.resistancePivot.Lows)
resistancePrices := findPossibleResistancePrices(closePrice.Float64(), minDistance, lows)
log.Infof("last price: %f, possible resistance prices: %+v", closePrice.Float64(), resistancePrices) log.Infof("last price: %f, possible resistance prices: %+v", closePrice.Float64(), resistancePrices)
@ -151,51 +155,68 @@ func (s *ResistanceShort) placeResistanceOrders(ctx context.Context, resistanceP
} }
func findPossibleSupportPrices(closePrice float64, minDistance float64, lows []float64) []float64 { func findPossibleSupportPrices(closePrice float64, minDistance float64, lows []float64) []float64 {
// sort float64 in increasing order return group(lower(lows, closePrice), minDistance)
// lower to higher prices }
sort.Float64s(lows)
var supportPrices []float64 func lower(arr []float64, x float64) []float64 {
var last = closePrice sort.Float64s(arr)
for i := len(lows) - 1; i >= 0; i-- {
price := lows[i]
var rst []float64
for _, a := range arr {
// filter prices that are lower than the current closed price // filter prices that are lower than the current closed price
if price > closePrice { if a > x {
continue continue
} }
if (price / last) < (1.0 - minDistance) { rst = append(rst, a)
}
return rst
}
func higher(arr []float64, x float64) []float64 {
sort.Float64s(arr)
var rst []float64
for _, a := range arr {
// filter prices that are lower than the current closed price
if a < x {
continue continue
} }
rst = append(rst, a)
supportPrices = append(supportPrices, price)
last = price
} }
return supportPrices return rst
}
func group(arr []float64, minDistance float64) []float64 {
var groups []float64
var grp = []float64{arr[0]}
for _, price := range arr {
avg := average(grp)
if (price / avg) > (1.0 + minDistance) {
groups = append(groups, avg)
grp = []float64{price}
} else {
grp = append(grp, price)
}
}
if len(grp) > 0 {
groups = append(groups, average(grp))
}
return groups
} }
func findPossibleResistancePrices(closePrice float64, minDistance float64, lows []float64) []float64 { func findPossibleResistancePrices(closePrice float64, minDistance float64, lows []float64) []float64 {
// sort float64 in increasing order return group(higher(lows, closePrice), minDistance)
// lower to higher prices }
sort.Float64s(lows)
func average(arr []float64) float64 {
var resistancePrices []float64 s := 0.0
var last = closePrice for _, a := range arr {
for _, price := range lows { s += a
// filter prices that are lower than the current closed price }
if price < closePrice { return s / float64(len(arr))
continue
}
if (price / last) < (1.0 + minDistance) {
continue
}
resistancePrices = append(resistancePrices, price)
last = price
}
return resistancePrices
} }

View File

@ -0,0 +1,28 @@
package pivotshort
import (
"testing"
"github.com/stretchr/testify/assert"
)
func Test_findPossibleResistancePrices(t *testing.T) {
prices := findPossibleResistancePrices(19000.0, 0.01, []float64{
23020.0,
23040.0,
23060.0,
24020.0,
24040.0,
24060.0,
})
assert.Equal(t, []float64{23035, 24040}, prices)
prices = findPossibleResistancePrices(19000.0, 0.01, []float64{
23020.0,
23040.0,
23060.0,
})
assert.Equal(t, []float64{23035}, prices)
}