Files
dex/pkg/lx/liquidation.go
zeekay 0d2a1d93ab refactor: simplify file naming - remove redundant suffixes
Renamed files:
- lending_pool.go → lending.go
- lending_pool_test.go → lending_test.go
- margin_trading.go → margin.go
- margin_trading_test.go → margin_test.go
- liquidation_engine.go → liquidation.go
- liquidation_engine_test.go → liquidation_test.go
- liquidation_engine_comprehensive_test.go → liquidation_comprehensive_test.go

No API changes - all public types/functions remain the same.
2025-12-11 17:09:28 -08:00

956 lines
25 KiB
Go

package lx
import (
"errors"
"fmt"
"math"
"math/big"
"sync"
"time"
)
// LiquidationEngine manages position liquidations and insurance fund
type LiquidationEngine struct {
// Core components
InsuranceFund *InsuranceFund
LiquidationQueue *LiquidationQueue
AutoDeleveraging *AutoDeleveragingEngine
SocializedLoss *SocializedLossEngine
// Liquidation parameters
MaintenanceMargin map[string]float64 // Per-asset maintenance margin
LiquidationFee float64 // Fee charged on liquidation
InsuranceFundFee float64 // Portion of fees going to insurance fund
// Liquidators
Liquidators map[string]*Liquidator
LiquidatorRewards map[string]*big.Int
// Performance tracking
TotalLiquidations uint64
TotalLiquidated *big.Int
TotalLosses *big.Int
InsuranceFundUsed *big.Int
LiquidationMetrics *LiquidationMetrics
LiquidationHistory []*LiquidationOrder
// Risk management
RiskEngine *RiskEngine
CircuitBreaker *CircuitBreaker
EmergencyMode bool
mu sync.RWMutex
}
// InsuranceFund manages the insurance fund for covering losses
type InsuranceFund struct {
// Fund balances
Balance map[string]*big.Int // Per-asset balances
TotalValueUSD *big.Int
// Fund parameters
TargetSize *big.Int
MinimumSize *big.Int
MaxDrawdown float64
// Fund operations
Contributions []*FundContribution
Withdrawals []*FundWithdrawal
LossCoverage []*LossCoverageEvent
// Performance
HighWaterMark *big.Int
CurrentDrawdown float64
APY float64
// Governance
FundManagers []string
WithdrawalRules *WithdrawalRules
LastUpdate time.Time
mu sync.RWMutex
}
// LiquidationQueue manages pending liquidations
type LiquidationQueue struct {
// Queue structure
HighPriority []*LiquidationOrder
MediumPriority []*LiquidationOrder
LowPriority []*LiquidationOrder
Orders []*LiquidationOrder // For testing compatibility
// Processing
ProcessingOrders map[string]*LiquidationOrder
CompletedOrders map[string]*LiquidationOrder
FailedOrders map[string]*LiquidationOrder
// Configuration
MaxQueueSize int
ProcessingInterval time.Duration
RetryAttempts int
mu sync.RWMutex
}
// LiquidationOrder represents a liquidation order
type LiquidationOrder struct {
OrderID string
PositionID string
UserID string
Symbol string
Side Side
Size float64
MarkPrice float64
LiquidationPrice float64
CollateralValue *big.Int
Loss *big.Int
Priority LiquidationPriority
Status LiquidationOrderStatus
CreatedAt time.Time
ProcessedAt *time.Time
LiquidatorID string
ExecutionPrice float64
LiquidationFee *big.Int
InsuranceFundClaim *big.Int
}
// LiquidationPriority defines liquidation priority levels
type LiquidationPriority int
const (
HighPriority LiquidationPriority = iota
MediumPriority
LowPriority
)
// LiquidationOrderStatus represents the status of a liquidation order
type LiquidationOrderStatus int
const (
LiquidationPending LiquidationOrderStatus = iota
LiquidationProcessing
LiquidationPartial
LiquidationComplete
LiquidationFailed
LiquidationCancelled
)
// Liquidator represents a liquidation participant
type Liquidator struct {
LiquidatorID string
Balance *big.Int
ActiveLiquidations []*LiquidationOrder
CompletedCount uint64
TotalProfit *big.Int
SuccessRate float64
AverageFillTime time.Duration
Reputation float64
Tier LiquidatorTier
LastActive time.Time
}
// LiquidatorTier represents liquidator tiers
type LiquidatorTier int
const (
BronzeLiquidator LiquidatorTier = iota
SilverLiquidator
GoldLiquidator
PlatinumLiquidator
DiamondLiquidator
)
// AutoDeleveragingEngine handles auto-deleveraging
type AutoDeleveragingEngine struct {
// ADL queue
ADLQueue map[string][]*ADLCandidate
// ADL parameters
ADLThreshold float64 // Insurance fund depletion threshold
MaxADLPercentage float64 // Maximum position reduction
// ADL history
ADLEvents []*ADLEvent
TotalADLVolume *big.Int
mu sync.RWMutex
}
// ADLCandidate represents a position eligible for auto-deleveraging
type ADLCandidate struct {
PositionID string
UserID string
PnLRanking float64 // Profit ranking for ADL priority
PositionSize float64
UnrealizedPnL *big.Int
Leverage float64
ADLPriority int
}
// ADLEvent represents an auto-deleveraging event
type ADLEvent struct {
EventID string
Timestamp time.Time
TriggerReason string
AffectedPositions []*ADLAffectedPosition
TotalReduced float64
InsuranceFundBefore *big.Int
InsuranceFundAfter *big.Int
}
// ADLAffectedPosition represents a position affected by ADL
type ADLAffectedPosition struct {
PositionID string
UserID string
OriginalSize float64
ReducedSize float64
ReductionPercentage float64
CompensationPaid *big.Int
}
// SocializedLossEngine handles socialized losses
type SocializedLossEngine struct {
// Loss distribution
PendingLosses map[string]*SocializedLoss
DistributedLosses map[string]*SocializedLoss
// Parameters
LossThreshold *big.Int // Minimum loss to trigger socialization
MaxLossPerUser float64 // Maximum loss percentage per user
// History
LossHistory []*SocializedLossEvent
TotalSocialized *big.Int
mu sync.RWMutex
}
// SocializedLoss represents a socialized loss
type SocializedLoss struct {
LossID string
TotalLoss *big.Int
AffectedAsset string
DistributionMethod string
AffectedUsers map[string]*UserLossShare
Timestamp time.Time
Status SocializedLossStatus
}
// UserLossShare represents a user's share of socialized loss
type UserLossShare struct {
UserID string
PositionSize float64
LossAmount *big.Int
Percentage float64
Compensated bool
CompensationAmount *big.Int
}
// SocializedLossStatus represents the status of socialized loss
type SocializedLossStatus int
const (
LossPending SocializedLossStatus = iota
LossDistributing
LossDistributed
LossCancelled
)
// LiquidationMetrics tracks liquidation performance
type LiquidationMetrics struct {
TotalLiquidations uint64
SuccessfulLiquidations uint64
FailedLiquidations uint64
PartialLiquidations uint64
TotalVolume *big.Int
AverageLoss *big.Int
MaxLoss *big.Int
InsuranceFundUsage *big.Int
ADLTriggers uint64
SocializedLosses uint64
LastUpdate time.Time
}
// CircuitBreaker provides emergency controls
type CircuitBreaker struct {
Enabled bool
TriggerConditions map[string]*TriggerCondition
CooldownPeriod time.Duration
LastTriggered time.Time
TriggeredCount uint64
}
// TriggerCondition defines circuit breaker trigger conditions
type TriggerCondition struct {
ConditionID string
Name string
Check func() bool
Action func() error
Severity TriggerSeverity
Enabled bool
}
// TriggerSeverity represents trigger severity levels
type TriggerSeverity int
const (
LowSeverity TriggerSeverity = iota
MediumSeverity
HighSeverity
CriticalSeverity
)
// NewLiquidationEngine creates a new liquidation engine
func NewLiquidationEngine() *LiquidationEngine {
return &LiquidationEngine{
InsuranceFund: NewInsuranceFund(),
LiquidationQueue: NewLiquidationQueue(),
AutoDeleveraging: NewAutoDeleveragingEngine(),
SocializedLoss: NewSocializedLossEngine(),
MaintenanceMargin: initLiquidationMaintenanceMargins(),
LiquidationFee: 0.005, // 0.5% liquidation fee
InsuranceFundFee: 0.5, // 50% of liquidation fees go to insurance fund
Liquidators: make(map[string]*Liquidator),
LiquidatorRewards: make(map[string]*big.Int),
TotalLiquidated: big.NewInt(0),
TotalLosses: big.NewInt(0),
InsuranceFundUsed: big.NewInt(0),
LiquidationMetrics: NewLiquidationMetrics(),
LiquidationHistory: make([]*LiquidationOrder, 0),
RiskEngine: NewRiskEngine(),
CircuitBreaker: NewCircuitBreaker(),
EmergencyMode: false,
}
}
// NewInsuranceFund creates a new insurance fund
func NewInsuranceFund() *InsuranceFund {
return &InsuranceFund{
Balance: make(map[string]*big.Int),
TotalValueUSD: big.NewInt(0),
TargetSize: big.NewInt(10000000), // $10M target
MinimumSize: big.NewInt(1000000), // $1M minimum
MaxDrawdown: 0.5, // 50% max drawdown
Contributions: make([]*FundContribution, 0),
Withdrawals: make([]*FundWithdrawal, 0),
LossCoverage: make([]*LossCoverageEvent, 0),
HighWaterMark: big.NewInt(0),
FundManagers: make([]string, 0),
WithdrawalRules: NewWithdrawalRules(),
LastUpdate: time.Now(),
}
}
// ProcessLiquidation processes a liquidation
func (le *LiquidationEngine) ProcessLiquidation(userID string, position *MarginPosition, liquidationOrder *Order) error {
le.mu.Lock()
defer le.mu.Unlock()
// Check circuit breaker
if le.CircuitBreaker.Enabled && le.CircuitBreaker.ShouldTrigger() {
return errors.New("circuit breaker triggered")
}
// Create liquidation order
liqOrder := &LiquidationOrder{
OrderID: generateLiquidationOrderID(),
PositionID: position.ID,
UserID: userID,
Symbol: position.Symbol,
Side: position.Side,
Size: position.Size,
MarkPrice: position.MarkPrice,
LiquidationPrice: position.LiquidationPrice,
CollateralValue: position.Margin,
Priority: le.calculatePriority(position),
Status: LiquidationPending,
CreatedAt: time.Now(),
}
// Calculate potential loss
loss := le.calculateLoss(position)
liqOrder.Loss = loss
// Add to queue based on priority
le.LiquidationQueue.Add(liqOrder)
// Process immediately if high priority
if liqOrder.Priority == HighPriority {
go le.executeLiquidation(liqOrder)
}
// Update metrics
le.TotalLiquidations++
le.LiquidationMetrics.TotalLiquidations++
return nil
}
// executeLiquidation executes a liquidation order
func (le *LiquidationEngine) executeLiquidation(order *LiquidationOrder) error {
// Update status
order.Status = LiquidationProcessing
le.LiquidationQueue.mu.Lock()
le.LiquidationQueue.ProcessingOrders[order.OrderID] = order
le.LiquidationQueue.mu.Unlock()
// Find liquidator
liquidator := le.findBestLiquidator(order)
if liquidator == nil {
// No liquidator available, try ADL
return le.triggerADL(order)
}
// Execute liquidation
executionPrice, err := le.executeTrade(order, liquidator)
if err != nil {
order.Status = LiquidationFailed
return err
}
order.ExecutionPrice = executionPrice
order.LiquidatorID = liquidator.LiquidatorID
// Calculate fees
orderValue := big.NewInt(int64(order.Size * executionPrice))
liquidationFee := new(big.Int).Mul(orderValue, big.NewInt(int64(le.LiquidationFee*1000)))
liquidationFee.Div(liquidationFee, big.NewInt(1000))
order.LiquidationFee = liquidationFee
// Distribute fees
insuranceFundPortion := new(big.Int).Mul(liquidationFee, big.NewInt(int64(le.InsuranceFundFee*1000)))
insuranceFundPortion.Div(insuranceFundPortion, big.NewInt(1000))
le.InsuranceFund.AddContribution(order.Symbol, insuranceFundPortion)
// Handle loss if any
if order.Loss.Cmp(big.NewInt(0)) > 0 {
if err := le.handleLoss(order); err != nil {
return err
}
}
// Update liquidator stats
liquidator.CompletedCount++
liquidator.TotalProfit.Add(liquidator.TotalProfit, liquidationFee)
liquidator.LastActive = time.Now()
// Complete order
order.Status = LiquidationComplete
order.ProcessedAt = &[]time.Time{time.Now()}[0]
// Move to completed
le.LiquidationQueue.mu.Lock()
delete(le.LiquidationQueue.ProcessingOrders, order.OrderID)
le.LiquidationQueue.CompletedOrders[order.OrderID] = order
le.LiquidationQueue.mu.Unlock()
// Update metrics
le.TotalLiquidated.Add(le.TotalLiquidated, orderValue)
le.LiquidationMetrics.SuccessfulLiquidations++
le.LiquidationMetrics.TotalVolume.Add(le.LiquidationMetrics.TotalVolume, orderValue)
return nil
}
// handleLoss handles losses from liquidation
func (le *LiquidationEngine) handleLoss(order *LiquidationOrder) error {
// First try to cover from insurance fund
if le.InsuranceFund.CanCoverLoss(order.Symbol, order.Loss) {
return le.InsuranceFund.CoverLoss(order.Symbol, order.Loss, order.OrderID)
}
// If insurance fund insufficient, check for ADL
insuranceRatio := le.InsuranceFund.GetCoverageRatio()
if insuranceRatio < le.AutoDeleveraging.ADLThreshold {
return le.triggerADL(order)
}
// Last resort: socialized loss
return le.SocializedLoss.DistributeLoss(order)
}
// triggerADL triggers auto-deleveraging
func (le *LiquidationEngine) triggerADL(order *LiquidationOrder) error {
return le.AutoDeleveraging.Execute(order)
}
// findBestLiquidator finds the best liquidator for an order
func (le *LiquidationEngine) findBestLiquidator(order *LiquidationOrder) *Liquidator {
var bestLiquidator *Liquidator
bestScore := 0.0
for _, liquidator := range le.Liquidators {
// Check if liquidator has sufficient balance
requiredBalance := big.NewInt(int64(order.Size * order.MarkPrice))
if liquidator.Balance.Cmp(requiredBalance) < 0 {
continue
}
// Calculate liquidator score
score := le.calculateLiquidatorScore(liquidator, order)
if score > bestScore {
bestScore = score
bestLiquidator = liquidator
}
}
return bestLiquidator
}
// calculateLiquidatorScore calculates a liquidator's score
func (le *LiquidationEngine) calculateLiquidatorScore(liquidator *Liquidator, order *LiquidationOrder) float64 {
score := 0.0
// Factor in reputation
score += liquidator.Reputation * 0.3
// Factor in success rate
score += liquidator.SuccessRate * 0.3
// Factor in tier
tierBonus := float64(liquidator.Tier) * 0.1
score += tierBonus
// Factor in recent activity
timeSinceActive := time.Since(liquidator.LastActive).Hours()
if timeSinceActive < 1 {
score += 0.2
} else if timeSinceActive < 24 {
score += 0.1
}
// Factor in balance (more balance = higher score)
balanceRatio := new(big.Float).SetInt(liquidator.Balance)
balanceRatio.Quo(balanceRatio, big.NewFloat(1000000)) // Normalize to millions
balanceScore, _ := balanceRatio.Float64()
score += math.Min(balanceScore*0.1, 0.2) // Cap at 0.2
return score
}
// calculatePriority calculates liquidation priority
func (le *LiquidationEngine) calculatePriority(position *MarginPosition) LiquidationPriority {
// Calculate how far below liquidation price
currentPrice := position.MarkPrice
liquidationPrice := position.LiquidationPrice
var priceRatio float64
if position.Side == Buy {
priceRatio = currentPrice / liquidationPrice
} else {
priceRatio = liquidationPrice / currentPrice
}
// High priority if well below liquidation price
if priceRatio < 0.95 {
return HighPriority
} else if priceRatio < 0.98 {
return MediumPriority
}
return LowPriority
}
// calculateLoss calculates the loss from a position
func (le *LiquidationEngine) calculateLoss(position *MarginPosition) *big.Int {
// If UnrealizedPnL is positive or zero, no loss
if position.UnrealizedPnL.Sign() >= 0 {
return big.NewInt(0)
}
// UnrealizedPnL is negative, calculate loss
// Loss = abs(UnrealizedPnL) - Margin
absLoss := new(big.Int).Abs(position.UnrealizedPnL)
// If loss is less than margin, no uncovered loss
if absLoss.Cmp(position.Margin) <= 0 {
return big.NewInt(0)
}
// Return the uncovered loss (amount exceeding margin)
return new(big.Int).Sub(absLoss, position.Margin)
}
// executeTrade executes the liquidation trade
func (le *LiquidationEngine) executeTrade(order *LiquidationOrder, liquidator *Liquidator) (float64, error) {
// Simulate trade execution
// In production, this would interact with the order book
slippage := 0.002 // 0.2% slippage
var executionPrice float64
if order.Side == Buy {
// Liquidating a long position, need to sell
executionPrice = order.MarkPrice * (1 - slippage)
} else {
// Liquidating a short position, need to buy
executionPrice = order.MarkPrice * (1 + slippage)
}
return executionPrice, nil
}
// InsuranceFund methods
func (fund *InsuranceFund) AddContribution(asset string, amount *big.Int) {
fund.mu.Lock()
defer fund.mu.Unlock()
if fund.Balance[asset] == nil {
fund.Balance[asset] = big.NewInt(0)
}
fund.Balance[asset].Add(fund.Balance[asset], amount)
fund.TotalValueUSD.Add(fund.TotalValueUSD, amount) // Simplified, should convert to USD
// Update high water mark
if fund.TotalValueUSD.Cmp(fund.HighWaterMark) > 0 {
fund.HighWaterMark.Set(fund.TotalValueUSD)
}
fund.LastUpdate = time.Now()
}
func (fund *InsuranceFund) CanCoverLoss(asset string, loss *big.Int) bool {
fund.mu.RLock()
defer fund.mu.RUnlock()
return fund.canCoverLossInternal(asset, loss)
}
func (fund *InsuranceFund) canCoverLossInternal(asset string, loss *big.Int) bool {
balance := fund.Balance[asset]
if balance == nil {
return false
}
return balance.Cmp(loss) >= 0
}
func (fund *InsuranceFund) CoverLoss(asset string, loss *big.Int, referenceID string) error {
fund.mu.Lock()
defer fund.mu.Unlock()
if !fund.canCoverLossInternal(asset, loss) {
return errors.New("insufficient insurance fund balance")
}
fund.Balance[asset].Sub(fund.Balance[asset], loss)
fund.TotalValueUSD.Sub(fund.TotalValueUSD, loss) // Simplified
// Record loss coverage event
event := &LossCoverageEvent{
EventID: generateEventID(),
Asset: asset,
Amount: loss,
ReferenceID: referenceID,
Timestamp: time.Now(),
}
fund.LossCoverage = append(fund.LossCoverage, event)
// Update drawdown
if fund.HighWaterMark.Cmp(big.NewInt(0)) > 0 {
drawdown := new(big.Float).SetInt(fund.HighWaterMark)
drawdown.Sub(drawdown, new(big.Float).SetInt(fund.TotalValueUSD))
drawdown.Quo(drawdown, new(big.Float).SetInt(fund.HighWaterMark))
fund.CurrentDrawdown, _ = drawdown.Float64()
}
fund.LastUpdate = time.Now()
return nil
}
func (fund *InsuranceFund) GetCoverageRatio() float64 {
fund.mu.RLock()
defer fund.mu.RUnlock()
if fund.TargetSize.Cmp(big.NewInt(0)) == 0 {
return 0
}
ratio := new(big.Float).SetInt(fund.TotalValueUSD)
ratio.Quo(ratio, new(big.Float).SetInt(fund.TargetSize))
result, _ := ratio.Float64()
return result
}
// LiquidationQueue methods
func NewLiquidationQueue() *LiquidationQueue {
return &LiquidationQueue{
HighPriority: make([]*LiquidationOrder, 0),
MediumPriority: make([]*LiquidationOrder, 0),
LowPriority: make([]*LiquidationOrder, 0),
Orders: make([]*LiquidationOrder, 0), // For testing compatibility
ProcessingOrders: make(map[string]*LiquidationOrder),
CompletedOrders: make(map[string]*LiquidationOrder),
FailedOrders: make(map[string]*LiquidationOrder),
MaxQueueSize: 10000,
ProcessingInterval: 100 * time.Millisecond,
RetryAttempts: 3,
}
}
func (queue *LiquidationQueue) Add(order *LiquidationOrder) {
queue.mu.Lock()
defer queue.mu.Unlock()
switch order.Priority {
case HighPriority:
queue.HighPriority = append(queue.HighPriority, order)
case MediumPriority:
queue.MediumPriority = append(queue.MediumPriority, order)
case LowPriority:
queue.LowPriority = append(queue.LowPriority, order)
}
}
// AutoDeleveraging methods
func NewAutoDeleveragingEngine() *AutoDeleveragingEngine {
return &AutoDeleveragingEngine{
ADLQueue: make(map[string][]*ADLCandidate),
ADLThreshold: 0.2, // Trigger ADL when insurance fund < 20% of target
MaxADLPercentage: 0.5, // Maximum 50% position reduction
ADLEvents: make([]*ADLEvent, 0),
TotalADLVolume: big.NewInt(0),
}
}
func (adl *AutoDeleveragingEngine) Execute(order *LiquidationOrder) error {
adl.mu.Lock()
defer adl.mu.Unlock()
// Get ADL candidates for the symbol
candidates := adl.ADLQueue[order.Symbol]
if len(candidates) == 0 {
return errors.New("no ADL candidates available")
}
// Sort candidates by PnL ranking (highest profit first)
// In production, implement proper sorting
event := &ADLEvent{
EventID: generateEventID(),
Timestamp: time.Now(),
TriggerReason: fmt.Sprintf("Insurance fund below threshold for %s", order.OrderID),
AffectedPositions: make([]*ADLAffectedPosition, 0),
}
remainingSize := order.Size
for _, candidate := range candidates {
if remainingSize <= 0 {
break
}
// Calculate reduction
reductionSize := math.Min(candidate.PositionSize*adl.MaxADLPercentage, remainingSize)
reductionPercentage := reductionSize / candidate.PositionSize
// Create affected position record
affected := &ADLAffectedPosition{
PositionID: candidate.PositionID,
UserID: candidate.UserID,
OriginalSize: candidate.PositionSize,
ReducedSize: reductionSize,
ReductionPercentage: reductionPercentage,
CompensationPaid: big.NewInt(0), // Calculate compensation
}
event.AffectedPositions = append(event.AffectedPositions, affected)
remainingSize -= reductionSize
}
adl.ADLEvents = append(adl.ADLEvents, event)
return nil
}
// SocializedLoss methods
func NewSocializedLossEngine() *SocializedLossEngine {
return &SocializedLossEngine{
PendingLosses: make(map[string]*SocializedLoss),
DistributedLosses: make(map[string]*SocializedLoss),
LossThreshold: big.NewInt(100000), // $100k minimum for socialized loss
MaxLossPerUser: 0.1, // Maximum 10% loss per user
LossHistory: make([]*SocializedLossEvent, 0),
TotalSocialized: big.NewInt(0),
}
}
func (sl *SocializedLossEngine) DistributeLoss(order *LiquidationOrder) error {
sl.mu.Lock()
defer sl.mu.Unlock()
if order.Loss.Cmp(sl.LossThreshold) < 0 {
return errors.New("loss below socialization threshold")
}
loss := &SocializedLoss{
LossID: generateLossID(),
TotalLoss: order.Loss,
AffectedAsset: order.Symbol,
DistributionMethod: "proportional",
AffectedUsers: make(map[string]*UserLossShare),
Timestamp: time.Now(),
Status: LossPending,
}
sl.PendingLosses[loss.LossID] = loss
// In production, would calculate and distribute loss shares
// based on user positions and risk profile
return nil
}
// CircuitBreaker methods
func NewCircuitBreaker() *CircuitBreaker {
return &CircuitBreaker{
Enabled: true,
TriggerConditions: initTriggerConditions(),
CooldownPeriod: 5 * time.Minute,
TriggeredCount: 0,
}
}
func (cb *CircuitBreaker) ShouldTrigger() bool {
if !cb.Enabled {
return false
}
// Check cooldown
if time.Since(cb.LastTriggered) < cb.CooldownPeriod {
return false
}
// Check trigger conditions
for _, condition := range cb.TriggerConditions {
if condition.Enabled && condition.Check() {
cb.LastTriggered = time.Now()
cb.TriggeredCount++
go condition.Action() // Execute action asynchronously
return true
}
}
return false
}
// Helper functions
func initLiquidationMaintenanceMargins() map[string]float64 {
return map[string]float64{
"BTC-USDT": 0.005,
"ETH-USDT": 0.01,
"BNB-USDT": 0.02,
"SOL-USDT": 0.025,
"AVAX-USDT": 0.025,
}
}
func initTriggerConditions() map[string]*TriggerCondition {
return map[string]*TriggerCondition{
"high_liquidation_rate": {
ConditionID: "high_liq_rate",
Name: "High Liquidation Rate",
Check: func() bool {
// Check if liquidation rate is too high
return false // Placeholder
},
Action: func() error {
// Pause new positions
return nil
},
Severity: HighSeverity,
Enabled: true,
},
"insurance_fund_depleted": {
ConditionID: "ins_fund_depl",
Name: "Insurance Fund Depleted",
Check: func() bool {
// Check if insurance fund is critically low
return false // Placeholder
},
Action: func() error {
// Enter emergency mode
return nil
},
Severity: CriticalSeverity,
Enabled: true,
},
}
}
func generateLiquidationOrderID() string {
return fmt.Sprintf("liq_%d", time.Now().UnixNano())
}
func generateEventID() string {
return fmt.Sprintf("event_%d", time.Now().UnixNano())
}
func generateLossID() string {
return fmt.Sprintf("loss_%d", time.Now().UnixNano())
}
func NewLiquidationMetrics() *LiquidationMetrics {
return &LiquidationMetrics{
TotalVolume: big.NewInt(0),
AverageLoss: big.NewInt(0),
MaxLoss: big.NewInt(0),
InsuranceFundUsage: big.NewInt(0),
LastUpdate: time.Now(),
}
}
func NewWithdrawalRules() *WithdrawalRules {
return &WithdrawalRules{
MinBalance: big.NewInt(1000000),
MaxWithdrawal: big.NewInt(100000),
CooldownPeriod: 24 * time.Hour,
RequiredVotes: 3,
}
}
// Additional types
type FundContribution struct {
ContributionID string
Source string
Asset string
Amount *big.Int
Timestamp time.Time
}
type FundWithdrawal struct {
WithdrawalID string
Recipient string
Asset string
Amount *big.Int
Reason string
ApprovedBy []string
Timestamp time.Time
}
type LossCoverageEvent struct {
EventID string
Asset string
Amount *big.Int
ReferenceID string
Timestamp time.Time
}
type WithdrawalRules struct {
MinBalance *big.Int
MaxWithdrawal *big.Int
CooldownPeriod time.Duration
RequiredVotes int
}
type SocializedLossEvent struct {
EventID string
LossID string
TotalLoss *big.Int
UsersAffected int
Timestamp time.Time
}