From 09dea3938d065ce7fa6c986c2b46bebc7accd640 Mon Sep 17 00:00:00 2001 From: c9s Date: Fri, 4 Mar 2022 19:24:40 +0800 Subject: [PATCH] implement profit insert --- .../mysql/20220304153317_add_profit_table.sql | 53 +++++++++------- .../20220304153309_add_profit_table.sql | 51 +++++++++------- pkg/service/profit.go | 61 ++++++++++++++++--- pkg/types/profit.go | 10 ++- 4 files changed, 117 insertions(+), 58 deletions(-) diff --git a/migrations/mysql/20220304153317_add_profit_table.sql b/migrations/mysql/20220304153317_add_profit_table.sql index 5db882b66..f74a21304 100644 --- a/migrations/mysql/20220304153317_add_profit_table.sql +++ b/migrations/mysql/20220304153317_add_profit_table.sql @@ -1,60 +1,67 @@ -- +up CREATE TABLE `profits` ( - `gid` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + `gid` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, - `symbol` VARCHAR(8) NOT NULL, + `strategy` VARCHAR(32) NOT NULL, + `strategy_instance_id` VARCHAR(64) NOT NULL, + + `symbol` VARCHAR(8) NOT NULL, -- average_cost is the position average cost - `average_cost` DECIMAL(16, 8) UNSIGNED NOT NULL, + `average_cost` DECIMAL(16, 8) UNSIGNED NOT NULL, -- profit is the pnl (profit and loss) - `profit` DECIMAL(16, 8) NOT NULL, + `profit` DECIMAL(16, 8) NOT NULL, -- net_profit is the pnl (profit and loss) - `net_profit` DECIMAL(16, 8) NOT NULL, + `net_profit` DECIMAL(16, 8) NOT NULL, -- profit_margin is the pnl (profit and loss) - `profit_margin` DECIMAL(16, 8) NOT NULL, + `profit_margin` DECIMAL(16, 8) NOT NULL, -- net_profit_margin is the pnl (profit and loss) - `net_profit_margin` DECIMAL(16, 8) NOT NULL, + `net_profit_margin` DECIMAL(16, 8) NOT NULL, - `quote_currency` VARCHAR(10) NOT NULL, + `quote_currency` VARCHAR(10) NOT NULL, - `base_currency` VARCHAR(10) NOT NULL, + `base_currency` VARCHAR(10) NOT NULL, -- ------------------------------------------------------- -- embedded trade data -- -- ------------------------------------------------------- - `exchange` VARCHAR(24) NOT NULL DEFAULT '', + `exchange` VARCHAR(24) NOT NULL DEFAULT '', - `is_futures` BOOLEAN NOT NULL DEFAULT FALSE, + `is_futures` BOOLEAN NOT NULL DEFAULT FALSE, - `is_margin` BOOLEAN NOT NULL DEFAULT FALSE, + `is_margin` BOOLEAN NOT NULL DEFAULT FALSE, - `is_isolated` BOOLEAN NOT NULL DEFAULT FALSE, + `is_isolated` BOOLEAN NOT NULL DEFAULT FALSE, - `trade_id` BIGINT UNSIGNED NOT NULL, + `trade_id` BIGINT UNSIGNED NOT NULL, -- side is the side of the trade that makes profit - `side` VARCHAR(4) NOT NULL DEFAULT '', + `side` VARCHAR(4) NOT NULL DEFAULT '', + + `is_buyer` BOOLEAN NOT NULL DEFAULT FALSE, + + `is_maker` BOOLEAN NOT NULL DEFAULT FALSE, -- price is the price of the trade that makes profit - `price` DECIMAL(16, 8) UNSIGNED NOT NULL, + `price` DECIMAL(16, 8) UNSIGNED NOT NULL, -- quantity is the quantity of the trade that makes profit - `quantity` DECIMAL(16, 8) UNSIGNED NOT NULL, + `quantity` DECIMAL(16, 8) UNSIGNED NOT NULL, - -- trade_amount is the quote quantity of the trade that makes profit - `trade_amount` DECIMAL(16, 8) UNSIGNED NOT NULL, + -- quote_quantity is the quote quantity of the trade that makes profit + `quote_quantity` DECIMAL(16, 8) UNSIGNED NOT NULL, - `traded_at` DATETIME(3) NOT NULL, + `traded_at` DATETIME(3) NOT NULL, -- fee - `fee_in_usd` DECIMAL(16, 8) UNSIGNED NOT NULL, - `fee` DECIMAL(16, 8) UNSIGNED NOT NULL, - `fee_currency` VARCHAR(10) NOT NULL, + `fee_in_usd` DECIMAL(16, 8) UNSIGNED, + `fee` DECIMAL(16, 8) UNSIGNED NOT NULL, + `fee_currency` VARCHAR(10) NOT NULL, PRIMARY KEY (`gid`), UNIQUE KEY `trade_id` (`trade_id`) diff --git a/migrations/sqlite3/20220304153309_add_profit_table.sql b/migrations/sqlite3/20220304153309_add_profit_table.sql index 8c2d99456..290d32539 100644 --- a/migrations/sqlite3/20220304153309_add_profit_table.sql +++ b/migrations/sqlite3/20220304153309_add_profit_table.sql @@ -1,60 +1,67 @@ -- +up CREATE TABLE `profits` ( - `gid` INTEGER PRIMARY KEY AUTOINCREMENT, + `gid` INTEGER PRIMARY KEY AUTOINCREMENT, - `symbol` VARCHAR(8) NOT NULL, + `strategy` VARCHAR(32) NOT NULL, + `strategy_instance_id` VARCHAR(64) NOT NULL, + + `symbol` VARCHAR(8) NOT NULL, -- average_cost is the position average cost - `average_cost` DECIMAL(16, 8) NOT NULL, + `average_cost` DECIMAL(16, 8) NOT NULL, -- profit is the pnl (profit and loss) - `profit` DECIMAL(16, 8) NOT NULL, + `profit` DECIMAL(16, 8) NOT NULL, -- net_profit is the pnl (profit and loss) - `net_profit` DECIMAL(16, 8) NOT NULL, + `net_profit` DECIMAL(16, 8) NOT NULL, -- profit_margin is the pnl (profit and loss) - `profit_margin` DECIMAL(16, 8) NOT NULL, + `profit_margin` DECIMAL(16, 8) NOT NULL, -- net_profit_margin is the pnl (profit and loss) - `net_profit_margin` DECIMAL(16, 8) NOT NULL, + `net_profit_margin` DECIMAL(16, 8) NOT NULL, - `quote_currency` VARCHAR(10) NOT NULL, + `quote_currency` VARCHAR(10) NOT NULL, - `base_currency` VARCHAR(10) NOT NULL, + `base_currency` VARCHAR(10) NOT NULL, -- ------------------------------------------------------- -- embedded trade data -- -- ------------------------------------------------------- - `exchange` VARCHAR(24) NOT NULL DEFAULT '', + `exchange` VARCHAR(24) NOT NULL DEFAULT '', - `is_futures` BOOLEAN NOT NULL DEFAULT FALSE, + `is_futures` BOOLEAN NOT NULL DEFAULT FALSE, - `is_margin` BOOLEAN NOT NULL DEFAULT FALSE, + `is_margin` BOOLEAN NOT NULL DEFAULT FALSE, - `is_isolated` BOOLEAN NOT NULL DEFAULT FALSE, + `is_isolated` BOOLEAN NOT NULL DEFAULT FALSE, - `trade_id` BIGINT NOT NULL, + `trade_id` BIGINT NOT NULL, -- side is the side of the trade that makes profit - `side` VARCHAR(4) NOT NULL DEFAULT '', + `side` VARCHAR(4) NOT NULL DEFAULT '', + + `is_buyer` BOOLEAN NOT NULL DEFAULT FALSE, + + `is_maker` BOOLEAN NOT NULL DEFAULT FALSE, -- price is the price of the trade that makes profit - `price` DECIMAL(16, 8) NOT NULL, + `price` DECIMAL(16, 8) NOT NULL, -- quantity is the quantity of the trade that makes profit - `quantity` DECIMAL(16, 8) NOT NULL, + `quantity` DECIMAL(16, 8) NOT NULL, -- trade_amount is the quote quantity of the trade that makes profit - `trade_amount` DECIMAL(16, 8) NOT NULL, + `quote_quantity` DECIMAL(16, 8) NOT NULL, - `traded_at` DATETIME(3) NOT NULL, + `traded_at` DATETIME(3) NOT NULL, -- fee - `fee_in_usd` DECIMAL(16, 8) NOT NULL, - `fee` DECIMAL(16, 8) NOT NULL, - `fee_currency` VARCHAR(10) NOT NULL + `fee_in_usd` DECIMAL(16, 8), + `fee` DECIMAL(16, 8) NOT NULL, + `fee_currency` VARCHAR(10) NOT NULL ); -- +down diff --git a/pkg/service/profit.go b/pkg/service/profit.go index 7920d3aca..4baf1029e 100644 --- a/pkg/service/profit.go +++ b/pkg/service/profit.go @@ -37,23 +37,64 @@ func (s *ProfitService) Load(ctx context.Context, id int64) (*types.Trade, error return nil, errors.Wrapf(ErrTradeNotFound, "trade id:%d not found", id) } -func (s *ProfitService) scanRows(rows *sqlx.Rows) (trades []types.Trade, err error) { +func (s *ProfitService) scanRows(rows *sqlx.Rows) (profits []types.Profit, err error) { for rows.Next() { - var trade types.Trade - if err := rows.StructScan(&trade); err != nil { - return trades, err + var profit types.Profit + if err := rows.StructScan(&profit); err != nil { + return profits, err } - trades = append(trades, trade) + profits = append(profits, profit) } - return trades, rows.Err() + return profits, rows.Err() } -func (s *ProfitService) Insert(trade types.Trade) error { +func (s *ProfitService) Insert(profit types.Profit) error { _, err := s.DB.NamedExec(` - INSERT INTO profits (id, exchange, symbol, trade_id, average_cost, profit, price, quantity, quote_quantity, side, traded_at, is_margin, is_futures, is_isolated) - VALUES (:id, :exchange, :order_id, :symbol, :price, :quantity, :quote_quantity, :side, :is_buyer, :is_maker, :fee, :fee_currency, :traded_at, :is_margin, :is_futures, :is_isolated)`, - trade) + INSERT INTO profits ( + strategy, + strategy_instance_id, + symbol, + average_cost, + profit, + trade_id, + price, + quantity, + quote_quantity, + side, + is_buyer, + is_maker, + fee, + fee_currency, + fee_in_usd, + traded_at, + exchange, + is_margin, + is_futures, + is_isolated + ) VALUES ( + :strategy, + :strategy_instance_id, + :symbol, + :average_cost, + :profit, + :trade_id, + :price, + :quantity, + :quote_quantity, + :side, + :is_buyer, + :is_maker, + :fee, + :fee_currency, + :fee_in_usd, + :traded_at, + :exchange, + :is_margin, + :is_futures, + :is_isolated + )`, + profit) return err } diff --git a/pkg/types/profit.go b/pkg/types/profit.go index 90d06134d..1f54019c0 100644 --- a/pkg/types/profit.go +++ b/pkg/types/profit.go @@ -20,8 +20,7 @@ type Profit struct { // NetProfit is (profit - trading fee) NetProfit fixedpoint.Value `json:"netProfit" db:"net_profit"` AverageCost fixedpoint.Value `json:"averageCost" db:"average_ost"` - - TradeAmount fixedpoint.Value `json:"tradeAmount" db:"trade_amount"` + TradeAmount fixedpoint.Value `json:"tradeAmount" db:"quote_quantity"` // ProfitMargin is a percentage of the profit and the capital amount ProfitMargin fixedpoint.Value `json:"profitMargin" db:"profit_margin"` @@ -32,10 +31,15 @@ type Profit struct { QuoteCurrency string `json:"quoteCurrency" db:"quote_currency"` BaseCurrency string `json:"baseCurrency" db:"base_currency"` + IsBuyer bool `json:"isBuyer" db:"is_buyer"` + IsMaker bool `json:"isMaker" db:"is_maker"` + // FeeInUSD is the summed fee of this profit, // you will need to convert the trade fee into USD since the fee currencies can be different. FeeInUSD fixedpoint.Value `json:"feeInUSD" db:"fee_in_usd"` - Time time.Time `json:"time" db:"time"` + Fee fixedpoint.Value `json:"fee" db:"fee"` + FeeCurrency string `json:"feeCurrency" db:"fee_currency"` + Time time.Time `json:"tradedAt" db:"traded_at"` Strategy string `json:"strategy" db:"strategy"` StrategyInstanceID string `json:"strategyInstanceID" db:"strategy_instance_id"` }