mirror of
https://github.com/laoxong/nofx.git
synced 2026-06-07 03:07:56 +08:00
fix(sync): add updated_at to position updates and auto-close when quantity=0
- UpdatePositionQuantityAndPrice: add updated_at timestamp - ReducePositionQuantity: add updated_at and auto-close position when qty <= 0.0001 - UpdatePositionExchangeInfo: add updated_at timestamp Fixes position sync issue after int64 timestamp migration where GORM autoUpdateTime tag no longer works with int64 fields
This commit is contained in:
@@ -158,16 +158,19 @@ func (s *PositionStore) UpdatePositionQuantityAndPrice(id int64, addQty float64,
|
||||
newEntryPrice := (pos.EntryPrice*pos.Quantity + addPrice*addQty) / newQty
|
||||
newEntryPrice = math.Round(newEntryPrice*100) / 100
|
||||
newFee := pos.Fee + addFee
|
||||
nowMs := time.Now().UTC().UnixMilli()
|
||||
|
||||
return s.db.Model(&TraderPosition{}).Where("id = ?", id).Updates(map[string]interface{}{
|
||||
"quantity": newQty,
|
||||
"entry_quantity": newEntryQty,
|
||||
"entry_price": newEntryPrice,
|
||||
"fee": newFee,
|
||||
"updated_at": nowMs,
|
||||
}).Error
|
||||
}
|
||||
|
||||
// ReducePositionQuantity reduces position quantity for partial close
|
||||
// If quantity reaches 0 (or near 0), automatically closes the position
|
||||
func (s *PositionStore) ReducePositionQuantity(id int64, reduceQty float64, exitPrice float64, addFee float64, addPnL float64) error {
|
||||
var pos TraderPosition
|
||||
if err := s.db.First(&pos, id).Error; err != nil {
|
||||
@@ -187,19 +190,40 @@ func (s *PositionStore) ReducePositionQuantity(id int64, reduceQty float64, exit
|
||||
newExitPrice = math.Round(newExitPrice*100) / 100
|
||||
}
|
||||
|
||||
nowMs := time.Now().UTC().UnixMilli()
|
||||
|
||||
// Check if position should be fully closed (quantity reduced to ~0)
|
||||
const QUANTITY_TOLERANCE = 0.0001
|
||||
if newQty <= QUANTITY_TOLERANCE {
|
||||
// Auto-close: set status to CLOSED
|
||||
return s.db.Model(&TraderPosition{}).Where("id = ?", id).Updates(map[string]interface{}{
|
||||
"quantity": 0,
|
||||
"fee": newFee,
|
||||
"exit_price": newExitPrice,
|
||||
"realized_pnl": newPnL,
|
||||
"status": "CLOSED",
|
||||
"exit_time": nowMs,
|
||||
"close_reason": "sync",
|
||||
"updated_at": nowMs,
|
||||
}).Error
|
||||
}
|
||||
|
||||
return s.db.Model(&TraderPosition{}).Where("id = ?", id).Updates(map[string]interface{}{
|
||||
"quantity": newQty,
|
||||
"fee": newFee,
|
||||
"exit_price": newExitPrice,
|
||||
"realized_pnl": newPnL,
|
||||
"updated_at": nowMs,
|
||||
}).Error
|
||||
}
|
||||
|
||||
// UpdatePositionExchangeInfo updates exchange_id and exchange_type
|
||||
func (s *PositionStore) UpdatePositionExchangeInfo(id int64, exchangeID, exchangeType string) error {
|
||||
nowMs := time.Now().UTC().UnixMilli()
|
||||
return s.db.Model(&TraderPosition{}).Where("id = ?", id).Updates(map[string]interface{}{
|
||||
"exchange_id": exchangeID,
|
||||
"exchange_type": exchangeType,
|
||||
"updated_at": nowMs,
|
||||
}).Error
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user