mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-22 06:53:52 +00:00
positionmodifier: move functions into types.Position
This commit is contained in:
parent
9588a6f6bd
commit
4bc70820c4
|
@ -27,9 +27,9 @@ type closePositionContext struct {
|
|||
percentage fixedpoint.Value
|
||||
}
|
||||
|
||||
type updatePositionContext struct {
|
||||
type modifyPositionContext struct {
|
||||
signature string
|
||||
updater StrategyPositionUpdater
|
||||
modifier *types.Position
|
||||
target string
|
||||
value fixedpoint.Value
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ type CoreInteraction struct {
|
|||
|
||||
exchangeStrategies map[string]SingleExchangeStrategy
|
||||
closePositionContext closePositionContext
|
||||
updatePositionContext updatePositionContext
|
||||
modifyPositionContext modifyPositionContext
|
||||
}
|
||||
|
||||
func NewCoreInteraction(environment *Environment, trader *Trader) *CoreInteraction {
|
||||
|
@ -74,6 +74,21 @@ func filterStrategyByInterface(checkInterface interface{}, exchangeStrategies ma
|
|||
return strategies, found
|
||||
}
|
||||
|
||||
func filterStrategyByField(fieldName string, fieldType reflect.Type, exchangeStrategies map[string]SingleExchangeStrategy) (strategies map[string]SingleExchangeStrategy, found bool) {
|
||||
found = false
|
||||
strategies = make(map[string]SingleExchangeStrategy)
|
||||
for signature, strategy := range exchangeStrategies {
|
||||
r := reflect.ValueOf(strategy).Elem()
|
||||
f := r.FieldByName(fieldName)
|
||||
if !f.IsZero() && f.Type() == fieldType {
|
||||
strategies[signature] = strategy
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
return strategies, found
|
||||
}
|
||||
|
||||
func generateStrategyButtonsForm(strategies map[string]SingleExchangeStrategy) [][3]string {
|
||||
var buttonsForm [][3]string
|
||||
signatures := getStrategySignatures(strategies)
|
||||
|
@ -397,14 +412,14 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
|||
})
|
||||
|
||||
// Position updater
|
||||
i.PrivateCommand("/setposition", "Set Strategy Position", func(reply interact.Reply) error {
|
||||
i.PrivateCommand("/modifyposition", "Modify Strategy Position", func(reply interact.Reply) error {
|
||||
// it.trader.exchangeStrategies
|
||||
// send symbol options
|
||||
if strategies, found := filterStrategyByInterface((*StrategyPositionUpdater)(nil), it.exchangeStrategies); found {
|
||||
if strategies, found := filterStrategyByField("Position", reflect.TypeOf(types.NewPosition("", "", "")), it.exchangeStrategies); found {
|
||||
reply.AddMultipleButtons(generateStrategyButtonsForm(strategies))
|
||||
reply.Message("Please choose one strategy")
|
||||
} else {
|
||||
reply.Message("No strategy supports StrategyPositionUpdater")
|
||||
reply.Message("No strategy supports Position Modify")
|
||||
}
|
||||
return nil
|
||||
}).Next(func(signature string, reply interact.Reply) error {
|
||||
|
@ -414,14 +429,16 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
|||
return fmt.Errorf("strategy %s not found", signature)
|
||||
}
|
||||
|
||||
updater, implemented := strategy.(StrategyPositionUpdater)
|
||||
r := reflect.ValueOf(strategy).Elem()
|
||||
f := r.FieldByName("Position")
|
||||
positionModifier, implemented := f.Interface().(*types.Position)
|
||||
if !implemented {
|
||||
reply.Message(fmt.Sprintf("Strategy %s does not support StrategyPositionUpdater", signature))
|
||||
return fmt.Errorf("strategy %s does not implement StrategyPositionUpdater", signature)
|
||||
reply.Message(fmt.Sprintf("Strategy %s does not support Position Modify", signature))
|
||||
return fmt.Errorf("strategy %s does not implement Position Modify", signature)
|
||||
}
|
||||
|
||||
it.updatePositionContext.updater = updater
|
||||
it.updatePositionContext.signature = signature
|
||||
it.modifyPositionContext.modifier = positionModifier
|
||||
it.modifyPositionContext.signature = signature
|
||||
|
||||
reply.Message("Please choose what you want to change")
|
||||
reply.AddButton("base", "Base", "base")
|
||||
|
@ -435,13 +452,13 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
|||
return fmt.Errorf("%q is not a valid target string", target)
|
||||
}
|
||||
|
||||
it.updatePositionContext.target = target
|
||||
it.modifyPositionContext.target = target
|
||||
|
||||
reply.Message("Enter the amount to change")
|
||||
|
||||
return nil
|
||||
}).Next(func(valueStr string, reply interact.Reply) error {
|
||||
value, err := strconv.ParseFloat(valueStr, 64)
|
||||
value, err := fixedpoint.NewFromString(valueStr)
|
||||
if err != nil {
|
||||
reply.Message(fmt.Sprintf("%q is not a valid value string", valueStr))
|
||||
return err
|
||||
|
@ -451,12 +468,12 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
|||
kc.RemoveKeyboard()
|
||||
}
|
||||
|
||||
if it.updatePositionContext.target == "base" {
|
||||
err = it.updatePositionContext.updater.UpdateBase(value)
|
||||
} else if it.updatePositionContext.target == "quote" {
|
||||
err = it.updatePositionContext.updater.UpdateQuote(value)
|
||||
} else if it.updatePositionContext.target == "cost" {
|
||||
err = it.updatePositionContext.updater.UpdateAverageCost(value)
|
||||
if it.modifyPositionContext.target == "base" {
|
||||
err = it.modifyPositionContext.modifier.ModifyBase(value)
|
||||
} else if it.modifyPositionContext.target == "quote" {
|
||||
err = it.modifyPositionContext.modifier.ModifyQuote(value)
|
||||
} else if it.modifyPositionContext.target == "cost" {
|
||||
err = it.modifyPositionContext.modifier.ModifyAverageCost(value)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -464,7 +481,7 @@ func (it *CoreInteraction) Commands(i *interact.Interact) {
|
|||
return err
|
||||
}
|
||||
|
||||
reply.Message(fmt.Sprintf("Position of strategy %s modified.", it.updatePositionContext.signature))
|
||||
reply.Message(fmt.Sprintf("Position of strategy %s modified.", it.modifyPositionContext.signature))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
package bbgo
|
||||
|
||||
import (
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
//go:generate callbackgen -type PositionUpdater -interface
|
||||
type PositionUpdater struct {
|
||||
Position *types.Position
|
||||
|
||||
// Callbacks
|
||||
updateBaseCallbacks []func()
|
||||
updateQuoteCallbacks []func()
|
||||
updateAverageCostCallbacks []func()
|
||||
}
|
||||
|
||||
func (s *PositionUpdater) UpdateBase(qty float64) error {
|
||||
s.Position.Base = fixedpoint.NewFromFloat(qty)
|
||||
|
||||
s.EmitUpdateBase()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PositionUpdater) UpdateQuote(qty float64) error {
|
||||
s.Position.Quote = fixedpoint.NewFromFloat(qty)
|
||||
|
||||
s.EmitUpdateQuote()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PositionUpdater) UpdateAverageCost(price float64) error {
|
||||
s.Position.AverageCost = fixedpoint.NewFromFloat(price)
|
||||
|
||||
s.EmitUpdateAverageCost()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type StrategyPositionUpdater interface {
|
||||
UpdateBase(qty float64) error
|
||||
UpdateQuote(qty float64) error
|
||||
UpdateAverageCost(price float64) error
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
// Code generated by "callbackgen -type PositionUpdater -interface"; DO NOT EDIT.
|
||||
|
||||
package bbgo
|
||||
|
||||
import ()
|
||||
|
||||
func (s *PositionUpdater) OnUpdateBase(cb func()) {
|
||||
s.updateBaseCallbacks = append(s.updateBaseCallbacks, cb)
|
||||
}
|
||||
|
||||
func (s *PositionUpdater) EmitUpdateBase() {
|
||||
for _, cb := range s.updateBaseCallbacks {
|
||||
cb()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PositionUpdater) OnUpdateQuote(cb func()) {
|
||||
s.updateQuoteCallbacks = append(s.updateQuoteCallbacks, cb)
|
||||
}
|
||||
|
||||
func (s *PositionUpdater) EmitUpdateQuote() {
|
||||
for _, cb := range s.updateQuoteCallbacks {
|
||||
cb()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PositionUpdater) OnUpdateAverageCost(cb func()) {
|
||||
s.updateAverageCostCallbacks = append(s.updateAverageCostCallbacks, cb)
|
||||
}
|
||||
|
||||
func (s *PositionUpdater) EmitUpdateAverageCost() {
|
||||
for _, cb := range s.updateAverageCostCallbacks {
|
||||
cb()
|
||||
}
|
||||
}
|
||||
|
||||
type PositionUpdaterEventHub interface {
|
||||
OnUpdateBase(cb func())
|
||||
|
||||
OnUpdateQuote(cb func())
|
||||
|
||||
OnUpdateAverageCost(cb func())
|
||||
}
|
|
@ -84,9 +84,6 @@ type Strategy struct {
|
|||
|
||||
// StrategyController
|
||||
bbgo.StrategyController
|
||||
|
||||
// PositionUpdater
|
||||
bbgo.PositionUpdater
|
||||
}
|
||||
|
||||
func (s *Strategy) ID() string {
|
||||
|
|
|
@ -59,6 +59,11 @@ type Position struct {
|
|||
AccumulatedProfit fixedpoint.Value `json:"accumulatedProfit,omitempty" db:"accumulated_profit"`
|
||||
|
||||
sync.Mutex
|
||||
|
||||
// Modify position callbacks
|
||||
modifyBaseCallbacks []func(qty fixedpoint.Value)
|
||||
modifyQuoteCallbacks []func(qty fixedpoint.Value)
|
||||
modifyAverageCostCallbacks []func(price fixedpoint.Value)
|
||||
}
|
||||
|
||||
func (p *Position) CsvHeader() []string {
|
||||
|
@ -195,6 +200,54 @@ func (p *Position) UnrealizedProfit(price fixedpoint.Value) fixedpoint.Value {
|
|||
return fixedpoint.Zero
|
||||
}
|
||||
|
||||
// ModifyBase modifies position base quantity with `qty`
|
||||
func (p *Position) ModifyBase(qty fixedpoint.Value) error {
|
||||
p.Base = qty
|
||||
|
||||
p.EmitModifyBase(qty)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EmitModifyBase triggers callbacks
|
||||
func (p *Position) EmitModifyBase(qty fixedpoint.Value) {
|
||||
for _, cb := range p.modifyBaseCallbacks {
|
||||
cb(qty)
|
||||
}
|
||||
}
|
||||
|
||||
// ModifyQuote modifies position quote quantity with `qty`
|
||||
func (p *Position) ModifyQuote(qty fixedpoint.Value) error {
|
||||
p.Quote = qty
|
||||
|
||||
p.EmitModifyQuote(qty)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EmitModifyQuote triggers callbacks
|
||||
func (p *Position) EmitModifyQuote(qty fixedpoint.Value) {
|
||||
for _, cb := range p.modifyQuoteCallbacks {
|
||||
cb(qty)
|
||||
}
|
||||
}
|
||||
|
||||
// ModifyAverageCost modifies position average cost with `price`
|
||||
func (p *Position) ModifyAverageCost(price fixedpoint.Value) error {
|
||||
p.AverageCost = price
|
||||
|
||||
p.EmitModifyAverageCost(price)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EmitModifyAverageCost triggers callbacks
|
||||
func (p *Position) EmitModifyAverageCost(price fixedpoint.Value) {
|
||||
for _, cb := range p.modifyAverageCostCallbacks {
|
||||
cb(price)
|
||||
}
|
||||
}
|
||||
|
||||
type FuturesPosition struct {
|
||||
Symbol string `json:"symbol"`
|
||||
BaseCurrency string `json:"baseCurrency"`
|
||||
|
|
Loading…
Reference in New Issue
Block a user