mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 14:55:16 +00:00
feature: revert position closer and position reader back
This commit is contained in:
parent
78a8c2aaaf
commit
64766c48f3
|
@ -1,6 +1,7 @@
|
||||||
package bbgo
|
package bbgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -12,9 +13,17 @@ import (
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PositionCloser interface {
|
||||||
|
ClosePosition(ctx context.Context, percentage fixedpoint.Value) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type PositionReader interface {
|
||||||
|
CurrentPosition() *types.Position
|
||||||
|
}
|
||||||
|
|
||||||
type closePositionContext struct {
|
type closePositionContext struct {
|
||||||
signature string
|
signature string
|
||||||
controller StrategyControllerInterface
|
closer PositionCloser
|
||||||
percentage fixedpoint.Value
|
percentage fixedpoint.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +43,19 @@ func NewCoreInteraction(environment *Environment, trader *Trader) *CoreInteracti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (it *CoreInteraction) FilterStrategyByInterface(checkInterface interface{}) (strategies []string, found bool) {
|
||||||
|
found = false
|
||||||
|
rt := reflect.TypeOf(checkInterface).Elem()
|
||||||
|
for signature, strategy := range it.exchangeStrategies {
|
||||||
|
if ok := reflect.TypeOf(strategy).Implements(rt); ok {
|
||||||
|
strategies = append(strategies, signature)
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strategies, found
|
||||||
|
}
|
||||||
|
|
||||||
func (it *CoreInteraction) GetStrategyController(strategy SingleExchangeStrategy) (controller StrategyControllerInterface, found bool) {
|
func (it *CoreInteraction) GetStrategyController(strategy SingleExchangeStrategy) (controller StrategyControllerInterface, found bool) {
|
||||||
if strategyController := reflect.ValueOf(&strategy).Elem().FieldByName("strategyController"); strategyController.IsValid() {
|
if strategyController := reflect.ValueOf(&strategy).Elem().FieldByName("strategyController"); strategyController.IsValid() {
|
||||||
controller = strategyController.Interface().(StrategyControllerInterface)
|
controller = strategyController.Interface().(StrategyControllerInterface)
|
||||||
|
@ -43,20 +65,6 @@ func (it *CoreInteraction) GetStrategyController(strategy SingleExchangeStrategy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *CoreInteraction) FilterStrategyByCallBack(callBack string) (strategies []string, found bool) {
|
|
||||||
found = false
|
|
||||||
for signature, strategy := range it.exchangeStrategies {
|
|
||||||
if strategyController, ok := it.GetStrategyController(strategy); ok {
|
|
||||||
if strategyController.HasCallback(callBack) {
|
|
||||||
strategies = append(strategies, signature)
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return strategies, found
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenerateStrategyButtonsForm(strategies []string) [][3]string {
|
func GenerateStrategyButtonsForm(strategies []string) [][3]string {
|
||||||
var buttonsForm [][3]string
|
var buttonsForm [][3]string
|
||||||
for _, strategy := range strategies {
|
for _, strategy := range strategies {
|
||||||
|
@ -113,11 +121,11 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
i.PrivateCommand("/position", "Show Position", func(reply interact.Reply) error {
|
i.PrivateCommand("/position", "Show Position", func(reply interact.Reply) error {
|
||||||
// it.trader.exchangeStrategies
|
// it.trader.exchangeStrategies
|
||||||
// send symbol options
|
// send symbol options
|
||||||
if strategies, found := it.FilterStrategyByCallBack("GetPositionCallback"); found {
|
if strategies, found := it.FilterStrategyByInterface((*PositionReader)(nil)); found {
|
||||||
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
||||||
reply.Message("Please choose one strategy")
|
reply.Message("Please choose one strategy")
|
||||||
} else {
|
} else {
|
||||||
reply.Message("No strategy supports GetPosition")
|
reply.Message("No strategy supports PositionReader")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}).Cycle(func(signature string, reply interact.Reply) error {
|
}).Cycle(func(signature string, reply interact.Reply) error {
|
||||||
|
@ -127,44 +135,38 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
return fmt.Errorf("strategy %s not found", signature)
|
return fmt.Errorf("strategy %s not found", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
controller, implemented := it.GetStrategyController(strategy)
|
reader, implemented := strategy.(PositionReader)
|
||||||
if !implemented {
|
if !implemented {
|
||||||
reply.Message(fmt.Sprintf("Strategy %s does not support StrategyController", signature))
|
reply.Message(fmt.Sprintf("Strategy %s does not support position close", signature))
|
||||||
return fmt.Errorf("strategy %s does not implement StrategyController", signature)
|
return fmt.Errorf("strategy %s does not implement PositionCloser interface", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
position, err := controller.EmitGetPosition()
|
position := reader.CurrentPosition()
|
||||||
|
if position != nil {
|
||||||
|
reply.Send("Your current position:")
|
||||||
|
reply.Send(position.PlainText())
|
||||||
|
|
||||||
|
if position.Base.IsZero() {
|
||||||
|
reply.Message(fmt.Sprintf("Strategy %q has no opened position", signature))
|
||||||
|
return fmt.Errorf("strategy %T has no opened position", strategy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if kc, ok := reply.(interact.KeyboardController); ok {
|
if kc, ok := reply.(interact.KeyboardController); ok {
|
||||||
kc.RemoveKeyboard()
|
kc.RemoveKeyboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
reply.Message(fmt.Sprintf("unable to get position of strategy %s: %s", signature, err.Error()))
|
|
||||||
return fmt.Errorf("unable to get position of strategy %s: %s", signature, err.Error())
|
|
||||||
} else {
|
|
||||||
if position != nil {
|
|
||||||
reply.Send("Your current position:")
|
|
||||||
reply.Send(position.PlainText())
|
|
||||||
|
|
||||||
if position.Base.IsZero() {
|
|
||||||
reply.Message(fmt.Sprintf("Strategy %q has no opened position", signature))
|
|
||||||
return fmt.Errorf("strategy %T has no opened position", strategy)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
i.PrivateCommand("/closeposition", "Close position", func(reply interact.Reply) error {
|
i.PrivateCommand("/closeposition", "Close position", func(reply interact.Reply) error {
|
||||||
// it.trader.exchangeStrategies
|
// it.trader.exchangeStrategies
|
||||||
// send symbol options
|
// send symbol options
|
||||||
if strategies, found := it.FilterStrategyByCallBack("ClosePositionCallback"); found {
|
if strategies, found := it.FilterStrategyByInterface((*PositionCloser)(nil)); found {
|
||||||
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
||||||
reply.Message("Please choose one strategy")
|
reply.Message("Please choose one strategy")
|
||||||
} else {
|
} else {
|
||||||
reply.Message("No any strategy supports ClosePosition")
|
reply.Message("No strategy supports PositionCloser")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}).Next(func(signature string, reply interact.Reply) error {
|
}).Next(func(signature string, reply interact.Reply) error {
|
||||||
|
@ -174,25 +176,28 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
return fmt.Errorf("strategy %s not found", signature)
|
return fmt.Errorf("strategy %s not found", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
controller, implemented := it.GetStrategyController(strategy)
|
closer, implemented := strategy.(PositionCloser)
|
||||||
if !implemented {
|
if !implemented {
|
||||||
reply.Message(fmt.Sprintf("Strategy %s does not support StrategyController", signature))
|
reply.Message(fmt.Sprintf("Strategy %s does not support position close", signature))
|
||||||
return fmt.Errorf("strategy %s does not implement StrategyController", signature)
|
return fmt.Errorf("strategy %s does not implement PositionCloser interface", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
it.closePositionContext.controller = controller
|
it.closePositionContext.closer = closer
|
||||||
it.closePositionContext.signature = signature
|
it.closePositionContext.signature = signature
|
||||||
|
|
||||||
if position, err := controller.EmitGetPosition(); err == nil {
|
if reader, implemented := strategy.(PositionReader); implemented {
|
||||||
reply.Send("Your current position:")
|
position := reader.CurrentPosition()
|
||||||
reply.Send(position.PlainText())
|
if position != nil {
|
||||||
|
reply.Send("Your current position:")
|
||||||
|
reply.Send(position.PlainText())
|
||||||
|
|
||||||
if position.Base.IsZero() {
|
if position.Base.IsZero() {
|
||||||
reply.Message("No opened position")
|
reply.Message("No opened position")
|
||||||
if kc, ok := reply.(interact.KeyboardController); ok {
|
if kc, ok := reply.(interact.KeyboardController); ok {
|
||||||
kc.RemoveKeyboard()
|
kc.RemoveKeyboard()
|
||||||
|
}
|
||||||
|
return fmt.Errorf("no opened position")
|
||||||
}
|
}
|
||||||
return fmt.Errorf("no opened position")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +218,7 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
kc.RemoveKeyboard()
|
kc.RemoveKeyboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
err = it.closePositionContext.controller.EmitClosePosition(percentage)
|
err = it.closePositionContext.closer.ClosePosition(context.Background(), percentage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reply.Message(fmt.Sprintf("Failed to close the position, %s", err.Error()))
|
reply.Message(fmt.Sprintf("Failed to close the position, %s", err.Error()))
|
||||||
return err
|
return err
|
||||||
|
@ -226,11 +231,11 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
i.PrivateCommand("/status", "Strategy Status", func(reply interact.Reply) error {
|
i.PrivateCommand("/status", "Strategy Status", func(reply interact.Reply) error {
|
||||||
// it.trader.exchangeStrategies
|
// it.trader.exchangeStrategies
|
||||||
// send symbol options
|
// send symbol options
|
||||||
if strategies, found := it.FilterStrategyByCallBack("GetStatusCallback"); found {
|
if strategies, found := it.FilterStrategyByInterface((*StrategyControllerInterface)(nil)); found {
|
||||||
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
||||||
reply.Message("Please choose a strategy")
|
reply.Message("Please choose a strategy")
|
||||||
} else {
|
} else {
|
||||||
reply.Message("No strategy supports GetStatus")
|
reply.Message("No strategy supports StrategyController")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}).Next(func(signature string, reply interact.Reply) error {
|
}).Next(func(signature string, reply interact.Reply) error {
|
||||||
|
@ -240,27 +245,22 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
return fmt.Errorf("strategy %s not found", signature)
|
return fmt.Errorf("strategy %s not found", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
controller, implemented := it.GetStrategyController(strategy)
|
controller, implemented := strategy.(StrategyControllerInterface)
|
||||||
if !implemented {
|
if !implemented {
|
||||||
reply.Message(fmt.Sprintf("Strategy %s does not support StrategyController", signature))
|
reply.Message(fmt.Sprintf("Strategy %s does not support StrategyController", signature))
|
||||||
return fmt.Errorf("strategy %s does not implement StrategyController", signature)
|
return fmt.Errorf("strategy %s does not implement StrategyController", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
status, err := controller.EmitGetStatus()
|
status := controller.GetStatus()
|
||||||
|
|
||||||
if kc, ok := reply.(interact.KeyboardController); ok {
|
if kc, ok := reply.(interact.KeyboardController); ok {
|
||||||
kc.RemoveKeyboard()
|
kc.RemoveKeyboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if status == types.StrategyStatusRunning {
|
||||||
reply.Message(fmt.Sprintf("unable to get status of strategy %s: %s", signature, err.Error()))
|
reply.Message(fmt.Sprintf("Strategy %s is running.", signature))
|
||||||
return fmt.Errorf("unable to get status of strategy %s: %s", signature, err.Error())
|
} else if status == types.StrategyStatusStopped {
|
||||||
} else {
|
reply.Message(fmt.Sprintf("Strategy %s is not running.", signature))
|
||||||
if status == types.StrategyStatusRunning {
|
|
||||||
reply.Message(fmt.Sprintf("Strategy %s is running.", signature))
|
|
||||||
} else if status == types.StrategyStatusStopped {
|
|
||||||
reply.Message(fmt.Sprintf("Strategy %s is not running.", signature))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -269,11 +269,11 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
i.PrivateCommand("/suspend", "Suspend Strategy", func(reply interact.Reply) error {
|
i.PrivateCommand("/suspend", "Suspend Strategy", func(reply interact.Reply) error {
|
||||||
// it.trader.exchangeStrategies
|
// it.trader.exchangeStrategies
|
||||||
// send symbol options
|
// send symbol options
|
||||||
if strategies, found := it.FilterStrategyByCallBack("SuspendCallback"); found {
|
if strategies, found := it.FilterStrategyByInterface((*StrategyControllerInterface)(nil)); found {
|
||||||
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
||||||
reply.Message("Please choose one strategy")
|
reply.Message("Please choose one strategy")
|
||||||
} else {
|
} else {
|
||||||
reply.Message("No strategy supports Suspend")
|
reply.Message("No strategy supports StrategyController")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}).Next(func(signature string, reply interact.Reply) error {
|
}).Next(func(signature string, reply interact.Reply) error {
|
||||||
|
@ -283,26 +283,23 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
return fmt.Errorf("strategy %s not found", signature)
|
return fmt.Errorf("strategy %s not found", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
controller, implemented := it.GetStrategyController(strategy)
|
controller, implemented := strategy.(StrategyControllerInterface)
|
||||||
if !implemented {
|
if !implemented {
|
||||||
reply.Message(fmt.Sprintf("Strategy %s does not support StrategyController", signature))
|
reply.Message(fmt.Sprintf("Strategy %s does not support StrategyController", signature))
|
||||||
return fmt.Errorf("strategy %s does not implement StrategyController", signature)
|
return fmt.Errorf("strategy %s does not implement StrategyController", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check strategy status before suspend
|
// Check strategy status before suspend
|
||||||
status, err := controller.EmitGetStatus()
|
if controller.GetStatus() != types.StrategyStatusRunning {
|
||||||
if status != types.StrategyStatusRunning {
|
|
||||||
reply.Message(fmt.Sprintf("Strategy %s is not running.", signature))
|
reply.Message(fmt.Sprintf("Strategy %s is not running.", signature))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err = controller.EmitSuspend()
|
|
||||||
|
|
||||||
if kc, ok := reply.(interact.KeyboardController); ok {
|
if kc, ok := reply.(interact.KeyboardController); ok {
|
||||||
kc.RemoveKeyboard()
|
kc.RemoveKeyboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err := controller.Suspend(); err != nil {
|
||||||
reply.Message(fmt.Sprintf("Failed to suspend the strategy, %s", err.Error()))
|
reply.Message(fmt.Sprintf("Failed to suspend the strategy, %s", err.Error()))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -314,11 +311,11 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
i.PrivateCommand("/resume", "Resume Strategy", func(reply interact.Reply) error {
|
i.PrivateCommand("/resume", "Resume Strategy", func(reply interact.Reply) error {
|
||||||
// it.trader.exchangeStrategies
|
// it.trader.exchangeStrategies
|
||||||
// send symbol options
|
// send symbol options
|
||||||
if strategies, found := it.FilterStrategyByCallBack("ResumeCallback"); found {
|
if strategies, found := it.FilterStrategyByInterface((*StrategyControllerInterface)(nil)); found {
|
||||||
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
||||||
reply.Message("Please choose one strategy")
|
reply.Message("Please choose one strategy")
|
||||||
} else {
|
} else {
|
||||||
reply.Message("No strategy supports Resume")
|
reply.Message("No strategy supports StrategyController")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}).Next(func(signature string, reply interact.Reply) error {
|
}).Next(func(signature string, reply interact.Reply) error {
|
||||||
|
@ -328,26 +325,23 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
return fmt.Errorf("strategy %s not found", signature)
|
return fmt.Errorf("strategy %s not found", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
controller, implemented := it.GetStrategyController(strategy)
|
controller, implemented := strategy.(StrategyControllerInterface)
|
||||||
if !implemented {
|
if !implemented {
|
||||||
reply.Message(fmt.Sprintf("Strategy %s does not support StrategyController", signature))
|
reply.Message(fmt.Sprintf("Strategy %s does not support StrategyController", signature))
|
||||||
return fmt.Errorf("strategy %s does not implement StrategyController", signature)
|
return fmt.Errorf("strategy %s does not implement StrategyController", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check strategy status before resume
|
// Check strategy status before suspend
|
||||||
status, err := controller.EmitGetStatus()
|
if controller.GetStatus() != types.StrategyStatusStopped {
|
||||||
if status != types.StrategyStatusStopped {
|
|
||||||
reply.Message(fmt.Sprintf("Strategy %s is running.", signature))
|
reply.Message(fmt.Sprintf("Strategy %s is running.", signature))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err = controller.EmitResume()
|
|
||||||
|
|
||||||
if kc, ok := reply.(interact.KeyboardController); ok {
|
if kc, ok := reply.(interact.KeyboardController); ok {
|
||||||
kc.RemoveKeyboard()
|
kc.RemoveKeyboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err := controller.Resume(); err != nil {
|
||||||
reply.Message(fmt.Sprintf("Failed to resume the strategy, %s", err.Error()))
|
reply.Message(fmt.Sprintf("Failed to resume the strategy, %s", err.Error()))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -359,11 +353,11 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
i.PrivateCommand("/emergencystop", "Emergency Stop", func(reply interact.Reply) error {
|
i.PrivateCommand("/emergencystop", "Emergency Stop", func(reply interact.Reply) error {
|
||||||
// it.trader.exchangeStrategies
|
// it.trader.exchangeStrategies
|
||||||
// send symbol options
|
// send symbol options
|
||||||
if strategies, found := it.FilterStrategyByCallBack("EmergencyStopCallback"); found {
|
if strategies, found := it.FilterStrategyByInterface((*StrategyControllerInterface)(nil)); found {
|
||||||
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
reply.AddMultipleButtons(GenerateStrategyButtonsForm(strategies))
|
||||||
reply.Message("Please choose one strategy")
|
reply.Message("Please choose one strategy")
|
||||||
} else {
|
} else {
|
||||||
reply.Message("No strategy supports EmergencyStop")
|
reply.Message("No strategy supports StrategyController")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}).Next(func(signature string, reply interact.Reply) error {
|
}).Next(func(signature string, reply interact.Reply) error {
|
||||||
|
@ -373,19 +367,17 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
||||||
return fmt.Errorf("strategy %s not found", signature)
|
return fmt.Errorf("strategy %s not found", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
controller, implemented := it.GetStrategyController(strategy)
|
controller, implemented := strategy.(StrategyControllerInterface)
|
||||||
if !implemented {
|
if !implemented {
|
||||||
reply.Message(fmt.Sprintf("Strategy %s does not support StrategyController", signature))
|
reply.Message(fmt.Sprintf("Strategy %s does not support StrategyController", signature))
|
||||||
return fmt.Errorf("strategy %s does not implement StrategyController", signature)
|
return fmt.Errorf("strategy %s does not implement StrategyController", signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := controller.EmitEmergencyStop()
|
|
||||||
|
|
||||||
if kc, ok := reply.(interact.KeyboardController); ok {
|
if kc, ok := reply.(interact.KeyboardController); ok {
|
||||||
kc.RemoveKeyboard()
|
kc.RemoveKeyboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err := controller.EmergencyStop(); err != nil {
|
||||||
reply.Message(fmt.Sprintf("Failed to emergency stop the strategy, %s", err.Error()))
|
reply.Message(fmt.Sprintf("Failed to emergency stop the strategy, %s", err.Error()))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user