mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-12 23:36:55 +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 := (pos.EntryPrice*pos.Quantity + addPrice*addQty) / newQty
|
||||||
newEntryPrice = math.Round(newEntryPrice*100) / 100
|
newEntryPrice = math.Round(newEntryPrice*100) / 100
|
||||||
newFee := pos.Fee + addFee
|
newFee := pos.Fee + addFee
|
||||||
|
nowMs := time.Now().UTC().UnixMilli()
|
||||||
|
|
||||||
return s.db.Model(&TraderPosition{}).Where("id = ?", id).Updates(map[string]interface{}{
|
return s.db.Model(&TraderPosition{}).Where("id = ?", id).Updates(map[string]interface{}{
|
||||||
"quantity": newQty,
|
"quantity": newQty,
|
||||||
"entry_quantity": newEntryQty,
|
"entry_quantity": newEntryQty,
|
||||||
"entry_price": newEntryPrice,
|
"entry_price": newEntryPrice,
|
||||||
"fee": newFee,
|
"fee": newFee,
|
||||||
|
"updated_at": nowMs,
|
||||||
}).Error
|
}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReducePositionQuantity reduces position quantity for partial close
|
// 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 {
|
func (s *PositionStore) ReducePositionQuantity(id int64, reduceQty float64, exitPrice float64, addFee float64, addPnL float64) error {
|
||||||
var pos TraderPosition
|
var pos TraderPosition
|
||||||
if err := s.db.First(&pos, id).Error; err != nil {
|
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
|
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{}{
|
return s.db.Model(&TraderPosition{}).Where("id = ?", id).Updates(map[string]interface{}{
|
||||||
"quantity": newQty,
|
"quantity": newQty,
|
||||||
"fee": newFee,
|
"fee": newFee,
|
||||||
"exit_price": newExitPrice,
|
"exit_price": newExitPrice,
|
||||||
"realized_pnl": newPnL,
|
"realized_pnl": newPnL,
|
||||||
|
"updated_at": nowMs,
|
||||||
}).Error
|
}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePositionExchangeInfo updates exchange_id and exchange_type
|
// UpdatePositionExchangeInfo updates exchange_id and exchange_type
|
||||||
func (s *PositionStore) UpdatePositionExchangeInfo(id int64, exchangeID, exchangeType string) error {
|
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{}{
|
return s.db.Model(&TraderPosition{}).Where("id = ?", id).Updates(map[string]interface{}{
|
||||||
"exchange_id": exchangeID,
|
"exchange_id": exchangeID,
|
||||||
"exchange_type": exchangeType,
|
"exchange_type": exchangeType,
|
||||||
|
"updated_at": nowMs,
|
||||||
}).Error
|
}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user