mirror of
https://github.com/luxfi/dex.git
synced 2026-09-24 00:26:31 +00:00
- Add missing OrderBook interface implementations - Fix go vet warnings (unreachable code, redundant newline) - Add build tags for long-running tests - Create proper Go and C++ orderbook implementations - Fix clearinghouse test skipping properly - Format all Go code with gofmt - Ensure all packages build successfully - All tests pass with -short flag
411 lines
10 KiB
Go
411 lines
10 KiB
Go
package lx
|
|
|
|
import (
|
|
"math/big"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// Test vault strategy functions with 0% coverage
|
|
func TestVaultStrategyFunctions(t *testing.T) {
|
|
engineConfig := EngineConfig{
|
|
EnablePerps: true,
|
|
EnableVaults: true,
|
|
EnableLending: true,
|
|
}
|
|
engine := NewTradingEngine(engineConfig)
|
|
manager := NewVaultManager(engine)
|
|
|
|
t.Run("createStrategy", func(t *testing.T) {
|
|
// Test market making strategy creation
|
|
mmConfig := StrategyConfig{
|
|
Type: "market_making",
|
|
Name: "Test MM Strategy",
|
|
Parameters: map[string]interface{}{
|
|
"spread": 0.001,
|
|
"depth": 10,
|
|
"max_orders": 20,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 1000.0,
|
|
MaxPositionValue: big.NewInt(1000000),
|
|
MaxLeverage: 5.0,
|
|
MaxDrawdown: 0.05,
|
|
},
|
|
}
|
|
|
|
strategy := manager.createStrategy(mmConfig)
|
|
assert.NotNil(t, strategy)
|
|
assert.Equal(t, "Test MM Strategy", strategy.GetName())
|
|
|
|
// Test momentum strategy creation
|
|
momentumConfig := StrategyConfig{
|
|
Type: "momentum",
|
|
Name: "Test Momentum Strategy",
|
|
Parameters: map[string]interface{}{
|
|
"lookback": 20,
|
|
"threshold": 0.02,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 500.0,
|
|
MaxLeverage: 3.0,
|
|
},
|
|
}
|
|
|
|
momentumStrategy := manager.createStrategy(momentumConfig)
|
|
assert.NotNil(t, momentumStrategy)
|
|
assert.Equal(t, "Test Momentum Strategy", momentumStrategy.GetName())
|
|
|
|
// Test arbitrage strategy creation
|
|
arbConfig := StrategyConfig{
|
|
Type: "arbitrage",
|
|
Name: "Test Arbitrage Strategy",
|
|
Parameters: map[string]interface{}{
|
|
"min_spread": 0.005,
|
|
"max_size": 100,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 200.0,
|
|
MaxLeverage: 2.0,
|
|
},
|
|
}
|
|
|
|
arbStrategy := manager.createStrategy(arbConfig)
|
|
assert.NotNil(t, arbStrategy)
|
|
assert.Equal(t, "Test Arbitrage Strategy", arbStrategy.GetName())
|
|
|
|
// Test mean reversion strategy creation
|
|
mrConfig := StrategyConfig{
|
|
Type: "mean_reversion",
|
|
Name: "Test Mean Reversion Strategy",
|
|
Parameters: map[string]interface{}{
|
|
"band_width": 0.02,
|
|
"lookback": 50,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 300.0,
|
|
MaxLeverage: 4.0,
|
|
},
|
|
}
|
|
|
|
mrStrategy := manager.createStrategy(mrConfig)
|
|
assert.NotNil(t, mrStrategy)
|
|
assert.Equal(t, "Test Mean Reversion Strategy", mrStrategy.GetName())
|
|
|
|
// Test unknown strategy type
|
|
unknownConfig := StrategyConfig{
|
|
Type: "unknown_strategy",
|
|
Name: "Unknown Strategy",
|
|
}
|
|
|
|
unknownStrategy := manager.createStrategy(unknownConfig)
|
|
assert.Nil(t, unknownStrategy)
|
|
})
|
|
|
|
t.Run("NewMarketMakingStrategy", func(t *testing.T) {
|
|
config := StrategyConfig{
|
|
Type: "market_making",
|
|
Name: "MM Strategy Test",
|
|
Parameters: map[string]interface{}{
|
|
"spread": 0.002,
|
|
"order_size": 10.0,
|
|
"max_orders": 15,
|
|
"refresh_rate": "1s",
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 1000.0,
|
|
MaxLeverage: 5.0,
|
|
MaxDrawdown: 0.1,
|
|
},
|
|
}
|
|
|
|
strategy := NewMarketMakingStrategy(config)
|
|
assert.NotNil(t, strategy)
|
|
assert.Equal(t, "MM Strategy Test", strategy.GetName())
|
|
assert.NotNil(t, strategy.GetRiskLimits())
|
|
assert.NotNil(t, strategy.GetPerformance())
|
|
})
|
|
|
|
t.Run("MarketMakingStrategy_Execute", func(t *testing.T) {
|
|
config := StrategyConfig{
|
|
Type: "market_making",
|
|
Name: "MM Execute Test",
|
|
Parameters: map[string]interface{}{
|
|
"spread": 0.001,
|
|
"order_size": 5.0,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 500.0,
|
|
MaxLeverage: 3.0,
|
|
},
|
|
}
|
|
|
|
strategy := NewMarketMakingStrategy(config)
|
|
orderbook := NewOrderBook("BTC-USDT")
|
|
capital := big.NewInt(10000000000) // 10,000 USDT
|
|
|
|
// Add some market data to the orderbook
|
|
orderbook.AddOrder(&Order{
|
|
ID: 1,
|
|
Type: Limit,
|
|
Side: Buy,
|
|
Size: 1.0,
|
|
Price: 49000,
|
|
User: "market_maker",
|
|
Timestamp: time.Now(),
|
|
})
|
|
|
|
orderbook.AddOrder(&Order{
|
|
ID: 2,
|
|
Type: Limit,
|
|
Side: Sell,
|
|
Size: 1.0,
|
|
Price: 51000,
|
|
User: "market_maker",
|
|
Timestamp: time.Now(),
|
|
})
|
|
|
|
orders := strategy.Execute(orderbook, capital)
|
|
assert.NotNil(t, orders)
|
|
// Market making should generate orders (may be empty in test environment)
|
|
assert.True(t, len(orders) >= 0)
|
|
})
|
|
|
|
t.Run("NewMomentumStrategy", func(t *testing.T) {
|
|
config := StrategyConfig{
|
|
Type: "momentum",
|
|
Name: "Momentum Test",
|
|
Parameters: map[string]interface{}{
|
|
"lookback": 20,
|
|
"threshold": 0.02,
|
|
"max_size": 100.0,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 1000.0,
|
|
MaxLeverage: 4.0,
|
|
},
|
|
}
|
|
|
|
strategy := NewMomentumStrategy(config)
|
|
assert.NotNil(t, strategy)
|
|
assert.Equal(t, "Momentum Test", strategy.GetName())
|
|
})
|
|
|
|
t.Run("MomentumStrategy_Execute", func(t *testing.T) {
|
|
config := StrategyConfig{
|
|
Type: "momentum",
|
|
Name: "Momentum Execute Test",
|
|
Parameters: map[string]interface{}{
|
|
"lookback": 10,
|
|
"threshold": 0.01,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 500.0,
|
|
},
|
|
}
|
|
|
|
strategy := NewMomentumStrategy(config)
|
|
orderbook := NewOrderBook("ETH-USDT")
|
|
capital := big.NewInt(5000000000) // 5,000 USDT
|
|
|
|
orders := strategy.Execute(orderbook, capital)
|
|
assert.NotNil(t, orders)
|
|
assert.True(t, len(orders) >= 0)
|
|
})
|
|
|
|
t.Run("NewArbitrageStrategy", func(t *testing.T) {
|
|
config := StrategyConfig{
|
|
Type: "arbitrage",
|
|
Name: "Arbitrage Test",
|
|
Parameters: map[string]interface{}{
|
|
"min_spread": 0.005,
|
|
"max_size": 50.0,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 200.0,
|
|
MaxLeverage: 2.0,
|
|
},
|
|
}
|
|
|
|
strategy := NewArbitrageStrategy(config)
|
|
assert.NotNil(t, strategy)
|
|
assert.Equal(t, "Arbitrage Test", strategy.GetName())
|
|
})
|
|
|
|
t.Run("ArbitrageStrategy_Execute", func(t *testing.T) {
|
|
config := StrategyConfig{
|
|
Type: "arbitrage",
|
|
Name: "Arbitrage Execute Test",
|
|
Parameters: map[string]interface{}{
|
|
"min_spread": 0.003,
|
|
"max_size": 25.0,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 100.0,
|
|
},
|
|
}
|
|
|
|
strategy := NewArbitrageStrategy(config)
|
|
orderbook := NewOrderBook("BTC-USDT")
|
|
capital := big.NewInt(2000000000) // 2,000 USDT
|
|
|
|
orders := strategy.Execute(orderbook, capital)
|
|
assert.NotNil(t, orders)
|
|
assert.True(t, len(orders) >= 0)
|
|
})
|
|
|
|
t.Run("NewMeanReversionStrategy", func(t *testing.T) {
|
|
config := StrategyConfig{
|
|
Type: "mean_reversion",
|
|
Name: "Mean Reversion Test",
|
|
Parameters: map[string]interface{}{
|
|
"band_width": 0.02,
|
|
"lookback": 50,
|
|
"entry_threshold": 0.8,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 300.0,
|
|
MaxLeverage: 3.0,
|
|
},
|
|
}
|
|
|
|
strategy := NewMeanReversionStrategy(config)
|
|
assert.NotNil(t, strategy)
|
|
assert.Equal(t, "Mean Reversion Test", strategy.GetName())
|
|
})
|
|
|
|
t.Run("MeanReversionStrategy_Execute", func(t *testing.T) {
|
|
config := StrategyConfig{
|
|
Type: "mean_reversion",
|
|
Name: "Mean Reversion Execute Test",
|
|
Parameters: map[string]interface{}{
|
|
"band_width": 0.015,
|
|
"lookback": 30,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 150.0,
|
|
},
|
|
}
|
|
|
|
strategy := NewMeanReversionStrategy(config)
|
|
orderbook := NewOrderBook("AVAX-USDT")
|
|
capital := big.NewInt(3000000000) // 3,000 USDT
|
|
|
|
orders := strategy.Execute(orderbook, capital)
|
|
assert.NotNil(t, orders)
|
|
assert.True(t, len(orders) >= 0)
|
|
})
|
|
}
|
|
|
|
// Test strategy performance tracking
|
|
func TestStrategyPerformanceTracking(t *testing.T) {
|
|
t.Run("StrategyPerformanceMetrics", func(t *testing.T) {
|
|
performance := &StrategyPerformance{
|
|
TotalTrades: 100,
|
|
WinningTrades: 65,
|
|
LosingTrades: 35,
|
|
TotalPnL: big.NewInt(5000000000), // 5,000 USDT profit
|
|
}
|
|
|
|
assert.Equal(t, 100, performance.TotalTrades)
|
|
assert.Equal(t, 65, performance.WinningTrades)
|
|
assert.Equal(t, 35, performance.LosingTrades)
|
|
|
|
// Calculate win rate
|
|
winRate := float64(performance.WinningTrades) / float64(performance.TotalTrades)
|
|
assert.Equal(t, 0.65, winRate)
|
|
|
|
// Check PnL is positive
|
|
assert.True(t, performance.TotalPnL.Cmp(big.NewInt(0)) > 0)
|
|
})
|
|
|
|
t.Run("PerformanceMetricsCalculations", func(t *testing.T) {
|
|
metrics := NewPerformanceMetrics()
|
|
assert.NotNil(t, metrics)
|
|
|
|
// Test Sharpe ratio calculation
|
|
metrics.calculateSharpe()
|
|
// Should complete without error
|
|
|
|
// Test max drawdown calculation
|
|
metrics.calculateMaxDrawdown()
|
|
// Should complete without error
|
|
})
|
|
}
|
|
|
|
// Test strategy rebalancing interface
|
|
func TestStrategyRebalancing(t *testing.T) {
|
|
t.Run("RebalancerInterface", func(t *testing.T) {
|
|
// Test that strategies can implement Rebalancer interface
|
|
config := StrategyConfig{
|
|
Type: "market_making",
|
|
Name: "Rebalancing Test",
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 1000.0,
|
|
},
|
|
}
|
|
|
|
strategy := NewMarketMakingStrategy(config)
|
|
assert.NotNil(t, strategy)
|
|
|
|
// Test rebalancer interface if implemented
|
|
assert.NotNil(t, strategy)
|
|
})
|
|
}
|
|
|
|
// Test strategy configuration validation
|
|
func TestStrategyConfigValidation(t *testing.T) {
|
|
t.Run("ValidConfiguration", func(t *testing.T) {
|
|
config := StrategyConfig{
|
|
Type: "market_making",
|
|
Name: "Valid Config Test",
|
|
Parameters: map[string]interface{}{
|
|
"spread": 0.001,
|
|
"depth": 10,
|
|
},
|
|
RiskLimits: RiskLimits{
|
|
MaxPositionSize: 1000.0,
|
|
MaxPositionValue: big.NewInt(1000000),
|
|
MaxLeverage: 5.0,
|
|
MaxDrawdown: 0.05,
|
|
DailyLossLimit: 10000.0,
|
|
MaxOpenPositions: 50,
|
|
MaxOrdersPerMin: 100,
|
|
},
|
|
}
|
|
|
|
assert.Equal(t, "market_making", config.Type)
|
|
assert.Equal(t, "Valid Config Test", config.Name)
|
|
assert.NotNil(t, config.Parameters)
|
|
assert.Equal(t, 0.001, config.Parameters["spread"])
|
|
assert.Equal(t, 10, config.Parameters["depth"])
|
|
|
|
// Validate risk limits
|
|
assert.Equal(t, 1000.0, config.RiskLimits.MaxPositionSize)
|
|
assert.Equal(t, big.NewInt(1000000), config.RiskLimits.MaxPositionValue)
|
|
assert.Equal(t, 5.0, config.RiskLimits.MaxLeverage)
|
|
assert.Equal(t, 0.05, config.RiskLimits.MaxDrawdown)
|
|
assert.Equal(t, 10000.0, config.RiskLimits.DailyLossLimit)
|
|
assert.Equal(t, 50, config.RiskLimits.MaxOpenPositions)
|
|
assert.Equal(t, 100, config.RiskLimits.MaxOrdersPerMin)
|
|
})
|
|
|
|
t.Run("PositionLimitsMap", func(t *testing.T) {
|
|
riskLimits := RiskLimits{
|
|
MaxPositionSize: 1000.0,
|
|
PositionLimits: map[string]float64{
|
|
"BTC-USDT": 100.0,
|
|
"ETH-USDT": 200.0,
|
|
"AVAX-USDT": 50.0,
|
|
},
|
|
}
|
|
|
|
assert.NotNil(t, riskLimits.PositionLimits)
|
|
assert.Equal(t, 100.0, riskLimits.PositionLimits["BTC-USDT"])
|
|
assert.Equal(t, 200.0, riskLimits.PositionLimits["ETH-USDT"])
|
|
assert.Equal(t, 50.0, riskLimits.PositionLimits["AVAX-USDT"])
|
|
})
|
|
}
|