mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
add position table and service
This commit is contained in:
parent
f0d500bbaa
commit
ac675d0099
|
@ -6,7 +6,7 @@ CREATE TABLE `positions`
|
|||
`strategy` VARCHAR(32) NOT NULL,
|
||||
`strategy_instance_id` VARCHAR(64) NOT NULL,
|
||||
|
||||
`symbol` VARCHAR(20) NOT NULL,
|
||||
`symbol` VARCHAR(20) NOT NULL,
|
||||
`quote_currency` VARCHAR(10) NOT NULL,
|
||||
`base_currency` VARCHAR(10) NOT NULL,
|
||||
|
||||
|
@ -14,6 +14,7 @@ CREATE TABLE `positions`
|
|||
`average_cost` DECIMAL(16, 8) UNSIGNED NOT NULL,
|
||||
`base` DECIMAL(16, 8) NOT NULL,
|
||||
`quote` DECIMAL(16, 8) NOT NULL,
|
||||
`profit` DECIMAL(16, 8) NULL,
|
||||
|
||||
`trade_id` BIGINT UNSIGNED NOT NULL,
|
||||
`traded_at` DATETIME(3) NOT NULL,
|
||||
|
|
|
@ -3,20 +3,21 @@ CREATE TABLE `positions`
|
|||
(
|
||||
`gid` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
|
||||
`strategy` VARCHAR(32) NOT NULL,
|
||||
`strategy_instance_id` VARCHAR(64) NOT NULL,
|
||||
`strategy` VARCHAR(32) NOT NULL,
|
||||
`strategy_instance_id` VARCHAR(64) NOT NULL,
|
||||
|
||||
`symbol` VARCHAR(20) NOT NULL,
|
||||
`quote_currency` VARCHAR(10) NOT NULL,
|
||||
`base_currency` VARCHAR(10) NOT NULL,
|
||||
`symbol` VARCHAR(20) NOT NULL,
|
||||
`quote_currency` VARCHAR(10) NOT NULL,
|
||||
`base_currency` VARCHAR(10) NOT NULL,
|
||||
|
||||
-- average_cost is the position average cost
|
||||
`average_cost` DECIMAL(16, 8) NOT NULL,
|
||||
`base` DECIMAL(16, 8) NOT NULL,
|
||||
`quote` DECIMAL(16, 8) NOT NULL,
|
||||
`average_cost` DECIMAL(16, 8) NOT NULL,
|
||||
`base` DECIMAL(16, 8) NOT NULL,
|
||||
`quote` DECIMAL(16, 8) NOT NULL,
|
||||
`profit` DECIMAL(16, 8) NULL,
|
||||
|
||||
`trade_id` BIGINT NOT NULL,
|
||||
`traded_at` DATETIME(3) NOT NULL
|
||||
`trade_id` BIGINT NOT NULL,
|
||||
`traded_at` DATETIME(3) NOT NULL
|
||||
);
|
||||
|
||||
-- +down
|
||||
|
|
92
pkg/service/position.go
Normal file
92
pkg/service/position.go
Normal file
|
@ -0,0 +1,92 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
type PositionService struct {
|
||||
DB *sqlx.DB
|
||||
}
|
||||
|
||||
func NewPositionService(db *sqlx.DB) *PositionService {
|
||||
return &PositionService{db}
|
||||
}
|
||||
|
||||
func (s *PositionService) Load(ctx context.Context, id int64) (*types.Position, error) {
|
||||
var pos types.Position
|
||||
|
||||
rows, err := s.DB.NamedQuery("SELECT * FROM positions WHERE id = :id", map[string]interface{}{
|
||||
"id": id,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
if rows.Next() {
|
||||
err = rows.StructScan(&pos)
|
||||
return &pos, err
|
||||
}
|
||||
|
||||
return nil, errors.Wrapf(ErrTradeNotFound, "position id:%d not found", id)
|
||||
}
|
||||
|
||||
func (s *PositionService) scanRows(rows *sqlx.Rows) (positions []types.Position, err error) {
|
||||
for rows.Next() {
|
||||
var p types.Position
|
||||
if err := rows.StructScan(&p); err != nil {
|
||||
return positions, err
|
||||
}
|
||||
|
||||
positions = append(positions, p)
|
||||
}
|
||||
|
||||
return positions, rows.Err()
|
||||
}
|
||||
|
||||
func (s *PositionService) Insert(position *types.Position, trade types.Trade, profit fixedpoint.Value) error {
|
||||
_, err := s.DB.NamedExec(`
|
||||
INSERT INTO positions (
|
||||
strategy,
|
||||
strategy_instance_id,
|
||||
symbol,
|
||||
quote_currency,
|
||||
base_currency,
|
||||
average_cost,
|
||||
base,
|
||||
quote,
|
||||
profit,
|
||||
trade_id,
|
||||
traded_at
|
||||
) VALUES (
|
||||
:strategy,
|
||||
:strategy_instance_id,
|
||||
:symbol,
|
||||
:quote_currency,
|
||||
:base_currency,
|
||||
:average_cost,
|
||||
:base,
|
||||
:quote,
|
||||
:profit,
|
||||
:trade_id,
|
||||
:traded_at
|
||||
)`,
|
||||
map[string]interface{} {
|
||||
"strategy": "",
|
||||
"strategy_instance_id": "",
|
||||
"symbol": position.Symbol,
|
||||
"quote_currency": position.QuoteCurrency,
|
||||
"base_currency": position.BaseCurrency,
|
||||
"average_cost": position.AverageCost,
|
||||
"base": position.Base,
|
||||
"quote": position.Quote,
|
||||
})
|
||||
return err
|
||||
}
|
34
pkg/service/position_test.go
Normal file
34
pkg/service/position_test.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
func TestPositionService(t *testing.T) {
|
||||
db, err := prepareDB(t)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
defer db.Close()
|
||||
|
||||
xdb := sqlx.NewDb(db.DB, "sqlite3")
|
||||
service := &PositionService{DB: xdb}
|
||||
|
||||
err = service.Insert(&types.Position{
|
||||
Symbol: "BTCUSDT",
|
||||
BaseCurrency: "BTC",
|
||||
QuoteCurrency: "USDT",
|
||||
AverageCost: fixedpoint.NewFromFloat(44000),
|
||||
ChangedAt: time.Now(),
|
||||
}, types.Trade{}, fixedpoint.NewFromFloat(10.9))
|
||||
assert.NoError(t, err)
|
||||
|
||||
}
|
|
@ -50,6 +50,8 @@ type Position struct {
|
|||
// TotalFee stores the fee currency -> total fee quantity
|
||||
TotalFee map[string]fixedpoint.Value `json:"totalFee"`
|
||||
|
||||
ChangedAt time.Time `json:"changedAt,omitempty"`
|
||||
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
|
@ -66,22 +68,22 @@ func (p *Position) NewProfit(trade Trade, profit, netProfit fixedpoint.Value) Pr
|
|||
ProfitMargin: profit.Div(trade.QuoteQuantity),
|
||||
NetProfitMargin: netProfit.Div(trade.QuoteQuantity),
|
||||
// trade related fields
|
||||
TradeID: trade.ID,
|
||||
Side: trade.Side,
|
||||
IsBuyer: trade.IsBuyer,
|
||||
IsMaker: trade.IsMaker,
|
||||
Price: trade.Price,
|
||||
Quantity: trade.Quantity,
|
||||
QuoteQuantity: trade.QuoteQuantity,
|
||||
TradeID: trade.ID,
|
||||
Side: trade.Side,
|
||||
IsBuyer: trade.IsBuyer,
|
||||
IsMaker: trade.IsMaker,
|
||||
Price: trade.Price,
|
||||
Quantity: trade.Quantity,
|
||||
QuoteQuantity: trade.QuoteQuantity,
|
||||
// FeeInUSD: 0,
|
||||
Fee: trade.Fee,
|
||||
FeeCurrency: trade.FeeCurrency,
|
||||
Fee: trade.Fee,
|
||||
FeeCurrency: trade.FeeCurrency,
|
||||
|
||||
Exchange: trade.Exchange,
|
||||
IsMargin: trade.IsMargin,
|
||||
IsFutures: trade.IsFutures,
|
||||
IsIsolated: trade.IsIsolated,
|
||||
TradedAt: trade.Time.Time(),
|
||||
Exchange: trade.Exchange,
|
||||
IsMargin: trade.IsMargin,
|
||||
IsFutures: trade.IsFutures,
|
||||
IsIsolated: trade.IsIsolated,
|
||||
TradedAt: trade.Time.Time(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user