adjust quantity bases on the balances

This commit is contained in:
c9s 2021-05-15 09:46:07 +08:00
parent f9cb414832
commit 236df245a2
3 changed files with 55 additions and 5 deletions

View File

@ -14,6 +14,18 @@ var (
ErrAssetBalanceLevelTooHigh = errors.New("asset balance level too high") ErrAssetBalanceLevelTooHigh = errors.New("asset balance level too high")
) )
// AdjustQuantityByMaxAmount adjusts the quantity to make the amount greater than the given minAmount
func AdjustQuantityByMaxAmount(quantity, currentPrice, maxAmount fixedpoint.Value) fixedpoint.Value {
// modify quantity for the min amount
amount := currentPrice.Mul(quantity)
if amount > maxAmount {
ratio := maxAmount.Div(amount)
quantity = quantity.Mul(ratio)
}
return quantity
}
// AdjustQuantityByMinAmount adjusts the quantity to make the amount greater than the given minAmount // AdjustQuantityByMinAmount adjusts the quantity to make the amount greater than the given minAmount
func AdjustQuantityByMinAmount(quantity, currentPrice, minAmount fixedpoint.Value) fixedpoint.Value { func AdjustQuantityByMinAmount(quantity, currentPrice, minAmount fixedpoint.Value) fixedpoint.Value {
// modify quantity for the min amount // modify quantity for the min amount

View File

@ -22,6 +22,7 @@ type TwapExecution struct {
StopPrice fixedpoint.Value StopPrice fixedpoint.Value
NumOfTicks int NumOfTicks int
UpdateInterval time.Duration UpdateInterval time.Duration
DeadlineTime time.Time
market types.Market market types.Market
marketDataStream types.Stream marketDataStream types.Stream
@ -79,7 +80,7 @@ func (e *TwapExecution) getSideBook() (pvs types.PriceVolumeSlice, err error) {
return pvs, err return pvs, err
} }
func (e *TwapExecution) newBestPriceMakerOrder() (orderForm types.SubmitOrder, err error) { func (e *TwapExecution) newBestPriceOrder() (orderForm types.SubmitOrder, err error) {
book := e.orderBook.Get() book := e.orderBook.Get()
sideBook, err := e.getSideBook() sideBook, err := e.getSideBook()
@ -166,9 +167,34 @@ func (e *TwapExecution) newBestPriceMakerOrder() (orderForm types.SubmitOrder, e
} }
minNotional := fixedpoint.NewFromFloat(e.market.MinNotional) minNotional := fixedpoint.NewFromFloat(e.market.MinNotional)
orderAmount := newPrice.Mul(orderQuantity) orderQuantity = AdjustQuantityByMinAmount(orderQuantity, newPrice, minNotional)
if orderAmount <= minNotional {
orderQuantity = AdjustQuantityByMinAmount(orderQuantity, newPrice, minNotional) switch e.Side {
case types.SideTypeSell:
// check base balance for sell, try to sell as more as possible
if b, ok := e.Session.Account.Balance(e.market.BaseCurrency); ok {
orderQuantity = fixedpoint.Min(b.Available, orderQuantity)
}
case types.SideTypeBuy:
// check base balance for sell, try to sell as more as possible
if b, ok := e.Session.Account.Balance(e.market.QuoteCurrency); ok {
orderQuantity = AdjustQuantityByMaxAmount(orderQuantity, newPrice, b.Available)
}
}
if e.DeadlineTime != emptyTime {
now := time.Now()
if now.After(e.DeadlineTime) {
orderForm = types.SubmitOrder{
Symbol: e.Symbol,
Side: e.Side,
Type: types.OrderTypeMarket,
Quantity: restQuantity.Float64(),
Market: e.market,
}
return orderForm, nil
}
} }
orderForm = types.SubmitOrder{ orderForm = types.SubmitOrder{
@ -264,7 +290,7 @@ func (e *TwapExecution) updateOrder(ctx context.Context) error {
e.cancelActiveOrders(ctx) e.cancelActiveOrders(ctx)
} }
orderForm, err := e.newBestPriceMakerOrder() orderForm, err := e.newBestPriceOrder()
if err != nil { if err != nil {
return err return err
} }

View File

@ -187,6 +187,16 @@ var executeOrderCmd = &cobra.Command{
return err return err
} }
deadlineDuration, err := cmd.Flags().GetDuration("deadline")
if err != nil {
return err
}
var deadlineTime time.Time
if deadlineDuration > 0 {
deadlineTime = time.Now().Add(deadlineDuration)
}
environ := bbgo.NewEnvironment() environ := bbgo.NewEnvironment()
if err := environ.ConfigureExchangeSessions(userConfig); err != nil { if err := environ.ConfigureExchangeSessions(userConfig); err != nil {
return err return err
@ -213,6 +223,7 @@ var executeOrderCmd = &cobra.Command{
StopPrice: stopPrice, StopPrice: stopPrice,
NumOfTicks: numOfPriceTicks, NumOfTicks: numOfPriceTicks,
UpdateInterval: updateInterval, UpdateInterval: updateInterval,
DeadlineTime: deadlineTime,
} }
if err := execution.Run(executionCtx); err != nil { if err := execution.Run(executionCtx); err != nil {
@ -334,6 +345,7 @@ func init() {
executeOrderCmd.Flags().String("slice-quantity", "", "slice quantity") executeOrderCmd.Flags().String("slice-quantity", "", "slice quantity")
executeOrderCmd.Flags().String("stop-price", "0", "stop price") executeOrderCmd.Flags().String("stop-price", "0", "stop price")
executeOrderCmd.Flags().Duration("update-interval", time.Second*10, "order update time") executeOrderCmd.Flags().Duration("update-interval", time.Second*10, "order update time")
executeOrderCmd.Flags().Duration("deadline", 0, "deadline of the order execution")
executeOrderCmd.Flags().Int("price-ticks", 0, "the number of price tick for the jump spread, default to 0") executeOrderCmd.Flags().Int("price-ticks", 0, "the number of price tick for the jump spread, default to 0")
RootCmd.AddCommand(listOrdersCmd) RootCmd.AddCommand(listOrdersCmd)