diff --git a/pkg/bbgo/interact.go b/pkg/bbgo/interact.go index f6e998a10..47336c25c 100644 --- a/pkg/bbgo/interact.go +++ b/pkg/bbgo/interact.go @@ -99,6 +99,24 @@ func filterStrategies(exchangeStrategies map[string]SingleExchangeStrategy, filt return retStrategies, nil } +func hasTypeField(obj interface{}, typ interface{}) bool { + targetType := reflect.TypeOf(typ) + found := false + _ = dynamic.IterateFields(obj, func(ft reflect.StructField, fv reflect.Value) error { + if fv.Type() == targetType { + found = true + } + + return nil + }) + return found +} + +func testInterface(obj interface{}, checkType interface{}) bool { + rt := reflect.TypeOf(checkType).Elem() + return reflect.TypeOf(obj).Implements(rt) +} + func filterStrategiesByInterface(exchangeStrategies map[string]SingleExchangeStrategy, checkInterface interface{}) (map[string]SingleExchangeStrategy, error) { rt := reflect.TypeOf(checkInterface).Elem() return filterStrategies(exchangeStrategies, func(s SingleExchangeStrategy) bool { @@ -210,9 +228,11 @@ func (it *CoreInteraction) Commands(i *interact.Interact) { }) i.PrivateCommand("/resetposition", "Reset position", func(reply interact.Reply) error { - // it.trader.exchangeStrategies - // send symbol options - if strategies, err := filterStrategiesByInterface(it.exchangeStrategies, (*PositionResetter)(nil)); err == nil && len(strategies) > 0 { + strategies, err := filterStrategies(it.exchangeStrategies, func(s SingleExchangeStrategy) bool { + return testInterface(s, (*PositionResetter)(nil)) || hasTypeField(s, &types.Position{}) + }) + + if err == nil && len(strategies) > 0 { reply.AddMultipleButtons(generateStrategyButtonsForm(strategies)) reply.Message("Please choose one strategy") } else { @@ -481,7 +501,7 @@ func (it *CoreInteraction) Commands(i *interact.Interact) { i.PrivateCommand("/modifyposition", "Modify Strategy Position", func(reply interact.Reply) error { // it.trader.exchangeStrategies // send symbol options - if strategies, err := filterStrategiesByField(it.exchangeStrategies, "Position", reflect.TypeOf(types.NewPosition("", "", ""))); err == nil && len(strategies) > 0 { + if strategies, err := filterStrategiesByField(it.exchangeStrategies, "Position", reflect.TypeOf(&types.Position{})); err == nil && len(strategies) > 0 { reply.AddMultipleButtons(generateStrategyButtonsForm(strategies)) reply.Message("Please choose one strategy") } else { diff --git a/pkg/bbgo/interact_test.go b/pkg/bbgo/interact_test.go index 21d56f162..7423b7a45 100644 --- a/pkg/bbgo/interact_test.go +++ b/pkg/bbgo/interact_test.go @@ -6,20 +6,28 @@ import ( "testing" "github.com/stretchr/testify/assert" + + "github.com/c9s/bbgo/pkg/fixedpoint" + "github.com/c9s/bbgo/pkg/types" ) type myStrategy struct { - Symbol string `json:"symbol"` + Symbol string `json:"symbol"` + Position *types.Position } -func (m myStrategy) ID() string { +func (m *myStrategy) ID() string { return "mystrategy" } -func (m myStrategy) InstanceID() string { +func (m *myStrategy) InstanceID() string { return fmt.Sprintf("%s:%s", m.ID(), m.Symbol) } +func (m *myStrategy) ClosePosition(ctx context.Context, percentage fixedpoint.Value) error { + return nil +} + func (m *myStrategy) Run(ctx context.Context, orderExecutor OrderExecutor, session *ExchangeSession) error { return nil } @@ -31,3 +39,20 @@ func Test_getStrategySignature(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "mystrategy:BTCUSDT", signature) } + +func Test_hasTypeField(t *testing.T) { + s := &myStrategy{ + Symbol: "BTCUSDT", + } + ok := hasTypeField(s, &types.Position{}) + assert.True(t, ok) +} + +func Test_testInterface(t *testing.T) { + s := &myStrategy{ + Symbol: "BTCUSDT", + } + + ok := testInterface(s, (*PositionCloser)(nil)) + assert.True(t, ok) +}