mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
xfunding: improve transfer logics
This commit is contained in:
parent
4242f052d8
commit
4a4f91e7f9
|
@ -43,61 +43,66 @@ func (s *Strategy) resetTransfer(ctx context.Context, ex FuturesTransfer, asset
|
|||
|
||||
func (s *Strategy) transferOut(ctx context.Context, ex FuturesTransfer, asset string, quantity fixedpoint.Value) error {
|
||||
// if transfer done
|
||||
// TotalBaseTransfer here is the rest quantity we need to transfer
|
||||
// (total spot -> futures transfer amount) is recorded in this variable.
|
||||
//
|
||||
// TotalBaseTransfer == 0 means we have nothing to transfer.
|
||||
if s.State.TotalBaseTransfer.IsZero() {
|
||||
return nil
|
||||
}
|
||||
|
||||
balances, err := s.futuresSession.Exchange.QueryAccountBalances(ctx)
|
||||
quantity = quantity.Add(s.State.PendingBaseTransfer)
|
||||
|
||||
// a simple protection here -- we can only transfer the rest quota (total base transfer) back to spot
|
||||
quantity = fixedpoint.Min(s.State.TotalBaseTransfer, quantity)
|
||||
|
||||
available, pending, err := s.queryAvailableTransfer(ctx, s.futuresSession.Exchange, asset, quantity)
|
||||
if err != nil {
|
||||
log.Infof("balance query error, adding to pending base transfer: %s %s + %s", quantity.String(), asset, s.State.PendingBaseTransfer.String())
|
||||
s.State.PendingBaseTransfer = s.State.PendingBaseTransfer.Add(quantity)
|
||||
s.State.PendingBaseTransfer = quantity
|
||||
return err
|
||||
}
|
||||
|
||||
b, ok := balances[asset]
|
||||
if !ok {
|
||||
log.Infof("balance not found, adding to pending base transfer: %s %s + %s", quantity.String(), asset, s.State.PendingBaseTransfer.String())
|
||||
s.State.PendingBaseTransfer = s.State.PendingBaseTransfer.Add(quantity)
|
||||
return fmt.Errorf("%s balance not found", asset)
|
||||
}
|
||||
s.State.PendingBaseTransfer = pending
|
||||
|
||||
log.Infof("found futures balance: %+v", b)
|
||||
|
||||
// add the previous pending base transfer and the current trade quantity
|
||||
amount := b.MaxWithdrawAmount
|
||||
if !quantity.IsZero() {
|
||||
amount = s.State.PendingBaseTransfer.Add(quantity)
|
||||
}
|
||||
|
||||
// try to transfer more if we enough balance
|
||||
amount = fixedpoint.Min(amount, b.MaxWithdrawAmount)
|
||||
|
||||
// we can only transfer the rest quota (total base transfer)
|
||||
amount = fixedpoint.Min(s.State.TotalBaseTransfer, amount)
|
||||
|
||||
// TODO: according to the fee, we might not be able to get enough balance greater than the trade quantity, we can adjust the quantity here
|
||||
if amount.IsZero() {
|
||||
log.Infof("zero amount, adding to pending base transfer: %s %s + %s ", quantity.String(), asset, s.State.PendingBaseTransfer.String())
|
||||
s.State.PendingBaseTransfer = s.State.PendingBaseTransfer.Add(quantity)
|
||||
return nil
|
||||
}
|
||||
|
||||
// de-leverage and get the collateral base quantity
|
||||
collateralBase := s.FuturesPosition.GetBase().Abs().Div(s.Leverage)
|
||||
_ = collateralBase
|
||||
|
||||
// if s.State.TotalBaseTransfer.Compare(collateralBase)
|
||||
|
||||
log.Infof("transfering out futures account asset %s %s", amount, asset)
|
||||
if err := ex.TransferFuturesAccountAsset(ctx, asset, amount, types.TransferOut); err != nil {
|
||||
log.Infof("transfering out futures account asset %f %s", available.Float64(), asset)
|
||||
if err := ex.TransferFuturesAccountAsset(ctx, asset, available, types.TransferOut); err != nil {
|
||||
s.State.PendingBaseTransfer = s.State.PendingBaseTransfer.Add(available)
|
||||
return err
|
||||
}
|
||||
|
||||
// reset pending transfer
|
||||
s.State.PendingBaseTransfer = fixedpoint.Zero
|
||||
|
||||
// reduce the transfer in the total base transfer
|
||||
s.State.TotalBaseTransfer = s.State.TotalBaseTransfer.Sub(amount)
|
||||
s.State.TotalBaseTransfer = s.State.TotalBaseTransfer.Sub(available)
|
||||
return nil
|
||||
}
|
||||
|
||||
// transferIn transfers the asset from the spot account to the futures account
|
||||
func (s *Strategy) transferIn(ctx context.Context, ex FuturesTransfer, asset string, quantity fixedpoint.Value) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
// add the pending transfer and reset the pending transfer
|
||||
quantity = s.State.PendingBaseTransfer.Add(quantity)
|
||||
|
||||
available, pending, err := s.queryAvailableTransfer(ctx, s.spotSession.Exchange, asset, quantity)
|
||||
if err != nil {
|
||||
s.State.PendingBaseTransfer = quantity
|
||||
return err
|
||||
}
|
||||
|
||||
s.State.PendingBaseTransfer = pending
|
||||
|
||||
if available.IsZero() {
|
||||
return fmt.Errorf("unable to transfer zero %s from spot wallet to futures wallet", asset)
|
||||
}
|
||||
|
||||
log.Infof("transfering %f %s from the spot wallet into futures wallet...", available.Float64(), asset)
|
||||
if err := ex.TransferFuturesAccountAsset(ctx, asset, available, types.TransferIn); err != nil {
|
||||
s.State.PendingBaseTransfer = s.State.PendingBaseTransfer.Add(available)
|
||||
return err
|
||||
}
|
||||
|
||||
// record the transfer in the total base transfer
|
||||
s.State.TotalBaseTransfer = s.State.TotalBaseTransfer.Add(available)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -118,18 +123,25 @@ func (s *Strategy) queryAvailableTransfer(
|
|||
return available, pending, fmt.Errorf("%s balance not found", asset)
|
||||
}
|
||||
|
||||
log.Infof("loaded %s balance: %+v", asset, b)
|
||||
|
||||
// if quantity = 0, we will transfer all available balance into the futures wallet
|
||||
if quantity.IsZero() {
|
||||
quantity = b.Available
|
||||
}
|
||||
|
||||
if b.Available.Compare(quantity) < 0 {
|
||||
limit := b.Available
|
||||
if b.MaxWithdrawAmount.Sign() > 0 {
|
||||
limit = fixedpoint.Min(b.MaxWithdrawAmount, limit)
|
||||
}
|
||||
|
||||
if limit.Compare(quantity) < 0 {
|
||||
log.Infof("%s available balance is not enough for transfer (%f < %f)",
|
||||
asset,
|
||||
b.Available.Float64(),
|
||||
quantity.Float64())
|
||||
|
||||
available = fixedpoint.Min(b.Available, quantity)
|
||||
available = fixedpoint.Min(limit, quantity)
|
||||
pending = quantity.Sub(available)
|
||||
log.Infof("adjusted transfer quantity from %f to %f", quantity.Float64(), available.Float64())
|
||||
return available, pending, nil
|
||||
|
@ -139,33 +151,3 @@ func (s *Strategy) queryAvailableTransfer(
|
|||
pending = fixedpoint.Zero
|
||||
return available, pending, nil
|
||||
}
|
||||
|
||||
// transferIn transfers the asset from the spot account to the futures account
|
||||
func (s *Strategy) transferIn(ctx context.Context, ex FuturesTransfer, asset string, quantity fixedpoint.Value) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
// add the pending transfer and reset the pending transfer
|
||||
quantity = s.State.PendingBaseTransfer.Add(quantity)
|
||||
|
||||
available, pending, err := s.queryAvailableTransfer(ctx, s.spotSession.Exchange, asset, quantity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.State.PendingBaseTransfer = pending
|
||||
|
||||
if available.IsZero() {
|
||||
return fmt.Errorf("unable to transfer zero %s from spot wallet to futures wallet", asset)
|
||||
}
|
||||
|
||||
log.Infof("transfering %f %s from the spot wallet into futures wallet...", available.Float64(), asset)
|
||||
if err := ex.TransferFuturesAccountAsset(ctx, asset, available, types.TransferIn); err != nil {
|
||||
s.State.PendingBaseTransfer = s.State.PendingBaseTransfer.Add(available)
|
||||
return err
|
||||
}
|
||||
|
||||
// record the transfer in the total base transfer
|
||||
s.State.TotalBaseTransfer = s.State.TotalBaseTransfer.Add(available)
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user