qbtrade/pkg/service/margin.go
2024-06-27 22:42:38 +08:00

148 lines
4.0 KiB
Go

package service
import (
"context"
"strconv"
"time"
sq "github.com/Masterminds/squirrel"
"github.com/jmoiron/sqlx"
"git.qtrade.icu/lychiyu/qbtrade/pkg/exchange/batch"
"git.qtrade.icu/lychiyu/qbtrade/pkg/types"
)
type MarginService struct {
DB *sqlx.DB
}
func (s *MarginService) Sync(ctx context.Context, ex types.Exchange, asset string, startTime time.Time) error {
api, ok := ex.(types.MarginHistoryService)
if !ok {
return nil
}
marginExchange, ok := ex.(types.MarginExchange)
if !ok {
return nil
}
marginSettings := marginExchange.GetMarginSettings()
if !marginSettings.IsMargin {
return nil
}
tasks := []SyncTask{
{
Select: SelectLastMarginLoans(ex.Name(), asset, 100),
Type: types.MarginLoan{},
BatchQuery: func(ctx context.Context, startTime, endTime time.Time) (interface{}, chan error) {
query := &batch.MarginLoanBatchQuery{
MarginHistoryService: api,
}
return query.Query(ctx, asset, startTime, endTime)
},
Time: func(obj interface{}) time.Time {
return obj.(types.MarginLoan).Time.Time()
},
ID: func(obj interface{}) string {
return strconv.FormatUint(obj.(types.MarginLoan).TransactionID, 10)
},
LogInsert: true,
},
{
Select: SelectLastMarginRepays(ex.Name(), asset, 100),
Type: types.MarginRepay{},
BatchQuery: func(ctx context.Context, startTime, endTime time.Time) (interface{}, chan error) {
query := &batch.MarginRepayBatchQuery{
MarginHistoryService: api,
}
return query.Query(ctx, asset, startTime, endTime)
},
Time: func(obj interface{}) time.Time {
return obj.(types.MarginRepay).Time.Time()
},
ID: func(obj interface{}) string {
return strconv.FormatUint(obj.(types.MarginRepay).TransactionID, 10)
},
LogInsert: true,
},
{
Select: SelectLastMarginInterests(ex.Name(), asset, 100),
Type: types.MarginInterest{},
BatchQuery: func(ctx context.Context, startTime, endTime time.Time) (interface{}, chan error) {
query := &batch.MarginInterestBatchQuery{
MarginHistoryService: api,
}
return query.Query(ctx, asset, startTime, endTime)
},
Time: func(obj interface{}) time.Time {
return obj.(types.MarginInterest).Time.Time()
},
ID: func(obj interface{}) string {
m := obj.(types.MarginInterest)
return m.Asset + m.IsolatedSymbol + strconv.FormatInt(m.Time.UnixMilli(), 10)
},
LogInsert: true,
},
{
Select: SelectLastMarginLiquidations(ex.Name(), 100),
Type: types.MarginLiquidation{},
BatchQuery: func(ctx context.Context, startTime, endTime time.Time) (interface{}, chan error) {
query := &batch.MarginLiquidationBatchQuery{
MarginHistoryService: api,
}
return query.Query(ctx, startTime, endTime)
},
Time: func(obj interface{}) time.Time {
return obj.(types.MarginLiquidation).UpdatedTime.Time()
},
ID: func(obj interface{}) string {
m := obj.(types.MarginLiquidation)
return strconv.FormatUint(m.OrderID, 10)
},
LogInsert: true,
},
}
for _, sel := range tasks {
if err := sel.execute(ctx, s.DB, startTime); err != nil {
return err
}
}
return nil
}
func SelectLastMarginLoans(ex types.ExchangeName, asset string, limit uint64) sq.SelectBuilder {
return sq.Select("*").
From("margin_loans").
Where(sq.Eq{"exchange": ex, "asset": asset}).
OrderBy("time DESC").
Limit(limit)
}
func SelectLastMarginRepays(ex types.ExchangeName, asset string, limit uint64) sq.SelectBuilder {
return sq.Select("*").
From("margin_repays").
Where(sq.Eq{"exchange": ex, "asset": asset}).
OrderBy("time DESC").
Limit(limit)
}
func SelectLastMarginInterests(ex types.ExchangeName, asset string, limit uint64) sq.SelectBuilder {
return sq.Select("*").
From("margin_interests").
Where(sq.Eq{"exchange": ex, "asset": asset}).
OrderBy("time DESC").
Limit(limit)
}
func SelectLastMarginLiquidations(ex types.ExchangeName, limit uint64) sq.SelectBuilder {
return sq.Select("*").
From("margin_liquidations").
Where(sq.Eq{"exchange": ex}).
OrderBy("time DESC").
Limit(limit)
}