mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 17:13:51 +00:00
Merge pull request #348 from austin362667/refactor-position
types: refactor Position and related files
This commit is contained in:
commit
8fba55707c
|
@ -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"
|
||||
)
|
||||
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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{
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -17,11 +17,11 @@ func (c *TradeCollector) EmitTrade(trade types.Trade) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *TradeCollector) OnPositionUpdate(cb func(position *Position)) {
|
||||
func (c *TradeCollector) OnPositionUpdate(cb func(position *types.Position)) {
|
||||
c.positionUpdateCallbacks = append(c.positionUpdateCallbacks, cb)
|
||||
}
|
||||
|
||||
func (c *TradeCollector) EmitPositionUpdate(position *Position) {
|
||||
func (c *TradeCollector) EmitPositionUpdate(position *types.Position) {
|
||||
for _, cb := range c.positionUpdateCallbacks {
|
||||
cb(position)
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ type TwapExecution struct {
|
|||
|
||||
activeMakerOrders *LocalActiveOrderBook
|
||||
orderStore *OrderStore
|
||||
position *Position
|
||||
position *types.Position
|
||||
|
||||
executionCtx context.Context
|
||||
cancelExecution context.CancelFunc
|
||||
|
@ -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,
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -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"`
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
|
|
@ -27,7 +27,7 @@ func init() {
|
|||
}
|
||||
|
||||
type State struct {
|
||||
Position *bbgo.Position `json:"position,omitempty"`
|
||||
Position *types.Position `json:"position,omitempty"`
|
||||
}
|
||||
|
||||
type Target struct {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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",
|
||||
})
|
||||
|
@ -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
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package bbgo
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
@ -6,7 +6,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
"github.com/c9s/bbgo/pkg/util"
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
@ -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"`
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
|
@ -1,4 +1,4 @@
|
|||
package bbgo
|
||||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
@ -6,7 +6,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
func TestPosition_ExchangeFeeRate_Short(t *testing.T) {
|
||||
|
@ -17,7 +16,7 @@ func TestPosition_ExchangeFeeRate_Short(t *testing.T) {
|
|||
}
|
||||
|
||||
feeRate := 0.075 * 0.01
|
||||
pos.SetExchangeFeeRate(types.ExchangeBinance, ExchangeFee{
|
||||
pos.SetExchangeFeeRate(ExchangeBinance, ExchangeFee{
|
||||
MakerFeeRate: fixedpoint.NewFromFloat(feeRate),
|
||||
TakerFeeRate: fixedpoint.NewFromFloat(feeRate),
|
||||
})
|
||||
|
@ -27,24 +26,24 @@ func TestPosition_ExchangeFeeRate_Short(t *testing.T) {
|
|||
fee := quoteQuantity * feeRate
|
||||
averageCost := (quoteQuantity - fee) / quantity
|
||||
bnbPrice := 570.0
|
||||
pos.AddTrade(types.Trade{
|
||||
Exchange: types.ExchangeBinance,
|
||||
pos.AddTrade(Trade{
|
||||
Exchange: ExchangeBinance,
|
||||
Price: 3000.0,
|
||||
Quantity: quantity,
|
||||
QuoteQuantity: quoteQuantity,
|
||||
Symbol: "BTCUSDT",
|
||||
Side: types.SideTypeSell,
|
||||
Side: SideTypeSell,
|
||||
Fee: fee / bnbPrice,
|
||||
FeeCurrency: "BNB",
|
||||
})
|
||||
|
||||
_, netProfit, madeProfit := pos.AddTrade(types.Trade{
|
||||
Exchange: types.ExchangeBinance,
|
||||
_, netProfit, madeProfit := pos.AddTrade(Trade{
|
||||
Exchange: ExchangeBinance,
|
||||
Price: 2000.0,
|
||||
Quantity: 10.0,
|
||||
QuoteQuantity: 2000.0 * 10.0,
|
||||
Symbol: "BTCUSDT",
|
||||
Side: types.SideTypeBuy,
|
||||
Side: SideTypeBuy,
|
||||
Fee: 2000.0 * 10.0 * feeRate / bnbPrice,
|
||||
FeeCurrency: "BNB",
|
||||
})
|
||||
|
@ -62,7 +61,7 @@ func TestPosition_ExchangeFeeRate_Long(t *testing.T) {
|
|||
}
|
||||
|
||||
feeRate := 0.075 * 0.01
|
||||
pos.SetExchangeFeeRate(types.ExchangeBinance, ExchangeFee{
|
||||
pos.SetExchangeFeeRate(ExchangeBinance, ExchangeFee{
|
||||
MakerFeeRate: fixedpoint.NewFromFloat(feeRate),
|
||||
TakerFeeRate: fixedpoint.NewFromFloat(feeRate),
|
||||
})
|
||||
|
@ -72,24 +71,24 @@ func TestPosition_ExchangeFeeRate_Long(t *testing.T) {
|
|||
fee := quoteQuantity * feeRate
|
||||
averageCost := (quoteQuantity + fee) / quantity
|
||||
bnbPrice := 570.0
|
||||
pos.AddTrade(types.Trade{
|
||||
Exchange: types.ExchangeBinance,
|
||||
pos.AddTrade(Trade{
|
||||
Exchange: ExchangeBinance,
|
||||
Price: 3000.0,
|
||||
Quantity: quantity,
|
||||
QuoteQuantity: quoteQuantity,
|
||||
Symbol: "BTCUSDT",
|
||||
Side: types.SideTypeBuy,
|
||||
Side: SideTypeBuy,
|
||||
Fee: fee / bnbPrice,
|
||||
FeeCurrency: "BNB",
|
||||
})
|
||||
|
||||
_, netProfit, madeProfit := pos.AddTrade(types.Trade{
|
||||
Exchange: types.ExchangeBinance,
|
||||
_, netProfit, madeProfit := pos.AddTrade(Trade{
|
||||
Exchange: ExchangeBinance,
|
||||
Price: 4000.0,
|
||||
Quantity: 10.0,
|
||||
QuoteQuantity: 4000.0 * 10.0,
|
||||
Symbol: "BTCUSDT",
|
||||
Side: types.SideTypeSell,
|
||||
Side: SideTypeSell,
|
||||
Fee: 4000.0 * 10.0 * feeRate / bnbPrice,
|
||||
FeeCurrency: "BNB",
|
||||
})
|
||||
|
@ -103,7 +102,7 @@ func TestPosition(t *testing.T) {
|
|||
var feeRate = 0.05 * 0.01
|
||||
var testcases = []struct {
|
||||
name string
|
||||
trades []types.Trade
|
||||
trades []Trade
|
||||
expectedAverageCost fixedpoint.Value
|
||||
expectedBase fixedpoint.Value
|
||||
expectedQuote fixedpoint.Value
|
||||
|
@ -111,9 +110,9 @@ func TestPosition(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
name: "base fee",
|
||||
trades: []types.Trade{
|
||||
trades: []Trade{
|
||||
{
|
||||
Side: types.SideTypeBuy,
|
||||
Side: SideTypeBuy,
|
||||
Price: 1000.0,
|
||||
Quantity: 0.01,
|
||||
QuoteQuantity: 1000.0 * 0.01,
|
||||
|
@ -128,9 +127,9 @@ func TestPosition(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "quote fee",
|
||||
trades: []types.Trade{
|
||||
trades: []Trade{
|
||||
{
|
||||
Side: types.SideTypeSell,
|
||||
Side: SideTypeSell,
|
||||
Price: 1000.0,
|
||||
Quantity: 0.01,
|
||||
QuoteQuantity: 1000.0 * 0.01,
|
||||
|
@ -145,15 +144,15 @@ func TestPosition(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "long",
|
||||
trades: []types.Trade{
|
||||
trades: []Trade{
|
||||
{
|
||||
Side: types.SideTypeBuy,
|
||||
Side: SideTypeBuy,
|
||||
Price: 1000.0,
|
||||
Quantity: 0.01,
|
||||
QuoteQuantity: 1000.0 * 0.01,
|
||||
},
|
||||
{
|
||||
Side: types.SideTypeBuy,
|
||||
Side: SideTypeBuy,
|
||||
Price: 2000.0,
|
||||
Quantity: 0.03,
|
||||
QuoteQuantity: 2000.0 * 0.03,
|
||||
|
@ -167,21 +166,21 @@ func TestPosition(t *testing.T) {
|
|||
|
||||
{
|
||||
name: "long and sell",
|
||||
trades: []types.Trade{
|
||||
trades: []Trade{
|
||||
{
|
||||
Side: types.SideTypeBuy,
|
||||
Side: SideTypeBuy,
|
||||
Price: 1000.0,
|
||||
Quantity: 0.01,
|
||||
QuoteQuantity: 1000.0 * 0.01,
|
||||
},
|
||||
{
|
||||
Side: types.SideTypeBuy,
|
||||
Side: SideTypeBuy,
|
||||
Price: 2000.0,
|
||||
Quantity: 0.03,
|
||||
QuoteQuantity: 2000.0 * 0.03,
|
||||
},
|
||||
{
|
||||
Side: types.SideTypeSell,
|
||||
Side: SideTypeSell,
|
||||
Price: 3000.0,
|
||||
Quantity: 0.01,
|
||||
QuoteQuantity: 3000.0 * 0.01,
|
||||
|
@ -195,21 +194,21 @@ func TestPosition(t *testing.T) {
|
|||
|
||||
{
|
||||
name: "long and sell to short",
|
||||
trades: []types.Trade{
|
||||
trades: []Trade{
|
||||
{
|
||||
Side: types.SideTypeBuy,
|
||||
Side: SideTypeBuy,
|
||||
Price: 1000.0,
|
||||
Quantity: 0.01,
|
||||
QuoteQuantity: 1000.0 * 0.01,
|
||||
},
|
||||
{
|
||||
Side: types.SideTypeBuy,
|
||||
Side: SideTypeBuy,
|
||||
Price: 2000.0,
|
||||
Quantity: 0.03,
|
||||
QuoteQuantity: 2000.0 * 0.03,
|
||||
},
|
||||
{
|
||||
Side: types.SideTypeSell,
|
||||
Side: SideTypeSell,
|
||||
Price: 3000.0,
|
||||
Quantity: 0.10,
|
||||
QuoteQuantity: 3000.0 * 0.10,
|
||||
|
@ -224,15 +223,15 @@ func TestPosition(t *testing.T) {
|
|||
|
||||
{
|
||||
name: "short",
|
||||
trades: []types.Trade{
|
||||
trades: []Trade{
|
||||
{
|
||||
Side: types.SideTypeSell,
|
||||
Side: SideTypeSell,
|
||||
Price: 2000.0,
|
||||
Quantity: 0.01,
|
||||
QuoteQuantity: 2000.0 * 0.01,
|
||||
},
|
||||
{
|
||||
Side: types.SideTypeSell,
|
||||
Side: SideTypeSell,
|
||||
Price: 3000.0,
|
||||
Quantity: 0.03,
|
||||
QuoteQuantity: 3000.0 * 0.03,
|
Loading…
Reference in New Issue
Block a user