2020-08-03 05:17:17 +00:00
package service
import (
"github.com/jmoiron/sqlx"
2020-08-03 07:25:06 +00:00
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
2020-09-05 08:22:46 +00:00
2020-10-11 08:46:15 +00:00
"github.com/c9s/bbgo/pkg/types"
2020-08-03 05:17:17 +00:00
)
type TradeService struct {
2020-08-03 07:25:06 +00:00
DB * sqlx . DB
2020-08-03 05:17:17 +00:00
}
2020-08-03 07:25:06 +00:00
func NewTradeService ( db * sqlx . DB ) * TradeService {
2020-08-03 05:17:17 +00:00
return & TradeService { db }
}
// QueryLast queries the last trade from the database
2020-11-05 03:00:51 +00:00
func ( s * TradeService ) QueryLast ( ex types . ExchangeName , symbol string ) ( * types . Trade , error ) {
log . Infof ( "querying last trade exchange = %s AND symbol = %s" , ex , symbol )
2020-08-03 07:25:06 +00:00
2020-11-05 03:00:51 +00:00
rows , err := s . DB . NamedQuery ( ` SELECT * FROM trades WHERE exchange = :exchange AND symbol = :symbol ORDER BY gid DESC LIMIT 1 ` , map [ string ] interface { } {
"symbol" : symbol ,
"exchange" : ex ,
2020-08-03 05:17:17 +00:00
} )
if err != nil {
2020-08-03 07:25:06 +00:00
return nil , errors . Wrap ( err , "query last trade error" )
}
if rows . Err ( ) != nil {
return nil , rows . Err ( )
2020-08-03 05:17:17 +00:00
}
defer rows . Close ( )
2020-08-03 07:25:06 +00:00
if rows . Next ( ) {
var trade types . Trade
err = rows . StructScan ( & trade )
return & trade , err
}
2020-08-03 05:17:17 +00:00
2020-08-03 07:25:06 +00:00
return nil , rows . Err ( )
2020-08-03 05:17:17 +00:00
}
2020-11-05 03:00:51 +00:00
func ( s * TradeService ) QueryForTradingFeeCurrency ( ex types . ExchangeName , symbol string , feeCurrency string ) ( [ ] types . Trade , error ) {
rows , err := s . DB . NamedQuery ( ` SELECT * FROM trades WHERE exchange = :exchange AND (symbol = :symbol OR fee_currency = :fee_currency) ORDER BY traded_at ASC ` , map [ string ] interface { } {
"exchange" : ex ,
2020-10-09 05:21:42 +00:00
"symbol" : symbol ,
2020-08-04 01:47:54 +00:00
"fee_currency" : feeCurrency ,
2020-08-03 12:06:33 +00:00
} )
if err != nil {
return nil , err
}
defer rows . Close ( )
return s . scanRows ( rows )
}
2020-11-05 03:00:51 +00:00
func ( s * TradeService ) Query ( ex types . ExchangeName , symbol string ) ( [ ] types . Trade , error ) {
rows , err := s . DB . NamedQuery ( ` SELECT * FROM trades WHERE exchange = :exchange AND symbol = :symbol ORDER BY gid ASC ` , map [ string ] interface { } {
"exchange" : ex ,
"symbol" : symbol ,
2020-08-03 05:17:17 +00:00
} )
if err != nil {
return nil , err
}
defer rows . Close ( )
2020-08-03 12:06:33 +00:00
return s . scanRows ( rows )
}
2020-10-09 05:21:42 +00:00
func ( s * TradeService ) scanRows ( rows * sqlx . Rows ) ( trades [ ] types . Trade , err error ) {
2020-08-03 05:17:17 +00:00
for rows . Next ( ) {
var trade types . Trade
if err := rows . StructScan ( & trade ) ; err != nil {
2020-11-05 03:00:51 +00:00
return trades , err
2020-08-03 05:17:17 +00:00
}
2020-08-03 07:25:06 +00:00
2020-08-03 05:17:17 +00:00
trades = append ( trades , trade )
}
2020-08-03 07:25:06 +00:00
return trades , rows . Err ( )
2020-08-03 05:17:17 +00:00
}
func ( s * TradeService ) Insert ( trade types . Trade ) error {
2020-08-03 07:25:06 +00:00
_ , err := s . DB . NamedExec ( `
2021-01-19 15:33:06 +00:00
INSERT IGNORE INTO trades ( id , exchange , order_id , symbol , price , quantity , quote_quantity , side , is_buyer , is_maker , fee , fee_currency , traded_at , is_margin , 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_isolated ) ` ,
2020-08-03 05:17:17 +00:00
trade )
return err
}