Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

types: refactor Position and related files #348

Merged
merged 1 commit into from
Dec 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions pkg/accounting/pnl/avg_cost.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package pnl
import (
"time"

"github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
Expand Down Expand Up @@ -33,8 +32,8 @@ func (c *AverageCostCalculator) Calculate(symbol string, trades []types.Trade, c

var currencyFees = map[string]float64{}

var position = bbgo.NewPositionFromMarket(c.Market)
position.SetFeeRate(bbgo.ExchangeFee{
var position = types.NewPositionFromMarket(c.Market)
position.SetFeeRate(types.ExchangeFee{
// binance vip 0 uses 0.075%
MakerFeeRate: fixedpoint.NewFromFloat(0.075 * 0.01),
TakerFeeRate: fixedpoint.NewFromFloat(0.075 * 0.01),
Expand Down
14 changes: 7 additions & 7 deletions pkg/bbgo/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ type ExchangeSession struct {
// marketDataStores contains the market data store of each market
marketDataStores map[string]*MarketDataStore

positions map[string]*Position
positions map[string]*types.Position

// standard indicators of each market
standardIndicatorSets map[string]*StandardIndicatorSet
Expand Down Expand Up @@ -236,7 +236,7 @@ func NewExchangeSession(name string, exchange types.Exchange) *ExchangeSession {
markets: make(map[string]types.Market),
startPrices: make(map[string]float64),
lastPrices: make(map[string]float64),
positions: make(map[string]*Position),
positions: make(map[string]*types.Position),
marketDataStores: make(map[string]*MarketDataStore),
standardIndicatorSets: make(map[string]*StandardIndicatorSet),
orderStores: make(map[string]*OrderStore),
Expand Down Expand Up @@ -388,7 +388,7 @@ func (session *ExchangeSession) initSymbol(ctx context.Context, environ *Environ
session.Trades[symbol].Append(trade)
})

position := &Position{
position := &types.Position{
Symbol: symbol,
BaseCurrency: market.BaseCurrency,
QuoteCurrency: market.QuoteCurrency,
Expand Down Expand Up @@ -475,7 +475,7 @@ func (session *ExchangeSession) StandardIndicatorSet(symbol string) (*StandardIn
return set, ok
}

func (session *ExchangeSession) Position(symbol string) (pos *Position, ok bool) {
func (session *ExchangeSession) Position(symbol string) (pos *types.Position, ok bool) {
pos, ok = session.positions[symbol]
if ok {
return pos, ok
Expand All @@ -486,7 +486,7 @@ func (session *ExchangeSession) Position(symbol string) (pos *Position, ok bool)
return nil, false
}

pos = &Position{
pos = &types.Position{
Symbol: symbol,
BaseCurrency: market.BaseCurrency,
QuoteCurrency: market.QuoteCurrency,
Expand All @@ -496,7 +496,7 @@ func (session *ExchangeSession) Position(symbol string) (pos *Position, ok bool)
return pos, ok
}

func (session *ExchangeSession) Positions() map[string]*Position {
func (session *ExchangeSession) Positions() map[string]*types.Position {
return session.positions
}

Expand Down Expand Up @@ -712,7 +712,7 @@ func InitExchangeSession(name string, session *ExchangeSession) error {
session.lastPrices = make(map[string]float64)
session.startPrices = make(map[string]float64)
session.marketDataStores = make(map[string]*MarketDataStore)
session.positions = make(map[string]*Position)
session.positions = make(map[string]*types.Position)
session.standardIndicatorSets = make(map[string]*StandardIndicatorSet)
session.orderStores = make(map[string]*OrderStore)
session.OrderExecutor = &ExchangeOrderExecutor{
Expand Down
6 changes: 3 additions & 3 deletions pkg/bbgo/tradecollector.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ type TradeCollector struct {

tradeStore *TradeStore
tradeC chan types.Trade
position *Position
position *types.Position
orderStore *OrderStore

tradeCallbacks []func(trade types.Trade)
positionUpdateCallbacks []func(position *Position)
positionUpdateCallbacks []func(position *types.Position)
profitCallbacks []func(trade types.Trade, profit, netProfit fixedpoint.Value)
}

func NewTradeCollector(symbol string, position *Position, orderStore *OrderStore) *TradeCollector {
func NewTradeCollector(symbol string, position *types.Position, orderStore *OrderStore) *TradeCollector {
return &TradeCollector{
Symbol: symbol,
orderSig: sigchan.New(1),
Expand Down
4 changes: 2 additions & 2 deletions pkg/bbgo/tradecollector_callbacks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/bbgo/twap_order_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type TwapExecution struct {

activeMakerOrders *LocalActiveOrderBook
orderStore *OrderStore
position *Position
position *types.Position

executionCtx context.Context
cancelExecution context.CancelFunc
Expand Down Expand Up @@ -444,7 +444,7 @@ func (e *TwapExecution) Run(parentCtx context.Context) error {

e.userDataStream = e.Session.Exchange.NewStream()
e.userDataStream.OnTradeUpdate(e.handleTradeUpdate)
e.position = &Position{
e.position = &types.Position{
Symbol: e.Symbol,
BaseCurrency: e.market.BaseCurrency,
QuoteCurrency: e.market.QuoteCurrency,
Expand Down
6 changes: 3 additions & 3 deletions pkg/strategy/bollpp/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func init() {
}

type State struct {
Position *bbgo.Position `json:"position,omitempty"`
Position *types.Position `json:"position,omitempty"`
ProfitStats bbgo.ProfitStats `json:"profitStats,omitempty"`
}

Expand Down Expand Up @@ -119,7 +119,7 @@ func (s *Strategy) LoadState() error {

// if position is nil, we need to allocate a new position for calculation
if s.state.Position == nil {
s.state.Position = bbgo.NewPositionFromMarket(s.market)
s.state.Position = types.NewPositionFromMarket(s.market)
}

// init profit states
Expand Down Expand Up @@ -297,7 +297,7 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
s.state.ProfitStats.AddTrade(trade)
})

s.tradeCollector.OnPositionUpdate(func(position *bbgo.Position) {
s.tradeCollector.OnPositionUpdate(func(position *types.Position) {
log.Infof("position changed: %s", s.state.Position)
s.Notify(s.state.Position)
})
Expand Down
20 changes: 10 additions & 10 deletions pkg/strategy/grid/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type State struct {
Orders []types.SubmitOrder `json:"orders,omitempty"`
FilledBuyGrids map[fixedpoint.Value]struct{} `json:"filledBuyGrids"`
FilledSellGrids map[fixedpoint.Value]struct{} `json:"filledSellGrids"`
Position *bbgo.Position `json:"position,omitempty"`
Position *types.Position `json:"position,omitempty"`

AccumulativeArbitrageProfit fixedpoint.Value `json:"accumulativeArbitrageProfit"`

Expand Down Expand Up @@ -511,7 +511,7 @@ func (s *Strategy) LoadState() error {
FilledBuyGrids: make(map[fixedpoint.Value]struct{}),
FilledSellGrids: make(map[fixedpoint.Value]struct{}),
ArbitrageOrders: make(map[uint64]types.Order),
Position: bbgo.NewPositionFromMarket(s.Market),
Position: types.NewPositionFromMarket(s.Market),
}
} else {
s.state = &state
Expand Down Expand Up @@ -591,16 +591,16 @@ func (s *Strategy) Run(ctx context.Context, orderExecutor bbgo.OrderExecutor, se
})

/*
if s.TradeService != nil {
s.tradeCollector.OnTrade(func(trade types.Trade) {
if err := s.TradeService.Mark(ctx, trade.ID, ID); err != nil {
log.WithError(err).Error("trade mark error")
}
})
}
if s.TradeService != nil {
s.tradeCollector.OnTrade(func(trade types.Trade) {
if err := s.TradeService.Mark(ctx, trade.ID, ID); err != nil {
log.WithError(err).Error("trade mark error")
}
})
}
*/

s.tradeCollector.OnPositionUpdate(func(position *bbgo.Position) {
s.tradeCollector.OnPositionUpdate(func(position *types.Position) {
s.Notifiability.Notify(position)
})
s.tradeCollector.BindStream(session.UserDataStream)
Expand Down
18 changes: 9 additions & 9 deletions pkg/strategy/support/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func init() {
}

type State struct {
Position *bbgo.Position `json:"position,omitempty"`
Position *types.Position `json:"position,omitempty"`
}

type Target struct {
Expand All @@ -42,7 +42,7 @@ type PercentageTargetStop struct {
}

// GenerateOrders generates the orders from the given targets
func (stop *PercentageTargetStop) GenerateOrders(market types.Market, pos *bbgo.Position) []types.SubmitOrder {
func (stop *PercentageTargetStop) GenerateOrders(market types.Market, pos *types.Position) []types.SubmitOrder {
var price = pos.AverageCost
var quantity = pos.Base

Expand All @@ -62,12 +62,12 @@ func (stop *PercentageTargetStop) GenerateOrders(market types.Market, pos *bbgo.
}

targetOrders = append(targetOrders, types.SubmitOrder{
Symbol: market.Symbol,
Market: market,
Type: types.OrderTypeLimit,
Side: types.SideTypeSell,
Price: targetPrice,
Quantity: targetQuantity,
Symbol: market.Symbol,
Market: market,
Type: types.OrderTypeLimit,
Side: types.SideTypeSell,
Price: targetPrice,
Quantity: targetQuantity,
MarginSideEffect: target.MarginOrderSideEffect,
TimeInForce: "GTC",
})
Expand Down Expand Up @@ -178,7 +178,7 @@ func (s *Strategy) LoadState() error {
}

if s.state.Position == nil {
s.state.Position = bbgo.NewPositionFromMarket(s.Market)
s.state.Position = types.NewPositionFromMarket(s.Market)
}

return nil
Expand Down
8 changes: 4 additions & 4 deletions pkg/strategy/xmaker/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func init() {
type State struct {
HedgePosition fixedpoint.Value `json:"hedgePosition"`
CoveredPosition fixedpoint.Value `json:"coveredPosition,omitempty"`
Position *bbgo.Position `json:"position,omitempty"`
Position *types.Position `json:"position,omitempty"`
ProfitStats ProfitStats `json:"profitStats,omitempty"`
}

Expand Down Expand Up @@ -680,7 +680,7 @@ func (s *Strategy) LoadState() error {

// if position is nil, we need to allocate a new position for calculation
if s.state.Position == nil {
s.state.Position = bbgo.NewPositionFromMarket(s.makerMarket)
s.state.Position = types.NewPositionFromMarket(s.makerMarket)
}

s.state.ProfitStats.Symbol = s.makerMarket.Symbol
Expand Down Expand Up @@ -794,14 +794,14 @@ func (s *Strategy) CrossRun(ctx context.Context, orderExecutionRouter bbgo.Order
}

if s.makerSession.MakerFeeRate > 0 || s.makerSession.TakerFeeRate > 0 {
s.state.Position.SetExchangeFeeRate(types.ExchangeName(s.MakerExchange), bbgo.ExchangeFee{
s.state.Position.SetExchangeFeeRate(types.ExchangeName(s.MakerExchange), types.ExchangeFee{
MakerFeeRate: s.makerSession.MakerFeeRate,
TakerFeeRate: s.makerSession.TakerFeeRate,
})
}

if s.sourceSession.MakerFeeRate > 0 || s.sourceSession.TakerFeeRate > 0 {
s.state.Position.SetExchangeFeeRate(types.ExchangeName(s.SourceExchange), bbgo.ExchangeFee{
s.state.Position.SetExchangeFeeRate(types.ExchangeName(s.SourceExchange), types.ExchangeFee{
MakerFeeRate: s.sourceSession.MakerFeeRate,
TakerFeeRate: s.sourceSession.TakerFeeRate,
})
Expand Down
43 changes: 29 additions & 14 deletions pkg/bbgo/position.go → pkg/types/position.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package bbgo
package types

import (
"fmt"
"sync"
"time"

"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
"github.com/c9s/bbgo/pkg/util"
"github.com/slack-go/slack"
)
Expand All @@ -21,7 +20,7 @@ type Position struct {
BaseCurrency string `json:"baseCurrency"`
QuoteCurrency string `json:"quoteCurrency"`

Market types.Market `json:"market"`
Market Market `json:"market"`

Base fixedpoint.Value `json:"base"`
Quote fixedpoint.Value `json:"quote"`
Expand All @@ -31,13 +30,29 @@ type Position struct {
// This is used for calculating net profit
ApproximateAverageCost fixedpoint.Value `json:"approximateAverageCost"`

FeeRate *ExchangeFee `json:"feeRate,omitempty"`
ExchangeFeeRates map[types.ExchangeName]ExchangeFee `json:"exchangeFeeRates"`
FeeRate *ExchangeFee `json:"feeRate,omitempty"`
ExchangeFeeRates map[ExchangeName]ExchangeFee `json:"exchangeFeeRates"`

// Futures data fields
Isolated bool `json:"isolated"`
Leverage fixedpoint.Value `json:"leverage"`
InitialMargin fixedpoint.Value `json:"initialMargin"`
MaintMargin fixedpoint.Value `json:"maintMargin"`
OpenOrderInitialMargin fixedpoint.Value `json:"openOrderInitialMargin"`
PositionInitialMargin fixedpoint.Value `json:"positionInitialMargin"`
UnrealizedProfit fixedpoint.Value `json:"unrealizedProfit"`
EntryPrice fixedpoint.Value `json:"entryPrice"`
MaxNotional fixedpoint.Value `json:"maxNotional"`
PositionSide string `json:"positionSide"`
PositionAmt fixedpoint.Value `json:"positionAmt"`
Notional fixedpoint.Value `json:"notional"`
IsolatedWallet fixedpoint.Value `json:"isolatedWallet"`
UpdateTime int64 `json:"updateTime"`

sync.Mutex
}

func NewPositionFromMarket(market types.Market) *Position {
func NewPositionFromMarket(market Market) *Position {
return &Position{
Symbol: market.Symbol,
BaseCurrency: market.BaseCurrency,
Expand All @@ -64,9 +79,9 @@ func (p *Position) SetFeeRate(exchangeFee ExchangeFee) {
p.FeeRate = &exchangeFee
}

func (p *Position) SetExchangeFeeRate(ex types.ExchangeName, exchangeFee ExchangeFee) {
func (p *Position) SetExchangeFeeRate(ex ExchangeName, exchangeFee ExchangeFee) {
if p.ExchangeFeeRates == nil {
p.ExchangeFeeRates = make(map[types.ExchangeName]ExchangeFee)
p.ExchangeFeeRates = make(map[ExchangeName]ExchangeFee)
}

p.ExchangeFeeRates[ex] = exchangeFee
Expand Down Expand Up @@ -127,15 +142,15 @@ func (p *Position) String() string {
)
}

func (p *Position) BindStream(stream types.Stream) {
stream.OnTradeUpdate(func(trade types.Trade) {
func (p *Position) BindStream(stream Stream) {
stream.OnTradeUpdate(func(trade Trade) {
if p.Symbol == trade.Symbol {
p.AddTrade(trade)
}
})
}

func (p *Position) AddTrades(trades []types.Trade) (fixedpoint.Value, fixedpoint.Value, bool) {
func (p *Position) AddTrades(trades []Trade) (fixedpoint.Value, fixedpoint.Value, bool) {
var totalProfitAmount, totalNetProfit fixedpoint.Value
for _, trade := range trades {
if profit, netProfit, madeProfit := p.AddTrade(trade); madeProfit {
Expand All @@ -147,7 +162,7 @@ func (p *Position) AddTrades(trades []types.Trade) (fixedpoint.Value, fixedpoint
return totalProfitAmount, totalNetProfit, totalProfitAmount != 0
}

func (p *Position) AddTrade(t types.Trade) (profit fixedpoint.Value, netProfit fixedpoint.Value, madeProfit bool) {
func (p *Position) AddTrade(t Trade) (profit fixedpoint.Value, netProfit fixedpoint.Value, madeProfit bool) {
price := fixedpoint.NewFromFloat(t.Price)
quantity := fixedpoint.NewFromFloat(t.Quantity)
quoteQuantity := fixedpoint.NewFromFloat(t.QuoteQuantity)
Expand Down Expand Up @@ -189,7 +204,7 @@ func (p *Position) AddTrade(t types.Trade) (profit fixedpoint.Value, netProfit f
// Base < 0 means we're in short position
switch t.Side {

case types.SideTypeBuy:
case SideTypeBuy:
if p.Base < 0 {
// convert short position to long position
if p.Base+quantity > 0 {
Expand Down Expand Up @@ -217,7 +232,7 @@ func (p *Position) AddTrade(t types.Trade) (profit fixedpoint.Value, netProfit f

return 0, 0, false

case types.SideTypeSell:
case SideTypeSell:
if p.Base > 0 {
// convert long position to short position
if p.Base-quantity < 0 {
Expand Down
Loading